From b2126738cd2091cf5e079b1f08a8f7ec39720b55 Mon Sep 17 00:00:00 2001 From: Ramtin Amin Date: Fri, 4 Nov 2016 10:54:10 -0600 Subject: [PATCH] LM32: Fix implementation of up_irq_save() and up_irq_restore() --- arch/misoc/include/lm32/irq.h | 7 +++- arch/misoc/src/lm32/lm32_doirq.c | 4 +- arch/misoc/src/lm32/lm32_initialstate.c | 4 ++ arch/misoc/src/lm32/lm32_irq.c | 32 +++++++++++---- arch/misoc/src/lm32/lm32_swint.c | 1 + arch/misoc/src/lm32/lm32_vectors.S | 13 ++++-- configs/misoc/hello/defconfig | 53 +++++++++++++++++++++---- 7 files changed, 90 insertions(+), 24 deletions(-) diff --git a/arch/misoc/include/lm32/irq.h b/arch/misoc/include/lm32/irq.h index e73d3815d5c..782bb06ae9e 100644 --- a/arch/misoc/include/lm32/irq.h +++ b/arch/misoc/include/lm32/irq.h @@ -82,10 +82,11 @@ #define REG_X29_NDX 29 /* General-purpose/return address */ #define REG_X30_NDX 30 /* Exception address */ #define REG_X31_NDX 31 /* Breakpoint address */ +#define REG_X32_NDX 32 /* Reg IE */ /* Interrupt Context register */ -#define XCPTCONTEXT_REGS 32 +#define XCPTCONTEXT_REGS 33 #define XCPTCONTEXT_SIZE (4 * XCPTCONTEXT_REGS) #ifdef __ASSEMBLY__ @@ -121,6 +122,7 @@ # define REG_X29 (4*REG_X29_NDX) # define REG_X30 (4*REG_X30_NDX) # define REG_X31 (4*REG_X31_NDX) +# define REG_INT_CTX (4*REG_X32_NDX) #else # define REG_X0 REG_X0_NDX # define REG_X1 REG_X1_NDX @@ -154,6 +156,7 @@ # define REG_X29 REG_X29_NDX # define REG_X30 REG_X30_NDX # define REG_X31 REG_X31_NDX +# define REG_INT_CTX REG_X32_NDX #endif /* Register aliases */ @@ -176,6 +179,8 @@ #define REG_A6 REG_X7 #define REG_A7 REG_X8 +#define REG_IE REG_INT_CTX + /**************************************************************************** * Public Types ****************************************************************************/ diff --git a/arch/misoc/src/lm32/lm32_doirq.c b/arch/misoc/src/lm32/lm32_doirq.c index 6d44eeb95c1..e318a65adf7 100644 --- a/arch/misoc/src/lm32/lm32_doirq.c +++ b/arch/misoc/src/lm32/lm32_doirq.c @@ -58,9 +58,7 @@ uint32_t *lm32_doirq(int irq, uint32_t *regs) { board_autoled_on(LED_INIRQ); -#ifdef CONFIG_SUPPRESS_INTERRUPTS - PANIC(); -#else + /* Current regs non-zero indicates that we are processing an interrupt; * g_current_regs is also used to manage interrupt level context switches. * diff --git a/arch/misoc/src/lm32/lm32_initialstate.c b/arch/misoc/src/lm32/lm32_initialstate.c index e42107e1450..6064e186c84 100644 --- a/arch/misoc/src/lm32/lm32_initialstate.c +++ b/arch/misoc/src/lm32/lm32_initialstate.c @@ -99,6 +99,10 @@ void up_initial_state(struct tcb_s *tcb) xcp->regs[REG_EPC] = (uint32_t)tcb->start; + /* Initial state of IE: Interrupts enabled */ + + xcp->regs[REG_INT_CTX] = 1; + /* If this task is running PIC, then set the PIC base register to the * address of the allocated D-Space region. */ diff --git a/arch/misoc/src/lm32/lm32_irq.c b/arch/misoc/src/lm32/lm32_irq.c index 726d60c2970..d64623dfa3e 100644 --- a/arch/misoc/src/lm32/lm32_irq.c +++ b/arch/misoc/src/lm32/lm32_irq.c @@ -69,7 +69,7 @@ void lm32_irq_initialize(void) g_current_regs = NULL; - /* Enable interrupt */ + /* Enable interrupts */ irq_setie(1); } @@ -77,15 +77,22 @@ void lm32_irq_initialize(void) irqstate_t up_irq_save(void) { irqstate_t flags; - irq_setie(0); -#warning Return value MUST be the previous IE value. Returning 1 will not work. - return 1; + /* Get the previous value of IE */ + + flags = irq_getie(); + + /* Disable interrupts and return the previous interrupt state */ + + irq_setie(0); + return flags; } void up_irq_restore(irqstate_t flags) { - irq_setie(1); + /* Restore the interrupt state returned by up_save_irq() */ + + irq_setie(flags); } /**************************************************************************** @@ -99,8 +106,13 @@ void up_irq_restore(irqstate_t flags) void up_disable_irq(int irq) { irqstate_t flags; - flags = irq_getmask(); - flags &= ~(1 <= 0 && irq < NR_IRQS); + + /* Disable interrupts by clearing the bit that corresponds to the irq */ + + flags = irq_getmask(); + flags &= ~(1 << irq); irq_setmask(flags); } @@ -115,7 +127,11 @@ void up_disable_irq(int irq) void up_enable_irq(int irq) { irqstate_t flags; - flags = irq_getmask(); + DEBUGASSERT(irq >= 0 && irq < NR_IRQS); + + /* Enable interrupts by setting the bit that corresponds to the irq */ + + flags = irq_getmask(); flags |= (1 << irq); irq_setmask(flags); } diff --git a/arch/misoc/src/lm32/lm32_swint.c b/arch/misoc/src/lm32/lm32_swint.c index f8c7b280ee3..9e5f932d466 100644 --- a/arch/misoc/src/lm32/lm32_swint.c +++ b/arch/misoc/src/lm32/lm32_swint.c @@ -326,5 +326,6 @@ uint32_t *lm32_swint(int irq, FAR void *context) */ g_current_regs = NULL; + return regs; } diff --git a/arch/misoc/src/lm32/lm32_vectors.S b/arch/misoc/src/lm32/lm32_vectors.S index f672fa7fda8..f5010599979 100644 --- a/arch/misoc/src/lm32/lm32_vectors.S +++ b/arch/misoc/src/lm32/lm32_vectors.S @@ -151,7 +151,7 @@ _do_reset: bi os_start .save_all: - addi sp, sp, -132 + addi sp, sp, -136 sw (sp+REG_X0), r0 sw (sp+REG_X1), r1 sw (sp+REG_X2), r2 @@ -190,11 +190,14 @@ _do_reset: /* ra needs to be moved from initial stack location */ - lw r1, (sp+ 132) + lw r1, (sp+ 136) sw (sp+REG_RA), r1 - /* the 2nd argument is the regs pointer */ + /* get IE/REG_INT_CTX */ + rcsr r1, IE + sw (sp+REG_INT_CTX), r1 + /* the 2nd argument is the regs pointer */ addi r2, sp, 0 ret @@ -231,8 +234,10 @@ _do_reset: lw r29, (r1+REG_RA) lw r30, (r1+REG_EA) lw r31, (r1+REG_BA) + lw r1, (r1+REG_INT_CTX) + wcsr IE, r1 lw r1, (r1+REG_X1) - addi sp, sp, 132 + addi sp, sp, 136 eret /* This global variable is unsigned long g_idle_topstack and is diff --git a/configs/misoc/hello/defconfig b/configs/misoc/hello/defconfig index 99c0c9ef2ce..f7b4a0082d2 100644 --- a/configs/misoc/hello/defconfig +++ b/configs/misoc/hello/defconfig @@ -16,7 +16,7 @@ CONFIG_HOST_LINUX=y # # Build Configuration # -# CONFIG_APPS_DIR="../apps" +CONFIG_APPS_DIR="../apps" CONFIG_BUILD_FLAT=y # CONFIG_BUILD_2PASS is not set @@ -74,8 +74,9 @@ CONFIG_DEBUG_FEATURES=y # CONFIG_ARCH_HAVE_STACKCHECK is not set # CONFIG_ARCH_HAVE_HEAPCHECK is not set CONFIG_DEBUG_SYMBOLS=y -# CONFIG_ARCH_HAVE_CUSTOMOPT is not set +CONFIG_ARCH_HAVE_CUSTOMOPT=y CONFIG_DEBUG_NOOPT=y +# CONFIG_DEBUG_CUSTOMOPT is not set # CONFIG_DEBUG_FULLOPT is not set # @@ -88,8 +89,10 @@ CONFIG_DEBUG_NOOPT=y CONFIG_ARCH_MISOC=y # CONFIG_ARCH_RGMP is not set # CONFIG_ARCH_RENESAS is not set +# CONFIG_ARCH_RISCV is not set # CONFIG_ARCH_SIM is not set # CONFIG_ARCH_X86 is not set +# CONFIG_ARCH_XTENSA is not set # CONFIG_ARCH_Z16 is not set # CONFIG_ARCH_Z80 is not set CONFIG_ARCH="misoc" @@ -97,6 +100,15 @@ CONFIG_ARCH_CHIP="lm32" CONFIG_ARCH_CHIP_LM32=y # CONFIG_ARCH_CHIP_MOR1K is not set +# +# MISOC Peripheral Support +# +CONFIG_MISOC_HAVE_UART1=y +CONFIG_MISOC_UART1=y +CONFIG_MISOC_UART=y +CONFIG_MISOC_UART_RX_BUF_SIZE=64 +CONFIG_MISOC_UART_TX_BUF_SIZE=64 + # # Architecture Options # @@ -131,7 +143,8 @@ CONFIG_BOARD_LOOPSPERMSEC=800 # # Interrupt options # -# CONFIG_ARCH_HAVE_INTERRUPTSTACK is not set +CONFIG_ARCH_HAVE_INTERRUPTSTACK=y +CONFIG_ARCH_INTERRUPTSTACK=0 # CONFIG_ARCH_HAVE_HIPRI_INTERRUPT is not set # @@ -276,6 +289,9 @@ CONFIG_DEV_NULL=y # CONFIG_ARCH_HAVE_I2CRESET is not set # CONFIG_I2C is not set # CONFIG_SPI is not set +# CONFIG_ARCH_HAVE_SPI_CRCGENERATION is not set +# CONFIG_ARCH_HAVE_SPI_CS_CONTROL is not set +# CONFIG_ARCH_HAVE_SPI_BITORDER is not set # CONFIG_I2S is not set # @@ -319,13 +335,13 @@ CONFIG_DEV_NULL=y # CONFIG_SENSORS is not set # CONFIG_SERCOMM_CONSOLE is not set CONFIG_SERIAL=y -CONFIG_DEV_LOWCONSOLE=y +# CONFIG_DEV_LOWCONSOLE is not set # CONFIG_SERIAL_REMOVABLE is not set -# CONFIG_SERIAL_CONSOLE is not set +CONFIG_SERIAL_CONSOLE=y # CONFIG_16550_UART is not set # CONFIG_UART_SERIALDRIVER is not set # CONFIG_UART0_SERIALDRIVER is not set -# CONFIG_UART1_SERIALDRIVER is not set +CONFIG_UART1_SERIALDRIVER=y # CONFIG_UART2_SERIALDRIVER is not set # CONFIG_UART3_SERIALDRIVER is not set # CONFIG_UART4_SERIALDRIVER is not set @@ -345,11 +361,29 @@ CONFIG_DEV_LOWCONSOLE=y # CONFIG_USART7_SERIALDRIVER is not set # CONFIG_USART8_SERIALDRIVER is not set # CONFIG_OTHER_UART_SERIALDRIVER is not set -# CONFIG_MCU_SERIAL is not set +CONFIG_MCU_SERIAL=y +# CONFIG_STANDARD_SERIAL is not set # CONFIG_SERIAL_IFLOWCONTROL is not set # CONFIG_SERIAL_OFLOWCONTROL is not set # CONFIG_SERIAL_DMA is not set +# CONFIG_SERIAL_TIOCSERGSTRUCT is not set # CONFIG_ARCH_HAVE_SERIAL_TERMIOS is not set +CONFIG_UART1_SERIAL_CONSOLE=y +# CONFIG_OTHER_SERIAL_CONSOLE is not set +# CONFIG_NO_SERIAL_CONSOLE is not set + +# +# UART1 Configuration +# +CONFIG_UART1_RXBUFSIZE=256 +CONFIG_UART1_TXBUFSIZE=256 +CONFIG_UART1_BAUD=115200 +CONFIG_UART1_BITS=8 +CONFIG_UART1_PARITY=0 +CONFIG_UART1_2STOP=0 +# CONFIG_UART1_IFLOWCONTROL is not set +# CONFIG_UART1_OFLOWCONTROL is not set +# CONFIG_UART1_DMA is not set # CONFIG_PSEUDOTERM is not set # CONFIG_USBDEV is not set # CONFIG_USBHOST is not set @@ -364,7 +398,7 @@ CONFIG_DEV_LOWCONSOLE=y # CONFIG_RAMLOG is not set # CONFIG_SYSLOG_INTBUFFER is not set # CONFIG_SYSLOG_TIMESTAMP is not set -# CONFIG_SYSLOG_SERIAL_CONSOLE is not set +CONFIG_SYSLOG_SERIAL_CONSOLE=y # CONFIG_SYSLOG_CHAR is not set CONFIG_SYSLOG_CONSOLE=y # CONFIG_SYSLOG_NONE is not set @@ -446,6 +480,8 @@ CONFIG_NUNGET_CHARS=0 # CONFIG_LIBC_FLOATINGPOINT is not set # CONFIG_LIBC_LONG_LONG is not set # CONFIG_LIBC_IOCTL_VARIADIC is not set +# CONFIG_LIBC_WCHAR is not set +# CONFIG_LIBC_LOCALE is not set CONFIG_LIB_RAND_ORDER=1 # CONFIG_EOL_IS_CR is not set # CONFIG_EOL_IS_LF is not set @@ -489,6 +525,7 @@ CONFIG_LIB_SENDFILE_BUFSIZE=512 # # Examples # +# CONFIG_EXAMPLES_CCTYPE is not set # CONFIG_EXAMPLES_CHAT is not set # CONFIG_EXAMPLES_CONFIGDATA is not set # CONFIG_EXAMPLES_DHCPD is not set