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:
parent
53e1ee95ae
commit
a2ecc7083f
@ -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
|
||||
************************************************************************************/
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user