main.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /*
  2. * Copyright (c) 2006-2019, RT-Thread Development Team
  3. * Copyright (c) 2019-Present Nuclei Limited. All rights reserved.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0
  6. *
  7. * Change Logs:
  8. * Date Author Notes
  9. * 2020-03-26 Huaqi the first version
  10. */
  11. #include "core_feature_base.h"
  12. #include "nuclei_sdk_soc.h"
  13. #include <rtthread.h>
  14. #include <stdio.h>
  15. #if !defined(__SMODE_PRESENT) || (__SMODE_PRESENT != 1)
  16. /* __SMODE_PRESENT should be defined in <Device>.h */
  17. #error "This example require CPU S-MODE feature!"
  18. #endif
  19. #if !defined(__PMP_PRESENT) || (__PMP_PRESENT != 1)
  20. /* __PMP_PRESENT should be defined in <Device>.h */
  21. #error "This example require CPU PMP feature!"
  22. #endif
  23. #define THREAD_PRIORITY 2
  24. #define THREAD_STACK_SIZE 512
  25. #define THREAD_TIMESLICE 5
  26. #define THREAD_NUM 5
  27. /* Align stack when using static thread */
  28. ALIGN(RT_ALIGN_SIZE)
  29. static rt_uint8_t thread_stack[THREAD_NUM][THREAD_STACK_SIZE];
  30. static struct rt_thread tid[THREAD_NUM];
  31. /* Thread entry function */
  32. static void thread_entry(void* parameter)
  33. {
  34. rt_uint32_t count = 0;
  35. while (1) {
  36. rt_kprintf("thread %d count: %d\n", (rt_uint32_t)parameter, count++);
  37. rt_thread_mdelay(250);
  38. }
  39. }
  40. /* Thread demo */
  41. int create_thread_demo(void)
  42. {
  43. unsigned long i;
  44. for (i = 0; i < THREAD_NUM; i ++) {
  45. /* Create static threads */
  46. rt_thread_init(&tid[i], "thread", thread_entry, (void*)i, thread_stack[i],
  47. THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
  48. }
  49. /* Startup threads */
  50. for (i = 0; i < THREAD_NUM; i ++) {
  51. rt_thread_startup(&tid[i]);
  52. }
  53. return 0;
  54. }
  55. int main(void)
  56. {
  57. rt_uint32_t count = 0;
  58. create_thread_demo();
  59. while (1) {
  60. rt_kprintf("Main thread count: %d\n", count++);
  61. rt_thread_mdelay(500);
  62. #ifdef CFG_SIMULATION
  63. if (count > 2) {
  64. // directly exit if in nuclei internally simulation
  65. SIMULATION_EXIT(0);
  66. }
  67. #endif
  68. }
  69. }
  70. extern void entry(void);
  71. #define SMODE_STACK_SIZE 2048
  72. // Execute Hart ID
  73. #define EXECUTE_HARTID 0
  74. #if defined(__SSTC_PRESENT) && __SSTC_PRESENT == 1
  75. #define SMODE_TIMER_IRQ SysTimer_S_IRQn
  76. #define SMODE_SWI_IRQ SysTimerSW_S_IRQn
  77. #else
  78. #define SMODE_TIMER_IRQ SysTimer_IRQn
  79. #define SMODE_SWI_IRQ SysTimerSW_IRQn
  80. #endif
  81. /* Create a stack for supervisor mode execution */
  82. uint8_t smode_stack[SMODE_STACK_SIZE] __attribute__((aligned(16)));
  83. uintptr_t smode_sp = (uintptr_t) (smode_stack + sizeof(smode_stack));
  84. int main_entry(void)
  85. {
  86. CSR_MCFGINFO_Type mcfg;
  87. CSR_MISA_Type misa;
  88. mcfg.d = __RV_CSR_READ(CSR_MCFG_INFO);
  89. misa.d = __RV_CSR_READ(CSR_MISA);
  90. if ((mcfg.b.clic & misa.b.s) == 0) {
  91. printf("INFO: S-Mode and ECLIC feature are required to run this SMode RT-Thread Demo\n");
  92. return 0;
  93. }
  94. #if defined(__SSTC_PRESENT) && __SSTC_PRESENT == 1
  95. if (mcfg.b.sstc == 0) {
  96. printf("INFO: SSTC feature are required to run this SMode RT-Thread Demo\n");
  97. return 0;
  98. }
  99. #endif
  100. // set pmp, S mode can access all address range
  101. pmp_config pmp_cfg = {
  102. /* M mode grants S and U mode with full permission of the whole address range */
  103. .protection = PMP_L | PMP_R | PMP_W | PMP_X,
  104. /* Memory region range 2^__RISCV_XLEN bytes */
  105. .order = __RISCV_XLEN,
  106. /* Initial base address is 0 */
  107. .base_addr = 0,
  108. };
  109. __set_PMPENTRYx(0, &pmp_cfg);
  110. // before drop to S Mode, specifies in which privilege mode the interrupt should be taken
  111. ECLIC_SetModeIRQ(SMODE_TIMER_IRQ, PRV_S);
  112. ECLIC_SetModeIRQ(SMODE_SWI_IRQ, PRV_S);
  113. #if defined(__SSTC_PRESENT) && __SSTC_PRESENT == 1
  114. /* Disable S-mode access some system timer registers */
  115. SysTimer_DisableSAccess();
  116. /* Enable CY,TM,IR in CSR_MCOUNTEREN to allow S-mode access cycle,time,instret csr */
  117. SysTimer_EnableSSTC();
  118. printf("Set ECLIC Timer S-Mode Interrupt and Software Timer S-Mode Interrupt to be executed in S-Mode\r\n");
  119. #else
  120. printf("Set ECLIC Timer M-Mode Interrupt and Software Timer M-Mode Interrupt to be executed in S-Mode\r\n");
  121. SysTimer_EnableSAccess();
  122. #endif
  123. printf("Drop to S-Mode to prepare RT-Thread Environment\r\n");
  124. /* Drop to S mode */
  125. __switch_mode(PRV_S, smode_sp, entry);
  126. // Should never return here
  127. return 1;
  128. }