1 // SPDX-License-Identifier: GPL-2.0+
3 * (C) Copyright 2021 Mark Kettenis <kettenis@openbsd.org>
8 #include <efi_loader.h>
11 #include <asm/armv8/mmu.h>
12 #include <asm/global_data.h>
14 #include <asm/system.h>
16 DECLARE_GLOBAL_DATA_PTR;
20 static struct mm_region t8103_mem_map[] = {
26 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
28 PTE_BLOCK_PXN | PTE_BLOCK_UXN
34 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
36 PTE_BLOCK_PXN | PTE_BLOCK_UXN
42 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
44 PTE_BLOCK_PXN | PTE_BLOCK_UXN
50 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
52 PTE_BLOCK_PXN | PTE_BLOCK_UXN
58 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) |
59 PTE_BLOCK_INNER_SHARE |
60 PTE_BLOCK_PXN | PTE_BLOCK_UXN
66 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) |
67 PTE_BLOCK_INNER_SHARE |
68 PTE_BLOCK_PXN | PTE_BLOCK_UXN
74 .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
78 .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) |
79 PTE_BLOCK_INNER_SHARE |
80 PTE_BLOCK_PXN | PTE_BLOCK_UXN
87 /* Apple M1 Pro/Max */
89 static struct mm_region t6000_mem_map[] = {
95 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
97 PTE_BLOCK_PXN | PTE_BLOCK_UXN
103 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
104 PTE_BLOCK_NON_SHARE |
105 PTE_BLOCK_PXN | PTE_BLOCK_UXN
111 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
112 PTE_BLOCK_NON_SHARE |
113 PTE_BLOCK_PXN | PTE_BLOCK_UXN
119 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) |
120 PTE_BLOCK_INNER_SHARE |
121 PTE_BLOCK_PXN | PTE_BLOCK_UXN
127 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) |
128 PTE_BLOCK_INNER_SHARE |
129 PTE_BLOCK_PXN | PTE_BLOCK_UXN
135 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
136 PTE_BLOCK_NON_SHARE |
137 PTE_BLOCK_PXN | PTE_BLOCK_UXN
143 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
144 PTE_BLOCK_NON_SHARE |
145 PTE_BLOCK_PXN | PTE_BLOCK_UXN
151 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
152 PTE_BLOCK_NON_SHARE |
153 PTE_BLOCK_PXN | PTE_BLOCK_UXN
156 .virt = 0x1300000000,
157 .phys = 0x1300000000,
159 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
160 PTE_BLOCK_NON_SHARE |
161 PTE_BLOCK_PXN | PTE_BLOCK_UXN
164 .virt = 0x10000000000,
165 .phys = 0x10000000000,
166 .size = 16UL * SZ_1G,
167 .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
168 PTE_BLOCK_INNER_SHARE
171 .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) |
172 PTE_BLOCK_INNER_SHARE |
173 PTE_BLOCK_PXN | PTE_BLOCK_UXN
175 /* List terminator */
182 static struct mm_region t6002_mem_map[] = {
188 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
189 PTE_BLOCK_NON_SHARE |
190 PTE_BLOCK_PXN | PTE_BLOCK_UXN
196 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
197 PTE_BLOCK_NON_SHARE |
198 PTE_BLOCK_PXN | PTE_BLOCK_UXN
204 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
205 PTE_BLOCK_NON_SHARE |
206 PTE_BLOCK_PXN | PTE_BLOCK_UXN
212 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) |
213 PTE_BLOCK_INNER_SHARE |
214 PTE_BLOCK_PXN | PTE_BLOCK_UXN
220 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) |
221 PTE_BLOCK_INNER_SHARE |
222 PTE_BLOCK_PXN | PTE_BLOCK_UXN
228 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
229 PTE_BLOCK_NON_SHARE |
230 PTE_BLOCK_PXN | PTE_BLOCK_UXN
236 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
237 PTE_BLOCK_NON_SHARE |
238 PTE_BLOCK_PXN | PTE_BLOCK_UXN
244 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
245 PTE_BLOCK_NON_SHARE |
246 PTE_BLOCK_PXN | PTE_BLOCK_UXN
249 .virt = 0x1300000000,
250 .phys = 0x1300000000,
252 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
253 PTE_BLOCK_NON_SHARE |
254 PTE_BLOCK_PXN | PTE_BLOCK_UXN
257 .virt = 0x2280000000,
258 .phys = 0x2280000000,
260 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
261 PTE_BLOCK_NON_SHARE |
262 PTE_BLOCK_PXN | PTE_BLOCK_UXN
265 .virt = 0x2380000000,
266 .phys = 0x2380000000,
268 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
269 PTE_BLOCK_NON_SHARE |
270 PTE_BLOCK_PXN | PTE_BLOCK_UXN
273 .virt = 0x2580000000,
274 .phys = 0x2580000000,
276 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
277 PTE_BLOCK_NON_SHARE |
278 PTE_BLOCK_PXN | PTE_BLOCK_UXN
281 .virt = 0x25a0000000,
282 .phys = 0x25a0000000,
284 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) |
285 PTE_BLOCK_INNER_SHARE |
286 PTE_BLOCK_PXN | PTE_BLOCK_UXN
289 .virt = 0x25c0000000,
290 .phys = 0x25c0000000,
292 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) |
293 PTE_BLOCK_INNER_SHARE |
294 PTE_BLOCK_PXN | PTE_BLOCK_UXN
297 .virt = 0x2700000000,
298 .phys = 0x2700000000,
300 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
301 PTE_BLOCK_NON_SHARE |
302 PTE_BLOCK_PXN | PTE_BLOCK_UXN
305 .virt = 0x2b00000000,
306 .phys = 0x2b00000000,
308 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
309 PTE_BLOCK_NON_SHARE |
310 PTE_BLOCK_PXN | PTE_BLOCK_UXN
313 .virt = 0x2f00000000,
314 .phys = 0x2f00000000,
316 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
317 PTE_BLOCK_NON_SHARE |
318 PTE_BLOCK_PXN | PTE_BLOCK_UXN
321 .virt = 0x3300000000,
322 .phys = 0x3300000000,
324 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
325 PTE_BLOCK_NON_SHARE |
326 PTE_BLOCK_PXN | PTE_BLOCK_UXN
329 .virt = 0x10000000000,
330 .phys = 0x10000000000,
331 .size = 16UL * SZ_1G,
332 .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
333 PTE_BLOCK_INNER_SHARE
336 .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) |
337 PTE_BLOCK_INNER_SHARE |
338 PTE_BLOCK_PXN | PTE_BLOCK_UXN
340 /* List terminator */
345 struct mm_region *mem_map;
354 return fdtdec_setup_mem_size_base();
357 int dram_init_banksize(void)
359 return fdtdec_setup_memory_banksize();
362 extern long fw_dtb_pointer;
364 void *board_fdt_blob_setup(int *err)
366 /* Return DTB pointer passed by m1n1 */
368 return (void *)fw_dtb_pointer;
371 void build_mem_map(void)
378 if (of_machine_is_compatible("apple,t8103"))
379 mem_map = t8103_mem_map;
380 else if (of_machine_is_compatible("apple,t6000"))
381 mem_map = t6000_mem_map;
382 else if (of_machine_is_compatible("apple,t6001"))
383 mem_map = t6000_mem_map;
384 else if (of_machine_is_compatible("apple,t6002"))
385 mem_map = t6002_mem_map;
387 panic("Unsupported SoC\n");
389 /* Find list terminator. */
390 for (i = 0; mem_map[i].size || mem_map[i].attrs; i++)
393 /* Align RAM mapping to page boundaries */
394 base = gd->bd->bi_dram[0].start;
395 size = gd->bd->bi_dram[0].size;
396 size += (base - ALIGN_DOWN(base, SZ_4K));
397 base = ALIGN_DOWN(base, SZ_4K);
398 size = ALIGN(size, SZ_4K);
400 /* Update RAM mapping */
401 mem_map[i - 2].virt = base;
402 mem_map[i - 2].phys = base;
403 mem_map[i - 2].size = size;
405 node = ofnode_path("/chosen/framebuffer");
406 if (!ofnode_valid(node))
409 base = ofnode_get_addr_size(node, "reg", &size);
410 if (base == FDT_ADDR_T_NONE)
413 /* Align framebuffer mapping to page boundaries */
414 size += (base - ALIGN_DOWN(base, SZ_4K));
415 base = ALIGN_DOWN(base, SZ_4K);
416 size = ALIGN(size, SZ_4K);
418 /* Add framebuffer mapping */
419 mem_map[i - 1].virt = base;
420 mem_map[i - 1].phys = base;
421 mem_map[i - 1].size = size;
424 void enable_caches(void)
432 u64 get_page_table_size(void)
437 #define KERNEL_COMP_SIZE SZ_128M
439 int board_late_init(void)
444 lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob);
446 /* somewhat based on the Linux Kernel boot requirements:
447 * align by 2M and maximal FDT size 2M
449 status |= env_set_hex("loadaddr", lmb_alloc(&lmb, SZ_1G, SZ_2M));
450 status |= env_set_hex("fdt_addr_r", lmb_alloc(&lmb, SZ_2M, SZ_2M));
451 status |= env_set_hex("kernel_addr_r", lmb_alloc(&lmb, SZ_128M, SZ_2M));
452 status |= env_set_hex("ramdisk_addr_r", lmb_alloc(&lmb, SZ_1G, SZ_2M));
453 status |= env_set_hex("kernel_comp_addr_r",
454 lmb_alloc(&lmb, KERNEL_COMP_SIZE, SZ_2M));
455 status |= env_set_hex("kernel_comp_size", KERNEL_COMP_SIZE);
456 status |= env_set_hex("scriptaddr", lmb_alloc(&lmb, SZ_4M, SZ_2M));
457 status |= env_set_hex("pxefile_addr_r", lmb_alloc(&lmb, SZ_4M, SZ_2M));
460 log_warning("late_init: Failed to set run time variables\n");