You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by gn...@apache.org on 2020/02/14 15:30:00 UTC

[incubator-nuttx] branch pr282 updated (ddc8f52 -> bb68a12)

This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a change to branch pr282
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git.


    from ddc8f52  drivers/eeprom/i2c_xx24xx.c: increase number of retries in ee24xx_waitwritecomplete
     new 1a4ff4c  arch: risc-v: Add support for PROTECTED build to rv64gc
     new 5fcde14  arch: risc-v: Add up_pthread_start.c and up_task_start.c to common dir
     new 382cc29  arch: risc-v: Add support for PROTECTED build to k210
     new bb68a12  boards: maix-bit: Add support for PROTECTED build

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 arch/risc-v/Kconfig                                |   1 +
 arch/risc-v/include/rv64gc/irq.h                   |   9 +-
 arch/risc-v/include/rv64gc/syscall.h               | 160 ++++++++++++++--
 arch/{arm => risc-v}/src/common/up_pthread_start.c |  41 ++--
 .../risc-v/src/common/up_task_start.c              |  47 +++--
 arch/risc-v/src/k210/Make.defs                     |  10 +-
 arch/risc-v/src/k210/k210_allocateheap.c           |  49 +++++
 arch/risc-v/src/k210/k210_irq.c                    |  12 +-
 arch/risc-v/src/k210/k210_irq_dispatch.c           |   4 +-
 arch/risc-v/src/k210/k210_start.c                  |  12 ++
 .../risc-v/src/k210/k210_userspace.c               |  77 +++++---
 .../risc-v/src/k210/k210_userspace.h               |  46 ++---
 arch/risc-v/src/k210/up_schedulesigaction.c        |  12 +-
 arch/risc-v/src/rv64gc/svcall.h                    | 128 +++++++++++++
 arch/risc-v/src/rv64gc/up_initialstate.c           |  19 --
 .../src/rv64gc}/up_signal_dispatch.c               |  41 ++--
 .../risc-v/src/rv64gc/up_signal_handler.S          | 123 ++++++------
 arch/risc-v/src/rv64gc/up_swint.c                  | 213 +++++++++++++++++++--
 arch/risc-v/src/rv64gc/up_syscall.S                | 111 -----------
 .../maix-bit/configs/{elf => kostest}/defconfig    |  28 ++-
 .../k210/maix-bit}/kernel/.gitignore               |   0
 .../k210/maix-bit}/kernel/Makefile                 |  45 ++---
 .../k210/maix-bit/kernel/k210_userspace.c}         |  57 ++----
 boards/risc-v/k210/maix-bit/scripts/memory.ld      |  37 ++++
 boards/risc-v/k210/maix-bit/scripts/user-space.ld  |  94 +++++++++
 25 files changed, 921 insertions(+), 455 deletions(-)
 copy arch/{arm => risc-v}/src/common/up_pthread_start.c (55%)
 copy sched/sched/sched_getcpu.c => arch/risc-v/src/common/up_task_start.c (55%)
 copy sched/sched/sched_getcpu.c => arch/risc-v/src/k210/k210_userspace.c (52%)
 copy sched/sched/sched_getcpu.c => arch/risc-v/src/k210/k210_userspace.h (60%)
 create mode 100644 arch/risc-v/src/rv64gc/svcall.h
 copy arch/{arm/src/armv7-m => risc-v/src/rv64gc}/up_signal_dispatch.c (59%)
 copy boards/arm/stm32h7/nucleo-h743zi/src/stm32_pwm.c => arch/risc-v/src/rv64gc/up_signal_handler.S (52%)
 delete mode 100644 arch/risc-v/src/rv64gc/up_syscall.S
 copy boards/risc-v/k210/maix-bit/configs/{elf => kostest}/defconfig (75%)
 copy boards/{arm/stm32l4/stm32l4r9ai-disco => risc-v/k210/maix-bit}/kernel/.gitignore (100%)
 copy boards/{arm/lc823450/lc823450-xgevk => risc-v/k210/maix-bit}/kernel/Makefile (67%)
 copy boards/{arm/stm32/clicker2-stm32/kernel/stm32_userspace.c => risc-v/k210/maix-bit/kernel/k210_userspace.c} (61%)
 create mode 100644 boards/risc-v/k210/maix-bit/scripts/memory.ld
 create mode 100644 boards/risc-v/k210/maix-bit/scripts/user-space.ld


[incubator-nuttx] 04/04: boards: maix-bit: Add support for PROTECTED build

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch pr282
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit bb68a12c95403c44e7d1c6f36a1830bd3ad41630
Author: Masayuki Ishikawa <ma...@gmail.com>
AuthorDate: Fri Feb 14 16:11:56 2020 +0900

    boards: maix-bit: Add support for PROTECTED build
---
 .../risc-v/k210/maix-bit/configs/kostest/defconfig |  55 ++++++++++
 boards/risc-v/k210/maix-bit/kernel/.gitignore      |   1 +
 boards/risc-v/k210/maix-bit/kernel/Makefile        | 107 +++++++++++++++++++
 .../risc-v/k210/maix-bit/kernel/k210_userspace.c   | 117 +++++++++++++++++++++
 boards/risc-v/k210/maix-bit/scripts/memory.ld      |  37 +++++++
 boards/risc-v/k210/maix-bit/scripts/user-space.ld  |  94 +++++++++++++++++
 6 files changed, 411 insertions(+)

