diff options
-rw-r--r-- | nuttx/Kconfig | 7 | ||||
-rw-r--r-- | nuttx/arch/arm/include/armv6-m/irq.h | 5 | ||||
-rw-r--r-- | nuttx/arch/arm/include/armv7-m/irq.h | 2 | ||||
-rw-r--r-- | nuttx/arch/arm/src/armv6-m/up_svcall.c | 84 | ||||
-rw-r--r-- | nuttx/arch/arm/src/armv7-m/mpu.h | 24 | ||||
-rw-r--r-- | nuttx/arch/arm/src/armv7-m/up_memfault.c | 7 | ||||
-rw-r--r-- | nuttx/arch/arm/src/armv7-m/up_mpu.c | 178 | ||||
-rw-r--r-- | nuttx/arch/arm/src/armv7-m/up_svcall.c | 71 |
8 files changed, 269 insertions, 109 deletions
diff --git a/nuttx/Kconfig b/nuttx/Kconfig index 53fd667d6..5c7d9bd38 100644 --- a/nuttx/Kconfig +++ b/nuttx/Kconfig @@ -383,6 +383,13 @@ config DEBUG_GRAPHICS ---help--- Enable NX graphics debug SYSLOG output (disabled by default) +config DEBUG_SYSCALL + bool "Enable SYSCALL Debug Output" + default n + depends on NUTTX_KERNEL + ---help--- + Enable very low level output related to system calls + comment "Driver Debug Options" config DEBUG_LCD diff --git a/nuttx/arch/arm/include/armv6-m/irq.h b/nuttx/arch/arm/include/armv6-m/irq.h index f4bfea33f..db5c82913 100644 --- a/nuttx/arch/arm/include/armv6-m/irq.h +++ b/nuttx/arch/arm/include/armv6-m/irq.h @@ -164,8 +164,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 + * to return from a system call. + */ + uint32_t excreturn; uint32_t sysreturn; #endif diff --git a/nuttx/arch/arm/include/armv7-m/irq.h b/nuttx/arch/arm/include/armv7-m/irq.h index 72318aac8..7556d0747 100644 --- a/nuttx/arch/arm/include/armv7-m/irq.h +++ b/nuttx/arch/arm/include/armv7-m/irq.h @@ -128,7 +128,7 @@ struct xcptcontext #ifdef CONFIG_NUTTX_KERNEL /* The following holds the return address and the exc_return value needed - * return from a system call. + * to return from a system call. */ uint32_t excreturn; diff --git a/nuttx/arch/arm/src/armv6-m/up_svcall.c b/nuttx/arch/arm/src/armv6-m/up_svcall.c index f36e92297..06d6a61e1 100644 --- a/nuttx/arch/arm/src/armv6-m/up_svcall.c +++ b/nuttx/arch/arm/src/armv6-m/up_svcall.c @@ -65,10 +65,11 @@ /* Debug output from this file may interfere with context switching! To get * debug output you must enabled the following in your NuttX configuration: * - * CONFIG_DEBUG and CONFIG_DEBUG_SYSCALL + * - CONFIG_DEBUG and CONFIG_DEBUG_SYSCALL (shows only syscalls) + * - CONFIG_DEBUG and CONFIG_DEBUG_SVCALL (shows everything) */ -#ifdef CONFIG_DEBUG_SYSCALL +#if defined(CONFIG_DEBUG_SYSCALL) || defined(CONFIG_DEBUG_SVCALL) # define svcdbg(format, arg...) lldbg(format, ##arg) #else # define svcdbg(x...) @@ -140,31 +141,40 @@ static void dispatch_syscall(void) int up_svcall(int irq, FAR void *context) { uint32_t *regs = (uint32_t*)context; + uint32_t cmd; DEBUGASSERT(regs && regs == current_regs); + cmd = regs[REG_R0]; /* The SVCall software interrupt is called with R0 = system call command * and R1..R7 = variable number of arguments depending on the system call. */ - svcdbg("SVCALL Entry: regs: %p cmd: %d\n", regs, regs[REG_R0]); - svcdbg(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n", - regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3], - regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]); - 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]); -#ifdef CONFIG_NUTTX_KERNEL - svcdbg("xPSR: %08x BASEPRI: %08x EXEC_RETURN: %08x\n", - regs[REG_XPSR], regs[REG_BASEPRI], regs[REG_EXC_RETURN]); -#else - svcdbg("xPSR: %08x BASEPRI: %08x\n", - regs[REG_XPSR], regs[REG_BASEPRI]); +#if defined(CONFIG_DEBUG_SYSCALL) || defined(CONFIG_DEBUG_SVCALL) +# ifndef CONFIG_DEBUG_SVCALL + if (cmd > SYS_switch_context) +# endif + { + svcdbg("SVCALL Entry: regs: %p cmd: %d\n", regs, cmd); + svcdbg(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n", + regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3], + regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]); + 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]); +# ifdef CONFIG_NUTTX_KERNEL + svcdbg(" PSR: %08x BASEPRI: %08x EXC_RETURN: %08x\n", + regs[REG_XPSR], regs[REG_BASEPRI], regs[REG_EXC_RETURN]); +# else + svcdbg(" PSR: %08x BASEPRI: %08x\n", + regs[REG_XPSR], regs[REG_BASEPRI]); +# endif + } #endif /* Handle the SVCall according to the command in R0 */ - switch (regs[REG_R0]) + switch (cmd) { /* R0=SYS_save_context: This is a save context command: * @@ -249,23 +259,20 @@ 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); + DEBUGASSERT(rtcb->xcp.sysreturn != 0); /* Setup to return to the saved syscall return address in - * unprivileged mode. + * the original mode. */ regs[REG_PC] = rtcb->xcp.sysreturn; - regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR; + 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 into R2. */ regs[REG_R0] = regs[REG_R2]; @@ -295,7 +302,7 @@ int up_svcall(int irq, FAR void *context) regs[REG_PC] = (uint32_t)USERSPACE->task_startup; regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR; - /* Change the paramter ordering to match the expection of struct + /* Change the parameter ordering to match the expectation of struct * userpace_s task_startup: */ @@ -316,20 +323,21 @@ 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(regs[REG_R0] < SYS_maxsyscall); + DEBUGASSERT(cmd < 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 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]; + rtcb->xcp.excreturn = regs[REG_EXC_RETURN]; + regs[REG_PC] = (uint32_t)dispatch_syscall; regs[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR; @@ -345,9 +353,14 @@ int up_svcall(int irq, FAR void *context) /* Report what happened. That might difficult in the case of a context switch */ +#if defined(CONFIG_DEBUG_SYSCALL) || defined(CONFIG_DEBUG_SVCALL) +# ifndef CONFIG_DEBUG_SVCALL + if (cmd > SYS_switch_context) +# elif if (regs != current_regs) +# endif { - svcdbg("SVCall Return: Context switch!\n"); + svcdbg("SVCall Return:\n"); svcdbg(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n", current_regs[REG_R0], current_regs[REG_R1], current_regs[REG_R2], current_regs[REG_R3], current_regs[REG_R4], current_regs[REG_R5], current_regs[REG_R6], current_regs[REG_R7]); @@ -355,18 +368,21 @@ int up_svcall(int irq, FAR void *context) current_regs[REG_R8], current_regs[REG_R9], current_regs[REG_R10], current_regs[REG_R11], current_regs[REG_R12], current_regs[REG_R13], current_regs[REG_R14], current_regs[REG_R15]); #ifdef CONFIG_NUTTX_KERNEL - svcdbg("xPSR: %08x BASEPRI: %08x EXEC_RETURN: %08x\n", + svcdbg(" PSR: %08x BASEPRI: %08x EXC_RETURN: %08x\n", current_regs[REG_XPSR], current_regs[REG_BASEPRI], current_regs[REG_EXC_RETURN]); #else - svcdbg("xPSR: %08x BASEPRI: %08x\n", + svcdbg(" PSR: %08x BASEPRI: %08x\n", current_regs[REG_XPSR], current_regs[REG_BASEPRI]); #endif } +# ifdef CONFIG_DEBUG_SVCALL else { svcdbg("SVCall Return: %d\n", regs[REG_R0]); } +# endif +#endif return OK; } diff --git a/nuttx/arch/arm/src/armv7-m/mpu.h b/nuttx/arch/arm/src/armv7-m/mpu.h index 7e2e6bb77..e6929cecf 100644 --- a/nuttx/arch/arm/src/armv7-m/mpu.h +++ b/nuttx/arch/arm/src/armv7-m/mpu.h @@ -1,7 +1,7 @@ /************************************************************************************ * arch/arm/src/armv7-m/mpu.h * - * 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 @@ -173,9 +173,9 @@ uint8_t mpu_log2regionfloor(size_t size); * Name: mpu_subregion * * Description: - * Given the size of the (1) memory to be mapped and (2) the log2 size - * of the mapping to use, determine the minimal sub-region set to span - * that memory region. + * Given (1) the offset to the beginning of valid data, (2) the size of the + * memory to be mapped and (2) the log2 size of the mapping to use, determine + * the minimal sub-region set to span that memory region. * * Assumption: * l2size has the same properties as the return value from @@ -183,7 +183,7 @@ uint8_t mpu_log2regionfloor(size_t size); * ****************************************************************************/ -uint32_t mpu_subregion(size_t size, uint8_t l2size); +uint32_t mpu_subregion(uintptr_t base, size_t size, uint8_t l2size); /************************************************************************************ * Inline Functions @@ -264,7 +264,7 @@ static inline void mpu_userflash(uintptr_t base, size_t size) /* Select the region size and the sub-region map */ l2size = mpu_log2regionceil(size); - subregions = mpu_subregion(size, l2size); + subregions = mpu_subregion(base, size, l2size); /* The configure the region */ @@ -302,7 +302,7 @@ static inline void mpu_privflash(uintptr_t base, size_t size) /* Select the region size and the sub-region map */ l2size = mpu_log2regionceil(size); - subregions = mpu_subregion(size, l2size); + subregions = mpu_subregion(base, size, l2size); /* The configure the region */ @@ -340,7 +340,7 @@ static inline void mpu_userintsram(uintptr_t base, size_t size) /* Select the region size and the sub-region map */ l2size = mpu_log2regionceil(size); - subregions = mpu_subregion(size, l2size); + subregions = mpu_subregion(base, size, l2size); /* The configure the region */ @@ -379,7 +379,7 @@ static inline void mpu_privintsram(uintptr_t base, size_t size) /* Select the region size and the sub-region map */ l2size = mpu_log2regionceil(size); - subregions = mpu_subregion(size, l2size); + subregions = mpu_subregion(base, size, l2size); /* The configure the region */ @@ -418,7 +418,7 @@ static inline void mpu_userextsram(uintptr_t base, size_t size) /* Select the region size and the sub-region map */ l2size = mpu_log2regionceil(size); - subregions = mpu_subregion(size, l2size); + subregions = mpu_subregion(base, size, l2size); /* The configure the region */ @@ -458,7 +458,7 @@ static inline void mpu_privextsram(uintptr_t base, size_t size) /* Select the region size and the sub-region map */ l2size = mpu_log2regionceil(size); - subregions = mpu_subregion(size, l2size); + subregions = mpu_subregion(base, size, l2size); /* The configure the region */ @@ -498,7 +498,7 @@ static inline void mpu_peripheral(uintptr_t base, size_t size) /* Select the region size and the sub-region map */ l2size = mpu_log2regionceil(size); - subregions = mpu_subregion(size, l2size); + subregions = mpu_subregion(base, size, l2size); /* The configure the region */ diff --git a/nuttx/arch/arm/src/armv7-m/up_memfault.c b/nuttx/arch/arm/src/armv7-m/up_memfault.c index ab93c7697..a90f7cc74 100644 --- a/nuttx/arch/arm/src/armv7-m/up_memfault.c +++ b/nuttx/arch/arm/src/armv7-m/up_memfault.c @@ -103,7 +103,12 @@ int up_memfault(int irq, FAR void *context) mfdbg(" 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]); - mfdbg(" PSR=%08x\n", regs[REG_XPSR]); +#ifdef REG_EXC_RETURN + mfdbg(" PSR: %08x EXC_RETURN: %08x\n", + regs[REG_XPSR], regs[REG_EXC_RETURN]); +#else + mfdbg(" PSR: %08x\n", regs[REG_XPSR]); +#endif PANIC(OSERR_UNEXPECTEDISR); return OK; diff --git a/nuttx/arch/arm/src/armv7-m/up_mpu.c b/nuttx/arch/arm/src/armv7-m/up_mpu.c index 1c3416c88..5df3f4ec8 100644 --- a/nuttx/arch/arm/src/armv7-m/up_mpu.c +++ b/nuttx/arch/arm/src/armv7-m/up_mpu.c @@ -58,15 +58,28 @@ * Private Data ****************************************************************************/ -/* This set represents the set of disabled memory sub-regions. A bit set +/* These sets represent the set of disabled memory sub-regions. A bit set * corresponds to a disabled sub-region; the LS bit corresponds to the first - * region. The array is indexed by the number of subregions: 0 means no sub- - * regions (0xff), and 0 means all subregions but one (0x00). + * region. + * + * The g_ms_regionmask array is indexed by the number of subregions at the + * end of the region: 0 means no sub-regions are available(0xff) and 8 means + * all subregions are available (0x00). */ -static const uint8_t g_regionmap[9] = +static const uint8_t g_ms_regionmask[9] = { - 0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01, 0x00 + 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00 +}; + +/* The g_ls_regionmask array is indexed by the number of subregions at the + * beginning of the region: 0 means no sub-regions need be disabled (0x00) + * and 8 means all subregions must be disabled (0xff). + */ + +static const uint8_t g_ls_regionmask[9] = +{ + 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff }; /* The next available region number */ @@ -78,6 +91,107 @@ static uint8_t g_region; ****************************************************************************/ /**************************************************************************** + * Name: mpu_subregion_ms + * + * Description: + * Given (1) the size of the memory to be mapped and (2) the log2 size + * of the mapping to use, determine the minimal sub-region set at the + * to be disabled at the higher end of the region. + * + * Assumption: + * l2size has the same properties as the return value from + * mpu_log2regionceil() + * + ****************************************************************************/ + +static inline uint32_t mpu_subregion_ms(size_t size, uint8_t l2size) +{ + unsigned int nsrs; + uint32_t asize; + uint32_t mask; + + /* Examples with l2size = 12: + * + * Shifted Adjusted Number Sub-Region + * Size Mask Size Shift Sub-Regions Bitset + * 0x1000 0x01ff 0x1000 9 8 0x00 + * 0x0c00 0x01ff 0x0c00 9 6 0xc0 + * 0x0c40 0x01ff 0x0e00 9 7 0x80 + */ + + if (l2size < 32) + { + mask = ((1 << l2size)-1) >> 3; /* Shifted mask */ + } + + /* The 4Gb region size is a special case */ + + else + { + /* NOTE: There is no way to represent a 4Gb region size in the 32-bit + * input. + */ + + mask = 0x1fffffff; /* Shifted mask */ + } + + asize = (size + mask) & ~mask; /* Adjusted size */ + nsrs = asize >> (l2size-3); /* Number of subregions */ + return g_ms_regionmask[nsrs]; +} + +/**************************************************************************** + * Name: mpu_subregion_ls + * + * Description: + * Given (1) the offset to the beginning of data in the region and (2) the + * log2 size of the mapping to use, determine the minimal sub-region set + * to span that memory region sub-region set at the to be disabled at the + * higher end of the region + * + * Assumption: + * l2size has the same properties as the return value from + * mpu_log2regionceil() + * + ****************************************************************************/ + +static inline uint32_t mpu_subregion_ls(size_t offset, uint8_t l2size) +{ + unsigned int nsrs; + uint32_t aoffset; + uint32_t mask; + + /* Examples with l2size = 12: + * + * Shifted Adjusted Number Sub-Region + * Offset Mask Offset Shift Sub-Regions Bitset + * 0x0000 0x01ff 0x0000 9 8 0x00 + * 0x0400 0x01ff 0x0400 9 6 0x03 + * 0x02c0 0x01ff 0x0200 9 7 0x01 + */ + + if (l2size < 32) + { + mask = ((1 << l2size)-1) >> 3; /* Shifted mask */ + } + + /* The 4Gb region size is a special case */ + + else + { + /* NOTE: There is no way to represent a 4Gb region size in the 32-bit + * input. + */ + + mask = 0x1fffffff; /* Shifted mask */ + } + + aoffset = offset & ~mask; /* Adjusted offset */ + nsrs = aoffset >> (l2size-3); /* Number of subregions */ + return g_ls_regionmask[nsrs]; +} + +/**************************************************************************** * Public Functions ****************************************************************************/ @@ -115,9 +229,9 @@ uint8_t mpu_log2regionceil(size_t size) { uint8_t l2size; - /* The minimum permitted region size is 16 bytes (log2(16) = 4. */ + /* The minimum permitted region size is 32 bytes (log2(32) = 5. */ - for (l2size = 4; l2size < 32 && size > (1 << l2size); l2size++); + for (l2size = 5; l2size < 32 && size > (1 << l2size); l2size++); return l2size; } @@ -158,47 +272,45 @@ uint8_t mpu_log2regionfloor(size_t size) * ****************************************************************************/ -uint32_t mpu_subregion(size_t size, uint8_t l2size) +uint32_t mpu_subregion(uintptr_t base, size_t size, uint8_t l2size) { - unsigned int nsrs; - uint32_t asize; - uint32_t mask; + uint32_t mask; + size_t offset; + uint32_t ret; - /* Eight subregions are support. The representation is as an 8-bit + /* Eight subregions are supported. The representation is as an 8-bit * value with the LS bit corresponding to subregion 0. A bit is set * to disable the sub-region. * * l2size: Log2 of the actual region size is <= (1 << l2size); */ - DEBUGASSERT(l2size > 3 && size <= (1 << l2size)); + DEBUGASSERT(l2size > 4 && size <= (1 << l2size)); - /* Examples with l2size = 12: - * - * Shifted Adjusted Number Sub-Region - * Size Mask Size Shift Sub-Regions Bitset - * 0x1000 0x01ff 0x1000 9 8 0x00 - * 0x0c00 0x01ff 0x0c00 9 6 0x03 - * 0x0c40 0x01ff 0x0e00 9 7 0x01 + /* For region sizes of 32, 64, and 128 bytes, the effect of setting + * one or more bits of the SRD field to 1 is UNPREDICTABLE. */ - if (l2size < 32) + if (l2size < 8) { - mask = ((1 << l2size)-1) >> 3; /* Shifted mask */ + return 0; } - /* The 4Gb region size is a special case */ + /* Calculate the offset of the base address into the aligned region. */ - else - { - /* NOTE: There is no way to represent a 4Gb region size in the 32-bit - * input. - */ + mask = (1 << l2size) - 1; + offset = base & mask; - mask = 0x1fffffff; /* Shifted mask */ - } + /* Calculate the mask need to handle disabled subregions at the end of the + * region + */ - asize = (size + mask) & ~mask; /* Adjusted size */ - nsrs = asize >> (l2size-3); /* Number of subregions */ - return g_regionmap[nsrs]; + ret = mpu_subregion_ms(size + offset, l2size); + + /* Then OR in the mask need to handle disabled subretinos at the beginning + * of the region. + */ + + ret |= mpu_subregion_ls(offset, l2size); + return ret; } diff --git a/nuttx/arch/arm/src/armv7-m/up_svcall.c b/nuttx/arch/arm/src/armv7-m/up_svcall.c index 8f7efc1da..950ddd1d3 100644 --- a/nuttx/arch/arm/src/armv7-m/up_svcall.c +++ b/nuttx/arch/arm/src/armv7-m/up_svcall.c @@ -65,10 +65,11 @@ /* Debug output from this file may interfere with context switching! To get * debug output you must enabled the following in your NuttX configuration: * - * CONFIG_DEBUG and CONFIG_DEBUG_SYSCALL + * - CONFIG_DEBUG and CONFIG_DEBUG_SYSCALL (shows only syscalls) + * - CONFIG_DEBUG and CONFIG_DEBUG_SVCALL (shows everything) */ -#ifdef CONFIG_DEBUG_SYSCALL +#if defined(CONFIG_DEBUG_SYSCALL) || defined(CONFIG_DEBUG_SVCALL) # define svcdbg(format, arg...) lldbg(format, ##arg) #else # define svcdbg(x...) @@ -92,8 +93,6 @@ * Description: * Call the stub function corresponding to the system call. * - * Here we need to preserve registers: - * * R0 - Need not be preserved until after the stub is called. * R1-R3 - Need to be preserved until the stub is called. The values of * R0 and R1 returned by the stub must be preserved. @@ -141,29 +140,39 @@ static void dispatch_syscall(void) int up_svcall(int irq, FAR void *context) { uint32_t *regs = (uint32_t*)context; + uint32_t cmd; DEBUGASSERT(regs && regs == current_regs); + cmd = regs[REG_R0]; /* The SVCall software interrupt is called with R0 = system call command * and R1..R7 = variable number of arguments depending on the system call. */ - svcdbg("SVCALL Entry: regs: %p cmd: %d\n", regs, regs[REG_R0]); - svcdbg(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n", - regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3], - regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]); - 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]); -#ifdef REG_EXC_RETURN - svcdbg(" PSR: %08x LR: %08x\n", regs[REG_XPSR], regs[REG_EXC_RETURN]); -#else - svcdbg(" PSR: %08x\n", regs[REG_XPSR]); +#if defined(CONFIG_DEBUG_SYSCALL) || defined(CONFIG_DEBUG_SVCALL) +# ifndef CONFIG_DEBUG_SVCALL + if (cmd > SYS_switch_context) +# endif + { + svcdbg("SVCALL Entry: regs: %p cmd: %d\n", regs, cmd); + svcdbg(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n", + regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3], + regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]); + 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]); +# ifdef REG_EXC_RETURN + svcdbg(" PSR: %08x EXC_RETURN: %08x\n", + regs[REG_XPSR], regs[REG_EXC_RETURN]); +# else + svcdbg(" PSR: %08x\n", regs[REG_XPSR]); +# endif + } #endif /* Handle the SVCall according to the command in R0 */ - switch (regs[REG_R0]) + switch (cmd) { /* R0=SYS_save_context: This is a save context command: * @@ -216,7 +225,7 @@ int up_svcall(int irq, FAR void *context) * * At this point, the following values are saved in context: * - * R0 = 1 + * R0 = SYS_switch_context * R1 = saveregs * R2 = restoreregs * @@ -297,7 +306,7 @@ int up_svcall(int irq, FAR void *context) regs[REG_PC] = (uint32_t)USERSPACE->task_startup; regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR; - /* Change the paramter ordering to match the expection of struct + /* Change the parameter ordering to match the expectation of struct * userpace_s task_startup: */ @@ -320,10 +329,10 @@ int up_svcall(int irq, FAR void *context) /* Verify that the SYS call number is within range */ - DEBUGASSERT(regs[REG_R0] < SYS_maxsyscall); + DEBUGASSERT(cmd < SYS_maxsyscall); - /* Make sure that we got here that there is a no saved syscall - * return address. We cannot yet handle nested system calls. + /* Make sure that there is a no saved syscall return address. We + * cannot yet handle nested system calls. */ DEBUGASSERT(rtcb->xcp.sysreturn == 0); @@ -348,26 +357,34 @@ int up_svcall(int irq, FAR void *context) /* Report what happened. That might difficult in the case of a context switch */ +#if defined(CONFIG_DEBUG_SYSCALL) || defined(CONFIG_DEBUG_SVCALL) +# ifndef CONFIG_DEBUG_SVCALL + if (cmd > SYS_switch_context) +# elif if (regs != current_regs) +# endif { - svcdbg("SVCall Return: Context switch!\n"); + svcdbg("SVCall Return:\n"); svcdbg(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n", current_regs[REG_R0], current_regs[REG_R1], current_regs[REG_R2], current_regs[REG_R3], current_regs[REG_R4], current_regs[REG_R5], current_regs[REG_R6], current_regs[REG_R7]); svcdbg(" R8: %08x %08x %08x %08x %08x %08x %08x %08x\n", current_regs[REG_R8], current_regs[REG_R9], current_regs[REG_R10], current_regs[REG_R11], current_regs[REG_R12], current_regs[REG_R13], current_regs[REG_R14], current_regs[REG_R15]); -#ifdef REG_EXC_RETURN - svcdbg(" PSR: %08x LR: %08x\n", +# ifdef REG_EXC_RETURN + svcdbg(" PSR: %08x EXC_RETURN: %08x\n", current_regs[REG_XPSR], current_regs[REG_EXC_RETURN]); -#else - svcdbg(" PSR: %08x\n", current_regs[REG_XPSR]); -#endif +# else + svcdbg(" PSR: %08x\n", current_regs[REG_XPSR]); +# endif } +# ifdef CONFIG_DEBUG_SVCALL else { svcdbg("SVCall Return: %d\n", regs[REG_R0]); } +# endif +#endif return OK; } |