瀏覽代碼

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

zhangjun 8 年之前
父節點
當前提交
d9c0bdc70e

+ 6 - 3
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;

+ 0 - 1
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;
 }
 

+ 19 - 3
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;
 }

+ 14 - 4
bsp/risc-v/platform/interrupt.c

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

+ 127 - 0
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 <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;
+  
+}
+

+ 47 - 0
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

+ 6 - 6
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

+ 1 - 1
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);