main.c 4.0 KB

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