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:03 UTC
[incubator-nuttx] 03/04: arch: risc-v: Add support for PROTECTED
build to k210
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;