Browse Source

fix bug in rt_hw_context_switch_interrupt_do
save sp to old thread
clear rt_thread_switch_interrupt_flag
always enable interrupt after rt_hw_context_switch
judeg the type of interrupt in trap_entry, then call handler(Machine timer interrupt of Machine external interrupt)

zhangjun 7 năm trước cách đây
mục cha
commit
b032dff161

+ 4 - 5
bsp/risc-v/applications/applications.c

@@ -15,17 +15,16 @@ static void led_thread_entry(void* parameter)
     unsigned int count=0;
 
     rt_hw_led_init();
-    rt_kprintf("core freq at %d Hz\n", get_cpu_freq());
     while (1)
     {
         /* led1 on */
 #ifndef RT_USING_FINSH
 /*        rt_kprintf("led on, count : %d\r\n",count);*/
 #endif
+	    rt_kprintf("core freq at %d Hz\n", get_cpu_freq());
         count++;
         rt_thread_delay( RT_TIMER_TICK_PER_SECOND/2 ); /* sleep 0.5 second and switch to other thread */
-    while(1);
-        rt_hw_led_on(0);
+/*        rt_hw_led_on(0);*/
 
         /* led1 off */
 #ifndef RT_USING_FINSH
@@ -33,10 +32,10 @@ static void led_thread_entry(void* parameter)
 #endif
         rt_hw_led_off(0);
 
-        rt_thread_delay( RT_TIMER_TICK_PER_SECOND*2);
+/*        rt_thread_delay( RT_TIMER_TICK_PER_SECOND*2);*/
     }
 }
-static rt_uint8_t led_stack[ 2048 ];
+static rt_uint8_t led_stack[ 1024];
 static struct rt_thread led_thread;
 void rt_application_init()
 {

+ 5 - 9
bsp/risc-v/drivers/board.c

@@ -14,11 +14,6 @@ static struct mem_desc hw_mem_desc[] =
 };
 #endif
 
-static void rt_systick_handler(int vector, void *param)
-{
-        rt_tick_increase();
-	return;
-}
 #include <encoding.h>
 static void rt_hw_timer_init(void)
 {
@@ -26,11 +21,12 @@ static void rt_hw_timer_init(void)
 	GPIO_REG(GPIO_OUTPUT_EN)   |=  ((0x1<< RED_LED_OFFSET)| (0x1<< GREEN_LED_OFFSET) | (0x1 << BLUE_LED_OFFSET)) ;
 	GPIO_REG(GPIO_OUTPUT_VAL)  |=   (0x1 << BLUE_LED_OFFSET) ;
 	GPIO_REG(GPIO_OUTPUT_VAL)  &=  ~((0x1<< RED_LED_OFFSET) | (0x1<< GREEN_LED_OFFSET)) ;
-	rt_hw_interrupt_enable(1);
-
-	CLINT_REG(CLINT_MTIME) = 0x0;
-	CLINT_REG(CLINT_MTIMECMP) = 0x10000;
+	
+/*	enable timer interrupt*/
+ 	set_csr(mie, MIP_MTIP);	
 	volatile uint64_t * mtimecmp    = (uint64_t*) (CLINT_CTRL_ADDR + CLINT_MTIMECMP);
+	CLINT_REG(CLINT_MTIME) = 0x0;
+/*	CLINT_REG(CLINT_MTIMECMP) = 0x10000;*/
 	*mtimecmp = 0x20000;
 	return;
 }

+ 76 - 81
bsp/risc-v/drivers/led.c

