More Cortex-M0/NUC120 fixes

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5670 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2013-02-25 18:36:25 +00:00
parent 53e1ee95ae
commit a2ecc7083f
6 changed files with 66 additions and 46 deletions

View File

@ -50,18 +50,18 @@
* exception mechanism relies on this value to detect when the processor has
* completed an exception handler.
*
* Bits [31:28] of an EXC_RETURN value are always 1. When the processor loads a
* Bits [31:4] of an EXC_RETURN value are always 1. When the processor loads a
* value matching this pattern to the PC it detects that the operation is a not
* a normal branch operation and instead, that the exception is complete.
* Therefore, it starts the exception return sequence.
*
* Bits[4:0] of the EXC_RETURN value indicate the required return stack and eventual
* Bits[3:0] of the EXC_RETURN value indicate the required return stack and eventual
* processor mode. The remaining bits of the EXC_RETURN value should be set to 1.
*/
/* EXC_RETURN_BASE: Bits that are always set in an EXC_RETURN value. */
#define EXC_RETURN_BASE 0xffffffe1
#define EXC_RETURN_BASE 0xfffffff1
/* EXC_RETURN_PROCESS_STACK: The exception saved (and will restore) the hardware
* context using the process stack pointer (if not set, the context was saved
@ -72,20 +72,12 @@
#define EXC_RETURN_PROCESS_STACK (1 << EXC_RETURN_PROCESS_BITNO)
/* EXC_RETURN_THREAD_MODE: The exception will return to thread mode (if not set,
* return stays in handler mode)
* return stays in handler mode).
*/
#define EXC_RETURN_THREAD_BITNO (3)
#define EXC_RETURN_THREAD_MODE (1 << EXC_RETURN_THREAD_BITNO)
/* EXC_RETURN_STD_CONTEXT: The state saved on the stack does not include the
* volatile FP registers and FPSCR. If this bit is clear, the state does include
* these registers.
*/
#define EXC_RETURN_STD_BITNO (4)
#define EXC_RETURN_STD_CONTEXT (1 << EXC_RETURN_STD_BITNO)
/* EXC_RETURN_HANDLER: Return to handler mode. Exception return gets state from
* the main stack. Execution uses MSP after return.
*/
@ -104,15 +96,7 @@
#define EXC_RETURN_UNPRIVTHR 0xfffffffd
/* In the kernel build is not selected, then all threads run in privileged thread
* mode.
*/
#ifdef CONFIG_NUTTX_KERNEL
# define EXC_RETURN 0xfffffff9
#endif
/************************Th************************************************************
/************************************************************************************
* Inline Functions
************************************************************************************/

View File

@ -93,7 +93,7 @@ exception_common:
*/
mov r0, r14 /* Copy high register to low register */
lsl r1, r0, #(31 - EXC_RETURN_PROCESS_BITNO) /* Move to bit 31 */
lsl r0, #(31 - EXC_RETURN_PROCESS_BITNO) /* Move to bit 31 */
bmi 1f /* Test bit 31 */
mrs r1, msp /* R1=The main stack pointer */
b 2f
@ -191,7 +191,7 @@ exception_common:
/* Recover R8-R11 and EXEC_RETURN (5 registers) */
mov r2, #(4*REG_R8) /* R2=Offset to R8 storage */
sub r0, r1, r2 /* R0=Address of R8 storage */
add r0, r1, r2 /* R0=Address of R8 storage */
ldmia r0!, {r2-r6} /* Recover R8-R11 and R14 (5 registers)*/
mov r8, r2 /* Move to position in high registers */
mov r9, r3
@ -199,21 +199,20 @@ exception_common:
mov r11, r5
mov r14, r6 /* EXEC_RETURN */
/* Recover SP (R2), BASEPRI (R3), and R4-R7. The size of the sofware saved
* portion is 11 words. 5 were recovered above; 6 are recovered by the
* ldmia below. So adding (4*5) to r1 accounts for all of the software
* saved registers.
/* Recover SP (R2), BASEPRI (R3), and R4-R7. Determine the value of
* the stack pointer as it was on entry to the exception handler.
*/
ldmia r1!, {r2-r7} /* Recover R4-R7 + 2 temp values */
add r1, #(4*5) /* R1=Value of MSP/PSP on exception entry */
mov r1, #HW_XCPT_SIZE /* R1=Size of hardware-saved portion of the context array */
sub r1, r2, r1 /* R1=Value of MSP/PSP on exception entry */
/* Restore the stack pointer. The EXC_RETURN value tells us whether the
* context is on the MSP or PSP.
*/
mov r0, r14 /* Copy high register to low register */
lsl r1, r0, #(31 - EXC_RETURN_PROCESS_BITNO) /* Move to bit 31 */
lsl r0, #(31 - EXC_RETURN_PROCESS_BITNO) /* Move to bit 31 */
bmi 5f /* Test bit 31 */
msr msp, r1 /* R1=The main stack pointer */
b 6f

