Merge pull request #3711 from bigmagic123/fix_ls2k_irq

Fix ls2k irq
This commit is contained in:
Bernard Xiong 2020-06-23 00:20:47 +08:00 committed by GitHub
commit 04cbae4731
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 473 additions and 61 deletions

View File

@ -104,7 +104,18 @@ CONFIG_FINSH_ARG_MAX=10
# #
# Device virtual file system # Device virtual file system
# #
# CONFIG_RT_USING_DFS is not set CONFIG_RT_USING_DFS=y
CONFIG_DFS_USING_WORKDIR=y
CONFIG_DFS_FILESYSTEMS_MAX=2
CONFIG_DFS_FILESYSTEM_TYPES_MAX=2
CONFIG_DFS_FD_MAX=16
# CONFIG_RT_USING_DFS_MNTTABLE is not set
# CONFIG_RT_USING_DFS_ELMFAT is not set
CONFIG_RT_USING_DFS_DEVFS=y
# CONFIG_RT_USING_DFS_ROMFS is not set
# CONFIG_RT_USING_DFS_RAMFS is not set
# CONFIG_RT_USING_DFS_UFFS is not set
# CONFIG_RT_USING_DFS_JFFS2 is not set
# #
# Device Drivers # Device Drivers
@ -148,6 +159,10 @@ CONFIG_RT_USING_PIN=y
# #
CONFIG_RT_USING_LIBC=y CONFIG_RT_USING_LIBC=y
# CONFIG_RT_USING_PTHREADS is not set # CONFIG_RT_USING_PTHREADS is not set
CONFIG_RT_USING_POSIX=y
# CONFIG_RT_USING_POSIX_MMAP is not set
# CONFIG_RT_USING_POSIX_TERMIOS is not set
# CONFIG_RT_USING_POSIX_AIO is not set
# CONFIG_RT_USING_MODULE is not set # CONFIG_RT_USING_MODULE is not set
# #

View File

@ -8,25 +8,14 @@
* 2017-10-20 ZYH add mode open drain and input pull down * 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> * 2020-06-01 Du Huanpeng GPIO driver based on <components/drivers/include/drivers/pin.h>
*/ */
#include <rtthread.h> #include <rtthread.h>
#include <drivers/pin.h> #include <drivers/pin.h>
#include <rthw.h>
#include <ls2k1000.h> #include <ls2k1000.h>
#include "drv_gpio.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 */
};
#ifdef RT_USING_PIN #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) 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; 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) 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; struct loongson_gpio *gpio;
gpio = (void *)device->user_data; 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; return RT_EOK;
} }
static rt_err_t loongson_pin_detach_irq(struct rt_device *device, rt_int32_t pin) 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; 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; return RT_EOK;
} }
static rt_err_t loongson_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled) 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; 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; 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 = { static struct rt_pin_ops loongson_pin_ops = {
.pin_mode = loongson_pin_mode, .pin_mode = loongson_pin_mode,
@ -139,6 +232,30 @@ int loongson_pin_init(void)
loongson_gpio_priv = (void *)GPIO_BASE; loongson_gpio_priv = (void *)GPIO_BASE;
rc = rt_device_pin_register("pin", &loongson_pin_ops, loongson_gpio_priv); 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; return rc;
} }
INIT_BOARD_EXPORT(loongson_pin_init); INIT_BOARD_EXPORT(loongson_pin_init);

View File

@ -13,6 +13,26 @@
#ifndef __DRV_GPIO_H__ #ifndef __DRV_GPIO_H__
#define __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); int loongson_pin_init(void);

View File

@ -28,7 +28,7 @@ struct rt_uart_ls2k
rt_uint32_t IRQ; 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; 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; 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; 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; 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; 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; 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, ls2k_uart_configure,
mipssim_uart_control, ls2k_uart_control,
mipssim_uart_putc, ls2k_uart_putc,
mipssim_uart_getc, ls2k_uart_getc,
}; };
struct rt_uart_ls2k uart_dev0 = struct rt_uart_ls2k uart_dev0 =
{ {
(void *)UART0_BASE, (void *)UARTx_BASE(0),
4, LS2K_UART_0_1_2_3_IRQ,
}; };
struct rt_serial_device serial; struct rt_serial_device serial;
@ -164,7 +164,7 @@ void rt_hw_uart_init(void)
uart = &uart_dev0; uart = &uart_dev0;
serial.ops = &mipssim_uart_ops; serial.ops = &ls2k_uart_ops;
serial.config = config; serial.config = config;
rt_hw_interrupt_install(uart->IRQ, uart_irq_handler, &serial, "UART"); rt_hw_interrupt_install(uart->IRQ, uart_irq_handler, &serial, "UART");

