1 /*
2  * Copyright (c) 2006-2020, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author         Notes
8  * 2020-04-16     bigmagic       first version
9  * 2021-12-28     GuEe-GUI       add smp support
10  * 2023-03-28     WangXiaoyao    sync works & memory layout fixups
11  *                               code formats
12  */
13 #define DBG_TAG "board"
14 #define DBG_LVL DBG_INFO
15 #include <rtdbg.h>
16 
17 #include <rthw.h>
18 #include <rtthread.h>
19 #include <mm_aspace.h>
20 
21 #include "board.h"
22 #include "drv_uart.h"
23 
24 #include "cp15.h"
25 #include "mmu.h"
26 #include "mbox.h"
27 #include <mm_page.h>
28 
29 #ifdef RT_USING_SMART
30 #include <lwp_arch.h>
31 #endif
32 
33 extern size_t MMUTable[];
34 
35 size_t gpio_base_addr = GPIO_BASE_ADDR;
36 
37 size_t uart_base_addr = UART_BASE;
38 
39 size_t gic_base_addr = GIC_V2_BASE;
40 
41 size_t arm_timer_base = ARM_TIMER_BASE;
42 
43 size_t pactl_cs_base = PACTL_CS_ADDR;
44 
45 size_t stimer_base_addr = STIMER_BASE;
46 
47 size_t mmc2_base_addr   = MMC2_BASE_ADDR;
48 
49 size_t videocore_mbox = VIDEOCORE_MBOX;
50 
51 size_t mbox_addr = MBOX_ADDR;
52 
53 size_t wdt_base_addr = WDT_BASE;
54 
55 uint8_t *mac_reg_base_addr = (uint8_t *)MAC_REG;
56 
57 uint8_t *eth_send_no_cache = (uint8_t *)SEND_DATA_NO_CACHE;
58 uint8_t *eth_recv_no_cache = (uint8_t *)RECV_DATA_NO_CACHE;
59 
60 #ifdef RT_USING_SMART
61 struct mem_desc platform_mem_desc[] = {
62     {KERNEL_VADDR_START, KERNEL_VADDR_START + 0x0fffffff, (rt_size_t)ARCH_MAP_FAILED, NORMAL_MEM}
63 };
64 #else
65 struct mem_desc platform_mem_desc[] = {
66     {0x00200000, (256ul << 20) - 1, 0x00200000, NORMAL_MEM},
67     {0xFC000000, 0x000100000000 - 1, 0xFC000000, DEVICE_MEM},
68 };
69 #endif
70 
71 const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc)/sizeof(platform_mem_desc[0]);
72 
idle_wfi(void)73 void idle_wfi(void)
74 {
75     asm volatile ("wfi");
76 }
77 
78 /**
79  * This function will initialize board
80  */
81 
82 extern size_t MMUTable[];
83 int rt_hw_gtimer_init(void);
84 
85 rt_region_t init_page_region = {
86     PAGE_START,
87     PAGE_END,
88 };
89 
90 /**
91  *  Initialize the Hardware related stuffs. Called from rtthread_startup()
92  *  after interrupt disabled.
93  */
rt_hw_board_init(void)94 void rt_hw_board_init(void)
95 {
96     rt_hw_earlycon_ioremap_early();
97 
98     /* io device remap */
99 #ifdef RT_USING_SMART
100     rt_hw_mmu_map_init(&rt_kernel_space, (void*)0xfffffffff0000000, 0x10000000, MMUTable, PV_OFFSET);
101 #else
102     rt_hw_mmu_map_init(&rt_kernel_space, (void*)0x080000000000, 0x10000000, MMUTable, 0);
103 #endif /* RT_USING_SMART */
104     rt_page_init(init_page_region);
105     rt_hw_mmu_setup(&rt_kernel_space, platform_mem_desc, platform_mem_desc_size);
106 
107     /* map peripheral address to virtual address */
108 #ifdef RT_USING_HEAP
109     /* initialize system heap */
110     rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
111 #endif
112 
113     /* initialize hardware interrupt */
114     rt_hw_interrupt_init();
115 
116     //gpio
117     gpio_base_addr = (size_t)rt_ioremap((void*)GPIO_BASE_ADDR, 0x1000);
118 
119     //pactl
120     pactl_cs_base = (size_t)rt_ioremap((void*)PACTL_CS_ADDR, 0x1000);
121 
122     //stimer
123     stimer_base_addr = (size_t)rt_ioremap((void*)STIMER_BASE, 0x1000);
124 
125     //mmc2_base_addr
126     mmc2_base_addr = (size_t)rt_ioremap((void*)MMC2_BASE_ADDR, 0x1000);
127 
128     //mbox
129     videocore_mbox = (size_t)rt_ioremap((void*)VIDEOCORE_MBOX, 0x1000);
130 
131     // mbox msg
132     mbox = (volatile unsigned int *)rt_pages_alloc(0);
133 
134     //wdt
135     wdt_base_addr = (size_t)rt_ioremap((void*)WDT_BASE, 0x1000);
136 
137     //mac
138     mac_reg_base_addr = (void *)rt_ioremap((void*)MAC_REG, 0x80000);
139 
140     // eth data
141     eth_send_no_cache = (void *)rt_pages_alloc(rt_page_bits(0x200000));
142     eth_recv_no_cache = (void *)rt_pages_alloc(rt_page_bits(0x200000));
143 
144     /* initialize uart */
145     rt_hw_uart_init();
146 
147     /* initialize timer for os tick */
148     rt_hw_gtimer_init();
149 
150 #ifdef RT_USING_CONSOLE
151     /* set console device */
152     rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
153 #endif /* RT_USING_CONSOLE */
154 
155 #ifdef RT_USING_COMPONENTS_INIT
156     rt_components_board_init();
157 #endif
158     rt_thread_idle_sethook(idle_wfi);
159 }
160 
161 #ifdef RT_USING_SMP
162 #include <gic.h>
163 
164 void rt_hw_mmu_ktbl_set(unsigned long tbl);
165 void _secondary_cpu_entry(void);
166 
167 static unsigned long cpu_release_paddr[] =
168 {
169     [0] = 0xd8,
170     [1] = 0xe0,
171     [2] = 0xe8,
172     [3] = 0xf0,
173     [4] = 0x00
174 };
175 
rt_hw_secondary_cpu_up(void)176 void rt_hw_secondary_cpu_up(void)
177 {
178     int i;
179     void *release_addr;
180 
181     for (i = 1; i < RT_CPUS_NR && cpu_release_paddr[i]; ++i)
182     {
183         release_addr = rt_ioremap((void *)cpu_release_paddr[i], sizeof(cpu_release_paddr[0]));
184         __asm__ volatile ("str %0, [%1]"::"rZ"((unsigned long)_secondary_cpu_entry + PV_OFFSET), "r"(release_addr));
185         rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, release_addr, sizeof(release_addr));
186         asm volatile ("dsb sy");
187         asm volatile ("sev");
188     }
189 }
190 
rt_hw_secondary_cpu_bsp_start(void)191 void rt_hw_secondary_cpu_bsp_start(void)
192 {
193     rt_hw_spin_lock(&_cpus_lock);
194 
195     rt_hw_mmu_ktbl_set((unsigned long)MMUTable);
196 
197     rt_hw_vector_init();
198 
199     arm_gic_cpu_init(0, 0);
200 
201     rt_hw_gtimer_init();
202 
203     rt_kprintf("\rcpu %d boot success\n", rt_hw_cpu_id());
204 
205     rt_system_scheduler_start();
206 }
207 
rt_hw_secondary_cpu_idle_exec(void)208 void rt_hw_secondary_cpu_idle_exec(void)
209 {
210     asm volatile ("wfe":::"memory", "cc");
211 }
212 
213 #endif
214