board.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-3-08 GuEe-GUI the first version
  9. */
  10. #include <rthw.h>
  11. #include <rtthread.h>
  12. #include <mmu.h>
  13. #include <psci.h>
  14. #include <gicv3.h>
  15. #include <gtimer.h>
  16. #include <cpuport.h>
  17. #include <interrupt.h>
  18. #include <ioremap.h>
  19. #include <psci_api.h>
  20. #include <board.h>
  21. #include <drv_uart.h>
  22. #include "mm_page.h"
  23. #define PLATFORM_MEM_TALBE(va, size) va, ((unsigned long)va + size - 1)
  24. struct mem_desc platform_mem_desc[] =
  25. {
  26. {PLATFORM_MEM_TALBE(0x20000000, 0x10000000), 0x20000000, NORMAL_MEM},
  27. {PLATFORM_MEM_TALBE(GRF_PMU_BASE, 0x10000), GRF_PMU_BASE, DEVICE_MEM},
  28. {PLATFORM_MEM_TALBE(GRF_SYS_BASE, 0x10000), GRF_SYS_BASE, DEVICE_MEM},
  29. {PLATFORM_MEM_TALBE(CRU_BASE, 0x10000), CRU_BASE, DEVICE_MEM},
  30. {PLATFORM_MEM_TALBE(UART0_MMIO_BASE, 0x10000), UART0_MMIO_BASE, DEVICE_MEM},
  31. {PLATFORM_MEM_TALBE(UART1_MMIO_BASE, 0x90000), UART1_MMIO_BASE, DEVICE_MEM},
  32. {PLATFORM_MEM_TALBE(GIC_PL600_DISTRIBUTOR_PPTR, 0x10000), GIC_PL600_DISTRIBUTOR_PPTR, DEVICE_MEM},
  33. {PLATFORM_MEM_TALBE(GIC_PL600_REDISTRIBUTOR_PPTR, 0xc0000), GIC_PL600_REDISTRIBUTOR_PPTR, DEVICE_MEM},
  34. #ifdef PKG_USING_RT_OPENAMP
  35. {PLATFORM_MEM_TALBE(AMP_SHARE_MEMORY_ADDRESS, AMP_SHARE_MEMORY_SIZE), AMP_SHARE_MEMORY_ADDRESS, NORMAL_MEM},
  36. #endif /* PKG_USING_RT_OPENAMP */
  37. };
  38. const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc) / sizeof(platform_mem_desc[0]);
  39. void idle_wfi(void)
  40. {
  41. __asm__ volatile ("wfi");
  42. }
  43. void rt_hw_board_init(void)
  44. {
  45. extern unsigned long MMUTable[512];
  46. rt_region_t init_page_region;
  47. rt_hw_mmu_map_init(&rt_kernel_space, (void *) 0x20000000, 0xE0000000 - 1, MMUTable, 0);
  48. init_page_region.start = RT_HW_PAGE_START;
  49. init_page_region.end = RT_HW_PAGE_END;
  50. rt_page_init(init_page_region);
  51. rt_hw_mmu_setup(&rt_kernel_space, platform_mem_desc, platform_mem_desc_size);
  52. /* initialize hardware interrupt */
  53. rt_hw_interrupt_init();
  54. /* initialize uart */
  55. rt_hw_uart_init();
  56. /* initialize timer for os tick */
  57. rt_hw_gtimer_init();
  58. rt_thread_idle_sethook(idle_wfi);
  59. // TODO porting to FDT-driven PSCI: arm_psci_init(PSCI_METHOD_SMC, RT_NULL, RT_NULL);
  60. psci_init();
  61. #if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE)
  62. /* set console device */
  63. rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
  64. #endif
  65. #ifdef RT_USING_HEAP
  66. /* initialize memory system */
  67. rt_kprintf("heap: [0x%08x - 0x%08x]\n", RT_HW_HEAP_BEGIN, RT_HW_HEAP_END);
  68. rt_system_heap_init(RT_HW_HEAP_BEGIN, RT_HW_HEAP_END);
  69. #endif
  70. #ifdef RT_USING_COMPONENTS_INIT
  71. rt_components_board_init();
  72. #endif
  73. #ifdef RT_USING_SMP
  74. /* install IPI handle */
  75. rt_hw_ipi_handler_install(RT_SCHEDULE_IPI, rt_scheduler_ipi_handler);
  76. arm_gic_umask(0, IRQ_ARM_IPI_KICK);
  77. #endif
  78. }
  79. void reboot(void)
  80. {
  81. // TODO poring to FDT to use new PSCI: arm_psci_system_reboot();
  82. if (psci_ops.system_reset)
  83. {
  84. psci_ops.system_reset();
  85. }
  86. else
  87. {
  88. void *cur_base = rt_ioremap((void *) CRU_BASE, 0x100);
  89. HWREG32(cur_base + 0x00D4) = 0xfdb9;
  90. HWREG32(cur_base + 0x00D8) = 0xeca8;
  91. }
  92. }
  93. MSH_CMD_EXPORT(reboot, reboot...);
  94. static void print_cpu_id(int argc, char *argv[])
  95. {
  96. rt_kprintf("rt_hw_cpu_id:%d\n", rt_hw_cpu_id());
  97. }
  98. MSH_CMD_EXPORT_ALIAS(print_cpu_id, cpuid, print_cpu_id);
  99. #ifdef RT_USING_AMP
  100. void start_cpu(int argc, char *argv[])
  101. {
  102. rt_uint32_t status;
  103. if (psci_ops.cpu_on)
  104. {
  105. status = psci_ops.cpu_on(0x3, (rt_uint64_t) 0x7A000000);
  106. rt_kprintf("arm_psci_cpu_on 0x%X\n", status);
  107. }
  108. }
  109. MSH_CMD_EXPORT(start_cpu, start_cpu);
  110. #ifdef RT_AMP_SLAVE
  111. void rt_hw_cpu_shutdown()
  112. {
  113. if (psci_ops.cpu_off)
  114. {
  115. psci_ops.cpu_off(0);
  116. }
  117. }
  118. #endif /* RT_AMP_SLAVE */
  119. #endif /* RT_USING_AMP */
  120. #if defined(RT_USING_SMP) || defined(RT_USING_AMP)
  121. rt_uint64_t rt_cpu_mpidr_early[] =
  122. {
  123. [0] = 0x80000000,
  124. [1] = 0x80000100,
  125. [2] = 0x80000200,
  126. [3] = 0x80000300,
  127. [RT_CPUS_NR] = 0
  128. };
  129. #endif
  130. #ifdef RT_USING_SMP
  131. void rt_hw_secondary_cpu_up(void)
  132. {
  133. int i;
  134. extern void secondary_cpu_start(void);
  135. for (i = 1; i < RT_CPUS_NR; ++i)
  136. {
  137. arm_psci_cpu_on(rt_cpu_mpidr_early[i], (rt_uint64_t) secondary_cpu_start);
  138. }
  139. }
  140. void secondary_cpu_c_start(void)
  141. {
  142. rt_hw_mmu_init();
  143. rt_hw_spin_lock(&_cpus_lock);
  144. arm_gic_cpu_init(0, platform_get_gic_cpu_base());
  145. arm_gic_redist_init(0, platform_get_gic_redist_base());
  146. rt_hw_vector_init();
  147. rt_hw_gtimer_local_enable();
  148. arm_gic_umask(0, IRQ_ARM_IPI_KICK);
  149. rt_kprintf("\rcall cpu %d on success\n", rt_hw_cpu_id());
  150. rt_system_scheduler_start();
  151. }
  152. void rt_hw_secondary_cpu_idle_exec(void)
  153. {
  154. __WFE();
  155. }
  156. #endif