[U-Boot] [PATCH v3 0/4] RPi one binary for RPi3/4 and RPi1/2

From: Matthias Brugger mbrugger@suse.com
In this series we prepare the RaspberryPi source code to be able to build one binary for RPi[3,4] and one for RPi[1,2]. To achieve this we need to set the IO base address on runtime. Apart from that, for arm64 we also need to set memory region correctly.
This patches fix this stuff. With this we could create one binary for each armv7 and armv8 based RPis. There is still some work to do to create a unified config, which will be done in a later patch series.
Changes in v3: - fix armv7 build
Changes in v2: - push fw_dtb_pointer into the .data section - fix register access in reset_cpu() - rename BCM2838 to BCM2711 in the correct patch - push rpi_bcm283x_base into the .data section - Move mem_map out of assembly file - push mem_map into the .data section - update the members of mem_map inestead of the pointer
Matthias Brugger (4): rpi: push fw_dtb_pointer in the .data section ARM: bcm283x: Move BCM283x_BASE to a global variable ARM: bcm283x: Set rpi_bcm283x_base at run-time ARM: bcm283x: Set memory map at run-time
arch/arm/mach-bcm283x/Kconfig | 6 - arch/arm/mach-bcm283x/include/mach/base.h | 11 ++ arch/arm/mach-bcm283x/include/mach/mbox.h | 4 +- arch/arm/mach-bcm283x/include/mach/sdhci.h | 5 +- arch/arm/mach-bcm283x/include/mach/timer.h | 7 +- arch/arm/mach-bcm283x/include/mach/wdog.h | 5 +- arch/arm/mach-bcm283x/init.c | 140 +++++++++++++++++++++ arch/arm/mach-bcm283x/mbox.c | 1 + arch/arm/mach-bcm283x/reset.c | 20 ++- board/raspberrypi/rpi/lowlevel_init.S | 12 +- board/raspberrypi/rpi/rpi.c | 49 +------- include/configs/rpi.h | 4 + 12 files changed, 192 insertions(+), 72 deletions(-) create mode 100644 arch/arm/mach-bcm283x/include/mach/base.h

From: Matthias Brugger mbrugger@suse.com
The fw_dtb_pointer was defined in the assembly code, which makes him live in section .text_rest Put that's not necessary, we can push the variable in the .data section.
This will prevent relocation errors like: board/raspberrypi/rpi/rpi.c:317:(.text.board_get_usable_ram_top+0x8): relocation truncated to fit: R_AARCH64_LDST64_ABS_LO12_NC against symbol `fw_dtb_pointer' defined in .text section in board/raspberrypi/rpi/built-in.o
Signed-off-by: Matthias Brugger mbrugger@suse.com
---
Changes in v3: - fix armv7 build
Changes in v2: - push fw_dtb_pointer into the .data section
board/raspberrypi/rpi/lowlevel_init.S | 12 ++---------- board/raspberrypi/rpi/rpi.c | 4 ++-- 2 files changed, 4 insertions(+), 12 deletions(-)
diff --git a/board/raspberrypi/rpi/lowlevel_init.S b/board/raspberrypi/rpi/lowlevel_init.S index 435eed521f..8c39b3e12e 100644 --- a/board/raspberrypi/rpi/lowlevel_init.S +++ b/board/raspberrypi/rpi/lowlevel_init.S @@ -6,15 +6,6 @@
#include <config.h>
-.align 8 -.global fw_dtb_pointer -fw_dtb_pointer: -#ifdef CONFIG_ARM64 - .dword 0x0 -#else - .word 0x0 -#endif - /* * Routine: save_boot_params (called after reset from start.S) * Description: save ATAG/FDT address provided by the firmware at boot time @@ -28,7 +19,8 @@ save_boot_params: adr x8, fw_dtb_pointer str x0, [x8] #else - str r2, fw_dtb_pointer + ldr r8, =fw_dtb_pointer + str r2, [r8] #endif
/* Returns */ diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c index 9e0abdda31..0e05d59e1f 100644 --- a/board/raspberrypi/rpi/rpi.c +++ b/board/raspberrypi/rpi/rpi.c @@ -27,8 +27,8 @@
DECLARE_GLOBAL_DATA_PTR;
-/* From lowlevel_init.S */ -extern unsigned long fw_dtb_pointer; +/* Assigned in lowlevel_init.S */ +unsigned long fw_dtb_pointer = 0x1;
/* TODO(sjg@chromium.org): Move these to the msg.c file */ struct msg_get_arm_mem {

On 12.11.19 13:00, matthias.bgg@kernel.org wrote:
From: Matthias Brugger mbrugger@suse.com
The fw_dtb_pointer was defined in the assembly code, which makes him live in section .text_rest Put that's not necessary, we can push the variable in the .data section.
This will prevent relocation errors like: board/raspberrypi/rpi/rpi.c:317:(.text.board_get_usable_ram_top+0x8): relocation truncated to fit: R_AARCH64_LDST64_ABS_LO12_NC against symbol `fw_dtb_pointer' defined in .text section in board/raspberrypi/rpi/built-in.o
Signed-off-by: Matthias Brugger mbrugger@suse.com
Changes in v3:
- fix armv7 build
Changes in v2:
push fw_dtb_pointer into the .data section
board/raspberrypi/rpi/lowlevel_init.S | 12 ++---------- board/raspberrypi/rpi/rpi.c | 4 ++-- 2 files changed, 4 insertions(+), 12 deletions(-)
diff --git a/board/raspberrypi/rpi/lowlevel_init.S b/board/raspberrypi/rpi/lowlevel_init.S index 435eed521f..8c39b3e12e 100644 --- a/board/raspberrypi/rpi/lowlevel_init.S +++ b/board/raspberrypi/rpi/lowlevel_init.S @@ -6,15 +6,6 @@
#include <config.h>
-.align 8 -.global fw_dtb_pointer -fw_dtb_pointer: -#ifdef CONFIG_ARM64
- .dword 0x0
-#else
- .word 0x0
-#endif
- /*
- Routine: save_boot_params (called after reset from start.S)
- Description: save ATAG/FDT address provided by the firmware at boot time
@@ -28,7 +19,8 @@ save_boot_params: adr x8, fw_dtb_pointer str x0, [x8] #else
- str r2, fw_dtb_pointer
ldr r8, =fw_dtb_pointer
str r2, [r8] #endif
/* Returns */
diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c index 9e0abdda31..0e05d59e1f 100644 --- a/board/raspberrypi/rpi/rpi.c +++ b/board/raspberrypi/rpi/rpi.c @@ -27,8 +27,8 @@
DECLARE_GLOBAL_DATA_PTR;
-/* From lowlevel_init.S */ -extern unsigned long fw_dtb_pointer; +/* Assigned in lowlevel_init.S */ +unsigned long fw_dtb_pointer = 0x1;
I assume you assign the 0x1 here so that it doesn't land in .bss which may get cleared after you wrote it? If so, please document that in the comment. Also even better yet, document it in a comment and just manually assign the variable to the ".data" section using
__attribute__((section(".data")))
Alex

