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:
parent
e6c40405c4
commit
93967f8b7f
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
#
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user