diff --git a/boards/risc-v/k210/maix-bit/configs/kostest/defconfig b/boards/risc-v/k210/maix-bit/configs/kostest/defconfig
new file mode 100644
index 0000000..5254e0b
--- /dev/null
+++ b/boards/risc-v/k210/maix-bit/configs/kostest/defconfig
@@ -0,0 +1,55 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed .config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that includes your
+# modifications.
+#
+# CONFIG_STANDARD_SERIAL is not set
+CONFIG_ARCH="risc-v"
+CONFIG_ARCH_BOARD="maix-bit"
+CONFIG_ARCH_BOARD_MAIX_BIT=y
+CONFIG_ARCH_CHIP="k210"
+CONFIG_ARCH_CHIP_K210=y
+CONFIG_ARCH_INTERRUPTSTACK=2048
+CONFIG_ARCH_RISCV=y
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_ARCH_USE_MPU=y
+CONFIG_BOARD_LOOPSPERMSEC=46000
+CONFIG_BUILD_PROTECTED=y
+CONFIG_BUILTIN=y
+CONFIG_DEBUG_ASSERTIONS=y
+CONFIG_DEBUG_ERROR=y
+CONFIG_DEBUG_FEATURES=y
+CONFIG_DEBUG_FULLOPT=y
+CONFIG_DEBUG_SYMBOLS=y
+CONFIG_DEV_ZERO=y
+CONFIG_FS_PROCFS=y
+CONFIG_IDLETHREAD_STACKSIZE=2048
+CONFIG_INTELHEX_BINARY=y
+CONFIG_LIBC_PERROR_STDOUT=y
+CONFIG_LIBC_STRERROR=y
+CONFIG_MAX_TASKS=64
+CONFIG_MAX_WDOGPARMS=2
+CONFIG_MM_KERNEL_HEAPSIZE=524288
+CONFIG_NFILE_STREAMS=8
+CONFIG_NUTTX_USERSPACE=0x80100000
+CONFIG_PASS1_BUILDIR="boards/risc-v/k210/maix-bit/kernel"
+CONFIG_PREALLOC_TIMERS=4
+CONFIG_PREALLOC_WDOGS=16
+CONFIG_RAM_SIZE=2097152
+CONFIG_RAM_START=0x80400000
+CONFIG_RAW_BINARY=y
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_WAITPID=y
+CONFIG_STACK_COLORATION=y
+CONFIG_START_DAY=14
+CONFIG_START_MONTH=2
+CONFIG_START_YEAR=2020
+CONFIG_SYS_RESERVED=8
+CONFIG_TASK_NAME_SIZE=20
+CONFIG_TESTING_OSTEST=y
+CONFIG_UART0_SERIAL_CONSOLE=y
+CONFIG_USERMAIN_STACKSIZE=3072
+CONFIG_USER_ENTRYPOINT="ostest_main"
+CONFIG_WDOG_INTRESERVE=0
diff --git a/boards/risc-v/k210/maix-bit/kernel/.gitignore b/boards/risc-v/k210/maix-bit/kernel/.gitignore
new file mode 100644
index 0000000..324b8d5
--- /dev/null
+++ b/boards/risc-v/k210/maix-bit/kernel/.gitignore
@@ -0,0 +1 @@
+/nuttx_user.elf
diff --git a/boards/risc-v/k210/maix-bit/kernel/Makefile b/boards/risc-v/k210/maix-bit/kernel/Makefile
new file mode 100644
index 0000000..94d3b1f
--- /dev/null
+++ b/boards/risc-v/k210/maix-bit/kernel/Makefile
@@ -0,0 +1,107 @@
+############################################################################
+# boards/risc-v/k210/maix-bit/kernel/Makefile
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.  The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+############################################################################
+
+-include $(TOPDIR)/Make.defs
+
+# This is the directory for the board-specific header files
+
+BOARD_INCLUDE = $(TOPDIR)$(DELIM)boards$(DELIM)$(CONFIG_ARCH)$(DELIM)$(CONFIG_ARCH_CHIP)$(DELIM)$(CONFIG_ARCH_BOARD)$(DELIM)include
+
+# The entry point name (if none is provided in the .config file)
+
+CONFIG_USER_ENTRYPOINT ?= user_start
+ENTRYPT = $(patsubst "%",%,$(CONFIG_USER_ENTRYPOINT))
+
+# Get the paths to the libraries and the links script path in format that
+# is appropriate for the host OS
+
+ifeq ($(WINTOOL),y)
+  # Windows-native toolchains
+  USER_LIBPATHS = ${shell for path in $(USERLIBS); do dir=`dirname $(TOPDIR)$(DELIM)$$path`;echo "-L\"`cygpath -w $$dir`\"";done}
+  USER_LDSCRIPT = -T "${shell cygpath -w $(TOPDIR)$(DELIM)boards$(DELIM)$(CONFIG_ARCH)$(DELIM)$(CONFIG_ARCH_CHIP)$(DELIM)$(CONFIG_ARCH_BOARD)$(DELIM)scripts$(DELIM)memory.ld}"
+  USER_LDSCRIPT += -T "${shell cygpath -w $(TOPDIR)$(DELIM)boards$(DELIM)$(CONFIG_ARCH)$(DELIM)$(CONFIG_ARCH_CHIP)$(DELIM)$(CONFIG_ARCH_BOARD)$(DELIM)scripts$(DELIM)user-space.ld}"
+  USER_HEXFILE += "${shell cygpath -w $(TOPDIR)$(DELIM)nuttx_user.hex}"
+  USER_SRECFILE += "${shell cygpath -w $(TOPDIR)$(DELIM)nuttx_user.srec}"
+  USER_BINFILE += "${shell cygpath -w $(TOPDIR)$(DELIM)nuttx_user.bin}"
+else
+  # Linux/Cygwin-native toolchain
+  USER_LIBPATHS = $(addprefix -L$(TOPDIR)$(DELIM),$(dir $(USERLIBS)))
+  USER_LDSCRIPT = -T$(TOPDIR)$(DELIM)boards$(DELIM)$(CONFIG_ARCH)$(DELIM)$(CONFIG_ARCH_CHIP)$(DELIM)$(CONFIG_ARCH_BOARD)$(DELIM)scripts$(DELIM)memory.ld
+  USER_LDSCRIPT += -T$(TOPDIR)$(DELIM)boards$(DELIM)$(CONFIG_ARCH)$(DELIM)$(CONFIG_ARCH_CHIP)$(DELIM)$(CONFIG_ARCH_BOARD)$(DELIM)scripts$(DELIM)user-space.ld
+  USER_HEXFILE += "$(TOPDIR)$(DELIM)nuttx_user.hex"
+  USER_SRECFILE += "$(TOPDIR)$(DELIM)nuttx_user.srec"
+  USER_BINFILE += "$(TOPDIR)$(DELIM)nuttx_user.bin"
+endif
+
+USER_LDFLAGS = --undefined=$(ENTRYPT) --entry=$(ENTRYPT) $(USER_LDSCRIPT)
+USER_LDLIBS = $(patsubst lib%,-l%,$(basename $(notdir $(USERLIBS))))
+USER_LIBGCC = "${shell "$(CC)" $(ARCHCPUFLAGS) -print-libgcc-file-name}"
+
+# Source files
+
+CSRCS = k210_userspace.c
+COBJS = $(CSRCS:.c=$(OBJEXT))
+OBJS  = $(COBJS)
+
+# Targets:
+
+all: $(TOPDIR)$(DELIM)nuttx_user.elf $(TOPDIR)$(DELIM)User.map
+.PHONY: nuttx_user.elf depend clean distclean
+
+$(COBJS): %$(OBJEXT): %.c
+	$(call COMPILE, $<, $@)
+
+# Create the nuttx_user.elf file containing all of the user-mode code
+
+nuttx_user.elf: $(OBJS)
+	$(Q) $(LD) -o $@ $(USER_LDFLAGS) $(USER_LIBPATHS) $(OBJS) --start-group $(USER_LDLIBS) --end-group $(USER_LIBGCC)
+
+$(TOPDIR)$(DELIM)nuttx_user.elf: nuttx_user.elf
+	@echo "LD: nuttx_user.elf"
+	$(Q) cp -a nuttx_user.elf $(TOPDIR)$(DELIM)nuttx_user.elf
+ifeq ($(CONFIG_INTELHEX_BINARY),y)
+	@echo "CP: nuttx_user.hex"
+	$(Q) $(OBJCOPY) $(OBJCOPYARGS) -O ihex nuttx_user.elf $(USER_HEXFILE)
+endif
+ifeq ($(CONFIG_MOTOROLA_SREC),y)
+	@echo "CP: nuttx_user.srec"
+	$(Q) $(OBJCOPY) $(OBJCOPYARGS) -O srec nuttx_user.elf $(USER_SRECFILE)
+endif
+ifeq ($(CONFIG_RAW_BINARY),y)
+	@echo "CP: nuttx_user.bin"
+	$(Q) $(OBJCOPY) $(OBJCOPYARGS) -O binary nuttx_user.elf $(USER_BINFILE)
+endif
+
+$(TOPDIR)$(DELIM)User.map: nuttx_user.elf
+	@echo "MK: User.map"
+	$(Q) $(NM) -n nuttx_user.elf >$(TOPDIR)$(DELIM)User.map
+	$(Q) $(CROSSDEV)size nuttx_user.elf
+
+.depend:
+
+depend: .depend
+
+clean:
+	$(call DELFILE, nuttx_user.elf)
+	$(call DELFILE, "$(TOPDIR)$(DELIM)nuttx_user.*")
+	$(call DELFILE, "$(TOPDIR)$(DELIM)User.map")
+	$(call CLEAN)
+
+distclean: clean
diff --git a/boards/risc-v/k210/maix-bit/kernel/k210_userspace.c b/boards/risc-v/k210/maix-bit/kernel/k210_userspace.c
new file mode 100644
index 0000000..70657c7
--- /dev/null
+++ b/boards/risc-v/k210/maix-bit/kernel/k210_userspace.c
@@ -0,0 +1,117 @@
+/****************************************************************************
+ * boards/risc-v/k210/maix-bit/kernel/k210_userspace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdlib.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/mm/mm.h>
+#include <nuttx/wqueue.h>
+#include <nuttx/userspace.h>
+
+#if defined(CONFIG_BUILD_PROTECTED) && !defined(__KERNEL__)
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Configuration ************************************************************/
+
+#ifndef CONFIG_NUTTX_USERSPACE
+#  error "CONFIG_NUTTX_USERSPACE not defined"
+#endif
+
+#if CONFIG_NUTTX_USERSPACE != 0x80100000
+#  error "CONFIG_NUTTX_USERSPACE must match the value in memory.ld"
+#endif
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/* These 'addresses' of these values are setup by the linker script.
+ * They are not actual uint32_t storage locations!
+ * They are only used meaningfully in the following way:
+ *
+ *  - The linker script defines, for example, the symbol_sdata.
+ *  - The declaration extern uint32_t _sdata; makes C happy.  C will believe
+ *    that the value _sdata is the address of a uint32_t variable _data
+ *    (it is not!).
+ *  - We can recover the linker value then by simply taking the address of
+ *    of _data.  like:  uint32_t *pdata = &_sdata;
+ */
+
+extern uint32_t _stext;           /* Start of .text */
+extern uint32_t _etext;           /* End_1 of .text + .rodata */
+extern const uint32_t _eronly;    /* End+1 of read only section */
+extern uint32_t _sdata;           /* Start of .data */
+extern uint32_t _edata;           /* End+1 of .data */
+extern uint32_t _sbss;            /* Start of .bss */
+extern uint32_t _ebss;            /* End+1 of .bss */
+
+/* This is the user space entry point */
+
+int CONFIG_USER_ENTRYPOINT(int argc, char *argv[]);
+
+const struct userspace_s userspace __attribute__ ((section (".userspace"))) =
+{
+  /* General memory map */
+
+  .us_entrypoint    = (main_t)CONFIG_USER_ENTRYPOINT,
+  .us_textstart     = (uintptr_t)&_stext,
+  .us_textend       = (uintptr_t)&_etext,
+  .us_datasource    = (uintptr_t)&_eronly,
+  .us_datastart     = (uintptr_t)&_sdata,
+  .us_dataend       = (uintptr_t)&_edata,
+  .us_bssstart      = (uintptr_t)&_sbss,
+  .us_bssend        = (uintptr_t)&_ebss,
+
+  /* Memory manager heap structure */
+
+  .us_heap          = &g_mmheap,
+
+  /* Task/thread startup routines */
+
+  .task_startup     = task_startup,
+#ifndef CONFIG_DISABLE_PTHREAD
+  .pthread_startup  = pthread_startup,
+#endif
+
+  /* Signal handler trampoline */
+
+  .signal_handler   = up_signal_handler,
+
+  /* User-space work queue support (declared in include/nuttx/wqueue.h) */
+
+#ifdef CONFIG_LIB_USRWORK
+  .work_usrstart    = work_usrstart,
+#endif
+};
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+#endif /* CONFIG_BUILD_PROTECTED && !__KERNEL__ */
diff --git a/boards/risc-v/k210/maix-bit/scripts/memory.ld b/boards/risc-v/k210/maix-bit/scripts/memory.ld
new file mode 100644
index 0000000..bf257e5
--- /dev/null
+++ b/boards/risc-v/k210/maix-bit/scripts/memory.ld
@@ -0,0 +1,37 @@
+/****************************************************************************
+ * boards/risc-v/k210/maix-bit/scripts/memory.ld
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/* Reg   Access        Start addr    End addr     Size
+ * MEM0  CPU w/  cache  0x80000000 - 0x803fffff : 4MB
+ * MEM1  CPU w/  cache  0x80400000 - 0x805fffff : 2MB
+ * MEM0  CPU w/o cache  0x40000000 - 0x403fffff : 4MB
+ * MEM1  CPU w/o cache  0x40400000 - 0x405fffff : 4MB
+ */
+
+MEMORY
+{
+  kflash (rx)  : ORIGIN = 0x80000000, LENGTH = 1024K  /* w/ cache */
+  uflash (rx)  : ORIGIN = 0x80100000, LENGTH = 1024K  /* w/ cache */
+  xflash (rx)  : ORIGIN = 0x80200000, LENGTH = 2048K  /* w/ cache */
+
+  ksram (rwx)  : ORIGIN = 0x80400000, LENGTH = 512K   /* w/ cache */
+  usram (rwx)  : ORIGIN = 0x80480000, LENGTH = 512K   /* w/ cache */
+  xsram (rwx)  : ORIGIN = 0x80500000, LENGTH = 1024K  /* w/ cache */
+}
diff --git a/boards/risc-v/k210/maix-bit/scripts/user-space.ld b/boards/risc-v/k210/maix-bit/scripts/user-space.ld
new file mode 100644
index 0000000..7f56966
--- /dev/null
+++ b/boards/risc-v/k210/maix-bit/scripts/user-space.ld
@@ -0,0 +1,94 @@
+/****************************************************************************
+ * boards/risc-v/k210/maix-bit/scripts/user-space.ld
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/* NOTE:  This depends on the memory.ld script having been included prior to
+ * this script.
+ */
+
+OUTPUT_ARCH("riscv")
+
+SECTIONS
+{
+    .userspace : {
+        *(.userspace)
+    } > uflash
+
+    .text : {
+        _stext = ABSOLUTE(.);
+        *(.text .text.*)
+        *(.fixup)
+        *(.gnu.warning)
+        *(.rodata .rodata.*)
+        *(.gnu.linkonce.t.*)
+        *(.glue_7)
+        *(.glue_7t)
+        *(.got)
+        *(.gcc_except_table)
+        *(.gnu.linkonce.r.*)
+        _etext = ABSOLUTE(.);
+    } > uflash
+
+    .init_section : {
+        _sinit = ABSOLUTE(.);
+        *(.init_array .init_array.*)
+        _einit = ABSOLUTE(.);
+    } > uflash
+
+    __exidx_start = ABSOLUTE(.);
+
+    __exidx_end = ABSOLUTE(.);
+
+    _eronly = ABSOLUTE(.);
+
+    .data : {
+        _sdata = ABSOLUTE(.);
+        *(.data .data.*)
+        *(.sdata .sdata.* .sdata2.*)
+        *(.gnu.linkonce.d.*)
+        CONSTRUCTORS
+        . = ALIGN(4);
+        _edata = ABSOLUTE(.);
+    } > usram AT > uflash
+
+    .bss : {
+        _sbss = ABSOLUTE(.);
+        *(.bss .bss.*)
+        *(.sbss .sbss.*)
+        *(.gnu.linkonce.b.*)
+        *(COMMON)
+        . = ALIGN(4);
+        _ebss = ABSOLUTE(.);
+    } > usram
+
+    /* Stabs debugging sections */
+
+    .stab 0 : { *(.stab) }
+    .stabstr 0 : { *(.stabstr) }
+    .stab.excl 0 : { *(.stab.excl) }
+    .stab.exclstr 0 : { *(.stab.exclstr) }
+    .stab.index 0 : { *(.stab.index) }
+    .stab.indexstr 0 : { *(.stab.indexstr) }
+    .comment 0 : { *(.comment) }
+    .debug_abbrev 0 : { *(.debug_abbrev) }
+    .debug_info 0 : { *(.debug_info) }
+    .debug_line 0 : { *(.debug_line) }
+    .debug_pubnames 0 : { *(.debug_pubnames) }
+    .debug_aranges 0 : { *(.debug_aranges) }
+}


