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
11 #include <rthw.h>
12 #include <rtthread.h>
13
14 #include <mmu.h>
15 #include <rtdevice.h>
16 #include <gicv3.h>
17 #include <gtimer.h>
18 #include <cpuport.h>
19 #include <interrupt.h>
20 #include <ioremap.h>
21 #include <psci.h>
22 #include <board.h>
23 #include <drv_uart.h>
24
25 #include "mm_page.h"
26
27 #define PLATFORM_MEM_TALBE(va, size) va, ((unsigned long)va + size - 1)
28
29 struct mem_desc platform_mem_desc[] =
30 {
31 {PLATFORM_MEM_TALBE(0x20000000, 0x10000000), 0x20000000, NORMAL_MEM},
32 {PLATFORM_MEM_TALBE(GRF_PMU_BASE, 0x10000), GRF_PMU_BASE, DEVICE_MEM},
33 {PLATFORM_MEM_TALBE(GRF_SYS_BASE, 0x10000), GRF_SYS_BASE, DEVICE_MEM},
34 {PLATFORM_MEM_TALBE(CRU_BASE, 0x10000), CRU_BASE, DEVICE_MEM},
35 {PLATFORM_MEM_TALBE(UART0_MMIO_BASE, 0x10000), UART0_MMIO_BASE, DEVICE_MEM},
36 {PLATFORM_MEM_TALBE(UART1_MMIO_BASE, 0x90000), UART1_MMIO_BASE, DEVICE_MEM},
37 {PLATFORM_MEM_TALBE(GIC_PL600_DISTRIBUTOR_PPTR, 0x10000), GIC_PL600_DISTRIBUTOR_PPTR, DEVICE_MEM},
38 {PLATFORM_MEM_TALBE(GIC_PL600_REDISTRIBUTOR_PPTR, 0xc0000), GIC_PL600_REDISTRIBUTOR_PPTR, DEVICE_MEM},
39 #ifdef PKG_USING_RT_OPENAMP
40 {PLATFORM_MEM_TALBE(AMP_SHARE_MEMORY_ADDRESS, AMP_SHARE_MEMORY_SIZE), AMP_SHARE_MEMORY_ADDRESS, NORMAL_MEM},
41 #endif /* PKG_USING_RT_OPENAMP */
42 };
43
44 const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc) / sizeof(platform_mem_desc[0]);
45
idle_wfi(void)46 void idle_wfi(void)
47 {
48 __asm__ volatile ("wfi");
49 }
50
rt_hw_board_init(void)51 void rt_hw_board_init(void)
52 {
53 extern unsigned long MMUTable[512];
54 rt_region_t init_page_region;
55
56 rt_hw_mmu_map_init(&rt_kernel_space, (void *) 0x20000000, 0xE0000000 - 1, MMUTable, 0);
57
58 init_page_region.start = RT_HW_PAGE_START;
59 init_page_region.end = RT_HW_PAGE_END;
60 rt_page_init(init_page_region);
61
62 rt_hw_mmu_setup(&rt_kernel_space, platform_mem_desc, platform_mem_desc_size);
63
64 #ifdef RT_USING_HEAP
65 /* initialize memory system */
66 rt_system_heap_init(RT_HW_HEAP_BEGIN, RT_HW_HEAP_END);
67 #endif
68 /* initialize hardware interrupt */
69 rt_hw_interrupt_init();
70
71 /* initialize uart */
72 rt_hw_uart_init();
73
74 /* initialize timer for os tick */
75 rt_hw_gtimer_init();
76
77 rt_thread_idle_sethook(idle_wfi);
78
79 #if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE)
80 /* set console device */
81 rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
82 #endif
83
84 #ifdef RT_USING_HEAP
85 /* initialize memory system */
86 rt_kprintf("heap: [0x%08x - 0x%08x]\n", RT_HW_HEAP_BEGIN, RT_HW_HEAP_END);
87 #endif
88
89 #ifdef RT_USING_COMPONENTS_INIT
90 rt_components_board_init();
91 #endif
92
93 #ifdef RT_USING_SMP
94 /* install IPI handle */
95 rt_hw_ipi_handler_install(RT_SCHEDULE_IPI, rt_scheduler_ipi_handler);
96 arm_gic_umask(0, IRQ_ARM_IPI_KICK);
97 #endif
98 }
99
reboot(void)100 void reboot(void)
101 {
102 psci_system_reboot();
103
104 void *cur_base = rt_ioremap((void *) CRU_BASE, 0x100);
105 HWREG32(cur_base + 0x00D4) = 0xfdb9;
106 HWREG32(cur_base + 0x00D8) = 0xeca8;
107 }
108 MSH_CMD_EXPORT(reboot, reboot...);
109
print_cpu_id(int argc,char * argv[])110 static void print_cpu_id(int argc, char *argv[])
111 {
112 rt_kprintf("rt_hw_cpu_id:%d\n", rt_hw_cpu_id());
113 }
114 MSH_CMD_EXPORT_ALIAS(print_cpu_id, cpuid, print_cpu_id);
115
116 #ifdef RT_USING_AMP
start_cpu(int argc,char * argv[])117 void start_cpu(int argc, char *argv[])
118 {
119 rt_uint32_t status;
120 status = rt_psci_cpu_on(0x3, (rt_uint64_t) 0x7A000000);
121 rt_kprintf("arm_psci_cpu_on 0x%X\n", status);
122 }
123 MSH_CMD_EXPORT(start_cpu, start_cpu);
124
125 #ifdef RT_AMP_SLAVE
rt_hw_cpu_shutdown(void)126 void rt_hw_cpu_shutdown(void)
127 {
128 rt_psci_cpu_off(0);
129 }
130 #endif /* RT_AMP_SLAVE */
131 #endif /* RT_USING_AMP */
132
133 #if defined(RT_USING_SMP) || defined(RT_USING_AMP)
134 rt_uint64_t rt_cpu_mpidr_early[] =
135 {
136 [0] = 0x80000000,
137 [1] = 0x80000100,
138 [2] = 0x80000200,
139 [3] = 0x80000300,
140 [RT_CPUS_NR] = 0
141 };
142 #endif
143
144 #ifdef RT_USING_SMP
rt_hw_secondary_cpu_up(void)145 void rt_hw_secondary_cpu_up(void)
146 {
147 int i;
148 extern void _secondary_cpu_entry(void);
149 rt_uint64_t entry = (rt_uint64_t)rt_kmem_v2p(_secondary_cpu_entry);
150
151 for (i = 1; i < RT_CPUS_NR; ++i)
152 {
153 rt_psci_cpu_on(rt_cpu_mpidr_early[i], entry);
154 }
155 }
156
157 extern unsigned long MMUTable[];
158
secondary_cpu_c_start(void)159 void secondary_cpu_c_start(void)
160 {
161 rt_hw_mmu_ktbl_set((unsigned long)MMUTable);
162 rt_hw_spin_lock(&_cpus_lock);
163
164 arm_gic_cpu_init(0, platform_get_gic_cpu_base());
165 arm_gic_redist_init(0, platform_get_gic_redist_base());
166 rt_hw_vector_init();
167 rt_hw_gtimer_local_enable();
168 arm_gic_umask(0, IRQ_ARM_IPI_KICK);
169
170 rt_kprintf("\rcall cpu %d on success\n", rt_hw_cpu_id());
171
172 rt_system_scheduler_start();
173 }
174
rt_hw_secondary_cpu_idle_exec(void)175 void rt_hw_secondary_cpu_idle_exec(void)
176 {
177 rt_hw_wfe();
178 }
179 #endif
180