arch: risc-v: Add support for PROTECTED build to k210

This commit is contained in:
Masayuki Ishikawa 2020-02-14 16:10:50 +09:00 committed by patacongo
parent 5fcde14cd1
commit 382cc29c72
9 changed files with 232 additions and 7 deletions

View File

@ -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

View File

@ -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

View File

@ -35,15 +35,64 @@
****************************************************************************/
#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
****************************************************************************/

View File

@ -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);

View File

@ -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;
}

View File

@ -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();

View File

@ -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 */

View File

@ -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 */

View File

@ -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;