Fix some ARMv7-M syscall logic

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5736 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2013-03-12 21:53:18 +00:00
parent e6c40405c4
commit 93967f8b7f
11 changed files with 78 additions and 55 deletions

View File

@ -699,10 +699,10 @@ endif
clean: subdir_clean
$(call DELFILE, $(BIN))
$(call DELFILE, nuttx.*)
$(call DELFILE, mm_test)
$(call DELFILE, *.map)
$(call DELFILE, _SAVED_APPS_config)
$(call DELFILE, nuttx-export*)
$(call DELFILE, nuttx_user*)
$(call CLEAN)
subdir_distclean:

View File

@ -704,10 +704,10 @@ endif
clean: subdir_clean
$(call DELFILE, $(BIN))
$(call DELFILE, nuttx.*)
$(call DELFILE, mm_test)
$(call DELFILE, *.map)
$(call DELFILE, _SAVED_APPS_config)
$(call DELFILE, nuttx-export*)
$(call DELFILE, nuttx_user*)
$(call CLEAN)
subdir_distclean:

View File

@ -127,8 +127,11 @@ struct xcptcontext
#endif
#ifdef CONFIG_NUTTX_KERNEL
/* The following holds the return address from a system call */
/* The following holds the return address and the exc_return value needed
* return from a system call.
*/
uint32_t excreturn;
uint32_t sysreturn;
#endif

View File