[incubator-nuttx] 03/04: arch: risc-v: Add support for PROTECTED build to k210

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch pr282
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 382cc29c72700871302486ff36ea62372b84e46f
Author: Masayuki Ishikawa <ma...@gmail.com>
AuthorDate: Fri Feb 14 16:10:50 2020 +0900

    arch: risc-v: Add support for PROTECTED build to k210
---
 arch/risc-v/Kconfig                         |  1 +
 arch/risc-v/src/k210/Make.defs              | 10 +++-
 arch/risc-v/src/k210/k210_allocateheap.c    | 49 ++++++++++++++++
 arch/risc-v/src/k210/k210_irq.c             | 12 +++-
 arch/risc-v/src/k210/k210_irq_dispatch.c    |  4 +-
 arch/risc-v/src/k210/k210_start.c           | 12 ++++
 arch/risc-v/src/k210/k210_userspace.c       | 90 +++++++++++++++++++++++++++++
 arch/risc-v/src/k210/k210_userspace.h       | 49 ++++++++++++++++
 arch/risc-v/src/k210/up_schedulesigaction.c | 12 +++-
 9 files changed, 232 insertions(+), 7 deletions(-)

diff --git a/arch/risc-v/Kconfig b/arch/risc-v/Kconfig
index bfc4c66..0e601a1 100644
--- a/arch/risc-v/Kconfig
+++ b/arch/risc-v/Kconfig
@@ -19,6 +19,7 @@ config ARCH_CHIP_FE310
 config ARCH_CHIP_K210
 	bool "Kendryte K210"
 	select ARCH_RV64GC
+	select ARCH_HAVE_MPU
 	select ARCH_HAVE_TESTSET
 	select ARCH_HAVE_MULTICPU
 	select ARCH_GLOBAL_IRQDISABLE
diff --git a/arch/risc-v/src/k210/Make.defs b/arch/risc-v/src/k210/Make.defs
index c8dd3cf..8b3032f 100644
--- a/arch/risc-v/src/k210/Make.defs
+++ b/arch/risc-v/src/k210/Make.defs
@@ -35,7 +35,7 @@
 HEAD_ASRC = k210_vectors.S
 
 # Specify our general Assembly files
-CHIP_ASRCS = k210_head.S up_syscall.S
+CHIP_ASRCS = k210_head.S
 
 CMN_ASRCS  += up_testset.S
 
@@ -66,3 +66,11 @@ ifeq ($(CONFIG_SMP), y)
 CHIP_CSRCS += k210_cpuidlestack.c k210_cpuindex.c
 CHIP_CSRCS += k210_cpupause.c k210_cpustart.c
 endif
+
+ifeq ($(CONFIG_BUILD_PROTECTED),y)
+CMN_CSRCS  += up_task_start.c up_pthread_start.c
+CMN_CSRCS  += up_signal_dispatch.c
+CMN_UASRCS += up_signal_handler.S
+
+CHIP_CSRCS += k210_userspace.c
+endif
diff --git a/arch/risc-v/src/k210/k210_allocateheap.c b/arch/risc-v/src/k210/k210_allocateheap.c
index eca9365..e2f420e 100644
--- a/arch/risc-v/src/k210/k210_allocateheap.c
+++ b/arch/risc-v/src/k210/k210_allocateheap.c
@@ -35,16 +35,65 @@
  ****************************************************************************/
 
 #include <nuttx/config.h>
+#include <nuttx/kmalloc.h>
+#include <nuttx/userspace.h>
 
 #include <arch/board/board.h>
 
 #include "k210.h"
 
 /****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define SRAM1_END CONFIG_RAM_END
+
+/****************************************************************************
  * Public Functions
  ****************************************************************************/
 
 /****************************************************************************
+ * Name: up_allocate_kheap
+ *
+ * Description:
+ *   For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel- and
+ *   user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function allocates
+ *   (and protects) the kernel-space heap.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP)
+void up_allocate_kheap(FAR void **heap_start, size_t *heap_size)
+{
+  /* Get the unaligned size and position of the user-space heap.
+   * This heap begins after the user-space .bss section at an offset
+   * of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment).
+   */
+
+  uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend;
+  ubase          += CONFIG_MM_KERNEL_HEAPSIZE;
+
+  size_t    usize = SRAM1_END - ubase;
+
+  DEBUGASSERT(ubase < (uintptr_t)SRAM1_END);
+
+  /* TODO: Adjust that size to account for MPU alignment requirements.
+   * NOTE that there is an implicit assumption that the SRAM1_END
+   * is aligned to the MPU requirement.
+   */
+
+  ubase = SRAM1_END - usize;
+
+  /* Return the kernel heap settings (i.e., the part of the heap region
+   * that was not dedicated to the user heap).
+   */
+
+  *heap_start = (FAR void *)USERSPACE->us_bssend;
+  *heap_size  = ubase - (uintptr_t)USERSPACE->us_bssend;
+}
+#endif
+
+/****************************************************************************
  * Name: up_addregion
  ****************************************************************************/
 