View File

@ -5,7 +5,7 @@
* *
* Change Logs: * Change Logs:
* Date Author Notes * Date Author Notes
* 2019-04-05 bigmagic Initial version * 2020-04-05 bigmagic Initial version
*/ */
#ifndef _DRV_UART_H__ #ifndef _DRV_UART_H__

View File

@ -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 * SPDX-License-Identifier: Apache-2.0
* *
@ -17,8 +17,9 @@
#include <rtthread.h> #include <rtthread.h>
#include <rthw.h> #include <rthw.h>
#include <exception.h> #include <exception.h>
#include <drivers/pin.h>
#define MAX_INTR 32 #include "ls2k1000.h"
#include "interrupt.h"
static struct rt_irq_desc irq_handle_table[MAX_INTR]; 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); 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 * This function will initialize hardware interrupt
*/ */
void rt_hw_interrupt_init(void) void rt_hw_interrupt_init(void)
{ {
rt_uint32_t idx; rt_uint32_t idx;
rt_memset(irq_handle_table, 0x00, sizeof(irq_handle_table)); rt_memset(irq_handle_table, 0x00, sizeof(irq_handle_table));
for (idx = 0; idx < MAX_INTR; idx ++) for (idx = 0; idx < MAX_INTR; idx ++)
{ {
irq_handle_table[idx].handler = rt_hw_interrupt_handler; 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, 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; irq_handle_table[vector].param = param;
} }
if(vector <= 32)
{
mips_unmask_cpu_irq(2);
}
else
{
mips_unmask_cpu_irq(3);
}
return old_handler; return old_handler;
} }
void rt_hw_timer_handler(void);
void rt_do_mips_cpu_irq(rt_uint32_t ip) void rt_do_mips_cpu_irq(rt_uint32_t ip)
{ {
void *param; void *param;
rt_isr_handler_t irq_func; rt_isr_handler_t irq_func;
if (ip == 7)
if (ip == 7) { {
rt_hw_timer_handler(); rt_hw_timer_handler();
} else { }
irq_func = irq_handle_table[ip].handler; else if (ip == 2)
param = irq_handle_table[ip].param; {
liointc_isr(LIOINTC0_BASE, CORE0_INTISR0, LIOINTC0_IRQBASE);
/* do interrupt */ }
irq_func(ip, param); else if (ip == 3)
{
liointc_isr(LIOINTC1_BASE, CORE0_INTISR1, LIOINTC1_IRQBASE);
} }
} }
void rt_hw_interrupt_umask(int irq) 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) 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));
}
} }
/*@}*/ /*@}*/

View File

@ -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

View File

@ -2,12 +2,23 @@
#define _LS2K1000_H__ #define _LS2K1000_H__
#include <mips.h> #include <mips.h>
#include "interrupt.h"
#define APB_BASE CKSEG1ADDR(0xbfe00000)
#define UART0_BASE_ADDR 0xbfe00000 #define UART0_BASE_ADDR 0xbfe00000
#define UART0_OFF 0x0 #define UART0_OFF 0x0
#define UART0_BASE CKSEG1ADDR(UART0_BASE_ADDR + UART0_OFF) #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 #define PLL_SYS_BASE 0xFFFFFFFFBFE10480
void rt_hw_timer_handler(void); void rt_hw_timer_handler(void);

View File

@ -68,6 +68,12 @@
/* Device virtual file system */ /* Device virtual file system */
#define RT_USING_DFS
#define DFS_USING_WORKDIR
#define DFS_FILESYSTEMS_MAX 2
#define DFS_FILESYSTEM_TYPES_MAX 2
#define DFS_FD_MAX 16
#define RT_USING_DFS_DEVFS
/* Device Drivers */ /* Device Drivers */
@ -84,6 +90,7 @@
/* POSIX layer and C standard library */ /* POSIX layer and C standard library */
#define RT_USING_LIBC #define RT_USING_LIBC
#define RT_USING_POSIX
/* Network */ /* Network */

