diff mbox series

[1/5] arm: apple: Add initial support for Apple's M1 SoC

Message ID 20210918135437.36667-2-kettenis@openbsd.org
State Superseded
Delegated to: Tom Rini
Headers show
Series Apple M1 Support | expand

Commit Message

Mark Kettenis Sept. 18, 2021, 1:54 p.m. UTC
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@openbsd.org>
---
 arch/arm/Kconfig                    |  22 ++++
 arch/arm/Makefile                   |   1 +
 arch/arm/mach-apple/Kconfig         |  18 ++++
 arch/arm/mach-apple/Makefile        |   4 +
 arch/arm/mach-apple/board.c         | 158 ++++++++++++++++++++++++++++
 arch/arm/mach-apple/lowlevel_init.S |  16 +++
 configs/apple_m1_defconfig          |  14 +++
 include/configs/apple.h             |  38 +++++++
 8 files changed, 271 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

Comments

Bin Meng Sept. 19, 2021, 1:04 a.m. UTC | #1
Hi Mark,

On Sat, Sep 18, 2021 at 9:55 PM Mark Kettenis <kettenis@openbsd.org> wrote:
>
> 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@openbsd.org>
> ---
>  arch/arm/Kconfig                    |  22 ++++
>  arch/arm/Makefile                   |   1 +
>  arch/arm/mach-apple/Kconfig         |  18 ++++
>  arch/arm/mach-apple/Makefile        |   4 +
>  arch/arm/mach-apple/board.c         | 158 ++++++++++++++++++++++++++++
>  arch/arm/mach-apple/lowlevel_init.S |  16 +++
>  configs/apple_m1_defconfig          |  14 +++
>  include/configs/apple.h             |  38 +++++++
>  8 files changed, 271 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 b5bd3284cd..7cdea1f615 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -895,6 +895,26 @@ config ARCH_NEXELL
>         select DM
>         select GPIO_EXTRA_HEADER
>
> +config ARCH_APPLE
> +       bool "Apple SoCs"
> +       select ARM64
> +       select LINUX_KERNEL_IMAGE_HEADER
> +       select POSITION_INDEPENDENT
> +       select BLK
> +       select DM
> +       select DM_KEYBOARD
> +       select DM_SERIAL
> +       select DM_USB
> +       select DM_VIDEO
> +       select CMD_USB
> +       select MISC
> +       select OF_CONTROL
> +       select OF_BOARD
> +       select USB
> +       imply CMD_DM
> +       imply CMD_GPT
> +       imply DISTRO_DEFAULTS
> +
>  config ARCH_OWL
>         bool "Actions Semi OWL SoCs"
>         select DM
> @@ -1932,6 +1952,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 c68e598a67..44178c204b 100644
> --- a/arch/arm/Makefile
> +++ b/arch/arm/Makefile
> @@ -51,6 +51,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..0c8b35292e
> --- /dev/null
> +++ b/arch/arm/mach-apple/board.c
> @@ -0,0 +1,158 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * (C) Copyright 2021 Mark Kettenis <kettenis@openbsd.org>
> + */
> +
> +#include <common.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)
> +{
> +       int index, node, ret;
> +       fdt_addr_t base;
> +       fdt_size_t size;
> +
> +       ret = fdtdec_setup_mem_size_base();
> +       if (ret)
> +               return ret;
> +
> +       /* Update RAM mapping. */

nits: please remove the ending .

> +       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 = fdt_path_offset(gd->fdt_blob, "/chosen/framebuffer");
> +       if (node < 0)
> +               return 0;
> +
> +       base = fdtdec_get_addr_size(gd->fdt_blob, node, "reg", &size);
> +       if (base == FDT_ADDR_T_NONE)
> +               return 0;
> +
> +       /* Add framebuffer mapping. */

ditto

> +       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)

This looks like we should add a new sysreset driver for Apple Arm SoC.

