add plic_driver.c for global interrupt
change interrupt num to 53 change stack size to 512 before system starup add uart drivers open msh remain bug: uart just interrupt ones
This commit is contained in:
parent
20f1a641d5
commit
d9c0bdc70e
|
@ -15,7 +15,7 @@ static void led_thread_entry(void* parameter)
|
||||||
unsigned int count=0;
|
unsigned int count=0;
|
||||||
|
|
||||||
rt_hw_led_init();
|
rt_hw_led_init();
|
||||||
while (1)
|
while (0)
|
||||||
{
|
{
|
||||||
/* led1 on */
|
/* led1 on */
|
||||||
#ifndef RT_USING_FINSH
|
#ifndef RT_USING_FINSH
|
||||||
|
@ -57,8 +57,11 @@ void rt_application_init()
|
||||||
}
|
}
|
||||||
|
|
||||||
init_thread = rt_thread_create("init",
|
init_thread = rt_thread_create("init",
|
||||||
rt_init_thread_entry, RT_NULL,
|
rt_init_thread_entry,
|
||||||
2048, 8, 20);
|
RT_NULL,
|
||||||
|
512,
|
||||||
|
8,
|
||||||
|
20);
|
||||||
if (init_thread != RT_NULL)
|
if (init_thread != RT_NULL)
|
||||||
rt_thread_startup(init_thread);
|
rt_thread_startup(init_thread);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -51,7 +51,6 @@ void rt_hw_board_init(void)
|
||||||
rt_components_board_init();
|
rt_components_board_init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* HW_ICOLL_CTRL_SET(BM_ICOLL_CTRL_IRQ_FINAL_ENABLE);*/
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ static void usart_init(int buard)
|
||||||
static void usart_handler(int vector, void *param)
|
static void usart_handler(int vector, void *param)
|
||||||
{
|
{
|
||||||
rt_hw_serial_isr((struct rt_serial_device*)param, RT_SERIAL_EVENT_RX_IND);
|
rt_hw_serial_isr((struct rt_serial_device*)param, RT_SERIAL_EVENT_RX_IND);
|
||||||
|
UART0_REG(UART_REG_IP) = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
static rt_err_t usart_configure(struct rt_serial_device *serial,
|
static rt_err_t usart_configure(struct rt_serial_device *serial,
|
||||||
|
@ -26,6 +27,8 @@ static rt_err_t usart_configure(struct rt_serial_device *serial,
|
||||||
GPIO_REG(GPIO_IOF_EN) |= IOF0_UART0_MASK;
|
GPIO_REG(GPIO_IOF_EN) |= IOF0_UART0_MASK;
|
||||||
UART0_REG(UART_REG_DIV) = get_cpu_freq() / 115200 - 1;
|
UART0_REG(UART_REG_DIV) = get_cpu_freq() / 115200 - 1;
|
||||||
UART0_REG(UART_REG_TXCTRL) |= UART_TXEN;
|
UART0_REG(UART_REG_TXCTRL) |= UART_TXEN;
|
||||||
|
UART0_REG(UART_REG_RXCTRL) |= UART_RXEN;
|
||||||
|
UART0_REG(UART_REG_IE) = UART_IP_RXWM;
|
||||||
return RT_EOK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
static rt_err_t usart_control(struct rt_serial_device *serial,
|
static rt_err_t usart_control(struct rt_serial_device *serial,
|
||||||
|
@ -48,8 +51,11 @@ static int usart_putc(struct rt_serial_device *serial, char c)
|
||||||
}
|
}
|
||||||
static int usart_getc(struct rt_serial_device *serial)
|
static int usart_getc(struct rt_serial_device *serial)
|
||||||
{
|
{
|
||||||
rt_uint8_t val = (rt_uint8_t) UART0_REG(UART_REG_RXFIFO);
|
rt_int32_t val = UART0_REG(UART_REG_RXFIFO);
|
||||||
return val;
|
if (val > 0)
|
||||||
|
return (rt_uint8_t)val;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
static struct rt_uart_ops ops = {
|
static struct rt_uart_ops ops = {
|
||||||
usart_configure,
|
usart_configure,
|
||||||
|
@ -69,7 +75,17 @@ static struct rt_serial_device serial = {
|
||||||
};
|
};
|
||||||
void rt_hw_uart_init(void)
|
void rt_hw_uart_init(void)
|
||||||
{
|
{
|
||||||
rt_hw_serial_register(&serial, "dusart", RT_DEVICE_FLAG_STREAM | RT_DEVICE_FLAG_RDWR
|
rt_hw_serial_register(
|
||||||
|
&serial,
|
||||||
|
"dusart",
|
||||||
|
RT_DEVICE_FLAG_STREAM
|
||||||
|
| RT_DEVICE_FLAG_RDWR
|
||||||
| RT_DEVICE_FLAG_INT_RX, RT_NULL);
|
| RT_DEVICE_FLAG_INT_RX, RT_NULL);
|
||||||
|
rt_hw_interrupt_install(
|
||||||
|
INT_UART0_BASE,
|
||||||
|
usart_handler,
|
||||||
|
(void*)&(serial.parent),
|
||||||
|
"uart interrupt");
|
||||||
|
rt_hw_interrupt_unmask(INT_UART0_BASE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
#include <rthw.h>
|
#include <rthw.h>
|
||||||
|
#include "plic_driver.h"
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
|
|
||||||
#define MAX_HANDLERS (128)
|
#define MAX_HANDLERS PLIC_NUM_INTERRUPTS
|
||||||
extern rt_uint32_t rt_interrupt_nest;
|
extern rt_uint32_t rt_interrupt_nest;
|
||||||
|
|
||||||
/* exception and interrupt handler table */
|
/* exception and interrupt handler table */
|
||||||
|
@ -10,12 +11,14 @@ struct rt_irq_desc irq_desc[MAX_HANDLERS];
|
||||||
rt_uint32_t rt_interrupt_from_thread;
|
rt_uint32_t rt_interrupt_from_thread;
|
||||||
rt_uint32_t rt_interrupt_to_thread;
|
rt_uint32_t rt_interrupt_to_thread;
|
||||||
rt_uint32_t rt_thread_switch_interrupt_flag;
|
rt_uint32_t rt_thread_switch_interrupt_flag;
|
||||||
|
plic_instance_t g_plic;
|
||||||
/**
|
/**
|
||||||
* This function will mask a interrupt.
|
* This function will mask a interrupt.
|
||||||
* @param vector the interrupt number
|
* @param vector the interrupt number
|
||||||
*/
|
*/
|
||||||
void rt_hw_interrupt_mask(int irq)
|
void rt_hw_interrupt_mask(int irq)
|
||||||
{
|
{
|
||||||
|
PLIC_disable_interrupt(&g_plic, irq);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +28,8 @@ void rt_hw_interrupt_mask(int irq)
|
||||||
*/
|
*/
|
||||||
void rt_hw_interrupt_unmask(int irq)
|
void rt_hw_interrupt_unmask(int irq)
|
||||||
{
|
{
|
||||||
|
PLIC_enable_interrupt(&g_plic, irq);
|
||||||
|
PLIC_set_priority(&g_plic, irq, 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector, void *param)
|
rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector, void *param)
|
||||||
|
@ -40,7 +45,11 @@ void rt_hw_interrupt_init(void)
|
||||||
"la t0, trap_entry\n"
|
"la t0, trap_entry\n"
|
||||||
"csrw mtvec, t0"
|
"csrw mtvec, t0"
|
||||||
);
|
);
|
||||||
/* enable interrupt*/
|
/* enable global interrupt*/
|
||||||
|
PLIC_init(&g_plic,
|
||||||
|
PLIC_CTRL_ADDR,
|
||||||
|
PLIC_NUM_INTERRUPTS,
|
||||||
|
PLIC_NUM_PRIORITIES);
|
||||||
|
|
||||||
/* init exceptions table */
|
/* init exceptions table */
|
||||||
for(idx=0; idx < MAX_HANDLERS; idx++)
|
for(idx=0; idx < MAX_HANDLERS; idx++)
|
||||||
|
@ -62,11 +71,12 @@ void rt_hw_interrupt_init(void)
|
||||||
rt_uint32_t rt_hw_interrupt_get_active(rt_uint32_t fiq_irq)
|
rt_uint32_t rt_hw_interrupt_get_active(rt_uint32_t fiq_irq)
|
||||||
{
|
{
|
||||||
//volatile rt_uint32_t irqstat;
|
//volatile rt_uint32_t irqstat;
|
||||||
rt_uint32_t id;
|
rt_uint32_t id = PLIC_claim_interrupt(&g_plic);
|
||||||
return 0;
|
return id;
|
||||||
}
|
}
|
||||||
void rt_hw_interrupt_ack(rt_uint32_t fiq_irq, rt_uint32_t id)
|
void rt_hw_interrupt_ack(rt_uint32_t fiq_irq, rt_uint32_t id)
|
||||||
{
|
{
|
||||||
|
PLIC_complete_interrupt(&g_plic, id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,127 @@
|
||||||
|
// See LICENSE for license details.
|
||||||
|
|
||||||
|
#include "sifive/devices/plic.h"
|
||||||
|
#include "plic_driver.h"
|
||||||
|
#include "platform.h"
|
||||||
|
#include "encoding.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
// Note that there are no assertions or bounds checking on these
|
||||||
|
// parameter values.
|
||||||
|
|
||||||
|
void volatile_memzero(uint8_t * base, unsigned int size)
|
||||||
|
{
|
||||||
|
volatile uint8_t * ptr;
|
||||||
|
for (ptr = base; ptr < (base + size); ptr++){
|
||||||
|
*ptr = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PLIC_init (
|
||||||
|
plic_instance_t * this_plic,
|
||||||
|
uintptr_t base_addr,
|
||||||
|
uint32_t num_sources,
|
||||||
|
uint32_t num_priorities
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
this_plic->base_addr = base_addr;
|
||||||
|
this_plic->num_sources = num_sources;
|
||||||
|
this_plic->num_priorities = num_priorities;
|
||||||
|
|
||||||
|
// Disable all interrupts (don't assume that these registers are reset).
|
||||||
|
unsigned long hart_id = read_csr(mhartid);
|
||||||
|
volatile_memzero((uint8_t*) (this_plic->base_addr +
|
||||||
|
PLIC_ENABLE_OFFSET +
|
||||||
|
(hart_id << PLIC_ENABLE_SHIFT_PER_TARGET)),
|
||||||
|
(num_sources + 8) / 8);
|
||||||
|
|
||||||
|
// Set all priorities to 0 (equal priority -- don't assume that these are reset).
|
||||||
|
volatile_memzero ((uint8_t *)(this_plic->base_addr +
|
||||||
|
PLIC_PRIORITY_OFFSET),
|
||||||
|
(num_sources + 1) << PLIC_PRIORITY_SHIFT_PER_SOURCE);
|
||||||
|
|
||||||
|
// Set the threshold to 0.
|
||||||
|
volatile plic_threshold* threshold = (plic_threshold*)
|
||||||
|
(this_plic->base_addr +
|
||||||
|
PLIC_THRESHOLD_OFFSET +
|
||||||
|
(hart_id << PLIC_THRESHOLD_SHIFT_PER_TARGET));
|
||||||
|
|
||||||
|
*threshold = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PLIC_set_threshold (plic_instance_t * this_plic,
|
||||||
|
plic_threshold threshold){
|
||||||
|
|
||||||
|
unsigned long hart_id = read_csr(mhartid);
|
||||||
|
volatile plic_threshold* threshold_ptr = (plic_threshold*) (this_plic->base_addr +
|
||||||
|
PLIC_THRESHOLD_OFFSET +
|
||||||
|
(hart_id << PLIC_THRESHOLD_SHIFT_PER_TARGET));
|
||||||
|
|
||||||
|
*threshold_ptr = threshold;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PLIC_enable_interrupt (plic_instance_t * this_plic, plic_source source){
|
||||||
|
|
||||||
|
unsigned long hart_id = read_csr(mhartid);
|
||||||
|
volatile uint8_t * current_ptr = (volatile uint8_t *)(this_plic->base_addr +
|
||||||
|
PLIC_ENABLE_OFFSET +
|
||||||
|
(hart_id << PLIC_ENABLE_SHIFT_PER_TARGET) +
|
||||||
|
(source >> 3));
|
||||||
|
uint8_t current = *current_ptr;
|
||||||
|
current = current | ( 1 << (source & 0x7));
|
||||||
|
*current_ptr = current;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PLIC_disable_interrupt (plic_instance_t * this_plic, plic_source source){
|
||||||
|
|
||||||
|
unsigned long hart_id = read_csr(mhartid);
|
||||||
|
volatile uint8_t * current_ptr = (volatile uint8_t *) (this_plic->base_addr +
|
||||||
|
PLIC_ENABLE_OFFSET +
|
||||||
|
(hart_id << PLIC_ENABLE_SHIFT_PER_TARGET) +
|
||||||
|
(source >> 3));
|
||||||
|
uint8_t current = *current_ptr;
|
||||||
|
current = current & ~(( 1 << (source & 0x7)));
|
||||||
|
*current_ptr = current;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PLIC_set_priority (plic_instance_t * this_plic, plic_source source, plic_priority priority){
|
||||||
|
|
||||||
|
if (this_plic->num_priorities > 0) {
|
||||||
|
volatile plic_priority * priority_ptr = (volatile plic_priority *)
|
||||||
|
(this_plic->base_addr +
|
||||||
|
PLIC_PRIORITY_OFFSET +
|
||||||
|
(source << PLIC_PRIORITY_SHIFT_PER_SOURCE));
|
||||||
|
*priority_ptr = priority;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plic_source PLIC_claim_interrupt(plic_instance_t * this_plic){
|
||||||
|
|
||||||
|
unsigned long hart_id = read_csr(mhartid);
|
||||||
|
|
||||||
|
volatile plic_source * claim_addr = (volatile plic_source * )
|
||||||
|
(this_plic->base_addr +
|
||||||
|
PLIC_CLAIM_OFFSET +
|
||||||
|
(hart_id << PLIC_CLAIM_SHIFT_PER_TARGET));
|
||||||
|
|
||||||
|
return *claim_addr;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PLIC_complete_interrupt(plic_instance_t * this_plic, plic_source source){
|
||||||
|
|
||||||
|
unsigned long hart_id = read_csr(mhartid);
|
||||||
|
volatile plic_source * claim_addr = (volatile plic_source *) (this_plic->base_addr +
|
||||||
|
PLIC_CLAIM_OFFSET +
|
||||||
|
(hart_id << PLIC_CLAIM_SHIFT_PER_TARGET));
|
||||||
|
*claim_addr = source;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
// See LICENSE file for licence details
|
||||||
|
|
||||||
|
#ifndef PLIC_DRIVER_H
|
||||||
|
#define PLIC_DRIVER_H
|
||||||
|
|
||||||
|
#include "platform.h"
|
||||||
|
|
||||||
|
typedef struct __plic_instance_t
|
||||||
|
{
|
||||||
|
uintptr_t base_addr;
|
||||||
|
|
||||||
|
uint32_t num_sources;
|
||||||
|
uint32_t num_priorities;
|
||||||
|
|
||||||
|
} plic_instance_t;
|
||||||
|
|
||||||
|
typedef uint32_t plic_source;
|
||||||
|
typedef uint32_t plic_priority;
|
||||||
|
typedef uint32_t plic_threshold;
|
||||||
|
|
||||||
|
void PLIC_init (
|
||||||
|
plic_instance_t * this_plic,
|
||||||
|
uintptr_t base_addr,
|
||||||
|
uint32_t num_sources,
|
||||||
|
uint32_t num_priorities
|
||||||
|
);
|
||||||
|
|
||||||
|
void PLIC_set_threshold (plic_instance_t * this_plic,
|
||||||
|
plic_threshold threshold);
|
||||||
|
|
||||||
|
void PLIC_enable_interrupt (plic_instance_t * this_plic,
|
||||||
|
plic_source source);
|
||||||
|
|
||||||
|
void PLIC_disable_interrupt (plic_instance_t * this_plic,
|
||||||
|
plic_source source);
|
||||||
|
|
||||||
|
void PLIC_set_priority (plic_instance_t * this_plic,
|
||||||
|
plic_source source,
|
||||||
|
plic_priority priority);
|
||||||
|
|
||||||
|
plic_source PLIC_claim_interrupt(plic_instance_t * this_plic);
|
||||||
|
|
||||||
|
void PLIC_complete_interrupt(plic_instance_t * this_plic,
|
||||||
|
plic_source source);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -17,10 +17,10 @@
|
||||||
/* SECTION: RT_DEBUG */
|
/* SECTION: RT_DEBUG */
|
||||||
/* Thread Debug */
|
/* Thread Debug */
|
||||||
#define RT_DEBUG
|
#define RT_DEBUG
|
||||||
#define RT_DEBUG_TIMER 1
|
#define RT_DEBUG_TIMER 0
|
||||||
/*#define RT_DEBUG_IRQ 1*/
|
/*#define RT_DEBUG_IRQ 1*/
|
||||||
#define RT_DEBUG_SCHEDULER 1
|
#define RT_DEBUG_SCHEDULER 0
|
||||||
#define RT_DEBUG_THREAD 1
|
#define RT_DEBUG_THREAD 0
|
||||||
|
|
||||||
#define RT_USING_OVERFLOW_CHECK
|
#define RT_USING_OVERFLOW_CHECK
|
||||||
|
|
||||||
|
@ -32,8 +32,8 @@
|
||||||
/* Using Software Timer */
|
/* Using Software Timer */
|
||||||
#define RT_USING_TIMER_SOFT
|
#define RT_USING_TIMER_SOFT
|
||||||
#define RT_TIMER_THREAD_PRIO 8
|
#define RT_TIMER_THREAD_PRIO 8
|
||||||
#define RT_TIMER_THREAD_STACK_SIZE 1024
|
#define RT_TIMER_THREAD_STACK_SIZE 512
|
||||||
#define RT_TIMER_TICK_PER_SECOND 10
|
#define RT_TIMER_TICK_PER_SECOND 50
|
||||||
|
|
||||||
/* SECTION: IPC */
|
/* SECTION: IPC */
|
||||||
/* Using Semaphore */
|
/* Using Semaphore */
|
||||||
|
@ -88,7 +88,7 @@
|
||||||
|
|
||||||
/* SECTION: finsh, a C-Express shell */
|
/* SECTION: finsh, a C-Express shell */
|
||||||
/* Using FinSH as Shell*/
|
/* Using FinSH as Shell*/
|
||||||
/*#define RT_USING_FINSH*/
|
#define RT_USING_FINSH
|
||||||
/* Using symbol table */
|
/* Using symbol table */
|
||||||
#define FINSH_USING_SYMTAB
|
#define FINSH_USING_SYMTAB
|
||||||
#define FINSH_USING_DESCRIPTION
|
#define FINSH_USING_DESCRIPTION
|
||||||
|
|
|
@ -18,7 +18,7 @@ PHDRS
|
||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
__stack_size = DEFINED(__stack_size) ? __stack_size : 2K;
|
__stack_size = DEFINED(__stack_size) ? __stack_size : 512;
|
||||||
. = 0x20400000;
|
. = 0x20400000;
|
||||||
|
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
|
|
Loading…
Reference in New Issue