diff --git a/arch/risc-v/src/k210/k210_irq.c b/arch/risc-v/src/k210/k210_irq.c
index 6d064c3..7812351 100644
--- a/arch/risc-v/src/k210/k210_irq.c
+++ b/arch/risc-v/src/k210/k210_irq.c
@@ -122,6 +122,10 @@ void up_irqinitialize(void)
 
   irq_attach(K210_IRQ_ECALLM, up_swint, NULL);
 
+#ifdef CONFIG_BUILD_PROTECTED
+  irq_attach(K210_IRQ_ECALLU, up_swint, NULL);
+#endif
+
 #ifdef CONFIG_SMP
   /* Clear MSOFT for CPU0 */
 
@@ -237,8 +241,12 @@ void up_enable_irq(int irq)
 
 uint32_t up_get_newintctx(void)
 {
-  /* Set machine previous privilege mode to machine mode.
-   * Also set machine previous interrupt enable
+  /* Set machine previous privilege mode to machine mode. Reegardless of
+   * how NuttX is configured and of what kind of thread is being started.
+   * That is because all threads, even user-mode threads will start in
+   * kernel trampoline at nxtask_start() or pthread_start().
+   * The thread's privileges will be dropped before transitioning to
+   * user code. Also set machine previous interrupt enable.
    */
 
   return (MSTATUS_MPPM | MSTATUS_MPIE);
diff --git a/arch/risc-v/src/k210/k210_irq_dispatch.c b/arch/risc-v/src/k210/k210_irq_dispatch.c
index 04b16f0..ced4c40 100644
--- a/arch/risc-v/src/k210/k210_irq_dispatch.c
+++ b/arch/risc-v/src/k210/k210_irq_dispatch.c
@@ -70,7 +70,7 @@ void *k210_dispatch_irq(uint64_t vector, uint64_t *regs)
 
   /* Check if fault happened */
 
-  if (vector < 11)
+  if (vector < K210_IRQ_ECALLU)
     {
       up_fault((int)irq, regs);
     }
@@ -88,7 +88,7 @@ void *k210_dispatch_irq(uint64_t vector, uint64_t *regs)
 
   /* NOTE: In case of ecall, we need to adjust mepc in the context */
 
-  if (K210_IRQ_ECALLM == irq)
+  if (K210_IRQ_ECALLM == irq || K210_IRQ_ECALLU == irq)
     {
       *mepc += 4;
     }
diff --git a/arch/risc-v/src/k210/k210_start.c b/arch/risc-v/src/k210/k210_start.c
index f1289f1..194bbd1 100644
--- a/arch/risc-v/src/k210/k210_start.c
+++ b/arch/risc-v/src/k210/k210_start.c
@@ -41,6 +41,7 @@
 
 #include "up_arch.h"
 #include "k210_clockconfig.h"
+#include "k210_userspace.h"
 #include "k210.h"
 #include "chip.h"
 
@@ -137,6 +138,17 @@ void __k210_start(uint32_t mhartid)
 
   showprogress('C');
 
+  /* For the case of the separate user-/kernel-space build, perform whatever
+   * platform specific initialization of the user memory is required.
+   * Normally this just means initializing the user space .data and .bss
+   * segments.
+   */
+
+#ifdef CONFIG_BUILD_PROTECTED
+  k210_userspace();
+  showprogress('D');
+#endif
+
   /* Call nx_start() */
 
   nx_start();
diff --git a/arch/risc-v/src/k210/k210_userspace.c b/arch/risc-v/src/k210/k210_userspace.c
new file mode 100644
index 0000000..00575d2
--- /dev/null
+++ b/arch/risc-v/src/k210/k210_userspace.c
@@ -0,0 +1,90 @@
+/****************************************************************************
+ * arch/risc-v/src/k210/k210_userspace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <assert.h>
+
+#include <nuttx/userspace.h>
+
+#include "k210_userspace.h"
+
+#ifdef CONFIG_BUILD_PROTECTED
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: k210_userspace
+ *
+ * Description:
+ *   For the case of the separate user-/kernel-space build, perform whatever
+ *   platform specific initialization of the user memory is required.
+ *   Normally this just means initializing the user space .data and .bss
+ *   segments.
+ *
+ ****************************************************************************/
+
+void k210_userspace(void)
+{
+  uint8_t *src;
+  uint8_t *dest;
+  uint8_t *end;
+
+  /* Clear all of user-space .bss */
+
+  DEBUGASSERT(USERSPACE->us_bssstart != 0 && USERSPACE->us_bssend != 0 &&
+              USERSPACE->us_bssstart <= USERSPACE->us_bssend);
+
+  dest = (uint8_t *)USERSPACE->us_bssstart;
+  end  = (uint8_t *)USERSPACE->us_bssend;
+
+  while (dest != end)
+    {
+      *dest++ = 0;
+    }
+
+  /* Initialize all of user-space .data */
+
+  DEBUGASSERT(USERSPACE->us_datasource != 0 &&
+              USERSPACE->us_datastart != 0 && USERSPACE->us_dataend != 0 &&
+              USERSPACE->us_datastart <= USERSPACE->us_dataend);
+
+  src  = (uint8_t *)USERSPACE->us_datasource;
+  dest = (uint8_t *)USERSPACE->us_datastart;
+  end  = (uint8_t *)USERSPACE->us_dataend;
+
+  while (dest != end)
+    {
+      *dest++ = *src++;
+    }
+
+  /* TODO:
+   * Configure the MPU to permit user-space access to its FLASH and RAM
+   */
+}
+
+#endif /* CONFIG_BUILD_PROTECTED */
diff --git a/arch/risc-v/src/k210/k210_userspace.h b/arch/risc-v/src/k210/k210_userspace.h
new file mode 100644
index 0000000..b184ac2
--- /dev/null
+++ b/arch/risc-v/src/k210/k210_userspace.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+ * arch/risc-v/src/k210/k210_userspace.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_RISCV_SRC_K210_K210_USERSPACE_H
+#define __ARCH_RISCV_SRC_K210_K210_USERSPACE_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+/****************************************************************************
+ * Public Functions Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: k210_userspace
+ *
+ * Description:
+ *   For the case of the separate user-/kernel-space build, perform whatever
+ *   platform specific initialization of the user memory is required.
+ *   Normally this just means initializing the user space .data and .bss
+ *   segments.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_BUILD_PROTECTED
+void k210_userspace(void);
+#endif
+
+#endif /* __ARCH_RISCV_SRC_K210_K210_USERSPACE_H */
diff --git a/arch/risc-v/src/k210/up_schedulesigaction.c b/arch/risc-v/src/k210/up_schedulesigaction.c
index 24f3896..8ab12b6 100644
--- a/arch/risc-v/src/k210/up_schedulesigaction.c
+++ b/arch/risc-v/src/k210/up_schedulesigaction.c
@@ -152,13 +152,17 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
               tcb->xcp.saved_int_ctx    = CURRENT_REGS[REG_INT_CTX];
 
               /* Then set up to vector to the trampoline with interrupts
-               * disabled
+               * disabled.  The kernel-space trampoline must run in
+               * privileged thread mode.
                */
 
               CURRENT_REGS[REG_EPC]     = (uintptr_t)up_sigdeliver;
 
               int_ctx                     = CURRENT_REGS[REG_INT_CTX];
               int_ctx                    &= ~MSTATUS_MIE;
+#ifdef CONFIG_BUILD_PROTECTED
+              int_ctx                    |= MSTATUS_MPPM;
+#endif
 
               CURRENT_REGS[REG_INT_CTX] = int_ctx;
 
@@ -192,7 +196,8 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
           tcb->xcp.saved_int_ctx    = tcb->xcp.regs[REG_INT_CTX];
 
           /* Then set up to vector to the trampoline with interrupts
-           * disabled
+           * disabled.  We must already be in privileged thread mode to be
+           * here.
            */
 
           tcb->xcp.regs[REG_EPC]      = (uintptr_t)up_sigdeliver;
@@ -324,6 +329,9 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
 
                   int_ctx                   = CURRENT_REGS[REG_INT_CTX];
                   int_ctx                   &= ~MSTATUS_MIE;
+#ifdef CONFIG_BUILD_PROTECTED
+                  int_ctx                   |= MSTATUS_MPPM;
+#endif
 
                   CURRENT_REGS[REG_INT_CTX] = int_ctx;
 


[incubator-nuttx] 02/04: arch: risc-v: Add up_pthread_start.c and up_task_start.c to common dir

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch pr282
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 5fcde14cd1081ddbf7a641a701da51c38b7ab57c
Author: Masayuki Ishikawa <ma...@gmail.com>
AuthorDate: Fri Feb 14 16:08:36 2020 +0900

    arch: risc-v: Add up_pthread_start.c and up_task_start.c to common dir
---
 arch/risc-v/src/common/up_pthread_start.c | 70 +++++++++++++++++++++++++++++++
 arch/risc-v/src/common/up_task_start.c    | 70 +++++++++++++++++++++++++++++++
 2 files changed, 140 insertions(+)

diff --git a/arch/risc-v/src/common/up_pthread_start.c b/arch/risc-v/src/common/up_pthread_start.c
new file mode 100644
index 0000000..5b346c5
--- /dev/null
+++ b/arch/risc-v/src/common/up_pthread_start.c
@@ -0,0 +1,70 @@
+/****************************************************************************
+ * arch/risc-v/src/common/up_pthread_start.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <pthread.h>
+#include <nuttx/arch.h>
+
+#include "svcall.h"
+#include "up_internal.h"
+
+#if ((defined(CONFIG_BUILD_PROTECTED) && defined(__KERNEL__)) || \
+      defined(CONFIG_BUILD_KERNEL)) && !defined(CONFIG_DISABLE_PTHREAD)
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_pthread_start
+ *
+ * Description:
+ *   In this kernel mode build, this function will be called to execute a
+ *   pthread in user-space.  When the pthread is first started, a kernel-mode
+ *   stub will first run to perform some housekeeping functions.  This
+ *   kernel-mode stub will then be called transfer control to the user-mode
+ *   pthread.
+ *
+ *   Normally the a user-mode start-up stub will also execute before the
+ *   pthread actually starts.  See libc/pthread/pthread_startup.c
+ *
+ * Input Parameters:
+ *   entrypt - The user-space address of the pthread entry point
+ *   arg     - Standard argument for the pthread entry point
+ *
+ * Returned Value:
+ *   This function should not return.  It should call the user-mode start-up
+ *   stub and that stub should call pthread_exit if/when the user pthread
+ *   terminates.
+ *
+ ****************************************************************************/
+
+void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg)
+{
+  /* Let sys_call2() do all of the work */
+
+  sys_call2(SYS_pthread_start, (uintptr_t)entrypt, (uintptr_t)arg);
+}
+
+#endif /* (CONFIG_BUILD_PROTECTED || CONFIG_BUILD_KERNEL) && !CONFIG_DISABLE_PTHREAD */
diff --git a/arch/risc-v/src/common/up_task_start.c b/arch/risc-v/src/common/up_task_start.c
new file mode 100644
index 0000000..52920b2
--- /dev/null
+++ b/arch/risc-v/src/common/up_task_start.c
@@ -0,0 +1,70 @@
+/****************************************************************************
+ * arch/risc-v/src/common/up_task_start.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/arch.h>
+
+#include "svcall.h"
+#include "up_internal.h"
+
+#if defined(CONFIG_BUILD_PROTECTED) || defined(CONFIG_BUILD_KERNEL)
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_task_start
+ *
+ * Description:
+ *   In this kernel mode build, this function will be called to execute a
+ *   task in user-space.  When the task is first started, a kernel-mode
+ *   stub will first run to perform some housekeeping functions.  This
+ *   kernel-mode stub will then be called transfer control to the user-mode
+ *   task.
+ *
+ *   Normally the a user-mode start-up stub will also execute before the
+ *   task actually starts.  See libc/sched/task_startup.c
+ *
+ * Input Parameters:
+ *   taskentry - The user-space entry point of the task.
+ *   argc - The number of parameters being passed.
+ *   argv - The parameters being passed. These lie in kernel-space memory
+ *     and will have to be reallocated  in user-space memory.
+ *
+ * Returned Value:
+ *   This function should not return.  It should call the user-mode start-up
+ *   stub and that stub should call exit if/when the user task terminates.
+ *
+ ****************************************************************************/
+
+void up_task_start(main_t taskentry, int argc, FAR char *argv[])
+{
+  /* Let sys_call3() do all of the work */
+
+  sys_call3(SYS_task_start, (uintptr_t)taskentry, (uintptr_t)argc,
+            (uintptr_t)argv);
+}
+
+#endif /* CONFIG_BUILD_PROTECTED || CONFIG_BUILD_KERNEL */


