drv_common_aarch32.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /**************************************************************************//**
  2. *
  3. * @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0
  6. *
  7. * Change Logs:
  8. * Date Author Notes
  9. * 2021-07-14 Wayne First version
  10. *
  11. ******************************************************************************/
  12. #include <rtthread.h>
  13. #if defined(USE_MA35D1_AARCH32)
  14. #include <rthw.h>
  15. #include <stdio.h>
  16. #include "drv_common.h"
  17. #include "board.h"
  18. #include "drv_uart.h"
  19. #include "drv_sspcc.h"
  20. #include "drv_ssmcc.h"
  21. #include "drv_umctl2.h"
  22. #define LOG_TAG "drv.common"
  23. #define DBG_SECTION_NAME LOG_TAG
  24. #define DBG_LEVEL LOG_LVL_INFO
  25. #define DBG_COLOR
  26. #include <rtdbg.h>
  27. #define NORMAL_MEM_UNCACHED (SHARED|AP_RW|DOMAIN0|STRONGORDER|DESC_SEC)
  28. /*
  29. MMU TLB setting:
  30. 0xFFFFFFFF ----------------------------
  31. | 1GB DDR(non-cacheable) |
  32. 0xC0000000 ----------------------------
  33. | 1GB DDR(cacheable) |
  34. 0x80000000 ----------------------------
  35. | DEVICE_MEM |
  36. | |
  37. 0x00000000 ----------------------------
  38. */
  39. struct mem_desc platform_mem_desc[] =
  40. {
  41. {0x00000000, 0x7FFFFFFF, 0x00000000, DEVICE_MEM}, // Peripherals
  42. {0x80000000, DDR_LIMIT_SIZE - 1, 0x80000000, NORMAL_MEM}, // 1GB DDR, cacheable
  43. {0xC0000000, 0xFFFFFFFF, 0x80000000, NORMAL_MEM_UNCACHED} // 1GB DDR, non-cacheable
  44. };
  45. const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc) / sizeof(platform_mem_desc[0]);
  46. /**
  47. * This function will initialize board
  48. */
  49. rt_mmu_info mmu_info;
  50. extern size_t MMUTable[];
  51. extern void nu_clock_dump(void);
  52. extern void nu_clock_raise(void);
  53. extern void nu_clock_init(void);
  54. extern void nu_chipcfg_dump(void);
  55. extern uint32_t nu_chipcfg_ddrsize(void);
  56. volatile uint32_t secondary_cpu_entry __attribute__((aligned(32))) = 0;
  57. static rt_uint32_t timerStep;
  58. void rt_hw_systick_isr(int vector, void *parameter)
  59. {
  60. gtimer_set_load_value(timerStep);
  61. rt_tick_increase();
  62. }
  63. int rt_hw_systick_init(void)
  64. {
  65. rt_hw_interrupt_install(NonSecPhysicalTimer_IRQn, rt_hw_systick_isr, RT_NULL, "systick");
  66. rt_hw_interrupt_umask(NonSecPhysicalTimer_IRQn);
  67. timerStep = gtimer_get_counter_frequency();
  68. timerStep /= RT_TICK_PER_SECOND;
  69. gtimer_set_load_value(timerStep);
  70. gtimer_set_control(1);
  71. return 0;
  72. }
  73. void rt_hw_us_delay(rt_uint32_t us)
  74. {
  75. rt_uint32_t ticks;
  76. volatile rt_uint32_t told, tnow, tcnt = 0;
  77. rt_uint32_t cmp = timerStep; // 12000 count / 1ms
  78. ticks = us * (cmp / 1000); // us * 12(count/1us)
  79. told = gtimer_get_current_value();
  80. while (1)
  81. {
  82. /* Timer counter is increment. */
  83. tnow = gtimer_get_current_value();
  84. if (tnow != told)
  85. {
  86. /* 0 -- now === old -------- cmp */
  87. if (tnow < told)
  88. {
  89. tcnt += (told - tnow);
  90. }
  91. else
  92. {
  93. /* 0 == old --- new ======== cmp */
  94. tcnt += (cmp - tnow + told);
  95. }
  96. told = tnow;
  97. /* Timeout */
  98. if (tcnt >= ticks)
  99. {
  100. break;
  101. }
  102. }
  103. __NOP();
  104. }
  105. } /* rt_hw_us_delay */
  106. void idle_wfi(void)
  107. {
  108. asm volatile("wfi");
  109. }
  110. rt_weak void nutool_pincfg_init(void)
  111. {
  112. }
  113. /**
  114. * This function will initial board.
  115. */
  116. rt_weak void rt_hw_board_init(void)
  117. {
  118. uint32_t u32BoardHeapEnd;
  119. /* Unlock protected registers */
  120. SYS_UnlockReg();
  121. /* initialize SSPCC */
  122. nu_sspcc_init();
  123. /* initialize SSMCC */
  124. nu_ssmcc_init();
  125. /* initialize UMCTL2 */
  126. nu_umctl2_init();
  127. /* initialize base clock */
  128. nu_clock_init();
  129. /* initialize peripheral pin function */
  130. nutool_pincfg_init();
  131. rt_hw_mmu_map_init(&mmu_info, (void*)0x80000000, 0x10000000, MMUTable, 0);
  132. rt_hw_mmu_ioremap_init(&mmu_info, (void*)0x80000000, 0x10000000);
  133. /* initialize hardware interrupt */
  134. rt_hw_interrupt_init();
  135. #if defined(RT_USING_HEAP)
  136. if (nu_chipcfg_ddrsize() > 0)
  137. {
  138. /* Get MCP DDR capacity in run-time. */
  139. u32BoardHeapEnd = 0x80000000 + nu_chipcfg_ddrsize();
  140. }
  141. else
  142. {
  143. /* Use board.h definition */
  144. u32BoardHeapEnd = (uint32_t)BOARD_HEAP_END;
  145. }
  146. rt_system_heap_init((void *)BOARD_HEAP_START, (void *)u32BoardHeapEnd);
  147. #endif
  148. /* initialize uart */
  149. rt_hw_uart_init();
  150. #if defined(RT_USING_CONSOLE)
  151. rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
  152. #endif
  153. nu_clock_raise();
  154. /* initialize systick */
  155. rt_hw_systick_init();
  156. rt_thread_idle_sethook(idle_wfi);
  157. #if defined(RT_USING_COMPONENTS_INIT)
  158. rt_components_board_init();
  159. #endif
  160. #if defined(RT_USING_HEAP)
  161. /* Dump heap information */
  162. LOG_I("Heap: Begin@%08x, END@%08x, SIZE: %d MB", BOARD_HEAP_START, u32BoardHeapEnd, ((rt_uint32_t)u32BoardHeapEnd - (rt_uint32_t)BOARD_HEAP_START) / 1024 / 1024);
  163. #endif
  164. nu_chipcfg_dump();
  165. nu_clock_dump();
  166. #if defined(RT_USING_SMP)
  167. /* install IPI handle */
  168. rt_hw_interrupt_set_priority(RT_SCHEDULE_IPI, 16);
  169. rt_hw_ipi_handler_install(RT_SCHEDULE_IPI, rt_scheduler_ipi_handler);
  170. rt_hw_interrupt_umask(RT_SCHEDULE_IPI);
  171. #endif
  172. }
  173. #if defined(RT_USING_SMP)
  174. extern void rt_secondary_cpu_entry(void);
  175. void set_secondary_cpu_boot_address(void)
  176. {
  177. secondary_cpu_entry = (uint32_t)&rt_secondary_cpu_entry;
  178. rt_kprintf("Wake up cpu-1 goto -> 0x%08x@0x%08x\n", secondary_cpu_entry, &secondary_cpu_entry);
  179. }
  180. void rt_hw_secondary_cpu_up(void)
  181. {
  182. rt_uint32_t i;
  183. rt_uint32_t cpu_mask;
  184. rt_kprintf("rt_hw_secondary_cpu_up is processing \r\n");
  185. set_secondary_cpu_boot_address();
  186. /* Flush to memory */
  187. rt_cpu_dcache_clean_flush();
  188. for (i = 1; i < RT_CPUS_NR; i++)
  189. {
  190. rt_kprintf("Bring up cpu-%d\r\n", i);
  191. cpu_mask = 1 << i;
  192. __asm__ volatile("dsb" ::
  193. : "memory");
  194. __asm__ volatile("isb" ::
  195. : "memory");
  196. __asm__ volatile("sev");
  197. rt_hw_ipi_send(RT_SCHEDULE_IPI, cpu_mask);
  198. }
  199. }
  200. void rt_hw_secondary_cpu_bsp_start(void)
  201. {
  202. rt_kprintf("[%s] cpu-%d\r\n", __func__, rt_hw_cpu_id());
  203. rt_hw_vector_init();
  204. rt_hw_spin_lock(&_cpus_lock);
  205. arm_gic_cpu_init(0, platform_get_gic_cpu_base());
  206. rt_hw_systick_init();
  207. rt_system_scheduler_start();
  208. }
  209. void rt_hw_secondary_cpu_idle_exec(void)
  210. {
  211. asm volatile("wfe" ::
  212. : "memory", "cc");
  213. }
  214. #endif
  215. #endif /* #if defined(USE_MA35D1_AARCH32) */