board.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. /*
  2. * Copyright (c) 2006-2020, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-01-30 lizhirui first version
  9. */
  10. #include <rthw.h>
  11. #include <rtthread.h>
  12. #include <rtdevice.h>
  13. #include "board.h"
  14. #include "tick.h"
  15. #include "drv_uart.h"
  16. #include "encoding.h"
  17. #include "stack.h"
  18. #include "sbi.h"
  19. #include "riscv.h"
  20. #include "plic.h"
  21. #include "stack.h"
  22. #ifdef RT_USING_USERSPACE
  23. #include "riscv_mmu.h"
  24. #include "mmu.h"
  25. #include "page.h"
  26. #include "lwp_arch.h"
  27. rt_region_t init_page_region = {(rt_size_t)RT_HW_PAGE_START, (rt_size_t)RT_HW_PAGE_END};
  28. rt_mmu_info mmu_info;
  29. extern size_t MMUTable[];
  30. struct mem_desc platform_mem_desc[] = {
  31. {KERNEL_VADDR_START, KERNEL_VADDR_START + 0x10000000 - 1, KERNEL_VADDR_START + PV_OFFSET, NORMAL_MEM},
  32. };
  33. #define NUM_MEM_DESC (sizeof(platform_mem_desc) / sizeof(platform_mem_desc[0]))
  34. #endif
  35. void init_bss(void)
  36. {
  37. unsigned int *dst;
  38. dst = &__bss_start;
  39. while (dst < &__bss_end)
  40. {
  41. *dst++ = 0;
  42. }
  43. }
  44. void primary_cpu_entry(void)
  45. {
  46. extern void entry(void);
  47. /* disable global interrupt */
  48. init_bss();
  49. rt_hw_interrupt_disable();
  50. entry();
  51. }
  52. #define IOREMAP_SIZE (1ul << 30)
  53. void rt_hw_board_init(void)
  54. {
  55. #ifdef RT_USING_USERSPACE
  56. rt_page_init(init_page_region);
  57. /* init mmu_info structure */
  58. rt_hw_mmu_map_init(&mmu_info, (void *)(USER_VADDR_START - IOREMAP_SIZE), IOREMAP_SIZE, (rt_size_t *)MMUTable, 0);
  59. // this API is reserved currently since PLIC etc had not been porting completely to MMU version
  60. rt_hw_mmu_kernel_map_init(&mmu_info, 0x00000000UL, 0x80000000);
  61. /* setup region, and enable MMU */
  62. rt_hw_mmu_setup(&mmu_info, platform_mem_desc, NUM_MEM_DESC);
  63. #endif
  64. #ifdef RT_USING_HEAP
  65. /* initialize memory system */
  66. rt_system_heap_init(RT_HW_HEAP_BEGIN, RT_HW_HEAP_END);
  67. #endif
  68. rt_hw_uart_init();
  69. #ifdef RT_USING_CONSOLE
  70. /* set console device */
  71. rt_console_set_device("uart");
  72. #ifdef RT_USING_HEAP
  73. rt_kprintf("heap: [0x%08x - 0x%08x]\n", (rt_ubase_t)RT_HW_HEAP_BEGIN, (rt_ubase_t)RT_HW_HEAP_END);
  74. #endif
  75. rt_hw_interrupt_init();
  76. rt_hw_tick_init();
  77. #endif /* RT_USING_CONSOLE */
  78. #ifdef RT_USING_COMPONENTS_INIT
  79. rt_components_board_init();
  80. #endif
  81. plic_init();
  82. }
  83. void rt_hw_cpu_reset(void)
  84. {
  85. sbi_shutdown();
  86. while (1)
  87. ;
  88. }
  89. MSH_CMD_EXPORT_ALIAS(rt_hw_cpu_reset, reboot, reset machine);
  90. void dump_regs(struct rt_hw_stack_frame *regs)
  91. {
  92. rt_kprintf("--------------Dump Registers-----------------\n");
  93. rt_kprintf("Function Registers:\n");
  94. rt_kprintf("\tra(x1) = 0x%p\tuser_sp = 0x%p\n", regs->ra, regs->user_sp_exc_stack);
  95. rt_kprintf("\tgp(x3) = 0x%p\ttp(x4) = 0x%p\n", regs->gp, regs->tp);
  96. rt_kprintf("Temporary Registers:\n");
  97. rt_kprintf("\tt0(x5) = 0x%p\tt1(x6) = 0x%p\n", regs->t0, regs->t1);
  98. rt_kprintf("\tt2(x7) = 0x%p\n", regs->t2);
  99. rt_kprintf("\tt3(x28) = 0x%p\tt4(x29) = 0x%p\n", regs->t3, regs->t4);
  100. rt_kprintf("\tt5(x30) = 0x%p\tt6(x31) = 0x%p\n", regs->t5, regs->t6);
  101. rt_kprintf("Saved Registers:\n");
  102. rt_kprintf("\ts0/fp(x8) = 0x%p\ts1(x9) = 0x%p\n", regs->s0_fp, regs->s1);
  103. rt_kprintf("\ts2(x18) = 0x%p\ts3(x19) = 0x%p\n", regs->s2, regs->s3);
  104. rt_kprintf("\ts4(x20) = 0x%p\ts5(x21) = 0x%p\n", regs->s4, regs->s5);
  105. rt_kprintf("\ts6(x22) = 0x%p\ts7(x23) = 0x%p\n", regs->s6, regs->s7);
  106. rt_kprintf("\ts8(x24) = 0x%p\ts9(x25) = 0x%p\n", regs->s8, regs->s9);
  107. rt_kprintf("\ts10(x26) = 0x%p\ts11(x27) = 0x%p\n", regs->s10, regs->s11);
  108. rt_kprintf("Function Arguments Registers:\n");
  109. rt_kprintf("\ta0(x10) = 0x%p\ta1(x11) = 0x%p\n", regs->a0, regs->a1);
  110. rt_kprintf("\ta2(x12) = 0x%p\ta3(x13) = 0x%p\n", regs->a2, regs->a3);
  111. rt_kprintf("\ta4(x14) = 0x%p\ta5(x15) = 0x%p\n", regs->a4, regs->a5);
  112. rt_kprintf("\ta6(x16) = 0x%p\ta7(x17) = 0x%p\n", regs->a6, regs->a7);
  113. rt_kprintf("sstatus = 0x%p\n", regs->sstatus);
  114. rt_kprintf("\t%s\n", (regs->sstatus & SSTATUS_SIE) ? "Supervisor Interrupt Enabled" : "Supervisor Interrupt Disabled");
  115. rt_kprintf("\t%s\n", (regs->sstatus & SSTATUS_SPIE) ? "Last Time Supervisor Interrupt Enabled" : "Last Time Supervisor Interrupt Disabled");
  116. rt_kprintf("\t%s\n", (regs->sstatus & SSTATUS_SPP) ? "Last Privilege is Supervisor Mode" : "Last Privilege is User Mode");
  117. rt_kprintf("\t%s\n", (regs->sstatus & SSTATUS_PUM) ? "Permit to Access User Page" : "Not Permit to Access User Page");
  118. rt_kprintf("\t%s\n", (regs->sstatus & (1 << 19)) ? "Permit to Read Executable-only Page" : "Not Permit to Read Executable-only Page");
  119. rt_size_t satp_v = read_csr(satp);
  120. rt_kprintf("satp = 0x%p\n", satp_v);
  121. rt_kprintf("\tCurrent Page Table(Physical) = 0x%p\n", __MASKVALUE(satp_v, __MASK(44)) << PAGE_OFFSET_BIT);
  122. rt_kprintf("\tCurrent ASID = 0x%p\n", __MASKVALUE(satp_v >> 44, __MASK(16)) << PAGE_OFFSET_BIT);
  123. const char *mode_str = "Unknown Address Translation/Protection Mode";
  124. switch (__MASKVALUE(satp_v >> 60, __MASK(4)))
  125. {
  126. case 0:
  127. mode_str = "No Address Translation/Protection Mode";
  128. break;
  129. case 8:
  130. mode_str = "Page-based 39-bit Virtual Addressing Mode";
  131. break;
  132. case 9:
  133. mode_str = "Page-based 48-bit Virtual Addressing Mode";
  134. break;
  135. }
  136. rt_kprintf("\tMode = %s\n", mode_str);
  137. rt_kprintf("-----------------Dump OK---------------------\n");
  138. }
  139. static const char *Exception_Name[] =
  140. {
  141. "Instruction Address Misaligned",
  142. "Instruction Access Fault",
  143. "Illegal Instruction",
  144. "Breakpoint",
  145. "Load Address Misaligned",
  146. "Load Access Fault",
  147. "Store/AMO Address Misaligned",
  148. "Store/AMO Access Fault",
  149. "Environment call from U-mode",
  150. "Environment call from S-mode",
  151. "Reserved-10",
  152. "Reserved-11",
  153. "Instruction Page Fault",
  154. "Load Page Fault",
  155. "Reserved-14",
  156. "Store/AMO Page Fault"};
  157. static const char *Interrupt_Name[] =
  158. {
  159. "User Software Interrupt",
  160. "Supervisor Software Interrupt",
  161. "Reversed-2",
  162. "Reversed-3",
  163. "User Timer Interrupt",
  164. "Supervisor Timer Interrupt",
  165. "Reversed-6",
  166. "Reversed-7",
  167. "User External Interrupt",
  168. "Supervisor External Interrupt",
  169. "Reserved-10",
  170. "Reserved-11",
  171. };
  172. extern struct rt_irq_desc irq_desc[];
  173. void handle_trap(rt_size_t scause, rt_size_t stval, rt_size_t sepc, struct rt_hw_stack_frame *sp)
  174. {
  175. // rt_kprintf(".");
  176. if (scause == (uint64_t)(0x8000000000000005))
  177. {
  178. rt_interrupt_enter();
  179. tick_isr();
  180. rt_interrupt_leave();
  181. }
  182. else if (scause == (uint64_t)(0x8000000000000009))
  183. {
  184. int plic_irq = plic_claim();
  185. plic_complete(plic_irq);
  186. irq_desc[plic_irq].handler(plic_irq, irq_desc[plic_irq].param);
  187. }
  188. else
  189. {
  190. rt_size_t id = __MASKVALUE(scause, __MASK(63UL));
  191. const char *msg;
  192. if (scause >> 63)
  193. {
  194. if (id < sizeof(Interrupt_Name) / sizeof(const char *))
  195. {
  196. msg = Interrupt_Name[id];
  197. }
  198. else
  199. {
  200. msg = "Unknown Interrupt";
  201. }
  202. rt_kprintf("Unhandled Interrupt %ld:%s\n", id, msg);
  203. }
  204. else
  205. {
  206. #ifdef RT_USING_USERSPACE
  207. if (id == 15)
  208. {
  209. arch_expand_user_stack((void *)stval);
  210. return;
  211. }
  212. #endif
  213. if (id < sizeof(Exception_Name) / sizeof(const char *))
  214. {
  215. msg = Exception_Name[id];
  216. }
  217. else
  218. {
  219. msg = "Unknown Exception";
  220. }
  221. rt_kprintf("Unhandled Exception %ld:%s\n", id, msg);
  222. }
  223. rt_kprintf("scause:0x%p,stval:0x%p,sepc:0x%p\n", scause, stval, sepc);
  224. dump_regs(sp);
  225. while (1)
  226. ;
  227. }
  228. }