[PATCH] arm: apple: Add M1 Pro/Max support

Mark Kettenis kettenis at openbsd.org
Tue Feb 8 22:00:09 CET 2022


Choose the memory map based on the compatible property from the
device tree passed to us by m1n1. Since DRAM on the M1 Pro/Max
starts at a different address avoid hardcoding the top of usable
memory. Also make sure that the addresses entered into the memory
map are page aligned such that we don't crash in dcache_enable().

Signed-off-by: Mark Kettenis <kettenis at openbsd.org>
Tested on: Macbook M1 Max
Tested-by: Janne Grunau <j at jannau.net>
---
 arch/arm/mach-apple/board.c | 207 +++++++++++++++++++++++++++++-------
 1 file changed, 168 insertions(+), 39 deletions(-)

diff --git a/arch/arm/mach-apple/board.c b/arch/arm/mach-apple/board.c
index b7e8d212f1..f9f8a2f278 100644
--- a/arch/arm/mach-apple/board.c
+++ b/arch/arm/mach-apple/board.c
@@ -14,12 +14,22 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-static struct mm_region apple_mem_map[] = {
+/* Apple M1 */
+
+static struct mm_region t8103_mem_map[] = {
 	{
 		/* I/O */
 		.virt = 0x200000000,
 		.phys = 0x200000000,
-		.size = 8UL * SZ_1G,
+		.size = 2UL * SZ_1G,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	}, {
+		/* I/O */
+		.virt = 0x380000000,
+		.phys = 0x380000000,
+		.size = SZ_1G,
 		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 			 PTE_BLOCK_NON_SHARE |
 			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
@@ -27,7 +37,7 @@ static struct mm_region apple_mem_map[] = {
 		/* I/O */
 		.virt = 0x500000000,
 		.phys = 0x500000000,
-		.size = 2UL * SZ_1G,
+		.size = SZ_1G,
 		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 			 PTE_BLOCK_NON_SHARE |
 			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
@@ -63,15 +73,110 @@ static struct mm_region apple_mem_map[] = {
 		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
 			 PTE_BLOCK_INNER_SHARE
 	}, {
-		/* Empty entry for framebuffer */
+		/* Framebuffer */
+		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) |
+			 PTE_BLOCK_INNER_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	}, {
+		/* List terminator */
 		0,
+	}
+};
+
+/* Apple M1 Pro/Max */
+
+static struct mm_region t6000_mem_map[] = {
+	{
+		/* I/O */
+		.virt = 0x280000000,
+		.phys = 0x280000000,
+		.size = SZ_1G,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	}, {
+		/* I/O */
+		.virt = 0x380000000,
+		.phys = 0x380000000,
+		.size = SZ_1G,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	}, {
+		/* I/O */
+		.virt = 0x580000000,
+		.phys = 0x580000000,
+		.size = SZ_512M,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	}, {
+		/* PCIE */
+		.virt = 0x5a0000000,
+		.phys = 0x5a0000000,
+		.size = SZ_512M,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) |
+			 PTE_BLOCK_INNER_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	}, {
+		/* PCIE */
+		.virt = 0x5c0000000,
+		.phys = 0x5c0000000,
+		.size = SZ_1G,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) |
+			 PTE_BLOCK_INNER_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	}, {
+		/* I/O */
+		.virt = 0x700000000,
+		.phys = 0x700000000,
+		.size = SZ_1G,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	}, {
+		/* I/O */
+		.virt = 0xb00000000,
+		.phys = 0xb00000000,
+		.size = SZ_1G,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	}, {
+		/* I/O */
+		.virt = 0xf00000000,
+		.phys = 0xf00000000,
+		.size = SZ_1G,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	}, {
+		/* I/O */
+		.virt = 0x1300000000,
+		.phys = 0x1300000000,
+		.size = SZ_1G,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	}, {
+		/* RAM */
+		.virt = 0x10000000000,
+		.phys = 0x10000000000,
+		.size = 16UL * SZ_1G,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+			 PTE_BLOCK_INNER_SHARE
+	}, {
+		/* Framebuffer */
+		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) |
+			 PTE_BLOCK_INNER_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
 	}, {
 		/* List terminator */
 		0,
 	}
 };
 
