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:
zhangjun 2017-07-30 22:36:12 +08:00
parent 20f1a641d5
commit d9c0bdc70e
8 changed files with 220 additions and 18 deletions

View File

@ -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;

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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;
} }
/** /**

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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);