mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-10-07 00:59:00 +08:00
fix ls2k libc and irq
This commit is contained in:
+132
-15
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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__
|
||||
|
||||
+163
-15
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user