[PATCH v4 3/7] arm: apple: Add initial support for Apple's M1 SoC
Mark Kettenis
kettenis at openbsd.org
Sat Oct 23 16:58:03 CEST 2021
Add support for Apple's M1 SoC that is used in "Apple Silicon"
Macs. This builds a basic U-Boot that can be used as a payload
for the m1n1 boot loader being developed by the Asahi Linux
project.
Signed-off-by: Mark Kettenis <kettenis at openbsd.org>
Reviewed-by: Simon Glass <sjg at chromium.org>
---
arch/arm/Kconfig | 21 ++++
arch/arm/Makefile | 1 +
arch/arm/mach-apple/Kconfig | 18 ++++
arch/arm/mach-apple/Makefile | 4 +
arch/arm/mach-apple/board.c | 161 ++++++++++++++++++++++++++++
arch/arm/mach-apple/lowlevel_init.S | 17 +++
configs/apple_m1_defconfig | 15 +++
include/configs/apple.h | 36 +++++++
8 files changed, 273 insertions(+)
create mode 100644 arch/arm/mach-apple/Kconfig
create mode 100644 arch/arm/mach-apple/Makefile
create mode 100644 arch/arm/mach-apple/board.c
create mode 100644 arch/arm/mach-apple/lowlevel_init.S
create mode 100644 configs/apple_m1_defconfig
create mode 100644 include/configs/apple.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 504abca0b7..37de90fa05 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -922,6 +922,25 @@ config ARCH_NEXELL
select DM
select GPIO_EXTRA_HEADER
+config ARCH_APPLE
+ bool "Apple SoCs"
+ select ARM64
+ select BLK
+ select CMD_USB
+ select DM
+ select DM_KEYBOARD
+ select DM_SERIAL
+ select DM_USB
+ select DM_VIDEO
+ select LINUX_KERNEL_IMAGE_HEADER
+ select OF_CONTROL
+ select OF_BOARD
+ select POSITION_INDEPENDENT
+ select USB
+ imply CMD_DM
+ imply CMD_GPT
+ imply DISTRO_DEFAULTS
+
config ARCH_OWL
bool "Actions Semi OWL SoCs"
select DM
@@ -2016,6 +2035,8 @@ config ISW_ENTRY_ADDR
image headers.
endif
+source "arch/arm/mach-apple/Kconfig"
+
source "arch/arm/mach-aspeed/Kconfig"
source "arch/arm/mach-at91/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 6c9a00c5a4..ad757e982e 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -55,6 +55,7 @@ PLATFORM_CPPFLAGS += $(arch-y) $(tune-y)
# Machine directory name. This list is sorted alphanumerically
# by CONFIG_* macro name.
+machine-$(CONFIG_ARCH_APPLE) += apple
machine-$(CONFIG_ARCH_ASPEED) += aspeed
machine-$(CONFIG_ARCH_AT91) += at91
machine-$(CONFIG_ARCH_BCM283X) += bcm283x
diff --git a/arch/arm/mach-apple/Kconfig b/arch/arm/mach-apple/Kconfig
new file mode 100644
index 0000000000..66cab91b2a
--- /dev/null
+++ b/arch/arm/mach-apple/Kconfig
@@ -0,0 +1,18 @@
+if ARCH_APPLE
+
+config SYS_TEXT_BASE
+ default 0x00000000
+
+config SYS_CONFIG_NAME
+ default "apple"
+
+config SYS_SOC
+ default "m1"
+
+config SYS_MALLOC_LEN
+ default 0x4000000
+
+config SYS_MALLOC_F_LEN
+ default 0x4000
+
+endif
diff --git a/arch/arm/mach-apple/Makefile b/arch/arm/mach-apple/Makefile
new file mode 100644
index 0000000000..e74a8c9df1
--- /dev/null
+++ b/arch/arm/mach-apple/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-y += board.o
+obj-y += lowlevel_init.o
diff --git a/arch/arm/mach-apple/board.c b/arch/arm/mach-apple/board.c
new file mode 100644
index 0000000000..188d31a1bd
--- /dev/null
+++ b/arch/arm/mach-apple/board.c
@@ -0,0 +1,161 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2021 Mark Kettenis <kettenis at openbsd.org>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <efi_loader.h>
+
+#include <asm/armv8/mmu.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/system.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static struct mm_region apple_mem_map[] = {
+ {
+ /* I/O */
+ .virt = 0x200000000,
+ .phys = 0x200000000,
+ .size = 8UL * SZ_1G,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ }, {
+ /* I/O */
+ .virt = 0x500000000,
+ .phys = 0x500000000,
+ .size = 2UL * SZ_1G,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ }, {
+ /* I/O */
+ .virt = 0x680000000,
+ .phys = 0x680000000,
+ .size = SZ_512M,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ }, {
+ /* PCIE */
+ .virt = 0x6a0000000,
+ .phys = 0x6a0000000,
+ .size = SZ_512M,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) |
+ PTE_BLOCK_INNER_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ }, {
+ /* PCIE */
+ .virt = 0x6c0000000,
+ .phys = 0x6c0000000,
+ .size = SZ_1G,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) |
+ PTE_BLOCK_INNER_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ }, {
+ /* RAM */
+ .virt = 0x800000000,
+ .phys = 0x800000000,
+ .size = 8UL * SZ_1G,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_INNER_SHARE
+ }, {
+ /* Empty entry for framebuffer */
+ 0,
+ }, {
+ /* List terminator */
+ 0,
+ }
+};
+
+struct mm_region *mem_map = apple_mem_map;
+
+int board_init(void)
+{
+ return 0;
+}
+
+int dram_init(void)
+{
+ ofnode node;
+ int index, ret;
+ fdt_addr_t base;
+ fdt_size_t size;
+
+ ret = fdtdec_setup_mem_size_base();
+ if (ret)
+ return ret;
+
+ /* 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;
+
+ node = ofnode_path("/chosen/framebuffer");
+ if (!ofnode_valid(node))
+ return 0;
+
+ base = ofnode_get_addr_size(node, "reg", &size);
+ if (base == FDT_ADDR_T_NONE)
+ return 0;
+
+ /* 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;
+
+ return 0;
+}
+
+int dram_init_banksize(void)
+{
+ return fdtdec_setup_memory_banksize();
+}
+
+#define APPLE_WDT_BASE 0x23d2b0000ULL
+
+#define APPLE_WDT_SYS_CTL_ENABLE BIT(2)
+
+typedef struct apple_wdt {
+ u32 reserved0[3];
+ u32 chip_ctl;
+ u32 sys_tmr;
+ u32 sys_cmp;
+ u32 reserved1;
+ u32 sys_ctl;
+} apple_wdt_t;
+
+void reset_cpu(void)
+{
+ apple_wdt_t *wdt = (apple_wdt_t *)APPLE_WDT_BASE;
+
+ writel(0, &wdt->sys_cmp);
+ writel(APPLE_WDT_SYS_CTL_ENABLE, &wdt->sys_ctl);
+
+ while(1)
+ wfi();
+}
+
+extern long fw_dtb_pointer;
+
+void *board_fdt_blob_setup(void)
+{
+ /* Return DTB pointer passed by m1n1 */
+ return (void *)fw_dtb_pointer;
+}
+
+ulong board_get_usable_ram_top(ulong total_size)
+{
+ /*
+ * Top part of RAM is used by firmware for things like the
+ * framebuffer. This gives us plenty of room to play with.
+ */
+ return 0x980000000;
+}
diff --git a/arch/arm/mach-apple/lowlevel_init.S b/arch/arm/mach-apple/lowlevel_init.S
new file mode 100644
index 0000000000..e1c0d91cef
--- /dev/null
+++ b/arch/arm/mach-apple/lowlevel_init.S
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2021 Mark Kettenis <kettenis at openbsd.org>
+ */
+
+.align 8
+.global fw_dtb_pointer
+fw_dtb_pointer:
+ .quad 0
+
+.global save_boot_params
+save_boot_params:
+ /* Stash DTB pointer passed by m1n1 */
+ adr x1, fw_dtb_pointer
+ str x0, [x1]
+
+ b save_boot_params_ret
diff --git a/configs/apple_m1_defconfig b/configs/apple_m1_defconfig
new file mode 100644
index 0000000000..6072e7524c
--- /dev/null
+++ b/configs/apple_m1_defconfig
@@ -0,0 +1,15 @@
+CONFIG_ARM=y
+CONFIG_ARCH_APPLE=y
+# CONFIG_DISPLAY_CPUINFO is not set
+# CONFIG_MMC is not set
+# CONFIG_NET is not set
+CONFIG_VIDEO_SIMPLE=y
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_DWC3=y
+CONFIG_USB_KEYBOARD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USE_PREBOOT=y
+CONFIG_PREBOOT="usb start"
+CONFIG_SYS_LOAD_ADDR=0x880000000
+# CONFIG_GENERATE_SMBIOS_TABLE is not set
diff --git a/include/configs/apple.h b/include/configs/apple.h
new file mode 100644
index 0000000000..b1f6043174
--- /dev/null
+++ b/include/configs/apple.h
@@ -0,0 +1,36 @@
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <linux/sizes.h>
+
+#define CONFIG_SYS_SDRAM_BASE 0x880000000
+
+#define CONFIG_LNX_KRNL_IMG_TEXT_OFFSET_BASE CONFIG_SYS_TEXT_BASE
+
+/* Environment */
+#define ENV_DEVICE_SETTINGS \
+ "stdin=serial,usbkbd\0" \
+ "stdout=serial,vidconsole\0" \
+ "stderr=serial,vidconsole\0"
+
+#define ENV_MEM_LAYOUT_SETTINGS \
+ "fdt_addr_r=0x960100000\0" \
+ "kernel_addr_r=0x960200000\0"
+
+#if CONFIG_IS_ENABLED(CMD_USB)
+ #define BOOT_TARGET_USB(func) func(USB, usb, 0)
+#else
+ #define BOOT_TARGET_USB(func)
+#endif
+
+#define BOOT_TARGET_DEVICES(func) \
+ BOOT_TARGET_USB(func)
+
+#include <config_distro_bootcmd.h>
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ ENV_DEVICE_SETTINGS \
+ ENV_MEM_LAYOUT_SETTINGS \
+ BOOTENV
+
+#endif
--
2.33.0
More information about the U-Boot
mailing list