[incubator-nuttx] 01/04: arch: risc-v: Add support for PROTECTED build to rv64gc

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch pr282
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 1a4ff4c4cdbb5e24f4af24a7f6c82f80ef9bfb66
Author: Masayuki Ishikawa <ma...@gmail.com>
AuthorDate: Fri Feb 14 16:04:19 2020 +0900

    arch: risc-v: Add support for PROTECTED build to rv64gc
---
 arch/risc-v/include/rv64gc/irq.h            |   9 +-
 arch/risc-v/include/rv64gc/syscall.h        | 160 +++++++++++++++++++--
 arch/risc-v/src/rv64gc/svcall.h             | 128 +++++++++++++++++
 arch/risc-v/src/rv64gc/up_initialstate.c    |  19 ---
 arch/risc-v/src/rv64gc/up_signal_dispatch.c |  76 ++++++++++
 arch/risc-v/src/rv64gc/up_signal_handler.S  |  97 +++++++++++++
 arch/risc-v/src/rv64gc/up_swint.c           | 213 +++++++++++++++++++++++++---
 arch/risc-v/src/rv64gc/up_syscall.S         | 111 ---------------
 8 files changed, 650 insertions(+), 163 deletions(-)

diff --git a/arch/risc-v/include/rv64gc/irq.h b/arch/risc-v/include/rv64gc/irq.h
index 939c43f..e4fbf62 100644
--- a/arch/risc-v/include/rv64gc/irq.h
+++ b/arch/risc-v/include/rv64gc/irq.h
@@ -285,10 +285,13 @@
 
 /* This structure represents the return state from a system call */
 
-#ifdef CONFIG_BUILD_KERNEL
+#ifdef CONFIG_LIB_SYSCALL
 struct xcpt_syscall_s
 {
   uint64_t sysreturn;   /* The return PC */
+#ifdef CONFIG_BUILD_PROTECTED
+  uint64_t int_ctx;     /* Interrupt context (i.e. mstatus) */
+#endif
 };
 #endif
 
@@ -316,7 +319,7 @@ struct xcptcontext
   uint64_t saved_epc;     /* Trampoline PC */
   uint64_t saved_int_ctx; /* Interrupt context with interrupts disabled. */
 
-#ifdef CONFIG_BUILD_KERNEL
+#ifdef CONFIG_BUILD_PROTECTED
   /* This is the saved address to use when returning from a user-space
    * signal handler.
    */
@@ -324,7 +327,7 @@ struct xcptcontext
   uint32_t sigreturn;
 #endif
 
-#ifdef CONFIG_BUILD_KERNEL
+#ifdef CONFIG_LIB_SYSCALL
   /* The following array holds information needed to return from each nested
    * system call.
    */
diff --git a/arch/risc-v/include/rv64gc/syscall.h b/arch/risc-v/include/rv64gc/syscall.h
index c6481ba..18f69b3 100644
--- a/arch/risc-v/include/rv64gc/syscall.h
+++ b/arch/risc-v/include/rv64gc/syscall.h
@@ -56,11 +56,21 @@
 
 #define SYS_syscall 0x00
 
+/* The SYS_signal_handler_return is executed here... its value is not always
+ * available in this context and so is assumed to be 7.
+ */
+
+#ifndef SYS_signal_handler_return
+#  define SYS_signal_handler_return (7)
+#elif SYS_signal_handler_return != 7
+#  error "SYS_signal_handler_return was assumed to be 7"
+#endif
+
 /* Configuration ************************************************************/
 
 /* SYS call 1 and 2 are defined for internal use by the RISC-V port (see
- * arch/risc-v/include/rv64gc/syscall.h).  In addition, SYS call 3 is the
- * return from a SYS call in kernel mode.  The first four syscall values must,
+ * arch/risc-v/include/rv64gc/syscall.h). In addition, SYS call 3 is the
+ * return from a SYS call in kernel mode. The first four syscall values must,
  * therefore, be reserved (0 is not used).
  */
 
@@ -144,7 +154,20 @@ extern "C"
  *
  ****************************************************************************/
 
-uintptr_t sys_call0(unsigned int nbr);
+static inline uintptr_t sys_call0(unsigned int nbr)
+{
+  register long r0 asm("a0") = (long)(nbr);
+
+  asm volatile
+    (
+     "ecall"
+     :: "r"(r0)
+     );
+
+  asm volatile("nop" : "=r"(r0));
+
+  return r0;
+}
 
 /****************************************************************************
  * Name: up_syscall1
@@ -154,7 +177,21 @@ uintptr_t sys_call0(unsigned int nbr);
  *
  ****************************************************************************/
 
-uintptr_t sys_call1(unsigned int nbr, uintptr_t parm1);
+static inline uintptr_t sys_call1(unsigned int nbr, uintptr_t parm1)
+{
+  register long r0 asm("a0") = (long)(nbr);
+  register long r1 asm("a1") = (long)(parm1);
+
+  asm volatile
+    (
+     "ecall"
+     :: "r"(r0), "r"(r1)
+     );
+
+  asm volatile("nop" : "=r"(r0));
+
+  return r0;
+}
 
 /****************************************************************************
  * Name: up_syscall2
@@ -164,7 +201,23 @@ uintptr_t sys_call1(unsigned int nbr, uintptr_t parm1);
  *
  ****************************************************************************/
 
