main.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. // See LICENSE for license details.
  2. #include <stdio.h>
  3. #include "nuclei_sdk_hal.h"
  4. #if !defined(__PMP_PRESENT) || (__PMP_PRESENT != 1)
  5. /* __PMP_PRESENT should be defined in <Device>.h */
  6. #warning "__PMP_PRESENT is not defined or equal to 1, please check!"
  7. #error "This example require CPU PMP feature!"
  8. #endif
  9. #if !defined(__SMODE_PRESENT) || (__SMODE_PRESENT == 0)
  10. /* __SMODE_PRESENT should be defined in <Device>.h */
  11. #warning "__SMODE_PRESENT is not defined or equal to 0, please check!"
  12. #error "This example require CPU SMODE feature!"
  13. #endif
  14. #if !defined(__SSTC_PRESENT) || (__SSTC_PRESENT == 0)
  15. /* __SSTC_PRESENT should be defined in <Device>.h */
  16. #warning "__SSTC_PRESENT is not defined or equal to 0, please check!"
  17. #error "This example require CPU SSTC feature!"
  18. #endif
  19. // 2048 is enough
  20. #define SMODE_STACK_SIZE 2048
  21. // 100ms
  22. #define TIMER_TICKS (SOC_TIMER_FREQ / 10)
  23. /* Create a stack for supervisor mode execution */
  24. uint8_t smode_stack[SMODE_STACK_SIZE] __attribute__((aligned(16)));
  25. uintptr_t smode_sp = (uintptr_t) (smode_stack + sizeof(smode_stack));
  26. /* Define the interrupt handler name same as vector table in case download mode is flashxip. */
  27. #define systimer_irq_handler core_stip_handler
  28. #define systimer_sw_irq_handler core_ssip_handler
  29. static uint32_t int0_cnt = 0; /* stip timer interrupt test counter */
  30. static uint32_t int1_cnt = 0; /* ssip timer interrupt test counter */
  31. unsigned int ssip_trig_flag = 1; /* sw trigger systimer sw interrupt flag */
  32. void systimer_irq_handler(void)
  33. {
  34. int0_cnt++;
  35. printf("SysTimer IRQ handler %d\n\r", int0_cnt);
  36. SysTick_Reload_S(TIMER_TICKS);
  37. }
  38. void systimer_sw_irq_handler(void)
  39. {
  40. /* To clear the software interrupt in CLINT interrupt mode, we need to clear
  41. * the SSIP bit field in SIP register */
  42. __RV_CSR_CLEAR(CSR_SIP, 1 << IRQ_S_SOFT);
  43. int1_cnt++;
  44. printf("SysTimer SW IRQ handler %d\n\r", int1_cnt);
  45. ssip_trig_flag = 1;
  46. }
  47. void setup_timer_s(void)
  48. {
  49. printf("init timer and start\n\r");
  50. SysTick_Config_S(TIMER_TICKS);
  51. }
  52. void print_sp_judge_privilege_mode(void)
  53. {
  54. uintptr_t sp;
  55. __asm__ volatile("add %0, x0, sp" :"=r"(sp));
  56. printf("Current sp is 0x%lx, ", (unsigned long)sp);
  57. if ( ((uint8_t *)sp <= &(smode_stack[SMODE_STACK_SIZE - 1])) && ((uint8_t *)sp >= &(smode_stack[0])) ) {
  58. printf("so it is in Supervisor Mode!\r\n");
  59. } else {
  60. printf("so it is in Machine Mode!\r\n");
  61. }
  62. }
  63. #ifdef CFG_SIMULATION
  64. #define LOOP_COUNT 2
  65. #else
  66. #define LOOP_COUNT 5
  67. #endif
  68. #if defined(__PMP_PRESENT) && (__PMP_PRESENT == 1)
  69. static void supervisor_mode_entry_point(void)
  70. {
  71. int32_t returnCode = 0;
  72. printf("[IN S-MODE ENTRY POINT] Hello Supervisor Mode!!!\r\n");
  73. print_sp_judge_privilege_mode();
  74. /* Enable S-mode interrupt overall */
  75. __enable_irq_s();
  76. /* Register and enable SysTimer_S_IRQn interrupt */
  77. returnCode = Core_Register_IRQ_S(SysTimer_S_IRQn, systimer_irq_handler); /* register system timer interrupt */
  78. setup_timer_s(); /* initialize timer */
  79. while (int0_cnt < LOOP_COUNT);
  80. __disable_core_irq_s(SysTimer_S_IRQn); /* Disable STIP interrupt */
  81. /* Register and enable SysTimerSW_S_IRQn interrupt */
  82. returnCode = Core_Register_IRQ_S(SysTimerSW_S_IRQn, systimer_sw_irq_handler); /* register system timer SW interrupt */
  83. do {
  84. if (ssip_trig_flag == 1) {
  85. ssip_trig_flag = 0;
  86. /* To trigger the software interrupt in CLINT interrupt mode, we need to set the
  87. * SSIP bit field in SIP register */
  88. __RV_CSR_SET(CSR_SIP, 1 << IRQ_S_SOFT);
  89. delay_1ms(200);
  90. }
  91. } while (int1_cnt < LOOP_COUNT); /* check test end condition */
  92. __disable_core_irq_s(SysTimerSW_S_IRQn); /* Disable SSIP interrupt */
  93. printf("SysTimer STIP and SSIP CLINT interrupt test finish and pass\r\n");
  94. #ifdef CFG_SIMULATION
  95. // directly exit if in nuclei internally simulation
  96. SIMULATION_EXIT(0);
  97. #endif
  98. while(1);
  99. }
  100. #endif /* #if defined(__PMP_PRESENT) && (__PMP_PRESENT == 1) */
  101. int main(int argc, char** argv)
  102. {
  103. // Check SSTC via CSR MCFGINFO register
  104. CSR_MCFGINFO_Type mcfg;
  105. mcfg.d = __RV_CSR_READ(CSR_MCFG_INFO);
  106. if (mcfg.b.sstc == 0) {
  107. printf("SSTC is not present, so will not run this example!\n");
  108. return 0;
  109. }
  110. /* Initialize interrupt as CLINT interrupt mode, see MTVEC register description */
  111. CLINT_Interrupt_Init();
  112. #if defined(__PMP_PRESENT) && (__PMP_PRESENT == 1)
  113. // set pmp, S mode can access all address range
  114. pmp_config pmp_cfg = {
  115. /* M mode grants S and U mode with full permission of the whole address range */
  116. .protection = PMP_L | PMP_R | PMP_W | PMP_X,
  117. /* Memory region range 2^__RISCV_XLEN bytes */
  118. .order = __RISCV_XLEN,
  119. /* Initial base address is 0 */
  120. .base_addr = 0,
  121. };
  122. __set_PMPENTRYx(0, &pmp_cfg);
  123. print_sp_judge_privilege_mode();
  124. /* Delegate S-mode sw interrupt and timer interrupt to S-mode */
  125. __set_mideleg(MIDELEG_STIE | MIDELEG_SSIE);
  126. SysTimer_EnableSSTC();
  127. printf("Drop to S-Mode now\n\r");
  128. /* Drop to S mode */
  129. __switch_mode(PRV_S, smode_sp, supervisor_mode_entry_point);
  130. #else
  131. printf("[ERROR]__PMP_PRESENT & __PMP_PRESENT must be defined as 1 in <Device>.h!\r\n");
  132. #endif
  133. return 0;
  134. }