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

View File

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

View File

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

View File

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

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 */
/* 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

View File

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