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