-uintptr_t sys_call2(unsigned int nbr, uintptr_t parm1, uintptr_t parm2);
+static inline uintptr_t sys_call2(unsigned int nbr, uintptr_t parm1,
+                                  uintptr_t parm2)
+{
+  register long r0 asm("a0") = (long)(nbr);
+  register long r1 asm("a1") = (long)(parm1);
+  register long r2 asm("a2") = (long)(parm2);
+
+  asm volatile
+    (
+     "ecall"
+     :: "r"(r0), "r"(r1), "r"(r2)
+     );
+
+  asm volatile("nop" : "=r"(r0));
+
+  return r0;
+}
 
 /****************************************************************************
  * Name: up_syscall3
@@ -174,8 +227,24 @@ uintptr_t sys_call2(unsigned int nbr, uintptr_t parm1, uintptr_t parm2);
  *
  ****************************************************************************/
 
-uintptr_t sys_call3(unsigned int nbr, uintptr_t parm1, uintptr_t parm2,
-                    uintptr_t parm3);
+static inline uintptr_t sys_call3(unsigned int nbr, uintptr_t parm1,
+                                  uintptr_t parm2, uintptr_t parm3)
+{
+  register long r0 asm("a0") = (long)(nbr);
+  register long r1 asm("a1") = (long)(parm1);
+  register long r2 asm("a2") = (long)(parm2);
+  register long r3 asm("a3") = (long)(parm3);
+
+  asm volatile
+    (
+     "ecall"
+     :: "r"(r0), "r"(r1), "r"(r2), "r"(r3)
+     );
+
+  asm volatile("nop" : "=r"(r0));
+
+  return r0;
+}
 
 /****************************************************************************
  * Name: up_syscall4
@@ -185,8 +254,26 @@ uintptr_t sys_call3(unsigned int nbr, uintptr_t parm1, uintptr_t parm2,
  *
  ****************************************************************************/
 
-uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1, uintptr_t parm2,
-                    uintptr_t parm3, uintptr_t parm4);
+static inline uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1,
+                                  uintptr_t parm2, uintptr_t parm3,
+                                  uintptr_t parm4)
+{
+  register long r0 asm("a0") = (long)(nbr);
+  register long r1 asm("a1") = (long)(parm1);
+  register long r2 asm("a2") = (long)(parm2);
+  register long r3 asm("a3") = (long)(parm3);
+  register long r4 asm("a4") = (long)(parm4);
+
+  asm volatile
+    (
+     "ecall"
+     :: "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4)
+     );
+
+  asm volatile("nop" : "=r"(r0));
+
+  return r0;
+}
 
 /****************************************************************************
  * Name: up_syscall5
@@ -196,8 +283,59 @@ uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1, uintptr_t parm2,
  *
  ****************************************************************************/
 
-uintptr_t sys_call5(unsigned int nbr, uintptr_t parm1, uintptr_t parm2,
-                    uintptr_t parm3, uintptr_t parm4, uintptr_t parm5);
+static inline uintptr_t sys_call5(unsigned int nbr, uintptr_t parm1,
+                                  uintptr_t parm2, uintptr_t parm3,
+                                  uintptr_t parm4, uintptr_t parm5)
+{
+  register long r0 asm("a0") = (long)(nbr);
+  register long r1 asm("a1") = (long)(parm1);
+  register long r2 asm("a2") = (long)(parm2);
+  register long r3 asm("a3") = (long)(parm3);
+  register long r4 asm("a4") = (long)(parm4);
+  register long r5 asm("a5") = (long)(parm5);
+
+  asm volatile
+    (
+     "ecall"
+     :: "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5)
+     );
+
+  asm volatile("nop" : "=r"(r0));
+
+  return r0;
+}
+
+/****************************************************************************
+ * Name: up_syscall6
+ *
+ * Description:
+ *   System call SYS_ argument and six additional parameters.
+ *
+ ****************************************************************************/
+
+static inline uintptr_t sys_call6(unsigned int nbr, uintptr_t parm1,
+                                  uintptr_t parm2, uintptr_t parm3,
+                                  uintptr_t parm4, uintptr_t parm5,
+                                  uintptr_t parm6)
+{
+  register long r0 asm("a0") = (long)(nbr);
+  register long r1 asm("a1") = (long)(parm1);
+  register long r2 asm("a2") = (long)(parm2);
+  register long r3 asm("a3") = (long)(parm3);
+  register long r4 asm("a4") = (long)(parm4);
+  register long r5 asm("a5") = (long)(parm5);
+  register long r6 asm("a6") = (long)(parm6);
+
+  asm volatile
+    (
+     "ecall"
+     :: "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5), "r"(r6)
+     );
+
+  asm volatile("nop" : "=r"(r0));
+
+  return r0;
+}
 
 #undef EXTERN
 #ifdef __cplusplus
diff --git a/arch/risc-v/src/rv64gc/svcall.h b/arch/risc-v/src/rv64gc/svcall.h
new file mode 100644
index 0000000..27d2dc5
--- /dev/null
+++ b/arch/risc-v/src/rv64gc/svcall.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+ * arch/risc-v/src/rv64gc/svcall.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_RISCV_SRC_RV64GC_SVCALL_H
+#define __ARCH_RISCV_SRC_RV64GC_SVCALL_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#ifdef CONFIG_LIB_SYSCALL
+#  include <syscall.h>
+#endif
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Configuration ************************************************************/
+
+/* This logic uses three system calls {0,1,2} for context switching and one
+ * for the syscall return.  So a minimum of four syscall values must be
+ * reserved.  If CONFIG_BUILD_PROTECTED is defined, then four more syscall
+ * values must be reserved.
+ */
+
+#ifdef CONFIG_LIB_SYSCALL
+#  ifdef CONFIG_BUILD_PROTECTED
+#    ifndef CONFIG_SYS_RESERVED
+#      error "CONFIG_SYS_RESERVED must be defined to have the value 8"
+#    elif CONFIG_SYS_RESERVED != 8
+#      error "CONFIG_SYS_RESERVED must have the value 8"
+#    endif
+#  else
+#    ifndef CONFIG_SYS_RESERVED
+#      error "CONFIG_SYS_RESERVED must be defined to have the value 4"
+#    elif CONFIG_SYS_RESERVED != 4
+#      error "CONFIG_SYS_RESERVED must have the value 4"
+#    endif
+#  endif
+#endif
+
+/* RV64GC system calls ******************************************************/
+
+/* SYS call 0:
+ *
+ * int up_saveusercontext(uint32_t *saveregs);
+ */
+
+#define SYS_save_context          (0)
+
+/* SYS call 1:
+ *
+ * void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function;
+ */
+
+#define SYS_restore_context       (1)
+
+/* SYS call 2:
+ *
+ * void up_switchcontext(uint32_t *saveregs, uint32_t *restoreregs);
+ */
+
+#define SYS_switch_context        (2)
+
+#ifdef CONFIG_LIB_SYSCALL
+/* SYS call 3:
+ *
+ * void up_syscall_return(void);
+ */
+
+#define SYS_syscall_return        (3)
+
+#ifdef CONFIG_BUILD_PROTECTED
+/* SYS call 4:
+ *
+ * void up_task_start(main_t taskentry, int argc, FAR char *argv[])
+ *        noreturn_function;
+ */
+
+#define SYS_task_start            (4)
+
+/* SYS call 5:
+ *
+ * void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg)
+ *        noreturn_function
+ */
+
+#define SYS_pthread_start         (5)
+
+/* SYS call 6:
+ *
+ * void signal_handler(_sa_sigaction_t sighand, int signo,
+ *                     FAR siginfo_t *info, FAR void *ucontext);
+ */
+
+#define SYS_signal_handler        (6)
+
+/* SYS call 7:
+ *
+ * void signal_handler_return(void);
+ */
+
+#define SYS_signal_handler_return (7)
+
+#endif /* CONFIG_BUILD_PROTECTED */
+#endif /* CONFIG_LIB_SYSCALL */
+
+#endif /* __ARCH_RISCV_SRC_RV64GC_SVCALL_H */
diff --git a/arch/risc-v/src/rv64gc/up_initialstate.c b/arch/risc-v/src/rv64gc/up_initialstate.c
index f7a06a6..8fbad33 100644
--- a/arch/risc-v/src/rv64gc/up_initialstate.c
+++ b/arch/risc-v/src/rv64gc/up_initialstate.c
@@ -88,25 +88,6 @@ void up_initial_state(struct tcb_s *tcb)
 
   xcp->regs[REG_EPC]     = (uintptr_t)tcb->start;
 