-struct mm_region *mem_map = apple_mem_map;
+struct mm_region *mem_map;
 
 int board_init(void)
 {
@@ -79,60 +184,84 @@ int board_init(void)
 }
 
 int dram_init(void)
+{
+	return fdtdec_setup_mem_size_base();
+}
+
+int dram_init_banksize(void)
+{
+	return fdtdec_setup_memory_banksize();
+}
+
+extern long fw_dtb_pointer;
+
+void *board_fdt_blob_setup(int *err)
+{
+	/* Return DTB pointer passed by m1n1 */
+	*err = 0;
+	return (void *)fw_dtb_pointer;
+}
+
+void build_mem_map(void)
 {
 	ofnode node;
-	int index, ret;
 	fdt_addr_t base;
 	fdt_size_t size;
+	int i;
+
+	if (of_machine_is_compatible("apple,t8103"))
+		mem_map = t8103_mem_map;
+	else if (of_machine_is_compatible("apple,t6000"))
+		mem_map = t6000_mem_map;
+	else if (of_machine_is_compatible("apple,t6001"))
+		mem_map = t6000_mem_map;
+	else
+		panic("Unsupported SoC\n");
 
-	ret = fdtdec_setup_mem_size_base();
-	if (ret)
-		return ret;
+	/* Find list terminator. */
+	for (i = 0; mem_map[i].size || mem_map[i].attrs; i++)
+		;
+
+	/* Align RAM mapping to page boundaries */
+	base = gd->bd->bi_dram[0].start;
+	size = gd->bd->bi_dram[0].size;
+	size += (base - ALIGN_DOWN(base, SZ_4K));
+	base = ALIGN_DOWN(base, SZ_4K);
+	size = ALIGN(size, SZ_4K);
 
 	/* Update RAM mapping */
-	index = ARRAY_SIZE(apple_mem_map) - 3;
-	apple_mem_map[index].virt = gd->ram_base;
-	apple_mem_map[index].phys = gd->ram_base;
-	apple_mem_map[index].size = gd->ram_size;
+	mem_map[i - 2].virt = base;
+	mem_map[i - 2].phys = base;
+	mem_map[i - 2].size = size;
 
 	node = ofnode_path("/chosen/framebuffer");
 	if (!ofnode_valid(node))
-		return 0;
+		return;
 
 	base = ofnode_get_addr_size(node, "reg", &size);
 	if (base == FDT_ADDR_T_NONE)
-		return 0;
+		return;
 
-	/* Add framebuffer mapping */
-	index = ARRAY_SIZE(apple_mem_map) - 2;
-	apple_mem_map[index].virt = base;
-	apple_mem_map[index].phys = base;
-	apple_mem_map[index].size = size;
-	apple_mem_map[index].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) |
-		PTE_BLOCK_INNER_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN;
+	/* Align framebuffer mapping to page boundaries */
+	size += (base - ALIGN_DOWN(base, SZ_4K));
+	base = ALIGN_DOWN(base, SZ_4K);
+	size = ALIGN(size, SZ_4K);
 
-	return 0;
+	/* Add framebuffer mapping */
+	mem_map[i - 1].virt = base;
+	mem_map[i - 1].phys = base;
+	mem_map[i - 1].size = size;
 }
 
-int dram_init_banksize(void)
+void enable_caches(void)
 {
-	return fdtdec_setup_memory_banksize();
-}
+	build_mem_map();
 
-extern long fw_dtb_pointer;
-
-void *board_fdt_blob_setup(int *err)
-{
-	/* Return DTB pointer passed by m1n1 */
-	*err = 0;
-	return (void *)fw_dtb_pointer;
+	icache_enable();
+	dcache_enable();
 }
 
-ulong board_get_usable_ram_top(ulong total_size)
+u64 get_page_table_size(void)
 {
-	/*
-	 * Top part of RAM is used by firmware for things like the
-	 * framebuffer.  This gives us plenty of room to play with.
-	 */
-	return 0x980000000;
+	return SZ_256K;
 }
-- 
2.34.1



More information about the U-Boot mailing list