board.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /*
  2. * Copyright (c) 2006-2019, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2019-07-29 zdzn first version
  9. */
  10. #include <rthw.h>
  11. #include <rtthread.h>
  12. #include "board.h"
  13. #include "drv_uart.h"
  14. #include "drv_timer.h"
  15. #include "cp15.h"
  16. #include "mmu.h"
  17. #ifdef RT_USING_SMP
  18. extern void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler);
  19. void ipi_handler(){
  20. rt_scheduler_ipi_handler(0,RT_NULL);
  21. }
  22. #endif
  23. void rt_hw_timer_isr(int vector, void *parameter)
  24. {
  25. ARM_TIMER_IRQCLR = 0;
  26. rt_tick_increase();
  27. }
  28. int rt_hw_timer_init()
  29. {
  30. __DSB();
  31. rt_hw_interrupt_install(IRQ_ARM_TIMER, rt_hw_timer_isr, RT_NULL, "tick");
  32. rt_hw_interrupt_umask(IRQ_ARM_TIMER);
  33. /* timer_clock = apb_clock/(pre_divider + 1) */
  34. ARM_TIMER_PREDIV = (250 - 1);
  35. ARM_TIMER_RELOAD = 0;
  36. ARM_TIMER_LOAD = 0;
  37. ARM_TIMER_IRQCLR = 0;
  38. ARM_TIMER_CTRL = 0;
  39. ARM_TIMER_RELOAD = 10000;
  40. ARM_TIMER_LOAD = 10000;
  41. /* 23-bit counter, enable interrupt, enable timer */
  42. ARM_TIMER_CTRL = (1 << 1) | (1 << 5) | (1 << 7);
  43. return 0;
  44. }
  45. void idle_wfi(void)
  46. {
  47. asm volatile ("wfi");
  48. }
  49. /**
  50. * Initialize the Hardware related stuffs. Called from rtthread_startup()
  51. * after interrupt disabled.
  52. */
  53. void rt_hw_board_init(void)
  54. {
  55. mmu_init();
  56. armv8_map(0, 0, 0x800000, MEM_ATTR_MEMORY);
  57. armv8_map(0x3f00B000, 0x3f00B000, 0x1000, MEM_ATTR_IO);//timer
  58. armv8_map(0x3f200000, 0x3f200000, 0x16000, MEM_ATTR_IO);//uart
  59. mmu_enable();
  60. /* initialize hardware interrupt */
  61. rt_hw_interrupt_init(); // in libcpu/interrupt.c. Set some data structures, no operation on device
  62. rt_hw_vector_init(); // in libcpu/interrupt.c. == rt_cpu_vector_set_base((rt_ubase_t)&system_vectors);
  63. /* initialize uart */
  64. rt_hw_uart_init(); // driver/drv_uart.c
  65. /* initialize timer for os tick */
  66. rt_hw_timer_init();
  67. rt_thread_idle_sethook(idle_wfi);
  68. #ifdef RT_USING_CONSOLE
  69. /* set console device */
  70. rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
  71. #endif /* RT_USING_CONSOLE */
  72. #ifdef RT_USING_HEAP
  73. /* initialize memory system */
  74. rt_kprintf("heap: 0x%08x - 0x%08x\n", RT_HW_HEAP_BEGIN, RT_HW_HEAP_END);
  75. rt_system_heap_init(RT_HW_HEAP_BEGIN, RT_HW_HEAP_END);
  76. #endif
  77. #ifdef RT_USING_COMPONENTS_INIT
  78. rt_components_board_init();
  79. #endif
  80. }
  81. #ifdef RT_USING_SMP
  82. void _reset(void);
  83. void secondary_cpu_start(void);
  84. void rt_hw_secondary_cpu_up(void)
  85. {
  86. int i;
  87. int retry,val;
  88. rt_cpu_dcache_clean_flush();
  89. rt_cpu_icache_flush();
  90. /*TODO maybe, there is some bug */
  91. for(i=RT_CPUS_NR-1; i>0; i-- )
  92. {
  93. rt_kprintf("boot cpu:%d\n", i);
  94. setup_bootstrap_addr(i, (int)_reset);
  95. __SEV();
  96. __DSB();
  97. __ISB();
  98. retry = 10;
  99. rt_thread_delay(RT_TICK_PER_SECOND/1000);
  100. do
  101. {
  102. val = CORE_MAILBOX3_CLEAR(i);
  103. if (val == 0)
  104. {
  105. rt_kprintf("start OK: CPU %d \n",i);
  106. break;
  107. }
  108. rt_thread_delay(RT_TICK_PER_SECOND);
  109. retry --;
  110. if (retry <= 0)
  111. {
  112. rt_kprintf("can't start for CPU %d \n",i);
  113. break;
  114. }
  115. }while (1);
  116. }
  117. __DSB();
  118. __SEV();
  119. }
  120. void secondary_cpu_c_start(void)
  121. {
  122. uint32_t id;
  123. id = rt_hw_cpu_id();
  124. rt_kprintf("cpu = 0x%08x\n",id);
  125. rt_hw_timer_init();
  126. rt_kprintf("cpu %d startup.\n",id);
  127. rt_hw_vector_init();
  128. enable_cpu_ipi_intr(id);
  129. rt_hw_spin_lock(&_cpus_lock);
  130. rt_system_scheduler_start();
  131. }
  132. void rt_hw_secondary_cpu_idle_exec(void)
  133. {
  134. __WFE();
  135. }
  136. #endif