summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbigamgic <[email protected]>2020-06-21 23:25:32 +0800
committerbigamgic <[email protected]>2020-06-21 23:28:11 +0800
commit1ec681a55121b9b1d5fcdb274a3c3d10d408a960 (patch)
tree1632165859d829d9a1a27847f23ba676e9507a0a
parenteb0544c847f6cb84b6990165ed473d509d821beb (diff)
fix ls2k libc and irq
-rw-r--r--bsp/ls2kdev/drivers/drv_gpio.c147
-rw-r--r--bsp/ls2kdev/drivers/drv_gpio.h20
-rw-r--r--bsp/ls2kdev/drivers/drv_uart.c24
-rw-r--r--bsp/ls2kdev/drivers/drv_uart.h2
-rw-r--r--bsp/ls2kdev/drivers/interrupt.c178
-rw-r--r--bsp/ls2kdev/drivers/interrupt.h85
-rw-r--r--bsp/ls2kdev/drivers/ls2k1000.h13
-rw-r--r--libcpu/mips/common/exception.c39
8 files changed, 449 insertions, 59 deletions
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 <components/drivers/include/drivers/pin.h>
*/
-
-
#include <rtthread.h>
#include <drivers/pin.h>
-#include <rthw.h>
#include <ls2k1000.h>
-
-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 <rthw.h>
+
+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 <rtthread.h>
#include <rthw.h>
#include <exception.h>
-
-#define MAX_INTR 32
+#include <drivers/pin.h>
+#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 <mips.h>
+#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<RT_EXCEPTION_MAX; i++)
- sys_exception_handlers[i] = (exception_func_t)unhandled_exception_handle;
+ for (i = 0; i < RT_EXCEPTION_MAX; i++)
+ sys_exception_handlers[i] =
+ (exception_func_t)unhandled_exception_handle;
}
int rt_hw_exception_init(void)
@@ -117,14 +122,16 @@ int rt_hw_exception_init(void)
void rt_general_exc_dispatch(struct pt_regs *regs)
{
- rt_ubase_t exccode = 0;
+ rt_ubase_t cause, exccode;
+ cause = read_c0_cause();
+ exccode = (cause & CAUSEF_EXCCODE) >> 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);
}