> +{
> +       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 (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..0f5313163e
> --- /dev/null
> +++ b/arch/arm/mach-apple/lowlevel_init.S
> @@ -0,0 +1,16 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * (C) Copyright 2021 Mark Kettenis <kettenis@openbsd.org>
> + */
> +
> +.align 8
> +.global fw_dtb_pointer
> +fw_dtb_pointer:
> +       .quad   0

Is this filled in by m1n1?

> +
> +.global save_boot_params
> +save_boot_params:
> +       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..a7ae15576b
> --- /dev/null
> +++ b/configs/apple_m1_defconfig
> @@ -0,0 +1,14 @@
> +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_GENERATE_SMBIOS_TABLE is not set
> diff --git a/include/configs/apple.h b/include/configs/apple.h
> new file mode 100644
> index 0000000000..1c246af002
> --- /dev/null
> +++ b/include/configs/apple.h
> @@ -0,0 +1,38 @@
> +#ifndef __CONFIG_H
> +#define __CONFIG_H
> +
> +#include <linux/sizes.h>
> +
> +#define CONFIG_SYS_LOAD_ADDR   0x880000000
> +
> +#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

Regards,
Bin
Bin Meng Sept. 19, 2021, 1:17 a.m. UTC | #2
Hi Mark,

On Sun, Sep 19, 2021 at 9:04 AM Bin Meng <bmeng.cn@gmail.com> wrote:
>
> Hi Mark,
>
> On Sat, Sep 18, 2021 at 9:55 PM Mark Kettenis <kettenis@openbsd.org> wrote:
> >
> > 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@openbsd.org>
> > ---
> >  arch/arm/Kconfig                    |  22 ++++
> >  arch/arm/Makefile                   |   1 +
> >  arch/arm/mach-apple/Kconfig         |  18 ++++
> >  arch/arm/mach-apple/Makefile        |   4 +
> >  arch/arm/mach-apple/board.c         | 158 ++++++++++++++++++++++++++++
> >  arch/arm/mach-apple/lowlevel_init.S |  16 +++
> >  configs/apple_m1_defconfig          |  14 +++
> >  include/configs/apple.h             |  38 +++++++
> >  8 files changed, 271 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 b5bd3284cd..7cdea1f615 100644
> > --- a/arch/arm/Kconfig
> > +++ b/arch/arm/Kconfig
> > @@ -895,6 +895,26 @@ config ARCH_NEXELL
> >         select DM
> >         select GPIO_EXTRA_HEADER
> >
> > +config ARCH_APPLE
> > +       bool "Apple SoCs"
> > +       select ARM64
> > +       select LINUX_KERNEL_IMAGE_HEADER
> > +       select POSITION_INDEPENDENT
> > +       select BLK
> > +       select DM
> > +       select DM_KEYBOARD
> > +       select DM_SERIAL
> > +       select DM_USB
> > +       select DM_VIDEO
> > +       select CMD_USB
> > +       select MISC
> > +       select OF_CONTROL
> > +       select OF_BOARD
> > +       select USB
> > +       imply CMD_DM
> > +       imply CMD_GPT
> > +       imply DISTRO_DEFAULTS
> > +
> >  config ARCH_OWL
> >         bool "Actions Semi OWL SoCs"
> >         select DM
> > @@ -1932,6 +1952,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 c68e598a67..44178c204b 100644
> > --- a/arch/arm/Makefile
> > +++ b/arch/arm/Makefile
> > @@ -51,6 +51,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..0c8b35292e
> > --- /dev/null
> > +++ b/arch/arm/mach-apple/board.c
> > @@ -0,0 +1,158 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * (C) Copyright 2021 Mark Kettenis <kettenis@openbsd.org>
> > + */
> > +
> > +#include <common.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)
> > +{
> > +       int index, node, ret;
> > +       fdt_addr_t base;
> > +       fdt_size_t size;
> > +
> > +       ret = fdtdec_setup_mem_size_base();
> > +       if (ret)
> > +               return ret;
> > +
> > +       /* Update RAM mapping. */
>
> nits: please remove the ending .
>
> > +       index = ARRAY_SIZE(apple_mem_map) - 3;

This is error prone. Someone else updating apple_mem_map may create an
incorrect index for us.

> > +       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 = fdt_path_offset(gd->fdt_blob, "/chosen/framebuffer");
> > +       if (node < 0)
> > +               return 0;
> > +
> > +       base = fdtdec_get_addr_size(gd->fdt_blob, node, "reg", &size);
> > +       if (base == FDT_ADDR_T_NONE)
> > +               return 0;
> > +
> > +       /* Add framebuffer mapping. */
>
> ditto
>
> > +       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)
>
> This looks like we should add a new sysreset driver for Apple Arm SoC.
>
> > +{
> > +       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 (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..0f5313163e
> > --- /dev/null
> > +++ b/arch/arm/mach-apple/lowlevel_init.S
> > @@ -0,0 +1,16 @@
> > +/* SPDX-License-Identifier: GPL-2.0+ */
> > +/*
> > + * (C) Copyright 2021 Mark Kettenis <kettenis@openbsd.org>
> > + */
> > +
> > +.align 8
> > +.global fw_dtb_pointer
> > +fw_dtb_pointer:
> > +       .quad   0
>
> Is this filled in by m1n1?

Sorry I misread, so this is passed by m1n1 and filled in by U-Boot. I
think we should stop using CONFIG_OF_BOARD, and for such case we
should use CONFIG_OF_PRIOR_STAGE.

>
> > +
> > +.global save_boot_params
> > +save_boot_params:
> > +       adr     x1, fw_dtb_pointer
> > +       str     x0, [x1]
> > +
> > +       b       save_boot_params_ret

Regards,
Bin
Mark Kettenis Sept. 19, 2021, 8:05 p.m. UTC | #3
> From: Bin Meng <bmeng.cn@gmail.com>
> Date: Sun, 19 Sep 2021 09:04:56 +0800

Hi Bin,

Thanks for taking a look.

> Hi Mark,
> 
> On Sat, Sep 18, 2021 at 9:55 PM Mark Kettenis <kettenis@openbsd.org> wrote:
> >
> > 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@openbsd.org>
> > ---
> >  arch/arm/Kconfig                    |  22 ++++
> >  arch/arm/Makefile                   |   1 +
> >  arch/arm/mach-apple/Kconfig         |  18 ++++
> >  arch/arm/mach-apple/Makefile        |   4 +
> >  arch/arm/mach-apple/board.c         | 158 ++++++++++++++++++++++++++++
> >  arch/arm/mach-apple/lowlevel_init.S |  16 +++
> >  configs/apple_m1_defconfig          |  14 +++
> >  include/configs/apple.h             |  38 +++++++
> >  8 files changed, 271 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 b5bd3284cd..7cdea1f615 100644
> > --- a/arch/arm/Kconfig
> > +++ b/arch/arm/Kconfig
> > @@ -895,6 +895,26 @@ config ARCH_NEXELL
> >         select DM
> >         select GPIO_EXTRA_HEADER
> >
> > +config ARCH_APPLE
> > +       bool "Apple SoCs"
> > +       select ARM64
> > +       select LINUX_KERNEL_IMAGE_HEADER
> > +       select POSITION_INDEPENDENT
> > +       select BLK
> > +       select DM
> > +       select DM_KEYBOARD
> > +       select DM_SERIAL
> > +       select DM_USB
> > +       select DM_VIDEO
> > +       select CMD_USB
> > +       select MISC
> > +       select OF_CONTROL
> > +       select OF_BOARD
> > +       select USB
> > +       imply CMD_DM
> > +       imply CMD_GPT
> > +       imply DISTRO_DEFAULTS
> > +
> >  config ARCH_OWL
> >         bool "Actions Semi OWL SoCs"
> >         select DM
> > @@ -1932,6 +1952,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 c68e598a67..44178c204b 100644
> > --- a/arch/arm/Makefile
> > +++ b/arch/arm/Makefile
> > @@ -51,6 +51,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..0c8b35292e
> > --- /dev/null
> > +++ b/arch/arm/mach-apple/board.c
> > @@ -0,0 +1,158 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * (C) Copyright 2021 Mark Kettenis <kettenis@openbsd.org>
> > + */
> > +
> > +#include <common.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)
> > +{
> > +       int index, node, ret;
> > +       fdt_addr_t base;
> > +       fdt_size_t size;
> > +
> > +       ret = fdtdec_setup_mem_size_base();
> > +       if (ret)
> > +               return ret;
> > +
> > +       /* Update RAM mapping. */
> 
> nits: please remove the ending .

Really?  The current codebase has both styles...  But sure, I can make
that change.

> > +       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 = fdt_path_offset(gd->fdt_blob, "/chosen/framebuffer");
> > +       if (node < 0)
> > +               return 0;
> > +
> > +       base = fdtdec_get_addr_size(gd->fdt_blob, node, "reg", &size);
> > +       if (base == FDT_ADDR_T_NONE)
> > +               return 0;
> > +
> > +       /* Add framebuffer mapping. */
> 
> ditto
> 
> > +       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)
> 
> This looks like we should add a new sysreset driver for Apple Arm SoC.

Could be.  This is actually a watchdog device that is used to reset
the machine.  So I suppose I should add a watchdog driver and use
SYSRESET_WATCHDOG.  Slight worry is that this relies on a lot more DM
code.  Does that mean the reset isn't available during early boot?

If it is acceptable, I would like to add the watchdog device in a
future series, once the device tree bindings for the watchdog have
been hammered out.

> > +{
> > +       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 (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..0f5313163e
> > --- /dev/null
> > +++ b/arch/arm/mach-apple/lowlevel_init.S
> > @@ -0,0 +1,16 @@
> > +/* SPDX-License-Identifier: GPL-2.0+ */
> > +/*
> > + * (C) Copyright 2021 Mark Kettenis <kettenis@openbsd.org>
> > + */
> > +
> > +.align 8
> > +.global fw_dtb_pointer
> > +fw_dtb_pointer:
> > +       .quad   0
> 
> Is this filled in by m1n1?
> 
> > +
> > +.global save_boot_params
> > +save_boot_params:
> > +       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..a7ae15576b
> > --- /dev/null
> > +++ b/configs/apple_m1_defconfig
> > @@ -0,0 +1,14 @@
> > +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_GENERATE_SMBIOS_TABLE is not set
> > diff --git a/include/configs/apple.h b/include/configs/apple.h
> > new file mode 100644
> > index 0000000000..1c246af002
> > --- /dev/null
> > +++ b/include/configs/apple.h
> > @@ -0,0 +1,38 @@
> > +#ifndef __CONFIG_H
> > +#define __CONFIG_H
> > +
> > +#include <linux/sizes.h>
> > +
> > +#define CONFIG_SYS_LOAD_ADDR   0x880000000
> > +
> > +#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
> 
> Regards,
> Bin
>
Mark Kettenis Sept. 19, 2021, 8:33 p.m. UTC | #4
> From: Bin Meng <bmeng.cn@gmail.com>
> Date: Sun, 19 Sep 2021 09:17:07 +0800
> 
> Hi Mark,
> 
> On Sun, Sep 19, 2021 at 9:04 AM Bin Meng <bmeng.cn@gmail.com> wrote:
> >
> > Hi Mark,
> >
> > On Sat, Sep 18, 2021 at 9:55 PM Mark Kettenis <kettenis@openbsd.org> wrote:
> > >
> > > 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@openbsd.org>
> > > ---
> > >  arch/arm/Kconfig                    |  22 ++++
> > >  arch/arm/Makefile                   |   1 +
> > >  arch/arm/mach-apple/Kconfig         |  18 ++++
> > >  arch/arm/mach-apple/Makefile        |   4 +
> > >  arch/arm/mach-apple/board.c         | 158 ++++++++++++++++++++++++++++
> > >  arch/arm/mach-apple/lowlevel_init.S |  16 +++
> > >  configs/apple_m1_defconfig          |  14 +++
> > >  include/configs/apple.h             |  38 +++++++
> > >  8 files changed, 271 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 b5bd3284cd..7cdea1f615 100644
> > > --- a/arch/arm/Kconfig
> > > +++ b/arch/arm/Kconfig
> > > @@ -895,6 +895,26 @@ config ARCH_NEXELL
> > >         select DM
> > >         select GPIO_EXTRA_HEADER
> > >
> > > +config ARCH_APPLE
> > > +       bool "Apple SoCs"
> > > +       select ARM64
> > > +       select LINUX_KERNEL_IMAGE_HEADER
> > > +       select POSITION_INDEPENDENT
> > > +       select BLK
> > > +       select DM
> > > +       select DM_KEYBOARD
> > > +       select DM_SERIAL
> > > +       select DM_USB
> > > +       select DM_VIDEO
> > > +       select CMD_USB
> > > +       select MISC
> > > +       select OF_CONTROL
> > > +       select OF_BOARD
> > > +       select USB
> > > +       imply CMD_DM
> > > +       imply CMD_GPT
> > > +       imply DISTRO_DEFAULTS
> > > +
> > >  config ARCH_OWL
> > >         bool "Actions Semi OWL SoCs"
> > >         select DM
> > > @@ -1932,6 +1952,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 c68e598a67..44178c204b 100644
> > > --- a/arch/arm/Makefile
> > > +++ b/arch/arm/Makefile
> > > @@ -51,6 +51,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..0c8b35292e
> > > --- /dev/null
> > > +++ b/arch/arm/mach-apple/board.c
> > > @@ -0,0 +1,158 @@
> > > +// SPDX-License-Identifier: GPL-2.0+
> > > +/*
> > > + * (C) Copyright 2021 Mark Kettenis <kettenis@openbsd.org>
> > > + */
> > > +
> > > +#include <common.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)
> > > +{
> > > +       int index, node, ret;
> > > +       fdt_addr_t base;
> > > +       fdt_size_t size;
> > > +
> > > +       ret = fdtdec_setup_mem_size_base();
> > > +       if (ret)
> > > +               return ret;
> > > +
> > > +       /* Update RAM mapping. */
> >
> > nits: please remove the ending .
> >
> > > +       index = ARRAY_SIZE(apple_mem_map) - 3;
> 
> This is error prone. Someone else updating apple_mem_map may create an
> incorrect index for us.

I don't see a better way without introducing more complexity.

> > > +       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 = fdt_path_offset(gd->fdt_blob, "/chosen/framebuffer");
> > > +       if (node < 0)
> > > +               return 0;
> > > +
> > > +       base = fdtdec_get_addr_size(gd->fdt_blob, node, "reg", &size);
> > > +       if (base == FDT_ADDR_T_NONE)
> > > +               return 0;
> > > +
> > > +       /* Add framebuffer mapping. */
> >
> > ditto
> >
> > > +       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)
> >
> > This looks like we should add a new sysreset driver for Apple Arm SoC.
> >
> > > +{
> > > +       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 (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..0f5313163e
> > > --- /dev/null
> > > +++ b/arch/arm/mach-apple/lowlevel_init.S
> > > @@ -0,0 +1,16 @@
> > > +/* SPDX-License-Identifier: GPL-2.0+ */
> > > +/*
> > > + * (C) Copyright 2021 Mark Kettenis <kettenis@openbsd.org>
> > > + */
> > > +
> > > +.align 8
> > > +.global fw_dtb_pointer
> > > +fw_dtb_pointer:
> > > +       .quad   0
> >
> > Is this filled in by m1n1?
> 
> Sorry I misread, so this is passed by m1n1 and filled in by U-Boot. I
> think we should stop using CONFIG_OF_BOARD, and for such case we
> should use CONFIG_OF_PRIOR_STAGE.

Yes, CONFIG_OF_PRIOR_STAGE would work as well.  But Tom was talking
about removing that option in favour of CONFIG_OF_BOARD the other day.

> > > +
> > > +.global save_boot_params
> > > +save_boot_params:
> > > +       adr     x1, fw_dtb_pointer
> > > +       str     x0, [x1]
> > > +
> > > +       b       save_boot_params_ret
> 
> Regards,
> Bin
>
Simon Glass Sept. 20, 2021, 3:15 a.m. UTC | #5
Hi Mark,

On Sat, 18 Sept 2021 at 07:55, Mark Kettenis <kettenis@openbsd.org> wrote:
>
> 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@openbsd.org>
> ---
>  arch/arm/Kconfig                    |  22 ++++
>  arch/arm/Makefile                   |   1 +
>  arch/arm/mach-apple/Kconfig         |  18 ++++
>  arch/arm/mach-apple/Makefile        |   4 +
>  arch/arm/mach-apple/board.c         | 158 ++++++++++++++++++++++++++++
>  arch/arm/mach-apple/lowlevel_init.S |  16 +++
>  configs/apple_m1_defconfig          |  14 +++
>  include/configs/apple.h             |  38 +++++++
>  8 files changed, 271 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 b5bd3284cd..7cdea1f615 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -895,6 +895,26 @@ config ARCH_NEXELL
>         select DM
>         select GPIO_EXTRA_HEADER
>
> +config ARCH_APPLE
> +       bool "Apple SoCs"
> +       select ARM64
> +       select LINUX_KERNEL_IMAGE_HEADER
> +       select POSITION_INDEPENDENT
> +       select BLK
> +       select DM
> +       select DM_KEYBOARD
> +       select DM_SERIAL
> +       select DM_USB
> +       select DM_VIDEO
> +       select CMD_USB
> +       select MISC
> +       select OF_CONTROL
> +       select OF_BOARD
> +       select USB
> +       imply CMD_DM
> +       imply CMD_GPT
> +       imply DISTRO_DEFAULTS

Suggest sorting these

> +
>  config ARCH_OWL
>         bool "Actions Semi OWL SoCs"
>         select DM
> @@ -1932,6 +1952,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 c68e598a67..44178c204b 100644
> --- a/arch/arm/Makefile
> +++ b/arch/arm/Makefile
> @@ -51,6 +51,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..0c8b35292e
> --- /dev/null
> +++ b/arch/arm/mach-apple/board.c
> @@ -0,0 +1,158 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * (C) Copyright 2021 Mark Kettenis <kettenis@openbsd.org>
> + */
> +
> +#include <common.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)
> +{
> +       int index, node, ret;
> +       fdt_addr_t base;
> +       fdt_size_t size;
> +
> +       ret = fdtdec_setup_mem_size_base();
> +       if (ret)
> +               return ret;
> +
> +       /* Update RAM mapping. */

Do you want the period at the end of that?

> +       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 = fdt_path_offset(gd->fdt_blob, "/chosen/framebuffer");

Can you use the ofnode interface here and below?

> +       if (node < 0)
> +               return 0;
> +
> +       base = fdtdec_get_addr_size(gd->fdt_blob, 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

should be in DT I think, with a driver

> +
> +#define APPLE_WDT_SYS_CTL_ENABLE       BIT(2)
> +
> +typedef struct apple_wdt {

Needs comments

> +       u32     reserved0[3];
> +       u32     chip_ctl;
> +       u32     sys_tmr;
> +       u32     sys_cmp;
> +       u32     reserved1;
> +       u32     sys_ctl;
> +} apple_wdt_t;
> +
> +void reset_cpu(void)

You should add a sysreset driver, as Bin says.

> +{
> +       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;

comment

> +
> +void *board_fdt_blob_setup(void)
> +{
> +       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..0f5313163e
> --- /dev/null
> +++ b/arch/arm/mach-apple/lowlevel_init.S
> @@ -0,0 +1,16 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * (C) Copyright 2021 Mark Kettenis <kettenis@openbsd.org>
> + */
> +
> +.align 8
> +.global fw_dtb_pointer
> +fw_dtb_pointer:
> +       .quad   0
> +
> +.global save_boot_params
> +save_boot_params:
> +       adr     x1, fw_dtb_pointer

could use a comment as to where this is set up. Previous-stage
firmware, I suppose?

> +       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..a7ae15576b
> --- /dev/null
> +++ b/configs/apple_m1_defconfig
> @@ -0,0 +1,14 @@
> +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_GENERATE_SMBIOS_TABLE is not set
> diff --git a/include/configs/apple.h b/include/configs/apple.h
> new file mode 100644
> index 0000000000..1c246af002
> --- /dev/null
> +++ b/include/configs/apple.h
> @@ -0,0 +1,38 @@
> +#ifndef __CONFIG_H
> +#define __CONFIG_H
> +
> +#include <linux/sizes.h>
> +
> +#define CONFIG_SYS_LOAD_ADDR   0x880000000
> +
> +#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
>

Regards,
Simon
Mark Kettenis Sept. 20, 2021, 8:49 a.m. UTC | #6
> From: Simon Glass <sjg@chromium.org>
> Date: Sun, 19 Sep 2021 21:15:57 -0600
> 
> Hi Mark,
> 
> On Sat, 18 Sept 2021 at 07:55, Mark Kettenis <kettenis@openbsd.org> wrote:
> >
> > 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@openbsd.org>
> > ---
> >  arch/arm/Kconfig                    |  22 ++++
> >  arch/arm/Makefile                   |   1 +
> >  arch/arm/mach-apple/Kconfig         |  18 ++++
> >  arch/arm/mach-apple/Makefile        |   4 +
> >  arch/arm/mach-apple/board.c         | 158 ++++++++++++++++++++++++++++
> >  arch/arm/mach-apple/lowlevel_init.S |  16 +++
> >  configs/apple_m1_defconfig          |  14 +++
> >  include/configs/apple.h             |  38 +++++++
> >  8 files changed, 271 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 b5bd3284cd..7cdea1f615 100644
> > --- a/arch/arm/Kconfig
> > +++ b/arch/arm/Kconfig
> > @@ -895,6 +895,26 @@ config ARCH_NEXELL
> >         select DM
> >         select GPIO_EXTRA_HEADER
> >
> > +config ARCH_APPLE
> > +       bool "Apple SoCs"
> > +       select ARM64
> > +       select LINUX_KERNEL_IMAGE_HEADER
> > +       select POSITION_INDEPENDENT
> > +       select BLK
> > +       select DM
> > +       select DM_KEYBOARD
> > +       select DM_SERIAL
> > +       select DM_USB
> > +       select DM_VIDEO
> > +       select CMD_USB
> > +       select MISC
> > +       select OF_CONTROL
> > +       select OF_BOARD
> > +       select USB
> > +       imply CMD_DM
> > +       imply CMD_GPT
> > +       imply DISTRO_DEFAULTS
> 
> Suggest sorting these

As in sort all the selects alphabetically and sort all the implies
alphabetically seperately?

Does my use of impy here even make sense?

This whole Kconfig stuff is a bit alien to me and I must say that it
isn't obvious what "best-practice" is in this area...

> > +
> >  config ARCH_OWL
> >         bool "Actions Semi OWL SoCs"
> >         select DM
> > @@ -1932,6 +1952,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 c68e598a67..44178c204b 100644
> > --- a/arch/arm/Makefile
> > +++ b/arch/arm/Makefile
> > @@ -51,6 +51,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..0c8b35292e
> > --- /dev/null
> > +++ b/arch/arm/mach-apple/board.c
> > @@ -0,0 +1,158 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * (C) Copyright 2021 Mark Kettenis <kettenis@openbsd.org>
> > + */
> > +
> > +#include <common.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)
> > +{
> > +       int index, node, ret;
> > +       fdt_addr_t base;
> > +       fdt_size_t size;
> > +
> > +       ret = fdtdec_setup_mem_size_base();
> > +       if (ret)
> > +               return ret;
> > +
> > +       /* Update RAM mapping. */
> 
> Do you want the period at the end of that?

Given that Bin brought up the same thing, I gather that not having a
full stop at the end of single-line comments is preferred?
 
> > +       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 = fdt_path_offset(gd->fdt_blob, "/chosen/framebuffer");
> 
> Can you use the ofnode interface here and below?

I can try...

> > +       if (node < 0)
> > +               return 0;
> > +
> > +       base = fdtdec_get_addr_size(gd->fdt_blob, 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
> 
> should be in DT I think, with a driver
> 
> > +
> > +#define APPLE_WDT_SYS_CTL_ENABLE       BIT(2)
> > +
> > +typedef struct apple_wdt {
> 
> Needs comments
> 
> > +       u32     reserved0[3];
> > +       u32     chip_ctl;
> > +       u32     sys_tmr;
> > +       u32     sys_cmp;
> > +       u32     reserved1;
> > +       u32     sys_ctl;
> > +} apple_wdt_t;
> > +
> > +void reset_cpu(void)
> 
> You should add a sysreset driver, as Bin says.
> 
> > +{
> > +       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;
> 
> comment
> 
> > +
> > +void *board_fdt_blob_setup(void)
> > +{
> > +       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..0f5313163e
> > --- /dev/null
> > +++ b/arch/arm/mach-apple/lowlevel_init.S
> > @@ -0,0 +1,16 @@
> > +/* SPDX-License-Identifier: GPL-2.0+ */
> > +/*
> > + * (C) Copyright 2021 Mark Kettenis <kettenis@openbsd.org>
> > + */
> > +
> > +.align 8
> > +.global fw_dtb_pointer
> > +fw_dtb_pointer:
> > +       .quad   0
> > +
> > +.global save_boot_params
> > +save_boot_params:
> > +       adr     x1, fw_dtb_pointer
> 
> could use a comment as to where this is set up. Previous-stage
> firmware, I suppose?

Yes.  I'm basically making U-Boot look like a Linux kernel, and m1n1
passes the DT in x1 just like the Linux kernel expects.

I suspect using CONFIG_OF_PRIOR_STAGE would make it more obvious what
is happening here.  But (a) I didn't know that existed and (b) we
discussed removing that option in the near future.


> > +       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..a7ae15576b
> > --- /dev/null
> > +++ b/configs/apple_m1_defconfig
> > @@ -0,0 +1,14 @@
> > +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_GENERATE_SMBIOS_TABLE is not set
> > diff --git a/include/configs/apple.h b/include/configs/apple.h
> > new file mode 100644
> > index 0000000000..1c246af002
> > --- /dev/null
> > +++ b/include/configs/apple.h
> > @@ -0,0 +1,38 @@
> > +#ifndef __CONFIG_H
> > +#define __CONFIG_H
> > +
> > +#include <linux/sizes.h>
> > +
> > +#define CONFIG_SYS_LOAD_ADDR   0x880000000
> > +
> > +#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
> >
> 
> Regards,
> Simon
>
Simon Glass Sept. 21, 2021, 1:11 a.m. UTC | #7
Hi Mark,

On Mon, 20 Sept 2021 at 02:49, Mark Kettenis <mark.kettenis@xs4all.nl> wrote:
>
> > From: Simon Glass <sjg@chromium.org>
> > Date: Sun, 19 Sep 2021 21:15:57 -0600
> >
> > Hi Mark,
> >
> > On Sat, 18 Sept 2021 at 07:55, Mark Kettenis <kettenis@openbsd.org> wrote:
> > >
> > > 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@openbsd.org>
> > > ---
> > >  arch/arm/Kconfig                    |  22 ++++
> > >  arch/arm/Makefile                   |   1 +
> > >  arch/arm/mach-apple/Kconfig         |  18 ++++
> > >  arch/arm/mach-apple/Makefile        |   4 +
> > >  arch/arm/mach-apple/board.c         | 158 ++++++++++++++++++++++++++++
> > >  arch/arm/mach-apple/lowlevel_init.S |  16 +++
> > >  configs/apple_m1_defconfig          |  14 +++
> > >  include/configs/apple.h             |  38 +++++++
> > >  8 files changed, 271 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 b5bd3284cd..7cdea1f615 100644
> > > --- a/arch/arm/Kconfig
> > > +++ b/arch/arm/Kconfig
> > > @@ -895,6 +895,26 @@ config ARCH_NEXELL
> > >         select DM
> > >         select GPIO_EXTRA_HEADER
> > >
> > > +config ARCH_APPLE
> > > +       bool "Apple SoCs"
> > > +       select ARM64
> > > +       select LINUX_KERNEL_IMAGE_HEADER
> > > +       select POSITION_INDEPENDENT
> > > +       select BLK
> > > +       select DM
> > > +       select DM_KEYBOARD
> > > +       select DM_SERIAL
> > > +       select DM_USB
> > > +       select DM_VIDEO
> > > +       select CMD_USB
> > > +       select MISC
> > > +       select OF_CONTROL
> > > +       select OF_BOARD
> > > +       select USB
> > > +       imply CMD_DM
> > > +       imply CMD_GPT
> > > +       imply DISTRO_DEFAULTS
> >
> > Suggest sorting these
>
> As in sort all the selects alphabetically and sort all the implies
> alphabetically seperately?

I suppose so.

>
> Does my use of impy here even make sense?

It allows people to disable it, whereas select does not. It looks OK to me.

>
> This whole Kconfig stuff is a bit alien to me and I must say that it
> isn't obvious what "best-practice" is in this area...

We try to avoid select so only use it if it really cannot build/run
without that feature. From what I can tell you have done that.

I know this is a different project, but there are some ideas here:

https://docs.zephyrproject.org/1.14.0/guides/kconfig/index.html

[..]

> > > +int dram_init(void)
> > > +{
> > > +       int index, node, ret;
> > > +       fdt_addr_t base;
> > > +       fdt_size_t size;
> > > +
> > > +       ret = fdtdec_setup_mem_size_base();
> > > +       if (ret)
> > > +               return ret;
> > > +
> > > +       /* Update RAM mapping. */
> >
> > Do you want the period at the end of that?
>
> Given that Bin brought up the same thing, I gather that not having a
> full stop at the end of single-line comments is preferred?

Yes, the periods just clutter things and people start adding them only
when it is a valid sentence, etc. Best to just leave them out.

>
> > > +       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 = fdt_path_offset(gd->fdt_blob, "/chosen/framebuffer");
> >
> > Can you use the ofnode interface here and below?
>
> I can try...

Something like:

ofnode node;

node = ofnode_path("/chosen/framebuffer");

then use ofnode_get_addr_size()

>
> > > +       if (node < 0)
> > > +               return 0;
> > > +
> > > +       base = fdtdec_get_addr_size(gd->fdt_blob, 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;
> > > +}

[..]

> > > diff --git a/arch/arm/mach-apple/lowlevel_init.S b/arch/arm/mach-apple/lowlevel_init.S
> > > new file mode 100644
> > > index 0000000000..0f5313163e
> > > --- /dev/null
> > > +++ b/arch/arm/mach-apple/lowlevel_init.S
> > > @@ -0,0 +1,16 @@
> > > +/* SPDX-License-Identifier: GPL-2.0+ */
> > > +/*
> > > + * (C) Copyright 2021 Mark Kettenis <kettenis@openbsd.org>
> > > + */
> > > +
> > > +.align 8
> > > +.global fw_dtb_pointer
> > > +fw_dtb_pointer:
> > > +       .quad   0
> > > +
> > > +.global save_boot_params
> > > +save_boot_params:
> > > +       adr     x1, fw_dtb_pointer
> >
> > could use a comment as to where this is set up. Previous-stage
> > firmware, I suppose?
>
> Yes.  I'm basically making U-Boot look like a Linux kernel, and m1n1
> passes the DT in x1 just like the Linux kernel expects.
>
> I suspect using CONFIG_OF_PRIOR_STAGE would make it more obvious what
> is happening here.  But (a) I didn't know that existed and (b) we
> discussed removing that option in the near future.

That sounds right to me, but a comment would help.

Regards,
Simon
Tom Rini Sept. 21, 2021, 12:42 p.m. UTC | #8
On Sun, Sep 19, 2021 at 10:33:25PM +0200, Mark Kettenis wrote:
> > From: Bin Meng <bmeng.cn@gmail.com>
> > Date: Sun, 19 Sep 2021 09:17:07 +0800
> > 
> > Hi Mark,
> > 
> > On Sun, Sep 19, 2021 at 9:04 AM Bin Meng <bmeng.cn@gmail.com> wrote:
> > >
> > > Hi Mark,
> > >
> > > On Sat, Sep 18, 2021 at 9:55 PM Mark Kettenis <kettenis@openbsd.org> wrote:
> > > >
> > > > 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@openbsd.org>
> > > > ---
> > > >  arch/arm/Kconfig                    |  22 ++++
> > > >  arch/arm/Makefile                   |   1 +
> > > >  arch/arm/mach-apple/Kconfig         |  18 ++++
> > > >  arch/arm/mach-apple/Makefile        |   4 +
> > > >  arch/arm/mach-apple/board.c         | 158 ++++++++++++++++++++++++++++
> > > >  arch/arm/mach-apple/lowlevel_init.S |  16 +++
> > > >  configs/apple_m1_defconfig          |  14 +++
> > > >  include/configs/apple.h             |  38 +++++++
> > > >  8 files changed, 271 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 b5bd3284cd..7cdea1f615 100644
> > > > --- a/arch/arm/Kconfig
> > > > +++ b/arch/arm/Kconfig
> > > > @@ -895,6 +895,26 @@ config ARCH_NEXELL
> > > >         select DM
> > > >         select GPIO_EXTRA_HEADER
> > > >
> > > > +config ARCH_APPLE
> > > > +       bool "Apple SoCs"
> > > > +       select ARM64
> > > > +       select LINUX_KERNEL_IMAGE_HEADER
> > > > +       select POSITION_INDEPENDENT
> > > > +       select BLK
> > > > +       select DM
> > > > +       select DM_KEYBOARD
> > > > +       select DM_SERIAL
> > > > +       select DM_USB
> > > > +       select DM_VIDEO
> > > > +       select CMD_USB
> > > > +       select MISC
> > > > +       select OF_CONTROL
> > > > +       select OF_BOARD
> > > > +       select USB
> > > > +       imply CMD_DM
> > > > +       imply CMD_GPT
> > > > +       imply DISTRO_DEFAULTS
> > > > +
> > > >  config ARCH_OWL
> > > >         bool "Actions Semi OWL SoCs"
> > > >         select DM
> > > > @@ -1932,6 +1952,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 c68e598a67..44178c204b 100644
> > > > --- a/arch/arm/Makefile
> > > > +++ b/arch/arm/Makefile
> > > > @@ -51,6 +51,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..0c8b35292e
> > > > --- /dev/null
> > > > +++ b/arch/arm/mach-apple/board.c
> > > > @@ -0,0 +1,158 @@
> > > > +// SPDX-License-Identifier: GPL-2.0+
> > > > +/*
> > > > + * (C) Copyright 2021 Mark Kettenis <kettenis@openbsd.org>
> > > > + */
> > > > +
> > > > +#include <common.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)
> > > > +{
> > > > +       int index, node, ret;
> > > > +       fdt_addr_t base;
> > > > +       fdt_size_t size;
> > > > +
> > > > +       ret = fdtdec_setup_mem_size_base();
> > > > +       if (ret)
> > > > +               return ret;
> > > > +
> > > > +       /* Update RAM mapping. */
> > >
> > > nits: please remove the ending .
> > >
> > > > +       index = ARRAY_SIZE(apple_mem_map) - 3;
> > 
> > This is error prone. Someone else updating apple_mem_map may create an
> > incorrect index for us.
> 
> I don't see a better way without introducing more complexity.
> 
> > > > +       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 = fdt_path_offset(gd->fdt_blob, "/chosen/framebuffer");
> > > > +       if (node < 0)
> > > > +               return 0;
> > > > +
> > > > +       base = fdtdec_get_addr_size(gd->fdt_blob, node, "reg", &size);
> > > > +       if (base == FDT_ADDR_T_NONE)
> > > > +               return 0;
> > > > +
> > > > +       /* Add framebuffer mapping. */
> > >
> > > ditto
> > >
> > > > +       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)
> > >
> > > This looks like we should add a new sysreset driver for Apple Arm SoC.
> > >
> > > > +{
> > > > +       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 (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..0f5313163e
> > > > --- /dev/null
> > > > +++ b/arch/arm/mach-apple/lowlevel_init.S
> > > > @@ -0,0 +1,16 @@
> > > > +/* SPDX-License-Identifier: GPL-2.0+ */
> > > > +/*
> > > > + * (C) Copyright 2021 Mark Kettenis <kettenis@openbsd.org>
> > > > + */
> > > > +
> > > > +.align 8
> > > > +.global fw_dtb_pointer
> > > > +fw_dtb_pointer:
> > > > +       .quad   0
> > >
> > > Is this filled in by m1n1?
> > 
> > Sorry I misread, so this is passed by m1n1 and filled in by U-Boot. I
> > think we should stop using CONFIG_OF_BOARD, and for such case we
> > should use CONFIG_OF_PRIOR_STAGE.
> 
> Yes, CONFIG_OF_PRIOR_STAGE would work as well.  But Tom was talking
> about removing that option in favour of CONFIG_OF_BOARD the other day.

Yes.  I was even looking for some feedback from you, Bin, on converting
some boards from CONFIG_OF_PRIOR_STAGE to CONFIG_OF_BOARD.  It seems
like CONFIG_OF_PRIOR_STAGE is a subset of CONFIG_OF_BOARD, at the cost
of possibly a few bytes.
Bin Meng Sept. 21, 2021, 3:53 p.m. UTC | #9
On Tue, Sep 21, 2021 at 8:42 PM Tom Rini <trini@konsulko.com> wrote:
>
> On Sun, Sep 19, 2021 at 10:33:25PM +0200, Mark Kettenis wrote:
> > > From: Bin Meng <bmeng.cn@gmail.com>
> > > Date: Sun, 19 Sep 2021 09:17:07 +0800
> > >
> > > Hi Mark,
> > >
> > > On Sun, Sep 19, 2021 at 9:04 AM Bin Meng <bmeng.cn@gmail.com> wrote:
> > > >
> > > > Hi Mark,
> > > >
> > > > On Sat, Sep 18, 2021 at 9:55 PM Mark Kettenis <kettenis@openbsd.org> wrote:
> > > > >
> > > > > 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@openbsd.org>
> > > > > ---
> > > > >  arch/arm/Kconfig                    |  22 ++++
> > > > >  arch/arm/Makefile                   |   1 +
> > > > >  arch/arm/mach-apple/Kconfig         |  18 ++++
> > > > >  arch/arm/mach-apple/Makefile        |   4 +
> > > > >  arch/arm/mach-apple/board.c         | 158 ++++++++++++++++++++++++++++
> > > > >  arch/arm/mach-apple/lowlevel_init.S |  16 +++
> > > > >  configs/apple_m1_defconfig          |  14 +++
> > > > >  include/configs/apple.h             |  38 +++++++
> > > > >  8 files changed, 271 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 b5bd3284cd..7cdea1f615 100644
> > > > > --- a/arch/arm/Kconfig
> > > > > +++ b/arch/arm/Kconfig
> > > > > @@ -895,6 +895,26 @@ config ARCH_NEXELL
> > > > >         select DM
> > > > >         select GPIO_EXTRA_HEADER
> > > > >
> > > > > +config ARCH_APPLE
> > > > > +       bool "Apple SoCs"
> > > > > +       select ARM64
> > > > > +       select LINUX_KERNEL_IMAGE_HEADER
> > > > > +       select POSITION_INDEPENDENT
> > > > > +       select BLK
> > > > > +       select DM
> > > > > +       select DM_KEYBOARD
> > > > > +       select DM_SERIAL
> > > > > +       select DM_USB
> > > > > +       select DM_VIDEO
> > > > > +       select CMD_USB
> > > > > +       select MISC
> > > > > +       select OF_CONTROL
> > > > > +       select OF_BOARD
> > > > > +       select USB
> > > > > +       imply CMD_DM
> > > > > +       imply CMD_GPT
> > > > > +       imply DISTRO_DEFAULTS
> > > > > +
> > > > >  config ARCH_OWL
> > > > >         bool "Actions Semi OWL SoCs"
> > > > >         select DM
> > > > > @@ -1932,6 +1952,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 c68e598a67..44178c204b 100644
> > > > > --- a/arch/arm/Makefile
> > > > > +++ b/arch/arm/Makefile
> > > > > @@ -51,6 +51,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..0c8b35292e
> > > > > --- /dev/null
> > > > > +++ b/arch/arm/mach-apple/board.c
> > > > > @@ -0,0 +1,158 @@
> > > > > +// SPDX-License-Identifier: GPL-2.0+
> > > > > +/*
> > > > > + * (C) Copyright 2021 Mark Kettenis <kettenis@openbsd.org>
> > > > > + */
> > > > > +
> > > > > +#include <common.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)
> > > > > +{
> > > > > +       int index, node, ret;
> > > > > +       fdt_addr_t base;
> > > > > +       fdt_size_t size;
> > > > > +
> > > > > +       ret = fdtdec_setup_mem_size_base();
> > > > > +       if (ret)
> > > > > +               return ret;
> > > > > +
> > > > > +       /* Update RAM mapping. */
> > > >
> > > > nits: please remove the ending .
> > > >
> > > > > +       index = ARRAY_SIZE(apple_mem_map) - 3;
> > >
> > > This is error prone. Someone else updating apple_mem_map may create an
> > > incorrect index for us.
> >
> > I don't see a better way without introducing more complexity.
> >
> > > > > +       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 = fdt_path_offset(gd->fdt_blob, "/chosen/framebuffer");
> > > > > +       if (node < 0)
> > > > > +               return 0;
> > > > > +
> > > > > +       base = fdtdec_get_addr_size(gd->fdt_blob, node, "reg", &size);
> > > > > +       if (base == FDT_ADDR_T_NONE)
> > > > > +               return 0;
> > > > > +
> > > > > +       /* Add framebuffer mapping. */
> > > >
> > > > ditto
> > > >
> > > > > +       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)
> > > >
> > > > This looks like we should add a new sysreset driver for Apple Arm SoC.
> > > >
> > > > > +{
> > > > > +       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 (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..0f5313163e
> > > > > --- /dev/null
> > > > > +++ b/arch/arm/mach-apple/lowlevel_init.S
> > > > > @@ -0,0 +1,16 @@
> > > > > +/* SPDX-License-Identifier: GPL-2.0+ */
> > > > > +/*
> > > > > + * (C) Copyright 2021 Mark Kettenis <kettenis@openbsd.org>
> > > > > + */
> > > > > +
> > > > > +.align 8
> > > > > +.global fw_dtb_pointer
> > > > > +fw_dtb_pointer:
> > > > > +       .quad   0
> > > >
> > > > Is this filled in by m1n1?
> > >
> > > Sorry I misread, so this is passed by m1n1 and filled in by U-Boot. I
> > > think we should stop using CONFIG_OF_BOARD, and for such case we
> > > should use CONFIG_OF_PRIOR_STAGE.
> >
> > Yes, CONFIG_OF_PRIOR_STAGE would work as well.  But Tom was talking
> > about removing that option in favour of CONFIG_OF_BOARD the other day.
>
> Yes.  I was even looking for some feedback from you, Bin, on converting
> some boards from CONFIG_OF_PRIOR_STAGE to CONFIG_OF_BOARD.  It seems
> like CONFIG_OF_PRIOR_STAGE is a subset of CONFIG_OF_BOARD, at the cost
> of possibly a few bytes.

Ah, I thought we wanted to do the other way around, by removing
CONFIG_OF_BOARD, and convert that to CONFIG_OF_PRIORI_STAGE?

Regards,
Bin
Tom Rini Sept. 21, 2021, 4:04 p.m. UTC | #10
On Tue, Sep 21, 2021 at 11:53:10PM +0800, Bin Meng wrote:
> On Tue, Sep 21, 2021 at 8:42 PM Tom Rini <trini@konsulko.com> wrote:
> >
> > On Sun, Sep 19, 2021 at 10:33:25PM +0200, Mark Kettenis wrote:
> > > > From: Bin Meng <bmeng.cn@gmail.com>
> > > > Date: Sun, 19 Sep 2021 09:17:07 +0800
> > > >
> > > > Hi Mark,
> > > >
> > > > On Sun, Sep 19, 2021 at 9:04 AM Bin Meng <bmeng.cn@gmail.com> wrote:
> > > > >
> > > > > Hi Mark,
> > > > >
> > > > > On Sat, Sep 18, 2021 at 9:55 PM Mark Kettenis <kettenis@openbsd.org> wrote:
> > > > > >
> > > > > > 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@openbsd.org>
> > > > > > ---
> > > > > >  arch/arm/Kconfig                    |  22 ++++
> > > > > >  arch/arm/Makefile                   |   1 +
> > > > > >  arch/arm/mach-apple/Kconfig         |  18 ++++
> > > > > >  arch/arm/mach-apple/Makefile        |   4 +
> > > > > >  arch/arm/mach-apple/board.c         | 158 ++++++++++++++++++++++++++++
> > > > > >  arch/arm/mach-apple/lowlevel_init.S |  16 +++
> > > > > >  configs/apple_m1_defconfig          |  14 +++
> > > > > >  include/configs/apple.h             |  38 +++++++
> > > > > >  8 files changed, 271 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 b5bd3284cd..7cdea1f615 100644
> > > > > > --- a/arch/arm/Kconfig
> > > > > > +++ b/arch/arm/Kconfig
> > > > > > @@ -895,6 +895,26 @@ config ARCH_NEXELL
> > > > > >         select DM
> > > > > >         select GPIO_EXTRA_HEADER
> > > > > >
> > > > > > +config ARCH_APPLE
> > > > > > +       bool "Apple SoCs"
> > > > > > +       select ARM64
> > > > > > +       select LINUX_KERNEL_IMAGE_HEADER
> > > > > > +       select POSITION_INDEPENDENT
> > > > > > +       select BLK
> > > > > > +       select DM
> > > > > > +       select DM_KEYBOARD
> > > > > > +       select DM_SERIAL
> > > > > > +       select DM_USB
> > > > > > +       select DM_VIDEO
> > > > > > +       select CMD_USB
> > > > > > +       select MISC
> > > > > > +       select OF_CONTROL
> > > > > > +       select OF_BOARD
> > > > > > +       select USB
> > > > > > +       imply CMD_DM
> > > > > > +       imply CMD_GPT
> > > > > > +       imply DISTRO_DEFAULTS
> > > > > > +
> > > > > >  config ARCH_OWL
> > > > > >         bool "Actions Semi OWL SoCs"
> > > > > >         select DM
> > > > > > @@ -1932,6 +1952,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 c68e598a67..44178c204b 100644
> > > > > > --- a/arch/arm/Makefile
> > > > > > +++ b/arch/arm/Makefile
> > > > > > @@ -51,6 +51,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..0c8b35292e
> > > > > > --- /dev/null
> > > > > > +++ b/arch/arm/mach-apple/board.c
> > > > > > @@ -0,0 +1,158 @@
> > > > > > +// SPDX-License-Identifier: GPL-2.0+
> > > > > > +/*
> > > > > > + * (C) Copyright 2021 Mark Kettenis <kettenis@openbsd.org>
> > > > > > + */
> > > > > > +
> > > > > > +#include <common.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)
> > > > > > +{
> > > > > > +       int index, node, ret;
> > > > > > +       fdt_addr_t base;
> > > > > > +       fdt_size_t size;
> > > > > > +
> > > > > > +       ret = fdtdec_setup_mem_size_base();
> > > > > > +       if (ret)
> > > > > > +               return ret;
> > > > > > +
> > > > > > +       /* Update RAM mapping. */
> > > > >
> > > > > nits: please remove the ending .
> > > > >
> > > > > > +       index = ARRAY_SIZE(apple_mem_map) - 3;
> > > >
> > > > This is error prone. Someone else updating apple_mem_map may create an
> > > > incorrect index for us.
> > >
> > > I don't see a better way without introducing more complexity.
> > >
> > > > > > +       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 = fdt_path_offset(gd->fdt_blob, "/chosen/framebuffer");
> > > > > > +       if (node < 0)
> > > > > > +               return 0;
> > > > > > +
> > > > > > +       base = fdtdec_get_addr_size(gd->fdt_blob, node, "reg", &size);
> > > > > > +       if (base == FDT_ADDR_T_NONE)
> > > > > > +               return 0;
> > > > > > +
> > > > > > +       /* Add framebuffer mapping. */
> > > > >
> > > > > ditto
> > > > >
> > > > > > +       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)
> > > > >
> > > > > This looks like we should add a new sysreset driver for Apple Arm SoC.
> > > > >
> > > > > > +{
> > > > > > +       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 (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..0f5313163e
> > > > > > --- /dev/null
> > > > > > +++ b/arch/arm/mach-apple/lowlevel_init.S
> > > > > > @@ -0,0 +1,16 @@
> > > > > > +/* SPDX-License-Identifier: GPL-2.0+ */
> > > > > > +/*
> > > > > > + * (C) Copyright 2021 Mark Kettenis <kettenis@openbsd.org>
> > > > > > + */
> > > > > > +
> > > > > > +.align 8
> > > > > > +.global fw_dtb_pointer
> > > > > > +fw_dtb_pointer:
> > > > > > +       .quad   0
> > > > >
> > > > > Is this filled in by m1n1?
> > > >
> > > > Sorry I misread, so this is passed by m1n1 and filled in by U-Boot. I
> > > > think we should stop using CONFIG_OF_BOARD, and for such case we
> > > > should use CONFIG_OF_PRIOR_STAGE.
> > >
> > > Yes, CONFIG_OF_PRIOR_STAGE would work as well.  But Tom was talking
> > > about removing that option in favour of CONFIG_OF_BOARD the other day.
> >
> > Yes.  I was even looking for some feedback from you, Bin, on converting
> > some boards from CONFIG_OF_PRIOR_STAGE to CONFIG_OF_BOARD.  It seems
> > like CONFIG_OF_PRIOR_STAGE is a subset of CONFIG_OF_BOARD, at the cost
> > of possibly a few bytes.
> 
> Ah, I thought we wanted to do the other way around, by removing
> CONFIG_OF_BOARD, and convert that to CONFIG_OF_PRIORI_STAGE?

Maybe I had it backwards then?  Whichever one can be implemented as a
form of the other, and then we just keep one way of saying "we have the
DT passed in to us".
Mark Kettenis Sept. 21, 2021, 4:08 p.m. UTC | #11
> From: Bin Meng <bmeng.cn@gmail.com>
> Date: Tue, 21 Sep 2021 23:53:10 +0800
> 
> On Tue, Sep 21, 2021 at 8:42 PM Tom Rini <trini@konsulko.com> wrote:
> >
> > On Sun, Sep 19, 2021 at 10:33:25PM +0200, Mark Kettenis wrote:
> > > > From: Bin Meng <bmeng.cn@gmail.com>
> > > > Date: Sun, 19 Sep 2021 09:17:07 +0800
> > > >
> > > > Hi Mark,
> > > >
> > > > On Sun, Sep 19, 2021 at 9:04 AM Bin Meng <bmeng.cn@gmail.com> wrote:
> > > > >
> > > > > Hi Mark,
> > > > >
> > > > > On Sat, Sep 18, 2021 at 9:55 PM Mark Kettenis <kettenis@openbsd.org> wrote:
> > > > > >
> > > > > > 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@openbsd.org>
> > > > > > ---
> > > > > >  arch/arm/Kconfig                    |  22 ++++
> > > > > >  arch/arm/Makefile                   |   1 +
> > > > > >  arch/arm/mach-apple/Kconfig         |  18 ++++
> > > > > >  arch/arm/mach-apple/Makefile        |   4 +
> > > > > >  arch/arm/mach-apple/board.c         | 158 ++++++++++++++++++++++++++++
> > > > > >  arch/arm/mach-apple/lowlevel_init.S |  16 +++
> > > > > >  configs/apple_m1_defconfig          |  14 +++
> > > > > >  include/configs/apple.h             |  38 +++++++
> > > > > >  8 files changed, 271 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 b5bd3284cd..7cdea1f615 100644
> > > > > > --- a/arch/arm/Kconfig
> > > > > > +++ b/arch/arm/Kconfig
> > > > > > @@ -895,6 +895,26 @@ config ARCH_NEXELL
> > > > > >         select DM
> > > > > >         select GPIO_EXTRA_HEADER
> > > > > >
> > > > > > +config ARCH_APPLE
> > > > > > +       bool "Apple SoCs"
> > > > > > +       select ARM64
> > > > > > +       select LINUX_KERNEL_IMAGE_HEADER
> > > > > > +       select POSITION_INDEPENDENT
> > > > > > +       select BLK
> > > > > > +       select DM
> > > > > > +       select DM_KEYBOARD
> > > > > > +       select DM_SERIAL
> > > > > > +       select DM_USB
> > > > > > +       select DM_VIDEO
> > > > > > +       select CMD_USB
> > > > > > +       select MISC
> > > > > > +       select OF_CONTROL
> > > > > > +       select OF_BOARD
> > > > > > +       select USB
> > > > > > +       imply CMD_DM
> > > > > > +       imply CMD_GPT
> > > > > > +       imply DISTRO_DEFAULTS
> > > > > > +
> > > > > >  config ARCH_OWL
> > > > > >         bool "Actions Semi OWL SoCs"
> > > > > >         select DM
> > > > > > @@ -1932,6 +1952,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 c68e598a67..44178c204b 100644
> > > > > > --- a/arch/arm/Makefile
> > > > > > +++ b/arch/arm/Makefile
> > > > > > @@ -51,6 +51,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..0c8b35292e
> > > > > > --- /dev/null
> > > > > > +++ b/arch/arm/mach-apple/board.c
> > > > > > @@ -0,0 +1,158 @@
> > > > > > +// SPDX-License-Identifier: GPL-2.0+
> > > > > > +/*
> > > > > > + * (C) Copyright 2021 Mark Kettenis <kettenis@openbsd.org>
> > > > > > + */
> > > > > > +
> > > > > > +#include <common.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)
> > > > > > +{
> > > > > > +       int index, node, ret;
> > > > > > +       fdt_addr_t base;
> > > > > > +       fdt_size_t size;
> > > > > > +
> > > > > > +       ret = fdtdec_setup_mem_size_base();
> > > > > > +       if (ret)
> > > > > > +               return ret;
> > > > > > +
> > > > > > +       /* Update RAM mapping. */
> > > > >
> > > > > nits: please remove the ending .
> > > > >
> > > > > > +       index = ARRAY_SIZE(apple_mem_map) - 3;
> > > >
> > > > This is error prone. Someone else updating apple_mem_map may create an
> > > > incorrect index for us.
> > >
> > > I don't see a better way without introducing more complexity.
> > >
> > > > > > +       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 = fdt_path_offset(gd->fdt_blob, "/chosen/framebuffer");
> > > > > > +       if (node < 0)
> > > > > > +               return 0;
> > > > > > +
> > > > > > +       base = fdtdec_get_addr_size(gd->fdt_blob, node, "reg", &size);
> > > > > > +       if (base == FDT_ADDR_T_NONE)
> > > > > > +               return 0;
> > > > > > +
> > > > > > +       /* Add framebuffer mapping. */
> > > > >
> > > > > ditto
> > > > >
> > > > > > +       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)
> > > > >
> > > > > This looks like we should add a new sysreset driver for Apple Arm SoC.
> > > > >
> > > > > > +{
> > > > > > +       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 (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..0f5313163e
> > > > > > --- /dev/null
> > > > > > +++ b/arch/arm/mach-apple/lowlevel_init.S
> > > > > > @@ -0,0 +1,16 @@
> > > > > > +/* SPDX-License-Identifier: GPL-2.0+ */
> > > > > > +/*
> > > > > > + * (C) Copyright 2021 Mark Kettenis <kettenis@openbsd.org>
> > > > > > + */
> > > > > > +
> > > > > > +.align 8
> > > > > > +.global fw_dtb_pointer
> > > > > > +fw_dtb_pointer:
> > > > > > +       .quad   0
> > > > >
> > > > > Is this filled in by m1n1?
> > > >
> > > > Sorry I misread, so this is passed by m1n1 and filled in by U-Boot. I
> > > > think we should stop using CONFIG_OF_BOARD, and for such case we
> > > > should use CONFIG_OF_PRIOR_STAGE.
> > >
> > > Yes, CONFIG_OF_PRIOR_STAGE would work as well.  But Tom was talking
> > > about removing that option in favour of CONFIG_OF_BOARD the other day.
> >
> > Yes.  I was even looking for some feedback from you, Bin, on converting
> > some boards from CONFIG_OF_PRIOR_STAGE to CONFIG_OF_BOARD.  It seems
> > like CONFIG_OF_PRIOR_STAGE is a subset of CONFIG_OF_BOARD, at the cost
> > of possibly a few bytes.
> 
> Ah, I thought we wanted to do the other way around, by removing
> CONFIG_OF_BOARD, and convert that to CONFIG_OF_PRIORI_STAGE?

I must say that I see some logic in keeping both, where
CONFIG_OF_BOARD indicates that the device tree is somehow stored on
the board and U-Boot has to run some code to fetch it, and
CONFIG_OF_PRIOR_STAGE is used when the device tree is provided by
firmware that runs before U-Boot.

In that case I obviously should use CONFIG_OF_PRIOR_STAGE here.
Simon Glass Sept. 25, 2021, 1:27 p.m. UTC | #12
Hi Mark,

On Tue, 21 Sept 2021 at 10:09, Mark Kettenis <mark.kettenis@xs4all.nl> wrote:
>
> > From: Bin Meng <bmeng.cn@gmail.com>
> > Date: Tue, 21 Sep 2021 23:53:10 +0800
> >
> > On Tue, Sep 21, 2021 at 8:42 PM Tom Rini <trini@konsulko.com> wrote:
> > >
> > > On Sun, Sep 19, 2021 at 10:33:25PM +0200, Mark Kettenis wrote:
> > > > > From: Bin Meng <bmeng.cn@gmail.com>
> > > > > Date: Sun, 19 Sep 2021 09:17:07 +0800
> > > > >
> > > > > Hi Mark,
> > > > >
> > > > > On Sun, Sep 19, 2021 at 9:04 AM Bin Meng <bmeng.cn@gmail.com> wrote:
> > > > > >
> > > > > > Hi Mark,
> > > > > >
> > > > > > On Sat, Sep 18, 2021 at 9:55 PM Mark Kettenis <kettenis@openbsd.org> wrote:
> > > > > > >
> > > > > > > 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@openbsd.org>
> > > > > > > ---
> > > > > > >  arch/arm/Kconfig                    |  22 ++++
> > > > > > >  arch/arm/Makefile                   |   1 +
> > > > > > >  arch/arm/mach-apple/Kconfig         |  18 ++++
> > > > > > >  arch/arm/mach-apple/Makefile        |   4 +
> > > > > > >  arch/arm/mach-apple/board.c         | 158 ++++++++++++++++++++++++++++
> > > > > > >  arch/arm/mach-apple/lowlevel_init.S |  16 +++
> > > > > > >  configs/apple_m1_defconfig          |  14 +++
> > > > > > >  include/configs/apple.h             |  38 +++++++
> > > > > > >  8 files changed, 271 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/mach-apple/lowlevel_init.S b/arch/arm/mach-apple/lowlevel_init.S
> > > > > > > new file mode 100644
> > > > > > > index 0000000000..0f5313163e
> > > > > > > --- /dev/null
> > > > > > > +++ b/arch/arm/mach-apple/lowlevel_init.S
> > > > > > > @@ -0,0 +1,16 @@
> > > > > > > +/* SPDX-License-Identifier: GPL-2.0+ */
> > > > > > > +/*
> > > > > > > + * (C) Copyright 2021 Mark Kettenis <kettenis@openbsd.org>
> > > > > > > + */
> > > > > > > +
> > > > > > > +.align 8
> > > > > > > +.global fw_dtb_pointer
> > > > > > > +fw_dtb_pointer:
> > > > > > > +       .quad   0
> > > > > >
> > > > > > Is this filled in by m1n1?
> > > > >
> > > > > Sorry I misread, so this is passed by m1n1 and filled in by U-Boot. I
> > > > > think we should stop using CONFIG_OF_BOARD, and for such case we
> > > > > should use CONFIG_OF_PRIOR_STAGE.
> > > >
> > > > Yes, CONFIG_OF_PRIOR_STAGE would work as well.  But Tom was talking
> > > > about removing that option in favour of CONFIG_OF_BOARD the other day.
> > >
> > > Yes.  I was even looking for some feedback from you, Bin, on converting
> > > some boards from CONFIG_OF_PRIOR_STAGE to CONFIG_OF_BOARD.  It seems
> > > like CONFIG_OF_PRIOR_STAGE is a subset of CONFIG_OF_BOARD, at the cost
> > > of possibly a few bytes.
> >
> > Ah, I thought we wanted to do the other way around, by removing
> > CONFIG_OF_BOARD, and convert that to CONFIG_OF_PRIORI_STAGE?
>
> I must say that I see some logic in keeping both, where
> CONFIG_OF_BOARD indicates that the device tree is somehow stored on
> the board and U-Boot has to run some code to fetch it, and
> CONFIG_OF_PRIOR_STAGE is used when the device tree is provided by
> firmware that runs before U-Boot.
>
> In that case I obviously should use CONFIG_OF_PRIOR_STAGE here.

Well see Ilias' series where he proposed going with OF_BOARD!

Tested on: Macbook Air M1
Tested-by: Simon Glass <sjg@chromium.org>

Regards,
Simon
diff mbox series

Patch

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index b5bd3284cd..7cdea1f615 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -895,6 +895,26 @@  config ARCH_NEXELL
 	select DM
 	select GPIO_EXTRA_HEADER
 
+config ARCH_APPLE
+	bool "Apple SoCs"
+	select ARM64
+	select LINUX_KERNEL_IMAGE_HEADER
+	select POSITION_INDEPENDENT
+	select BLK
+	select DM
+	select DM_KEYBOARD
+	select DM_SERIAL
+	select DM_USB
+	select DM_VIDEO
+	select CMD_USB
+	select MISC
+	select OF_CONTROL
+	select OF_BOARD
+	select USB
+	imply CMD_DM
+	imply CMD_GPT
+	imply DISTRO_DEFAULTS
+
 config ARCH_OWL
 	bool "Actions Semi OWL SoCs"
 	select DM
@@ -1932,6 +1952,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 c68e598a67..44178c204b 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -51,6 +51,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..0c8b35292e
--- /dev/null
+++ b/arch/arm/mach-apple/board.c
@@ -0,0 +1,158 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2021 Mark Kettenis <kettenis@openbsd.org>
+ */
+
+#include <common.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)
+{
+	int index, node, 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 = fdt_path_offset(gd->fdt_blob, "/chosen/framebuffer");
+	if (node < 0)
+		return 0;
+
+	base = fdtdec_get_addr_size(gd->fdt_blob, 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 (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..0f5313163e
--- /dev/null
+++ b/arch/arm/mach-apple/lowlevel_init.S
@@ -0,0 +1,16 @@ 
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2021 Mark Kettenis <kettenis@openbsd.org>
+ */
+
+.align 8
+.global fw_dtb_pointer
+fw_dtb_pointer:
+	.quad	0
+
+.global save_boot_params
+save_boot_params:
+	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..a7ae15576b
--- /dev/null
+++ b/configs/apple_m1_defconfig
@@ -0,0 +1,14 @@ 
+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_GENERATE_SMBIOS_TABLE is not set
diff --git a/include/configs/apple.h b/include/configs/apple.h
new file mode 100644
index 0000000000..1c246af002
--- /dev/null
+++ b/include/configs/apple.h
@@ -0,0 +1,38 @@ 
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <linux/sizes.h>
+
+#define CONFIG_SYS_LOAD_ADDR	0x880000000
+
+#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