@@ -75,87 +75,82 @@ void rt_hw_led_on(int led)
 {
 
 	/*
-  // Make sure the HFROSC is on before the next line:
-  PRCI_REG(PRCI_HFROSCCFG) |= ROSC_EN(1);
-  // Run off 16 MHz Crystal for accuracy. Note that the
-  // first line is 
-  PRCI_REG(PRCI_PLLCFG) = (PLL_REFSEL(1) | PLL_BYPASS(1));
-  PRCI_REG(PRCI_PLLCFG) |= (PLL_SEL(1));
-  // Turn off HFROSC to save power
-  PRCI_REG(PRCI_HFROSCCFG) &= ~(ROSC_EN(1));
-  */
-  
-
-  // Wait a bit to avoid corruption on the UART.
-  // (In some cases, switching to the IOF can lead
-  // to output glitches, so need to let the UART
-  // reciever time out and resynchronize to the real 
-  // start of the stream.
-  volatile int i=0;
-  while(i < 10000){i++;}
-
-  _puts(sifive_msg);
-  //_puts("Config String:\n\r");
-  //_puts(*((const char **) 0x100C));
-  //_puts("\n\r");
-  _puts(led_msg);
-  uint16_t r=0xFF;
-  uint16_t g=0;
-  uint16_t b=0;
-  char c = 0;
-  
-  // Set up RGB PWM
-  
- /* 
-  PWM1_REG(PWM_CFG)   = 0;
-  // To balance the power consumption, make one left, one right, and one center aligned.
-  PWM1_REG(PWM_CFG)   = (PWM_CFG_ENALWAYS) | (PWM_CFG_CMP2CENTER);
-  PWM1_REG(PWM_COUNT) = 0;
-  
-  // Period is approximately 244 Hz
-  // the LEDs are intentionally left somewhat dim, 
-  // as the full brightness can be painful to look at.
-  PWM1_REG(PWM_CMP0)  = 0;
-  */
-
-
-  while(1){
-  
-    if(r > 0 && b == 0){
-      r--;
-      g++;
-    }
-    if(g > 0 && r == 0){
-      g--;
-      b++;
-    }
-    if(b > 0 && g == 0){
-      r++;
-      b--;
-    }
-    
-    uint32_t G = g;
-    uint32_t R = r;
-    uint32_t B = b;
-    
-    PWM1_REG(PWM_CMP1)  = G << 4;            // PWM is low on the left, GPIO is low on the left side, LED is ON on the left.
-    PWM1_REG(PWM_CMP2)  = (B << 1) << 4;     // PWM is high on the middle, GPIO is low in the middle, LED is ON in the middle.
-    PWM1_REG(PWM_CMP3)  = 0xFFFF - (R << 4); // PWM is low on the left, GPIO is low on the right, LED is on on the right.
-  
-    // Check for user input
-    if (c == 0){
-      if (_getc(&c) != 0){
-        _putc(c);
-        _puts("\n\r");
-        
-        if ((c == 'y') || (c == 'Y')){
-          _puts("PASS\n\r");
-        } else{
-          _puts("FAIL\n\r");
-        }
-      }
-    }
-  }
+	// Make sure the HFROSC is on before the next line:
+	PRCI_REG(PRCI_HFROSCCFG) |= ROSC_EN(1);
+	// Run off 16 MHz Crystal for accuracy. Note that the
+	// first line is 
+	PRCI_REG(PRCI_PLLCFG) = (PLL_REFSEL(1) | PLL_BYPASS(1));
+	PRCI_REG(PRCI_PLLCFG) |= (PLL_SEL(1));
+	// Turn off HFROSC to save power
+	PRCI_REG(PRCI_HFROSCCFG) &= ~(ROSC_EN(1));
+	*/
+
+
+	// Wait a bit to avoid corruption on the UART.
+	// (In some cases, switching to the IOF can lead
+	// to output glitches, so need to let the UART
+	// reciever time out and resynchronize to the real 
+	// start of the stream.
+	volatile int i=0;
+	while(i < 10000){i++;}
+
+	_puts(sifive_msg);
+	//_puts("Config String:\n\r");
+	//_puts(*((const char **) 0x100C));
+	//_puts("\n\r");
+	_puts(led_msg);
+	uint16_t r=0xFF;
+	uint16_t g=0;
+	uint16_t b=0;
+	char c = 0;
+
+	// Set up RGB PWM
+
+	/* 
+	   PWM1_REG(PWM_CFG)   = 0;
+	// To balance the power consumption, make one left, one right, and one center aligned.
+	PWM1_REG(PWM_CFG)   = (PWM_CFG_ENALWAYS) | (PWM_CFG_CMP2CENTER);
+	PWM1_REG(PWM_COUNT) = 0;
+
+	// Period is approximately 244 Hz
+	// the LEDs are intentionally left somewhat dim, 
+	// as the full brightness can be painful to look at.
+	PWM1_REG(PWM_CMP0)  = 0;
+	*/
+	if(r > 0 && b == 0){
+		r--;
+		g++;
+	}
+	if(g > 0 && r == 0){
+		g--;
+		b++;
+	}
+	if(b > 0 && g == 0){
+		r++;
+		b--;
+	}
+
+	uint32_t G = g;
+	uint32_t R = r;
+	uint32_t B = b;
+
+	PWM1_REG(PWM_CMP1)  = G << 4;            // PWM is low on the left, GPIO is low on the left side, LED is ON on the left.
+	PWM1_REG(PWM_CMP2)  = (B << 1) << 4;     // PWM is high on the middle, GPIO is low in the middle, LED is ON in the middle.
+	PWM1_REG(PWM_CMP3)  = 0xFFFF - (R << 4); // PWM is low on the left, GPIO is low on the right, LED is on on the right.
+
+	// Check for user input
+	if (c == 0){
+		if (_getc(&c) != 0){
+			_putc(c);
+			_puts("\n\r");
+
+			if ((c == 'y') || (c == 'Y')){
+				_puts("PASS\n\r");
+			} else{
+				_puts("FAIL\n\r");
+			}
+		}
+	}
 	return;
 }
 void rt_hw_led_off(int led)

+ 21 - 6
libcpu/risc-v/e310/context_gcc.S

@@ -32,9 +32,21 @@
 rt_hw_interrupt_disable:
   addi sp, sp, -12
   sw a5, (sp)
