fix ls2k libc and irq
This commit is contained in:
parent
eb0544c847
commit
1ec681a551
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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__
|
||||||
|
|
|
@ -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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
|
@ -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__
|
#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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue