Explorar o código

[bsp][d1] add interrupt manage, move c906 to libcpu

jasonhu %!s(int64=4) %!d(string=hai) anos
pai
achega
ad288e6d85
Modificáronse 42 ficheiros con 729 adicións e 312 borrados
  1. 9 0
      bsp/d1-allwinner-nezha/.gitignore
  2. 3 0
      bsp/d1-allwinner-nezha/BUGS.md
  3. 1 1
      bsp/d1-allwinner-nezha/Kconfig
  4. 1 0
      bsp/d1-allwinner-nezha/README.md
  5. 1 1
      bsp/d1-allwinner-nezha/SConstruct
  6. 1 1
      bsp/d1-allwinner-nezha/applications/main.c
  7. 26 204
      bsp/d1-allwinner-nezha/drivers/board.c
  8. 1 1
      bsp/d1-allwinner-nezha/drivers/board.h
  9. 18 18
      bsp/d1-allwinner-nezha/drivers/drv_uart.c
  10. 8 0
      bsp/d1-allwinner-nezha/drivers/encoding.h
  11. 1 1
      bsp/d1-allwinner-nezha/drivers/io.h
  12. 3 0
      bsp/d1-allwinner-nezha/libraries/README.md
  13. 1 1
      bsp/d1-allwinner-nezha/rtconfig.py
  14. 10 0
      bsp/d1-allwinner-nezha/sdcard.bat
  15. 3 1
      libcpu/risc-v/SConscript
  16. 0 2
      libcpu/risc-v/t-head/c906/SConscript
  17. 1 1
      libcpu/risc-v/t-head/c906/cache.c
  18. 0 0
      libcpu/risc-v/t-head/c906/context_gcc.S
  19. 8 8
      libcpu/risc-v/t-head/c906/cpuport.c
  20. 4 2
      libcpu/risc-v/t-head/c906/cpuport.h
  21. 105 0
      libcpu/risc-v/t-head/c906/interrupt.c
  22. 2 2
      libcpu/risc-v/t-head/c906/interrupt_gcc.S
  23. 9 9
      libcpu/risc-v/t-head/c906/mmu.c
  24. 1 1
      libcpu/risc-v/t-head/c906/mmu.h
  25. 5 5
      libcpu/risc-v/t-head/c906/page.c
  26. 0 0
      libcpu/risc-v/t-head/c906/page.h
  27. 74 0
      libcpu/risc-v/t-head/c906/plic.c
  28. 34 0
      libcpu/risc-v/t-head/c906/plic.h
  29. 1 1
      libcpu/risc-v/t-head/c906/riscv.h
  30. 25 25
      libcpu/risc-v/t-head/c906/riscv_io.h
  31. 1 1
      libcpu/risc-v/t-head/c906/riscv_mmu.c
  32. 1 1
      libcpu/risc-v/t-head/c906/riscv_mmu.h
  33. 44 0
      libcpu/risc-v/t-head/c906/rt_interrupt.h
  34. 0 0
      libcpu/risc-v/t-head/c906/stack.h
  35. 1 1
      libcpu/risc-v/t-head/c906/stackframe.h
  36. 0 0
      libcpu/risc-v/t-head/c906/startup_gcc.S
  37. 10 10
      libcpu/risc-v/t-head/c906/symbol_analysis.c
  38. 1 1
      libcpu/risc-v/t-head/c906/symbol_analysis.h
  39. 9 9
      libcpu/risc-v/t-head/c906/syscall_c.c
  40. 6 3
      libcpu/risc-v/t-head/c906/tick.c
  41. 1 1
      libcpu/risc-v/t-head/c906/tick.h
  42. 299 0
      libcpu/risc-v/t-head/c906/trap.c

+ 9 - 0
bsp/d1-allwinner-nezha/.gitignore

@@ -0,0 +1,9 @@
+__pycache__/
+rtthread.bin
+rtthread.elf
+*.map
+build/
+.sconsign.dblite
+cconfig.h
+.vscode/
+rtconfig.pyc

+ 3 - 0
bsp/d1-allwinner-nezha/BUGS.md

@@ -0,0 +1,3 @@
+# BUGS: 
+* [] 2021/10/28  
+    执行cpp程序不能加载/不能在romfs里面执行cpp程序

+ 1 - 1
bsp/d1-allwinner-nezha/Kconfig

@@ -30,7 +30,7 @@ config RT_USING_USERSPACE
     bool
     default y
 
-source "driver/Kconfig"
+source "drivers/Kconfig"
 source "libraries/Kconfig"
 
 config __STACKSIZE__

+ 1 - 0
bsp/d1-allwinner-nezha/README.md

@@ -0,0 +1 @@
+# RT-Thread全志D1移植

+ 1 - 1
bsp/d1-allwinner-nezha/SConstruct

@@ -27,7 +27,7 @@ rtconfig.VENDOR="t-head"
 rtconfig.ARCH='risc-v'
 
 # prepare building environment
-objs = PrepareBuilding(env, RTT_ROOT, has_libcpu = True)
+objs = PrepareBuilding(env, RTT_ROOT, has_libcpu = False)
 
 stack_size = 4096
 

+ 1 - 1
bsp/d1-allwinner-nezha/applications/main.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2018, RT-Thread Development Team
+ * Copyright (c) 2006-2021, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *

+ 26 - 204
bsp/d1-allwinner-nezha/drivers/board.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2020, RT-Thread Development Team
+ * Copyright (c) 2006-2021, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -73,12 +73,6 @@ void primary_cpu_entry(void)
     entry();
 }
 
-//中断初始化程序
-void rt_hw_interrupt_init()
-{
-    /* Enable machine external interrupts. */
-    set_csr(sie, SIP_SEIP);
-}
 
 //这个初始化程序由内核主动调用,此时调度器还未启动,因此在此不能使用依赖线程上下文的函数
 void rt_hw_board_init(void)
@@ -88,33 +82,33 @@ void rt_hw_board_init(void)
     /* initialize hardware interrupt */
     rt_hw_uart_init();
     rt_hw_tick_init();
-    #ifdef RT_USING_HEAP
-        /* initialize memory system */
-        rt_system_heap_init(RT_HW_HEAP_BEGIN, RT_HW_HEAP_END);
-    #endif
+#ifdef RT_USING_HEAP
+    /* initialize memory system */
+    rt_system_heap_init(RT_HW_HEAP_BEGIN, RT_HW_HEAP_END);
+#endif
+
+#ifdef RT_USING_CONSOLE
+    /* set console device */
+    rt_console_set_device("uart");
+#endif /* RT_USING_CONSOLE */
 
-    #ifdef RT_USING_CONSOLE
-        /* set console device */
-        rt_console_set_device("uart");
-    #endif /* RT_USING_CONSOLE */
+#ifdef RT_USING_COMPONENTS_INIT
+    rt_components_board_init();
+#endif
+#ifdef RT_USING_HEAP
+    rt_kprintf("heap: [0x%08x - 0x%08x]\n", (rt_ubase_t) RT_HW_HEAP_BEGIN, (rt_ubase_t) RT_HW_HEAP_END);
+#endif
 
-    #ifdef RT_USING_COMPONENTS_INIT
-        rt_components_board_init();
-    #endif
-    #ifdef RT_USING_HEAP
-        rt_kprintf("heap: [0x%08x - 0x%08x]\n", (rt_ubase_t) RT_HW_HEAP_BEGIN, (rt_ubase_t) RT_HW_HEAP_END);
-    #endif
-    
-    #ifdef RT_USING_USERSPACE
-        rt_hw_mmu_map_init(&mmu_info,(void *)0x100000000UL,0xFFFFFFFEFFFFFFFFUL,(rt_size_t *)MMUTable,0);
-        rt_page_init(init_page_region);
-        rt_hw_mmu_kernel_map_init(&mmu_info,0x00000000UL,0xFFFFFFFFUL);
-        //将低1GB MMIO区域设置为无Cache与Strong Order访存模式
-        MMUTable[0] &= ~PTE_CACHE;
-        MMUTable[0] &= ~PTE_SHARE;
-        MMUTable[0] |= PTE_SO;
-        switch_mmu((void *)MMUTable);
-    #endif
+#ifdef RT_USING_USERSPACE
+    rt_hw_mmu_map_init(&mmu_info,(void *)0x100000000UL,0xFFFFFFFEFFFFFFFFUL,(rt_size_t *)MMUTable,0);
+    rt_page_init(init_page_region);
+    rt_hw_mmu_kernel_map_init(&mmu_info,0x00000000UL,0xFFFFFFFFUL);
+    //将低1GB MMIO区域设置为无Cache与Strong Order访存模式
+    MMUTable[0] &= ~PTE_CACHE;
+    MMUTable[0] &= ~PTE_SHARE;
+    MMUTable[0] |= PTE_SO;
+    switch_mmu((void *)MMUTable);
+#endif
 }
 
 void rt_hw_cpu_reset(void)
@@ -123,175 +117,3 @@ void rt_hw_cpu_reset(void)
     while(1);
 }
 MSH_CMD_EXPORT_ALIAS(rt_hw_cpu_reset, reboot, reset machine);
-
-#include "symbol_analysis.h"
-void dump_regs(struct rt_hw_stack_frame *regs)
-{
-    rt_kprintf("--------------Dump Registers-----------------\n");
-
-    rt_kprintf("Function Registers:\n");
-    rt_kprintf("\tra(x1) = 0x%p(",regs -> ra);print_symbol_info(regs -> ra,RT_FALSE);rt_kprintf(")\n");
-    rt_kprintf("\tuser_sp(x2) = 0x%p(",regs -> user_sp_exc_stack);print_symbol_info(regs -> user_sp_exc_stack,RT_FALSE);rt_kprintf(")\n");
-    rt_kprintf("\tgp(x3) = 0x%p(",regs -> gp);print_symbol_info(regs -> gp,RT_FALSE);rt_kprintf(")\n");
-    rt_kprintf("\ttp(x4) = 0x%p(",regs -> tp);print_symbol_info(regs -> tp,RT_FALSE);rt_kprintf(")\n");
-    rt_kprintf("Temporary Registers:\n");
-    rt_kprintf("\tt0(x5) = 0x%p(",regs -> t0);print_symbol_info(regs -> t0,RT_FALSE);rt_kprintf(")\n");
-    rt_kprintf("\tt1(x6) = 0x%p(",regs -> t1);print_symbol_info(regs -> t1,RT_FALSE);rt_kprintf(")\n");
-    rt_kprintf("\tt2(x7) = 0x%p(",regs -> t2);print_symbol_info(regs -> t2,RT_FALSE);rt_kprintf(")\n");
-    rt_kprintf("\tt3(x28) = 0x%p(",regs -> t3);print_symbol_info(regs -> t3,RT_FALSE);rt_kprintf(")\n");
-    rt_kprintf("\tt4(x29) = 0x%p(",regs -> t4);print_symbol_info(regs -> t4,RT_FALSE);rt_kprintf(")\n");
-    rt_kprintf("\tt5(x30) = 0x%p(",regs -> t5);print_symbol_info(regs -> t5,RT_FALSE);rt_kprintf(")\n");
-    rt_kprintf("\tt6(x31) = 0x%p(",regs -> t6);print_symbol_info(regs -> t6,RT_FALSE);rt_kprintf(")\n");
-    rt_kprintf("Saved Registers:\n");
-    rt_kprintf("\ts0/fp(x8) = 0x%p(",regs -> s0_fp);print_symbol_info(regs -> s0_fp,RT_FALSE);rt_kprintf(")\n");
-    rt_kprintf("\ts1(x9) = 0x%p(",regs -> s1);print_symbol_info(regs -> s1,RT_FALSE);rt_kprintf(")\n");
-    rt_kprintf("\ts2(x18) = 0x%p(",regs -> s2);print_symbol_info(regs -> s2,RT_FALSE);rt_kprintf(")\n");
-    rt_kprintf("\ts3(x19) = 0x%p(",regs -> s3);print_symbol_info(regs -> s3,RT_FALSE);rt_kprintf(")\n");
-    rt_kprintf("\ts4(x20) = 0x%p(",regs -> s4);print_symbol_info(regs -> s4,RT_FALSE);rt_kprintf(")\n");
-    rt_kprintf("\ts5(x21) = 0x%p(",regs -> s5);print_symbol_info(regs -> s5,RT_FALSE);rt_kprintf(")\n");
-    rt_kprintf("\ts6(x22) = 0x%p(",regs -> s6);print_symbol_info(regs -> s6,RT_FALSE);rt_kprintf(")\n");
-    rt_kprintf("\ts7(x23) = 0x%p(",regs -> s7);print_symbol_info(regs -> s7,RT_FALSE);rt_kprintf(")\n");
-    rt_kprintf("\ts8(x24) = 0x%p(",regs -> s8);print_symbol_info(regs -> s8,RT_FALSE);rt_kprintf(")\n");
-    rt_kprintf("\ts9(x25) = 0x%p(",regs -> s9);print_symbol_info(regs -> s9,RT_FALSE);rt_kprintf(")\n");
-    rt_kprintf("\ts10(x26) = 0x%p(",regs -> s10);print_symbol_info(regs -> s10,RT_FALSE);rt_kprintf(")\n");
-    rt_kprintf("\ts11(x27) = 0x%p(",regs -> s11);print_symbol_info(regs -> s11,RT_FALSE);rt_kprintf(")\n");
-    rt_kprintf("Function Arguments Registers:\n");
-    rt_kprintf("\ta0(x10) = 0x%p(",regs -> a0);print_symbol_info(regs -> a0,RT_FALSE);rt_kprintf(")\n");
-    rt_kprintf("\ta1(x11) = 0x%p(",regs -> a1);print_symbol_info(regs -> a1,RT_FALSE);rt_kprintf(")\n");
-    rt_kprintf("\ta2(x12) = 0x%p(",regs -> a2);print_symbol_info(regs -> a2,RT_FALSE);rt_kprintf(")\n");
-    rt_kprintf("\ta3(x13) = 0x%p(",regs -> a3);print_symbol_info(regs -> a3,RT_FALSE);rt_kprintf(")\n");
-    rt_kprintf("\ta4(x14) = 0x%p(",regs -> a4);print_symbol_info(regs -> a4,RT_FALSE);rt_kprintf(")\n");
-    rt_kprintf("\ta5(x15) = 0x%p(",regs -> a5);print_symbol_info(regs -> a5,RT_FALSE);rt_kprintf(")\n");
-    rt_kprintf("\ta6(x16) = 0x%p(",regs -> a6);print_symbol_info(regs -> a6,RT_FALSE);rt_kprintf(")\n");
-    rt_kprintf("\ta7(x17) = 0x%p(",regs -> a7);print_symbol_info(regs -> a7,RT_FALSE);rt_kprintf(")\n");
-    rt_kprintf("sstatus = 0x%p\n",regs -> sstatus);
-    rt_kprintf("\t%s\n",(regs -> sstatus & SSTATUS_SIE) ? "Supervisor Interrupt Enabled" : "Supervisor Interrupt Disabled");
-    rt_kprintf("\t%s\n",(regs -> sstatus & SSTATUS_SPIE) ? "Last Time Supervisor Interrupt Enabled" : "Last Time Supervisor Interrupt Disabled");
-    rt_kprintf("\t%s\n",(regs -> sstatus & SSTATUS_SPP) ? "Last Privilege is Supervisor Mode" : "Last Privilege is User Mode");
-    rt_kprintf("\t%s\n",(regs -> sstatus & SSTATUS_PUM) ? "Permit to Access User Page" : "Not Permit to Access User Page");
-    rt_kprintf("\t%s\n",(regs -> sstatus & (1 << 19)) ? "Permit to Read Executable-only Page" : "Not Permit to Read Executable-only Page");
-    rt_size_t satp_v = read_csr(satp);
-    rt_kprintf("satp = 0x%p\n",satp_v);
-    rt_kprintf("\tCurrent Page Table(Physical) = 0x%p\n",__MASKVALUE(satp_v,__MASK(44)) << PAGE_OFFSET_BIT);
-    rt_kprintf("\tCurrent ASID = 0x%p\n",__MASKVALUE(satp_v >> 44,__MASK(16)) << PAGE_OFFSET_BIT);
-    const char *mode_str = "Unknown Address Translation/Protection Mode";
-    
-    switch(__MASKVALUE(satp_v >> 60,__MASK(4)))
-    {
-        case 0:
-            mode_str = "No Address Translation/Protection Mode";
-            break;
-
-        case 8:
-            mode_str = "Page-based 39-bit Virtual Addressing Mode";
-            break;
-
-        case 9:
-            mode_str = "Page-based 48-bit Virtual Addressing Mode";
-            break;
-    }
-
-    rt_kprintf("\tMode = %s\n",mode_str);
-    rt_kprintf("-----------------Dump OK---------------------\n");
-    print_stacktrace(regs -> epc,regs -> s0_fp);
-}
-
-static const char *Exception_Name[] = 
-                                {
-                                    "Instruction Address Misaligned",
-                                    "Instruction Access Fault",
-                                    "Illegal Instruction",
-                                    "Breakpoint",
-                                    "Load Address Misaligned",
-                                    "Load Access Fault",
-                                    "Store/AMO Address Misaligned",
-                                    "Store/AMO Access Fault",
-                                    "Environment call from U-mode",
-                                    "Environment call from S-mode",
-                                    "Reserved-10",
-                                    "Reserved-11",
-                                    "Instruction Page Fault",
-                                    "Load Page Fault",
-                                    "Reserved-14",
-                                    "Store/AMO Page Fault"
-                                };
-
-static const char *Interrupt_Name[] = 
-                                {
-                                    "User Software Interrupt",
-                                    "Supervisor Software Interrupt",
-                                    "Reversed-2",
-                                    "Reversed-3",
-                                    "User Timer Interrupt",
-                                    "Supervisor Timer Interrupt",
-                                    "Reversed-6",
-                                    "Reversed-7",
-                                    "User External Interrupt",
-                                    "Supervisor External Interrupt",
-                                    "Reserved-10",
-                                    "Reserved-11",
-                                };
-
-//Trap处理入口
-void handle_trap(rt_size_t scause,rt_size_t stval,rt_size_t sepc,struct rt_hw_stack_frame *sp)
-{
-    // rt_kprintf(".");
-    if(scause == (uint64_t)(0x8000000000000005))//S态时钟中断
-    {
-        rt_interrupt_enter();
-        tick_isr();
-        rt_interrupt_leave();
-    }
-    /*else if(scause == (uint64_t)(0x8000000000000009))
-    {
-        rt_kprintf("a\n");
-        while(1);
-        extern struct rt_serial_device  serial1;
-        rt_hw_serial_isr(&serial1,RT_SERIAL_EVENT_RX_IND);
-    }*/
-    else
-    {
-        rt_size_t id = __MASKVALUE(scause,__MASK(63UL));
-        const char *msg;
-
-        //若为中断,则认为这是一个未处理的中断
-        if(scause >> 63)
-        {
-            if(id < sizeof(Interrupt_Name) / sizeof(const char *))
-            {
-                msg = Interrupt_Name[id];
-            }
-            else
-            {
-                msg = "Unknown Interrupt";
-            }
-
-            rt_kprintf("Unhandled Interrupt %ld:%s\n",id,msg);
-        }
-        else//否则是一个异常,需要特殊处理缺页异常
-        {
-            #ifdef RT_USING_USERSPACE
-                if(id == 15)//若为缺页异常,则进行用户栈扩展
-                {
-                    arch_expand_user_stack((void *)stval);
-                    return;
-                }
-            #endif
-
-            if(id < sizeof(Exception_Name) / sizeof(const char *))
-            {
-                msg = Exception_Name[id];
-            }
-            else
-            {
-                msg = "Unknown Exception";
-            }
-
-            rt_kprintf("Unhandled Exception %ld:%s\n",id,msg);
-        }
-
-        rt_kprintf("scause:0x%p,stval:0x%p,sepc:0x%p\n",scause,stval,sepc);
-        dump_regs(sp);
-        while(1);
-    }
-}

+ 1 - 1
bsp/d1-allwinner-nezha/drivers/board.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2020, RT-Thread Development Team
+ * Copyright (c) 2006-2021, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *

+ 18 - 18
bsp/d1-allwinner-nezha/drivers/drv_uart.c

@@ -17,23 +17,23 @@
 #define UART_DEFAULT_BAUDRATE               115200
 #define SUNXI_UART_ADDR            0x02500000
 
-#define SUNXI_UART_RBR (0x00) 		/* receive buffer register */
-#define SUNXI_UART_THR (0x00) 		/* transmit holding register */
-#define SUNXI_UART_DLL (0x00) 		/* divisor latch low register */
-#define SUNXI_UART_DLH (0x04) 		/* diviso latch high register */
-#define SUNXI_UART_IER (0x04) 		/* interrupt enable register */
-#define SUNXI_UART_IIR (0x08) 		/* interrupt identity register */
-#define SUNXI_UART_FCR (0x08) 		/* FIFO control register */
-#define SUNXI_UART_LCR (0x0c) 		/* line control register */
-#define SUNXI_UART_MCR (0x10) 		/* modem control register */
-#define SUNXI_UART_LSR (0x14) 		/* line status register */
-#define SUNXI_UART_MSR (0x18) 		/* modem status register */
-#define SUNXI_UART_SCH (0x1c) 		/* scratch register */
-#define SUNXI_UART_USR (0x7c) 		/* status register */
-#define SUNXI_UART_TFL (0x80) 		/* transmit FIFO level */
-#define SUNXI_UART_RFL (0x84) 		/* RFL */
-#define SUNXI_UART_HALT (0xa4) 		/* halt tx register */
-#define SUNXI_UART_RS485 (0xc0)		/* RS485 control and status register */
+#define SUNXI_UART_RBR (0x00)       /* receive buffer register */
+#define SUNXI_UART_THR (0x00)       /* transmit holding register */
+#define SUNXI_UART_DLL (0x00)       /* divisor latch low register */
+#define SUNXI_UART_DLH (0x04)       /* diviso latch high register */
+#define SUNXI_UART_IER (0x04)       /* interrupt enable register */
+#define SUNXI_UART_IIR (0x08)       /* interrupt identity register */
+#define SUNXI_UART_FCR (0x08)       /* FIFO control register */
+#define SUNXI_UART_LCR (0x0c)       /* line control register */
+#define SUNXI_UART_MCR (0x10)       /* modem control register */
+#define SUNXI_UART_LSR (0x14)       /* line status register */
+#define SUNXI_UART_MSR (0x18)       /* modem status register */
+#define SUNXI_UART_SCH (0x1c)       /* scratch register */
+#define SUNXI_UART_USR (0x7c)       /* status register */
+#define SUNXI_UART_TFL (0x80)       /* transmit FIFO level */
+#define SUNXI_UART_RFL (0x84)       /* RFL */
+#define SUNXI_UART_HALT (0xa4)      /* halt tx register */
+#define SUNXI_UART_RS485 (0xc0)     /* RS485 control and status register */
 
 #define BIT(x) (1 << x)
 
@@ -176,7 +176,7 @@ int rt_hw_uart_init(void)
                               RT_DEVICE_FLAG_STREAM | RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
                               uart);
     }
-    
+
     return 0;
 }
 

+ 8 - 0
bsp/d1-allwinner-nezha/drivers/encoding.h

@@ -103,6 +103,14 @@
 #define SIP_STIP    MIP_STIP /* timer interrupt */
 #define SIP_SEIP    MIP_SEIP /* ext interrupt */
 
+#define RISCV_XLEN    64
+
+#define SCAUSE_INTERRUPT    (1UL << (RISCV_XLEN - 1))
+
+#define SCAUSE_S_SOFTWARE_INTR  1
+#define SCAUSE_S_TIMER_INTR     5
+#define SCAUSE_S_EXTERNAL_INTR  9
+
 #define PRV_U 0
 #define PRV_S 1
 #define PRV_H 2

+ 1 - 1
bsp/d1-allwinner-nezha/drivers/io.h

@@ -49,4 +49,4 @@ static inline uint32_t read_reg(
     return readl(addr + offset);
 }
 
-#endif // ARCH_IO_H
+#endif // ARCH_IO_H

+ 3 - 0
bsp/d1-allwinner-nezha/libraries/README.md

@@ -0,0 +1,3 @@
+# allwinner-libraries
+
+针对全志芯片的外设驱动库

+ 1 - 1
bsp/d1-allwinner-nezha/rtconfig.py

@@ -26,7 +26,7 @@ BUILD = 'debug'
 if PLATFORM == 'gcc':
     # toolchains
     #PREFIX  = 'riscv64-unknown-elf-'
-    PREFIX  = 'riscv64-unknown-linux-musl-'
+    PREFIX  = os.getenv('RTT_CC_PREFIX') or 'riscv64-unknown-linux-musl-'
     CC      = PREFIX + 'gcc'
     CXX     = PREFIX + 'g++'
     AS      = PREFIX + 'gcc'

+ 10 - 0
bsp/d1-allwinner-nezha/sdcard.bat

@@ -0,0 +1,10 @@
+@echo off
+
+if "%1" EQU "" (
+    echo Please input you sdcard volumn! sucn as "sdcard.bat G"
+) else (
+    echo copy rtthread.bin to volumn:%1
+    copy rtthread.bin %1:
+)
+
+@echo on

+ 3 - 1
libcpu/risc-v/SConscript

@@ -16,11 +16,13 @@ elif rtconfig.CPU == "nuclei" :
     group = group
 elif rtconfig.CPU == "virt64" :
     group = group
+elif rtconfig.CPU == "c906" :
+    group = group
 else :
     group = group + SConscript(os.path.join(cwd, 'common', 'SConscript'))
 
 # cpu porting code files
-if  rtconfig.CPU == "e906" :
+if  rtconfig.CPU == "e906" or rtconfig.CPU == "c906":
     group = group + SConscript(os.path.join(cwd, rtconfig.VENDOR, rtconfig.CPU, 'SConscript'))
 else :
     group = group + SConscript(os.path.join(cwd, rtconfig.CPU, 'SConscript'))

+ 0 - 2
bsp/d1-allwinner-nezha/c906/SConscript → libcpu/risc-v/t-head/c906/SConscript

@@ -2,8 +2,6 @@
 
 from building import *
 
-Import('rtconfig')
-
 cwd     = GetCurrentDir()
 src     = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S')
 CPPPATH = [cwd]

+ 1 - 1
bsp/d1-allwinner-nezha/c906/cache.c → libcpu/risc-v/t-head/c906/cache.c

@@ -82,4 +82,4 @@ rt_base_t rt_hw_cpu_dcache_status()
 int sys_cacheflush(void *addr, int size, int cache)
 {
     return 0;
-}
+}

+ 0 - 0
bsp/d1-allwinner-nezha/c906/context_gcc.S → libcpu/risc-v/t-head/c906/context_gcc.S


+ 8 - 8
bsp/d1-allwinner-nezha/c906/cpuport.c → libcpu/risc-v/t-head/c906/cpuport.c

@@ -20,17 +20,17 @@
 
 /**
  * @brief from thread used interrupt context switch
- * 
+ *
  */
 volatile rt_ubase_t  rt_interrupt_from_thread = 0;
 /**
  * @brief to thread used interrupt context switch
- * 
+ *
  */
 volatile rt_ubase_t  rt_interrupt_to_thread   = 0;
 /**
  * @brief flag to indicate context switch in interrupt or not
- * 
+ *
  */
 volatile rt_ubase_t rt_thread_switch_interrupt_flag = 0;
 
@@ -72,13 +72,8 @@ rt_uint8_t *rt_hw_stack_init(void       *tentry,
     frame->epc     = (rt_ubase_t)tentry;
     frame->user_sp_exc_stack = (rt_ubase_t)(((rt_ubase_t)stk) + sizeof(struct rt_hw_stack_frame));
 
-    #ifdef BOARD_K210
-    /* force to supervisor mode(SPP=1) and set SPIE and SUM to 1 */
-    frame->sstatus = 0x00000120;
-    #else
     /* force to supervisor mode(SPP=1) and set SPIE and SUM to 1 */
     frame->sstatus = 0x00040120;
-    #endif
 
     return stk;
 }
@@ -115,3 +110,8 @@ void rt_hw_cpu_shutdown()
         RT_ASSERT(0);
     }
 }
+
+int rt_hw_cpu_id(void)
+{
+    return 0;   /* d1 has one core */
+}

+ 4 - 2
bsp/d1-allwinner-nezha/c906/cpuport.h → libcpu/risc-v/t-head/c906/cpuport.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2018, RT-Thread Development Team
+ * Copyright (c) 2006-2021, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -38,9 +38,11 @@ rt_inline void rt_hw_isb()
     asm volatile("fence.i":::"memory");
 }
 
+int rt_hw_cpu_id(void);
+
 #endif
 
 #endif
 #ifdef RISCV_U_MODE
 #define RISCV_USER_ENTRY 0xFFFFFFE000000000ULL
-#endif
+#endif

+ 105 - 0
libcpu/risc-v/t-head/c906/interrupt.c

@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-10-19     JasonHu      first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#include "rt_interrupt.h"
+#include "riscv.h"
+#include "plic.h"
+
+extern rt_uint32_t rt_interrupt_nest;
+extern rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
+extern rt_uint32_t rt_thread_switch_interrupt_flag;
+
+struct rt_irq_desc isr_table[INTERRUPTS_MAX];
+
+static void rt_hw_interrupt_handler(int vector, void *param)
+{
+    rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
+}
+
+/**
+ * This function will initialize hardware interrupt
+ */
+void rt_hw_interrupt_init(void)
+{
+    rt_int32_t idx;
+
+    rt_memset(isr_table, 0x00, sizeof(isr_table));
+    for (idx = 0; idx < INTERRUPTS_MAX; idx++)
+    {
+        isr_table[idx].handler = rt_hw_interrupt_handler;
+    }
+
+    /* init interrupt nest, and context in thread sp */
+    rt_interrupt_nest               = 0;
+    rt_interrupt_from_thread        = 0;
+    rt_interrupt_to_thread          = 0;
+    rt_thread_switch_interrupt_flag = 0;
+
+    /* Enable machine external interrupts. */
+    set_csr(sie, SIP_SEIP);
+}
+
+/**
+ * This function will mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_mask(int vector)
+{
+    if ((vector < 0) || (vector > IRQ_MAX_NR))
+    {
+        return;
+    }
+    plic_disable_irq(vector);
+}
+
+/**
+
+ * This function will un-mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_umask(int vector)
+{
+    if ((vector < 0) || (vector > IRQ_MAX_NR))
+    {
+        return;
+    }
+    plic_enable_irq(vector);
+}
+
+/**
+ * This function will install a interrupt service routine to a interrupt.
+ * @param vector the interrupt number
+ * @param handler the interrupt service routine to be installed
+ * @param param the interrupt service function parameter
+ * @param name the interrupt name
+ * @return old handler
+ */
+rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
+        void *param, const char *name)
+{
+    rt_isr_handler_t old_handler = RT_NULL;
+    if ((vector < 0) || (vector > IRQ_MAX_NR))
+    {
+        return old_handler;
+    }
+
+    old_handler = isr_table[IRQ_OFFSET + vector].handler;
+
+#ifdef RT_USING_INTERRUPT_INFO
+    rt_strncpy(isr_table[IRQ_OFFSET + vector].name, name, RT_NAME_MAX);
+#endif /* RT_USING_INTERRUPT_INFO */
+    isr_table[IRQ_OFFSET + vector].handler = handler;
+    isr_table[IRQ_OFFSET + vector].param = param;
+
+    return old_handler;
+}

+ 2 - 2
bsp/d1-allwinner-nezha/c906/interrupt_gcc.S → libcpu/risc-v/t-head/c906/interrupt_gcc.S

@@ -161,10 +161,10 @@ syscall_exit:
 
 .global rt_hw_interrupt_enable
 rt_hw_interrupt_enable:
-    csrs sstatus, a0
+    csrs sstatus, a0    /* restore to old csr */
     jr ra
 
 .global rt_hw_interrupt_disable
 rt_hw_interrupt_disable:
-    csrrci a0, sstatus, 2
+    csrrci a0, sstatus, 2   /* clear SIE */
     jr ra

+ 9 - 9
bsp/d1-allwinner-nezha/c906/mmu.c → libcpu/risc-v/t-head/c906/mmu.c

@@ -78,7 +78,7 @@ int rt_hw_mmu_map_init(rt_mmu_info *mmu_info,void *v_address,rt_size_t size,rt_s
     for(l1_off = va_s;l1_off <= va_e;l1_off++)
     {
         size_t v = vtable[l1_off];
-        
+
         if(v)
         {
             rt_hw_interrupt_enable(level);
@@ -209,7 +209,7 @@ static rt_size_t find_vaddr(rt_mmu_info *mmu_info,rt_size_t pages)
     return 0;
 }
 
-//check whether the range of virtual address are free 
+//check whether the range of virtual address are free
 static int check_vaddr(rt_mmu_info *mmu_info,void *va,rt_size_t pages)
 {
     rt_size_t loop_va = __UMASKVALUE((rt_size_t)va,PAGE_OFFSET_MASK);
@@ -379,13 +379,13 @@ static int __rt_hw_mmu_map(rt_mmu_info *mmu_info,void *v_addr,void *p_addr,rt_si
                 return -1;
             }
         }
-        
+
         RT_ASSERT(!PTE_USED(*(mmu_l3 + l3_off)));
         ref_cnt = mmu_l3 + __SIZE(VPN0_BIT);
         (*ref_cnt)++;
         *(mmu_l3 + l3_off) = COMBINEPTE((rt_size_t)loop_pa,PAGE_DEFAULT_ATTR_LEAF);
         rt_hw_cpu_dcache_clean(mmu_l3 + l3_off,sizeof(*(mmu_l3 + l3_off)));
-        
+
         loop_va += PAGE_SIZE;
         loop_pa += PAGE_SIZE;
     }
@@ -519,7 +519,7 @@ void *_rt_hw_mmu_map_auto(rt_mmu_info *mmu_info,void *v_addr,rt_size_t size,rt_s
     if(v_addr)
     {
         vaddr = __UMASKVALUE((rt_size_t)v_addr,PAGE_OFFSET_MASK);
-        
+
         if(check_vaddr(mmu_info,(void *)vaddr,pages) != 0)
         {
             return 0;
@@ -581,7 +581,7 @@ void *rt_hw_mmu_map_auto(rt_mmu_info *mmu_info,void *v_addr,rt_size_t size,rt_si
 void rt_hw_mmu_unmap(rt_mmu_info *mmu_info,void *v_addr,rt_size_t size)
 {
     rt_base_t level;
-    
+
     level = rt_hw_interrupt_disable();
     _rt_hw_mmu_unmap(mmu_info,v_addr,size);
     rt_hw_interrupt_enable(level);
@@ -603,12 +603,12 @@ void *_rt_hw_mmu_v2p(rt_mmu_info *mmu_info,void *v_addr)
     }
 
     mmu_l1 = ((rt_size_t *)mmu_info -> vtable) + l1_off;
-    
+
     if(PTE_USED(*mmu_l1))
     {
         RT_ASSERT(!PAGE_IS_LEAF(*mmu_l1));
         mmu_l2 = (rt_size_t *)PPN_TO_VPN(GET_PADDR(*mmu_l1),mmu_info -> pv_off);
-        
+
         if(PTE_USED(*(mmu_l2 + l2_off)))
         {
             RT_ASSERT(!PAGE_IS_LEAF(*(mmu_l2 + l2_off)));
@@ -634,4 +634,4 @@ void *rt_hw_mmu_v2p(rt_mmu_info *mmu_info,void *v_addr)
     ret = _rt_hw_mmu_v2p(mmu_info,v_addr);
     rt_hw_interrupt_enable(level);
     return ret;
-}
+}

+ 1 - 1
bsp/d1-allwinner-nezha/c906/mmu.h → libcpu/risc-v/t-head/c906/mmu.h

@@ -54,4 +54,4 @@ void rt_hw_mmu_unmap(rt_mmu_info *mmu_info,void *v_addr,rt_size_t size);
 void *_rt_hw_mmu_v2p(rt_mmu_info *mmu_info,void *v_addr);
 void *rt_hw_mmu_v2p(rt_mmu_info *mmu_info,void *v_addr);
 
-#endif
+#endif

+ 5 - 5
bsp/d1-allwinner-nezha/c906/page.c → libcpu/risc-v/t-head/c906/page.c

@@ -44,7 +44,7 @@ static rt_size_t page_nr;
 
 static struct page *page_list[ADDRESS_WIDTH_BITS];
 
-//get the correct page_list index according the actual size 
+//get the correct page_list index according the actual size
 rt_size_t rt_page_bits(rt_size_t size)
 {
     rt_base_t bit;
@@ -169,7 +169,7 @@ void rt_page_ref_inc(void *addr, uint32_t size_bits)
 static void page_insert(struct page *p,rt_size_t size_bits)
 {
     PAGE_VALID(p);
-    
+
     p -> next = page_list[size_bits];
 
     if(p -> next)
@@ -350,7 +350,7 @@ void rt_page_init(rt_region_t reg)
 
     rt_size_t nr = PAGE_SIZE / sizeof(struct page);
     rt_size_t total = (reg.end - reg.start) >> PAGE_OFFSET_BIT;
-    
+
     /*
         equation:cell((total - mnr) / nr) = mnr
         let total - mnr = knr + p(k is integer,0 <= p < nr)
@@ -400,8 +400,8 @@ void rt_page_init(rt_region_t reg)
         {
             size_bits = align_bits;
         }
-        
+
         _pages_free(addr_to_page((void *)reg.start),size_bits - PAGE_OFFSET_BIT);
         reg.start += (1U << size_bits);
     }
-}
+}

+ 0 - 0
bsp/d1-allwinner-nezha/c906/page.h → libcpu/risc-v/t-head/c906/page.h


+ 74 - 0
libcpu/risc-v/t-head/c906/plic.c

@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-10-19     JasonHu      first version
+ */
+
+#include <rtthread.h>
+#include <cpuport.h>
+
+#include <rtdbg.h>
+
+#include "plic.h"
+#include "rt_interrupt.h"
+#include "io.h"
+
+void plic_enable_irq(int irqno)
+{
+    if (irqno < 0 || irqno >= IRQ_MAX_NR) {
+        LOG_E("[IRQ] plic enable bad irq %d!", irqno);
+        return;
+    }
+    int hart = rt_hw_cpu_id();
+
+    uint32_t *enable_addr = (uint32_t *)PLIC_SENABLE(hart);
+
+    enable_addr += irqno / 32;
+    uint8_t irqno_off = irqno % 32;
+    // set uart's enable bit for this hart's S-mode.
+    writel(readl((void *)enable_addr) | (1 << irqno_off), enable_addr);
+
+    uint32_t *priority_addr = (uint32_t *) PLIC_PRIORITY;
+    priority_addr += irqno;
+    writel(1, priority_addr);
+}
+
+void plic_disable_irq(int irqno)
+{
+    if (irqno < 0 || irqno >= IRQ_MAX_NR)
+    {
+        LOG_E("[IRQ] plic disable bad irq %d!", irqno);
+    }
+
+    int hart = rt_hw_cpu_id();
+
+    uint32_t *enable_addr = (uint32_t *)PLIC_SENABLE(hart);
+
+    enable_addr += irqno / 32;
+    uint8_t irqno_off = irqno % 32;
+    // set uart's enable bit for this hart's S-mode.
+    writel(readl((void *)enable_addr) & ~(1 << irqno_off), enable_addr);
+
+    uint32_t *priority_addr = (uint32_t *) PLIC_PRIORITY;
+    priority_addr += irqno;
+    writel(0, priority_addr);
+}
+
+// ask the PLIC what interrupt we should serve.
+int plic_claim(void)
+{
+    int hart = rt_hw_cpu_id();
+    int irq = readl((void *)PLIC_SCLAIM(hart));
+    return irq;
+}
+
+// tell the PLIC we've served this IRQ.
+void plic_complete(int irq)
+{
+    int hart = rt_hw_cpu_id();
+    writel(irq, (void *)PLIC_SCLAIM(hart));
+}

+ 34 - 0
libcpu/risc-v/t-head/c906/plic.h

@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-10-19     JasonHu      first version
+ */
+
+#ifndef __RISCV64_PLIC_H__
+#define __RISCV64_PLIC_H__
+
+// Platform level interrupt controller
+#define PLIC                    0x10000000L
+
+#define PLIC_PRIORITY           (PLIC + 0x0)
+#define PLIC_PENDING            (PLIC + 0x1000)
+#define PLIC_MENABLE(hart)      (PLIC + 0x2000 + (hart) * 0x100)      // machine interrupt enable
+#define PLIC_SENABLE(hart)      (PLIC + 0x2080 + (hart) * 0x100)      // supervisor interrupt enable
+#define PLIC_MPRIORITY(hart)    (PLIC + 0x200000 + (hart) * 0x2000)
+#define PLIC_SPRIORITY(hart)    (PLIC + 0x201000 + (hart) * 0x2000)
+#define PLIC_MCLAIM(hart)       (PLIC + 0x200004 + (hart) * 0x2000)
+#define PLIC_SCLAIM(hart)       (PLIC + 0x201004 + (hart) * 0x2000)
+
+void plic_init(void);
+void plic_enable_irq(int irqno);
+void plic_disable_irq(int irqno);
+// ask PLIC what interrupt we should serve
+int plic_claim(void);
+// tell PLIC that we've served this IRQ
+void plic_complete(int irq);
+
+#endif

+ 1 - 1
bsp/d1-allwinner-nezha/c906/riscv.h → libcpu/risc-v/t-head/c906/riscv.h

@@ -26,4 +26,4 @@
 #define __ALIGNUP(value,bit) (((value) + __MASK(bit)) & __UMASK(bit))
 #define __ALIGNDOWN(value,bit) ((value) & __UMASK(bit))
 
-#endif
+#endif

+ 25 - 25
bsp/d1-allwinner-nezha/c906/riscv_io.h → libcpu/risc-v/t-head/c906/riscv_io.h

@@ -70,40 +70,40 @@
 
     /* clang-format off */
 
-    #define __io_rbr()		do {} while (0)
-    #define __io_rar()		do {} while (0)
-    #define __io_rbw()		do {} while (0)
-    #define __io_raw()		do {} while (0)
+    #define __io_rbr()      do {} while (0)
+    #define __io_rar()      do {} while (0)
+    #define __io_rbw()      do {} while (0)
+    #define __io_raw()      do {} while (0)
 
-    #define readb_relaxed(c)	({ rt_uint8_t  __v; __io_rbr(); __v = __raw_readb(c); __io_rar(); __v; })
-    #define readw_relaxed(c)	({ rt_uint16_t __v; __io_rbr(); __v = __raw_readw(c); __io_rar(); __v; })
-    #define readl_relaxed(c)	({ rt_uint32_t __v; __io_rbr(); __v = __raw_readl(c); __io_rar(); __v; })
+    #define readb_relaxed(c)    ({ rt_uint8_t  __v; __io_rbr(); __v = __raw_readb(c); __io_rar(); __v; })
+    #define readw_relaxed(c)    ({ rt_uint16_t __v; __io_rbr(); __v = __raw_readw(c); __io_rar(); __v; })
+    #define readl_relaxed(c)    ({ rt_uint32_t __v; __io_rbr(); __v = __raw_readl(c); __io_rar(); __v; })
 
-    #define writeb_relaxed(v,c)	({ __io_rbw(); __raw_writeb((v),(c)); __io_raw(); })
-    #define writew_relaxed(v,c)	({ __io_rbw(); __raw_writew((v),(c)); __io_raw(); })
-    #define writel_relaxed(v,c)	({ __io_rbw(); __raw_writel((v),(c)); __io_raw(); })
+    #define writeb_relaxed(v,c) ({ __io_rbw(); __raw_writeb((v),(c)); __io_raw(); })
+    #define writew_relaxed(v,c) ({ __io_rbw(); __raw_writew((v),(c)); __io_raw(); })
+    #define writel_relaxed(v,c) ({ __io_rbw(); __raw_writel((v),(c)); __io_raw(); })
 
     #if __riscv_xlen != 32
-    #define readq_relaxed(c)	({ rt_uint64_t __v; __io_rbr(); __v = __raw_readq(c); __io_rar(); __v; })
-    #define writeq_relaxed(v,c)	({ __io_rbw(); __raw_writeq((v),(c)); __io_raw(); })
+    #define readq_relaxed(c)    ({ rt_uint64_t __v; __io_rbr(); __v = __raw_readq(c); __io_rar(); __v; })
+    #define writeq_relaxed(v,c) ({ __io_rbw(); __raw_writeq((v),(c)); __io_raw(); })
     #endif
 
-    #define __io_br()	do {} while (0)
-    #define __io_ar()	__asm__ __volatile__ ("fence i,r" : : : "memory");
-    #define __io_bw()	__asm__ __volatile__ ("fence w,o" : : : "memory");
-    #define __io_aw()	do {} while (0)
+    #define __io_br()   do {} while (0)
+    #define __io_ar()   __asm__ __volatile__ ("fence i,r" : : : "memory");
+    #define __io_bw()   __asm__ __volatile__ ("fence w,o" : : : "memory");
+    #define __io_aw()   do {} while (0)
 
-    #define readb(c)	({ rt_uint8_t  __v; __io_br(); __v = __raw_readb(c); __io_ar(); __v; })
-    #define readw(c)	({ rt_uint16_t __v; __io_br(); __v = __raw_readw(c); __io_ar(); __v; })
-    #define readl(c)	({ rt_uint32_t __v; __io_br(); __v = __raw_readl(c); __io_ar(); __v; })
+    #define readb(c)    ({ rt_uint8_t  __v; __io_br(); __v = __raw_readb(c); __io_ar(); __v; })
+    #define readw(c)    ({ rt_uint16_t __v; __io_br(); __v = __raw_readw(c); __io_ar(); __v; })
+    #define readl(c)    ({ rt_uint32_t __v; __io_br(); __v = __raw_readl(c); __io_ar(); __v; })
 
-    #define writeb(v,c)	({ __io_bw(); __raw_writeb((v),(c)); __io_aw(); })
-    #define writew(v,c)	({ __io_bw(); __raw_writew((v),(c)); __io_aw(); })
-    #define writel(v,c)	({ __io_bw(); __raw_writel((v),(c)); __io_aw(); })
+    #define writeb(v,c) ({ __io_bw(); __raw_writeb((v),(c)); __io_aw(); })
+    #define writew(v,c) ({ __io_bw(); __raw_writew((v),(c)); __io_aw(); })
+    #define writel(v,c) ({ __io_bw(); __raw_writel((v),(c)); __io_aw(); })
 
     #if __riscv_xlen != 32
-    #define readq(c)	({ rt_uint64_t __v; __io_br(); __v = __raw_readq(c); __io_ar(); __v; })
-    #define writeq(v,c)	({ __io_bw(); __raw_writeq((v),(c)); __io_aw(); })
+    #define readq(c)    ({ rt_uint64_t __v; __io_br(); __v = __raw_readq(c); __io_ar(); __v; })
+    #define writeq(v,c) ({ __io_bw(); __raw_writeq((v),(c)); __io_aw(); })
     #endif
 
-#endif
+#endif

+ 1 - 1
bsp/d1-allwinner-nezha/c906/riscv_mmu.c → libcpu/risc-v/t-head/c906/riscv_mmu.c

@@ -34,4 +34,4 @@ void mmu_enable_user_page_access()
 void mmu_disable_user_page_access()
 {
     clear_csr(sstatus,SSTATUS_PUM);
-}
+}

+ 1 - 1
bsp/d1-allwinner-nezha/c906/riscv_mmu.h → libcpu/risc-v/t-head/c906/riscv_mmu.h

@@ -79,4 +79,4 @@ void mmu_set_pagetable(rt_ubase_t addr);
 void mmu_enable_user_page_access();
 void mmu_disable_user_page_access();
 
-#endif
+#endif

+ 44 - 0
libcpu/risc-v/t-head/c906/rt_interrupt.h

@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-10-19     JasonHu      first version
+ */
+
+#ifndef __INTERRUPT_H__
+#define __INTERRUPT_H__
+
+#include <rthw.h>
+
+#define IRQ_OFFSET          16
+#define IRQ_MAX_NR          234
+#define INTERRUPTS_MAX      (IRQ_OFFSET + IRQ_MAX_NR)
+
+enum {
+    EP_INSTRUCTION_ADDRESS_MISALIGNED = 0,
+    EP_INSTRUCTION_ACCESS_FAULT,
+    EP_ILLEGAL_INSTRUCTION,
+    EP_BREAKPOINT,
+    EP_LOAD_ADDRESS_MISALIGNED,
+    EP_LOAD_ACCESS_FAULT,
+    EP_STORE_ADDRESS_MISALIGNED,
+    EP_STORE_ACCESS_FAULT,
+    EP_ENVIRONMENT_CALL_U_MODE,
+    EP_ENVIRONMENT_CALL_S_MODE,
+    EP_RESERVED10,
+    EP_ENVIRONMENT_CALL_M_MODE,
+    EP_INSTRUCTION_PAGE_FAULT,          /* page attr */
+    EP_LOAD_PAGE_FAULT,                 /* read data */
+    EP_RESERVED14,
+    EP_STORE_PAGE_FAULT,                /* write data */
+};
+
+void rt_hw_interrupt_init(void);
+void rt_hw_interrupt_mask(int vector);
+void rt_hw_interrupt_umask(int vector);
+rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, void *param, const char *name);
+
+#endif

+ 0 - 0
bsp/d1-allwinner-nezha/c906/stack.h → libcpu/risc-v/t-head/c906/stack.h


+ 1 - 1
bsp/d1-allwinner-nezha/c906/stackframe.h → libcpu/risc-v/t-head/c906/stackframe.h

@@ -160,4 +160,4 @@
     csrci sstatus, 2
 .endm
 
-#endif
+#endif

+ 0 - 0
bsp/d1-allwinner-nezha/c906/startup_gcc.S → libcpu/risc-v/t-head/c906/startup_gcc.S


+ 10 - 10
bsp/d1-allwinner-nezha/c906/symbol_analysis.c → libcpu/risc-v/t-head/c906/symbol_analysis.c

@@ -56,7 +56,7 @@ os_symtab_item *find_symbol_table(rt_size_t symbol_table_addr,rt_size_t symbol_n
 
             left++;
         }
-    }    
+    }
 
     left--;
 
@@ -107,7 +107,7 @@ void print_symbol_info(rt_size_t address,rt_bool_t function)
     os_symtab_item *general_symbol = find_symbol_table(symtab_header -> general_symbol_table_offset,symtab_header -> general_symbol_table_num,address);
     const char *dot = "";
     rt_bool_t valid = RT_FALSE;
-    
+
     if(function)
     {
         while(function_symbol != RT_NULL)
@@ -119,7 +119,7 @@ void print_symbol_info(rt_size_t address,rt_bool_t function)
                 dot = ",";
                 valid = RT_TRUE;
             }
-            
+
             if(((rt_size_t)(function_symbol + 1)) >= (((rt_size_t)&_osdebug_start) + symtab_header -> function_table_offset + symtab_header -> function_table_num * sizeof(os_symtab_item)))
             {
                 break;
@@ -129,7 +129,7 @@ void print_symbol_info(rt_size_t address,rt_bool_t function)
             {
                 function_symbol++;
             }
-            
+
             break;
         }
 
@@ -141,7 +141,7 @@ void print_symbol_info(rt_size_t address,rt_bool_t function)
                 print_symbol(general_symbol,address);
                 dot = ",";
                 valid = RT_TRUE;
-                
+
                 if(((rt_size_t)(general_symbol + 1)) >= (((rt_size_t)&_osdebug_start) + symtab_header -> general_symbol_table_offset + symtab_header -> general_symbol_table_num * sizeof(os_symtab_item)))
                 {
                     break;
@@ -164,7 +164,7 @@ void print_symbol_info(rt_size_t address,rt_bool_t function)
                     dot = ",";
                     valid = RT_TRUE;
                 }
-                
+
                 if(((rt_size_t)(object_symbol + 1)) >= (((rt_size_t)&_osdebug_start) + symtab_header -> object_table_offset + symtab_header -> object_table_num * sizeof(os_symtab_item)))
                 {
                     break;
@@ -190,7 +190,7 @@ void print_symbol_info(rt_size_t address,rt_bool_t function)
                 dot = ",";
                 valid = RT_TRUE;
             }
-            
+
             if(((rt_size_t)(object_symbol + 1)) >= (((rt_size_t)&_osdebug_start) + symtab_header -> object_table_offset + symtab_header -> object_table_num * sizeof(os_symtab_item)))
             {
                 break;
@@ -212,7 +212,7 @@ void print_symbol_info(rt_size_t address,rt_bool_t function)
                 print_symbol(general_symbol,address);
                 dot = ",";
                 valid = RT_TRUE;
-                
+
                 if(((rt_size_t)(general_symbol + 1)) >= (((rt_size_t)&_osdebug_start) + symtab_header -> general_symbol_table_offset + symtab_header -> general_symbol_table_num * sizeof(os_symtab_item)))
                 {
                     break;
@@ -235,7 +235,7 @@ void print_symbol_info(rt_size_t address,rt_bool_t function)
                     dot = ",";
                     valid = RT_TRUE;
                 }
-                
+
                 if(((rt_size_t)(function_symbol + 1)) >= (((rt_size_t)&_osdebug_start) + symtab_header -> function_table_offset + symtab_header -> function_table_num * sizeof(os_symtab_item)))
                 {
                     break;
@@ -245,7 +245,7 @@ void print_symbol_info(rt_size_t address,rt_bool_t function)
                 {
                     function_symbol++;
                 }
-                
+
                 break;
             }
         }

+ 1 - 1
bsp/d1-allwinner-nezha/c906/symbol_analysis.h → libcpu/risc-v/t-head/c906/symbol_analysis.h

@@ -41,4 +41,4 @@
     void print_symbol_info(rt_size_t address,rt_bool_t function);
     void print_stacktrace(rt_size_t epc,rt_size_t fp);
 
-#endif
+#endif

+ 9 - 9
bsp/d1-allwinner-nezha/c906/syscall_c.c → libcpu/risc-v/t-head/c906/syscall_c.c

@@ -43,17 +43,17 @@ void syscall_handler(struct rt_hw_stack_frame *regs)
         while(1);
     }
 
-	syscallfunc_t syscallfunc = (syscallfunc_t)lwp_get_sys_api(regs -> a7);
-	
-	if(syscallfunc == RT_NULL)
-	{
-		rt_kprintf("unsupported syscall!\n");
+    syscallfunc_t syscallfunc = (syscallfunc_t)lwp_get_sys_api(regs -> a7);
+
+    if(syscallfunc == RT_NULL)
+    {
+        rt_kprintf("unsupported syscall!\n");
         while(1);
-	}
+    }
 
     LOG_I("\033[36msyscall id = %d,arg0 = 0x%p,arg1 = 0x%p,arg2 = 0x%p,arg3 = 0x%p,arg4 = 0x%p,arg5 = 0x%p,arg6 = 0x%p\n\033[37m",regs -> a7,regs -> a0,regs -> a1,regs -> a2,regs -> a3,regs -> a4,regs -> a5,regs -> a6);
     regs -> a0 = syscallfunc(regs -> a0,regs -> a1,regs -> a2,regs -> a3,regs -> a4,regs -> a5,regs -> a6);
-	regs -> a7 = 0;
-	regs -> epc += 4;//skip ecall instruction
+    regs -> a7 = 0;
+    regs -> epc += 4;//skip ecall instruction
     LOG_I("\033[36msyscall deal ok,ret = 0x%p\n\033[37m",regs -> a0);
-}
+}

+ 6 - 3
bsp/d1-allwinner-nezha/c906/tick.c → libcpu/risc-v/t-head/c906/tick.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2018, RT-Thread Development Team
+ * Copyright (c) 2006-2021, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -14,6 +14,9 @@
 #include <encoding.h>
 #include "sbi.h"
 
+/* 100 ticks per second */
+#define TICK_CYCLE (4000 * 65)
+
 static volatile uint64_t time_elapsed = 0;
 static volatile unsigned long tick_cycles = 0;
 
@@ -28,7 +31,7 @@ static uint64_t get_ticks()
 int tick_isr(void)
 {
     // uint64_t core_id = current_coreid();
-    int tick_cycles = 40000;
+    int tick_cycles = TICK_CYCLE;
     // clint->mtimecmp[core_id] += tick_cycles;
     rt_tick_increase();
     sbi_set_timer(get_ticks() + tick_cycles);
@@ -48,7 +51,7 @@ int rt_hw_tick_init(void)
 
     /* calculate the tick cycles */
     // tick_cycles = interval * sysctl_clock_get_freq(SYSCTL_CLOCK_CPU) / CLINT_CLOCK_DIV / 1000ULL - 1;
-    tick_cycles = 40000;
+    tick_cycles = TICK_CYCLE;
     /* Set timer */
     sbi_set_timer(get_ticks() + tick_cycles);
 

+ 1 - 1
bsp/d1-allwinner-nezha/c906/tick.h → libcpu/risc-v/t-head/c906/tick.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2018, RT-Thread Development Team
+ * Copyright (c) 2006-2021, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *

+ 299 - 0
libcpu/risc-v/t-head/c906/trap.c

@@ -0,0 +1,299 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021/1/30      lizirui      first version
+ * 2021/10/20     JasonHu      move to trap.c
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#define DBG_LVL DBG_LOG
+#include <rtdbg.h>
+
+#include "board.h"
+#include "tick.h"
+
+#include "drv_uart.h"
+#include "encoding.h"
+#include "stack.h"
+#include "sbi.h"
+#include "riscv.h"
+
+#include "rt_interrupt.h"
+#include "plic.h"
+
+#ifdef RT_USING_USERSPACE
+    #include "riscv_mmu.h"
+    #include "mmu.h"
+    #include "page.h"
+    #include "lwp_arch.h"
+#endif
+
+#include "symbol_analysis.h"
+void dump_regs(struct rt_hw_stack_frame *regs)
+{
+    rt_kprintf("--------------Dump Registers-----------------\n");
+
+    rt_kprintf("Function Registers:\n");
+    rt_kprintf("\tra(x1) = 0x%p(",regs->ra);
+    print_symbol_info(regs->ra, RT_FALSE);
+    rt_kprintf(")\n");
+    rt_kprintf("\tuser_sp(x2) = 0x%p(",regs->user_sp_exc_stack);
+    print_symbol_info(regs->user_sp_exc_stack, RT_FALSE);
+    rt_kprintf(")\n");
+    rt_kprintf("\tgp(x3) = 0x%p(",regs->gp);
+    print_symbol_info(regs->gp, RT_FALSE);
+    rt_kprintf(")\n");
+    rt_kprintf("\ttp(x4) = 0x%p(",regs->tp);
+    print_symbol_info(regs->tp, RT_FALSE);
+    rt_kprintf(")\n");
+    rt_kprintf("Temporary Registers:\n");
+    rt_kprintf("\tt0(x5) = 0x%p(",regs->t0);
+    print_symbol_info(regs->t0, RT_FALSE);
+    rt_kprintf(")\n");
+    rt_kprintf("\tt1(x6) = 0x%p(",regs->t1);
+    print_symbol_info(regs->t1, RT_FALSE);
+    rt_kprintf(")\n");
+    rt_kprintf("\tt2(x7) = 0x%p(",regs->t2);
+    print_symbol_info(regs->t2, RT_FALSE);
+    rt_kprintf(")\n");
+    rt_kprintf("\tt3(x28) = 0x%p(",regs->t3);
+    print_symbol_info(regs->t3, RT_FALSE);
+    rt_kprintf(")\n");
+    rt_kprintf("\tt4(x29) = 0x%p(",regs->t4);
+    print_symbol_info(regs->t4, RT_FALSE);
+    rt_kprintf(")\n");
+    rt_kprintf("\tt5(x30) = 0x%p(",regs->t5);
+    print_symbol_info(regs->t5, RT_FALSE);
+    rt_kprintf(")\n");
+    rt_kprintf("\tt6(x31) = 0x%p(",regs->t6);
+    print_symbol_info(regs->t6, RT_FALSE);
+    rt_kprintf(")\n");
+    rt_kprintf("Saved Registers:\n");
+    rt_kprintf("\ts0/fp(x8) = 0x%p(",regs->s0_fp);
+    print_symbol_info(regs->s0_fp, RT_FALSE);
+    rt_kprintf(")\n");
+    rt_kprintf("\ts1(x9) = 0x%p(",regs->s1);
+    print_symbol_info(regs->s1, RT_FALSE);
+    rt_kprintf(")\n");
+    rt_kprintf("\ts2(x18) = 0x%p(",regs->s2);
+    print_symbol_info(regs->s2, RT_FALSE);
+    rt_kprintf(")\n");
+    rt_kprintf("\ts3(x19) = 0x%p(",regs->s3);
+    print_symbol_info(regs->s3, RT_FALSE);
+    rt_kprintf(")\n");
+    rt_kprintf("\ts4(x20) = 0x%p(",regs->s4);
+    print_symbol_info(regs->s4, RT_FALSE);
+    rt_kprintf(")\n");
+    rt_kprintf("\ts5(x21) = 0x%p(",regs->s5);
+    print_symbol_info(regs->s5, RT_FALSE);
+    rt_kprintf(")\n");
+    rt_kprintf("\ts6(x22) = 0x%p(",regs->s6);
+    print_symbol_info(regs->s6, RT_FALSE);
+    rt_kprintf(")\n");
+    rt_kprintf("\ts7(x23) = 0x%p(",regs->s7);
+    print_symbol_info(regs->s7, RT_FALSE);
+    rt_kprintf(")\n");
+    rt_kprintf("\ts8(x24) = 0x%p(",regs->s8);
+    print_symbol_info(regs->s8, RT_FALSE);
+    rt_kprintf(")\n");
+    rt_kprintf("\ts9(x25) = 0x%p(",regs->s9);
+    print_symbol_info(regs->s9, RT_FALSE);
+    rt_kprintf(")\n");
+    rt_kprintf("\ts10(x26) = 0x%p(",regs->s10);
+    print_symbol_info(regs->s10, RT_FALSE);
+    rt_kprintf(")\n");
+    rt_kprintf("\ts11(x27) = 0x%p(",regs->s11);
+    print_symbol_info(regs->s11, RT_FALSE);
+    rt_kprintf(")\n");
+    rt_kprintf("Function Arguments Registers:\n");
+    rt_kprintf("\ta0(x10) = 0x%p(",regs->a0);
+    print_symbol_info(regs->a0, RT_FALSE);
+    rt_kprintf(")\n");
+    rt_kprintf("\ta1(x11) = 0x%p(",regs->a1);
+    print_symbol_info(regs->a1, RT_FALSE);
+    rt_kprintf(")\n");
+    rt_kprintf("\ta2(x12) = 0x%p(",regs->a2);
+    print_symbol_info(regs->a2, RT_FALSE);
+    rt_kprintf(")\n");
+    rt_kprintf("\ta3(x13) = 0x%p(",regs->a3);
+    print_symbol_info(regs->a3, RT_FALSE);
+    rt_kprintf(")\n");
+    rt_kprintf("\ta4(x14) = 0x%p(",regs->a4);
+    print_symbol_info(regs->a4, RT_FALSE);
+    rt_kprintf(")\n");
+    rt_kprintf("\ta5(x15) = 0x%p(",regs->a5);
+    print_symbol_info(regs->a5, RT_FALSE);
+    rt_kprintf(")\n");
+    rt_kprintf("\ta6(x16) = 0x%p(",regs->a6);
+    print_symbol_info(regs->a6, RT_FALSE);
+    rt_kprintf(")\n");
+    rt_kprintf("\ta7(x17) = 0x%p(",regs->a7);
+    print_symbol_info(regs->a7, RT_FALSE);
+    rt_kprintf(")\n");
+    rt_kprintf("sstatus = 0x%p\n",regs->sstatus);
+    rt_kprintf("\t%s\n",(regs->sstatus & SSTATUS_SIE) ? "Supervisor Interrupt Enabled" : "Supervisor Interrupt Disabled");
+    rt_kprintf("\t%s\n",(regs->sstatus & SSTATUS_SPIE) ? "Last Time Supervisor Interrupt Enabled" : "Last Time Supervisor Interrupt Disabled");
+    rt_kprintf("\t%s\n",(regs->sstatus & SSTATUS_SPP) ? "Last Privilege is Supervisor Mode" : "Last Privilege is User Mode");
+    rt_kprintf("\t%s\n",(regs->sstatus & SSTATUS_PUM) ? "Permit to Access User Page" : "Not Permit to Access User Page");
+    rt_kprintf("\t%s\n",(regs->sstatus & (1 << 19)) ? "Permit to Read Executable-only Page" : "Not Permit to Read Executable-only Page");
+    rt_size_t satp_v = read_csr(satp);
+    rt_kprintf("satp = 0x%p\n",satp_v);
+
+#ifdef RT_USING_USERSPACE
+    rt_kprintf("\tCurrent Page Table(Physical) = 0x%p\n",__MASKVALUE(satp_v,__MASK(44)) << PAGE_OFFSET_BIT);
+    rt_kprintf("\tCurrent ASID = 0x%p\n",__MASKVALUE(satp_v >> 44,__MASK(16)) << PAGE_OFFSET_BIT);
+#endif
+
+    const char *mode_str = "Unknown Address Translation/Protection Mode";
+
+    switch(__MASKVALUE(satp_v >> 60,__MASK(4)))
+    {
+        case 0:
+            mode_str = "No Address Translation/Protection Mode";
+            break;
+
+        case 8:
+            mode_str = "Page-based 39-bit Virtual Addressing Mode";
+            break;
+
+        case 9:
+            mode_str = "Page-based 48-bit Virtual Addressing Mode";
+            break;
+    }
+
+    rt_kprintf("\tMode = %s\n",mode_str);
+    rt_kprintf("-----------------Dump OK---------------------\n");
+    print_stacktrace(regs->epc,regs->s0_fp);
+}
+
+static const char *Exception_Name[] =
+                                {
+                                    "Instruction Address Misaligned",
+                                    "Instruction Access Fault",
+                                    "Illegal Instruction",
+                                    "Breakpoint",
+                                    "Load Address Misaligned",
+                                    "Load Access Fault",
+                                    "Store/AMO Address Misaligned",
+                                    "Store/AMO Access Fault",
+                                    "Environment call from U-mode",
+                                    "Environment call from S-mode",
+                                    "Reserved-10",
+                                    "Reserved-11",
+                                    "Instruction Page Fault",
+                                    "Load Page Fault",
+                                    "Reserved-14",
+                                    "Store/AMO Page Fault"
+                                };
+
+static const char *Interrupt_Name[] =
+                                {
+                                    "User Software Interrupt",
+                                    "Supervisor Software Interrupt",
+                                    "Reversed-2",
+                                    "Reversed-3",
+                                    "User Timer Interrupt",
+                                    "Supervisor Timer Interrupt",
+                                    "Reversed-6",
+                                    "Reversed-7",
+                                    "User External Interrupt",
+                                    "Supervisor External Interrupt",
+                                    "Reserved-10",
+                                    "Reserved-11",
+                                };
+
+static int sys_ticks = 0;
+
+extern struct rt_irq_desc isr_table[];
+
+//Trap处理入口
+void handle_trap(rt_size_t scause,rt_size_t stval,rt_size_t sepc,struct rt_hw_stack_frame *sp)
+{
+    rt_size_t id = __MASKVALUE(scause,__MASK(63UL));
+    const char *msg;
+
+    /* supervisor external interrupt */
+    if ((SCAUSE_INTERRUPT & scause) && SCAUSE_S_EXTERNAL_INTR == (scause & 0xff))
+    {
+        rt_interrupt_enter();
+        int irq = plic_claim();
+        rt_isr_handler_t isr;
+        void *param;
+
+        if (irq < 0 || irq >= IRQ_MAX_NR)
+        {
+            LOG_E("bad irq number %d!\n", irq);
+            return;
+        }
+
+        if (!irq)   // irq = 0 => no irq
+        {
+            LOG_W("no irq!\n");
+            return;
+        }
+        isr = isr_table[IRQ_OFFSET + irq].handler;
+        param = isr_table[IRQ_OFFSET + irq].param;
+        if (isr != RT_NULL)
+        {
+            isr(irq, param);
+        }
+        plic_complete(irq);
+        rt_interrupt_leave();
+        return;
+    }
+    else if ((SCAUSE_INTERRUPT | SCAUSE_S_TIMER_INTR) == scause)
+    {
+        /* supervisor timer */
+        sys_ticks++;
+        if (sys_ticks % RT_TICK_PER_SECOND == 0)
+        {
+            // rt_kprintf(".");
+        }
+        rt_interrupt_enter();
+        tick_isr();
+        rt_interrupt_leave();
+        return;
+    }
+    else if (SCAUSE_INTERRUPT & scause)
+    {
+        if(id < sizeof(Interrupt_Name) / sizeof(const char *))
+        {
+            msg = Interrupt_Name[id];
+        }
+        else
+        {
+            msg = "Unknown Interrupt";
+        }
+        LOG_E("Unhandled Interrupt %ld:%s\n",id,msg);
+    }
+    else
+    {
+#ifdef RT_USING_USERSPACE
+        /* page fault */
+        if (id == EP_LOAD_PAGE_FAULT ||
+            id == EP_STORE_PAGE_FAULT)
+        {
+            arch_expand_user_stack((void *)stval);
+            return;
+        }
+#endif
+        if(id < sizeof(Exception_Name) / sizeof(const char *))
+        {
+            msg = Exception_Name[id];
+        }
+        else
+        {
+            msg = "Unknown Exception";
+        }
+
+        rt_kprintf("Unhandled Exception %ld:%s\n",id,msg);
+    }
+
+    rt_kprintf("scause:0x%p,stval:0x%p,sepc:0x%p\n",scause,stval,sepc);
+    while(1);
+}