+  li a5, 0x800
   csrr a0, mie
-  li a5, MIP_MEIP|MIP_MTIP|MIP_MSIP
-/*  csrrc a5, mstatus, MSTATUS_MIE*/
+  blt a0, a5, 1f
+/*  interrupt is enable before disable it*/
+  addi a0, a0, 1
+
+  li a5, 0x1
+  addi a5, a5, -2048
+  csrrc a5, mie, a5
+/*  csrrc a5, mie, 128*/
+  j 2f
+/*  interrupt is disabled before disable it*/
+1:
+  li a0, 0
+2:
   lw a5, (sp)
   addi sp, sp, 12
   ret
@@ -46,9 +58,12 @@ rt_hw_interrupt_disable:
 rt_hw_interrupt_enable:
   addi sp, sp, -12
   sw a5, (sp)
-  li a5, MIP_MEIP|MIP_MTIP|MIP_MSIP
+  beqz a0, 1f
+  li a5, 0x1
+  addi a5, a5, -2048
   csrrs a5, mie, a5
-/*  csrrsi a5, mstatus, MSTATUS_MIE*/
+/*  csrrs a5, mie, 128*/
+1:
   lw a5, (sp)
   addi sp, sp, 12
   ret
@@ -98,8 +113,8 @@ rt_hw_context_switch:
  *Remain in M-mode after mret
  *enable interrupt in M-mode
  */
-  li t0, MSTATUS_MPIE|MSTATUS_MPP
-  csrs mstatus, t0
+  li t0, 136
+  csrrs t0, mstatus, t0
 
   LOAD sp,  (a1)
   LOAD x30, 1*REGBYTES(sp)

+ 0 - 20
libcpu/risc-v/e310/init.c

@@ -187,26 +187,6 @@ extern void handle_m_ext_interrupt();
 extern void handle_m_time_interrupt();
 #endif
 
-uintptr_t handle_trap(uintptr_t mcause, uintptr_t epc)
-{
-  if (0){
-#ifdef USE_PLIC
-    // External Machine-Level interrupt from PLIC
-  } else if ((mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_EXT)) {
-    handle_m_ext_interrupt();
-#endif
-#ifdef USE_M_TIME
-    // External Machine-Level interrupt from PLIC
-  } else if ((mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_TIMER)){
-    handle_m_time_interrupt();
-#endif
-  }
-  else {
-    write(1, "trap\n", 5);
-    _exit(1 + mcause);
-  }
-  return epc;
-}
 
 void _init()
 {

+ 28 - 9
libcpu/risc-v/e310/start_gcc.S

@@ -36,7 +36,10 @@ _start:
 	la gp, __global_pointer$
 .option pop
 	la sp, _sp
-	csrrsi a5, mstatus, 0
+/*
+ *disable all interrupt at startup
+ */
+	csrrc a5, mstatus, 0xb
 
 #if defined(ENABLE_SMP)
 	smp_pause(t0, t1)
@@ -69,6 +72,7 @@ _start:
 	la a0, __libc_fini_array
 	call atexit
 	call __libc_init_array
+	/*call _init directly in rt-thread*/
         call _init
 
 #ifndef __riscv_float_abi_soft
@@ -175,17 +179,31 @@ trap_entry:
 
 
   call rt_interrupt_enter
+  csrr a0, mcause
+  lui  a5, 0x80000 
+  not  a5, a5
+  and  a5, a5, a0
+  li   a4, 11
+  mv   s1, a1
+  /*Machine external interrupt*/
+  bne  a5, a4, 1f
   call rt_hw_trap_irq
-  call handle_m_time_interrupt
+1:
+  /*Machine software interrupt*/
+  li   a4, 7
+  bne  a5, a4, 2f
+  call rt_systick_handler
+2:
   call rt_interrupt_leave
 
-  la a0, rt_thread_switch_interrupt_flag
-  lw a1, (a0)
+  # Remain in M-mode after mret
+  li    t0, 136
+  csrrs t0, mstatus, t0
+
+  la   a0, rt_thread_switch_interrupt_flag
+  lw   a1, (a0)
   bnez a1, rt_hw_context_switch_interrupt_do
 
-  # Remain in M-mode after mret
-  li t0, MSTATUS_MPP
-  csrs mstatus, t0
 
   LOAD x30, 1*REGBYTES(sp)
   LOAD x31, 2*REGBYTES(sp)
@@ -225,12 +243,13 @@ trap_entry:
   mret
 
 rt_hw_context_switch_interrupt_do:
-
+  /*clear rt_thread_switch_interrupt_flag*/
   la   a0, rt_thread_switch_interrupt_flag
-  lw   a5, (a0)
   li   a5, 0
   sw   a5, (a0)
 
+  LOAD a0,  rt_interrupt_from_thread
+  STORE sp,  (a0)
   LOAD a0,  rt_interrupt_to_thread
   LOAD sp,  (a0)
   LOAD x30, 1*REGBYTES(sp)