-  /* If this task is running PIC, then set the PIC base register to the
-   * address of the allocated D-Space region.
-   */
-
-#ifdef CONFIG_PIC
-#  warning "Missing logic"
-#endif
-
-  /* Set privileged- or unprivileged-mode, depending on how NuttX is
-   * configured and what kind of thread is being started.
-   *
-   * If the kernel build is not selected, then all threads run in
-   * privileged thread mode.
-   */
-
-#ifdef CONFIG_BUILD_KERNEL
-#  warning "Missing logic"
-#endif
-
   /* Set the initial value of the interrupt context register.
    *
    * Since various RISC-V platforms use different interrupt
diff --git a/arch/risc-v/src/rv64gc/up_signal_dispatch.c b/arch/risc-v/src/rv64gc/up_signal_dispatch.c
new file mode 100644
index 0000000..a1daaca
--- /dev/null
+++ b/arch/risc-v/src/rv64gc/up_signal_dispatch.c
@@ -0,0 +1,76 @@
+/****************************************************************************
+ * arch/risc-v/src/rv64gc/up_signal_dispatch.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/arch.h>
+
+#include "svcall.h"
+#include "up_internal.h"
+
+#if (defined(CONFIG_BUILD_PROTECTED) && defined(__KERNEL__)) || \
+     defined(CONFIG_BUILD_KERNEL)
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_signal_dispatch
+ *
+ * Description:
+ *   In the kernel mode build, this function will be called to execute a
+ *   a signal handler in user-space.  When the signal is delivered, a
+ *   kernel-mode stub will first run to perform some housekeeping functions.
+ *   This kernel-mode stub will then be called transfer control to the user
+ *   mode signal handler by calling this function.
+ *
+ *   Normally the a user-mode signaling handling stub will also execute
+ *   before the ultimate signal handler is called.  See
+ *   arch/arm/src/armv[6\7]/up_signal_handler.  This function is the
+ *   user-space, signal handler trampoline function.  It is called from
+ *   up_signal_dispatch() in user-mode.
+ *
+ * Input Parameters:
+ *   sighand - The address user-space signal handling function
+ *   signo, info, and ucontext - Standard arguments to be passed to the
+ *     signal handling function.
+ *
+ * Returned Value:
+ *   None.  This function does not return in the normal sense.  It returns
+ *   via an architecture specific system call made by up_signal_handler().
+ *   However, this will look like a normal return by the caller of
+ *   up_signal_dispatch.
+ *
+ ****************************************************************************/
+
+void up_signal_dispatch(_sa_sigaction_t sighand, int signo,
+                        FAR siginfo_t *info, FAR void *ucontext)
+{
+  /* Let sys_call4() do all of the work */
+
+  sys_call4(SYS_signal_handler, (uintptr_t)sighand, (uintptr_t)signo,
+            (uintptr_t)info, (uintptr_t)ucontext);
+}
+
+#endif /* (CONFIG_BUILD_PROTECTED || CONFIG_BUILD_KERNEL) && !CONFIG_DISABLE_PTHREAD */
diff --git a/arch/risc-v/src/rv64gc/up_signal_handler.S b/arch/risc-v/src/rv64gc/up_signal_handler.S
new file mode 100644
index 0000000..231dcc8
--- /dev/null
+++ b/arch/risc-v/src/rv64gc/up_signal_handler.S
@@ -0,0 +1,97 @@
+/****************************************************************************
+ * arch/risc-v/src/rv64gc/up_signal_handler.S
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <arch/syscall.h>
+
+#if defined(CONFIG_BUILD_PROTECTED) && !defined(__KERNEL__)
+
+/****************************************************************************
+ * File info
+ ****************************************************************************/
+
+  .file   "up_signal_handler.S"
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_signal_handler
+ *
+ * Description:
+ *   This function is the user-space, signal handler trampoline function.  It
+ *   is called from up_signal_dispatch() in user-mode.
+ *
+ * Input Parameters:
+ *   a0 = sighand
+ *     The address user-space signal handling function
+ *   a1-a3 = signo, info, and ucontext
+ *     Standard arguments to be passed to the signal handling function.
+ *
+ * Returned Value:
+ *   None.  This function does not return in the normal sense.  It returns
+ *   via the SYS_signal_handler_return (see svcall.h)
+ *
+ ****************************************************************************/
+
+  .text
+  .globl up_signal_handler
+  .type  up_signal_handler, function
+
+up_signal_handler:
+
+  /* Save ra on the stack */
+
+  addi sp, sp, -8
+  sd   ra, (sp)
+
+  /* Call the signal handler */
+
+  mv   t0, a0  /* t0=sighand */
+  mv   a0, a1  /* a0=signo */
+  mv   a1, a2  /* a1=info */
+  mv   a2, a3  /* a2=ucontext */
+  jalr t0      /* Call the signal handler (modifies ra) */
+
+  /* Restore the register */
+
+  ld   ra, (sp)  /* Restore ra in sp */
+  addi sp, sp, 8
+
+  /* Execute the SYS_signal_handler_return SVCall (will not return) */
+
+  li   a0, SYS_signal_handler_return
+  ecall
+  nop
+
+  .size up_signal_handler, .-up_signal_handler
+  .end
+
+#endif /* CONFIG_BUILD_PROTECTED && !__KERNEL__ */
diff --git a/arch/risc-v/src/rv64gc/up_swint.c b/arch/risc-v/src/rv64gc/up_swint.c
index 59663a4..c45c7bc 100644
--- a/arch/risc-v/src/rv64gc/up_swint.c
+++ b/arch/risc-v/src/rv64gc/up_swint.c
@@ -41,15 +41,19 @@
 
 #include <stdint.h>
 #include <string.h>
-#include <syscall.h>
 #include <assert.h>
 #include <debug.h>
 
+#include <arch/irq.h>
 #include <nuttx/sched.h>
+#include <nuttx/userspace.h>
 
-#include <arch/irq.h>
+#ifdef CONFIG_LIB_SYSCALL
+#  include <syscall.h>
+#endif
 
 #include "signal/signal.h"
+#include "svcall.h"
 #include "up_internal.h"
 
 /****************************************************************************
@@ -93,15 +97,38 @@ static void up_registerdump(const uint64_t *regs)
  * Name: dispatch_syscall
  *
  * Description:
- *   Call the stub function corresponding to the system call.
+ *   Call the stub function corresponding to the system call.  NOTE the non-
+ *   standard parameter passing:
+ *
+ *     A0 = SYS_ call number
+ *     A1 = parm0
+ *     A2 = parm1
+ *     A3 = parm2
+ *     A4 = parm3
+ *     A5 = parm4
+ *     A6 = parm5
  *
  ****************************************************************************/
 
-#ifdef CONFIG_BUILD_KERNEL
+#ifdef CONFIG_LIB_SYSCALL
 static void dispatch_syscall(void) naked_function;
 static void dispatch_syscall(void)
 {
-#  error "Missing logic"
+  asm volatile
+    (
+     " addi sp, sp, -8\n"         /* Create a stack frame to hold ra */
+     " sd   ra, 0(sp)\n"          /* Save ra in the stack frame */
+     " la   t0, g_stublookup\n"   /* t0=The base of the stub lookup table */
+     " slli a0, a0, 3\n"          /* a0=Offset for the stub lookup table */
+     " add  t0, t0, a0\n"         /* t0=The address in the table */
+     " ld   t0, 0(t0)\n"          /* t0=The address of the stub for this syscall */
+     " jalr ra, t0\n"             /* Call the stub (modifies ra) */
+     " ld   ra, 0(sp)\n"          /* Restore ra */
+     " addi sp, sp, 8\n"          /* Destroy the stack frame */
+     " mv   a2, a0\n"             /* a2=Save return value in a0 */
+     " li   a0, 3\n"              /* a0=SYS_syscall_return (3) */
+     " ecall"                     /* Return from the syscall */
+  );
 }
 #endif
 
@@ -184,7 +211,7 @@ int up_swint(int irq, FAR void *context, FAR void *arg)
         }
         break;
 
-      /* A0=SYS_syscall_return: This a switch context command:
+      /* A0=SYS_syscall_return: This is a SYSCALL return command:
        *
        *   void up_sycall_return(void);
        *
@@ -196,7 +223,7 @@ int up_swint(int irq, FAR void *context, FAR void *arg)
        * unprivileged thread mode.
        */
 
-#ifdef CONFIG_BUILD_KERNEL
+#ifdef CONFIG_LIB_SYSCALL
       case SYS_syscall_return:
         {
           struct tcb_s *rtcb = sched_self();
@@ -210,20 +237,162 @@ int up_swint(int irq, FAR void *context, FAR void *arg)
            * the original mode.
            */
 
-          CURRENT_REGS[REG_EPC] = rtcb->xcp.syscall[index].sysreturn;
-#error "Missing logic -- need to restore the original mode"
-          rtcb->xcp.nsyscalls     = index;
+          regs[REG_EPC]         = rtcb->xcp.syscall[index].sysreturn;
+#ifdef CONFIG_BUILD_PROTECTED
+          regs[REG_INT_CTX]      = rtcb->xcp.syscall[index].int_ctx;
+#endif
+
+          /* The return value must be in A0-A1.
+           * dispatch_syscall() temporarily moved the value for R0 into A2.
+           */
+
+          regs[REG_A0]         = regs[REG_A2];
+
+          /* Save the new SYSCALL nesting level */
+
+          rtcb->xcp.nsyscalls  = index;
 
           /* Handle any signal actions that were deferred while processing
            * the system call.
            */
 
-          rtcb->flags            &= ~TCB_FLAG_SYSCALL;
+          rtcb->flags          &= ~TCB_FLAG_SYSCALL;
           (void)nxsig_unmask_pendingsignal();
         }
         break;
 #endif
 