View File

@ -40,7 +40,7 @@ OBJDUMP = PREFIX + 'objdump'
OBJCPY = PREFIX + 'objcopy' OBJCPY = PREFIX + 'objcopy'
READELF = PREFIX + 'readelf' READELF = PREFIX + 'readelf'
DEVICE = ' -march=mips64r2 -mabi=64 -msoft-float -EL' DEVICE = ' -march=mips64r2 -mabi=64 -msoft-float -EL -mno-gpopt'
CFLAGS = DEVICE + ' -G0 -mno-abicalls -fno-pic -fno-builtin -fno-exceptions -ffunction-sections -fomit-frame-pointer' CFLAGS = DEVICE + ' -G0 -mno-abicalls -fno-pic -fno-builtin -fno-exceptions -ffunction-sections -fomit-frame-pointer'
AFLAGS = ' -c' + DEVICE + ' -fno-pic -fno-builtin -mno-abicalls -x assembler-with-cpp' AFLAGS = ' -c' + DEVICE + ' -fno-pic -fno-builtin -mno-abicalls -x assembler-with-cpp'
LFLAGS = DEVICE + ' -nostartfiles -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,Reset_Handler -T ls2k_ram.lds' LFLAGS = DEVICE + ' -nostartfiles -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,Reset_Handler -T ls2k_ram.lds'

View File

@ -39,7 +39,7 @@ void rt_hw_interrupt_enable(rt_base_t level)
/** /**
* exception handle table * exception handle table
*/ */
#define RT_EXCEPTION_MAX 31 #define RT_EXCEPTION_MAX 31
exception_func_t sys_exception_handlers[RT_EXCEPTION_MAX]; 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; return old_handler;
} }
void mips_dump_regs(struct pt_regs *regs) { void mips_dump_regs(struct pt_regs *regs)
{
int i, j; int i, j;
for(i = 0; i < 32 / 4; i++) { for (i = 0; i < 32 / 4; i++)
for(j = 0; j < 4; j++) { {
for (j = 0; j < 4; j++)
{
int reg = 4 * i + j; int reg = 4 * i + j;
rt_kprintf("%d: 0x%08x, ", reg, regs->regs[reg]); 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) 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("Unknown Exception, EPC: 0x%08x, CAUSE: 0x%08x\n", read_c0_epc(),
rt_kprintf("ST0: 0x%08x ",regs->cp0_status); read_c0_cause());
rt_kprintf("ErrorPC: 0x%08x\n",read_c0_errorepc()); rt_kprintf("ST0: 0x%08x ", regs->cp0_status);
rt_kprintf("ErrorPC: 0x%08x\n", read_c0_errorepc());
mips_dump_regs(regs); mips_dump_regs(regs);
rt_hw_cpu_shutdown(); rt_hw_cpu_shutdown();
} }
@ -95,8 +99,9 @@ static void install_default_exception_handler(void)
{ {
rt_int32_t i; rt_int32_t i;
for (i=0; i<RT_EXCEPTION_MAX; i++) for (i = 0; i < RT_EXCEPTION_MAX; i++)
sys_exception_handlers[i] = (exception_func_t)unhandled_exception_handle; sys_exception_handlers[i] =
(exception_func_t)unhandled_exception_handle;
} }
int rt_hw_exception_init(void) 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) 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; 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) if (pending & CAUSEF_IP0)
rt_do_mips_cpu_irq(0); rt_do_mips_cpu_irq(0);
if (pending & CAUSEF_IP1) if (pending & CAUSEF_IP1)
@ -141,7 +148,9 @@ void rt_general_exc_dispatch(struct pt_regs *regs)
rt_do_mips_cpu_irq(6); rt_do_mips_cpu_irq(6);
if (pending & CAUSEF_IP7) if (pending & CAUSEF_IP7)
rt_do_mips_cpu_irq(7); rt_do_mips_cpu_irq(7);
} else { }
else
{
if (sys_exception_handlers[exccode]) if (sys_exception_handlers[exccode])
sys_exception_handlers[exccode](regs); sys_exception_handlers[exccode](regs);
} }