@ -1,7 +1,7 @@
/****************************************************************************
* arch/arm/src/armv7-m/up_svcall.c
*
* Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved.
* Copyright (C) 2009, 2011-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -151,7 +151,11 @@ int up_svcall(int irq, FAR void *context)
svcdbg(" R8: %08x %08x %08x %08x %08x %08x %08x %08x\n",
regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11],
regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]);
svcdbg(" PSR=%08x\n", regs[REG_XPSR]);
#ifdef REG_EXC_RETURN
svcdbg(" PSR: %08x LR: %08x\n", regs[REG_XPSR], current_regs[REG_EXC_RETURN]);
#else
svcdbg(" PSR: %08x\n", regs[REG_XPSR]);
#endif
/* Handle the SVCall according to the command in R0 */
@ -246,23 +250,22 @@ int up_svcall(int irq, FAR void *context)
{
struct tcb_s *rtcb = sched_self();
/* Make sure that we got here from a privileged thread and
* that there is a saved syscall return address.
*/
/* Make sure that there is a saved syscall return address. */
DEBUGASSERT(rtcb->xcp.sysreturn != 0 &&
regs[REG_EXC_RETURN] == EXC_RETURN_PRIVTHR);
svcdbg("sysreturn: %08x excreturn: %08x\n",
rtcb->xcp.sysreturn, rtcb->xcp.excreturn);
DEBUGASSERT(rtcb->xcp.sysreturn != 0);
/* Setup to return to the saved syscall return address in
* unprivileged mode.
* the original mode.
*/
current_regs[REG_PC] = rtcb->xcp.sysreturn;
current_regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR;
current_regs[REG_EXC_RETURN] = rtcb->xcp.excreturn;
rtcb->xcp.sysreturn = 0;
/* The return value must be in R0-R1. dispatch_syscall() temporarily
* moved the value to R2.
* moved the value for R0 to R2.
*/
current_regs[REG_R0] = current_regs[REG_R2];
@ -280,21 +283,22 @@ int up_svcall(int irq, FAR void *context)
#ifdef CONFIG_NUTTX_KERNEL
FAR struct tcb_s *rtcb = sched_self();
/* Verify the the SYS call number is within range */
/* Verify that the SYS call number is within range */
DEBUGASSERT(current_regs[REG_R0] < SYS_maxsyscall);
/* Make sure that we got here from a unprivileged thread and that
* there is a no saved syscall return address.
/* Make sure that we got here that there is a no saved syscall
* return address. We cannot yet handle nested system calls.
*/
DEBUGASSERT(rtcb->xcp.sysreturn == 0 &&
regs[REG_EXC_RETURN] == EXC_RETURN_UNPRIVTHR);
DEBUGASSERT(rtcb->xcp.sysreturn == 0);
/* Setup to return to dispatch_syscall in privileged mode. */
rtcb->xcp.sysreturn = regs[REG_PC];
regs[REG_PC] = (uint32_t)dispatch_syscall;
rtcb->xcp.excreturn = current_regs[REG_EXC_RETURN];
current_regs[REG_PC] = (uint32_t)dispatch_syscall;
current_regs[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR;
/* Offset R0 to account for the reserved values */

View File

@ -239,19 +239,16 @@ int up_swint0(int irq, FAR void *context)
{
struct tcb_s *rtcb = sched_self();
/* Make sure that we got here from a privileged thread and
* that there is a saved syscall return address.
*/
/* Make sure that there is a saved syscall return address. */
#error "Missing logic -- need to test for privileged mode"
DEBUGASSERT(rtcb->xcp.sysreturn != 0 && ???);
DEBUGASSERT(rtcb->xcp.sysreturn != 0);
/* Setup to return to the saved syscall return address in
* unprivileged mode.
* the original mode.
*/
current_regs[REG_EPC] = rtcb->xcp.sysreturn;
#error "Missing logic -- need to set for unprivileged mode"
#error "Missing logic -- need to restore the original mode"
rtcb->sysreturn = 0;
}
break;
@ -267,20 +264,19 @@ int up_swint0(int irq, FAR void *context)
#ifdef CONFIG_NUTTX_KERNEL
FAR struct tcb_s *rtcb = sched_self();
/* Verify the the SYS call number is within range */
/* Verify that the SYS call number is within range */
DEBUGASSERT(current_regs[REG_A0] < SYS_maxsyscall);
/* Make sure that we got here from an unprivileged thread and that
* there is a no saved syscall return address.
/* Make sure that we got here that there is a no saved syscall
* return address. We cannot yet handle nested system calls.
*/
#error "Missing logic -- Need to set unprivileged mode"
DEBUGASSERT(rtcb->xcp.sysreturn == 0 && ???);
DEBUGASSERT(rtcb->xcp.sysreturn == 0);
/* Setup to return to dispatch_syscall in privileged mode. */
rtcb->sysreturn = regs[REG_EPC]
rtcb->sysreturn = regs[REG_EPC];
regs[REG_EPC] = (uint32_t)dispatch_syscall;
#error "Missing logic -- Need to set privileged mode"

View File

@ -342,6 +342,10 @@ CONFIGURATION
in FLASH. But loading the nuttx ELF does not harm the nuttx_user.elf
in FLASH. Conclusion: Always load nuttx_user.elf before nuttx.
Just to complicate matters, it is sometimes the case that you need
load objects twice to account for write failures. I have not yet
found a simple foolproof way to reliably get the code into FLASH.
nsh
---
Configures the NuttShell (nsh) located at examples/nsh. The

View File

@ -107,7 +107,7 @@ depend: .depend
clean:
$(call DELFILE, nuttx_user.elf)
$(call DELFILE, "$(TOPDIR)$(DELIM)nuttx_user.elf")
$(call DELFILE, "$(TOPDIR)$(DELIM)nuttx_user.*")
$(call DELFILE, "$(TOPDIR)$(DELIM)User.map")
$(call CLEAN)

View File

@ -1,7 +1,7 @@
############################################################################
# configs/sam3u-ek/kernel/Makefile
#
# Copyright (C) 2011 Gregory Nutt. All rights reserved.
# Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
@ -107,7 +107,7 @@ depend: .depend
clean:
$(call DELFILE, nuttx_user.elf)
$(call DELFILE, "$(TOPDIR)$(DELIM)nuttx_user.elf")
$(call DELFILE, "$(TOPDIR)$(DELIM)nuttx_user.*")
$(call DELFILE, "$(TOPDIR)$(DELIM)User.map")
$(call CLEAN)

View File

@ -40,7 +40,6 @@ CONFIG_HOST_LINUX=y
#
CONFIG_DEBUG=y
CONFIG_DEBUG_VERBOSE=y
# CONFIG_SYSLOG_ENABLE is not set
#
# Subsystem Debug Options
@ -74,7 +73,6 @@ CONFIG_ARCH_SIM=y
# CONFIG_ARCH_Z16 is not set
# CONFIG_ARCH_Z80 is not set
CONFIG_ARCH="sim"
CONFIG_BOARD_LOOPSPERMSEC=100
#
# Simulation Configuration Options
@ -103,6 +101,8 @@ CONFIG_BOARD_LOOPSPERMSEC=100
#
# Board Settings
#
CONFIG_BOARD_LOOPSPERMSEC=100
# CONFIG_ARCH_CALIBRATION is not set
CONFIG_DRAM_START=0x00000000
CONFIG_DRAM_SIZE=0
@ -133,6 +133,7 @@ CONFIG_ARCH_BOARD="sim"
#
# RTOS Features
#
# CONFIG_BOARD_INITIALIZE is not set
CONFIG_MSEC_PER_TICK=10
CONFIG_RR_INTERVAL=0
# CONFIG_SCHED_INSTRUMENTATION is not set
@ -149,8 +150,8 @@ CONFIG_MUTEX_TYPES=y
# CONFIG_FDCLONE_DISABLE is not set
# CONFIG_FDCLONE_STDIO is not set
CONFIG_SDCLONE_DISABLE=y
# CONFIG_SCHED_WORKQUEUE is not set
CONFIG_SCHED_WAITPID=y
# CONFIG_SCHED_STARTHOOK is not set
# CONFIG_SCHED_ATEXIT is not set
# CONFIG_SCHED_ONEXIT is not set
CONFIG_USER_ENTRYPOINT="ostest_main"
@ -160,9 +161,7 @@ CONFIG_DISABLE_OS_API=y
# CONFIG_DISABLE_PTHREAD is not set
# CONFIG_DISABLE_SIGNALS is not set
# CONFIG_DISABLE_MQUEUE is not set
# CONFIG_DISABLE_MOUNTPOINT is not set
# CONFIG_DISABLE_ENVIRON is not set
CONFIG_DISABLE_POLL=y
#
# Signal Numbers
@ -199,6 +198,7 @@ CONFIG_PTHREAD_STACK_DEFAULT=8192
#
# Device Drivers
#
CONFIG_DISABLE_POLL=y
CONFIG_DEV_NULL=y
# CONFIG_DEV_ZERO is not set
# CONFIG_LOOP is not set
@ -249,6 +249,7 @@ CONFIG_SERIAL=y
#
# File system configuration
#
# CONFIG_DISABLE_MOUNTPOINT is not set
# CONFIG_FS_RAMMAP is not set
# CONFIG_FS_FAT is not set
# CONFIG_FS_NXFFS is not set
@ -257,6 +258,7 @@ CONFIG_SERIAL=y
#
# System Logging
#
# CONFIG_SYSLOG_ENABLE is not set
# CONFIG_SYSLOG is not set
#
@ -267,6 +269,7 @@ CONFIG_SERIAL=y
#
# Memory Management
#
# CONFIG_MM_MULTIHEAP is not set
# CONFIG_MM_SMALL is not set
CONFIG_MM_REGIONS=1
# CONFIG_GRAN is not set
@ -301,6 +304,8 @@ CONFIG_LIB_HOMEDIR="/"
# CONFIG_EOL_IS_BOTH_CRLF is not set
CONFIG_EOL_IS_EITHER_CRLF=y
# CONFIG_LIBC_EXECFUNCS is not set
CONFIG_POSIX_SPAWN_PROXY_STACKSIZE=1024
CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=2048
# CONFIG_LIBC_STRERROR is not set
# CONFIG_LIBC_PERROR_STDOUT is not set
CONFIG_ARCH_LOWPUTC=y
@ -309,8 +314,9 @@ CONFIG_LIB_SENDFILE_BUFSIZE=512
# CONFIG_ARCH_OPTIMIZED_FUNCTIONS is not set
#
# Non-standard Helper Functions
# Non-standard Library Support
#
# CONFIG_SCHED_WORKQUEUE is not set
# CONFIG_LIB_KBDCODEC is not set
#
@ -332,7 +338,6 @@ CONFIG_LIB_SENDFILE_BUFSIZE=512
#
# CONFIG_EXAMPLES_BUTTONS is not set
# CONFIG_EXAMPLES_CAN is not set
# CONFIG_EXAMPLES_CDCACM is not set
# CONFIG_EXAMPLES_COMPOSITE is not set
# CONFIG_EXAMPLES_DHCPD is not set
# CONFIG_EXAMPLES_ELF is not set
@ -348,7 +353,6 @@ CONFIG_LIB_SENDFILE_BUFSIZE=512
# CONFIG_EXAMPLES_MM is not set
# CONFIG_EXAMPLES_MOUNT is not set
# CONFIG_EXAMPLES_MODBUS is not set
# CONFIG_EXAMPLES_NETTEST is not set
# CONFIG_EXAMPLES_NSH is not set
# CONFIG_EXAMPLES_NULL is not set
# CONFIG_EXAMPLES_NX is not set
@ -387,8 +391,9 @@ CONFIG_EXAMPLES_OSTEST_RR_RUNS=10
# CONFIG_EXAMPLES_WATCHDOG is not set
#
# Interpreters
# Graphics Support
#
# CONFIG_TIFF is not set
#
# Interpreters
@ -418,11 +423,7 @@ CONFIG_EXAMPLES_OSTEST_RR_RUNS=10
# CONFIG_NETUTILS_WEBCLIENT is not set
#
# ModBus
#
#
# FreeModbus
# FreeModBus
#
# CONFIG_MODBUS is not set
@ -477,3 +478,7 @@ CONFIG_EXAMPLES_OSTEST_RR_RUNS=10
# Sysinfo
#
# CONFIG_SYSTEM_SYSINFO is not set
#
# USB Monitor
#

View File

@ -144,6 +144,7 @@ FAR struct file_struct *fs_fdopen(int fd, int oflags, FAR struct tcb_s *tcb)
{
tcb = sched_self();
}
DEBUGASSERT(tcb && tcb->group);
/* Verify that this is a valid file/socket descriptor and that the
@ -192,7 +193,11 @@ FAR struct file_struct *fs_fdopen(int fd, int oflags, FAR struct tcb_s *tcb)
/* Get the stream list from the TCB */
#if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
slist = tcb->group->tg_streamlist;
#else
slist = &tcb->group->tg_streamlist;
#endif
/* Find an unallocated FILE structure in the stream list */

View File

@ -237,6 +237,7 @@ void os_start(void)
slldbg("Entry\n");
/* Initialize RTOS Data ***************************************************/
/* Initialize all task lists */
dq_init(&g_readytorun);
@ -272,6 +273,7 @@ void os_start(void)
g_pidhash[ PIDHASH(0)].tcb = &g_idletcb.cmn;
g_pidhash[ PIDHASH(0)].pid = 0;
/* Initialize the IDLE task TCB *******************************************/
/* Initialize a TCB for this thread of execution. NOTE: The default
* value for most components of the g_idletcb are zero. The entire
* structure is set to zero. Then only the (potentially) non-zero
@ -298,6 +300,7 @@ void os_start(void)
up_initial_state(&g_idletcb.cmn);
/* Initialize RTOS facilities *********************************************/
/* Initialize the semaphore facility(if in link). This has to be done
* very early because many subsystems depend upon fully functional
* semaphores.
@ -344,12 +347,6 @@ void os_start(void)
}
#endif
/* Allocate the IDLE group and suppress child status. */
#ifdef HAVE_TASK_GROUP
(void)group_allocate(&g_idletcb);
#endif
/* Initialize the interrupt handling subsystem (if included) */
#ifdef CONFIG_HAVE_WEAKFUNCTIONS
@ -462,6 +459,13 @@ void os_start(void)
lib_initialize();
}
/* IDLE Group Initialization **********************************************/
/* Allocate the IDLE group and suppress child status. */
#ifdef HAVE_TASK_GROUP
(void)group_allocate(&g_idletcb);
#endif
/* Create stdout, stderr, stdin on the IDLE task. These will be
* inherited by all of the threads created by the IDLE task.
*/
@ -477,10 +481,12 @@ void os_start(void)
g_idletcb.cmn.group->tg_flags = GROUP_FLAG_NOCLDWAIT;
#endif
/* Bring Up the System ****************************************************/
/* Create initial tasks and bring-up the system */
(void)os_bringup();
/* The IDLE Loop **********************************************************/
/* When control is return to this point, the system is idle. */
sdbg("Beginning Idle Loop\n");