On 12/11/2019 13:20, Alexander Graf wrote:
On 12.11.19 13:00, matthias.bgg@kernel.org wrote:
From: Matthias Brugger mbrugger@suse.com
The fw_dtb_pointer was defined in the assembly code, which makes him live in section .text_rest Put that's not necessary, we can push the variable in the .data section.
This will prevent relocation errors like: board/raspberrypi/rpi/rpi.c:317:(.text.board_get_usable_ram_top+0x8): relocation truncated to fit: R_AARCH64_LDST64_ABS_LO12_NC against symbol `fw_dtb_pointer' defined in .text section in board/raspberrypi/rpi/built-in.o
Signed-off-by: Matthias Brugger mbrugger@suse.com
Changes in v3:
- fix armv7 build
Changes in v2:
- push fw_dtb_pointer into the .data section
board/raspberrypi/rpi/lowlevel_init.S | 12 ++---------- board/raspberrypi/rpi/rpi.c | 4 ++-- 2 files changed, 4 insertions(+), 12 deletions(-)
diff --git a/board/raspberrypi/rpi/lowlevel_init.S b/board/raspberrypi/rpi/lowlevel_init.S index 435eed521f..8c39b3e12e 100644 --- a/board/raspberrypi/rpi/lowlevel_init.S +++ b/board/raspberrypi/rpi/lowlevel_init.S @@ -6,15 +6,6 @@ #include <config.h> -.align 8 -.global fw_dtb_pointer -fw_dtb_pointer: -#ifdef CONFIG_ARM64 - .dword 0x0 -#else - .word 0x0 -#endif
/* * Routine: save_boot_params (called after reset from start.S) * Description: save ATAG/FDT address provided by the firmware at boot time @@ -28,7 +19,8 @@ save_boot_params: adr x8, fw_dtb_pointer str x0, [x8] #else - str r2, fw_dtb_pointer + ldr r8, =fw_dtb_pointer + str r2, [r8] #endif /* Returns */ diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c index 9e0abdda31..0e05d59e1f 100644 --- a/board/raspberrypi/rpi/rpi.c +++ b/board/raspberrypi/rpi/rpi.c @@ -27,8 +27,8 @@ DECLARE_GLOBAL_DATA_PTR; -/* From lowlevel_init.S */ -extern unsigned long fw_dtb_pointer; +/* Assigned in lowlevel_init.S */ +unsigned long fw_dtb_pointer = 0x1;
I assume you assign the 0x1 here so that it doesn't land in .bss which may get cleared after you wrote it? If so, please document that in the comment. Also
Yes exactly.
even better yet, document it in a comment and just manually assign the variable to the ".data" section using
__attribute__((section(".data")))
Agree that's a cleaner approach then adding any random value to the pointer.
Regards, Matthias

From: Matthias Brugger mbrugger@suse.com
We move the per SOC define BCM283x_BASE to a global variable. This is a first step to provide a single binary for several bcm283x SoCs.
Signed-off-by: Matthias Brugger mbrugger@suse.com
---
Changes in v3: None Changes in v2: - fix register access in reset_cpu()
arch/arm/mach-bcm283x/include/mach/base.h | 11 +++++++++++ arch/arm/mach-bcm283x/include/mach/mbox.h | 4 +++- arch/arm/mach-bcm283x/include/mach/sdhci.h | 5 ++++- arch/arm/mach-bcm283x/include/mach/timer.h | 7 ++++++- arch/arm/mach-bcm283x/include/mach/wdog.h | 5 ++++- arch/arm/mach-bcm283x/init.c | 8 ++++++++ arch/arm/mach-bcm283x/mbox.c | 1 + arch/arm/mach-bcm283x/reset.c | 20 +++++++++++++++----- include/configs/rpi.h | 4 ++++ 9 files changed, 56 insertions(+), 9 deletions(-) create mode 100644 arch/arm/mach-bcm283x/include/mach/base.h
diff --git a/arch/arm/mach-bcm283x/include/mach/base.h b/arch/arm/mach-bcm283x/include/mach/base.h new file mode 100644 index 0000000000..c4ae39852f --- /dev/null +++ b/arch/arm/mach-bcm283x/include/mach/base.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * (C) Copyright 2019 Matthias Brugger + */ + +#ifndef _BCM283x_BASE_H_ +#define _BCM283x_BASE_H_ + +extern unsigned long rpi_bcm283x_base; + +#endif diff --git a/arch/arm/mach-bcm283x/include/mach/mbox.h b/arch/arm/mach-bcm283x/include/mach/mbox.h index 0b6c2543d5..60e226ce1d 100644 --- a/arch/arm/mach-bcm283x/include/mach/mbox.h +++ b/arch/arm/mach-bcm283x/include/mach/mbox.h @@ -7,6 +7,7 @@ #define _BCM2835_MBOX_H
#include <linux/compiler.h> +#include <asm/arch/base.h>
/* * The BCM2835 SoC contains (at least) two CPUs; the VideoCore (a/k/a "GPU") @@ -37,7 +38,8 @@
/* Raw mailbox HW */
-#define BCM2835_MBOX_PHYSADDR (CONFIG_BCM283x_BASE + 0x0000b880) +#define BCM2835_MBOX_PHYSADDR ({ BUG_ON(!rpi_bcm283x_base); \ + rpi_bcm283x_base + 0x0000b880; })
struct bcm2835_mbox_regs { u32 read; diff --git a/arch/arm/mach-bcm283x/include/mach/sdhci.h b/arch/arm/mach-bcm283x/include/mach/sdhci.h index b443c379d8..7323690687 100644 --- a/arch/arm/mach-bcm283x/include/mach/sdhci.h +++ b/arch/arm/mach-bcm283x/include/mach/sdhci.h @@ -6,7 +6,10 @@ #ifndef _BCM2835_SDHCI_H_ #define _BCM2835_SDHCI_H_
-#define BCM2835_SDHCI_BASE (CONFIG_BCM283x_BASE + 0x00300000) +#include <asm/arch/base.h> + +#define BCM2835_SDHCI_PHYSADDR ({ BUG_ON(!rpi_bcm283x_base); \ + rpi_bcm283x_base + 0x00300000; })
int bcm2835_sdhci_init(u32 regbase, u32 emmc_freq);
diff --git a/arch/arm/mach-bcm283x/include/mach/timer.h b/arch/arm/mach-bcm283x/include/mach/timer.h index 61beb1aba1..01c0ebad64 100644 --- a/arch/arm/mach-bcm283x/include/mach/timer.h +++ b/arch/arm/mach-bcm283x/include/mach/timer.h @@ -6,7 +6,12 @@ #ifndef _BCM2835_TIMER_H #define _BCM2835_TIMER_H
-#define BCM2835_TIMER_PHYSADDR (CONFIG_BCM283x_BASE + 0x00003000) +#ifndef __ASSEMBLY__ +#include <asm/arch/base.h> +#endif + +#define BCM2835_TIMER_PHYSADDR ({ BUG_ON(!rpi_bcm283x_base); \ + rpi_bcm283x_base + 0x00003000; })
#define BCM2835_TIMER_CS_M3 (1 << 3) #define BCM2835_TIMER_CS_M2 (1 << 2) diff --git a/arch/arm/mach-bcm283x/include/mach/wdog.h b/arch/arm/mach-bcm283x/include/mach/wdog.h index 8292b3cf1f..9942666720 100644 --- a/arch/arm/mach-bcm283x/include/mach/wdog.h +++ b/arch/arm/mach-bcm283x/include/mach/wdog.h @@ -6,7 +6,10 @@ #ifndef _BCM2835_WDOG_H #define _BCM2835_WDOG_H
-#define BCM2835_WDOG_PHYSADDR (CONFIG_BCM283x_BASE + 0x00100000) +#include <asm/arch/base.h> + +#define BCM2835_WDOG_PHYSADDR ({ BUG_ON(!rpi_bcm283x_base); \ + rpi_bcm283x_base + 0x00100000; })
struct bcm2835_wdog_regs { u32 unknown0[7]; diff --git a/arch/arm/mach-bcm283x/init.c b/arch/arm/mach-bcm283x/init.c index 97414415a6..d36017e823 100644 --- a/arch/arm/mach-bcm283x/init.c +++ b/arch/arm/mach-bcm283x/init.c @@ -8,6 +8,8 @@
#include <common.h>
+unsigned long rpi_bcm283x_base; + int arch_cpu_init(void) { icache_enable(); @@ -15,6 +17,12 @@ int arch_cpu_init(void) return 0; }
+int mach_cpu_init(void) +{ + rpi_bcm283x_base = CONFIG_BCM283x_BASE; + + return 0; +} #ifdef CONFIG_ARMV7_LPAE void enable_caches(void) { diff --git a/arch/arm/mach-bcm283x/mbox.c b/arch/arm/mach-bcm283x/mbox.c index 3c67f68c17..467d0d5fba 100644 --- a/arch/arm/mach-bcm283x/mbox.c +++ b/arch/arm/mach-bcm283x/mbox.c @@ -5,6 +5,7 @@
#include <common.h> #include <asm/io.h> +#include <asm/arch/base.h> #include <asm/arch/mbox.h> #include <phys2bus.h>
diff --git a/arch/arm/mach-bcm283x/reset.c b/arch/arm/mach-bcm283x/reset.c index b3da0c7cd6..cd8138d702 100644 --- a/arch/arm/mach-bcm283x/reset.c +++ b/arch/arm/mach-bcm283x/reset.c @@ -8,6 +8,7 @@
#include <common.h> #include <asm/io.h> +#include <asm/arch/base.h> #include <asm/arch/wdog.h> #include <efi_loader.h>
@@ -25,10 +26,10 @@
void hw_watchdog_disable(void) {}
-__efi_runtime_data struct bcm2835_wdog_regs *wdog_regs = - (struct bcm2835_wdog_regs *)BCM2835_WDOG_PHYSADDR; +__efi_runtime_data struct bcm2835_wdog_regs *wdog_regs;
-void __efi_runtime reset_cpu(ulong ticks) +static void __efi_runtime +__reset_cpu(struct bcm2835_wdog_regs *wdog_regs, ulong ticks) { uint32_t rstc, timeout;
@@ -46,6 +47,14 @@ void __efi_runtime reset_cpu(ulong ticks) writel(BCM2835_WDOG_PASSWORD | rstc, &wdog_regs->rstc); }
+void reset_cpu(ulong ticks) +{ + struct bcm2835_wdog_regs *regs = + (struct bcm2835_wdog_regs *)BCM2835_WDOG_PHYSADDR; + + __reset_cpu(regs, 0); +} + #ifdef CONFIG_EFI_LOADER
void __efi_runtime EFIAPI efi_reset_system( @@ -58,7 +67,7 @@ void __efi_runtime EFIAPI efi_reset_system( if (reset_type == EFI_RESET_COLD || reset_type == EFI_RESET_WARM || reset_type == EFI_RESET_PLATFORM_SPECIFIC) { - reset_cpu(0); + __reset_cpu(wdog_regs, 0); } else if (reset_type == EFI_RESET_SHUTDOWN) { /* * We set the watchdog hard reset bit here to distinguish this reset @@ -69,7 +78,7 @@ void __efi_runtime EFIAPI efi_reset_system( val |= BCM2835_WDOG_PASSWORD; val |= BCM2835_WDOG_RSTS_RASPBERRYPI_HALT; writel(val, &wdog_regs->rsts); - reset_cpu(0); + __reset_cpu(wdog_regs, 0); }
while (1) { } @@ -77,6 +86,7 @@ void __efi_runtime EFIAPI efi_reset_system(
efi_status_t efi_reset_system_init(void) { + wdog_regs = (struct bcm2835_wdog_regs *)BCM2835_WDOG_PHYSADDR; return efi_add_runtime_mmio(&wdog_regs, sizeof(*wdog_regs)); }
diff --git a/include/configs/rpi.h b/include/configs/rpi.h index 77d2d5458a..69b09f3f72 100644 --- a/include/configs/rpi.h +++ b/include/configs/rpi.h @@ -9,6 +9,10 @@ #include <linux/sizes.h> #include <asm/arch/timer.h>
+#ifndef __ASSEMBLY__ +#include <asm/arch/base.h> +#endif + #if defined(CONFIG_TARGET_RPI_2) || defined(CONFIG_TARGET_RPI_3_32B) #define CONFIG_SKIP_LOWLEVEL_INIT #endif

From: Matthias Brugger mbrugger@suse.com
As part of the effort to create one binary for several bcm83x SoCs we use the SoC compatible to decide which IO base address we use.
Signed-off-by: Matthias Brugger mbrugger@suse.com
---
Changes in v3: None Changes in v2: - rename BCM2838 to BCM2711 in the correct patch - push rpi_bcm283x_base into the .data section
arch/arm/mach-bcm283x/Kconfig | 6 ---- arch/arm/mach-bcm283x/init.c | 62 +++++++++++++++++++++++++++++++++-- 2 files changed, 60 insertions(+), 8 deletions(-)
diff --git a/arch/arm/mach-bcm283x/Kconfig b/arch/arm/mach-bcm283x/Kconfig index b08275f598..e8e0ff0eb4 100644 --- a/arch/arm/mach-bcm283x/Kconfig +++ b/arch/arm/mach-bcm283x/Kconfig @@ -202,10 +202,4 @@ config SYS_SOC config SYS_CONFIG_NAME default "rpi"
-config BCM283x_BASE - hex - default "0x20000000" if BCM2835 - default "0x3f000000" if BCM2836 || BCM2837 - default "0xfe000000" if BCM2711 - endmenu diff --git a/arch/arm/mach-bcm283x/init.c b/arch/arm/mach-bcm283x/init.c index d36017e823..d374fb60ba 100644 --- a/arch/arm/mach-bcm283x/init.c +++ b/arch/arm/mach-bcm283x/init.c @@ -7,8 +7,48 @@ */
#include <common.h> +#include <dm/device.h>
-unsigned long rpi_bcm283x_base; +#define PDATA_BCM2835 0 +#define PDATA_BCM2836 1 +#define PDATA_BCM2837 2 +#define PDATA_BCM2711 3 + +unsigned long rpi_bcm283x_base = 0x3f000000; + +struct bcm283x_pdata { + unsigned long io_base; +}; + +struct bcm283x_pdata pdata_bcm283x[] = { + [PDATA_BCM2835] = { + .io_base = 0x20000000, + }, + [PDATA_BCM2836] = { + .io_base = 0x3f000000, + }, +#ifdef CONFIG_ARM64 + [PDATA_BCM2837] = { + .io_base = 0x3f000000, + }, + [PDATA_BCM2711] = { + .io_base = 0xfe000000, + }, +#endif +}; + +/* + * I/O address space varies on different chip versions. + * We set the base address by inspecting the DTB. + */ +static const struct udevice_id board_ids[] = { + { .compatible = "brcm,bcm2835", .data = PDATA_BCM2835}, + { .compatible = "brcm,bcm2836", .data = PDATA_BCM2836}, + { .compatible = "brcm,bcm2837", .data = PDATA_BCM2837}, + { .compatible = "brcm,bcm2838", .data = PDATA_BCM2711}, + { .compatible = "brcm,bcm2711", .data = PDATA_BCM2711}, + { }, +};
int arch_cpu_init(void) { @@ -19,10 +59,28 @@ int arch_cpu_init(void)
int mach_cpu_init(void) { - rpi_bcm283x_base = CONFIG_BCM283x_BASE; + const struct udevice_id *of_match = board_ids; + int ret; + + rpi_bcm283x_base = 0; + + while (of_match->compatible) { + struct bcm283x_pdata pdat; + + ret = fdt_node_check_compatible(gd->fdt_blob, 0, + of_match->compatible); + if (!ret) { + pdat = pdata_bcm283x[of_match->data]; + rpi_bcm283x_base = pdat.io_base; + break; + } + + of_match++; + }
return 0; } + #ifdef CONFIG_ARMV7_LPAE void enable_caches(void) {

On 12.11.19 13:00, matthias.bgg@kernel.org wrote:
From: Matthias Brugger mbrugger@suse.com
As part of the effort to create one binary for several bcm83x SoCs we use the SoC compatible to decide which IO base address we use.
Signed-off-by: Matthias Brugger mbrugger@suse.com
Is there any reason we can't just base on the ranges property of the /soc node instead? That way we don't duplicate the base offset all over the place.
Alex
Changes in v3: None Changes in v2:
rename BCM2838 to BCM2711 in the correct patch
push rpi_bcm283x_base into the .data section
arch/arm/mach-bcm283x/Kconfig | 6 ---- arch/arm/mach-bcm283x/init.c | 62 +++++++++++++++++++++++++++++++++-- 2 files changed, 60 insertions(+), 8 deletions(-)
diff --git a/arch/arm/mach-bcm283x/Kconfig b/arch/arm/mach-bcm283x/Kconfig index b08275f598..e8e0ff0eb4 100644 --- a/arch/arm/mach-bcm283x/Kconfig +++ b/arch/arm/mach-bcm283x/Kconfig @@ -202,10 +202,4 @@ config SYS_SOC config SYS_CONFIG_NAME default "rpi"
-config BCM283x_BASE
- hex
- default "0x20000000" if BCM2835
- default "0x3f000000" if BCM2836 || BCM2837
- default "0xfe000000" if BCM2711
- endmenu
diff --git a/arch/arm/mach-bcm283x/init.c b/arch/arm/mach-bcm283x/init.c index d36017e823..d374fb60ba 100644 --- a/arch/arm/mach-bcm283x/init.c +++ b/arch/arm/mach-bcm283x/init.c @@ -7,8 +7,48 @@ */
#include <common.h> +#include <dm/device.h>
-unsigned long rpi_bcm283x_base; +#define PDATA_BCM2835 0 +#define PDATA_BCM2836 1 +#define PDATA_BCM2837 2 +#define PDATA_BCM2711 3
+unsigned long rpi_bcm283x_base = 0x3f000000;
+struct bcm283x_pdata {
- unsigned long io_base;
+};
+struct bcm283x_pdata pdata_bcm283x[] = {
- [PDATA_BCM2835] = {
.io_base = 0x20000000,
- },
- [PDATA_BCM2836] = {
.io_base = 0x3f000000,
- },
+#ifdef CONFIG_ARM64
- [PDATA_BCM2837] = {
.io_base = 0x3f000000,
- },
- [PDATA_BCM2711] = {
.io_base = 0xfe000000,
- },
+#endif +};
+/*
- I/O address space varies on different chip versions.
- We set the base address by inspecting the DTB.
- */
+static const struct udevice_id board_ids[] = {
- { .compatible = "brcm,bcm2835", .data = PDATA_BCM2835},
- { .compatible = "brcm,bcm2836", .data = PDATA_BCM2836},
- { .compatible = "brcm,bcm2837", .data = PDATA_BCM2837},
- { .compatible = "brcm,bcm2838", .data = PDATA_BCM2711},
- { .compatible = "brcm,bcm2711", .data = PDATA_BCM2711},
- { },
+};
int arch_cpu_init(void) { @@ -19,10 +59,28 @@ int arch_cpu_init(void)
int mach_cpu_init(void) {
- rpi_bcm283x_base = CONFIG_BCM283x_BASE;
const struct udevice_id *of_match = board_ids;
int ret;
rpi_bcm283x_base = 0;
while (of_match->compatible) {
struct bcm283x_pdata pdat;
ret = fdt_node_check_compatible(gd->fdt_blob, 0,
of_match->compatible);
if (!ret) {
pdat = pdata_bcm283x[of_match->data];
rpi_bcm283x_base = pdat.io_base;
break;
}
of_match++;
}
return 0; }
#ifdef CONFIG_ARMV7_LPAE void enable_caches(void) {

From: Matthias Brugger mbrugger@suse.com
For bcm283x based on arm64 we also have to change the mm_region. Add assign this in mach_cpu_init() so we can create now one binary for RPi3 and RPi4.
Signed-off-by: Matthias Brugger mbrugger@suse.com
---
Changes in v3: None Changes in v2: - Move mem_map out of assembly file - push mem_map into the .data section - update the members of mem_map inestead of the pointer
arch/arm/mach-bcm283x/init.c | 74 ++++++++++++++++++++++++++++++++++++ board/raspberrypi/rpi/rpi.c | 45 ---------------------- 2 files changed, 74 insertions(+), 45 deletions(-)
diff --git a/arch/arm/mach-bcm283x/init.c b/arch/arm/mach-bcm283x/init.c index d374fb60ba..639a5cf975 100644 --- a/arch/arm/mach-bcm283x/init.c +++ b/arch/arm/mach-bcm283x/init.c @@ -8,6 +8,9 @@
#include <common.h> #include <dm/device.h> +#ifdef CONFIG_ARM64 +#include <asm/armv8/mmu.h> +#endif
#define PDATA_BCM2835 0 #define PDATA_BCM2836 1 @@ -16,23 +19,77 @@
unsigned long rpi_bcm283x_base = 0x3f000000;
+#ifdef CONFIG_ARM64 +static struct mm_region bcm283x_mem_map[] = { + { + .virt = 0x00000000UL, + .phys = 0x00000000UL, + .size = 0x3f000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE + }, { + .virt = 0x3f000000UL, + .phys = 0x3f000000UL, + .size = 0x01000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* List terminator */ + 0, + } +}; + +static struct mm_region bcm2711_mem_map[] = { + { + .virt = 0x00000000UL, + .phys = 0x00000000UL, + .size = 0xfe000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE + }, { + .virt = 0xfe000000UL, + .phys = 0xfe000000UL, + .size = 0x01800000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* List terminator */ + 0, + } +}; + +struct mm_region *mem_map = bcm283x_mem_map; + +#else +struct mm_region { + /* dummy struct */ +}; +#endif + struct bcm283x_pdata { unsigned long io_base; + struct mm_region *m_map; };
struct bcm283x_pdata pdata_bcm283x[] = { [PDATA_BCM2835] = { .io_base = 0x20000000, + .m_map = NULL, }, [PDATA_BCM2836] = { .io_base = 0x3f000000, + .m_map = NULL, }, #ifdef CONFIG_ARM64 [PDATA_BCM2837] = { .io_base = 0x3f000000, + .m_map = bcm283x_mem_map, }, [PDATA_BCM2711] = { .io_base = 0xfe000000, + .m_map = bcm2711_mem_map }, #endif }; @@ -57,6 +114,22 @@ int arch_cpu_init(void) return 0; }
+#ifdef CONFIG_ARM64 +static void rpi_updated_mem_map(struct mm_region *pd) +{ + int i; + + for (i = 0; i < 2; i++) { + mem_map[i].virt = pd[i].virt; + mem_map[i].phys = pd[i].phys; + mem_map[i].size = pd[i].size; + mem_map[i].attrs = pd[i].attrs; + } +} +#else +static void rpi_updated_mem_map(struct mm_region *pd) {} +#endif + int mach_cpu_init(void) { const struct udevice_id *of_match = board_ids; @@ -72,6 +145,7 @@ int mach_cpu_init(void) if (!ret) { pdat = pdata_bcm283x[of_match->data]; rpi_bcm283x_base = pdat.io_base; + rpi_updated_mem_map(pdat.m_map); break; }
diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c index 0e05d59e1f..248d04bfd2 100644 --- a/board/raspberrypi/rpi/rpi.c +++ b/board/raspberrypi/rpi/rpi.c @@ -248,51 +248,6 @@ static uint32_t rev_scheme; static uint32_t rev_type; static const struct rpi_model *model;
-#ifdef CONFIG_ARM64 -#ifndef CONFIG_BCM2711 -static struct mm_region bcm283x_mem_map[] = { - { - .virt = 0x00000000UL, - .phys = 0x00000000UL, - .size = 0x3f000000UL, - .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | - PTE_BLOCK_INNER_SHARE - }, { - .virt = 0x3f000000UL, - .phys = 0x3f000000UL, - .size = 0x01000000UL, - .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | - PTE_BLOCK_NON_SHARE | - PTE_BLOCK_PXN | PTE_BLOCK_UXN - }, { - /* List terminator */ - 0, - } -}; -#else -static struct mm_region bcm283x_mem_map[] = { - { - .virt = 0x00000000UL, - .phys = 0x00000000UL, - .size = 0xfe000000UL, - .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | - PTE_BLOCK_INNER_SHARE - }, { - .virt = 0xfe000000UL, - .phys = 0xfe000000UL, - .size = 0x01800000UL, - .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | - PTE_BLOCK_NON_SHARE | - PTE_BLOCK_PXN | PTE_BLOCK_UXN - }, { - /* List terminator */ - 0, - } -}; -#endif -struct mm_region *mem_map = bcm283x_mem_map; -#endif - int dram_init(void) { ALLOC_CACHE_ALIGN_BUFFER(struct msg_get_arm_mem, msg, 1);

On 12.11.19 13:00, matthias.bgg@kernel.org wrote:
From: Matthias Brugger mbrugger@suse.com
For bcm283x based on arm64 we also have to change the mm_region. Add assign this in mach_cpu_init() so we can create now one binary for RPi3 and RPi4.
Signed-off-by: Matthias Brugger mbrugger@suse.com
For the future, can you think of a reason why we could not always generate the map at runtime?
Alex
Changes in v3: None Changes in v2:
Move mem_map out of assembly file
push mem_map into the .data section
update the members of mem_map inestead of the pointer
arch/arm/mach-bcm283x/init.c | 74 ++++++++++++++++++++++++++++++++++++ board/raspberrypi/rpi/rpi.c | 45 ---------------------- 2 files changed, 74 insertions(+), 45 deletions(-)
diff --git a/arch/arm/mach-bcm283x/init.c b/arch/arm/mach-bcm283x/init.c index d374fb60ba..639a5cf975 100644 --- a/arch/arm/mach-bcm283x/init.c +++ b/arch/arm/mach-bcm283x/init.c @@ -8,6 +8,9 @@
#include <common.h> #include <dm/device.h> +#ifdef CONFIG_ARM64 +#include <asm/armv8/mmu.h> +#endif
#define PDATA_BCM2835 0 #define PDATA_BCM2836 1 @@ -16,23 +19,77 @@
unsigned long rpi_bcm283x_base = 0x3f000000;
+#ifdef CONFIG_ARM64 +static struct mm_region bcm283x_mem_map[] = {
- {
.virt = 0x00000000UL,
.phys = 0x00000000UL,
.size = 0x3f000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
- }, {
.virt = 0x3f000000UL,
.phys = 0x3f000000UL,
.size = 0x01000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
- }, {
/* List terminator */
0,
- }
+};
+static struct mm_region bcm2711_mem_map[] = {
- {
.virt = 0x00000000UL,
.phys = 0x00000000UL,
.size = 0xfe000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
- }, {
.virt = 0xfe000000UL,
.phys = 0xfe000000UL,
.size = 0x01800000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
- }, {
/* List terminator */
0,
- }
+};
+struct mm_region *mem_map = bcm283x_mem_map;
+#else +struct mm_region {
- /* dummy struct */
+}; +#endif
struct bcm283x_pdata { unsigned long io_base;
struct mm_region *m_map; };
struct bcm283x_pdata pdata_bcm283x[] = { [PDATA_BCM2835] = { .io_base = 0x20000000,
.m_map = NULL,
}, [PDATA_BCM2836] = { .io_base = 0x3f000000,
.m_map = NULL,
}, #ifdef CONFIG_ARM64 [PDATA_BCM2837] = { .io_base = 0x3f000000,
.m_map = bcm283x_mem_map,
}, [PDATA_BCM2711] = { .io_base = 0xfe000000,
.m_map = bcm2711_mem_map
}, #endif };
@@ -57,6 +114,22 @@ int arch_cpu_init(void) return 0; }
+#ifdef CONFIG_ARM64 +static void rpi_updated_mem_map(struct mm_region *pd) +{
- int i;
- for (i = 0; i < 2; i++) {
mem_map[i].virt = pd[i].virt;
mem_map[i].phys = pd[i].phys;
mem_map[i].size = pd[i].size;
mem_map[i].attrs = pd[i].attrs;
- }
+} +#else +static void rpi_updated_mem_map(struct mm_region *pd) {} +#endif
- int mach_cpu_init(void) { const struct udevice_id *of_match = board_ids;
@@ -72,6 +145,7 @@ int mach_cpu_init(void) if (!ret) { pdat = pdata_bcm283x[of_match->data]; rpi_bcm283x_base = pdat.io_base;
}rpi_updated_mem_map(pdat.m_map); break;
diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c index 0e05d59e1f..248d04bfd2 100644 --- a/board/raspberrypi/rpi/rpi.c +++ b/board/raspberrypi/rpi/rpi.c @@ -248,51 +248,6 @@ static uint32_t rev_scheme; static uint32_t rev_type; static const struct rpi_model *model;
-#ifdef CONFIG_ARM64 -#ifndef CONFIG_BCM2711 -static struct mm_region bcm283x_mem_map[] = {
- {
.virt = 0x00000000UL,
.phys = 0x00000000UL,
.size = 0x3f000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
- }, {
.virt = 0x3f000000UL,
.phys = 0x3f000000UL,
.size = 0x01000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
- }, {
/* List terminator */
0,
- }
-}; -#else -static struct mm_region bcm283x_mem_map[] = {
- {
.virt = 0x00000000UL,
.phys = 0x00000000UL,
.size = 0xfe000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
- }, {
.virt = 0xfe000000UL,
.phys = 0xfe000000UL,
.size = 0x01800000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
- }, {
/* List terminator */
0,
- }
-}; -#endif -struct mm_region *mem_map = bcm283x_mem_map; -#endif
- int dram_init(void) { ALLOC_CACHE_ALIGN_BUFFER(struct msg_get_arm_mem, msg, 1);

On 13/11/2019 11:44, Alexander Graf wrote:
On 12.11.19 13:00, matthias.bgg@kernel.org wrote:
From: Matthias Brugger mbrugger@suse.com
For bcm283x based on arm64 we also have to change the mm_region. Add assign this in mach_cpu_init() so we can create now one binary for RPi3 and RPi4.
Signed-off-by: Matthias Brugger mbrugger@suse.com
For the future, can you think of a reason why we could not always generate the map at runtime?
The only reason I can think of, is that the core of U-Boot changes so that mach_cpu_init() would be too late. But in this case we would only need to update the mem_map earlier, which shouldn't be an issue.
Regards, Matthias
Alex
Changes in v3: None Changes in v2:
- Move mem_map out of assembly file
- push mem_map into the .data section
- update the members of mem_map inestead of the pointer
arch/arm/mach-bcm283x/init.c | 74 ++++++++++++++++++++++++++++++++++++ board/raspberrypi/rpi/rpi.c | 45 ---------------------- 2 files changed, 74 insertions(+), 45 deletions(-)
diff --git a/arch/arm/mach-bcm283x/init.c b/arch/arm/mach-bcm283x/init.c index d374fb60ba..639a5cf975 100644 --- a/arch/arm/mach-bcm283x/init.c +++ b/arch/arm/mach-bcm283x/init.c @@ -8,6 +8,9 @@ #include <common.h> #include <dm/device.h> +#ifdef CONFIG_ARM64 +#include <asm/armv8/mmu.h> +#endif #define PDATA_BCM2835 0 #define PDATA_BCM2836 1 @@ -16,23 +19,77 @@ unsigned long rpi_bcm283x_base = 0x3f000000; +#ifdef CONFIG_ARM64 +static struct mm_region bcm283x_mem_map[] = { + { + .virt = 0x00000000UL, + .phys = 0x00000000UL, + .size = 0x3f000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE + }, { + .virt = 0x3f000000UL, + .phys = 0x3f000000UL, + .size = 0x01000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* List terminator */ + 0, + } +};
+static struct mm_region bcm2711_mem_map[] = { + { + .virt = 0x00000000UL, + .phys = 0x00000000UL, + .size = 0xfe000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE + }, { + .virt = 0xfe000000UL, + .phys = 0xfe000000UL, + .size = 0x01800000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* List terminator */ + 0, + } +};
+struct mm_region *mem_map = bcm283x_mem_map;
+#else +struct mm_region { + /* dummy struct */ +}; +#endif
struct bcm283x_pdata { unsigned long io_base; + struct mm_region *m_map; }; struct bcm283x_pdata pdata_bcm283x[] = { [PDATA_BCM2835] = { .io_base = 0x20000000, + .m_map = NULL, }, [PDATA_BCM2836] = { .io_base = 0x3f000000, + .m_map = NULL, }, #ifdef CONFIG_ARM64 [PDATA_BCM2837] = { .io_base = 0x3f000000, + .m_map = bcm283x_mem_map, }, [PDATA_BCM2711] = { .io_base = 0xfe000000, + .m_map = bcm2711_mem_map }, #endif }; @@ -57,6 +114,22 @@ int arch_cpu_init(void) return 0; } +#ifdef CONFIG_ARM64 +static void rpi_updated_mem_map(struct mm_region *pd) +{ + int i;
+ for (i = 0; i < 2; i++) { + mem_map[i].virt = pd[i].virt; + mem_map[i].phys = pd[i].phys; + mem_map[i].size = pd[i].size; + mem_map[i].attrs = pd[i].attrs; + } +} +#else +static void rpi_updated_mem_map(struct mm_region *pd) {} +#endif
int mach_cpu_init(void) { const struct udevice_id *of_match = board_ids; @@ -72,6 +145,7 @@ int mach_cpu_init(void) if (!ret) { pdat = pdata_bcm283x[of_match->data]; rpi_bcm283x_base = pdat.io_base; + rpi_updated_mem_map(pdat.m_map); break; } diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c index 0e05d59e1f..248d04bfd2 100644 --- a/board/raspberrypi/rpi/rpi.c +++ b/board/raspberrypi/rpi/rpi.c @@ -248,51 +248,6 @@ static uint32_t rev_scheme; static uint32_t rev_type; static const struct rpi_model *model; -#ifdef CONFIG_ARM64 -#ifndef CONFIG_BCM2711 -static struct mm_region bcm283x_mem_map[] = { - { - .virt = 0x00000000UL, - .phys = 0x00000000UL, - .size = 0x3f000000UL, - .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | - PTE_BLOCK_INNER_SHARE - }, { - .virt = 0x3f000000UL, - .phys = 0x3f000000UL, - .size = 0x01000000UL, - .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | - PTE_BLOCK_NON_SHARE | - PTE_BLOCK_PXN | PTE_BLOCK_UXN - }, { - /* List terminator */ - 0, - } -}; -#else -static struct mm_region bcm283x_mem_map[] = { - { - .virt = 0x00000000UL, - .phys = 0x00000000UL, - .size = 0xfe000000UL, - .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | - PTE_BLOCK_INNER_SHARE - }, { - .virt = 0xfe000000UL, - .phys = 0xfe000000UL, - .size = 0x01800000UL, - .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | - PTE_BLOCK_NON_SHARE | - PTE_BLOCK_PXN | PTE_BLOCK_UXN - }, { - /* List terminator */ - 0, - } -}; -#endif -struct mm_region *mem_map = bcm283x_mem_map; -#endif
int dram_init(void) { ALLOC_CACHE_ALIGN_BUFFER(struct msg_get_arm_mem, msg, 1);
participants (3)
-
Alexander Graf
-
Matthias Brugger
-
matthias.bgg@kernel.org