+      /* R0=SYS_task_start:  This a user task start
+       *
+       *   void up_task_start(main_t taskentry, int argc,
+       *                      FAR char *argv[]) noreturn_function;
+       *
+       * At this point, the following values are saved in context:
+       *
+       *   A0 = SYS_task_start
+       *   A1 = taskentry
+       *   A2 = argc
+       *   A3 = argv
+       */
+
+#ifdef CONFIG_BUILD_PROTECTED
+      case SYS_task_start:
+        {
+          /* Set up to return to the user-space task start-up function in
+           * unprivileged mode.
+           */
+
+          regs[REG_EPC]      = (uintptr_t)USERSPACE->task_startup & ~1;
+
+          regs[REG_A0]       = regs[REG_A1]; /* Task entry */
+          regs[REG_A1]       = regs[REG_A2]; /* argc */
+          regs[REG_A2]       = regs[REG_A3]; /* argv */
+
+          regs[REG_INT_CTX] &= ~MSTATUS_MPPM; /* User mode */
+        }
+        break;
+#endif
+
+      /* R0=SYS_pthread_start:  This a user pthread start
+       *
+       *   void up_pthread_start(pthread_startroutine_t entrypt,
+       *                         pthread_addr_t arg) noreturn_function;
+       *
+       * At this point, the following values are saved in context:
+       *
+       *   R0 = SYS_pthread_start
+       *   R1 = entrypt
+       *   R2 = arg
+       */
+
+#if defined(CONFIG_BUILD_PROTECTED) && !defined(CONFIG_DISABLE_PTHREAD)
+      case SYS_pthread_start:
+        {
+          /* Set up to return to the user-space pthread start-up function in
+           * unprivileged mode.
+           */
+
+          regs[REG_EPC]      = (uintptr_t)USERSPACE->pthread_startup & ~1;
+
+          /* Change the parameter ordering to match the expectation of struct
+           * userpace_s pthread_startup:
+           */
+
+          regs[REG_A0]       = regs[REG_A1];  /* pthread entry */
+          regs[REG_A1]       = regs[REG_A2];  /* arg */
+          regs[REG_INT_CTX] &= ~MSTATUS_MPPM; /* User mode */
+        }
+        break;
+#endif
+
+      /* R0=SYS_signal_handler:  This a user signal handler callback
+       *
+       * void signal_handler(_sa_sigaction_t sighand, int signo,
+       *                     FAR siginfo_t *info, FAR void *ucontext);
+       *
+       * At this point, the following values are saved in context:
+       *
+       *   R0 = SYS_signal_handler
+       *   R1 = sighand
+       *   R2 = signo
+       *   R3 = info
+       *   R4 = ucontext
+       */
+
+#ifdef CONFIG_BUILD_PROTECTED
+      case SYS_signal_handler:
+        {
+          struct tcb_s *rtcb   = sched_self();
+
+          /* Remember the caller's return address */
+
+          DEBUGASSERT(rtcb->xcp.sigreturn == 0);
+          rtcb->xcp.sigreturn  = regs[REG_EPC];
+
+          /* Set up to return to the user-space pthread start-up function in
+           * unprivileged mode.
+           */
+
+          regs[REG_EPC]      = (uintptr_t)USERSPACE->signal_handler & ~1;
+          regs[REG_INT_CTX] &= ~MSTATUS_MPPM; /* User mode */
+
+          /* Change the parameter ordering to match the expectation of struct
+           * userpace_s signal_handler.
+           */
+
+          regs[REG_A0]       = regs[REG_A1]; /* sighand */
+          regs[REG_A1]       = regs[REG_A2]; /* signal */
+          regs[REG_A2]       = regs[REG_A3]; /* info */
+          regs[REG_A3]       = regs[REG_A4]; /* ucontext */
+        }
+        break;
+#endif
+
+      /* R0=SYS_signal_handler_return:  This a user signal handler callback
+       *
+       *   void signal_handler_return(void);
+       *
+       * At this point, the following values are saved in context:
+       *
+       *   R0 = SYS_signal_handler_return
+       */
+
+#ifdef CONFIG_BUILD_PROTECTED
+      case SYS_signal_handler_return:
+        {
+          struct tcb_s *rtcb   = sched_self();
+
+          /* Set up to return to the kernel-mode signal dispatching logic. */
+
+          DEBUGASSERT(rtcb->xcp.sigreturn != 0);
+          regs[REG_EPC]        = rtcb->xcp.sigreturn & ~1;
+          regs[REG_INT_CTX]   |= MSTATUS_MPPM; /* Machine mode */
+
+          rtcb->xcp.sigreturn  = 0;
+        }
+        break;
+#endif
+
       /* This is not an architecture-specify system call.  If NuttX is built
        * as a standalone kernel with a system call interface, then all of the
        * additional system calls must be handled as in the default case.
@@ -231,7 +400,7 @@ int up_swint(int irq, FAR void *context, FAR void *arg)
 
       default:
         {
-#ifdef CONFIG_BUILD_KERNEL
+#ifdef CONFIG_LIB_SYSCALL
           FAR struct tcb_s *rtcb = sched_self();
           int index = rtcb->xcp.nsyscalls;
 
@@ -247,20 +416,26 @@ int up_swint(int irq, FAR void *context, FAR void *arg)
 
           /* Setup to return to dispatch_syscall in privileged mode. */
 
-          rtcb->xcpsyscall[index].sysreturn = regs[REG_EPC];
-#error "Missing logic -- Need to save mode"
+          rtcb->xcp.syscall[index].sysreturn  = regs[REG_EPC];
+#ifdef CONFIG_BUILD_PROTECTED
+          rtcb->xcp.syscall[index].int_ctx     = regs[REG_INT_CTX];
+#endif
+
           rtcb->xcp.nsyscalls  = index + 1;
 
-          regs[REG_EPC]        = (uint32_t)dispatch_syscall;
-#error "Missing logic -- Need to set privileged mode"
+          regs[REG_EPC]        = (uintptr_t)dispatch_syscall & ~1;
+
+#ifdef CONFIG_BUILD_PROTECTED
+          regs[REG_INT_CTX]   |= MSTATUS_MPPM; /* Machine mode */
+#endif
 
-          /* Offset R0 to account for the reserved values */
+          /* Offset A0 to account for the reserved values */
 
-          CURRENT_REGS[REG_A0] -= CONFIG_SYS_RESERVED;
+          regs[REG_A0]        -= CONFIG_SYS_RESERVED;
 
           /* Indicate that we are in a syscall handler. */
 
-          rtcb->flags            |= TCB_FLAG_SYSCALL;
+          rtcb->flags         |= TCB_FLAG_SYSCALL;
 #else
           svcerr("ERROR: Bad SYS call: %d\n", regs[REG_A0]);
 #endif
diff --git a/arch/risc-v/src/rv64gc/up_syscall.S b/arch/risc-v/src/rv64gc/up_syscall.S
deleted file mode 100644
index c28094a..0000000
--- a/arch/risc-v/src/rv64gc/up_syscall.S
+++ /dev/null
@@ -1,111 +0,0 @@
-/****************************************************************************
- * arch/riscv/src/rv64gc/up_syscall.S
- *
- *   Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@nuttx.org>
- *
- *   Modified for RISC-V:
- *
- *   Copyright (C) 2016 Ken Pettit. All rights reserved.
- *   Author: Ken Pettit <pe...@gmail.com>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- *    used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- ****************************************************************************/
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-/****************************************************************************
- * Public Symbols
- ****************************************************************************/
-
-	.file	"up_syscall0.S"
-	.global sys_call0
-	.global sys_call1
-	.global sys_call2
-	.global sys_call3
-	.global sys_call4
-	.global sys_call5
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: up_syscall0, up_syscall1, up_syscall2, up_syscall3
- *
- * Description:
- *   up_syscall0 - System call SYS_ argument and no additional parameters.
- *   up_syscall1 - System call SYS_ argument and one additional parameter.
- *   up_syscall2 - System call SYS_ argument and two additional parameters.
- *   up_syscall3 - System call SYS_ argument and three additional parameters.
- *   up_syscall4 - System call SYS_ argument and four additional parameters.
- *   up_syscall5 - System call SYS_ argument and five additional parameters.
- *
- * Assumption:
- *   All interrupts are disabled except for the software interrupts.
- *
- ****************************************************************************/
-
-	.text
-
-sys_call0:	/* a0 holds the syscall number */
-sys_call1:	/* a0 holds the syscall number, argument in a1 */
-sys_call2:	/* a0 holds the syscall number, arguments in a1 and a2 */
-sys_call3:	/* a0 holds the syscall number, arguments in a1, a2, and a3 */
-sys_call4:	/* a0 holds the syscall number, arguments in a1, a2, a3 and a4 */
-sys_call5:	/* a0 holds the syscall number, arguments in a1, a2, a3, a4 and a5 */
-
-	/* Issue the ECALL opcode to perform a SW interrupt to the OS */
-
-   ecall
-
-	/* The actual interrupt may not a occur for a few more cycles.  Let's
-	 * put a few nop's here in hope that the SW interrupt occurs during
-	 * the sequence of nops.
-	 */
-
-	nop
-	nop
-
-	/* Then return with the result of the software interrupt in v0 */
-
-	ret
-	nop