From d9c0bdc70e6c4f2b1a091fe442e4bcc58a7fe361 Mon Sep 17 00:00:00 2001 From: zhangjun <2281979437@qq.com> Date: Sun, 30 Jul 2017 22:36:12 +0800 Subject: [PATCH] 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 --- bsp/risc-v/applications/applications.c | 9 +- bsp/risc-v/drivers/board.c | 1 - bsp/risc-v/drivers/usart.c | 22 ++++- bsp/risc-v/platform/interrupt.c | 18 +++- bsp/risc-v/platform/plic_driver.c | 127 +++++++++++++++++++++++++ bsp/risc-v/platform/plic_driver.h | 47 +++++++++ bsp/risc-v/rtconfig.h | 12 +-- bsp/risc-v/sdram.ld | 2 +- 8 files changed, 220 insertions(+), 18 deletions(-) create mode 100644 bsp/risc-v/platform/plic_driver.c create mode 100644 bsp/risc-v/platform/plic_driver.h diff --git a/bsp/risc-v/applications/applications.c b/bsp/risc-v/applications/applications.c index bba2b58053..aaae803c76 100644 --- a/bsp/risc-v/applications/applications.c +++ b/bsp/risc-v/applications/applications.c @@ -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; diff --git a/bsp/risc-v/drivers/board.c b/bsp/risc-v/drivers/board.c index 3915d4bac3..fa29d146f7 100644 --- a/bsp/risc-v/drivers/board.c +++ b/bsp/risc-v/drivers/board.c @@ -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; } diff --git a/bsp/risc-v/drivers/usart.c b/bsp/risc-v/drivers/usart.c index 24f346ec0c..ee34e17d59 100644 --- a/bsp/risc-v/drivers/usart.c +++ b/bsp/risc-v/drivers/usart.c @@ -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; } diff --git a/bsp/risc-v/platform/interrupt.c b/bsp/risc-v/platform/interrupt.c index b0ac8927b0..c4b2d73d95 100644 --- a/bsp/risc-v/platform/interrupt.c +++ b/bsp/risc-v/platform/interrupt.c @@ -1,7 +1,8 @@ #include +#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; } /** diff --git a/bsp/risc-v/platform/plic_driver.c b/bsp/risc-v/platform/plic_driver.c new file mode 100644 index 0000000000..01b7e6edb1 --- /dev/null +++ b/bsp/risc-v/platform/plic_driver.c @@ -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 + + +// 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; + +} + diff --git a/bsp/risc-v/platform/plic_driver.h b/bsp/risc-v/platform/plic_driver.h new file mode 100644 index 0000000000..92c2a29ec5 --- /dev/null +++ b/bsp/risc-v/platform/plic_driver.h @@ -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 diff --git a/bsp/risc-v/rtconfig.h b/bsp/risc-v/rtconfig.h index 46ac2ddf5d..016961963e 100644 --- a/bsp/risc-v/rtconfig.h +++ b/bsp/risc-v/rtconfig.h @@ -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 diff --git a/bsp/risc-v/sdram.ld b/bsp/risc-v/sdram.ld index 189e611f17..43d70c5026 100644 --- a/bsp/risc-v/sdram.ld +++ b/bsp/risc-v/sdram.ld @@ -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);