View File

@ -115,10 +115,10 @@ void up_initial_state(struct tcb_s *tcb)
xcp->regs[REG_PIC] = (uint32_t)tcb->dspace->region;
}
/* Make certain that bit 0 is set in the main entry address. This
* is only an issue when NXFLAT is enabled. NXFLAT doesn't know
* anything about thumb; the addresses that NXFLAT sets are based
* on file header info and won't have bit 0 set.
/* Make certain that bit 0 is set in the main entry address. This is
* only an issue when NXFLAT is enabled. NXFLAT doesn't know anything
* about thumb; the addresses that NXFLAT sets are based on file header
* info and won't have bit 0 set.
*/
#ifdef CONFIG_NXFLAT
@ -128,22 +128,24 @@ void up_initial_state(struct tcb_s *tcb)
/* Set privileged- or unprivileged-mode, depending on how NuttX is
* configured and what kind of thread is being started.
*
* If the kernel build is not selected, then all threads run in
* privileged thread mode.
*/
xcp->regs[REG_EXC_RETURN] = EXC_RETURN_BASE | EXC_RETURN_THREAD_MODE;
xcp->regs[REG_EXC_RETURN] |= EXC_RETURN_STD_CONTEXT;
#ifdef CONFIG_NUTTX_KERNEL
if ((tcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_KERNEL)
{
/* It is a normal task or a pthread. Set user mode */
xcp->regs[REG_EXC_RETURN] = EXC_RETURN_PROCESS_STACK;
xcp->regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR;
}
else
#endif /* CONFIG_NUTTX_KERNEL */
{
/* If the kernel build is not selected -OR- if this is a kernel
* thread, then start it in privileged thread mode.
*/
xcp->regs[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR;
}
/* Enable or disable interrupts, based on user configuration */

View File

@ -155,7 +155,7 @@ void up_initial_state(struct tcb_s *tcb)
{
/* It is a normal task or a pthread. Set user mode */
xcp->regs[REG_EXC_RETURN] = EXC_RETURN_PROCESS_STACK;
xcp->regs[REG_EXC_RETURN] |= EXC_RETURN_PROCESS_STACK;
}
#endif /* CONFIG_NUTTX_KERNEL */

View File

@ -63,18 +63,21 @@
#ifdef HAVE_SERIAL_CONSOLE
# if defined(CONFIG_UART0_SERIAL_CONSOLE)
# define NUC_CONSOLE_BASE NUC_UART0_BASE
# define NUC_CONSOLE_DEPTH UART0_FIFO_DEPTH
# define NUC_CONSOLE_BAUD CONFIG_UART0_BAUD
# define NUC_CONSOLE_BITS CONFIG_UART0_BITS
# define NUC_CONSOLE_PARITY CONFIG_UART0_PARITY
# define NUC_CONSOLE_2STOP CONFIG_UART0_2STOP
# elif defined(CONFIG_UART1_SERIAL_CONSOLE)
# define NUC_CONSOLE_BASE NUC_UART1_BASE
# define NUC_CONSOLE_DEPTH UART1_FIFO_DEPTH
# define NUC_CONSOLE_BAUD CONFIG_UART1_BAUD
# define NUC_CONSOLE_BITS CONFIG_UART1_BITS
# define NUC_CONSOLE_PARITY CONFIG_UART1_PARITY
# define NUC_CONSOLE_2STOP CONFIG_UART1_2STOP
# elif defined(CONFIG_UART2_SERIAL_CONSOLE)
# define NUC_CONSOLE_BASE NUC_UART2_BASE
# define NUC_CONSOLE_DEPTH UART2_FIFO_DEPTH
# define NUC_CONSOLE_BAUD CONFIG_UART2_BAUD
# define NUC_CONSOLE_BITS CONFIG_UART2_BITS
# define NUC_CONSOLE_PARITY CONFIG_UART2_PARITY
@ -97,6 +100,38 @@
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: nuc_console_ready
*
* Description:
* Wait until the console is ready to add another character to the TX
* FIFO.
*
*****************************************************************************/
#ifdef HAVE_SERIAL_CONSOLE
static inline void nuc_console_ready(void)
{
#if 1
/* Wait for the TX FIFO to be empty (excessive!) */
while ((getreg32(NUC_CONSOLE_BASE + NUC_UART_FSR_OFFSET) & UART_FSR_TX_EMPTY) == 0);
#else
uint32_t depth;
/* Wait until there is space in the TX FIFO */
do
{
register uint32_t regval = getreg32(NUC_CONSOLE_BASE + NUC_UART_FSR_OFFSET);
depth = (regval & UART_FSR_TX_POINTER_MASK) >> UART_FSR_TX_POINTER_SHIFT;
}
while (depth >= (NUC_CONSOLE_DEPTH-1));
#endif
}
#endif /* HAVE_SERIAL_CONSOLE */
/****************************************************************************
* Public Functions
****************************************************************************/
@ -293,9 +328,9 @@ void nuc_lowsetup(void)
void nuc_lowputc(uint32_t ch)
{
#ifdef HAVE_SERIAL_CONSOLE
/* Wait for the TX FIFO to be empty (excessive!) */
/* Wait for the TX FIFO to become available */
while ((getreg32(NUC_CONSOLE_BASE + NUC_UART_FSR_OFFSET) & UART_FSR_TX_EMPTY) == 0);
nuc_console_ready();
/* Then write the character to to the TX FIFO */

View File

@ -159,7 +159,7 @@ static struct nuc_dev_s g_uart0priv =
.irq = NUC_IRQ_UART0,
.parity = CONFIG_UART0_PARITY,
.bits = CONFIG_UART0_BITS,
.depth = UART0_FIFO_DEPTH,
.depth = (UART0_FIFO_DEPTH-1),
.stopbits2 = CONFIG_UART0_2STOP,
};
@ -190,7 +190,7 @@ static struct nuc_dev_s g_uart1priv =
.irq = NUC_IRQ_UART1,
.parity = CONFIG_UART1_PARITY,
.bits = CONFIG_UART1_BITS,
.depth = UART1_FIFO_DEPTH,
.depth = (UART1_FIFO_DEPTH-1),
.stopbits2 = CONFIG_UART1_2STOP,
};
@ -221,7 +221,7 @@ static struct nuc_dev_s g_uart2priv =
.irq = NUC_IRQ_UART2,
.parity = CONFIG_UART2_PARITY,
.bits = CONFIG_UART2_BITS,
.depth = UART2_FIFO_DEPTH,
.depth = (UART2_FIFO_DEPTH-1),
.stopbits2 = CONFIG_UART2_2STOP,
};