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;
|
||||
|
||||
rt_hw_led_init();
|
||||
while (1)
|
||||
while (0)
|
||||
{
|
||||
/* led1 on */
|
||||
#ifndef RT_USING_FINSH
|
||||
|
@ -57,8 +57,11 @@ void rt_application_init()
|
|||
}
|
||||
|
||||
init_thread = rt_thread_create("init",
|
||||
rt_init_thread_entry, RT_NULL,
|
||||
2048, 8, 20);
|
||||
rt_init_thread_entry,
|
||||
RT_NULL,
|
||||
512,
|
||||
8,
|
||||
20);
|
||||
if (init_thread != RT_NULL)
|
||||
rt_thread_startup(init_thread);
|
||||
return;
|
||||
|
|
|
@ -51,7 +51,6 @@ void rt_hw_board_init(void)
|
|||
rt_components_board_init();
|
||||
#endif
|
||||
|
||||
/* HW_ICOLL_CTRL_SET(BM_ICOLL_CTRL_IRQ_FINAL_ENABLE);*/
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ static void usart_init(int buard)
|
|||
static void usart_handler(int vector, void *param)
|
||||
{
|
||||
rt_hw_serial_isr((struct rt_serial_device*)param, RT_SERIAL_EVENT_RX_IND);
|
||||
UART0_REG(UART_REG_IP) = 0;
|
||||
return;
|
||||
}
|
||||
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;
|
||||
UART0_REG(UART_REG_DIV) = get_cpu_freq() / 115200 - 1;
|
||||
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;
|
||||
}
|
||||
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)
|
||||
{
|
||||
rt_uint8_t val = (rt_uint8_t) UART0_REG(UART_REG_RXFIFO);
|
||||
return val;
|
||||
rt_int32_t val = UART0_REG(UART_REG_RXFIFO);
|
||||
if (val > 0)
|
||||
return (rt_uint8_t)val;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
static struct rt_uart_ops ops = {
|
||||
usart_configure,
|
||||
|
@ -69,7 +75,17 @@ static struct rt_serial_device serial = {
|
|||
};
|
||||
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_hw_interrupt_install(
|
||||
INT_UART0_BASE,
|
||||
usart_handler,
|
||||
(void*)&(serial.parent),
|
||||
"uart interrupt");
|
||||
rt_hw_interrupt_unmask(INT_UART0_BASE);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#include <rthw.h>
|
||||
#include "plic_driver.h"
|
||||
#include "platform.h"
|
||||
|
||||
#define MAX_HANDLERS (128)
|
||||
#define MAX_HANDLERS PLIC_NUM_INTERRUPTS
|
||||
extern rt_uint32_t rt_interrupt_nest;
|
||||
|
||||
/* 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_to_thread;
|
||||
rt_uint32_t rt_thread_switch_interrupt_flag;
|
||||
plic_instance_t g_plic;
|
||||
/**
|
||||
* This function will mask a interrupt.
|
||||
* @param vector the interrupt number
|
||||
*/
|
||||
void rt_hw_interrupt_mask(int irq)
|
||||
{
|
||||
PLIC_disable_interrupt(&g_plic, irq);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -25,6 +28,8 @@ void rt_hw_interrupt_mask(int irq)
|
|||
*/
|
||||
void rt_hw_interrupt_unmask(int irq)
|
||||
{
|
||||
PLIC_enable_interrupt(&g_plic, irq);
|
||||
PLIC_set_priority(&g_plic, irq, 1);
|
||||
return;
|
||||
}
|
||||
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"
|
||||
"csrw mtvec, t0"
|
||||
);
|
||||
/* enable interrupt*/
|
||||
/* enable global interrupt*/
|
||||
PLIC_init(&g_plic,
|
||||
PLIC_CTRL_ADDR,
|
||||
PLIC_NUM_INTERRUPTS,
|
||||
PLIC_NUM_PRIORITIES);
|
||||
|
||||
/* init exceptions table */
|
||||
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)
|
||||
{
|
||||
//volatile rt_uint32_t irqstat;
|
||||
rt_uint32_t id;
|
||||
return 0;
|
||||
rt_uint32_t id = PLIC_claim_interrupt(&g_plic);
|
||||
return id;
|
||||
}
|
||||
void rt_hw_interrupt_ack(rt_uint32_t fiq_irq, rt_uint32_t id)
|
||||
{
|
||||
PLIC_complete_interrupt(&g_plic, id);
|
||||
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 */
|
||||
/* Thread Debug */
|
||||
#define RT_DEBUG
|
||||
#define RT_DEBUG_TIMER 1
|
||||
#define RT_DEBUG_TIMER 0
|
||||
/*#define RT_DEBUG_IRQ 1*/
|
||||
#define RT_DEBUG_SCHEDULER 1
|
||||
#define RT_DEBUG_THREAD 1
|
||||
#define RT_DEBUG_SCHEDULER 0
|
||||
#define RT_DEBUG_THREAD 0
|
||||
|
||||
#define RT_USING_OVERFLOW_CHECK
|
||||
|
||||
|
@ -32,8 +32,8 @@
|
|||
/* Using Software Timer */
|
||||
#define RT_USING_TIMER_SOFT
|
||||
#define RT_TIMER_THREAD_PRIO 8
|
||||
#define RT_TIMER_THREAD_STACK_SIZE 1024
|
||||
#define RT_TIMER_TICK_PER_SECOND 10
|
||||
#define RT_TIMER_THREAD_STACK_SIZE 512
|
||||
#define RT_TIMER_TICK_PER_SECOND 50
|
||||
|
||||
/* SECTION: IPC */
|
||||
/* Using Semaphore */
|
||||
|
@ -88,7 +88,7 @@
|
|||
|
||||
/* SECTION: finsh, a C-Express shell */
|
||||
/* Using FinSH as Shell*/
|
||||
/*#define RT_USING_FINSH*/
|
||||
#define RT_USING_FINSH
|
||||
/* Using symbol table */
|
||||
#define FINSH_USING_SYMTAB
|
||||
#define FINSH_USING_DESCRIPTION
|
||||
|
|
|
@ -18,7 +18,7 @@ PHDRS
|
|||
|
||||
SECTIONS
|
||||
{
|
||||
__stack_size = DEFINED(__stack_size) ? __stack_size : 2K;
|
||||
__stack_size = DEFINED(__stack_size) ? __stack_size : 512;
|
||||
. = 0x20400000;
|
||||
|
||||
. = ALIGN(4);
|
||||
|
|
Loading…
Reference in New Issue