diff options
-rw-r--r-- | c/src/lib/libbsp/arm/shared/startup/linkcmds.base | 9 | ||||
-rw-r--r-- | c/src/lib/libbsp/sparc/erc32/make/custom/erc32.cfg | 2 | ||||
-rw-r--r-- | c/src/lib/libbsp/sparc/shared/startup/linkcmds.base | 35 | ||||
-rw-r--r-- | c/src/make/Makefile.am | 2 | ||||
-rw-r--r-- | c/src/make/bsp.mk.in | 59 | ||||
-rw-r--r-- | c/src/make/configure.ac | 1 | ||||
-rw-r--r-- | cpukit/libcsupport/include/sys/ioccom.h | 26 | ||||
-rw-r--r-- | cpukit/libcsupport/src/termios.c | 71 | ||||
-rw-r--r-- | cpukit/libfs/src/pipe/fifo.c | 95 | ||||
-rw-r--r-- | cpukit/libfs/src/pipe/pipe.h | 2 | ||||
-rw-r--r-- | cpukit/libnetworking/rtems/rtems_select.c | 32 | ||||
-rw-r--r-- | testsuites/libtests/flashdisk01/test-file-system.c | 6 | ||||
-rw-r--r-- | testsuites/sptests/spfifo04/init.c | 12 |
13 files changed, 315 insertions, 37 deletions
diff --git a/c/src/lib/libbsp/arm/shared/startup/linkcmds.base b/c/src/lib/libbsp/arm/shared/startup/linkcmds.base index 5174d480ad..c01b77b589 100644 --- a/c/src/lib/libbsp/arm/shared/startup/linkcmds.base +++ b/c/src/lib/libbsp/arm/shared/startup/linkcmds.base @@ -306,6 +306,15 @@ SECTIONS { _bsd__start_set_sysctl_set = .; *(_bsd_set_sysctl_set); _bsd__stop_set_sysctl_set = .; + __start_pcpu_set = .; + *(set_pcpu); + __stop_pcpu_set = .; + _bsd__start_set_ieee80211_ioctl_getset = .; + *(_bsd_set_ieee80211_ioctl_getset); + _bsd__stop_set_ieee80211_ioctl_getset = .; + _bsd__start_set_ieee80211_ioctl_setset = .; + *(_bsd_set_ieee80211_ioctl_setset); + _bsd__stop_set_ieee80211_ioctl_setset = .; bsp_section_rodata_end = .; } > REGION_RODATA AT > REGION_RODATA_LOAD diff --git a/c/src/lib/libbsp/sparc/erc32/make/custom/erc32.cfg b/c/src/lib/libbsp/sparc/erc32/make/custom/erc32.cfg index 3879d3dc73..f1fced8bc6 100644 --- a/c/src/lib/libbsp/sparc/erc32/make/custom/erc32.cfg +++ b/c/src/lib/libbsp/sparc/erc32/make/custom/erc32.cfg @@ -12,4 +12,4 @@ RTEMS_CPU_MODEL=erc32 CPU_CFLAGS = -mcpu=cypress # optimize flag: typically -O2 -CFLAGS_OPTIMIZE_V = -O2 -g +CFLAGS_OPTIMIZE_V = -O0 -g diff --git a/c/src/lib/libbsp/sparc/shared/startup/linkcmds.base b/c/src/lib/libbsp/sparc/shared/startup/linkcmds.base index 1bbb77374e..ab5a9ef604 100644 --- a/c/src/lib/libbsp/sparc/shared/startup/linkcmds.base +++ b/c/src/lib/libbsp/sparc/shared/startup/linkcmds.base @@ -120,6 +120,9 @@ SECTIONS } > ram .rela.dyn : { + data_start = .; + _data_start = .; + _sdata = . ; *(.rela.init) *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) *(.rela.fini) @@ -132,11 +135,37 @@ SECTIONS *(.rela.got) *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } >ram + .robsdsets : { + /* Special FreeBSD linker set sections */ + __start_set_sysctl_set = .; + *(set_sysctl_*); + __stop_set_sysctl_set = .; + *(set_domain_*); + *(set_pseudo_*); + _bsd__start_set_modmetadata_set = .; + *(_bsd_set_modmetadata_set); + _bsd__stop_set_modmetadata_set = .; + _bsd__start_set_sysctl_set = .; + *(_bsd_set_sysctl_set); + _bsd__stop_set_sysctl_set = .; + __start_pcpu_set = .; + *(set_pcpu); + __stop_pcpu_set = .; + _bsd__start_set_ieee80211_ioctl_getset = .; + *(_bsd_set_ieee80211_ioctl_getset); + _bsd__stop_set_ieee80211_ioctl_getset = .; + _bsd__start_set_ieee80211_ioctl_setset = .; + *(_bsd_set_ieee80211_ioctl_setset); + _bsd__stop_set_ieee80211_ioctl_setset = .; + } >ram + .rwbsdsets : { + /* Special FreeBSD linker set sections */ + _bsd__start_set_sysinit_set = .; + *(_bsd_set_sysinit_set); + _bsd__stop_set_sysinit_set = .; + } >ram .data : { - data_start = .; - _data_start = .; - _sdata = . ; *(.data*) *(.gnu.linkonce.d*) *(.gcc_except_table*) diff --git a/c/src/make/Makefile.am b/c/src/make/Makefile.am index d0383df8ed..b3ca7c0a7a 100644 --- a/c/src/make/Makefile.am +++ b/c/src/make/Makefile.am @@ -18,7 +18,7 @@ rtems_bspdir = $(rtemsdir)/@RTEMS_BSP@ rtems_bsp_DATA = Makefile.inc rtems_bsp_makedir = $(rtems_bspdir)/make -rtems_bsp_make_DATA = bsp.cfg target.cfg +rtems_bsp_make_DATA = bsp.cfg target.cfg bsp.mk bsp.cfg: bsp.cfg.in Makefile sed \ diff --git a/c/src/make/bsp.mk.in b/c/src/make/bsp.mk.in new file mode 100644 index 0000000000..12a4e1936f --- /dev/null +++ b/c/src/make/bsp.mk.in @@ -0,0 +1,59 @@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +RTEMS_API = @RTEMS_API@ +RTEMS_BSP = @RTEMS_BSP@ +RTEMS_ROOT = @prefix@ +RTEMS_SHARE = $(RTEMS_ROOT)/share/rtems$(RTEMS_API) +PROJECT_ROOT = @exec_prefix@/@RTEMS_BSP@ +PROJECT_INCLUDE = $(PROJECT_ROOT)/lib/include +PROJECT_LIB = $(PROJECT_ROOT)/lib +BUILDDIR = build-$(RTEMS_BSP) + +include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg + +DEPFLAGS = -MT $@ -MD -MP -MF $(basename $@).d +SYSFLAGS = -B $(PROJECT_LIB) -specs bsp_specs -qrtems +WARNFLAGS = -Wall -Wextra -Wformat=2 -Wcast-qual -Wconversion -Wno-unused +OPTFLAGS = $(CFLAGS_OPTIMIZE_V) + +CFLAGS = $(DEPFLAGS) $(SYSFLAGS) $(WARNFLAGS) $(CPU_CFLAGS) $(OPTFLAGS) +CXXFLAGS = $(DEPFLAGS) $(SYSFLAGS) $(WARNFLAGS) $(CPU_CFLAGS) $(OPTFLAGS) +LINKFLAGS = $(SYSFLAGS) $(CPU_CFLAGS) $(LDFLAGS) $(OPTFLAGS) +ASFLAGS = $(CPU_CFLAGS) + +CCLINK = $(CC) $(LINKFLAGS) -Wl,-Map,$(basename $@).map +CXXLINK = $(CXX) $(LINKFLAGS) -Wl,-Map,$(basename $@).map + +$(BUILDDIR)/%.o: %.c + $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@ + +$(BUILDDIR)/%.o: %.S + $(CC) $(CPPFLAGS) -DASM $(CFLAGS) -c $< -o $@ + +$(BUILDDIR)/%.o: %.cc + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@ + +$(BUILDDIR)/%.o: %.s + $(AS) $(ASFLAGS) $< -o $@ + +AR = @AR@ +AS = @AS@ +CC = @CC@ +CXX = @CXX@ +LD = @LD@ +NM = @NM@ +OBJCOPY = @OBJCOPY@ +RANLIB = @RANLIB@ +SIZE = @SIZE@ +STRIP = @STRIP@ +export AR +export AS +export CC +export CXX +export LD +export NM +export OBJCOPY +export RANLIB +export SIZE +export STRIP diff --git a/c/src/make/configure.ac b/c/src/make/configure.ac index 1517c68a99..0a5abd959f 100644 --- a/c/src/make/configure.ac +++ b/c/src/make/configure.ac @@ -78,5 +78,6 @@ AC_CONFIG_LINKS([leaf.cfg:leaf.cfg]) # Explicitly list all Makefiles here AC_CONFIG_FILES([Makefile +bsp.mk ]) AC_OUTPUT diff --git a/cpukit/libcsupport/include/sys/ioccom.h b/cpukit/libcsupport/include/sys/ioccom.h index 7f6ff26cf4..1a31374301 100644 --- a/cpukit/libcsupport/include/sys/ioccom.h +++ b/cpukit/libcsupport/include/sys/ioccom.h @@ -33,8 +33,7 @@ #ifndef _SYS_IOCCOM_H_ #define _SYS_IOCCOM_H_ -#include <sys/types.h> -#include <stdint.h> +#include <rtems.h> /* * Ioctl's have the command encoded in the lower word, and the size of @@ -74,6 +73,29 @@ #define RTEMS_IO_RCVWAKEUP 4 #define RTEMS_IO_SNDWAKEUP 5 +typedef enum { + RTEMS_IOCTL_SELECT_OTHER, + RTEMS_IOCTL_SELECT_READ, + RTEMS_IOCTL_SELECT_WRITE +} rtems_ioctl_select_kind; + +/** + * @brief IO control request for select() support. + * + * The driver shall return + * - 1, when the request can be fullfilled immediately, + * - 0, when the request task must wait, and + * - -1, in case of an error. + */ +typedef struct { + rtems_ioctl_select_kind kind; + rtems_id request_task_id; +} rtems_ioctl_select_request; + +#define RTEMS_IOCTL_SELECT _IOW('R', 0, rtems_ioctl_select_request) + +#define RTEMS_IOCTL_SELECT_EVENT RTEMS_EVENT_24 + /* copied from libnetworking/sys/filio.h and commented out there */ /* Generic file-descriptor ioctl's. */ #define FIOCLEX _IO('f', 1) /* set close on exec on fd */ diff --git a/cpukit/libcsupport/src/termios.c b/cpukit/libcsupport/src/termios.c index bcf8d8acb3..ef9cc71b84 100644 --- a/cpukit/libcsupport/src/termios.c +++ b/cpukit/libcsupport/src/termios.c @@ -507,6 +507,73 @@ termios_set_flowctrl(struct rtems_termios_tty *tty) } } +static bool +rtems_termios_can_read (const struct rtems_termios_tty *tty) +{ + if (tty->cindex == tty->ccount) { + if (tty->device.outputUsesInterrupts == TERMIOS_IRQ_DRIVEN) { + return tty->rawInBuf.Head != tty->rawInBuf.Tail; + } else { + return true; + } + } else { + return tty->cindex < tty->ccount; + } +} + +static bool +rtems_termios_can_write (const struct rtems_termios_tty *tty) +{ + /* + * Termios has no non-blocking writes. In case the raw output buffer is + * full, we wait for the interrupt or poll. + */ + return true; +} + +static void +rtems_termios_select_wakeup (struct termios *tty, void *arg) +{ + rtems_id task_id = (rtems_id) arg; + rtems_status_code sc = rtems_event_send (task_id, RTEMS_IOCTL_SELECT_EVENT); + if (sc != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (sc); +} + +static int +rtems_termios_select (struct rtems_termios_tty *tty, + const rtems_ioctl_select_request *request) +{ + int rv = 0; + + rtems_interrupt_level level; + rtems_interrupt_disable(level); + switch (request->kind) { + case RTEMS_IOCTL_SELECT_READ: + if (rtems_termios_can_read (tty)) { + rv = 1; + } else { + tty->tty_rcvwakeup = 0; + tty->tty_rcv.sw_pfn = rtems_termios_select_wakeup; + tty->tty_rcv.sw_arg = (void *) request->request_task_id; + } + break; + case RTEMS_IOCTL_SELECT_WRITE: + if (rtems_termios_can_write (tty)) { + rv = 1; + } else { + tty->tty_snd.sw_pfn = rtems_termios_select_wakeup; + tty->tty_snd.sw_arg = (void *) request->request_task_id; + } + break; + default: + break; + } + rtems_interrupt_enable(level); + + return rv; +} + rtems_status_code rtems_termios_ioctl (void *arg) { @@ -530,6 +597,10 @@ rtems_termios_ioctl (void *arg) } break; + case RTEMS_IOCTL_SELECT: + args->ioctl_return = rtems_termios_select (tty, args->buffer); + break; + case RTEMS_IO_GET_ATTRIBUTES: *(struct termios *)args->buffer = tty->termios; break; diff --git a/cpukit/libfs/src/pipe/fifo.c b/cpukit/libfs/src/pipe/fifo.c index 06eacd712f..d07346498a 100644 --- a/cpukit/libfs/src/pipe/fifo.c +++ b/cpukit/libfs/src/pipe/fifo.c @@ -66,6 +66,21 @@ static rtems_id pipe_semaphore = RTEMS_ID_NONE; #include <rtems/rtems/barrier.h> #include <rtems/score/thread.h> +static void pipe_select_wakeup(rtems_id *id_ptr) +{ + rtems_id id = *id_ptr; + + *id_ptr = 0; + + if (id != 0) { + rtems_status_code sc = rtems_event_send(id, RTEMS_IOCTL_SELECT_EVENT); + + if (sc != RTEMS_SUCCESSFUL) { + rtems_fatal_error_occurred(sc); + } + } +} + /* Set barriers to be interruptible by signals. */ static void pipe_interruptible(pipe_control_t *pipe) { @@ -92,10 +107,9 @@ static int pipe_alloc( pipe_control_t *pipe; int err = -ENOMEM; - pipe = malloc(sizeof(pipe_control_t)); + pipe = calloc(1, sizeof(pipe_control_t)); if (pipe == NULL) return err; - memset(pipe, 0, sizeof(pipe_control_t)); pipe->Size = PIPE_BUF; pipe->Buffer = malloc(pipe->Size); @@ -445,6 +459,7 @@ ssize_t pipe_read( if (PIPE_EMPTY(pipe)) pipe->Start = 0; + pipe_select_wakeup(&pipe->select_write_task_id); if (pipe->waitingWriters > 0) PIPE_WAKEUPWRITERS(pipe); read += chunk; @@ -523,6 +538,7 @@ ssize_t pipe_write( memcpy(pipe->Buffer + PIPE_WSTART(pipe), buffer + written, chunk); pipe->Length += chunk; + pipe_select_wakeup(&pipe->select_read_task_id); if (pipe->waitingReaders > 0) PIPE_WAKEUPREADERS(pipe); written += chunk; @@ -545,6 +561,53 @@ out_nolock: return ret; } +static int pipe_register_select_wakeup( + rtems_id *id_ptr, + const rtems_ioctl_select_request *request +) +{ + int rv = 0; + rtems_id current_id = *id_ptr; + rtems_id request_id = request->request_task_id; + + if (current_id == 0 || current_id == request_id) { + *id_ptr = request_id; + } else { + rv = -EINVAL; + } + + return rv; +} + +static int pipe_select( + pipe_control_t *pipe, + const rtems_ioctl_select_request *request +) +{ + int rv = 0; + + switch (request->kind) { + case RTEMS_IOCTL_SELECT_READ: + if (!PIPE_EMPTY(pipe)) { + rv = 1; + } else { + rv = pipe_register_select_wakeup(&pipe->select_read_task_id, request); + } + break; + case RTEMS_IOCTL_SELECT_WRITE: + if (PIPE_SPACE(pipe) > 0) { + rv = 1; + } else { + rv = pipe_register_select_wakeup(&pipe->select_write_task_id, request); + } + break; + default: + break; + } + + return rv; +} + /* * Interface to file system ioctl. */ @@ -555,18 +618,26 @@ int pipe_ioctl( rtems_libio_t *iop ) { - if (cmd == FIONREAD) { - if (buffer == NULL) - return -EFAULT; - - if (! PIPE_LOCK(pipe)) - return -EINTR; + int rv = 0; + + if (PIPE_LOCK(pipe)) { + switch (cmd) { + case RTEMS_IOCTL_SELECT: + rv = pipe_select(pipe, buffer); + break; + case FIONREAD: + /* Return length of pipe */ + *(unsigned int *) buffer = pipe->Length; + break; + default: + rv = -EINVAL; + break; + } - /* Return length of pipe */ - *(unsigned int *)buffer = pipe->Length; PIPE_UNLOCK(pipe); - return 0; + } else { + rv = -EINTR; } - return -EINVAL; + return rv; } diff --git a/cpukit/libfs/src/pipe/pipe.h b/cpukit/libfs/src/pipe/pipe.h index 29e7542b43..5795093497 100644 --- a/cpukit/libfs/src/pipe/pipe.h +++ b/cpukit/libfs/src/pipe/pipe.h @@ -37,6 +37,8 @@ typedef struct pipe_control { rtems_id Semaphore; rtems_id readBarrier; /* wait queues */ rtems_id writeBarrier; + rtems_id select_read_task_id; + rtems_id select_write_task_id; #if 0 boolean Anonymous; /* anonymous pipe or FIFO */ #endif diff --git a/cpukit/libnetworking/rtems/rtems_select.c b/cpukit/libnetworking/rtems/rtems_select.c index b581904769..19a67ae63c 100644 --- a/cpukit/libnetworking/rtems/rtems_select.c +++ b/cpukit/libnetworking/rtems/rtems_select.c @@ -26,6 +26,11 @@ #include <net/if.h> #include <net/route.h> +RTEMS_STATIC_ASSERT(RTEMS_IOCTL_SELECT_OTHER == 0, other); +RTEMS_STATIC_ASSERT(RTEMS_IOCTL_SELECT_READ == FREAD, fread); +RTEMS_STATIC_ASSERT(RTEMS_IOCTL_SELECT_WRITE == FWRITE, fwrite); +RTEMS_STATIC_ASSERT(RTEMS_IOCTL_SELECT_EVENT == SBWAIT_EVENT, sbwait_event); + /* ********************************************************************* * RTEMS implementation of select() system call * @@ -84,6 +89,11 @@ selscan (rtems_id tid, fd_mask **ibits, fd_mask **obits, int nfd, int *retval) fd_mask bits, bit; int n = 0; static int flag[3] = { FREAD, FWRITE, 0 }; + int update_obits; + int rv; + rtems_ioctl_select_request select_request; + + select_request.request_task_id = tid; for (msk = 0; msk < 3; msk++) { if (ibits[msk] == NULL) @@ -94,10 +104,26 @@ selscan (rtems_id tid, fd_mask **ibits, fd_mask **obits, int nfd, int *retval) if ((bits & bit) == 0) continue; bits &= ~bit; + update_obits = 0; so = rtems_bsdnet_fdToSocket (fd); - if (so == NULL) - return (EBADF); - if (socket_select (so, flag[msk], tid)) { + if (so != NULL) { + if (socket_select (so, flag[msk], tid)) { + update_obits = 1; + } + } else { + select_request.kind = flag[msk]; + + rtems_bsdnet_semaphore_release(); + rv = ioctl (fd, RTEMS_IOCTL_SELECT, &select_request); + rtems_bsdnet_semaphore_obtain(); + if (rv == 1) { + update_obits = 1; + } else if (rv != 0) { + return (EBADF); + } + } + + if (update_obits) { obits[msk][fd/NFDBITS] |= (1 << (fd % NFDBITS)); n++; diff --git a/testsuites/libtests/flashdisk01/test-file-system.c b/testsuites/libtests/flashdisk01/test-file-system.c index d3515d0743..52783732b9 100644 --- a/testsuites/libtests/flashdisk01/test-file-system.c +++ b/testsuites/libtests/flashdisk01/test-file-system.c @@ -596,8 +596,9 @@ static test_state do_file_append(unsigned index, fs_state *fs) if (pos != (off_t) -1) { size_t buf_size = sizeof(fs->buf); + size_t offset = HEADER_SIZE + 1; long random = lrand48(); - size_t out = get_bucket_with_random(buf_size, random) + 1; + size_t out = get_bucket_with_random(buf_size - offset, random) + offset; ssize_t out_actual = 0; uint8_t *buf = fs->buf; uint32_t value = (uint32_t) random; @@ -605,9 +606,6 @@ static test_state do_file_append(unsigned index, fs_state *fs) size_t word_count = 0; size_t w = 0; - /* Must be big enough for the header */ - out = out >= HEADER_SIZE ? out : HEADER_SIZE; - /* * In case out is not an integral multiple of four we will write a bit to * much. This does not hurt since the buffer is big enough. diff --git a/testsuites/sptests/spfifo04/init.c b/testsuites/sptests/spfifo04/init.c index 51fab0d2ed..e8f11c860d 100644 --- a/testsuites/sptests/spfifo04/init.c +++ b/testsuites/sptests/spfifo04/init.c @@ -53,11 +53,6 @@ rtems_task Init( rtems_test_assert( offset == -1 ); rtems_test_assert( errno == ESPIPE ); - puts( "Init - ioctl: FIONBIO -- Expected EFAULT" ); - status = ioctl( fd, FIONBIO, NULL ); - rtems_test_assert( status == -1 ); - rtems_test_assert( errno == EFAULT ); - puts( "Init - ioctl: FIONBIO -- OK" ); status = ioctl( fd, FIONBIO, &flag ); rtems_test_assert( status == 0 ); @@ -68,15 +63,10 @@ rtems_task Init( rtems_test_assert( status == 0 ); puts( "Init - ioctl: Dummy Command -- Expected EINVAL" ); - status = ioctl( fd, -1, NULL ); + status = ioctl( fd, -1 ); rtems_test_assert( status == -1 ); rtems_test_assert( errno == EINVAL ); - puts( "Init - ioctl: FIONREAD -- Expected EFAULT" ); - status = ioctl( fd, FIONREAD, NULL ); - rtems_test_assert( status == -1 ); - rtems_test_assert( errno == EFAULT ); - puts( "Init - ioctl: FIONREAD -- OK" ); status = ioctl( fd, FIONREAD, &pipe_length ); rtems_test_assert( status == 0 ); |