From 1ec681a55121b9b1d5fcdb274a3c3d10d408a960 Mon Sep 17 00:00:00 2001 From: bigamgic Date: Sun, 21 Jun 2020 23:25:32 +0800 Subject: [PATCH] fix ls2k libc and irq --- bsp/ls2kdev/drivers/drv_gpio.c | 147 +++++++++++++++++++++++--- bsp/ls2kdev/drivers/drv_gpio.h | 20 ++++ bsp/ls2kdev/drivers/drv_uart.c | 24 ++--- bsp/ls2kdev/drivers/drv_uart.h | 2 +- bsp/ls2kdev/drivers/interrupt.c | 178 +++++++++++++++++++++++++++++--- bsp/ls2kdev/drivers/interrupt.h | 85 +++++++++++++++ bsp/ls2kdev/drivers/ls2k1000.h | 13 ++- libcpu/mips/common/exception.c | 39 ++++--- 8 files changed, 449 insertions(+), 59 deletions(-) create mode 100644 bsp/ls2kdev/drivers/interrupt.h diff --git a/bsp/ls2kdev/drivers/drv_gpio.c b/bsp/ls2kdev/drivers/drv_gpio.c index bcbecd9e2c..e1c5d61331 100644 --- a/bsp/ls2kdev/drivers/drv_gpio.c +++ b/bsp/ls2kdev/drivers/drv_gpio.c @@ -8,25 +8,14 @@ * 2017-10-20 ZYH add mode open drain and input pull down * 2020-06-01 Du Huanpeng GPIO driver based on */ - - #include #include -#include #include - -struct loongson_gpio { - rt_uint64_t GPIO0_OEN; - rt_uint64_t GPIO1_OEN; /* Reserved */ - rt_uint64_t GPIO0_O; - rt_uint64_t GPIO1_O; /* Reserved */ - rt_uint64_t GPIO0_I; - rt_uint64_t GPIO1_I; /* Reserved */ - rt_uint64_t GPIO0_INTEN; - rt_uint64_t GPIO1_INTEN; /* Reserved */ -}; +#include "drv_gpio.h" #ifdef RT_USING_PIN +#define GPIO_IRQ_NUM (64) +static struct gpio_irq_def _g_gpio_irq_tbl[GPIO_IRQ_NUM]; static void loongson_pin_mode(struct rt_device *device, rt_base_t pin, rt_base_t mode) { @@ -92,13 +81,36 @@ static int loongson_pin_read(struct rt_device *device, rt_base_t pin) return rc; } - /* TODO: add GPIO interrupt */ +/* TODO: add GPIO interrupt */ static rt_err_t loongson_pin_attach_irq(struct rt_device *device, rt_int32_t pin, rt_uint32_t mode, void (*hdr)(void *args), void *args) { + rt_uint8_t index; + rt_uint64_t m; struct loongson_gpio *gpio; gpio = (void *)device->user_data; + if(pin < 4) + { + index = pin; + } + else if(pin < 32) + { + index = 5; + } + else + { + index = 6; + } + + _g_gpio_irq_tbl[index].irq_cb[pin] = hdr; + _g_gpio_irq_tbl[index].irq_arg[pin] = args; + _g_gpio_irq_tbl[index].irq_type[pin] = mode; + + liointc_set_irq_mode(index, mode); + m = (rt_uint64_t)1 << pin; + gpio->GPIO0_INTEN |= m; + return RT_EOK; } static rt_err_t loongson_pin_detach_irq(struct rt_device *device, rt_int32_t pin) @@ -107,6 +119,24 @@ static rt_err_t loongson_pin_detach_irq(struct rt_device *device, rt_int32_t pin gpio = (void *)device->user_data; + rt_uint8_t index; + if(pin < 4) + { + index = pin; + } + else if(pin < 32) + { + index = 5; + } + else + { + index = 6; + } + _g_gpio_irq_tbl[index].irq_cb[pin] = RT_NULL; + _g_gpio_irq_tbl[index].irq_arg[pin] = RT_NULL; + _g_gpio_irq_tbl[index].irq_type[pin] = RT_NULL; + _g_gpio_irq_tbl[index].state[pin] = RT_NULL; + return RT_EOK; } static rt_err_t loongson_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled) @@ -115,9 +145,72 @@ static rt_err_t loongson_pin_irq_enable(struct rt_device *device, rt_base_t pin, gpio = (void *)device->user_data; + rt_uint8_t index; + if(pin < 4) + { + index = pin; + } + else if(pin < 32) + { + index = 5; + } + else + { + index = 6; + } + + if (enabled) + _g_gpio_irq_tbl[index].state[pin] = 1; + else + _g_gpio_irq_tbl[index].state[pin] = 0; return RT_EOK; } +static void gpio_irq_handler(int irq, void *param) +{ + struct gpio_irq_def *irq_def = (struct gpio_irq_def *)param; + rt_uint32_t pin; + rt_uint32_t value; + rt_uint32_t tmpvalue; + + if(irq == LS2K_GPIO0_INT_IRQ) + { + pin = 0; + } + else if(irq == LS2K_GPIO1_INT_IRQ) + { + pin = 1; + } + else if(irq == LS2K_GPIO2_INT_IRQ) + { + pin = 2; + } + else if(irq == LS2K_GPIO3_INT_IRQ) + { + pin = 3; + } + else if(irq == LS2K_GPIO_INTLO_IRQ) + { + pin = 4; + } + else + { + pin = 32; + } + + while (value) + { + if ((value & 0x1) && (irq_def->irq_cb[pin] != RT_NULL)) + { + if(irq_def->state[pin]) + { + irq_def->irq_cb[pin](irq_def->irq_arg[pin]); + } + } + pin++; + value = value >> 1; + } +} static struct rt_pin_ops loongson_pin_ops = { .pin_mode = loongson_pin_mode, @@ -139,6 +232,30 @@ int loongson_pin_init(void) loongson_gpio_priv = (void *)GPIO_BASE; rc = rt_device_pin_register("pin", &loongson_pin_ops, loongson_gpio_priv); + //gpio0 + rt_hw_interrupt_install(LS2K_GPIO0_INT_IRQ, gpio_irq_handler, &_g_gpio_irq_tbl[0], "gpio0_irq"); + rt_hw_interrupt_umask(LS2K_GPIO0_INT_IRQ); + + //gpio1 + rt_hw_interrupt_install(LS2K_GPIO1_INT_IRQ, gpio_irq_handler, &_g_gpio_irq_tbl[1], "gpio1_irq"); + rt_hw_interrupt_umask(LS2K_GPIO1_INT_IRQ); + + //gpio2 + rt_hw_interrupt_install(LS2K_GPIO2_INT_IRQ, gpio_irq_handler, &_g_gpio_irq_tbl[2], "gpio2_irq"); + rt_hw_interrupt_umask(LS2K_GPIO2_INT_IRQ); + + //gpio3 + rt_hw_interrupt_install(LS2K_GPIO3_INT_IRQ, gpio_irq_handler, &_g_gpio_irq_tbl[3], "gpio3_irq"); + rt_hw_interrupt_umask(LS2K_GPIO3_INT_IRQ); + + //gpio4~gpio31 + rt_hw_interrupt_install(LS2K_GPIO_INTLO_IRQ, gpio_irq_handler, &_g_gpio_irq_tbl[4], "gpio4_irq"); + rt_hw_interrupt_umask(LS2K_GPIO_INTLO_IRQ); + + //gpio32~gpio63 + rt_hw_interrupt_install(LS2K_GPIO_INTHI_IRQ, gpio_irq_handler, &_g_gpio_irq_tbl[5], "gpio5_irq"); + rt_hw_interrupt_umask(LS2K_GPIO_INTHI_IRQ); + return rc; } INIT_BOARD_EXPORT(loongson_pin_init); diff --git a/bsp/ls2kdev/drivers/drv_gpio.h b/bsp/ls2kdev/drivers/drv_gpio.h index 6d505c1294..51a75c306e 100644 --- a/bsp/ls2kdev/drivers/drv_gpio.h +++ b/bsp/ls2kdev/drivers/drv_gpio.h @@ -13,6 +13,26 @@ #ifndef __DRV_GPIO_H__ #define __DRV_GPIO_H__ +#include + +struct gpio_irq_def +{ + void *irq_arg[32]; + void (*irq_cb[32])(void *param); + rt_uint8_t irq_type[32]; + rt_uint8_t state[32]; +}; + +struct loongson_gpio { + rt_uint64_t GPIO0_OEN; + rt_uint64_t GPIO1_OEN; /* Reserved */ + rt_uint64_t GPIO0_O; + rt_uint64_t GPIO1_O; /* Reserved */ + rt_uint64_t GPIO0_I; + rt_uint64_t GPIO1_I; /* Reserved */ + rt_uint64_t GPIO0_INTEN; + rt_uint64_t GPIO1_INTEN; /* Reserved */ +}; int loongson_pin_init(void); diff --git a/bsp/ls2kdev/drivers/drv_uart.c b/bsp/ls2kdev/drivers/drv_uart.c index 428393dcc4..baed70b61f 100644 --- a/bsp/ls2kdev/drivers/drv_uart.c +++ b/bsp/ls2kdev/drivers/drv_uart.c @@ -28,7 +28,7 @@ struct rt_uart_ls2k rt_uint32_t IRQ; }; -static rt_err_t mipssim_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg) +static rt_err_t ls2k_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg) { struct rt_uart_ls2k *uart_dev = RT_NULL; @@ -48,7 +48,7 @@ static rt_err_t mipssim_uart_configure(struct rt_serial_device *serial, struct s return RT_EOK; } -static rt_err_t mipssim_uart_control(struct rt_serial_device *serial, int cmd, void *arg) +static rt_err_t ls2k_uart_control(struct rt_serial_device *serial, int cmd, void *arg) { struct rt_uart_ls2k *uart_dev = RT_NULL; @@ -88,7 +88,7 @@ static rt_bool_t uart_is_transmit_empty(struct rt_uart_ls2k *uart_dev) } } -static int mipssim_uart_putc(struct rt_serial_device *serial, char c) +static int ls2k_uart_putc(struct rt_serial_device *serial, char c) { struct rt_uart_ls2k *uart_dev = RT_NULL; @@ -104,7 +104,7 @@ static int mipssim_uart_putc(struct rt_serial_device *serial, char c) return 1; } -static int mipssim_uart_getc(struct rt_serial_device *serial) +static int ls2k_uart_getc(struct rt_serial_device *serial) { struct rt_uart_ls2k *uart_dev = RT_NULL; @@ -141,18 +141,18 @@ static void uart_irq_handler(int vector, void *param) } -static const struct rt_uart_ops mipssim_uart_ops = +static const struct rt_uart_ops ls2k_uart_ops = { - mipssim_uart_configure, - mipssim_uart_control, - mipssim_uart_putc, - mipssim_uart_getc, + ls2k_uart_configure, + ls2k_uart_control, + ls2k_uart_putc, + ls2k_uart_getc, }; struct rt_uart_ls2k uart_dev0 = { - (void *)UART0_BASE, - 4, + (void *)UARTx_BASE(0), + LS2K_UART_0_1_2_3_IRQ, }; struct rt_serial_device serial; @@ -164,7 +164,7 @@ void rt_hw_uart_init(void) uart = &uart_dev0; - serial.ops = &mipssim_uart_ops; + serial.ops = &ls2k_uart_ops; serial.config = config; rt_hw_interrupt_install(uart->IRQ, uart_irq_handler, &serial, "UART"); diff --git a/bsp/ls2kdev/drivers/drv_uart.h b/bsp/ls2kdev/drivers/drv_uart.h index 95c69a0442..4d17b99b35 100644 --- a/bsp/ls2kdev/drivers/drv_uart.h +++ b/bsp/ls2kdev/drivers/drv_uart.h @@ -5,7 +5,7 @@ * * Change Logs: * Date Author Notes - * 2019-04-05 bigmagic Initial version + * 2020-04-05 bigmagic Initial version */ #ifndef _DRV_UART_H__ diff --git a/bsp/ls2kdev/drivers/interrupt.c b/bsp/ls2kdev/drivers/interrupt.c index 6473e5aa94..97f5994ec7 100644 --- a/bsp/ls2kdev/drivers/interrupt.c +++ b/bsp/ls2kdev/drivers/interrupt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2019, RT-Thread Development Team + * Copyright (c) 2006-2020, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -17,8 +17,9 @@ #include #include #include - -#define MAX_INTR 32 +#include +#include "ls2k1000.h" +#include "interrupt.h" static struct rt_irq_desc irq_handle_table[MAX_INTR]; @@ -27,17 +28,141 @@ static void rt_hw_interrupt_handler(int vector, void *param) rt_kprintf("Unhandled interrupt %d occured!!!\n", vector); } +static void liointc_init(void) +{ + int i; + /* Router for LIOINTC0, to Core 0, INT0 (CPU IP2) */ + for (i = 0; i < 32; i ++) + { + HWREG8(LIOINTC0_BASE + i) = LIOINTC_COREx_INTy(0, 0); + } + + /* Router for LIOINTC1, to Core 0, INT1 (CPU IP3) */ + for (i = 0; i < 32; i ++) + { + HWREG8(LIOINTC1_BASE + i) = LIOINTC_COREx_INTy(0, 1); + } + + /* Disable all IRQs */ + HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_DISABLE) = 0xffffffff; + HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_DISABLE) = 0xffffffff; + + /* Set all IRQs to low level triggered (Default?) */ + HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_POL) = 0x0; + HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_EDGE) = 0x0; + + HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_POL) = 0x0; + HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_EDGE) = 0x0; +} + +//set irq mode +void liointc_set_irq_mode(int irq, int mode) +{ + if(irq < 32) + { + if(mode == PIN_IRQ_MODE_RISING) + { + HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_POL) |= (0x0 << (irq)); + HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_EDGE) |= (0x1 << (irq)); + } + else if(mode == PIN_IRQ_MODE_FALLING) + { + HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_POL) |= (0x1 << (irq)); + HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_EDGE) |= (0x1 << (irq)); + } + else if(mode == PIN_IRQ_MODE_HIGH_LEVEL) + { + HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_POL) |= (0x1 << (irq)); + HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_EDGE) |= (0x0 << (irq)); + } + else if(mode == PIN_IRQ_MODE_LOW_LEVEL) + { + HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_POL) |= (0x0 << (irq)); + HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_EDGE) |= (0x0 << (irq)); + } + else + { + HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_POL) |= (0x1 << (irq)); + HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_EDGE) |= (0x1 << (irq)); + } + } + else + { + if(mode == PIN_IRQ_MODE_RISING) + { + HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_POL) |= (0x0 << (irq - 32)); + HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_EDGE) |= (0x1 << (irq - 32)); + } + else if(mode == PIN_IRQ_MODE_FALLING) + { + HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_POL) |= (0x1 << (irq - 32)); + HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_EDGE) |= (0x1 << (irq - 32)); + } + else if(mode == PIN_IRQ_MODE_HIGH_LEVEL) + { + HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_POL) |= (0x1 << (irq - 32)); + HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_EDGE) |= (0x0 << (irq - 32)); + } + else if(mode == PIN_IRQ_MODE_LOW_LEVEL) + { + HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_POL) |= (0x0 << (irq - 32)); + HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_EDGE) |= (0x0 << (irq - 32)); + } + else + { + HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_POL) |= (0x1 << (irq - 32)); + HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_EDGE) |= (0x1 << (irq - 32)); + } + } +} + +static void liointc_isr(rt_ubase_t reg_base, rt_ubase_t isr_base, + int irq_base) +{ + rt_uint32_t isr, tmp; + int intx; + /* Mask to clear ISR */ + isr = HWREG32(isr_base); + + tmp = isr; + /* Handle each of them */ + while (tmp) + { + rt_isr_handler_t irq_func; + void *param; + int irq; + + intx = __rt_ffs(isr) - 1; + tmp &= ~(1 << intx); + + irq = intx + irq_base; + + irq_func = irq_handle_table[irq].handler; + param = irq_handle_table[irq].param; + irq_func(irq, param); +#ifdef RT_USING_INTERRUPT_INFO + irq_handle_table[irq].counter++; +#endif + } + + /* Enable them again */ + HWREG32(reg_base + LIOINTC_REG_INTC_ENABLE) = isr; +} + /** * This function will initialize hardware interrupt */ void rt_hw_interrupt_init(void) { rt_uint32_t idx; + rt_memset(irq_handle_table, 0x00, sizeof(irq_handle_table)); for (idx = 0; idx < MAX_INTR; idx ++) { irq_handle_table[idx].handler = rt_hw_interrupt_handler; } + + liointc_init(); } rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, @@ -56,34 +181,57 @@ rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, irq_handle_table[vector].param = param; } + if(vector <= 32) + { + mips_unmask_cpu_irq(2); + } + else + { + mips_unmask_cpu_irq(3); + } + return old_handler; } -void rt_hw_timer_handler(void); - void rt_do_mips_cpu_irq(rt_uint32_t ip) { void *param; rt_isr_handler_t irq_func; - - if (ip == 7) { + if (ip == 7) + { rt_hw_timer_handler(); - } else { - irq_func = irq_handle_table[ip].handler; - param = irq_handle_table[ip].param; - - /* do interrupt */ - irq_func(ip, param); + } + else if (ip == 2) + { + liointc_isr(LIOINTC0_BASE, CORE0_INTISR0, LIOINTC0_IRQBASE); + } + else if (ip == 3) + { + liointc_isr(LIOINTC1_BASE, CORE0_INTISR1, LIOINTC1_IRQBASE); } } void rt_hw_interrupt_umask(int irq) { - mips_unmask_cpu_irq(irq); + if(irq < LIOINTC0_IRQBASE + 32) + { + HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_ENABLE) = (1 << irq); + } + else if(irq < LIOINTC1_IRQBASE + 32) + { + HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_ENABLE) = (1 << (irq - 32)); + } } void rt_hw_interrupt_mask(int irq) { - mips_mask_cpu_irq(irq); + if(irq < LIOINTC0_IRQBASE + 32) + { + HWREG32(LIOINTC0_BASE + LIOINTC_REG_INTC_DISABLE) = (1 << irq); + } + else if(irq < LIOINTC1_IRQBASE + 32) + { + HWREG32(LIOINTC1_BASE + LIOINTC_REG_INTC_DISABLE) = (1 << (irq - 32)); + } } /*@}*/ diff --git a/bsp/ls2kdev/drivers/interrupt.h b/bsp/ls2kdev/drivers/interrupt.h new file mode 100644 index 0000000000..18707f7321 --- /dev/null +++ b/bsp/ls2kdev/drivers/interrupt.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2006-2020, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-06-21 bigmagic Initial version + */ + +#ifndef _DRV_INTERRUPT_H__ +#define _DRV_INTERRUPT_H__ + +#define LS2K_UART_0_1_2_3_IRQ (0) +#define LS2K_UART_4_5_6_7_IRQ (1) +#define LS2K_UART_8_9_10_11_IRQ (2) +#define LS2K_EL_IRQ (3) +#define LS2K_HDA_IRQ (4) +#define LS2K_I2S_IRQ (5) +#define LS2K_RESERVED1_IRQ (6) +#define LS2K_THSENS_IRQ (7) +#define LS2K_TOY_TICK_IRQ (8) +#define LS2K_RTC_TICK_IRQ (9) +#define LS2K_CAM_TICK_IRQ (10) +#define LS2K_RESERVED2_IRQ (11) +#define LS2K_GMAC0_SBD_IRQ (12) +#define LS2K_GMAC0_PMT_IRQ (13) +#define LS2K_GMAC1_SBD_IRQ (14) +#define LS2K_GMAC1_PMT_IRQ (15) +#define LS2K_CANO_IRQ (16) +#define LS2K_CAN1_IRQ (17) +#define LS2K_BOOT_IRQ (18) +#define LS2K_SATA_IRQ (19) +#define LS2K_NAND_IRQ (20) +#define LS2K_HPET_IRQ (21) +#define LS2K_I2C0_IRQ (21) +#define LS2K_I2C1_IRQ (22) +#define LS2K_I2C2_IRQ (23) +#define LS2K_PWM0_IRQ (24) +#define LS2K_PWM1_IRQ (25) +#define LS2K_PWM2_IRQ (26) +#define LS2K_PWM3_IRQ (27) +#define LS2K_DC_IRQ (28) +#define LS2K_GPU_IRQ (29) +#define LS2K_VPU_IRQ (30) +#define LS2K_SDIO_IRQ (31) +//#define LS2K_PCIE0_IRQ (32~35) +//#define LS2K_PCIE1_IRQ (36~37) +#define LS2K_HPET1_IRQ (38) +#define LS2K_HPET2_IRQ (39) +//#define LS2K_TOY_IRQ (40~43) +//#define LS2K_DMA_IRQ (44~48) +#define LS2K_OTG_IRQ (49) +#define LS2K_EHCI_IRQ (50) +#define LS2K_OHCI_IRQ (51) +//#define LS2K_RTC_IRQ (52~54) +#define LS2K_RSA_IRQ (55) +#define LS2K_AES_IRQ (56) +#define LS2K_DES_IRQ (57) +#define LS2K_GPIO_INTLO_IRQ (58) +#define LS2K_GPIO_INTHI_IRQ (59) +#define LS2K_GPIO0_INT_IRQ (60) +#define LS2K_GPIO1_INT_IRQ (61) +#define LS2K_GPIO2_INT_IRQ (62) +#define LS2K_GPIO3_INT_IRQ (63) + +#define MAX_INTR 64 +#define LIOINTC0_IRQBASE 0 +#define LIOINTC1_IRQBASE 32 + +#define LIOINTC_SHIFT_INTx 4 +#define LIOINTC_COREx_INTy(x, y) ((1 << x) | (1 << (y + LIOINTC_SHIFT_INTx))) + +#define LIOINTC_INTC_CHIP_START 0x20 + +#define LIOINTC_REG_INTC_STATUS (LIOINTC_INTC_CHIP_START + 0x00) +#define LIOINTC_REG_INTC_EN_STATUS (LIOINTC_INTC_CHIP_START + 0x04) +#define LIOINTC_REG_INTC_ENABLE (LIOINTC_INTC_CHIP_START + 0x08) +#define LIOINTC_REG_INTC_DISABLE (LIOINTC_INTC_CHIP_START + 0x0c) +#define LIOINTC_REG_INTC_POL (LIOINTC_INTC_CHIP_START + 0x10) +#define LIOINTC_REG_INTC_EDGE (LIOINTC_INTC_CHIP_START + 0x14) + +void liointc_set_irq_mode(int irq, int mode); + +#endif \ No newline at end of file diff --git a/bsp/ls2kdev/drivers/ls2k1000.h b/bsp/ls2kdev/drivers/ls2k1000.h index 90adf4a6ed..cb6586525e 100644 --- a/bsp/ls2kdev/drivers/ls2k1000.h +++ b/bsp/ls2kdev/drivers/ls2k1000.h @@ -2,12 +2,23 @@ #define _LS2K1000_H__ #include +#include "interrupt.h" + +#define APB_BASE CKSEG1ADDR(0xbfe00000) #define UART0_BASE_ADDR 0xbfe00000 #define UART0_OFF 0x0 #define UART0_BASE CKSEG1ADDR(UART0_BASE_ADDR + UART0_OFF) -#define GPIO_BASE 0xFFFFFFFFBFE10500 +#define UARTx_BASE(x) ((APB_BASE | (0x0 << 12) | (x << 8))) + +#define LIOINTC0_BASE CKSEG1ADDR(0x1fe11400) +#define CORE0_INTISR0 CKSEG1ADDR(0x1fe11040) + +#define LIOINTC1_BASE CKSEG1ADDR(0x1fe11440) +#define CORE0_INTISR1 CKSEG1ADDR(0x1fe11048) + +#define GPIO_BASE 0xFFFFFFFFBFE10500 #define PLL_SYS_BASE 0xFFFFFFFFBFE10480 void rt_hw_timer_handler(void); diff --git a/libcpu/mips/common/exception.c b/libcpu/mips/common/exception.c index cd7d97e6c0..84bb0446d6 100644 --- a/libcpu/mips/common/exception.c +++ b/libcpu/mips/common/exception.c @@ -39,7 +39,7 @@ void rt_hw_interrupt_enable(rt_base_t level) /** * exception handle table */ -#define RT_EXCEPTION_MAX 31 +#define RT_EXCEPTION_MAX 31 exception_func_t sys_exception_handlers[RT_EXCEPTION_MAX]; /** @@ -59,10 +59,13 @@ exception_func_t rt_set_except_vector(int n, exception_func_t func) return old_handler; } -void mips_dump_regs(struct pt_regs *regs) { +void mips_dump_regs(struct pt_regs *regs) +{ int i, j; - for(i = 0; i < 32 / 4; i++) { - for(j = 0; j < 4; j++) { + for (i = 0; i < 32 / 4; i++) + { + for (j = 0; j < 4; j++) + { int reg = 4 * i + j; rt_kprintf("%d: 0x%08x, ", reg, regs->regs[reg]); } @@ -84,9 +87,10 @@ void cache_error_handler(void) static void unhandled_exception_handle(struct pt_regs *regs) { - rt_kprintf("Unknown Exception, EPC: 0x%08x, CAUSE: 0x%08x\n", read_c0_epc(), read_c0_cause()); - rt_kprintf("ST0: 0x%08x ",regs->cp0_status); - rt_kprintf("ErrorPC: 0x%08x\n",read_c0_errorepc()); + rt_kprintf("Unknown Exception, EPC: 0x%08x, CAUSE: 0x%08x\n", read_c0_epc(), + read_c0_cause()); + rt_kprintf("ST0: 0x%08x ", regs->cp0_status); + rt_kprintf("ErrorPC: 0x%08x\n", read_c0_errorepc()); mips_dump_regs(regs); rt_hw_cpu_shutdown(); } @@ -95,8 +99,9 @@ static void install_default_exception_handler(void) { rt_int32_t i; - for (i=0; i> CAUSEB_EXCCODE; - - if (exccode == 0) { + if (exccode == 0) + { rt_ubase_t status, pending; - status = read_c0_status(); - pending = (CAUSEF_IP) & (status & ST0_IM); + status = read_c0_status(); + pending = (cause & CAUSEF_IP) & (status & ST0_IM); if (pending & CAUSEF_IP0) rt_do_mips_cpu_irq(0); if (pending & CAUSEF_IP1) @@ -141,7 +148,9 @@ void rt_general_exc_dispatch(struct pt_regs *regs) rt_do_mips_cpu_irq(6); if (pending & CAUSEF_IP7) rt_do_mips_cpu_irq(7); - } else { + } + else + { if (sys_exception_handlers[exccode]) sys_exception_handlers[exccode](regs); }