From 67a54fd52ed1170698c8a7583520b76c56543d27 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sun, 31 Aug 2014 07:15:46 -0600 Subject: [PATCH] ARMv7-A: A little more logic and a few more fixes for Cortex-A kernel build --- arch/arm/src/a1x/Make.defs | 4 ++ arch/arm/src/armv7-a/arm_syscall.c | 62 +++++++++-------- arch/arm/src/armv7-a/crt0.c | 105 +++++++++++++++++++++++++++++ arch/arm/src/sama5/Make.defs | 4 ++ sched/Kconfig | 10 +++ 5 files changed, 157 insertions(+), 28 deletions(-) create mode 100644 arch/arm/src/armv7-a/crt0.c diff --git a/arch/arm/src/a1x/Make.defs b/arch/arm/src/a1x/Make.defs index 0f35f7249f..92825cc124 100644 --- a/arch/arm/src/a1x/Make.defs +++ b/arch/arm/src/a1x/Make.defs @@ -82,6 +82,10 @@ CMN_CSRCS += arm_allocpage.c arm_checkmapping.c arm_pginitialize.c CMN_CSRCS += arm_va2pte.c endif +ifeq ($(CONFIG_BUILD_KERNEL),y) +CMN_CSRCS += up_task_start.c up_pthread_start.c up_stackframe.c +endif + ifeq ($(CONFIG_ARCH_ADDRENV),y) CMN_CSRCS += arm_addrenv.c endif diff --git a/arch/arm/src/armv7-a/arm_syscall.c b/arch/arm/src/armv7-a/arm_syscall.c index 32b122e42e..0295ffafef 100644 --- a/arch/arm/src/armv7-a/arm_syscall.c +++ b/arch/arm/src/armv7-a/arm_syscall.c @@ -48,8 +48,8 @@ #include #include +#include "arm.h" #include "svcall.h" -#include "up_internal.h" /**************************************************************************** * Pre-processor Definitions @@ -242,21 +242,21 @@ uint32_t *arm_syscall(uint32_t *regs) #ifdef CONFIG_BUILD_KERNEL case SYS_task_start: { - /* Set up to return to the user-space task start-up function in - * unprivileged mode. + /* Set up to return to the user-space _start function in + * unprivileged mode. We need: + * + * R0 = argc + * R1 = argv + * PC = taskentry + * CSPR = user mode */ - regs[REG_PC] = (uint32_t)USERSPACE->task_startup; - regval = regs[REG_CPSR] & ~PSR_MODE_MASK; - regs[REG_CPSR] = regval | PSR_MODE_USR; + regs[REG_PC] = regs[REG_R1]; + regs[REG_R0] = regs[REG_R2]; + regs[REG_R1] = regs[REG_R3]; - /* Change the parameter ordering to match the expectation of struct - * userpace_s task_startup: - */ - - regs[REG_R0] = regs[REG_R1]; /* Task entry */ - regs[REG_R1] = regs[REG_R2]; /* argc */ - regs[REG_R2] = regs[REG_R3]; /* argv */ + cpsr = regs[REG_CPSR] & ~PSR_MODE_MASK; + regs[REG_CPSR] = cpsr | PSR_MODE_USR; } break; #endif @@ -276,19 +276,19 @@ uint32_t *arm_syscall(uint32_t *regs) case SYS_pthread_start: { /* Set up to return to the user-space pthread start-up function in - * unprivileged mode. + * unprivileged mode. We need: + * + * R0 = arg + * PC = entrypt + * CSPR = user mode */ - regs[REG_PC] = (uint32_t)USERSPACE->pthread_startup; - regval = regs[REG_CPSR] & ~PSR_MODE_MASK; - regs[REG_CPSR] = regval | PSR_MODE_USR; - /* Change the parameter ordering to match the expectation of struct - * userpace_s pthread_startup: - */ + regs[REG_PC] = regs[REG_R1]; + regs[REG_R0] = regs[REG_R2]; - regs[REG_R0] = regs[REG_R1]; /* pthread entry */ - regs[REG_R1] = regs[REG_R2]; /* arg */ + cpsr = regs[REG_CPSR] & ~PSR_MODE_MASK; + regs[REG_CPSR] = cpsr | PSR_MODE_USR; } break; #endif @@ -310,6 +310,8 @@ uint32_t *arm_syscall(uint32_t *regs) #if defined(CONFIG_BUILD_KERNEL) && !defined(CONFIG_DISABLE_SIGNALS) case SYS_signal_handler: { +#warning Missing logic +#if 0 struct tcb_s *rtcb = sched_self(); /* Remember the caller's return address */ @@ -322,8 +324,8 @@ uint32_t *arm_syscall(uint32_t *regs) */ regs[REG_PC] = (uint32_t)USERSPACE->signal_handler; - regval = regs[REG_CPSR] & ~PSR_MODE_MASK; - regs[REG_CPSR] = regval | PSR_MODE_USR; + cpsr = regs[REG_CPSR] & ~PSR_MODE_MASK; + regs[REG_CPSR] = cpsr | PSR_MODE_USR; /* Change the parameter ordering to match the expectation of struct * userpace_s signal_handler. @@ -338,6 +340,7 @@ uint32_t *arm_syscall(uint32_t *regs) */ regs[REG_R3] = *(uint32_t*)(regs[REG_SP+4]); +#endif } break; #endif @@ -354,6 +357,8 @@ uint32_t *arm_syscall(uint32_t *regs) #if defined(CONFIG_BUILD_KERNEL) && !defined(CONFIG_DISABLE_SIGNALS) case SYS_signal_handler_return: { +#warning Missing logic +#if 0 struct tcb_s *rtcb = sched_self(); /* Set up to return to the kernel-mode signal dispatching logic. */ @@ -361,9 +366,10 @@ uint32_t *arm_syscall(uint32_t *regs) DEBUGASSERT(rtcb->xcp.sigreturn != 0); regs[REG_PC] = rtcb->xcp.sigreturn; - regval = regs[REG_CPSR] & ~PSR_MODE_MASK; - regs[REG_CPSR] = regval | PSR_MODE_SVC; + cpsr = regs[REG_CPSR] & ~PSR_MODE_MASK; + regs[REG_CPSR] = cpsr | PSR_MODE_SVC; rtcb->xcp.sigreturn = 0; +#endif } break; #endif @@ -399,8 +405,8 @@ uint32_t *arm_syscall(uint32_t *regs) regs[REG_PC] = (uint32_t)dispatch_syscall; #ifdef CONFIG_BUILD_KERNEL - regval = regs[REG_CPSR] & ~PSR_MODE_MASK; - regs[REG_CPSR] = regval | PSR_MODE_SVC; + cpsr = regs[REG_CPSR] & ~PSR_MODE_MASK; + regs[REG_CPSR] = cpsr | PSR_MODE_SVC; #endif /* Offset R0 to account for the reserved values */ diff --git a/arch/arm/src/armv7-a/crt0.c b/arch/arm/src/armv7-a/crt0.c new file mode 100644 index 0000000000..cda8944339 --- /dev/null +++ b/arch/arm/src/armv7-a/crt0.c @@ -0,0 +1,105 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/crt0.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include + +#ifdef CONFIG_BUILD_KERNEL + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +extern main_t main; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _start + * + * Description: + * This function is the low level entry point into the main thread of + * execution of a task. It receives initial control when the task is + * started and calls main entry point of the newly started task. + * + * Input Parameters: + * 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 + * main() function. If that function returns, this function will call + * exit. + * + ****************************************************************************/ + +void _start(int argc, FAR char *argv[]) +{ + int ret; + + /* Call C++ constructors */ + /* Setup so that C++ destructors called on task exit */ + /* REVISIT: Missing logic */ + + /* Call the main() entry point passing argc and argv. */ + + ret = main(argc, argc); + + /* Call exit() if/when the main() returns */ + + exit(ret); +} + +#endif /* CONFIG_BUILD_KERNEL */ diff --git a/arch/arm/src/sama5/Make.defs b/arch/arm/src/sama5/Make.defs index 9d5fc06ddd..e2ecb97162 100644 --- a/arch/arm/src/sama5/Make.defs +++ b/arch/arm/src/sama5/Make.defs @@ -84,6 +84,10 @@ CMN_CSRCS += arm_allocpage.c arm_checkmapping.c arm_pginitialize.c CMN_CSRCS += arm_va2pte.c endif +ifeq ($(CONFIG_BUILD_KERNEL),y) +CMN_CSRCS += up_task_start.c up_pthread_start.c up_stackframe.c +endif + ifeq ($(CONFIG_ARCH_ADDRENV),y) CMN_CSRCS += arm_addrenv.c endif diff --git a/sched/Kconfig b/sched/Kconfig index 02f35d5a0a..5068a4e969 100644 --- a/sched/Kconfig +++ b/sched/Kconfig @@ -261,14 +261,20 @@ config USER_INITPATH config INIT_SYMTAB string "Symbol table" default "NULL" + depends on !BUILD_PROTECTED && !BUILD_KERNEL ---help--- The name of othe global array that holds the exported symbol table. The special string "NULL" may be provided if there is no symbol table. Quotation marks will be stripped when config.h is generated. + NOTE: This setting cannot be used in protected or kernel builds. + Any kernel mode symbols tables would not be usable for resolving + symbols in user mode executables. + config INIT_NEXPORTS string "Symbol table size" default "0" + depends on !BUILD_PROTECTED && !BUILD_KERNEL ---help--- The size of the symbol table. NOTE that is is logically a numeric value but is represent by a string. That allows you to put @@ -276,6 +282,10 @@ config INIT_NEXPORTS symbol table size. Quotation marks will be stripped when config.h is generated. + NOTE: This setting cannot be used in protected or kernel builds. + Any kernel mode symbols tables would not be usable for resolving + symbols in user mode executables. + endif # INIT_FILEPATH config RR_INTERVAL