summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--c/src/lib/libbsp/arm/shared/startup/linkcmds.base9
-rw-r--r--c/src/lib/libbsp/sparc/erc32/make/custom/erc32.cfg2
-rw-r--r--c/src/lib/libbsp/sparc/shared/startup/linkcmds.base35
-rw-r--r--c/src/make/Makefile.am2
-rw-r--r--c/src/make/bsp.mk.in59
-rw-r--r--c/src/make/configure.ac1
-rw-r--r--cpukit/libcsupport/include/sys/ioccom.h26
-rw-r--r--cpukit/libcsupport/src/termios.c71
-rw-r--r--cpukit/libfs/src/pipe/fifo.c95
-rw-r--r--cpukit/libfs/src/pipe/pipe.h2
-rw-r--r--cpukit/libnetworking/rtems/rtems_select.c32
-rw-r--r--testsuites/libtests/flashdisk01/test-file-system.c6
-rw-r--r--testsuites/sptests/spfifo04/init.c12
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 d6561dde77..008685ee67 100644
--- a/c/src/lib/libbsp/arm/shared/startup/linkcmds.base
+++ b/c/src/lib/libbsp/arm/shared/startup/linkcmds.base
@@ -310,6 +310,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 );