[PATCH 00/40] RFC: rpi: Enable ACPI booting on ARM with Raspberry Pi 4

At present in U-Boot ACPI tables are only generated for x86 devices. It is possible to build them for ARM as well. That is the subject of this series.
The goal is to allow a rpi4 boot into Linux on ARM using ACPI rather than devicetree. This is not due to any feeling that ACPI offers advantages to the boot flow, merely because it can be done.
This goal is not yet achieved. Mostly all that is achieved is some refactoring of the ACPI code, but that is enough to get things at least building on ARM. The rpi-4 the tables are installed and the board boots to grub, where it is then unable to find the OS on the USB stick that is inserted. Further work is needed to complete things, but the ACPI changes can be applied as is.
In terms of review, please ignore the RFC/WIP patches as they need to be reworked. I am sending this series in this state to avoid sitting on patches for too long and risking duplicate effort.
The following tables are emitted with this series:
- GTDT - Generic Timer Description Table - APIC - Multiple Advanced Programmable Interrupt Controller Description Table (some new records for ARM) - DSDT - Differentiated System Description Table - DBG2 - Debug Port Table 2 - FACP - Firmware ACPI Control Structure - CSRT - Core System Resource Table - PPTT - Processor Properties Topology Table
Missing still are: - SSDR - Secondary System Description Table - BGRT - Boot Graphics Resource Table
Future work is needed to: - Finish the remaining two tables - Get things booting nicely on rpi4 - Find a nice way to select between ACPI and devicetree at runtime - Obtain the ACPI information from the devicetree instead of #defines - Use the U-Boot bcm headers instead of importing new ones - Drop the unused files - Add some documentation
To test it, boot U-Boot on a rpi_4 with a suitable distribution.
This series is available at u-boot-dm/acpi-working
Simon Glass (40): Makefile: Allow LTO to be disabled for a build x86: Allow any arch to generate ACPI tables x86: Move the acpi table to generic global_data arm: Allow supporting ACPI-table generation x86: Tidy up use of CONFIG_ACPIGEN sandbox: Allow building with GENERATE_ACPI_TABLE efi: Correct call to write_acpi_tables() efi: Correct address handling with ACPI tables acpi: Use finer-grained control of ACPI-table generation acpi: Allow include files within the board directory acpi: Move acpi_fill_header() to the generic header acpi: Add a table start acpi: Add a linker list for ACPI tables x86: acpi: Split out context creation from base tables x86: Use the ACPI table writer x86: Move base tables to a writer function x86: Move FACS table to a writer function x86: Move DSDT table to a writer function x86: Move GNVS table to a writer function x86: Move FADT table to a writer function x86: Move FACP table into separate functions x86: Move SSDT table to a writer function x86: Move TPM2 table to a writer function x86: Move MADT table to a writer function x86: Move TCPA table to a writer function x86: Move CSRT table to a writer function x86: acpi: Update acpi_fill_csrt() to use acpi_ctx x86: Move device-specific ACPI tables to a writer function x86: Move acpi_get_rsdp_addr() ACPI tables to the writer acpi: Collect tables in the acpi_item list acpi: Tidy up the item list acpi: Tidy up the table list doc: Add usage information for the acpi command acpi: Add some tables needed by ARM devices acpi: Add myself as maintainer WIP: Add debugging for ACPI emission RFC: Allow passing ACPI tables to bootefi WIP: Add ASL files from tianocore WIP: Bring in some header files from tianocore RFC: rpi: Enable booting with ACPI tables
MAINTAINERS | 6 + Makefile | 18 +- arch/Kconfig | 6 +- arch/arm/config.mk | 4 +- arch/arm/include/asm/acpi_table.h | 15 + arch/arm/include/asm/global_data.h | 2 +- .../mach-bcm283x/include/mach/acpi/bcm2711.h | 93 +++ .../mach-bcm283x/include/mach/acpi/bcm2836.h | 124 +++ .../include/mach/acpi/bcm2836_gpio.h | 85 ++ .../include/mach/acpi/bcm2836_gpu.h | 48 ++ .../include/mach/acpi/bcm2836_pwm.h | 34 + .../include/mach/acpi/bcm2836_sdhost.h | 90 ++ .../include/mach/acpi/bcm2836_sdio.h | 203 +++++ arch/sandbox/include/asm/acpi_table.h | 2 + arch/sandbox/include/asm/global_data.h | 1 - arch/sandbox/include/asm/tables.h | 0 arch/x86/Kconfig | 9 - arch/x86/cpu/apollolake/acpi.c | 17 +- arch/x86/cpu/baytrail/acpi.c | 27 +- arch/x86/cpu/quark/acpi.c | 27 +- arch/x86/cpu/tangier/acpi.c | 34 +- arch/x86/include/asm/acpi_table.h | 4 - arch/x86/include/asm/global_data.h | 1 - arch/x86/lib/Makefile | 2 +- arch/x86/lib/acpi_table.c | 374 +++------ board/raspberrypi/rpi/Makefile | 2 + board/raspberrypi/rpi/acpitables.h | 189 +++++ board/raspberrypi/rpi/acpitables.inf | 79 ++ board/raspberrypi/rpi/csrt.aslc | 330 ++++++++ board/raspberrypi/rpi/dbg2miniuart.aslc | 81 ++ board/raspberrypi/rpi/dbg2pl011.aslc | 81 ++ board/raspberrypi/rpi/dsdt.asl | 285 +++++++ board/raspberrypi/rpi/emmc.asl | 166 ++++ board/raspberrypi/rpi/fadt.aslc | 96 +++ board/raspberrypi/rpi/gpudevs.asl | 397 +++++++++ board/raspberrypi/rpi/gtdt.aslc | 55 ++ board/raspberrypi/rpi/iort.aslc | 100 +++ board/raspberrypi/rpi/madt.aslc | 78 ++ board/raspberrypi/rpi/pci.asl | 168 ++++ board/raspberrypi/rpi/pep.asl | 90 ++ board/raspberrypi/rpi/pep.c | 79 ++ board/raspberrypi/rpi/pep.h | 121 +++ board/raspberrypi/rpi/pptt.aslc | 191 +++++ board/raspberrypi/rpi/rhpx.asl | 195 +++++ board/raspberrypi/rpi/rpi.c | 460 +++++++++- board/raspberrypi/rpi/rpi4.dsc | 790 ++++++++++++++++++ board/raspberrypi/rpi/sdhc.asl | 119 +++ board/raspberrypi/rpi/spcrminiuart.aslc | 91 ++ board/raspberrypi/rpi/spcrpl011.aslc | 91 ++ board/raspberrypi/rpi/ssdtthermal.asl | 77 ++ board/raspberrypi/rpi/uart.asl | 202 +++++ board/raspberrypi/rpi/xhci.asl | 165 ++++ cmd/acpi.c | 13 +- cmd/bootefi.c | 44 +- configs/cherryhill_defconfig | 1 + configs/chromebook_link64_defconfig | 1 + configs/chromebook_link_defconfig | 1 + configs/chromebook_samus_tpl_defconfig | 1 + configs/coreboot64_defconfig | 1 + configs/coreboot_defconfig | 1 + configs/crownbay_defconfig | 1 + configs/efi-x86_payload32_defconfig | 1 + configs/efi-x86_payload64_defconfig | 1 + configs/rpi_4_defconfig | 2 + configs/slimbootloader_defconfig | 1 + configs/tools-only_defconfig | 1 + doc/build/gcc.rst | 17 + doc/usage/acpi.rst | 235 ++++++ doc/usage/index.rst | 1 + drivers/core/acpi.c | 70 +- drivers/misc/qfw.c | 3 +- include/acpi/acpi_table.h | 235 +++++- include/asm-generic/global_data.h | 8 + include/dm/acpi.h | 110 +++ lib/Kconfig | 18 + lib/Makefile | 2 +- lib/acpi/Makefile | 23 +- lib/acpi/acpi_table.c | 82 -- lib/acpi/acpi_writer.c | 132 +++ lib/acpi/base.c | 94 +++ lib/acpi/csrt.c | 49 ++ lib/acpi/dsdt.c | 55 ++ lib/acpi/facs.c | 35 + lib/acpi/ssdt.c | 49 ++ lib/efi_loader/Makefile | 2 - lib/efi_loader/efi_acpi.c | 5 +- scripts/Makefile.lib | 3 +- test/dm/acpi.c | 79 +- 88 files changed, 6875 insertions(+), 506 deletions(-) create mode 100644 arch/arm/mach-bcm283x/include/mach/acpi/bcm2711.h create mode 100644 arch/arm/mach-bcm283x/include/mach/acpi/bcm2836.h create mode 100644 arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_gpio.h create mode 100644 arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_gpu.h create mode 100644 arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_pwm.h create mode 100644 arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_sdhost.h create mode 100644 arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_sdio.h create mode 100644 arch/sandbox/include/asm/tables.h create mode 100644 board/raspberrypi/rpi/acpitables.h create mode 100644 board/raspberrypi/rpi/acpitables.inf create mode 100644 board/raspberrypi/rpi/csrt.aslc create mode 100644 board/raspberrypi/rpi/dbg2miniuart.aslc create mode 100644 board/raspberrypi/rpi/dbg2pl011.aslc create mode 100644 board/raspberrypi/rpi/dsdt.asl create mode 100644 board/raspberrypi/rpi/emmc.asl create mode 100644 board/raspberrypi/rpi/fadt.aslc create mode 100644 board/raspberrypi/rpi/gpudevs.asl create mode 100644 board/raspberrypi/rpi/gtdt.aslc create mode 100644 board/raspberrypi/rpi/iort.aslc create mode 100644 board/raspberrypi/rpi/madt.aslc create mode 100644 board/raspberrypi/rpi/pci.asl create mode 100644 board/raspberrypi/rpi/pep.asl create mode 100644 board/raspberrypi/rpi/pep.c create mode 100644 board/raspberrypi/rpi/pep.h create mode 100644 board/raspberrypi/rpi/pptt.aslc create mode 100644 board/raspberrypi/rpi/rhpx.asl create mode 100644 board/raspberrypi/rpi/rpi4.dsc create mode 100644 board/raspberrypi/rpi/sdhc.asl create mode 100644 board/raspberrypi/rpi/spcrminiuart.aslc create mode 100644 board/raspberrypi/rpi/spcrpl011.aslc create mode 100644 board/raspberrypi/rpi/ssdtthermal.asl create mode 100644 board/raspberrypi/rpi/uart.asl create mode 100644 board/raspberrypi/rpi/xhci.asl create mode 100644 doc/usage/acpi.rst create mode 100644 lib/acpi/acpi_writer.c create mode 100644 lib/acpi/base.c create mode 100644 lib/acpi/csrt.c create mode 100644 lib/acpi/dsdt.c create mode 100644 lib/acpi/facs.c create mode 100644 lib/acpi/ssdt.c

LTO (Link-Time Optimisation) is an very useful feature which can significantly reduce the size of U-Boot binaries. So far it has been made available for selected ARM boards and sandbox.
However, incremental builds are much slower when LTO is used. For example, an incremental build of sandbox takes 2.1 seconds on my machine, but 6.7 seconds with LTO enabled.
Add a LTO_BUILD=n parameter to the build, so it can be disabled during development if needed, for faster builds.
Add some documentation about LTO while we are here.
Signed-off-by: Simon Glass sjg@chromium.org ---
Makefile | 18 +++++++++++++----- arch/arm/config.mk | 4 ++-- arch/arm/include/asm/global_data.h | 2 +- doc/build/gcc.rst | 17 +++++++++++++++++ 4 files changed, 33 insertions(+), 8 deletions(-)
diff --git a/Makefile b/Makefile index 57c3643d9a8..f5ab9778495 100644 --- a/Makefile +++ b/Makefile @@ -434,6 +434,9 @@ KBUILD_CFLAGS += -fshort-wchar -fno-strict-aliasing KBUILD_AFLAGS := -D__ASSEMBLY__ KBUILD_LDFLAGS :=
+# Set this to "n" use of LTO for this build, e.g. LTO_BUILD=n +LTO_BUILD ?= y + ifeq ($(cc-name),clang) ifneq ($(CROSS_COMPILE),) CLANG_TARGET := --target=$(notdir $(CROSS_COMPILE:%-=%)) @@ -642,6 +645,11 @@ export CFLAGS_EFI # Compiler flags to add when building EFI app export CFLAGS_NON_EFI # Compiler flags to remove when building EFI app export EFI_TARGET # binutils target if EFI is natively supported
+export LTO_ENABLE + +# This is y if LTO is enabled for this build +LTO_ENABLE=$(if $(CONFIG_LTO),$(LTO_BUILD),) + # If board code explicitly specified LDSCRIPT or CONFIG_SYS_LDSCRIPT, use # that (or fail if absent). Otherwise, search for a linker script in a # standard location. @@ -689,16 +697,16 @@ endif LTO_CFLAGS := LTO_FINAL_LDFLAGS := export LTO_CFLAGS LTO_FINAL_LDFLAGS -ifdef CONFIG_LTO +ifeq ($(LTO_ENABLE),y) ifeq ($(cc-name),clang) - LTO_CFLAGS += -flto + LTO_CFLAGS += -DLTO_ENABLE -flto LTO_FINAL_LDFLAGS += -flto
AR = $(shell $(CC) -print-prog-name=llvm-ar) NM = $(shell $(CC) -print-prog-name=llvm-nm) else NPROC := $(shell nproc 2>/dev/null || echo 1) - LTO_CFLAGS += -flto=$(NPROC) + LTO_CFLAGS += -DLTO_ENABLE -flto=$(NPROC) LTO_FINAL_LDFLAGS += -fuse-linker-plugin -flto=$(NPROC)
# use plugin aware tools @@ -1721,7 +1729,7 @@ ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(ARCH)/Makefile.postlink)
# Generate linker list symbols references to force compiler to not optimize # them away when compiling with LTO -ifdef CONFIG_LTO +ifeq ($(LTO_ENABLE),y) u-boot-keep-syms-lto := keep-syms-lto.o u-boot-keep-syms-lto_c := $(patsubst %.o,%.c,$(u-boot-keep-syms-lto))
@@ -1743,7 +1751,7 @@ endif
# Rule to link u-boot # May be overridden by arch/$(ARCH)/config.mk -ifdef CONFIG_LTO +ifeq ($(LTO_ENABLE),y) quiet_cmd_u-boot__ ?= LTO $@ cmd_u-boot__ ?= \ $(CC) -nostdlib -nostartfiles \ diff --git a/arch/arm/config.mk b/arch/arm/config.mk index b107b1af27a..065dbec4064 100644 --- a/arch/arm/config.mk +++ b/arch/arm/config.mk @@ -15,11 +15,11 @@ CFLAGS_NON_EFI := -fno-pic -ffixed-r9 -ffunction-sections -fdata-sections \ -fstack-protector-strong CFLAGS_EFI := -fpic -fshort-wchar
-ifneq ($(CONFIG_LTO)$(CONFIG_USE_PRIVATE_LIBGCC),yy) +ifneq ($(LTO_ENABLE)$(CONFIG_USE_PRIVATE_LIBGCC),yy) LDFLAGS_FINAL += --gc-sections endif
-ifndef CONFIG_LTO +ifneq ($(LTO_ENABLE),y) PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections endif
diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h index 085e12b5d4d..b255b195aa0 100644 --- a/arch/arm/include/asm/global_data.h +++ b/arch/arm/include/asm/global_data.h @@ -98,7 +98,7 @@ struct arch_global_data {
#include <asm-generic/global_data.h>
-#if defined(__clang__) || defined(CONFIG_LTO) +#if defined(__clang__) || defined(LTO_ENABLE)
#define DECLARE_GLOBAL_DATA_PTR #define gd get_gd() diff --git a/doc/build/gcc.rst b/doc/build/gcc.rst index cdd79700326..136c318727d 100644 --- a/doc/build/gcc.rst +++ b/doc/build/gcc.rst @@ -141,6 +141,23 @@ of dtc is new enough. It also makes sure that pylibfdt is present, if needed Note that the :doc:`tools` are always built with the included version of libfdt so it is not possible to build U-Boot tools with a system libfdt, at present.
+Link-time optimisation (LTO) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +U-Boot supports link-time optimisation which can reduce the size of the final +U-Boot binaries, particularly with SPL. + +At present this can be enabled by ARM boards by adding `CONFIG_LTO=y` into the +defconfig file. Other architectures are not supported. LTO is enabled by default +for sandbox. + +This does incur a link-time penalty of several seconds. For faster incremental +builds during development, you can disable it by setting `LTO_BUILD` to `n`. + +.. code-block:: bash + + LTO_BUILD=n make + Other build targets ~~~~~~~~~~~~~~~~~~~

These have sadly found their way to ARM now. Allow any arch to support generating ACPI tables.
Disable this for the tools build.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/Kconfig | 2 ++ arch/x86/Kconfig | 9 --------- configs/tools-only_defconfig | 1 + lib/Kconfig | 18 ++++++++++++++++++ 4 files changed, 21 insertions(+), 9 deletions(-)
diff --git a/arch/Kconfig b/arch/Kconfig index 3e2cc84ab2c..037ecff4b2f 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -148,6 +148,7 @@ config SANDBOX select SYS_CACHE_SHIFT_4 select IRQ select SUPPORT_EXTENSION_SCAN + select SUPPORT_ACPI imply BITREVERSE select BLOBLIST imply LTO @@ -210,6 +211,7 @@ config X86 select HAVE_PRIVATE_LIBGCC select OF_CONTROL select PCI + select SUPPORT_ACPI select SUPPORT_OF_CONTROL select SYS_CACHE_SHIFT_6 select TIMER diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index b8d8ee30838..7cbfd6c9720 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -770,15 +770,6 @@ config GENERATE_MP_TABLE multiprocessing as well as symmetric I/O interrupt handling with the local APIC and I/O APIC.
-config GENERATE_ACPI_TABLE - bool "Generate an ACPI (Advanced Configuration and Power Interface) table" - select QFW if QEMU - help - The Advanced Configuration and Power Interface (ACPI) specification - provides an open standard for device configuration and management - by the operating system. It defines platform-independent interfaces - for configuration and power management monitoring. - config ACPI_GNVS_EXTERNAL bool help diff --git a/configs/tools-only_defconfig b/configs/tools-only_defconfig index f482c9a1c1b..0f918c492b2 100644 --- a/configs/tools-only_defconfig +++ b/configs/tools-only_defconfig @@ -17,6 +17,7 @@ CONFIG_OF_CONTROL=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_BOOTP_SEND_HOSTNAME=y CONFIG_IP_DEFRAG=y +# CONFIG_GENERATE_ACPI_TABLE is not set # CONFIG_ACPIGEN is not set CONFIG_AXI=y CONFIG_AXI_SANDBOX=y diff --git a/lib/Kconfig b/lib/Kconfig index 807a4c6ade0..34554af45dd 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -192,6 +192,24 @@ config LIB_HW_RAND
endchoice
+config SUPPORT_ACPI + bool + help + Enable this if your arch or board can support generating ACPI + (Advanced Configuration and Power Interface) tables. In this case + U-Boot can generate these tables and pass them to the Operating + System. + +config GENERATE_ACPI_TABLE + bool "Generate an ACPI (Advanced Configuration and Power Interface) table" + depends on SUPPORT_ACPI + select QFW if QEMU + help + The Advanced Configuration and Power Interface (ACPI) specification + provides an open standard for device configuration and management + by the operating system. It defines platform-independent interfaces + for configuration and power management monitoring. + config SPL_TINY_MEMSET bool "Use a very small memset() in SPL" help

These have sadly found their way to ARM now. Allow any arch to support generating ACPI tables.
Disable this for the tools build.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/Kconfig | 2 ++ arch/x86/Kconfig | 9 --------- configs/tools-only_defconfig | 1 + lib/Kconfig | 18 ++++++++++++++++++ 4 files changed, 21 insertions(+), 9 deletions(-)
Applied to u-boot-dm, thanks!

Allow this to be used on any arch. Also convert to using macros so that we can check the CONFIG option in C code.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/sandbox/include/asm/global_data.h | 1 - arch/x86/include/asm/global_data.h | 1 - cmd/acpi.c | 6 +++--- include/asm-generic/global_data.h | 8 ++++++++ lib/acpi/acpi_table.c | 2 +- test/dm/acpi.c | 2 +- 6 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/arch/sandbox/include/asm/global_data.h b/arch/sandbox/include/asm/global_data.h index f95ddb058a2..f4ce72d5660 100644 --- a/arch/sandbox/include/asm/global_data.h +++ b/arch/sandbox/include/asm/global_data.h @@ -13,7 +13,6 @@ struct arch_global_data { uint8_t *ram_buf; /* emulated RAM buffer */ void *text_base; /* pointer to base of text region */ - ulong acpi_start; /* Start address of ACPI tables */ };
#include <asm-generic/global_data.h> diff --git a/arch/x86/include/asm/global_data.h b/arch/x86/include/asm/global_data.h index 3e4044593c8..23693f85a78 100644 --- a/arch/x86/include/asm/global_data.h +++ b/arch/x86/include/asm/global_data.h @@ -122,7 +122,6 @@ struct arch_global_data { struct fsp_header *fsp_s_hdr; /* Pointer to FSP-S header */ #endif void *itss_priv; /* Private ITSS data pointer */ - ulong acpi_start; /* Start address of ACPI tables */ ulong coreboot_table; /* Address of coreboot table */ };
diff --git a/cmd/acpi.c b/cmd/acpi.c index e5b9a1752bc..92ac0f5d490 100644 --- a/cmd/acpi.c +++ b/cmd/acpi.c @@ -47,7 +47,7 @@ struct acpi_table_header *find_table(const char *sig) struct acpi_rsdt *rsdt; int len, i, count;
- rsdp = map_sysmem(gd->arch.acpi_start, 0); + rsdp = map_sysmem(gd_acpi_start(), 0); if (!rsdp) return NULL; rsdt = map_sysmem(rsdp->rsdt_address, 0); @@ -143,12 +143,12 @@ static int do_acpi_list(struct cmd_tbl *cmdtp, int flag, int argc, { struct acpi_rsdp *rsdp;
- rsdp = map_sysmem(gd->arch.acpi_start, 0); + rsdp = map_sysmem(gd_acpi_start(), 0); if (!rsdp) { printf("No ACPI tables present\n"); return 0; } - printf("ACPI tables start at %lx\n", gd->arch.acpi_start); + printf("ACPI tables start at %lx\n", gd_acpi_start()); list_rsdp(rsdp);
return 0; diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index 16fd305a65c..e06a2db63de 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -452,6 +452,10 @@ struct global_data { * @acpi_ctx: ACPI context pointer */ struct acpi_ctx *acpi_ctx; + /** + * @acpi_start: Start address of ACPI tables + */ + ulong acpi_start; #endif #if CONFIG_IS_ENABLED(GENERATE_SMBIOS_TABLE) /** @@ -508,8 +512,12 @@ static_assert(sizeof(struct global_data) == GD_SIZE);
#ifdef CONFIG_GENERATE_ACPI_TABLE #define gd_acpi_ctx() gd->acpi_ctx +#define gd_acpi_start() gd->acpi_start +#define gd_set_acpi_start(addr) gd->acpi_start = addr #else #define gd_acpi_ctx() NULL +#define gd_acpi_start() 0UL +#define gd_set_acpi_start(addr) #endif
/** diff --git a/lib/acpi/acpi_table.c b/lib/acpi/acpi_table.c index d1685404c21..3a72718df89 100644 --- a/lib/acpi/acpi_table.c +++ b/lib/acpi/acpi_table.c @@ -260,7 +260,7 @@ void acpi_setup_base_tables(struct acpi_ctx *ctx, void *start)
/* Align ACPI tables to 16 byte */ acpi_align(ctx); - gd->arch.acpi_start = map_to_sysmem(ctx->current); + gd_set_acpi_start(map_to_sysmem(ctx->current));
/* We need at least an RSDP and an RSDT Table */ ctx->rsdp = ctx->current; diff --git a/test/dm/acpi.c b/test/dm/acpi.c index c51073c9a6c..804124df9e9 100644 --- a/test/dm/acpi.c +++ b/test/dm/acpi.c @@ -320,7 +320,7 @@ static int dm_test_acpi_setup_base_tables(struct unit_test_state *uts) buf = memalign(64, BUF_SIZE); ut_assertnonnull(buf); acpi_setup_base_tables(&ctx, buf + 4); - ut_asserteq(map_to_sysmem(PTR_ALIGN(buf + 4, 16)), gd->arch.acpi_start); + ut_asserteq(map_to_sysmem(PTR_ALIGN(buf + 4, 16)), gd_acpi_start());
rsdp = buf + 16; ut_asserteq_ptr(rsdp, ctx.rsdp);

Allow this to be used on any arch. Also convert to using macros so that we can check the CONFIG option in C code.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/sandbox/include/asm/global_data.h | 1 - arch/x86/include/asm/global_data.h | 1 - cmd/acpi.c | 6 +++--- include/asm-generic/global_data.h | 8 ++++++++ lib/acpi/acpi_table.c | 2 +- test/dm/acpi.c | 2 +- 6 files changed, 13 insertions(+), 7 deletions(-)
Applied to u-boot-dm, thanks!

Some ARM boards are using ACPI now. It seems that U-Boot should support this method. Add ARM to the list of archs which can generate ACPI tables.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/Kconfig b/arch/Kconfig index 037ecff4b2f..7e4083f80b1 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -58,6 +58,7 @@ config ARM select ARCH_SUPPORTS_LTO select CREATE_ARCH_SYMLINK select HAVE_PRIVATE_LIBGCC if !ARM64 + select SUPPORT_ACPI select SUPPORT_OF_CONTROL
config M68K

From: Simon Glass sjg@chromium.org Date: Wed, 1 Dec 2021 09:02:38 -0700
Some ARM boards are using ACPI now. It seems that U-Boot should support this method. Add ARM to the list of archs which can generate ACPI tables.
Can you explain why you think U-Boot should care?
Because I think promoting ACPI as a viable firmware interface for the type of boards supported by U-Boot would be a serious mistake...
Signed-off-by: Simon Glass sjg@chromium.org
arch/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/Kconfig b/arch/Kconfig index 037ecff4b2f..7e4083f80b1 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -58,6 +58,7 @@ config ARM select ARCH_SUPPORTS_LTO select CREATE_ARCH_SYMLINK select HAVE_PRIVATE_LIBGCC if !ARM64
- select SUPPORT_ACPI select SUPPORT_OF_CONTROL
config M68K
2.34.0.rc2.393.gf8c9666880-goog

On Wed, Dec 01, 2021 at 05:49:54PM +0100, Mark Kettenis wrote:
From: Simon Glass sjg@chromium.org Date: Wed, 1 Dec 2021 09:02:38 -0700
Some ARM boards are using ACPI now. It seems that U-Boot should support this method. Add ARM to the list of archs which can generate ACPI tables.
Can you explain why you think U-Boot should care?
Because I think promoting ACPI as a viable firmware interface for the type of boards supported by U-Boot would be a serious mistake...
Given the large overlap of SoCs that support both SystemReady IR and SystemReady ES, I asked Simon how hard it would be to pass ACPI tables, instead of DTB. Are there going to be some challenges to be able to get ES certified under U-Boot? Certainly. But I'm not convinced that U-Boot is just a wrong-fit for the ES case when part of the whole point of these certifications is that it doesn't matter what's implementing it, it's a standard.

Hi
Le mer. 1 déc. 2021 à 18:11, Tom Rini trini@konsulko.com a écrit :
On Wed, Dec 01, 2021 at 05:49:54PM +0100, Mark Kettenis wrote:
From: Simon Glass sjg@chromium.org Date: Wed, 1 Dec 2021 09:02:38 -0700
Some ARM boards are using ACPI now. It seems that U-Boot should support this method. Add ARM to the list of archs which can generate ACPI
tables.
Can you explain why you think U-Boot should care?
Because I think promoting ACPI as a viable firmware interface for the type of boards supported by U-Boot would be a serious mistake...
Given the large overlap of SoCs that support both SystemReady IR and SystemReady ES, I asked Simon how hard it would be to pass ACPI tables, instead of DTB. Are there going to be some challenges to be able to get ES certified under U-Boot? Certainly. But I'm not convinced that U-Boot is just a wrong-fit for the ES case when part of the whole point of these certifications is that it doesn't matter what's implementing it, it's a standard.
looks like an exciting endeavor ! If we factor in safety certification, there are probably more chances to achieve this with U-Boot that EDK2. That said, AML implementation in U-Boot, which may end up being necessary, need special care.
-- Tom

Hi François,
On Wed, 1 Dec 2021 at 10:45, François Ozog francois.ozog@linaro.org wrote:
Hi
Le mer. 1 déc. 2021 à 18:11, Tom Rini trini@konsulko.com a écrit :
On Wed, Dec 01, 2021 at 05:49:54PM +0100, Mark Kettenis wrote:
From: Simon Glass sjg@chromium.org Date: Wed, 1 Dec 2021 09:02:38 -0700
Some ARM boards are using ACPI now. It seems that U-Boot should support this method. Add ARM to the list of archs which can generate ACPI tables.
Can you explain why you think U-Boot should care?
Because I think promoting ACPI as a viable firmware interface for the type of boards supported by U-Boot would be a serious mistake...
Given the large overlap of SoCs that support both SystemReady IR and SystemReady ES, I asked Simon how hard it would be to pass ACPI tables, instead of DTB. Are there going to be some challenges to be able to get ES certified under U-Boot? Certainly. But I'm not convinced that U-Boot is just a wrong-fit for the ES case when part of the whole point of these certifications is that it doesn't matter what's implementing it, it's a standard.
looks like an exciting endeavor ! If we factor in safety certification, there are probably more chances to achieve this with U-Boot that EDK2. That said, AML implementation in U-Boot, which may end up being necessary, need special care.
BTW there is a fair bit of AML-generation code behind CONFIG_ACPIGEN [1]. It is widely used on coral, for example. It also has unit tests! [2]
As to Mark's point, I am very happy to share my own opinions on ACPI, but I think that is sideways of the discussion here.
Regards, Simon
[1] https://github.com/u-boot/u-boot/blob/master/include/acpi/acpigen.h [2] https://github.com/u-boot/u-boot/blob/master/test/dm/acpigen.c

Hi François,
On Wed, 1 Dec 2021 at 10:45, François Ozog francois.ozog@linaro.org wrote:
Hi
Le mer. 1 déc. 2021 à 18:11, Tom Rini trini@konsulko.com a écrit :
On Wed, Dec 01, 2021 at 05:49:54PM +0100, Mark Kettenis wrote:
From: Simon Glass sjg@chromium.org Date: Wed, 1 Dec 2021 09:02:38 -0700
Some ARM boards are using ACPI now. It seems that U-Boot should support this method. Add ARM to the list of archs which can generate ACPI tables.
Can you explain why you think U-Boot should care?
Because I think promoting ACPI as a viable firmware interface for the type of boards supported by U-Boot would be a serious mistake...
Given the large overlap of SoCs that support both SystemReady IR and SystemReady ES, I asked Simon how hard it would be to pass ACPI tables, instead of DTB. Are there going to be some challenges to be able to get ES certified under U-Boot? Certainly. But I'm not convinced that U-Boot is just a wrong-fit for the ES case when part of the whole point of these certifications is that it doesn't matter what's implementing it, it's a standard.
looks like an exciting endeavor ! If we factor in safety certification, there are probably more chances to achieve this with U-Boot that EDK2. That said, AML implementation in U-Boot, which may end up being necessary, need special care.
BTW there is a fair bit of AML-generation code behind CONFIG_ACPIGEN [1]. It is widely used on coral, for example. It also has unit tests! [2]
As to Mark's point, I am very happy to share my own opinions on ACPI, but I think that is sideways of the discussion here.
Regards, Simon
[1] https://github.com/u-boot/u-boot/blob/master/include/acpi/acpigen.h [2] https://github.com/u-boot/u-boot/blob/master/test/dm/acpigen.c
Applied to u-boot-dm, thanks!

This is enabled for quite a few boards which don't create ACPI tables. Tidy this up by dropping the option for some boards.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/Kconfig | 2 +- configs/cherryhill_defconfig | 1 + configs/chromebook_link64_defconfig | 1 + configs/chromebook_link_defconfig | 1 + configs/chromebook_samus_tpl_defconfig | 1 + configs/coreboot64_defconfig | 1 + configs/coreboot_defconfig | 1 + configs/crownbay_defconfig | 1 + configs/efi-x86_payload32_defconfig | 1 + configs/efi-x86_payload64_defconfig | 1 + configs/slimbootloader_defconfig | 1 + 11 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/arch/Kconfig b/arch/Kconfig index 7e4083f80b1..57f72be25a7 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -249,7 +249,7 @@ config X86 imply USB_HOST_ETHER imply PCH imply RTC_MC146818 - imply ACPIGEN if !QEMU + imply ACPIGEN if !QEMU && !EFI_APP imply SYSINFO if GENERATE_SMBIOS_TABLE imply SYSINFO_SMBIOS if GENERATE_SMBIOS_TABLE
diff --git a/configs/cherryhill_defconfig b/configs/cherryhill_defconfig index c3231032ca4..35044c239cb 100644 --- a/configs/cherryhill_defconfig +++ b/configs/cherryhill_defconfig @@ -38,6 +38,7 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_TFTP_TSIZE=y CONFIG_REGMAP=y CONFIG_SYSCON=y +# CONFIG_ACPIGEN is not set CONFIG_CPU=y CONFIG_RTL8169=y CONFIG_SPI=y diff --git a/configs/chromebook_link64_defconfig b/configs/chromebook_link64_defconfig index c43d9dcb927..a4b2af13e79 100644 --- a/configs/chromebook_link64_defconfig +++ b/configs/chromebook_link64_defconfig @@ -62,6 +62,7 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_TFTP_TSIZE=y CONFIG_REGMAP=y CONFIG_SYSCON=y +# CONFIG_ACPIGEN is not set CONFIG_CPU=y CONFIG_DM_I2C=y CONFIG_SYS_I2C_INTEL=y diff --git a/configs/chromebook_link_defconfig b/configs/chromebook_link_defconfig index ad9e9dd961e..c1deefb068a 100644 --- a/configs/chromebook_link_defconfig +++ b/configs/chromebook_link_defconfig @@ -53,6 +53,7 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_TFTP_TSIZE=y CONFIG_REGMAP=y CONFIG_SYSCON=y +# CONFIG_ACPIGEN is not set CONFIG_CPU=y CONFIG_DM_I2C=y CONFIG_SYS_I2C_INTEL=y diff --git a/configs/chromebook_samus_tpl_defconfig b/configs/chromebook_samus_tpl_defconfig index b231b3b0dbd..1579e3f2779 100644 --- a/configs/chromebook_samus_tpl_defconfig +++ b/configs/chromebook_samus_tpl_defconfig @@ -71,6 +71,7 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y # CONFIG_NET is not set CONFIG_REGMAP=y CONFIG_SYSCON=y +# CONFIG_ACPIGEN is not set CONFIG_CPU=y CONFIG_DM_I2C=y CONFIG_SYS_I2C_DW=y diff --git a/configs/coreboot64_defconfig b/configs/coreboot64_defconfig index 799a83caa2f..f4cc91cccf4 100644 --- a/configs/coreboot64_defconfig +++ b/configs/coreboot64_defconfig @@ -44,6 +44,7 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_TFTP_TSIZE=y CONFIG_REGMAP=y CONFIG_SYSCON=y +# CONFIG_ACPIGEN is not set # CONFIG_PCI_PNP is not set CONFIG_SOUND=y CONFIG_SOUND_I8254=y diff --git a/configs/coreboot_defconfig b/configs/coreboot_defconfig index 131de75d929..bb2f592e77b 100644 --- a/configs/coreboot_defconfig +++ b/configs/coreboot_defconfig @@ -39,6 +39,7 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_TFTP_TSIZE=y CONFIG_REGMAP=y CONFIG_SYSCON=y +# CONFIG_ACPIGEN is not set # CONFIG_PCI_PNP is not set CONFIG_SOUND=y CONFIG_SOUND_I8254=y diff --git a/configs/crownbay_defconfig b/configs/crownbay_defconfig index 58c370a9893..0f381b5be7d 100644 --- a/configs/crownbay_defconfig +++ b/configs/crownbay_defconfig @@ -46,6 +46,7 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_TFTP_TSIZE=y CONFIG_REGMAP=y CONFIG_SYSCON=y +# CONFIG_ACPIGEN is not set CONFIG_CPU=y CONFIG_E1000=y CONFIG_SOUND=y diff --git a/configs/efi-x86_payload32_defconfig b/configs/efi-x86_payload32_defconfig index 4f1d6a91989..64bd1d690e6 100644 --- a/configs/efi-x86_payload32_defconfig +++ b/configs/efi-x86_payload32_defconfig @@ -37,6 +37,7 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_TFTP_TSIZE=y CONFIG_REGMAP=y CONFIG_SYSCON=y +# CONFIG_ACPIGEN is not set # CONFIG_PCI_PNP is not set # CONFIG_GZIP is not set CONFIG_EFI=y diff --git a/configs/efi-x86_payload64_defconfig b/configs/efi-x86_payload64_defconfig index 26cfc494900..fb7bd2706d3 100644 --- a/configs/efi-x86_payload64_defconfig +++ b/configs/efi-x86_payload64_defconfig @@ -37,6 +37,7 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_TFTP_TSIZE=y CONFIG_REGMAP=y CONFIG_SYSCON=y +# CONFIG_ACPIGEN is not set # CONFIG_PCI_PNP is not set # CONFIG_GZIP is not set CONFIG_EFI=y diff --git a/configs/slimbootloader_defconfig b/configs/slimbootloader_defconfig index 5cfbaa224fa..a18e0279d4a 100644 --- a/configs/slimbootloader_defconfig +++ b/configs/slimbootloader_defconfig @@ -21,6 +21,7 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_TFTP_TSIZE=y CONFIG_REGMAP=y CONFIG_SYSCON=y +# CONFIG_ACPIGEN is not set # CONFIG_PCI_PNP is not set CONFIG_CONSOLE_SCROLL_LINES=5 # CONFIG_GZIP is not set

This is enabled for quite a few boards which don't create ACPI tables. Tidy this up by dropping the option for some boards.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/Kconfig | 2 +- configs/cherryhill_defconfig | 1 + configs/chromebook_link64_defconfig | 1 + configs/chromebook_link_defconfig | 1 + configs/chromebook_samus_tpl_defconfig | 1 + configs/coreboot64_defconfig | 1 + configs/coreboot_defconfig | 1 + configs/crownbay_defconfig | 1 + configs/efi-x86_payload32_defconfig | 1 + configs/efi-x86_payload64_defconfig | 1 + configs/slimbootloader_defconfig | 1 + 11 files changed, 11 insertions(+), 1 deletion(-)
Applied to u-boot-dm, thanks!

At present this option is missing a header file, a function prototype and the qfw driver needs a header included.
Fix these problems so we can enable this option on sandbox. This will increase the build coverage.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/sandbox/include/asm/acpi_table.h | 2 ++ arch/sandbox/include/asm/tables.h | 0 drivers/misc/qfw.c | 1 + 3 files changed, 3 insertions(+) create mode 100644 arch/sandbox/include/asm/tables.h
diff --git a/arch/sandbox/include/asm/acpi_table.h b/arch/sandbox/include/asm/acpi_table.h index 921c7f4201d..ae17f6c5197 100644 --- a/arch/sandbox/include/asm/acpi_table.h +++ b/arch/sandbox/include/asm/acpi_table.h @@ -6,4 +6,6 @@ #ifndef __ASM_ACPI_TABLE_H__ #define __ASM_ACPI_TABLE_H__
+ulong write_acpi_tables(ulong start); + #endif /* __ASM_ACPI_TABLE_H__ */ diff --git a/arch/sandbox/include/asm/tables.h b/arch/sandbox/include/asm/tables.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/drivers/misc/qfw.c b/drivers/misc/qfw.c index ea00be88a8d..a298e5cf727 100644 --- a/drivers/misc/qfw.c +++ b/drivers/misc/qfw.c @@ -14,6 +14,7 @@ #include <qfw.h> #include <dm.h> #include <misc.h> +#include <tables_csum.h> #ifdef CONFIG_GENERATE_ACPI_TABLE #include <asm/tables.h> #endif

On 12/1/21 17:02, Simon Glass wrote:
At present this option is missing a header file, a function prototype and the qfw driver needs a header included.
Fix these problems so we can enable this option on sandbox. This will increase the build coverage.
Signed-off-by: Simon Glass sjg@chromium.org
arch/sandbox/include/asm/acpi_table.h | 2 ++ arch/sandbox/include/asm/tables.h | 0 drivers/misc/qfw.c | 1 + 3 files changed, 3 insertions(+) create mode 100644 arch/sandbox/include/asm/tables.h
diff --git a/arch/sandbox/include/asm/acpi_table.h b/arch/sandbox/include/asm/acpi_table.h index 921c7f4201d..ae17f6c5197 100644 --- a/arch/sandbox/include/asm/acpi_table.h +++ b/arch/sandbox/include/asm/acpi_table.h @@ -6,4 +6,6 @@ #ifndef __ASM_ACPI_TABLE_H__ #define __ASM_ACPI_TABLE_H__
+ulong write_acpi_tables(ulong start);
This definition should be in a global include. The parameter must a pointer to restrict sandbox specific code to the sandbox.
Best regards
Heinrich
- #endif /* __ASM_ACPI_TABLE_H__ */
diff --git a/arch/sandbox/include/asm/tables.h b/arch/sandbox/include/asm/tables.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/drivers/misc/qfw.c b/drivers/misc/qfw.c index ea00be88a8d..a298e5cf727 100644 --- a/drivers/misc/qfw.c +++ b/drivers/misc/qfw.c @@ -14,6 +14,7 @@ #include <qfw.h> #include <dm.h> #include <misc.h> +#include <tables_csum.h> #ifdef CONFIG_GENERATE_ACPI_TABLE #include <asm/tables.h> #endif

Hi Heinrich,
On Wed, 1 Dec 2021 at 11:14, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 12/1/21 17:02, Simon Glass wrote:
At present this option is missing a header file, a function prototype and the qfw driver needs a header included.
Fix these problems so we can enable this option on sandbox. This will increase the build coverage.
Signed-off-by: Simon Glass sjg@chromium.org
arch/sandbox/include/asm/acpi_table.h | 2 ++ arch/sandbox/include/asm/tables.h | 0 drivers/misc/qfw.c | 1 + 3 files changed, 3 insertions(+) create mode 100644 arch/sandbox/include/asm/tables.h
diff --git a/arch/sandbox/include/asm/acpi_table.h b/arch/sandbox/include/asm/acpi_table.h index 921c7f4201d..ae17f6c5197 100644 --- a/arch/sandbox/include/asm/acpi_table.h +++ b/arch/sandbox/include/asm/acpi_table.h @@ -6,4 +6,6 @@ #ifndef __ASM_ACPI_TABLE_H__ #define __ASM_ACPI_TABLE_H__
+ulong write_acpi_tables(ulong start);
This definition should be in a global include. The parameter must a pointer to restrict sandbox specific code to the sandbox.
Yes indeed, I meant to fix the header before sending but missed it. Will fix.
It doesn't really help making it a pointer, even if I wanted to, which I don't, sorry. We still need to print out the address, and pass it on to other functions, so if we pass a pointer we just need to convert back to an address for that purpose.
Regards, Simon

Hi Heinrich,
On Wed, 1 Dec 2021 at 11:14, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 12/1/21 17:02, Simon Glass wrote:
At present this option is missing a header file, a function prototype and the qfw driver needs a header included.
Fix these problems so we can enable this option on sandbox. This will increase the build coverage.
Signed-off-by: Simon Glass sjg@chromium.org
arch/sandbox/include/asm/acpi_table.h | 2 ++ arch/sandbox/include/asm/tables.h | 0 drivers/misc/qfw.c | 1 + 3 files changed, 3 insertions(+) create mode 100644 arch/sandbox/include/asm/tables.h
Applied to u-boot-dm, thanks!

This must be passed a ulong, not a u64. Fix it to avoid LTO warnings on sandbox.
Signed-off-by: Simon Glass sjg@chromium.org ---
lib/efi_loader/efi_acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/efi_loader/efi_acpi.c b/lib/efi_loader/efi_acpi.c index a62c34009cc..016bbf6db33 100644 --- a/lib/efi_loader/efi_acpi.c +++ b/lib/efi_loader/efi_acpi.c @@ -34,7 +34,7 @@ efi_status_t efi_acpi_register(void) * a 4k-aligned address, so it is safe to assume that * write_acpi_tables() will write the table at that address. */ - write_acpi_tables(acpi); + write_acpi_tables((ulong)acpi);
/* And expose them to our EFI payload */ return efi_install_configuration_table(&acpi_guid,

On 12/1/21 17:02, Simon Glass wrote:
This must be passed a ulong, not a u64. Fix it to avoid LTO warnings on sandbox.
Signed-off-by: Simon Glass sjg@chromium.org
lib/efi_loader/efi_acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/efi_loader/efi_acpi.c b/lib/efi_loader/efi_acpi.c index a62c34009cc..016bbf6db33 100644 --- a/lib/efi_loader/efi_acpi.c +++ b/lib/efi_loader/efi_acpi.c @@ -34,7 +34,7 @@ efi_status_t efi_acpi_register(void) * a 4k-aligned address, so it is safe to assume that * write_acpi_tables() will write the table at that address. */
- write_acpi_tables(acpi);
- write_acpi_tables((ulong)acpi);
This is wrong: acpi is not an address in the virtual address space of the sandbox. You must not pass it to use map_sysmem() to convert it to a pointer.
Please change the parameter of write_acpi_tables() to be a pointer and move all sandbox specific conversions to the sandbox code.
Best regards
Heinrich
/* And expose them to our EFI payload */ return efi_install_configuration_table(&acpi_guid,

Hi Heinrich,
On Wed, 1 Dec 2021 at 11:08, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 12/1/21 17:02, Simon Glass wrote:
This must be passed a ulong, not a u64. Fix it to avoid LTO warnings on sandbox.
Signed-off-by: Simon Glass sjg@chromium.org
lib/efi_loader/efi_acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/efi_loader/efi_acpi.c b/lib/efi_loader/efi_acpi.c index a62c34009cc..016bbf6db33 100644 --- a/lib/efi_loader/efi_acpi.c +++ b/lib/efi_loader/efi_acpi.c @@ -34,7 +34,7 @@ efi_status_t efi_acpi_register(void) * a 4k-aligned address, so it is safe to assume that * write_acpi_tables() will write the table at that address. */
write_acpi_tables(acpi);
write_acpi_tables((ulong)acpi);
This is wrong: acpi is not an address in the virtual address space of the sandbox. You must not pass it to use map_sysmem() to convert it to a pointer.
I think you are referring to the other patch.
Here the problem is that a u64 is being passed to a ulong. As you say, this should be a global prototype and I will fix that in v2.
Please change the parameter of write_acpi_tables() to be a pointer and move all sandbox specific conversions to the sandbox code.
Sorry, no, I don't want to do that as it would be a significant departure from how U-Boot currently works. We use ulong everywhere for addresses.
Regards, Simon

On 12/1/21 20:32, Simon Glass wrote:
Hi Heinrich,
On Wed, 1 Dec 2021 at 11:08, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 12/1/21 17:02, Simon Glass wrote:
This must be passed a ulong, not a u64. Fix it to avoid LTO warnings on sandbox.
Signed-off-by: Simon Glass sjg@chromium.org
lib/efi_loader/efi_acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/efi_loader/efi_acpi.c b/lib/efi_loader/efi_acpi.c index a62c34009cc..016bbf6db33 100644 --- a/lib/efi_loader/efi_acpi.c +++ b/lib/efi_loader/efi_acpi.c @@ -34,7 +34,7 @@ efi_status_t efi_acpi_register(void) * a 4k-aligned address, so it is safe to assume that * write_acpi_tables() will write the table at that address. */
write_acpi_tables(acpi);
write_acpi_tables((ulong)acpi);
This is wrong: acpi is not an address in the virtual address space of the sandbox. You must not pass it to use map_sysmem() to convert it to a pointer.
I think you are referring to the other patch.
Here the problem is that a u64 is being passed to a ulong. As you say, this should be a global prototype and I will fix that in v2.
Please change the parameter of write_acpi_tables() to be a pointer and move all sandbox specific conversions to the sandbox code.
Sorry, no, I don't want to do that as it would be a significant departure from how U-Boot currently works. We use ulong everywhere for addresses.
We typically use pointers to pass references to memory and not ulong. Relative addresses in the virtual address space of the sandbox are only relevant for testing on and user interaction with the sandbox.
The location of the memory location for the ACPI table is not determined by the user.
Please, have a look at the called function where the sandbox address is immediately converted back to a pointer. The parameter value is only used in a debug statement. This double conversion makes is a waste of memory and CPU cycles. Even for the debug output on the sandbox I would go for a pointer because that is the value that I will need to understand what is happening in the booted image.
Best regards
Heinrich
Regards, Simon

Hi Heinrich,
On Wed, 1 Dec 2021 at 12:57, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 12/1/21 20:32, Simon Glass wrote:
Hi Heinrich,
On Wed, 1 Dec 2021 at 11:08, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 12/1/21 17:02, Simon Glass wrote:
This must be passed a ulong, not a u64. Fix it to avoid LTO warnings on sandbox.
Signed-off-by: Simon Glass sjg@chromium.org
lib/efi_loader/efi_acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/efi_loader/efi_acpi.c b/lib/efi_loader/efi_acpi.c index a62c34009cc..016bbf6db33 100644 --- a/lib/efi_loader/efi_acpi.c +++ b/lib/efi_loader/efi_acpi.c @@ -34,7 +34,7 @@ efi_status_t efi_acpi_register(void) * a 4k-aligned address, so it is safe to assume that * write_acpi_tables() will write the table at that address. */
write_acpi_tables(acpi);
write_acpi_tables((ulong)acpi);
This is wrong: acpi is not an address in the virtual address space of the sandbox. You must not pass it to use map_sysmem() to convert it to a pointer.
I think you are referring to the other patch.
Here the problem is that a u64 is being passed to a ulong. As you say, this should be a global prototype and I will fix that in v2.
Please change the parameter of write_acpi_tables() to be a pointer and move all sandbox specific conversions to the sandbox code.
Sorry, no, I don't want to do that as it would be a significant departure from how U-Boot currently works. We use ulong everywhere for addresses.
We typically use pointers to pass references to memory and not ulong.
(again, I think this discussion relates to the other patch)
That is true in some internal code, but more often a ulong is used for an address, e.g. with the boot flow, commands, ACPI, board init, etc. etc. The ulong is the standard holder of an address in U-Boot and ACPI uses addresses. Haven't we been through this before?
Relative addresses in the virtual address space of the sandbox are only relevant for testing on and user interaction with the sandbox.
The location of the memory location for the ACPI table is not determined by the user.
Please, have a look at the called function where the sandbox address is immediately converted back to a pointer. The parameter value is only used in a debug statement. This double conversion makes is a waste of memory and CPU cycles. Even for the debug output on the sandbox I would go for a pointer because that is the value that I will need to understand what is happening in the booted image.
I think you are over-indexing on sandbox. The first thing to explain is why a u64 is used to hold what I believe to be a void pointer. IMO the API is not right. Or perhaps just its interaction with sandbox is wrong. But somehow, we need to fix the bug in the other patch.
The only thing that is useful to see with sandbox is the address. The pointers are random numbers really, not easily related to the addresses that they came from. For example, with 'md 0', I want to see the address '0', not the pointer value which might be 0x33d27120000 or anything else.
Regards, Simon

Am 1. Dezember 2021 22:12:09 MEZ schrieb Simon Glass sjg@chromium.org:
Hi Heinrich,
On Wed, 1 Dec 2021 at 12:57, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 12/1/21 20:32, Simon Glass wrote:
Hi Heinrich,
On Wed, 1 Dec 2021 at 11:08, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 12/1/21 17:02, Simon Glass wrote:
This must be passed a ulong, not a u64. Fix it to avoid LTO warnings on sandbox.
Signed-off-by: Simon Glass sjg@chromium.org
lib/efi_loader/efi_acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/efi_loader/efi_acpi.c b/lib/efi_loader/efi_acpi.c index a62c34009cc..016bbf6db33 100644 --- a/lib/efi_loader/efi_acpi.c +++ b/lib/efi_loader/efi_acpi.c @@ -34,7 +34,7 @@ efi_status_t efi_acpi_register(void) * a 4k-aligned address, so it is safe to assume that * write_acpi_tables() will write the table at that address. */
write_acpi_tables(acpi);
write_acpi_tables((ulong)acpi);
This is wrong: acpi is not an address in the virtual address space of the sandbox. You must not pass it to use map_sysmem() to convert it to a pointer.
I think you are referring to the other patch.
Here the problem is that a u64 is being passed to a ulong. As you say, this should be a global prototype and I will fix that in v2.
Please change the parameter of write_acpi_tables() to be a pointer and move all sandbox specific conversions to the sandbox code.
Sorry, no, I don't want to do that as it would be a significant departure from how U-Boot currently works. We use ulong everywhere for addresses.
We typically use pointers to pass references to memory and not ulong.
(again, I think this discussion relates to the other patch)
That is true in some internal code, but more often a ulong is used for an address, e.g. with the boot flow, commands, ACPI, board init, etc. etc. The ulong is the standard holder of an address in U-Boot and ACPI uses addresses. Haven't we been through this before?
Relative addresses in the virtual address space of the sandbox are only relevant for testing on and user interaction with the sandbox.
The location of the memory location for the ACPI table is not determined by the user.
Please, have a look at the called function where the sandbox address is immediately converted back to a pointer. The parameter value is only used in a debug statement. This double conversion makes is a waste of memory and CPU cycles. Even for the debug output on the sandbox I would go for a pointer because that is the value that I will need to understand what is happening in the booted image.
I think you are over-indexing on sandbox. The first thing to explain is why a u64 is used to hold what I believe to be a void pointer.
The UEFI API requires u64 for AllocatePages() and GetMemoryMap(). This is a design choice of the API that I don't expect to be corrected in future API versions.
IMO
the API is not right. Or perhaps just its interaction with sandbox is wrong. But somehow, we need to fix the bug in the other patch.
The only thing that is useful to see with sandbox is the address. The pointers are random numbers really, not easily related to the addresses that they came from. For example, with 'md 0', I want to see the address '0', not the pointer value which might be 0x33d27120000 or anything else.
In U-Boot except for the sandbox pointers is all we need. Other defconfigs neither need nor use a virtual address space.
The only reason why the sandbox uses a virtual address space is ease of user interaction and ease of imlementing unit tests. This is why offsets to the sandbox memory start are passed around instead of addresses (pointers).
Currently the sandbox requirements have spilled to a lot of different code parts. An alternative design could have strictly restricted the offset-address conversions to console input and output.
I don't expect this design to be reverted. But we should not artificially increase the number of places where we use offsets instead of pointers.
If a called function can not use an offset but needs the pointer, passing an offset as a parameter makes no sense.
Best regards
Heinrich
Regards, Simon

Hi Heinrich,
On Wed, 1 Dec 2021 at 22:00, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
Am 1. Dezember 2021 22:12:09 MEZ schrieb Simon Glass sjg@chromium.org:
Hi Heinrich,
On Wed, 1 Dec 2021 at 12:57, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 12/1/21 20:32, Simon Glass wrote:
Hi Heinrich,
On Wed, 1 Dec 2021 at 11:08, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 12/1/21 17:02, Simon Glass wrote:
This must be passed a ulong, not a u64. Fix it to avoid LTO warnings on sandbox.
Signed-off-by: Simon Glass sjg@chromium.org
lib/efi_loader/efi_acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/efi_loader/efi_acpi.c b/lib/efi_loader/efi_acpi.c index a62c34009cc..016bbf6db33 100644 --- a/lib/efi_loader/efi_acpi.c +++ b/lib/efi_loader/efi_acpi.c @@ -34,7 +34,7 @@ efi_status_t efi_acpi_register(void) * a 4k-aligned address, so it is safe to assume that * write_acpi_tables() will write the table at that address. */
write_acpi_tables(acpi);
write_acpi_tables((ulong)acpi);
This is wrong: acpi is not an address in the virtual address space of the sandbox. You must not pass it to use map_sysmem() to convert it to a pointer.
I think you are referring to the other patch.
Here the problem is that a u64 is being passed to a ulong. As you say, this should be a global prototype and I will fix that in v2.
Please change the parameter of write_acpi_tables() to be a pointer and move all sandbox specific conversions to the sandbox code.
Sorry, no, I don't want to do that as it would be a significant departure from how U-Boot currently works. We use ulong everywhere for addresses.
We typically use pointers to pass references to memory and not ulong.
(again, I think this discussion relates to the other patch)
That is true in some internal code, but more often a ulong is used for an address, e.g. with the boot flow, commands, ACPI, board init, etc. etc. The ulong is the standard holder of an address in U-Boot and ACPI uses addresses. Haven't we been through this before?
Relative addresses in the virtual address space of the sandbox are only relevant for testing on and user interaction with the sandbox.
The location of the memory location for the ACPI table is not determined by the user.
Please, have a look at the called function where the sandbox address is immediately converted back to a pointer. The parameter value is only used in a debug statement. This double conversion makes is a waste of memory and CPU cycles. Even for the debug output on the sandbox I would go for a pointer because that is the value that I will need to understand what is happening in the booted image.
I think you are over-indexing on sandbox. The first thing to explain is why a u64 is used to hold what I believe to be a void pointer.
The UEFI API requires u64 for AllocatePages() and GetMemoryMap(). This is a design choice of the API that I don't expect to be corrected in future API versions.
IMO
the API is not right. Or perhaps just its interaction with sandbox is wrong. But somehow, we need to fix the bug in the other patch.
The only thing that is useful to see with sandbox is the address. The pointers are random numbers really, not easily related to the addresses that they came from. For example, with 'md 0', I want to see the address '0', not the pointer value which might be 0x33d27120000 or anything else.
In U-Boot except for the sandbox pointers is all we need. Other defconfigs neither need nor use a virtual address space.
The only reason why the sandbox uses a virtual address space is ease of user interaction and ease of imlementing unit tests. This is why offsets to the sandbox memory start are passed around instead of addresses (pointers).
Where did you get that idea? U-Boot has always used addresses rather than pointers. Sandbox happens to take advantage of that, that is all.
Currently the sandbox requirements have spilled to a lot of different code parts. An alternative design could have strictly restricted the offset-address conversions to console input and output.
I don't expect this design to be reverted. But we should not artificially increase the number of places where we use offsets instead of pointers.
If a called function can not use an offset but needs the pointer, passing an offset as a parameter makes no sense.
It is not an offset, it is an address. You are getting tied up in the sandbox side of this. Casting an address to a pointer should be done using mapmem, for sandbox compatibility, that's all.
The use of ulong in U-Boot is actually a very nice feature and very convenient. I very-much oppose any change there. Sandbox is how we do our testing and is an important part of the code.
So how do you propose to fix the bug in this EFI code? I am not prepared to change the ACPI interface to use pointers in its arguments. Almost all the interfaces in U-Boot work the same way, it just makes no sense.
Regards, SImon

Hi Heinrich,
On Wed, 1 Dec 2021 at 22:00, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
Am 1. Dezember 2021 22:12:09 MEZ schrieb Simon Glass sjg@chromium.org:
Hi Heinrich,
On Wed, 1 Dec 2021 at 12:57, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 12/1/21 20:32, Simon Glass wrote:
Hi Heinrich,
On Wed, 1 Dec 2021 at 11:08, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 12/1/21 17:02, Simon Glass wrote:
This must be passed a ulong, not a u64. Fix it to avoid LTO warnings on sandbox.
Signed-off-by: Simon Glass sjg@chromium.org
lib/efi_loader/efi_acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Applied to u-boot-dm, thanks!

The current EFI implementation confuses pointers and addresses. Normally we can get away with this but in the case of sandbox it causes failures.
Despite the fact that efi_allocate_pages() returns a u64, it is actually a pointer, not an address. Add special handling to avoid a crash when running 'bootefi hello'.
Signed-off-by: Simon Glass sjg@chromium.org ---
lib/efi_loader/efi_acpi.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/lib/efi_loader/efi_acpi.c b/lib/efi_loader/efi_acpi.c index 016bbf6db33..9d101aa843e 100644 --- a/lib/efi_loader/efi_acpi.c +++ b/lib/efi_loader/efi_acpi.c @@ -8,6 +8,7 @@ #include <common.h> #include <efi_loader.h> #include <log.h> +#include <mapmem.h> #include <acpi/acpi_table.h>
static const efi_guid_t acpi_guid = EFI_ACPI_TABLE_GUID; @@ -22,6 +23,7 @@ efi_status_t efi_acpi_register(void) /* Map within the low 32 bits, to allow for 32bit ACPI tables */ u64 acpi = U32_MAX; efi_status_t ret; + ulong addr;
/* Reserve 64kiB page for ACPI */ ret = efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS, @@ -34,7 +36,8 @@ efi_status_t efi_acpi_register(void) * a 4k-aligned address, so it is safe to assume that * write_acpi_tables() will write the table at that address. */ - write_acpi_tables((ulong)acpi); + addr = map_to_sysmem((void *)(ulong)acpi); + write_acpi_tables(addr);
/* And expose them to our EFI payload */ return efi_install_configuration_table(&acpi_guid,

On 12/1/21 17:02, Simon Glass wrote:
The current EFI implementation confuses pointers and addresses. Normally we can get away with this but in the case of sandbox it causes failures.
Despite the fact that efi_allocate_pages() returns a u64, it is actually a pointer, not an address. Add special handling to avoid a crash when running 'bootefi hello'.
Signed-off-by: Simon Glass sjg@chromium.org
lib/efi_loader/efi_acpi.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/lib/efi_loader/efi_acpi.c b/lib/efi_loader/efi_acpi.c index 016bbf6db33..9d101aa843e 100644 --- a/lib/efi_loader/efi_acpi.c +++ b/lib/efi_loader/efi_acpi.c @@ -8,6 +8,7 @@ #include <common.h> #include <efi_loader.h> #include <log.h> +#include <mapmem.h> #include <acpi/acpi_table.h>
static const efi_guid_t acpi_guid = EFI_ACPI_TABLE_GUID; @@ -22,6 +23,7 @@ efi_status_t efi_acpi_register(void) /* Map within the low 32 bits, to allow for 32bit ACPI tables */ u64 acpi = U32_MAX; efi_status_t ret;
ulong addr;
/* Reserve 64kiB page for ACPI */ ret = efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
@@ -34,7 +36,8 @@ efi_status_t efi_acpi_register(void) * a 4k-aligned address, so it is safe to assume that * write_acpi_tables() will write the table at that address. */
- write_acpi_tables((ulong)acpi);
- addr = map_to_sysmem((void *)(ulong)acpi);
Please, don't pollute general code with sandbox specific stuff where this can be avoided.
write_acpi_tables() anyway converts to a pointer. We should not convert twice. Correct the parameter of write_acpi_tables() instead to expect a pointer.
Best regards
Heinrich
write_acpi_tables(addr);
/* And expose them to our EFI payload */ return efi_install_configuration_table(&acpi_guid,

Hi Heinrich,
On Wed, 1 Dec 2021 at 11:13, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 12/1/21 17:02, Simon Glass wrote:
The current EFI implementation confuses pointers and addresses. Normally we can get away with this but in the case of sandbox it causes failures.
Despite the fact that efi_allocate_pages() returns a u64, it is actually a pointer, not an address. Add special handling to avoid a crash when running 'bootefi hello'.
Signed-off-by: Simon Glass sjg@chromium.org
lib/efi_loader/efi_acpi.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/lib/efi_loader/efi_acpi.c b/lib/efi_loader/efi_acpi.c index 016bbf6db33..9d101aa843e 100644 --- a/lib/efi_loader/efi_acpi.c +++ b/lib/efi_loader/efi_acpi.c @@ -8,6 +8,7 @@ #include <common.h> #include <efi_loader.h> #include <log.h> +#include <mapmem.h> #include <acpi/acpi_table.h>
static const efi_guid_t acpi_guid = EFI_ACPI_TABLE_GUID; @@ -22,6 +23,7 @@ efi_status_t efi_acpi_register(void) /* Map within the low 32 bits, to allow for 32bit ACPI tables */ u64 acpi = U32_MAX; efi_status_t ret;
ulong addr; /* Reserve 64kiB page for ACPI */ ret = efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
@@ -34,7 +36,8 @@ efi_status_t efi_acpi_register(void) * a 4k-aligned address, so it is safe to assume that * write_acpi_tables() will write the table at that address. */
write_acpi_tables((ulong)acpi);
addr = map_to_sysmem((void *)(ulong)acpi);
Please, don't pollute general code with sandbox specific stuff where this can be avoided.
write_acpi_tables() anyway converts to a pointer. We should not convert twice. Correct the parameter of write_acpi_tables() instead to expect a pointer.
I don't want to use pointers to pass addresses. It is not the common approach in U-Boot. We use ulong to pass addresses.
Re the need for this change, I beg to differ, and the crash shows that I am right :-)
Don't you think it is odd that the EFI allocation routine returns a u64 instead of a void *, like malloc()? If that were fixed, then this code would make more sense. I think we talked about it before.
Regards, Simon

Hi Heinrich,
On Wed, 1 Dec 2021 at 11:13, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 12/1/21 17:02, Simon Glass wrote:
The current EFI implementation confuses pointers and addresses. Normally we can get away with this but in the case of sandbox it causes failures.
Despite the fact that efi_allocate_pages() returns a u64, it is actually a pointer, not an address. Add special handling to avoid a crash when running 'bootefi hello'.
Signed-off-by: Simon Glass sjg@chromium.org
lib/efi_loader/efi_acpi.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
Applied to u-boot-dm, thanks!

Rather than keying everything off ACPIGEN, use the main GENERATE_ACPI_TABLE option to determine whether the core ACPI code is included. Make sure these option are not enabled in SPL/TPL since we never generate tables there.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/Kconfig | 1 + arch/x86/lib/Makefile | 2 +- lib/Makefile | 2 +- lib/acpi/Makefile | 8 ++++---- 4 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/arch/Kconfig b/arch/Kconfig index 57f72be25a7..a978503d3e2 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -196,6 +196,7 @@ config SANDBOX imply PHY_FIXED imply DM_DSA imply CMD_EXTENSION + imply GENERATE_ACPI_TABLE
config SH bool "SuperH architecture" diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 18757b29aa9..61b3f6ad352 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -41,7 +41,7 @@ obj-y += acpi.o obj-$(CONFIG_HAVE_ACPI_RESUME) += acpi_s3.o ifndef CONFIG_QEMU obj-y += acpigen.o -obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi_table.o +obj-$(CONFIG_$(SPL_TPL_)GENERATE_ACPI_TABLE) += acpi_table.o endif obj-y += tables.o ifndef CONFIG_SPL_BUILD diff --git a/lib/Makefile b/lib/Makefile index 5ddbc77ed6d..b54b7deb5ac 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -58,7 +58,7 @@ obj-$(CONFIG_TPM_V1) += tpm-v1.o obj-$(CONFIG_TPM_V2) += tpm-v2.o endif
-obj-$(CONFIG_$(SPL_)ACPIGEN) += acpi/ +obj-$(CONFIG_$(SPL_TPL_)GENERATE_ACPI_TABLE) += acpi/ obj-$(CONFIG_$(SPL_)MD5) += md5.o obj-$(CONFIG_ECDSA) += ecdsa/ obj-$(CONFIG_$(SPL_)RSA) += rsa/ diff --git a/lib/acpi/Makefile b/lib/acpi/Makefile index 5c2f793701f..f5d58aba908 100644 --- a/lib/acpi/Makefile +++ b/lib/acpi/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0+ #
-obj-y += acpigen.o -obj-y += acpi_device.o -obj-y += acpi_dp.o -obj-y += acpi_table.o +obj-$(CONFIG_$(SPL_)ACPIGEN) += acpigen.o +obj-$(CONFIG_$(SPL_)ACPIGEN) += acpi_device.o +obj-$(CONFIG_$(SPL_)ACPIGEN) += acpi_dp.o +obj-$(CONFIG_$(SPL_)ACPIGEN) += acpi_table.o

Some .asl files include others using the iasl 'include' directive. This needs to be able to find the files referenced.
For an out-of-tree build the source directory is not the current directory. Moreover, U-Boot preprocesses the input file and puts the result in the output directory. So iasl does not know where the real source file came from.
Add a -I option to produce the correct behaviour. We could add an option to not preprocess the .asl source, but for now that seems unnecessary.
Signed-off-by: Simon Glass sjg@chromium.org ---
scripts/Makefile.lib | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 39f03398ed8..0aa8953a720 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -438,7 +438,8 @@ quiet_cmd_acpi_c_asl= ASL $< cmd_acpi_c_asl= \ $(CPP) -x assembler-with-cpp -D__ASSEMBLY__ -D__ACPI__ \ -P $(UBOOTINCLUDE) -o $(ASL_TMP) $< && \ - iasl -p $@ -tc $(ASL_TMP) $(if $(KBUILD_VERBOSE:1=), >/dev/null) && \ + iasl -p $@ -I $(srctree)/board/$(BOARDDIR) -tc $(ASL_TMP) \ + $(if $(KBUILD_VERBOSE:1=), >/dev/null) && \ mv $(patsubst %.c,%.hex,$@) $@
$(obj)/dsdt.c: $(src)/dsdt.asl

Some .asl files include others using the iasl 'include' directive. This needs to be able to find the files referenced.
For an out-of-tree build the source directory is not the current directory. Moreover, U-Boot preprocesses the input file and puts the result in the output directory. So iasl does not know where the real source file came from.
Add a -I option to produce the correct behaviour. We could add an option to not preprocess the .asl source, but for now that seems unnecessary.
Signed-off-by: Simon Glass sjg@chromium.org ---
scripts/Makefile.lib | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
Applied to u-boot-dm, thanks!

This function is not x86-specific so move it into the common header file.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/include/asm/acpi_table.h | 1 - include/acpi/acpi_table.h | 8 ++++++++ 2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/arch/x86/include/asm/acpi_table.h b/arch/x86/include/asm/acpi_table.h index d5c8805df38..b9c8911b514 100644 --- a/arch/x86/include/asm/acpi_table.h +++ b/arch/x86/include/asm/acpi_table.h @@ -24,7 +24,6 @@ struct acpi_table_header;
/* These can be used by the target port */
-void acpi_fill_header(struct acpi_table_header *header, char *signature); void acpi_create_fadt(struct acpi_fadt *fadt, struct acpi_facs *facs, void *dsdt); int acpi_create_madt_lapics(u32 current); diff --git a/include/acpi/acpi_table.h b/include/acpi/acpi_table.h index a28eb71f4d7..9e43849259c 100644 --- a/include/acpi/acpi_table.h +++ b/include/acpi/acpi_table.h @@ -698,6 +698,14 @@ void acpi_setup_base_tables(struct acpi_ctx *ctx, void *start); void acpi_write_rsdp(struct acpi_rsdp *rsdp, struct acpi_rsdt *rsdt, struct acpi_xsdt *xsdt);
+/** + * acpi_fill_header() - Set up a table header + * + * @header: Pointer to header to set up + * @signature: 4-character signature to use (e.g. "FACS") + */ +void acpi_fill_header(struct acpi_table_header *header, char *signature); + #endif /* !__ACPI__*/
#include <asm/acpi_table.h>

This function is not x86-specific so move it into the common header file.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/include/asm/acpi_table.h | 1 - include/acpi/acpi_table.h | 8 ++++++++ 2 files changed, 8 insertions(+), 1 deletion(-)
Applied to u-boot-dm, thanks!

It is useful to record the start of an ACPI table so that offsets from that point can be easily calculated.
Add this to the context and set it before calling the writer method.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/core/acpi.c | 5 ++--- include/dm/acpi.h | 4 ++++ 2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/core/acpi.c b/drivers/core/acpi.c index 2176d8b8365..35a317fd2b0 100644 --- a/drivers/core/acpi.c +++ b/drivers/core/acpi.c @@ -266,19 +266,18 @@ int acpi_recurse_method(struct acpi_ctx *ctx, struct udevice *parent,
func = acpi_get_method(parent, method); if (func) { - void *start = ctx->current; - log_debug("- method %d, %s %p\n", method, parent->name, func); ret = device_of_to_plat(parent); if (ret) return log_msg_ret("ofdata", ret); + ctx->tab_start = ctx->current; ret = func(parent, ctx); if (ret) return log_msg_ret("func", ret);
/* Add the item to the internal list */ if (type != TYPE_NONE) { - ret = acpi_add_item(ctx, parent, type, start); + ret = acpi_add_item(ctx, parent, type, ctx->tab_start); if (ret) return log_msg_ret("add", ret); } diff --git a/include/dm/acpi.h b/include/dm/acpi.h index 7f1f2ef2cb6..22f62bc0f2a 100644 --- a/include/dm/acpi.h +++ b/include/dm/acpi.h @@ -43,6 +43,9 @@ enum acpi_dump_option { * * @base: Base address of ACPI tables * @current: Current address for writing + * @tab_start: Address of start of the table being written. This is set up + * before the writer or driver method is called. It must not be changed by the + * method * @rsdp: Pointer to the Root System Description Pointer, typically used when * adding a new table. The RSDP holds pointers to the RSDT and XSDT. * @rsdt: Pointer to the Root System Description Table @@ -56,6 +59,7 @@ enum acpi_dump_option { struct acpi_ctx { void *base; void *current; + void *tab_start; struct acpi_rsdp *rsdp; struct acpi_rsdt *rsdt; struct acpi_xsdt *xsdt;

It is useful to record the start of an ACPI table so that offsets from that point can be easily calculated.
Add this to the context and set it before calling the writer method.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/core/acpi.c | 5 ++--- include/dm/acpi.h | 4 ++++ 2 files changed, 6 insertions(+), 3 deletions(-)
Applied to u-boot-dm, thanks!

At present we call lots of functions to generate the required ACPI tables. It would be better to standardise these functions and allow them to be automatically collected and used when needed.
Add a linker list to handle this.
Signed-off-by: Simon Glass sjg@chromium.org ---
include/dm/acpi.h | 57 ++++++++++++++++++++++++++ lib/acpi/acpi_writer.c | 91 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 lib/acpi/acpi_writer.c
diff --git a/include/dm/acpi.h b/include/dm/acpi.h index 22f62bc0f2a..c404c01b621 100644 --- a/include/dm/acpi.h +++ b/include/dm/acpi.h @@ -27,6 +27,8 @@
#if !defined(__ACPI__)
+#include <linker_lists.h> + struct nhlt; struct udevice;
@@ -68,6 +70,48 @@ struct acpi_ctx { int ltop; };
+/** + * enum acpi_writer_flags_t - flags to use for the ACPI writers + */ +enum acpi_writer_flags_t { + ACPIWF_ALIGN64_, +}; + +struct acpi_writer; + +/** + * acpi_writer_func() - Function that can write an ACPI table + * + * @ctx: ACPI context to use for writing + * @entry: Linker-list entry for this writer + * @return 0 if OK, -ve on error + */ +typedef int (*acpi_writer_func)(struct acpi_ctx *ctx, + const struct acpi_writer *entry); + +/** + * struct acpi_writer - an ACPI table that can be written + * + * @name: Name of the writer + * @table: Table name that is generated (e.g. "DSDT") + * @h_write: Writer function + */ +struct acpi_writer { + const char *name; + const char *table; + acpi_writer_func h_write; + int flags; +}; + +/* Declare a new ACPI table writer */ +#define ACPI_WRITER(_name, _table, _write, _flags) \ + ll_entry_declare(struct acpi_writer, _name, acpi_writer) = { \ + .name = #_name, \ + .table = _table, \ + .h_write = _write, \ + .flags = _flags, \ + } + /** * struct acpi_ops - ACPI operations supported by driver model */ @@ -240,6 +284,19 @@ int acpi_get_path(const struct udevice *dev, char *out_path, int maxlen); */ void acpi_reset_items(void);
+/** + * acpi_write_one() - Call a single ACPI writer entry + * + * This handles aligning the context afterwards, if the entry flags indicate + * that. + * + * @ctx: ACPI context to use + * @entry: Entry to call + * @return 0 if OK, -ENOENT if this writer produced an empty entry, other -ve + * value on error + */ +int acpi_write_one(struct acpi_ctx *ctx, const struct acpi_writer *entry); + #endif /* __ACPI__ */
#endif diff --git a/lib/acpi/acpi_writer.c b/lib/acpi/acpi_writer.c new file mode 100644 index 00000000000..5ddffc87343 --- /dev/null +++ b/lib/acpi/acpi_writer.c @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Handles writing the declared ACPI tables + * + * Copyright 2021 Google LLC + */ + +#define LOG_CATEGORY LOGC_ACPI + +#include <common.h> +#include <log.h> +#include <malloc.h> +#include <mapmem.h> +#include <acpi/acpi_table.h> +#include <asm/global_data.h> +#include <dm/acpi.h> + +DECLARE_GLOBAL_DATA_PTR; + +int acpi_write_one(struct acpi_ctx *ctx, const struct acpi_writer *entry) +{ + int ret; + + log_debug("%s: writing table '%s'\n", entry->name, + entry->table); + ctx->tab_start = ctx->current; + ret = entry->h_write(ctx, entry); + if (ret == -ENOENT) { + log_debug("%s: Omitted due to being empty\n", + entry->name); + ret = 0; + ctx->current = ctx->tab_start; /* drop the table */ + return ret; + } + if (ret) + return log_msg_ret("write", ret); + + acpi_align(ctx); + + return 0; +} + +static int acpi_write_all(struct acpi_ctx *ctx) +{ + const struct acpi_writer *writer = + ll_entry_start(struct acpi_writer, acpi_writer); + const int n_ents = ll_entry_count(struct acpi_writer, acpi_writer); + const struct acpi_writer *entry; + int ret; + + for (entry = writer; entry != writer + n_ents; entry++) { + ret = acpi_write_one(ctx, entry); + if (ret && ret != -ENOENT) + return log_msg_ret("one", ret); + } + + return 0; +} + +/* + * QEMU's version of write_acpi_tables is defined in drivers/misc/qfw.c + */ +ulong write_acpi_tables(ulong start_addr) +{ + struct acpi_ctx *ctx; + ulong addr; + void *start; + int ret; + + ctx = calloc(1, sizeof(*ctx)); + if (!ctx) + return log_msg_ret("mem", -ENOMEM); + gd->acpi_ctx = ctx; + + start = map_sysmem(start_addr, 0); + + log_debug("ACPI: Writing ACPI tables at %lx\n", start_addr); + + acpi_reset_items(); + + ret = acpi_write_all(ctx); + if (ret) { + log_err("Failed to write ACPI tables (err=%d)\n", ret); + return log_msg_ret("write", -ENOMEM); + } + + addr = map_to_sysmem(ctx->current); + log_debug("ACPI current = %lx\n", addr); + + return addr; +}

At present we call lots of functions to generate the required ACPI tables. It would be better to standardise these functions and allow them to be automatically collected and used when needed.
Add a linker list to handle this.
Signed-off-by: Simon Glass sjg@chromium.org ---
include/dm/acpi.h | 57 ++++++++++++++++++++++++++ lib/acpi/acpi_writer.c | 91 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 lib/acpi/acpi_writer.c
Applied to u-boot-dm, thanks!

At present acpi_setup_base_tables() both sets up the ACPI context and writes out the base tables.
We want to use an ACPI writer to write the base tables, so split this function into two, with acpi_setup_ctx() doing the context set, and acpi_setup_base_tables() just doing the base tables.
Disable the writer's write_acpi_tables() function for now, to avoid build errors. It is enabled in a following patch.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/lib/acpi_table.c | 6 +++--- include/acpi/acpi_table.h | 10 +++++----- include/dm/acpi.h | 12 ++++++++++++ lib/acpi/Makefile | 1 + lib/acpi/acpi_table.c | 11 ++--------- lib/acpi/acpi_writer.c | 22 ++++++++++++++++------ test/dm/acpi.c | 31 ++++++++++++++++++++++++++----- 7 files changed, 65 insertions(+), 28 deletions(-)
diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c index 3f847711e2b..f57323b5c3f 100644 --- a/arch/x86/lib/acpi_table.c +++ b/arch/x86/lib/acpi_table.c @@ -522,17 +522,17 @@ ulong write_acpi_tables(ulong start_addr) int ret; int i;
- ctx = calloc(1, sizeof(*ctx)); + ctx = malloc(sizeof(*ctx)); if (!ctx) return log_msg_ret("mem", -ENOMEM); - gd->acpi_ctx = ctx;
start = map_sysmem(start_addr, 0);
debug("ACPI: Writing ACPI tables at %lx\n", start_addr);
acpi_reset_items(); - acpi_setup_base_tables(ctx, start); + acpi_setup_ctx(ctx, start); + acpi_setup_base_tables(ctx);
debug("ACPI: * FACS\n"); facs = ctx->current; diff --git a/include/acpi/acpi_table.h b/include/acpi/acpi_table.h index 9e43849259c..a720017283d 100644 --- a/include/acpi/acpi_table.h +++ b/include/acpi/acpi_table.h @@ -679,14 +679,14 @@ void acpi_inc_align(struct acpi_ctx *ctx, uint amount); int acpi_add_table(struct acpi_ctx *ctx, void *table);
/** - * acpi_setup_base_tables() - Set up context along with RSDP, RSDT and XSDT + * acpi_setup_base_tables() - Set up base tables - RSDP, RSDT and XSDT * - * Set up the context with the given start position. Some basic tables are - * always needed, so set them up as well. + * Writes the basic tables to the given context, which must first be set up with + * acpi_setup_ctx(). * - * @ctx: Context to set up + * @ctx: Context to write base tables to */ -void acpi_setup_base_tables(struct acpi_ctx *ctx, void *start); +void acpi_setup_base_tables(struct acpi_ctx *ctx);
/** * acpi_write_rsdp() - Write out an RSDP indicating where the ACPI tables are diff --git a/include/dm/acpi.h b/include/dm/acpi.h index c404c01b621..5069e879268 100644 --- a/include/dm/acpi.h +++ b/include/dm/acpi.h @@ -297,6 +297,18 @@ void acpi_reset_items(void); */ int acpi_write_one(struct acpi_ctx *ctx, const struct acpi_writer *entry);
+/** + * acpi_setup_ctx() - Set up a new ACPI context + * + * This zeros the context and sets up the base and current pointers, ensuring + * that they are aligned. Then it writes the acpi_start and acpi_ctx values in + * global_data + * + * @ctx: ACPI context to set up + * @start: Start address for ACPI table + */ +void acpi_setup_ctx(struct acpi_ctx *ctx, ulong start); + #endif /* __ACPI__ */
#endif diff --git a/lib/acpi/Makefile b/lib/acpi/Makefile index f5d58aba908..1318e83dfc4 100644 --- a/lib/acpi/Makefile +++ b/lib/acpi/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_$(SPL_)ACPIGEN) += acpigen.o obj-$(CONFIG_$(SPL_)ACPIGEN) += acpi_device.o obj-$(CONFIG_$(SPL_)ACPIGEN) += acpi_dp.o obj-$(CONFIG_$(SPL_)ACPIGEN) += acpi_table.o +obj-y += acpi_writer.o diff --git a/lib/acpi/acpi_table.c b/lib/acpi/acpi_table.c index 3a72718df89..284b5a9afb8 100644 --- a/lib/acpi/acpi_table.c +++ b/lib/acpi/acpi_table.c @@ -253,15 +253,8 @@ static void acpi_write_xsdt(struct acpi_xsdt *xsdt) sizeof(struct acpi_xsdt)); }
-void acpi_setup_base_tables(struct acpi_ctx *ctx, void *start) +void acpi_setup_base_tables(struct acpi_ctx *ctx) { - ctx->base = start; - ctx->current = start; - - /* Align ACPI tables to 16 byte */ - acpi_align(ctx); - gd_set_acpi_start(map_to_sysmem(ctx->current)); - /* We need at least an RSDP and an RSDT Table */ ctx->rsdp = ctx->current; acpi_inc_align(ctx, sizeof(struct acpi_rsdp)); @@ -271,7 +264,7 @@ void acpi_setup_base_tables(struct acpi_ctx *ctx, void *start) acpi_inc_align(ctx, sizeof(struct acpi_xsdt));
/* clear all table memory */ - memset((void *)start, '\0', ctx->current - start); + memset(ctx->base, '\0', ctx->current - ctx->base);
acpi_write_rsdp(ctx->rsdp, ctx->rsdt, ctx->xsdt); acpi_write_rsdt(ctx->rsdt); diff --git a/lib/acpi/acpi_writer.c b/lib/acpi/acpi_writer.c index 5ddffc87343..7779bf38aab 100644 --- a/lib/acpi/acpi_writer.c +++ b/lib/acpi/acpi_writer.c @@ -60,23 +60,20 @@ static int acpi_write_all(struct acpi_ctx *ctx) /* * QEMU's version of write_acpi_tables is defined in drivers/misc/qfw.c */ -ulong write_acpi_tables(ulong start_addr) +ulong new_write_acpi_tables(ulong start_addr) { struct acpi_ctx *ctx; ulong addr; - void *start; int ret;
- ctx = calloc(1, sizeof(*ctx)); + ctx = malloc(sizeof(*ctx)); if (!ctx) return log_msg_ret("mem", -ENOMEM); - gd->acpi_ctx = ctx; - - start = map_sysmem(start_addr, 0);
log_debug("ACPI: Writing ACPI tables at %lx\n", start_addr);
acpi_reset_items(); + acpi_setup_ctx(ctx, start_addr);
ret = acpi_write_all(ctx); if (ret) { @@ -89,3 +86,16 @@ ulong write_acpi_tables(ulong start_addr)
return addr; } + +void acpi_setup_ctx(struct acpi_ctx *ctx, ulong start) +{ + gd->acpi_ctx = ctx; + memset(ctx, '\0', sizeof(*ctx)); + + /* Align ACPI tables to 16-byte boundary */ + start = ALIGN(start, 16); + ctx->base = map_sysmem(start, 0); + ctx->current = ctx->base; + + gd_set_acpi_start(start); +} diff --git a/test/dm/acpi.c b/test/dm/acpi.c index 804124df9e9..a1d70b58597 100644 --- a/test/dm/acpi.c +++ b/test/dm/acpi.c @@ -45,6 +45,22 @@ struct testacpi_plat { bool no_name; };
+/** + * setup_ctx_and_base_tables() - Set up context along with RSDP, RSDT and XSDT + * + * Set up the context with the given start position. Some basic tables are + * always needed, so set them up as well. + * + * @ctx: Context to set up + */ +static int setup_ctx_and_base_tables(struct acpi_ctx *ctx, ulong start) +{ + acpi_setup_ctx(ctx, start); + acpi_setup_base_tables(ctx); + + return 0; +} + static int testacpi_write_tables(const struct udevice *dev, struct acpi_ctx *ctx) { @@ -240,13 +256,15 @@ static int dm_test_acpi_write_tables(struct unit_test_state *uts) { struct acpi_dmar *dmar; struct acpi_ctx ctx; + ulong addr; void *buf; int i;
buf = malloc(BUF_SIZE); ut_assertnonnull(buf); + addr = map_to_sysmem(buf);
- acpi_setup_base_tables(&ctx, buf); + setup_ctx_and_base_tables(&ctx, addr); dmar = ctx.current; ut_assertok(acpi_write_dev_tables(&ctx));
@@ -312,6 +330,7 @@ static int dm_test_acpi_setup_base_tables(struct unit_test_state *uts) struct acpi_xsdt *xsdt; struct acpi_ctx ctx; void *buf, *end; + ulong addr;
/* * Use an unaligned address deliberately, by allocating an aligned @@ -319,7 +338,8 @@ static int dm_test_acpi_setup_base_tables(struct unit_test_state *uts) */ buf = memalign(64, BUF_SIZE); ut_assertnonnull(buf); - acpi_setup_base_tables(&ctx, buf + 4); + addr = map_to_sysmem(buf); + setup_ctx_and_base_tables(&ctx, addr + 4); ut_asserteq(map_to_sysmem(PTR_ALIGN(buf + 4, 16)), gd_acpi_start());
rsdp = buf + 16; @@ -361,13 +381,13 @@ static int dm_test_acpi_cmd_list(struct unit_test_state *uts)
buf = memalign(16, BUF_SIZE); ut_assertnonnull(buf); - acpi_setup_base_tables(&ctx, buf); + addr = map_to_sysmem(buf); + setup_ctx_and_base_tables(&ctx, addr);
ut_assertok(acpi_write_dev_tables(&ctx));
console_record_reset(); run_command("acpi list", 0); - addr = (ulong)map_to_sysmem(buf); ut_assert_nextline("ACPI tables start at %lx", addr); ut_assert_nextline("RSDP %08lx %06zx (v02 U-BOOT)", addr, sizeof(struct acpi_rsdp)); @@ -403,7 +423,8 @@ static int dm_test_acpi_cmd_dump(struct unit_test_state *uts)
buf = memalign(16, BUF_SIZE); ut_assertnonnull(buf); - acpi_setup_base_tables(&ctx, buf); + addr = map_to_sysmem(buf); + setup_ctx_and_base_tables(&ctx, addr);
ut_assertok(acpi_write_dev_tables(&ctx));

At present acpi_setup_base_tables() both sets up the ACPI context and writes out the base tables.
We want to use an ACPI writer to write the base tables, so split this function into two, with acpi_setup_ctx() doing the context set, and acpi_setup_base_tables() just doing the base tables.
Disable the writer's write_acpi_tables() function for now, to avoid build errors. It is enabled in a following patch.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/lib/acpi_table.c | 6 +++--- include/acpi/acpi_table.h | 10 +++++----- include/dm/acpi.h | 12 ++++++++++++ lib/acpi/Makefile | 1 + lib/acpi/acpi_table.c | 11 ++--------- lib/acpi/acpi_writer.c | 22 ++++++++++++++++------ test/dm/acpi.c | 31 ++++++++++++++++++++++++++----- 7 files changed, 65 insertions(+), 28 deletions(-)
Applied to u-boot-dm, thanks!

Use the new ACPI writer to write the ACPI tables. At present this is all done in one monolithic function. Future work will split this out.
Unfortunately the QFW write_acpi_tables() function conflicts with the 'writer' version, so disable that for sandbox.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/lib/acpi_table.c | 21 ++++----------------- drivers/misc/qfw.c | 2 +- lib/acpi/acpi_writer.c | 4 +++- test/dm/acpi.c | 6 +++--- 4 files changed, 11 insertions(+), 22 deletions(-)
diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c index f57323b5c3f..321faaeb185 100644 --- a/arch/x86/lib/acpi_table.c +++ b/arch/x86/lib/acpi_table.c @@ -503,10 +503,10 @@ static int acpi_create_ssdt(struct acpi_ctx *ctx, /* * QEMU's version of write_acpi_tables is defined in drivers/misc/qfw.c */ -ulong write_acpi_tables(ulong start_addr) +static int write_acpi_tables_x86(struct acpi_ctx *ctx, + const struct acpi_writer *entry) { const int thl = sizeof(struct acpi_table_header); - struct acpi_ctx *ctx; struct acpi_facs *facs; struct acpi_table_header *dsdt; struct acpi_fadt *fadt; @@ -516,22 +516,11 @@ ulong write_acpi_tables(ulong start_addr) struct acpi_madt *madt; struct acpi_csrt *csrt; struct acpi_spcr *spcr; - void *start; int aml_len; ulong addr; int ret; int i;
- ctx = malloc(sizeof(*ctx)); - if (!ctx) - return log_msg_ret("mem", -ENOMEM); - - start = map_sysmem(start_addr, 0); - - debug("ACPI: Writing ACPI tables at %lx\n", start_addr); - - acpi_reset_items(); - acpi_setup_ctx(ctx, start); acpi_setup_base_tables(ctx);
debug("ACPI: * FACS\n"); @@ -674,14 +663,12 @@ ulong write_acpi_tables(ulong start_addr)
acpi_write_dev_tables(ctx);
- addr = map_to_sysmem(ctx->current); - debug("current = %lx\n", addr); - acpi_rsdp_addr = (unsigned long)ctx->rsdp; debug("ACPI: done\n");
- return addr; + return 0; } +ACPI_WRITER(x86, NULL, write_acpi_tables_x86, 0);
ulong acpi_get_rsdp_addr(void) { diff --git a/drivers/misc/qfw.c b/drivers/misc/qfw.c index a298e5cf727..677841aac5e 100644 --- a/drivers/misc/qfw.c +++ b/drivers/misc/qfw.c @@ -19,7 +19,7 @@ #include <asm/tables.h> #endif
-#ifdef CONFIG_GENERATE_ACPI_TABLE +#if defined(CONFIG_GENERATE_ACPI_TABLE) && !defined(CONFIG_SANDBOX) /* * This function allocates memory for ACPI tables * diff --git a/lib/acpi/acpi_writer.c b/lib/acpi/acpi_writer.c index 7779bf38aab..53fc753aeeb 100644 --- a/lib/acpi/acpi_writer.c +++ b/lib/acpi/acpi_writer.c @@ -40,6 +40,7 @@ int acpi_write_one(struct acpi_ctx *ctx, const struct acpi_writer *entry) return 0; }
+#ifndef CONFIG_QEMU static int acpi_write_all(struct acpi_ctx *ctx) { const struct acpi_writer *writer = @@ -60,7 +61,7 @@ static int acpi_write_all(struct acpi_ctx *ctx) /* * QEMU's version of write_acpi_tables is defined in drivers/misc/qfw.c */ -ulong new_write_acpi_tables(ulong start_addr) +ulong write_acpi_tables(ulong start_addr) { struct acpi_ctx *ctx; ulong addr; @@ -86,6 +87,7 @@ ulong new_write_acpi_tables(ulong start_addr)
return addr; } +#endif /* QEMU */
void acpi_setup_ctx(struct acpi_ctx *ctx, ulong start) { diff --git a/test/dm/acpi.c b/test/dm/acpi.c index a1d70b58597..49b71bec3c0 100644 --- a/test/dm/acpi.c +++ b/test/dm/acpi.c @@ -322,8 +322,8 @@ static int dm_test_acpi_basic(struct unit_test_state *uts) } DM_TEST(dm_test_acpi_basic, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
-/* Test acpi_setup_base_tables */ -static int dm_test_acpi_setup_base_tables(struct unit_test_state *uts) +/* Test setup_ctx_and_base_tables */ +static int dm_test_setup_ctx_and_base_tables(struct unit_test_state *uts) { struct acpi_rsdp *rsdp; struct acpi_rsdt *rsdt; @@ -369,7 +369,7 @@ static int dm_test_acpi_setup_base_tables(struct unit_test_state *uts)
return 0; } -DM_TEST(dm_test_acpi_setup_base_tables, +DM_TEST(dm_test_setup_ctx_and_base_tables, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
/* Test 'acpi list' command */

Use the new ACPI writer to write the ACPI tables. At present this is all done in one monolithic function. Future work will split this out.
Unfortunately the QFW write_acpi_tables() function conflicts with the 'writer' version, so disable that for sandbox.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/lib/acpi_table.c | 21 ++++----------------- drivers/misc/qfw.c | 2 +- lib/acpi/acpi_writer.c | 4 +++- test/dm/acpi.c | 6 +++--- 4 files changed, 11 insertions(+), 22 deletions(-)
Applied to u-boot-dm, thanks!

Use the new ACPI writer to write the base tables at the start of the area, moving this code from the x86 implementation.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/lib/acpi_table.c | 2 - include/acpi/acpi_table.h | 10 ----- include/dm/acpi.h | 23 +++++++++- lib/acpi/Makefile | 5 +++ lib/acpi/acpi_table.c | 75 ------------------------------- lib/acpi/acpi_writer.c | 5 ++- lib/acpi/base.c | 92 +++++++++++++++++++++++++++++++++++++++ test/dm/acpi.c | 17 +++++--- 8 files changed, 133 insertions(+), 96 deletions(-) create mode 100644 lib/acpi/base.c
diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c index 321faaeb185..e6aa3c5a709 100644 --- a/arch/x86/lib/acpi_table.c +++ b/arch/x86/lib/acpi_table.c @@ -521,8 +521,6 @@ static int write_acpi_tables_x86(struct acpi_ctx *ctx, int ret; int i;
- acpi_setup_base_tables(ctx); - debug("ACPI: * FACS\n"); facs = ctx->current; acpi_inc_align(ctx, sizeof(struct acpi_facs)); diff --git a/include/acpi/acpi_table.h b/include/acpi/acpi_table.h index a720017283d..87674e2cc0d 100644 --- a/include/acpi/acpi_table.h +++ b/include/acpi/acpi_table.h @@ -678,16 +678,6 @@ void acpi_inc_align(struct acpi_ctx *ctx, uint amount); */ int acpi_add_table(struct acpi_ctx *ctx, void *table);
-/** - * acpi_setup_base_tables() - Set up base tables - RSDP, RSDT and XSDT - * - * Writes the basic tables to the given context, which must first be set up with - * acpi_setup_ctx(). - * - * @ctx: Context to write base tables to - */ -void acpi_setup_base_tables(struct acpi_ctx *ctx); - /** * acpi_write_rsdp() - Write out an RSDP indicating where the ACPI tables are * diff --git a/include/dm/acpi.h b/include/dm/acpi.h index 5069e879268..ac60b11116f 100644 --- a/include/dm/acpi.h +++ b/include/dm/acpi.h @@ -72,9 +72,11 @@ struct acpi_ctx {
/** * enum acpi_writer_flags_t - flags to use for the ACPI writers + * + * ACPIWF_ALIGN64 - align to 64 bytes after writing this one (default is 16) */ enum acpi_writer_flags_t { - ACPIWF_ALIGN64_, + ACPIWF_ALIGN64 = 1 << 0, };
struct acpi_writer; @@ -103,7 +105,7 @@ struct acpi_writer { int flags; };
-/* Declare a new ACPI table writer */ +/* Declare a new ACPI-table writer */ #define ACPI_WRITER(_name, _table, _write, _flags) \ ll_entry_declare(struct acpi_writer, _name, acpi_writer) = { \ .name = #_name, \ @@ -112,6 +114,10 @@ struct acpi_writer { .flags = _flags, \ }
+/* Get a pointer to a given ACPI-table writer */ +#define ACPI_WRITER_GET(_name) \ + ll_entry_get(struct acpi_writer, _name, acpi_writer) + /** * struct acpi_ops - ACPI operations supported by driver model */ @@ -309,6 +315,19 @@ int acpi_write_one(struct acpi_ctx *ctx, const struct acpi_writer *entry); */ void acpi_setup_ctx(struct acpi_ctx *ctx, ulong start);
+/** + * acpi_write_one() - Call a single ACPI writer entry + * + * This handles aligning the context afterwards, if the entry flags indicate + * that. + * + * @ctx: ACPI context to use + * @entry: Entry to call + * @return 0 if OK, -ENOENT if this writer produced an empty entry, other -ve + * value on error + */ +int acpi_write_one(struct acpi_ctx *ctx, const struct acpi_writer *entry); + #endif /* __ACPI__ */
#endif diff --git a/lib/acpi/Makefile b/lib/acpi/Makefile index 1318e83dfc4..4674a9287f6 100644 --- a/lib/acpi/Makefile +++ b/lib/acpi/Makefile @@ -6,3 +6,8 @@ obj-$(CONFIG_$(SPL_)ACPIGEN) += acpi_device.o obj-$(CONFIG_$(SPL_)ACPIGEN) += acpi_dp.o obj-$(CONFIG_$(SPL_)ACPIGEN) += acpi_table.o obj-y += acpi_writer.o + +# With QEMU the ACPI tables come from there, not from U-Boot +ifndef CONFIG_QEMU +obj-y += base.o +endif diff --git a/lib/acpi/acpi_table.c b/lib/acpi/acpi_table.c index 284b5a9afb8..f8642f99420 100644 --- a/lib/acpi/acpi_table.c +++ b/lib/acpi/acpi_table.c @@ -201,81 +201,6 @@ int acpi_add_table(struct acpi_ctx *ctx, void *table) return 0; }
-void acpi_write_rsdp(struct acpi_rsdp *rsdp, struct acpi_rsdt *rsdt, - struct acpi_xsdt *xsdt) -{ - memset(rsdp, 0, sizeof(struct acpi_rsdp)); - - memcpy(rsdp->signature, RSDP_SIG, 8); - memcpy(rsdp->oem_id, OEM_ID, 6); - - rsdp->length = sizeof(struct acpi_rsdp); - rsdp->rsdt_address = map_to_sysmem(rsdt); - - rsdp->xsdt_address = map_to_sysmem(xsdt); - rsdp->revision = ACPI_RSDP_REV_ACPI_2_0; - - /* Calculate checksums */ - rsdp->checksum = table_compute_checksum(rsdp, 20); - rsdp->ext_checksum = table_compute_checksum(rsdp, - sizeof(struct acpi_rsdp)); -} - -static void acpi_write_rsdt(struct acpi_rsdt *rsdt) -{ - struct acpi_table_header *header = &rsdt->header; - - /* Fill out header fields */ - acpi_fill_header(header, "RSDT"); - header->length = sizeof(struct acpi_rsdt); - header->revision = 1; - - /* Entries are filled in later, we come with an empty set */ - - /* Fix checksum */ - header->checksum = table_compute_checksum(rsdt, - sizeof(struct acpi_rsdt)); -} - -static void acpi_write_xsdt(struct acpi_xsdt *xsdt) -{ - struct acpi_table_header *header = &xsdt->header; - - /* Fill out header fields */ - acpi_fill_header(header, "XSDT"); - header->length = sizeof(struct acpi_xsdt); - header->revision = 1; - - /* Entries are filled in later, we come with an empty set */ - - /* Fix checksum */ - header->checksum = table_compute_checksum(xsdt, - sizeof(struct acpi_xsdt)); -} - -void acpi_setup_base_tables(struct acpi_ctx *ctx) -{ - /* We need at least an RSDP and an RSDT Table */ - ctx->rsdp = ctx->current; - acpi_inc_align(ctx, sizeof(struct acpi_rsdp)); - ctx->rsdt = ctx->current; - acpi_inc_align(ctx, sizeof(struct acpi_rsdt)); - ctx->xsdt = ctx->current; - acpi_inc_align(ctx, sizeof(struct acpi_xsdt)); - - /* clear all table memory */ - memset(ctx->base, '\0', ctx->current - ctx->base); - - acpi_write_rsdp(ctx->rsdp, ctx->rsdt, ctx->xsdt); - acpi_write_rsdt(ctx->rsdt); - acpi_write_xsdt(ctx->xsdt); - /* - * Per ACPI spec, the FACS table address must be aligned to a 64 byte - * boundary (Windows checks this, but Linux does not). - */ - acpi_align64(ctx); -} - void acpi_create_dbg2(struct acpi_dbg2_header *dbg2, int port_type, int port_subtype, struct acpi_gen_regaddr *address, u32 address_size, diff --git a/lib/acpi/acpi_writer.c b/lib/acpi/acpi_writer.c index 53fc753aeeb..d2505e6eaa4 100644 --- a/lib/acpi/acpi_writer.c +++ b/lib/acpi/acpi_writer.c @@ -35,7 +35,10 @@ int acpi_write_one(struct acpi_ctx *ctx, const struct acpi_writer *entry) if (ret) return log_msg_ret("write", ret);
- acpi_align(ctx); + if (entry->flags & ACPIWF_ALIGN64) + acpi_align64(ctx); + else + acpi_align(ctx);
return 0; } diff --git a/lib/acpi/base.c b/lib/acpi/base.c new file mode 100644 index 00000000000..3e8d703934e --- /dev/null +++ b/lib/acpi/base.c @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Write base ACPI tables + * + * Copyright 2021 Google LLC + */ + +#include <common.h> +#include <acpi/acpi_table.h> +#include <dm/acpi.h> +#include <mapmem.h> +#include <tables_csum.h> + +void acpi_write_rsdp(struct acpi_rsdp *rsdp, struct acpi_rsdt *rsdt, + struct acpi_xsdt *xsdt) +{ + memset(rsdp, 0, sizeof(struct acpi_rsdp)); + + memcpy(rsdp->signature, RSDP_SIG, 8); + memcpy(rsdp->oem_id, OEM_ID, 6); + + rsdp->length = sizeof(struct acpi_rsdp); + rsdp->rsdt_address = map_to_sysmem(rsdt); + + rsdp->xsdt_address = map_to_sysmem(xsdt); + rsdp->revision = ACPI_RSDP_REV_ACPI_2_0; + + /* Calculate checksums */ + rsdp->checksum = table_compute_checksum(rsdp, 20); + rsdp->ext_checksum = table_compute_checksum(rsdp, + sizeof(struct acpi_rsdp)); +} + +static void acpi_write_rsdt(struct acpi_rsdt *rsdt) +{ + struct acpi_table_header *header = &rsdt->header; + + /* Fill out header fields */ + acpi_fill_header(header, "RSDT"); + header->length = sizeof(struct acpi_rsdt); + header->revision = 1; + + /* Entries are filled in later, we come with an empty set */ + + /* Fix checksum */ + header->checksum = table_compute_checksum(rsdt, + sizeof(struct acpi_rsdt)); +} + +static void acpi_write_xsdt(struct acpi_xsdt *xsdt) +{ + struct acpi_table_header *header = &xsdt->header; + + /* Fill out header fields */ + acpi_fill_header(header, "XSDT"); + header->length = sizeof(struct acpi_xsdt); + header->revision = 1; + + /* Entries are filled in later, we come with an empty set */ + + /* Fix checksum */ + header->checksum = table_compute_checksum(xsdt, + sizeof(struct acpi_xsdt)); +} + +static int acpi_write_base(struct acpi_ctx *ctx, + const struct acpi_writer *entry) +{ + /* We need at least an RSDP and an RSDT Table */ + ctx->rsdp = ctx->current; + acpi_inc_align(ctx, sizeof(struct acpi_rsdp)); + ctx->rsdt = ctx->current; + acpi_inc_align(ctx, sizeof(struct acpi_rsdt)); + ctx->xsdt = ctx->current; + acpi_inc_align(ctx, sizeof(struct acpi_xsdt)); + + /* clear all table memory */ + memset(ctx->base, '\0', ctx->current - ctx->base); + + acpi_write_rsdp(ctx->rsdp, ctx->rsdt, ctx->xsdt); + acpi_write_rsdt(ctx->rsdt); + acpi_write_xsdt(ctx->xsdt); + + return 0; +} +/* + * Per ACPI spec, the FACS table address must be aligned to a 64-byte boundary + * (Windows checks this, but Linux does not). + * + * Use the '0' prefix to put this one first + */ +ACPI_WRITER(0base, NULL, acpi_write_base, ACPIWF_ALIGN64); diff --git a/test/dm/acpi.c b/test/dm/acpi.c index 49b71bec3c0..da728692528 100644 --- a/test/dm/acpi.c +++ b/test/dm/acpi.c @@ -53,10 +53,15 @@ struct testacpi_plat { * * @ctx: Context to set up */ -static int setup_ctx_and_base_tables(struct acpi_ctx *ctx, ulong start) +static int setup_ctx_and_base_tables(struct unit_test_state *uts, + struct acpi_ctx *ctx, ulong start) { + struct acpi_writer *entry = ACPI_WRITER_GET(0base); + acpi_setup_ctx(ctx, start); - acpi_setup_base_tables(ctx); + + ctx->tab_start = ctx->current; + ut_assertok(acpi_write_one(ctx, entry));
return 0; } @@ -264,7 +269,7 @@ static int dm_test_acpi_write_tables(struct unit_test_state *uts) ut_assertnonnull(buf); addr = map_to_sysmem(buf);
- setup_ctx_and_base_tables(&ctx, addr); + ut_assertok(setup_ctx_and_base_tables(uts, &ctx, addr)); dmar = ctx.current; ut_assertok(acpi_write_dev_tables(&ctx));
@@ -339,7 +344,7 @@ static int dm_test_setup_ctx_and_base_tables(struct unit_test_state *uts) buf = memalign(64, BUF_SIZE); ut_assertnonnull(buf); addr = map_to_sysmem(buf); - setup_ctx_and_base_tables(&ctx, addr + 4); + ut_assertok(setup_ctx_and_base_tables(uts, &ctx, addr + 4)); ut_asserteq(map_to_sysmem(PTR_ALIGN(buf + 4, 16)), gd_acpi_start());
rsdp = buf + 16; @@ -382,7 +387,7 @@ static int dm_test_acpi_cmd_list(struct unit_test_state *uts) buf = memalign(16, BUF_SIZE); ut_assertnonnull(buf); addr = map_to_sysmem(buf); - setup_ctx_and_base_tables(&ctx, addr); + ut_assertok(setup_ctx_and_base_tables(uts, &ctx, addr));
ut_assertok(acpi_write_dev_tables(&ctx));
@@ -424,7 +429,7 @@ static int dm_test_acpi_cmd_dump(struct unit_test_state *uts) buf = memalign(16, BUF_SIZE); ut_assertnonnull(buf); addr = map_to_sysmem(buf); - setup_ctx_and_base_tables(&ctx, addr); + ut_assertok(setup_ctx_and_base_tables(uts, &ctx, addr));
ut_assertok(acpi_write_dev_tables(&ctx));

Use the new ACPI writer to write the base tables at the start of the area, moving this code from the x86 implementation.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/lib/acpi_table.c | 2 - include/acpi/acpi_table.h | 10 ----- include/dm/acpi.h | 23 +++++++++- lib/acpi/Makefile | 5 +++ lib/acpi/acpi_table.c | 75 ------------------------------- lib/acpi/acpi_writer.c | 5 ++- lib/acpi/base.c | 92 +++++++++++++++++++++++++++++++++++++++ test/dm/acpi.c | 17 +++++--- 8 files changed, 133 insertions(+), 96 deletions(-) create mode 100644 lib/acpi/base.c
Applied to u-boot-dm, thanks!

Move this table over to use a writer function, moving the code from the x86 implementation.
Add a pointer to the DSDT in struct acpi_ctx so we can reference it later.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/lib/acpi_table.c | 26 ++------------------------ include/dm/acpi.h | 2 ++ lib/acpi/Makefile | 1 + lib/acpi/facs.c | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 38 insertions(+), 24 deletions(-) create mode 100644 lib/acpi/facs.c
diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c index e6aa3c5a709..22f34a46d07 100644 --- a/arch/x86/lib/acpi_table.c +++ b/arch/x86/lib/acpi_table.c @@ -38,21 +38,6 @@ extern const unsigned char AmlCode[]; /* ACPI RSDP address to be used in boot parameters */ static ulong acpi_rsdp_addr;
-static void acpi_create_facs(struct acpi_facs *facs) -{ - memset((void *)facs, 0, sizeof(struct acpi_facs)); - - memcpy(facs->signature, "FACS", 4); - facs->length = sizeof(struct acpi_facs); - facs->hardware_signature = 0; - facs->firmware_waking_vector = 0; - facs->global_lock = 0; - facs->flags = 0; - facs->x_firmware_waking_vector_l = 0; - facs->x_firmware_waking_vector_h = 0; - facs->version = 1; -} - static int acpi_create_madt_lapic(struct acpi_madt_lapic *lapic, u8 cpu, u8 apic) { @@ -507,7 +492,6 @@ static int write_acpi_tables_x86(struct acpi_ctx *ctx, const struct acpi_writer *entry) { const int thl = sizeof(struct acpi_table_header); - struct acpi_facs *facs; struct acpi_table_header *dsdt; struct acpi_fadt *fadt; struct acpi_table_header *ssdt; @@ -521,12 +505,6 @@ static int write_acpi_tables_x86(struct acpi_ctx *ctx, int ret; int i;
- debug("ACPI: * FACS\n"); - facs = ctx->current; - acpi_inc_align(ctx, sizeof(struct acpi_facs)); - - acpi_create_facs(facs); - debug("ACPI: * DSDT\n"); dsdt = ctx->current;
@@ -599,7 +577,7 @@ static int write_acpi_tables_x86(struct acpi_ctx *ctx, debug("ACPI: * FADT\n"); fadt = ctx->current; acpi_inc_align(ctx, sizeof(struct acpi_fadt)); - acpi_create_fadt(fadt, facs, dsdt); + acpi_create_fadt(fadt, ctx->facs, dsdt); acpi_add_table(ctx, fadt);
debug("ACPI: * SSDT\n"); @@ -666,7 +644,7 @@ static int write_acpi_tables_x86(struct acpi_ctx *ctx,
return 0; } -ACPI_WRITER(x86, NULL, write_acpi_tables_x86, 0); +ACPI_WRITER(2x86, NULL, write_acpi_tables_x86, 0);
ulong acpi_get_rsdp_addr(void) { diff --git a/include/dm/acpi.h b/include/dm/acpi.h index ac60b11116f..c19a7717771 100644 --- a/include/dm/acpi.h +++ b/include/dm/acpi.h @@ -52,6 +52,7 @@ enum acpi_dump_option { * adding a new table. The RSDP holds pointers to the RSDT and XSDT. * @rsdt: Pointer to the Root System Description Table * @xsdt: Pointer to the Extended System Description Table + * @facs: Pointer to the Firmware ACPI Control Structure * @nhlt: Intel Non-High-Definition-Audio Link Table (NHLT) pointer, used to * build up information that audio codecs need to provide in the NHLT ACPI * table @@ -65,6 +66,7 @@ struct acpi_ctx { struct acpi_rsdp *rsdp; struct acpi_rsdt *rsdt; struct acpi_xsdt *xsdt; + struct acpi_facs *facs; struct nhlt *nhlt; char *len_stack[ACPIGEN_LENSTACK_SIZE]; int ltop; diff --git a/lib/acpi/Makefile b/lib/acpi/Makefile index 4674a9287f6..9f70fe69d3e 100644 --- a/lib/acpi/Makefile +++ b/lib/acpi/Makefile @@ -10,4 +10,5 @@ obj-y += acpi_writer.o # With QEMU the ACPI tables come from there, not from U-Boot ifndef CONFIG_QEMU obj-y += base.o +obj-y += facs.o endif diff --git a/lib/acpi/facs.c b/lib/acpi/facs.c new file mode 100644 index 00000000000..8a1568fbaa0 --- /dev/null +++ b/lib/acpi/facs.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Write an ACPI Firmware ACPI Control Structure (FACS) table + * + * Copyright 2021 Google LLC + */ + +#include <common.h> +#include <acpi/acpi_table.h> +#include <dm/acpi.h> + +int acpi_write_facs(struct acpi_ctx *ctx, const struct acpi_writer *entry) +{ + struct acpi_facs *facs = ctx->current; + + memset((void *)facs, '\0', sizeof(struct acpi_facs)); + + memcpy(facs->signature, "FACS", 4); + facs->length = sizeof(struct acpi_facs); + facs->hardware_signature = 0; + facs->firmware_waking_vector = 0; + facs->global_lock = 0; + facs->flags = 0; + facs->x_firmware_waking_vector_l = 0; + facs->x_firmware_waking_vector_h = 0; + facs->version = 1; + + ctx->facs = facs; + acpi_inc(ctx, sizeof(struct acpi_facs)); + + return 0; +} +ACPI_WRITER(1facs, "FACS", acpi_write_facs, 0);

Move this table over to use a writer function, moving the code from the x86 implementation.
Add a pointer to the DSDT in struct acpi_ctx so we can reference it later.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/lib/acpi_table.c | 26 ++------------------------ include/dm/acpi.h | 2 ++ lib/acpi/Makefile | 1 + lib/acpi/facs.c | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 38 insertions(+), 24 deletions(-) create mode 100644 lib/acpi/facs.c
Applied to u-boot-dm, thanks!

Move this table over to use a writer function, moving the code from the x86 implementation.
Add a pointer to the DSDT in struct acpi_ctx so we can reference it later.
Disable this table for sandbox since we don't actually compile real ASL code.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/lib/acpi_table.c | 49 +++++----------------------------- include/dm/acpi.h | 2 ++ lib/acpi/Makefile | 6 +++++ lib/acpi/base.c | 2 ++ lib/acpi/dsdt.c | 55 +++++++++++++++++++++++++++++++++++++++ lib/acpi/facs.c | 2 ++ 6 files changed, 74 insertions(+), 42 deletions(-) create mode 100644 lib/acpi/dsdt.c
diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c index 22f34a46d07..e0c76ab279f 100644 --- a/arch/x86/lib/acpi_table.c +++ b/arch/x86/lib/acpi_table.c @@ -29,12 +29,6 @@ #include <dm/acpi.h> #include <linux/err.h>
-/* - * IASL compiles the dsdt entries and writes the hex values - * to a C array AmlCode[] (see dsdt.c). - */ -extern const unsigned char AmlCode[]; - /* ACPI RSDP address to be used in boot parameters */ static ulong acpi_rsdp_addr;
@@ -491,8 +485,6 @@ static int acpi_create_ssdt(struct acpi_ctx *ctx, static int write_acpi_tables_x86(struct acpi_ctx *ctx, const struct acpi_writer *entry) { - const int thl = sizeof(struct acpi_table_header); - struct acpi_table_header *dsdt; struct acpi_fadt *fadt; struct acpi_table_header *ssdt; struct acpi_mcfg *mcfg; @@ -500,42 +492,14 @@ static int write_acpi_tables_x86(struct acpi_ctx *ctx, struct acpi_madt *madt; struct acpi_csrt *csrt; struct acpi_spcr *spcr; - int aml_len; ulong addr; int ret; int i;
- debug("ACPI: * DSDT\n"); - dsdt = ctx->current; - - /* Put the table header first */ - memcpy(dsdt, &AmlCode, thl); - acpi_inc(ctx, thl); - log_debug("DSDT starts at %p, hdr ends at %p\n", dsdt, ctx->current); - - /* If the table is not empty, allow devices to inject things */ - aml_len = dsdt->length - thl; - if (aml_len) { - void *base = ctx->current; - - acpi_inject_dsdt(ctx); - log_debug("Added %x bytes from inject_dsdt, now at %p\n", - ctx->current - base, ctx->current); - log_debug("Copy AML code size %x to %p\n", aml_len, - ctx->current); - memcpy(ctx->current, AmlCode + thl, aml_len); - acpi_inc(ctx, aml_len); - } - - dsdt->length = ctx->current - (void *)dsdt; - acpi_align(ctx); - log_debug("Updated DSDT length to %x, total %x\n", dsdt->length, - ctx->current - (void *)dsdt); - if (!IS_ENABLED(CONFIG_ACPI_GNVS_EXTERNAL)) { /* Pack GNVS into the ACPI table area */ - for (i = 0; i < dsdt->length; i++) { - u32 *gnvs = (u32 *)((u32)dsdt + i); + for (i = 0; i < ctx->dsdt->length; i++) { + u32 *gnvs = (u32 *)((u32)ctx->dsdt + i);
if (*gnvs == ACPI_GNVS_ADDR) { *gnvs = map_to_sysmem(ctx->current); @@ -561,8 +525,9 @@ static int write_acpi_tables_x86(struct acpi_ctx *ctx, * the GNVS address. Set the checksum to zero since it is part of the * region being checksummed. */ - dsdt->checksum = 0; - dsdt->checksum = table_compute_checksum((void *)dsdt, dsdt->length); + ctx->dsdt->checksum = 0; + ctx->dsdt->checksum = table_compute_checksum((void *)ctx->dsdt, + ctx->dsdt->length);
/* * Fill in platform-specific global NVS variables. If this fails we @@ -577,7 +542,7 @@ static int write_acpi_tables_x86(struct acpi_ctx *ctx, debug("ACPI: * FADT\n"); fadt = ctx->current; acpi_inc_align(ctx, sizeof(struct acpi_fadt)); - acpi_create_fadt(fadt, ctx->facs, dsdt); + acpi_create_fadt(fadt, ctx->facs, ctx->dsdt); acpi_add_table(ctx, fadt);
debug("ACPI: * SSDT\n"); @@ -644,7 +609,7 @@ static int write_acpi_tables_x86(struct acpi_ctx *ctx,
return 0; } -ACPI_WRITER(2x86, NULL, write_acpi_tables_x86, 0); +ACPI_WRITER(9x86, NULL, write_acpi_tables_x86, 0);
ulong acpi_get_rsdp_addr(void) { diff --git a/include/dm/acpi.h b/include/dm/acpi.h index c19a7717771..bdde0152758 100644 --- a/include/dm/acpi.h +++ b/include/dm/acpi.h @@ -53,6 +53,7 @@ enum acpi_dump_option { * @rsdt: Pointer to the Root System Description Table * @xsdt: Pointer to the Extended System Description Table * @facs: Pointer to the Firmware ACPI Control Structure + * @dsdt: Pointer to the Differentiated System Description Table * @nhlt: Intel Non-High-Definition-Audio Link Table (NHLT) pointer, used to * build up information that audio codecs need to provide in the NHLT ACPI * table @@ -67,6 +68,7 @@ struct acpi_ctx { struct acpi_rsdt *rsdt; struct acpi_xsdt *xsdt; struct acpi_facs *facs; + struct acpi_table_header *dsdt; struct nhlt *nhlt; char *len_stack[ACPIGEN_LENSTACK_SIZE]; int ltop; diff --git a/lib/acpi/Makefile b/lib/acpi/Makefile index 9f70fe69d3e..ccdf42896dc 100644 --- a/lib/acpi/Makefile +++ b/lib/acpi/Makefile @@ -10,5 +10,11 @@ obj-y += acpi_writer.o # With QEMU the ACPI tables come from there, not from U-Boot ifndef CONFIG_QEMU obj-y += base.o + +# Sandbox does not build a .asl file +ifndef CONFIG_SANDBOX +obj-y += dsdt.o +endif + obj-y += facs.o endif diff --git a/lib/acpi/base.c b/lib/acpi/base.c index 3e8d703934e..2057bd2bef8 100644 --- a/lib/acpi/base.c +++ b/lib/acpi/base.c @@ -5,6 +5,8 @@ * Copyright 2021 Google LLC */
+#define LOG_CATEGORY LOGC_ACPI + #include <common.h> #include <acpi/acpi_table.h> #include <dm/acpi.h> diff --git a/lib/acpi/dsdt.c b/lib/acpi/dsdt.c new file mode 100644 index 00000000000..db98cc20e1d --- /dev/null +++ b/lib/acpi/dsdt.c @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Write the ACPI Differentiated System Description Table (DSDT) + * + * Copyright 2021 Google LLC + */ + +#define LOG_CATEGORY LOGC_ACPI + +#include <common.h> +#include <acpi/acpi_table.h> +#include <dm/acpi.h> +#include <tables_csum.h> + +/* + * IASL compiles the dsdt entries and writes the hex values + * to a C array AmlCode[] (see dsdt.c). + */ +extern const unsigned char AmlCode[]; + +int acpi_write_dsdt(struct acpi_ctx *ctx, const struct acpi_writer *entry) +{ + const int thl = sizeof(struct acpi_table_header); + struct acpi_table_header *dsdt = ctx->current; + int aml_len; + + /* Put the table header first */ + memcpy(dsdt, &AmlCode, thl); + acpi_inc(ctx, thl); + log_debug("DSDT starts at %p, hdr ends at %p\n", dsdt, ctx->current); + + /* If the table is not empty, allow devices to inject things */ + aml_len = dsdt->length - thl; + if (aml_len) { + void *base = ctx->current; + int ret; + + ret = acpi_inject_dsdt(ctx); + if (ret) + return log_msg_ret("inject", ret); + log_debug("Added %lx bytes from inject_dsdt, now at %p\n", + (ulong)(ctx->current - base), ctx->current); + log_debug("Copy AML code size %x to %p\n", aml_len, + ctx->current); + memcpy(ctx->current, AmlCode + thl, aml_len); + acpi_inc(ctx, aml_len); + } + + ctx->dsdt = dsdt; + dsdt->length = ctx->current - (void *)dsdt; + log_debug("Updated DSDT length to %x\n", dsdt->length); + + return 0; +} +ACPI_WRITER(3dsdt, "DSDT", acpi_write_dsdt, 0); diff --git a/lib/acpi/facs.c b/lib/acpi/facs.c index 8a1568fbaa0..e89f43ca5c9 100644 --- a/lib/acpi/facs.c +++ b/lib/acpi/facs.c @@ -5,6 +5,8 @@ * Copyright 2021 Google LLC */
+#define LOG_CATEGORY LOGC_ACPI + #include <common.h> #include <acpi/acpi_table.h> #include <dm/acpi.h>

Move this table over to use a writer function, moving the code from the x86 implementation.
Add a pointer to the DSDT in struct acpi_ctx so we can reference it later.
Disable this table for sandbox since we don't actually compile real ASL code.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/lib/acpi_table.c | 49 +++++----------------------------- include/dm/acpi.h | 2 ++ lib/acpi/Makefile | 6 +++++ lib/acpi/base.c | 2 ++ lib/acpi/dsdt.c | 55 +++++++++++++++++++++++++++++++++++++++ lib/acpi/facs.c | 2 ++ 6 files changed, 74 insertions(+), 42 deletions(-) create mode 100644 lib/acpi/dsdt.c
Applied to u-boot-dm, thanks!

Move this table over to use a writer function, for x86 only. Handle the two cases
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/lib/acpi_table.c | 73 +++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 37 deletions(-)
diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c index e0c76ab279f..cff47b5b386 100644 --- a/arch/x86/lib/acpi_table.c +++ b/arch/x86/lib/acpi_table.c @@ -479,66 +479,65 @@ static int acpi_create_ssdt(struct acpi_ctx *ctx, return 0; }
-/* - * QEMU's version of write_acpi_tables is defined in drivers/misc/qfw.c - */ -static int write_acpi_tables_x86(struct acpi_ctx *ctx, - const struct acpi_writer *entry) +int acpi_write_gnvs(struct acpi_ctx *ctx, const struct acpi_writer *entry) { - struct acpi_fadt *fadt; - struct acpi_table_header *ssdt; - struct acpi_mcfg *mcfg; - struct acpi_tcpa *tcpa; - struct acpi_madt *madt; - struct acpi_csrt *csrt; - struct acpi_spcr *spcr; ulong addr; - int ret; - int i;
if (!IS_ENABLED(CONFIG_ACPI_GNVS_EXTERNAL)) { + int i; + + /* We need the DSDT to be done */ + if (!ctx->dsdt) + return log_msg_ret("dsdt", -EAGAIN); + /* Pack GNVS into the ACPI table area */ for (i = 0; i < ctx->dsdt->length; i++) { u32 *gnvs = (u32 *)((u32)ctx->dsdt + i);
if (*gnvs == ACPI_GNVS_ADDR) { *gnvs = map_to_sysmem(ctx->current); - debug("Fix up global NVS in DSDT to %#08x\n", - *gnvs); + log_debug("Fix up global NVS in DSDT to %#08x\n", + *gnvs); break; } }
/* - * Fill in platform-specific global NVS variables. If this fails - * we cannot return the error but this should only happen while - * debugging. + * Recalculate the length and update the DSDT checksum since we + * patched the GNVS address. Set the checksum to zero since it + * is part of the region being checksummed. */ - addr = acpi_create_gnvs(ctx->current); - if (IS_ERR_VALUE(addr)) - printf("Error: Gailed to create GNVS\n"); - acpi_inc_align(ctx, sizeof(struct acpi_global_nvs)); + ctx->dsdt->checksum = 0; + ctx->dsdt->checksum = table_compute_checksum((void *)ctx->dsdt, + ctx->dsdt->length); }
- /* - * Recalculate the length and update the DSDT checksum since we patched - * the GNVS address. Set the checksum to zero since it is part of the - * region being checksummed. - */ - ctx->dsdt->checksum = 0; - ctx->dsdt->checksum = table_compute_checksum((void *)ctx->dsdt, - ctx->dsdt->length); - - /* - * Fill in platform-specific global NVS variables. If this fails we - * cannot return the error but this should only happen while debugging. - */ + /* Fill in platform-specific global NVS variables */ addr = acpi_create_gnvs(ctx->current); if (IS_ERR_VALUE(addr)) - printf("Error: Failed to create GNVS\n"); + return log_msg_ret("gnvs", (int)addr);
acpi_inc_align(ctx, sizeof(struct acpi_global_nvs));
+ return 0; +} +ACPI_WRITER(4gnvs, "GNVS", acpi_write_gnvs, 0); + +/* + * QEMU's version of write_acpi_tables is defined in drivers/misc/qfw.c + */ +int write_acpi_tables_x86(struct acpi_ctx *ctx, + const struct acpi_writer *entry) +{ + struct acpi_fadt *fadt; + struct acpi_table_header *ssdt; + struct acpi_mcfg *mcfg; + struct acpi_tcpa *tcpa; + struct acpi_madt *madt; + struct acpi_csrt *csrt; + struct acpi_spcr *spcr; + int ret; + debug("ACPI: * FADT\n"); fadt = ctx->current; acpi_inc_align(ctx, sizeof(struct acpi_fadt));

Move this table over to use a writer function, for x86 only. Handle the two cases
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/lib/acpi_table.c | 73 +++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 37 deletions(-)
Applied to u-boot-dm, thanks!

Move this table over to use a writer function, for x86 only.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/lib/acpi_table.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c index cff47b5b386..1f4b7fad3ff 100644 --- a/arch/x86/lib/acpi_table.c +++ b/arch/x86/lib/acpi_table.c @@ -523,13 +523,27 @@ int acpi_write_gnvs(struct acpi_ctx *ctx, const struct acpi_writer *entry) } ACPI_WRITER(4gnvs, "GNVS", acpi_write_gnvs, 0);
+static int acpi_write_fadt(struct acpi_ctx *ctx, + const struct acpi_writer *entry) +{ + struct acpi_fadt *fadt; + + fadt = ctx->current; + acpi_create_fadt(fadt, ctx->facs, ctx->dsdt); + acpi_add_table(ctx, fadt); + + acpi_inc(ctx, sizeof(struct acpi_fadt)); + + return 0; +} +ACPI_WRITER(5fact, "FADT", acpi_write_fadt, 0); + /* * QEMU's version of write_acpi_tables is defined in drivers/misc/qfw.c */ int write_acpi_tables_x86(struct acpi_ctx *ctx, const struct acpi_writer *entry) { - struct acpi_fadt *fadt; struct acpi_table_header *ssdt; struct acpi_mcfg *mcfg; struct acpi_tcpa *tcpa; @@ -538,12 +552,6 @@ int write_acpi_tables_x86(struct acpi_ctx *ctx, struct acpi_spcr *spcr; int ret;
- debug("ACPI: * FADT\n"); - fadt = ctx->current; - acpi_inc_align(ctx, sizeof(struct acpi_fadt)); - acpi_create_fadt(fadt, ctx->facs, ctx->dsdt); - acpi_add_table(ctx, fadt); - debug("ACPI: * SSDT\n"); ssdt = (struct acpi_table_header *)ctx->current; if (!acpi_create_ssdt(ctx, ssdt, OEM_TABLE_ID))

Move this table over to use a writer function, for x86 only.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/lib/acpi_table.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-)
Applied to u-boot-dm, thanks!

Each board has its own way of creating this table. Rather than calling the acpi_create_fadt() function for each one from a common acpi_write_fadt() function, just move the writer into the board-specific code.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/cpu/apollolake/acpi.c | 17 +++++++++++++---- arch/x86/cpu/baytrail/acpi.c | 27 +++++++++++++++++++-------- arch/x86/cpu/quark/acpi.c | 27 +++++++++++++++++++-------- arch/x86/cpu/tangier/acpi.c | 25 +++++++++++++++++-------- arch/x86/include/asm/acpi_table.h | 2 -- arch/x86/lib/acpi_table.c | 15 --------------- 6 files changed, 68 insertions(+), 45 deletions(-)
diff --git a/arch/x86/cpu/apollolake/acpi.c b/arch/x86/cpu/apollolake/acpi.c index fd21c0b4968..a3dd7373af0 100644 --- a/arch/x86/cpu/apollolake/acpi.c +++ b/arch/x86/cpu/apollolake/acpi.c @@ -146,16 +146,25 @@ void fill_fadt(struct acpi_fadt *fadt) fadt->x_pm_tmr_blk.addrl = IOMAP_ACPI_BASE + PM1_TMR; }
-void acpi_create_fadt(struct acpi_fadt *fadt, struct acpi_facs *facs, - void *dsdt) +static int apl_write_fadt(struct acpi_ctx *ctx, const struct acpi_writer *entry) { - struct acpi_table_header *header = &fadt->header; + struct acpi_table_header *header; + struct acpi_fadt *fadt;
- acpi_fadt_common(fadt, facs, dsdt); + fadt = ctx->current; + acpi_fadt_common(fadt, ctx->facs, ctx->dsdt); intel_acpi_fill_fadt(fadt); fill_fadt(fadt); + header = &fadt->header; header->checksum = table_compute_checksum(fadt, header->length); + + acpi_add_table(ctx, fadt); + + acpi_inc(ctx, sizeof(struct acpi_fadt)); + + return 0; } +ACPI_WRITER(5fadt, "FACS", apl_write_fadt, 0);
int apl_acpi_fill_dmar(struct acpi_ctx *ctx) { diff --git a/arch/x86/cpu/baytrail/acpi.c b/arch/x86/cpu/baytrail/acpi.c index 07757b88a30..59db2e2c5d8 100644 --- a/arch/x86/cpu/baytrail/acpi.c +++ b/arch/x86/cpu/baytrail/acpi.c @@ -15,20 +15,24 @@ #include <asm/arch/iomap.h> #include <dm/uclass-internal.h>
-void acpi_create_fadt(struct acpi_fadt *fadt, struct acpi_facs *facs, - void *dsdt) +static int baytrail_write_fadt(struct acpi_ctx *ctx, + const struct acpi_writer *entry) { - struct acpi_table_header *header = &(fadt->header); + struct acpi_table_header *header; + struct acpi_fadt *fadt; + + fadt = ctx->current; + header = &fadt->header; u16 pmbase = ACPI_BASE_ADDRESS;
- memset((void *)fadt, 0, sizeof(struct acpi_fadt)); + memset(fadt, '\0', sizeof(struct acpi_fadt));
acpi_fill_header(header, "FACP"); header->length = sizeof(struct acpi_fadt); header->revision = 4;
- fadt->firmware_ctrl = (u32)facs; - fadt->dsdt = (u32)dsdt; + fadt->firmware_ctrl = (u32)ctx->facs; + fadt->dsdt = (u32)ctx->dsdt; fadt->preferred_pm_profile = ACPI_PM_MOBILE; fadt->sci_int = 9; fadt->smi_cmd = 0; @@ -75,9 +79,9 @@ void acpi_create_fadt(struct acpi_fadt *fadt, struct acpi_facs *facs, fadt->reset_reg.addrh = 0; fadt->reset_value = SYS_RST | RST_CPU | FULL_RST;
- fadt->x_firmware_ctl_l = (u32)facs; + fadt->x_firmware_ctl_l = (u32)ctx->facs; fadt->x_firmware_ctl_h = 0; - fadt->x_dsdt_l = (u32)dsdt; + fadt->x_dsdt_l = (u32)ctx->dsdt; fadt->x_dsdt_h = 0;
fadt->x_pm1a_evt_blk.space_id = ACPI_ADDRESS_SPACE_IO; @@ -137,7 +141,14 @@ void acpi_create_fadt(struct acpi_fadt *fadt, struct acpi_facs *facs, fadt->x_gpe1_blk.addrh = 0x0;
header->checksum = table_compute_checksum(fadt, header->length); + + acpi_add_table(ctx, fadt); + + acpi_inc(ctx, sizeof(struct acpi_fadt)); + + return 0; } +ACPI_WRITER(5fadt, "FACP", baytrail_write_fadt, 0);
int acpi_create_gnvs(struct acpi_global_nvs *gnvs) { diff --git a/arch/x86/cpu/quark/acpi.c b/arch/x86/cpu/quark/acpi.c index 82b776ff65f..9ce9ee3aabf 100644 --- a/arch/x86/cpu/quark/acpi.c +++ b/arch/x86/cpu/quark/acpi.c @@ -10,20 +10,24 @@ #include <asm/arch/global_nvs.h> #include <asm/arch/iomap.h>
-void acpi_create_fadt(struct acpi_fadt *fadt, struct acpi_facs *facs, - void *dsdt) +static int quark_write_fadt(struct acpi_ctx *ctx, + const struct acpi_writer *entry) { - struct acpi_table_header *header = &(fadt->header); u16 pmbase = ACPI_PM1_BASE_ADDRESS; + struct acpi_table_header *header; + struct acpi_fadt *fadt;
- memset((void *)fadt, 0, sizeof(struct acpi_fadt)); + fadt = ctx->current; + header = &fadt->header; + + memset(fadt, '\0', sizeof(struct acpi_fadt));
acpi_fill_header(header, "FACP"); header->length = sizeof(struct acpi_fadt); header->revision = 4;
- fadt->firmware_ctrl = (u32)facs; - fadt->dsdt = (u32)dsdt; + fadt->firmware_ctrl = (u32)ctx->facs; + fadt->dsdt = (u32)ctx->dsdt; fadt->preferred_pm_profile = ACPI_PM_UNSPECIFIED; fadt->sci_int = 9; fadt->smi_cmd = 0; @@ -70,9 +74,9 @@ void acpi_create_fadt(struct acpi_fadt *fadt, struct acpi_facs *facs, fadt->reset_reg.addrh = 0; fadt->reset_value = SYS_RST | RST_CPU | FULL_RST;
- fadt->x_firmware_ctl_l = (u32)facs; + fadt->x_firmware_ctl_l = (u32)ctx->facs; fadt->x_firmware_ctl_h = 0; - fadt->x_dsdt_l = (u32)dsdt; + fadt->x_dsdt_l = (u32)ctx->dsdt; fadt->x_dsdt_h = 0;
fadt->x_pm1a_evt_blk.space_id = ACPI_ADDRESS_SPACE_IO; @@ -132,7 +136,14 @@ void acpi_create_fadt(struct acpi_fadt *fadt, struct acpi_facs *facs, fadt->x_gpe1_blk.addrh = 0x0;
header->checksum = table_compute_checksum(fadt, header->length); + + acpi_add_table(ctx, fadt); + + acpi_inc(ctx, sizeof(struct acpi_fadt)); + + return 0; } +ACPI_WRITER(5fadt, "FACP", quark_write_fadt, 0);
int acpi_create_gnvs(struct acpi_global_nvs *gnvs) { diff --git a/arch/x86/cpu/tangier/acpi.c b/arch/x86/cpu/tangier/acpi.c index 82f4ce5a34a..11873565366 100644 --- a/arch/x86/cpu/tangier/acpi.c +++ b/arch/x86/cpu/tangier/acpi.c @@ -16,19 +16,23 @@ #include <asm/arch/iomap.h> #include <dm/uclass-internal.h>
-void acpi_create_fadt(struct acpi_fadt *fadt, struct acpi_facs *facs, - void *dsdt) +static int tangier_write_fadt(struct acpi_ctx *ctx, + const struct acpi_writer *entry) { - struct acpi_table_header *header = &(fadt->header); + struct acpi_table_header *header; + struct acpi_fadt *fadt;
- memset((void *)fadt, 0, sizeof(struct acpi_fadt)); + fadt = ctx->current; + header = &fadt->header; + + memset(fadt, '\0', sizeof(struct acpi_fadt));
acpi_fill_header(header, "FACP"); header->length = sizeof(struct acpi_fadt); header->revision = 6;
- fadt->firmware_ctrl = (u32)facs; - fadt->dsdt = (u32)dsdt; + fadt->firmware_ctrl = (u32)ctx->facs; + fadt->dsdt = (u32)ctx->dsdt; fadt->preferred_pm_profile = ACPI_PM_UNSPECIFIED;
fadt->iapc_boot_arch = ACPI_FADT_VGA_NOT_PRESENT | @@ -41,13 +45,18 @@ void acpi_create_fadt(struct acpi_fadt *fadt, struct acpi_facs *facs,
fadt->minor_revision = 2;
- fadt->x_firmware_ctl_l = (u32)facs; + fadt->x_firmware_ctl_l = (u32)ctx->facs; fadt->x_firmware_ctl_h = 0; - fadt->x_dsdt_l = (u32)dsdt; + fadt->x_dsdt_l = (u32)ctx->dsdt; fadt->x_dsdt_h = 0;
header->checksum = table_compute_checksum(fadt, header->length); + + acpi_inc(ctx, sizeof(struct acpi_fadt)); + + return 0; } +ACPI_WRITER(5fadt, "FACP", tangier_write_fadt, 0);
u32 acpi_fill_madt(u32 current) { diff --git a/arch/x86/include/asm/acpi_table.h b/arch/x86/include/asm/acpi_table.h index b9c8911b514..a22f8d90f82 100644 --- a/arch/x86/include/asm/acpi_table.h +++ b/arch/x86/include/asm/acpi_table.h @@ -24,8 +24,6 @@ struct acpi_table_header;
/* These can be used by the target port */
-void acpi_create_fadt(struct acpi_fadt *fadt, struct acpi_facs *facs, - void *dsdt); int acpi_create_madt_lapics(u32 current); int acpi_create_madt_ioapic(struct acpi_madt_ioapic *ioapic, u8 id, u32 addr, u32 gsi_base); diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c index 1f4b7fad3ff..c1011a48d0c 100644 --- a/arch/x86/lib/acpi_table.c +++ b/arch/x86/lib/acpi_table.c @@ -523,21 +523,6 @@ int acpi_write_gnvs(struct acpi_ctx *ctx, const struct acpi_writer *entry) } ACPI_WRITER(4gnvs, "GNVS", acpi_write_gnvs, 0);
-static int acpi_write_fadt(struct acpi_ctx *ctx, - const struct acpi_writer *entry) -{ - struct acpi_fadt *fadt; - - fadt = ctx->current; - acpi_create_fadt(fadt, ctx->facs, ctx->dsdt); - acpi_add_table(ctx, fadt); - - acpi_inc(ctx, sizeof(struct acpi_fadt)); - - return 0; -} -ACPI_WRITER(5fact, "FADT", acpi_write_fadt, 0); - /* * QEMU's version of write_acpi_tables is defined in drivers/misc/qfw.c */

Each board has its own way of creating this table. Rather than calling the acpi_create_fadt() function for each one from a common acpi_write_fadt() function, just move the writer into the board-specific code.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/cpu/apollolake/acpi.c | 17 +++++++++++++---- arch/x86/cpu/baytrail/acpi.c | 27 +++++++++++++++++++-------- arch/x86/cpu/quark/acpi.c | 27 +++++++++++++++++++-------- arch/x86/cpu/tangier/acpi.c | 25 +++++++++++++++++-------- arch/x86/include/asm/acpi_table.h | 2 -- arch/x86/lib/acpi_table.c | 15 --------------- 6 files changed, 68 insertions(+), 45 deletions(-)
Applied to u-boot-dm, thanks!

Move this table over to use a writer function, moving the code from the x86 implementation.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/lib/acpi_table.c | 93 +++++++++++++-------------------------- lib/acpi/Makefile | 1 + lib/acpi/ssdt.c | 49 +++++++++++++++++++++ 3 files changed, 80 insertions(+), 63 deletions(-) create mode 100644 lib/acpi/ssdt.c
diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c index c1011a48d0c..18b284789d7 100644 --- a/arch/x86/lib/acpi_table.c +++ b/arch/x86/lib/acpi_table.c @@ -176,26 +176,6 @@ __weak u32 acpi_fill_mcfg(u32 current) return current; }
-/* MCFG is defined in the PCI Firmware Specification 3.0 */ -static void acpi_create_mcfg(struct acpi_mcfg *mcfg) -{ - struct acpi_table_header *header = &(mcfg->header); - u32 current = (u32)mcfg + sizeof(struct acpi_mcfg); - - memset((void *)mcfg, 0, sizeof(struct acpi_mcfg)); - - /* Fill out header fields */ - acpi_fill_header(header, "MCFG"); - header->length = sizeof(struct acpi_mcfg); - header->revision = 1; - - current = acpi_fill_mcfg(current); - - /* (Re)calculate length and checksum */ - header->length = current - (u32)mcfg; - header->checksum = table_compute_checksum((void *)mcfg, header->length); -} - /** * acpi_create_tcpa() - Create a TCPA table * @@ -449,36 +429,6 @@ static void acpi_create_spcr(struct acpi_spcr *spcr) header->checksum = table_compute_checksum((void *)spcr, header->length); }
-static int acpi_create_ssdt(struct acpi_ctx *ctx, - struct acpi_table_header *ssdt, - const char *oem_table_id) -{ - memset((void *)ssdt, '\0', sizeof(struct acpi_table_header)); - - acpi_fill_header(ssdt, "SSDT"); - ssdt->revision = acpi_get_table_revision(ACPITAB_SSDT); - ssdt->aslc_revision = 1; - ssdt->length = sizeof(struct acpi_table_header); - - acpi_inc(ctx, sizeof(struct acpi_table_header)); - - acpi_fill_ssdt(ctx); - - /* (Re)calculate length and checksum */ - ssdt->length = ctx->current - (void *)ssdt; - ssdt->checksum = table_compute_checksum((void *)ssdt, ssdt->length); - log_debug("SSDT at %p, length %x\n", ssdt, ssdt->length); - - /* Drop the table if it is empty */ - if (ssdt->length == sizeof(struct acpi_table_header)) { - ctx->current = ssdt; - return -ENOENT; - } - acpi_align(ctx); - - return 0; -} - int acpi_write_gnvs(struct acpi_ctx *ctx, const struct acpi_writer *entry) { ulong addr; @@ -523,31 +473,48 @@ int acpi_write_gnvs(struct acpi_ctx *ctx, const struct acpi_writer *entry) } ACPI_WRITER(4gnvs, "GNVS", acpi_write_gnvs, 0);
+/* MCFG is defined in the PCI Firmware Specification 3.0 */ +int acpi_write_mcfg(struct acpi_ctx *ctx, const struct acpi_writer *entry) +{ + struct acpi_table_header *header; + struct acpi_mcfg *mcfg; + u32 current; + + mcfg = ctx->current; + header = &mcfg->header; + + current = (u32)mcfg + sizeof(struct acpi_mcfg); + + memset(mcfg, '\0', sizeof(struct acpi_mcfg)); + + /* Fill out header fields */ + acpi_fill_header(header, "MCFG"); + header->length = sizeof(struct acpi_mcfg); + header->revision = 1; + + /* (Re)calculate length and checksum */ + header->length = current - (u32)mcfg; + header->checksum = table_compute_checksum(mcfg, header->length); + + acpi_inc(ctx, mcfg->header.length); + acpi_add_table(ctx, mcfg); + + return 0; +} +ACPI_WRITER(5mcfg, "MCFG", acpi_write_mcfg, 0); + /* * QEMU's version of write_acpi_tables is defined in drivers/misc/qfw.c */ int write_acpi_tables_x86(struct acpi_ctx *ctx, const struct acpi_writer *entry) { - struct acpi_table_header *ssdt; - struct acpi_mcfg *mcfg; struct acpi_tcpa *tcpa; struct acpi_madt *madt; struct acpi_csrt *csrt; struct acpi_spcr *spcr; int ret;
- debug("ACPI: * SSDT\n"); - ssdt = (struct acpi_table_header *)ctx->current; - if (!acpi_create_ssdt(ctx, ssdt, OEM_TABLE_ID)) - acpi_add_table(ctx, ssdt); - - debug("ACPI: * MCFG\n"); - mcfg = ctx->current; - acpi_create_mcfg(mcfg); - acpi_inc_align(ctx, mcfg->header.length); - acpi_add_table(ctx, mcfg); - if (IS_ENABLED(CONFIG_TPM_V2)) { struct acpi_tpm2 *tpm2;
diff --git a/lib/acpi/Makefile b/lib/acpi/Makefile index ccdf42896dc..552d499fde4 100644 --- a/lib/acpi/Makefile +++ b/lib/acpi/Makefile @@ -17,4 +17,5 @@ obj-y += dsdt.o endif
obj-y += facs.o +obj-y += ssdt.o endif diff --git a/lib/acpi/ssdt.c b/lib/acpi/ssdt.c new file mode 100644 index 00000000000..659c1aad406 --- /dev/null +++ b/lib/acpi/ssdt.c @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Write an ACPI Secondary System Descriptor Table (SSDT) table + * + * Copyright 2021 Google LLC + */ + +#define LOG_CATEGORY LOGC_ACPI + +#include <common.h> +#include <acpi/acpi_table.h> +#include <dm/acpi.h> +#include <tables_csum.h> + +int acpi_write_ssdt(struct acpi_ctx *ctx, const struct acpi_writer *entry) +{ + struct acpi_table_header *ssdt; + int ret; + + ssdt = ctx->current; + memset((void *)ssdt, '\0', sizeof(struct acpi_table_header)); + + acpi_fill_header(ssdt, "SSDT"); + memcpy(ssdt->oem_table_id, OEM_TABLE_ID, sizeof(ssdt->oem_table_id)); + ssdt->revision = acpi_get_table_revision(ACPITAB_SSDT); + ssdt->aslc_revision = 1; + ssdt->length = sizeof(struct acpi_table_header); + + acpi_inc(ctx, sizeof(struct acpi_table_header)); + + ret = acpi_fill_ssdt(ctx); + if (ret) { + ctx->current = ssdt; + return log_msg_ret("fill", ret); + } + + /* (Re)calculate length and checksum */ + ssdt->length = ctx->current - (void *)ssdt; + ssdt->checksum = table_compute_checksum((void *)ssdt, ssdt->length); + log_debug("SSDT at %p, length %x\n", ssdt, ssdt->length); + + /* Drop the table if it is empty */ + if (ssdt->length == sizeof(struct acpi_table_header)) + return log_msg_ret("fill", -ENOENT); + acpi_add_table(ctx, ssdt); + + return 0; +} +ACPI_WRITER(6ssdt, "SSDT", acpi_write_ssdt, 0);

Move this table over to use a writer function, moving the code from the x86 implementation.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/lib/acpi_table.c | 93 +++++++++++++-------------------------- lib/acpi/Makefile | 1 + lib/acpi/ssdt.c | 49 +++++++++++++++++++++ 3 files changed, 80 insertions(+), 63 deletions(-) create mode 100644 lib/acpi/ssdt.c
Applied to u-boot-dm, thanks!

Move this table over to use a writer function, for x86 only.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/lib/acpi_table.c | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-)
diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c index 18b284789d7..7b80d82888e 100644 --- a/arch/x86/lib/acpi_table.c +++ b/arch/x86/lib/acpi_table.c @@ -233,14 +233,21 @@ static int get_tpm2_log(void **ptrp, int *sizep) return 0; }
-static int acpi_create_tpm2(struct acpi_tpm2 *tpm2) +static int acpi_write_tpm2(struct acpi_ctx *ctx, + const struct acpi_writer *entry) { - struct acpi_table_header *header = &tpm2->header; + struct acpi_table_header *header; + struct acpi_tpm2 *tpm2; int tpm2_log_len; void *lasa; int ret;
- memset((void *)tpm2, 0, sizeof(struct acpi_tpm2)); + if (!IS_ENABLED(CONFIG_TPM_V2)) + return log_msg_ret("none", -ENOENT); + + tpm2 = ctx->current; + header = &tpm2->header; + memset(tpm2, '\0', sizeof(struct acpi_tpm2));
/* * Some payloads like SeaBIOS depend on log area to use TPM2. @@ -248,7 +255,7 @@ static int acpi_create_tpm2(struct acpi_tpm2 *tpm2) */ ret = get_tpm2_log(&lasa, &tpm2_log_len); if (ret) - return ret; + return log_msg_ret("log", ret);
/* Fill out header fields. */ acpi_fill_header(header, "TPM2"); @@ -257,7 +264,7 @@ static int acpi_create_tpm2(struct acpi_tpm2 *tpm2) header->length = sizeof(struct acpi_tpm2); header->revision = acpi_get_table_revision(ACPITAB_TPM2);
- /* Hard to detect for coreboot. Just set it to 0 */ + /* Hard to detect for U-Boot. Just set it to 0 */ tpm2->platform_class = 0;
/* Must be set to 0 for FIFO-interface support */ @@ -267,13 +274,17 @@ static int acpi_create_tpm2(struct acpi_tpm2 *tpm2)
/* Fill the log area size and start address fields. */ tpm2->laml = tpm2_log_len; - tpm2->lasa = (uintptr_t)lasa; + tpm2->lasa = map_to_sysmem(lasa);
/* Calculate checksum. */ - header->checksum = table_compute_checksum((void *)tpm2, header->length); + header->checksum = table_compute_checksum(tpm2, header->length); + + acpi_inc(ctx, tpm2->header.length); + acpi_add_table(ctx, tpm2);
return 0; } +ACPI_WRITER(5tpm2, "TPM2", acpi_write_tpm2, 0);
__weak u32 acpi_fill_csrt(u32 current) { @@ -515,20 +526,6 @@ int write_acpi_tables_x86(struct acpi_ctx *ctx, struct acpi_spcr *spcr; int ret;
- if (IS_ENABLED(CONFIG_TPM_V2)) { - struct acpi_tpm2 *tpm2; - - debug("ACPI: * TPM2\n"); - tpm2 = (struct acpi_tpm2 *)ctx->current; - ret = acpi_create_tpm2(tpm2); - if (!ret) { - acpi_inc_align(ctx, tpm2->header.length); - acpi_add_table(ctx, tpm2); - } else { - log_warning("TPM2 table creation failed\n"); - } - } - debug("ACPI: * MADT\n"); madt = ctx->current; acpi_create_madt(madt);

Move this table over to use a writer function, for x86 only.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/lib/acpi_table.c | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-)
Applied to u-boot-dm, thanks!

Move this table over to use a writer function, for x86 only.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/lib/acpi_table.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c index 7b80d82888e..4ae917176e0 100644 --- a/arch/x86/lib/acpi_table.c +++ b/arch/x86/lib/acpi_table.c @@ -131,12 +131,16 @@ __weak u32 acpi_fill_madt(u32 current) return current; }
-static void acpi_create_madt(struct acpi_madt *madt) +int acpi_write_madt(struct acpi_ctx *ctx, const struct acpi_writer *entry) { - struct acpi_table_header *header = &(madt->header); - u32 current = (u32)madt + sizeof(struct acpi_madt); + struct acpi_table_header *header; + struct acpi_madt *madt; + u32 current;
- memset((void *)madt, 0, sizeof(struct acpi_madt)); + madt = ctx->current; + + memset(madt, '\0', sizeof(struct acpi_madt)); + header = &madt->header;
/* Fill out header fields */ acpi_fill_header(header, "APIC"); @@ -146,13 +150,19 @@ static void acpi_create_madt(struct acpi_madt *madt) madt->lapic_addr = LAPIC_DEFAULT_BASE; madt->flags = ACPI_MADT_PCAT_COMPAT;
+ current = (u32)madt + sizeof(struct acpi_madt); current = acpi_fill_madt(current);
/* (Re)calculate length and checksum */ header->length = current - (u32)madt;
header->checksum = table_compute_checksum((void *)madt, header->length); + acpi_add_table(ctx, madt); + acpi_inc(ctx, madt->header.length); + + return 0; } +ACPI_WRITER(5x86, NULL, acpi_write_madt, 0);
int acpi_create_mcfg_mmconfig(struct acpi_mcfg_mmconfig *mmconfig, u32 base, u16 seg_nr, u8 start, u8 end) @@ -521,17 +531,10 @@ int write_acpi_tables_x86(struct acpi_ctx *ctx, const struct acpi_writer *entry) { struct acpi_tcpa *tcpa; - struct acpi_madt *madt; struct acpi_csrt *csrt; struct acpi_spcr *spcr; int ret;
- debug("ACPI: * MADT\n"); - madt = ctx->current; - acpi_create_madt(madt); - acpi_inc_align(ctx, madt->header.length); - acpi_add_table(ctx, madt); - if (IS_ENABLED(CONFIG_TPM_V1)) { debug("ACPI: * TCPA\n"); tcpa = (struct acpi_tcpa *)ctx->current;

Move this table over to use a writer function, for x86 only.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/lib/acpi_table.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-)
Applied to u-boot-dm, thanks!

Move this table over to use a writer function, for x86 only.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/lib/acpi_table.c | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-)
diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c index 4ae917176e0..f5045cde3ef 100644 --- a/arch/x86/lib/acpi_table.c +++ b/arch/x86/lib/acpi_table.c @@ -189,22 +189,26 @@ __weak u32 acpi_fill_mcfg(u32 current) /** * acpi_create_tcpa() - Create a TCPA table * - * @tcpa: Pointer to place to put table - * * Trusted Computing Platform Alliance Capabilities Table * TCPA PC Specific Implementation SpecificationTCPA is defined in the PCI * Firmware Specification 3.0 */ -static int acpi_create_tcpa(struct acpi_tcpa *tcpa) +int acpi_write_tcpa(struct acpi_ctx *ctx, const struct acpi_writer *entry) { - struct acpi_table_header *header = &tcpa->header; - u32 current = (u32)tcpa + sizeof(struct acpi_tcpa); + struct acpi_table_header *header; + struct acpi_tcpa *tcpa; + u32 current; int size = 0x10000; /* Use this as the default size */ void *log; int ret;
+ if (!IS_ENABLED(CONFIG_TPM_V1)) + return -ENOENT; if (!CONFIG_IS_ENABLED(BLOBLIST)) return -ENXIO; + + tcpa = ctx->current; + header = &tcpa->header; memset(tcpa, '\0', sizeof(struct acpi_tcpa));
/* Fill out header fields */ @@ -218,14 +222,19 @@ static int acpi_create_tcpa(struct acpi_tcpa *tcpa)
tcpa->platform_class = 0; tcpa->laml = size; - tcpa->lasa = (ulong)log; + tcpa->lasa = map_to_sysmem(log);
/* (Re)calculate length and checksum */ + current = (u32)tcpa + sizeof(struct acpi_tcpa); header->length = current - (u32)tcpa; - header->checksum = table_compute_checksum((void *)tcpa, header->length); + header->checksum = table_compute_checksum(tcpa, header->length); + + acpi_inc(ctx, tcpa->header.length); + acpi_add_table(ctx, tcpa);
return 0; } +ACPI_WRITER(5tcpa, "TCPA", acpi_write_tcpa, 0);
static int get_tpm2_log(void **ptrp, int *sizep) { @@ -530,23 +539,8 @@ ACPI_WRITER(5mcfg, "MCFG", acpi_write_mcfg, 0); int write_acpi_tables_x86(struct acpi_ctx *ctx, const struct acpi_writer *entry) { - struct acpi_tcpa *tcpa; struct acpi_csrt *csrt; struct acpi_spcr *spcr; - int ret; - - if (IS_ENABLED(CONFIG_TPM_V1)) { - debug("ACPI: * TCPA\n"); - tcpa = (struct acpi_tcpa *)ctx->current; - ret = acpi_create_tcpa(tcpa); - if (ret) { - log_warning("Failed to create TCPA table (err=%d)\n", - ret); - } else { - acpi_inc_align(ctx, tcpa->header.length); - acpi_add_table(ctx, tcpa); - } - }
debug("ACPI: * CSRT\n"); csrt = ctx->current;

Move this table over to use a writer function, for x86 only.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/lib/acpi_table.c | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-)
Applied to u-boot-dm, thanks!

Move this table over to use a writer function, moving the code from the x86 implementation.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/lib/acpi_table.c | 62 ++++++++------------------------------- lib/acpi/Makefile | 1 + lib/acpi/csrt.c | 50 +++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 49 deletions(-) create mode 100644 lib/acpi/csrt.c
diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c index f5045cde3ef..b7557f7f3fd 100644 --- a/arch/x86/lib/acpi_table.c +++ b/arch/x86/lib/acpi_table.c @@ -305,41 +305,12 @@ static int acpi_write_tpm2(struct acpi_ctx *ctx, } ACPI_WRITER(5tpm2, "TPM2", acpi_write_tpm2, 0);
-__weak u32 acpi_fill_csrt(u32 current) +int acpi_write_spcr(struct acpi_ctx *ctx, const struct acpi_writer *entry) { - return 0; -} - -static int acpi_create_csrt(struct acpi_csrt *csrt) -{ - struct acpi_table_header *header = &(csrt->header); - u32 current = (u32)csrt + sizeof(struct acpi_csrt); - uint ptr; - - memset((void *)csrt, 0, sizeof(struct acpi_csrt)); - - /* Fill out header fields */ - acpi_fill_header(header, "CSRT"); - header->length = sizeof(struct acpi_csrt); - header->revision = 0; - - ptr = acpi_fill_csrt(current); - if (!ptr) - return -ENOENT; - current = ptr; - - /* (Re)calculate length and checksum */ - header->length = current - (u32)csrt; - header->checksum = table_compute_checksum((void *)csrt, header->length); - - return 0; -} - -static void acpi_create_spcr(struct acpi_spcr *spcr) -{ - struct acpi_table_header *header = &(spcr->header); struct serial_device_info serial_info = {0}; ulong serial_address, serial_offset; + struct acpi_table_header *header; + struct acpi_spcr *spcr; struct udevice *dev; uint serial_config; uint serial_width; @@ -347,7 +318,10 @@ static void acpi_create_spcr(struct acpi_spcr *spcr) int space_id; int ret = -ENODEV;
- memset((void *)spcr, 0, sizeof(struct acpi_spcr)); + spcr = ctx->current; + header = &spcr->header; + + memset(spcr, '\0', sizeof(struct acpi_spcr));
/* Fill out header fields */ acpi_fill_header(header, "SPCR"); @@ -457,7 +431,13 @@ static void acpi_create_spcr(struct acpi_spcr *spcr)
/* Fix checksum */ header->checksum = table_compute_checksum((void *)spcr, header->length); + + acpi_add_table(ctx, spcr); + acpi_inc(ctx, spcr->header.length); + + return 0; } +ACPI_WRITER(5spcr, "SPCR", acpi_write_spcr, 0);
int acpi_write_gnvs(struct acpi_ctx *ctx, const struct acpi_writer *entry) { @@ -539,22 +519,6 @@ ACPI_WRITER(5mcfg, "MCFG", acpi_write_mcfg, 0); int write_acpi_tables_x86(struct acpi_ctx *ctx, const struct acpi_writer *entry) { - struct acpi_csrt *csrt; - struct acpi_spcr *spcr; - - debug("ACPI: * CSRT\n"); - csrt = ctx->current; - if (!acpi_create_csrt(csrt)) { - acpi_inc_align(ctx, csrt->header.length); - acpi_add_table(ctx, csrt); - } - - debug("ACPI: * SPCR\n"); - spcr = ctx->current; - acpi_create_spcr(spcr); - acpi_inc_align(ctx, spcr->header.length); - acpi_add_table(ctx, spcr); - acpi_write_dev_tables(ctx);
acpi_rsdp_addr = (unsigned long)ctx->rsdp; diff --git a/lib/acpi/Makefile b/lib/acpi/Makefile index 552d499fde4..f9b504988f2 100644 --- a/lib/acpi/Makefile +++ b/lib/acpi/Makefile @@ -10,6 +10,7 @@ obj-y += acpi_writer.o # With QEMU the ACPI tables come from there, not from U-Boot ifndef CONFIG_QEMU obj-y += base.o +obj-y += csrt.o
# Sandbox does not build a .asl file ifndef CONFIG_SANDBOX diff --git a/lib/acpi/csrt.c b/lib/acpi/csrt.c new file mode 100644 index 00000000000..76069318416 --- /dev/null +++ b/lib/acpi/csrt.c @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Write an ACPI Core System Resource Table (CSRT) + * + * Copyright 2021 Google LLC + */ + +#define LOG_CATEGORY LOGC_ACPI + +#include <common.h> +#include <mapmem.h> +#include <tables_csum.h> +#include <acpi/acpi_table.h> +#include <dm/acpi.h> + +__weak u32 acpi_fill_csrt(u32 current) +{ + return 0; +} + +int acpi_write_csrt(struct acpi_ctx *ctx, const struct acpi_writer *entry) +{ + struct acpi_table_header *header; + struct acpi_csrt *csrt; + uint ptr; + + csrt = ctx->current; + header = &csrt->header; + + memset(csrt, '\0', sizeof(struct acpi_csrt)); + + /* Fill out header fields */ + acpi_fill_header(header, "CSRT"); + header->length = sizeof(struct acpi_csrt); + header->revision = 0; + + ptr = acpi_fill_csrt(map_to_sysmem(csrt)); + if (!ptr) + return log_msg_ret("fill", -ENOENT); + + /* (Re)calculate length and checksum */ + header->length = (ulong)ctx->current - (ulong)csrt; + header->checksum = table_compute_checksum(csrt, header->length); + + acpi_add_table(ctx, csrt); + acpi_inc(ctx, csrt->header.length); + + return 0; +} +ACPI_WRITER(5csrt, "CSRT", acpi_write_csrt, 0);

Move this table over to use a writer function, moving the code from the x86 implementation.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/lib/acpi_table.c | 62 ++++++++------------------------------- lib/acpi/Makefile | 1 + lib/acpi/csrt.c | 50 +++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 49 deletions(-) create mode 100644 lib/acpi/csrt.c
Applied to u-boot-dm, thanks!

Update this function to the newer style, so we can avoid passing and returning an address through this function.
Also move this function out of the x86 code so it can be used by other archs.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/cpu/tangier/acpi.c | 9 ++++++--- arch/x86/include/asm/acpi_table.h | 1 - include/acpi/acpi_table.h | 12 ++++++++++++ lib/acpi/csrt.c | 13 ++++++------- 4 files changed, 24 insertions(+), 11 deletions(-)
diff --git a/arch/x86/cpu/tangier/acpi.c b/arch/x86/cpu/tangier/acpi.c index 11873565366..12f92896124 100644 --- a/arch/x86/cpu/tangier/acpi.c +++ b/arch/x86/cpu/tangier/acpi.c @@ -109,11 +109,14 @@ static u32 acpi_fill_csrt_dma(struct acpi_csrt_group *grp) return grp->length; }
-u32 acpi_fill_csrt(u32 current) +int acpi_fill_csrt(struct acpi_ctx *ctx) { - current += acpi_fill_csrt_dma((struct acpi_csrt_group *)current); + int size;
- return current; + size = acpi_fill_csrt_dma(ctx->current); + acpi_inc(ctx, size); + + return 0; }
int acpi_create_gnvs(struct acpi_global_nvs *gnvs) diff --git a/arch/x86/include/asm/acpi_table.h b/arch/x86/include/asm/acpi_table.h index a22f8d90f82..9a93b2658ac 100644 --- a/arch/x86/include/asm/acpi_table.h +++ b/arch/x86/include/asm/acpi_table.h @@ -35,7 +35,6 @@ u32 acpi_fill_madt(u32 current); int acpi_create_mcfg_mmconfig(struct acpi_mcfg_mmconfig *mmconfig, u32 base, u16 seg_nr, u8 start, u8 end); u32 acpi_fill_mcfg(u32 current); -u32 acpi_fill_csrt(u32 current);
/** * acpi_write_hpet() - Write out a HPET table diff --git a/include/acpi/acpi_table.h b/include/acpi/acpi_table.h index 87674e2cc0d..80646a44b2b 100644 --- a/include/acpi/acpi_table.h +++ b/include/acpi/acpi_table.h @@ -696,6 +696,18 @@ void acpi_write_rsdp(struct acpi_rsdp *rsdp, struct acpi_rsdt *rsdt, */ void acpi_fill_header(struct acpi_table_header *header, char *signature);
+/** + * acpi_fill_csrt() - Fill out the body of the CSRT + * + * This should write the contents of the Core System Resource Table (CSRT) + * to the context. The header (struct acpi_table_header) has already been + * written. + * + * @ctx: ACPI context to write to + * @return 0 if OK, -ve on error + */ +int acpi_fill_csrt(struct acpi_ctx *ctx); + #endif /* !__ACPI__*/
#include <asm/acpi_table.h> diff --git a/lib/acpi/csrt.c b/lib/acpi/csrt.c index 76069318416..2ba86f22952 100644 --- a/lib/acpi/csrt.c +++ b/lib/acpi/csrt.c @@ -13,7 +13,7 @@ #include <acpi/acpi_table.h> #include <dm/acpi.h>
-__weak u32 acpi_fill_csrt(u32 current) +__weak int acpi_fill_csrt(struct acpi_ctx *ctx) { return 0; } @@ -22,7 +22,7 @@ int acpi_write_csrt(struct acpi_ctx *ctx, const struct acpi_writer *entry) { struct acpi_table_header *header; struct acpi_csrt *csrt; - uint ptr; + int ret;
csrt = ctx->current; header = &csrt->header; @@ -31,19 +31,18 @@ int acpi_write_csrt(struct acpi_ctx *ctx, const struct acpi_writer *entry)
/* Fill out header fields */ acpi_fill_header(header, "CSRT"); - header->length = sizeof(struct acpi_csrt); header->revision = 0; + acpi_inc(ctx, sizeof(*header));
- ptr = acpi_fill_csrt(map_to_sysmem(csrt)); - if (!ptr) - return log_msg_ret("fill", -ENOENT); + ret = acpi_fill_csrt(ctx); + if (ret) + return log_msg_ret("fill", ret);
/* (Re)calculate length and checksum */ header->length = (ulong)ctx->current - (ulong)csrt; header->checksum = table_compute_checksum(csrt, header->length);
acpi_add_table(ctx, csrt); - acpi_inc(ctx, csrt->header.length);
return 0; }

Update this function to the newer style, so we can avoid passing and returning an address through this function.
Also move this function out of the x86 code so it can be used by other archs.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/cpu/tangier/acpi.c | 9 ++++++--- arch/x86/include/asm/acpi_table.h | 1 - include/acpi/acpi_table.h | 12 ++++++++++++ lib/acpi/csrt.c | 13 ++++++------- 4 files changed, 24 insertions(+), 11 deletions(-)
Applied to u-boot-dm, thanks!

Move this over to use a writer function, moving the code from the x86 implementation.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/lib/acpi_table.c | 2 -- lib/acpi/acpi_writer.c | 12 ++++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c index b7557f7f3fd..8275c36ad31 100644 --- a/arch/x86/lib/acpi_table.c +++ b/arch/x86/lib/acpi_table.c @@ -519,8 +519,6 @@ ACPI_WRITER(5mcfg, "MCFG", acpi_write_mcfg, 0); int write_acpi_tables_x86(struct acpi_ctx *ctx, const struct acpi_writer *entry) { - acpi_write_dev_tables(ctx); - acpi_rsdp_addr = (unsigned long)ctx->rsdp; debug("ACPI: done\n");
diff --git a/lib/acpi/acpi_writer.c b/lib/acpi/acpi_writer.c index d2505e6eaa4..59f951cba45 100644 --- a/lib/acpi/acpi_writer.c +++ b/lib/acpi/acpi_writer.c @@ -90,6 +90,18 @@ ulong write_acpi_tables(ulong start_addr)
return addr; } + +int write_dev_tables(struct acpi_ctx *ctx, const struct acpi_writer *entry) +{ + int ret; + + ret = acpi_write_dev_tables(ctx); + if (ret) + return log_msg_ret("write", ret); + + return 0; +} +ACPI_WRITER(8dev, NULL, write_dev_tables, 0); #endif /* QEMU */
void acpi_setup_ctx(struct acpi_ctx *ctx, ulong start)

Move this over to use a writer function, moving the code from the x86 implementation.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/lib/acpi_table.c | 2 -- lib/acpi/acpi_writer.c | 12 ++++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-)
Applied to u-boot-dm, thanks!

Move this over to use a writer file, moving the code from the x86 implementation.
There is no need to store a separate variable since we can simply access the ACPI context.
With this, the original monolithic x86 function for writing ACPI tables is gone.
Note that QEMU has its own implementation.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/lib/acpi_table.c | 21 --------------------- lib/acpi/acpi_writer.c | 8 ++++++++ 2 files changed, 8 insertions(+), 21 deletions(-)
diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c index 8275c36ad31..c0534343f1f 100644 --- a/arch/x86/lib/acpi_table.c +++ b/arch/x86/lib/acpi_table.c @@ -29,9 +29,6 @@ #include <dm/acpi.h> #include <linux/err.h>
-/* ACPI RSDP address to be used in boot parameters */ -static ulong acpi_rsdp_addr; - static int acpi_create_madt_lapic(struct acpi_madt_lapic *lapic, u8 cpu, u8 apic) { @@ -513,24 +510,6 @@ int acpi_write_mcfg(struct acpi_ctx *ctx, const struct acpi_writer *entry) } ACPI_WRITER(5mcfg, "MCFG", acpi_write_mcfg, 0);
-/* - * QEMU's version of write_acpi_tables is defined in drivers/misc/qfw.c - */ -int write_acpi_tables_x86(struct acpi_ctx *ctx, - const struct acpi_writer *entry) -{ - acpi_rsdp_addr = (unsigned long)ctx->rsdp; - debug("ACPI: done\n"); - - return 0; -} -ACPI_WRITER(9x86, NULL, write_acpi_tables_x86, 0); - -ulong acpi_get_rsdp_addr(void) -{ - return acpi_rsdp_addr; -} - /** * acpi_write_hpet() - Write out a HPET table * diff --git a/lib/acpi/acpi_writer.c b/lib/acpi/acpi_writer.c index 59f951cba45..9b0aa23fd78 100644 --- a/lib/acpi/acpi_writer.c +++ b/lib/acpi/acpi_writer.c @@ -102,6 +102,14 @@ int write_dev_tables(struct acpi_ctx *ctx, const struct acpi_writer *entry) return 0; } ACPI_WRITER(8dev, NULL, write_dev_tables, 0); + +ulong acpi_get_rsdp_addr(void) +{ + if (!gd->acpi_ctx) + return 0; + + return map_to_sysmem(gd->acpi_ctx->rsdp); +} #endif /* QEMU */
void acpi_setup_ctx(struct acpi_ctx *ctx, ulong start)

Move this over to use a writer file, moving the code from the x86 implementation.
There is no need to store a separate variable since we can simply access the ACPI context.
With this, the original monolithic x86 function for writing ACPI tables is gone.
Note that QEMU has its own implementation.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/lib/acpi_table.c | 21 --------------------- lib/acpi/acpi_writer.c | 8 ++++++++ 2 files changed, 8 insertions(+), 21 deletions(-)
Applied to u-boot-dm, thanks!

At present this list is used to collect items within the DSDT and SSDT tables. It is useful for it to collect the whole tables as well, so there is a list of what was created and which write created each one.
Refactor the code accordingly.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/core/acpi.c | 43 +++++++++++++++++++++++++++++++----------- include/dm/acpi.h | 14 ++++++++++++++ lib/acpi/acpi_writer.c | 5 +++++ 3 files changed, 51 insertions(+), 11 deletions(-)
diff --git a/drivers/core/acpi.c b/drivers/core/acpi.c index 35a317fd2b0..bb186444dd3 100644 --- a/drivers/core/acpi.c +++ b/drivers/core/acpi.c @@ -19,11 +19,19 @@
#define MAX_ACPI_ITEMS 100
-/* Type of table that we collected */ +/** + * Type of table that we collected + * + * @TYPE_NONE: Not yet known + * @TYPE_SSDT: Items in the Secondary System Description Table + * @TYPE_DSDT: Items in the Differentiated System Description Table + * @TYPE_OTHER: Other (whole) + */ enum gen_type_t { TYPE_NONE, TYPE_SSDT, TYPE_DSDT, + TYPE_OTHER, };
/* Type of method to call */ @@ -42,11 +50,13 @@ typedef int (*acpi_method)(const struct udevice *dev, struct acpi_ctx *ctx); * * @dev: Device that generated this data * @type: Table type it refers to + * @writer: Writer that wrote this table * @buf: Buffer containing the data * @size: Size of the data in bytes */ struct acpi_item { struct udevice *dev; + const struct acpi_writer *writer; enum gen_type_t type; char *buf; int size; @@ -103,16 +113,18 @@ int acpi_get_path(const struct udevice *dev, char *out_path, int maxlen) }
/** - * acpi_add_item() - Add a new item to the list of data collected + * add_item() - Add a new item to the list of data collected * * @ctx: ACPI context - * @dev: Device that generated the data + * @dev: Device that generated the data, if type != TYPE_OTHER + * @writer: Writer entry that generated the data, if type == TYPE_OTHER * @type: Table type it refers to * @start: The start of the data (the end is obtained from ctx->current) * @return 0 if OK, -ENOSPC if too many items, -ENOMEM if out of memory */ -static int acpi_add_item(struct acpi_ctx *ctx, struct udevice *dev, - enum gen_type_t type, void *start) +static int add_item(struct acpi_ctx *ctx, struct udevice *dev, + const struct acpi_writer *writer, enum gen_type_t type, + void *start) { struct acpi_item *item; void *end = ctx->current; @@ -124,14 +136,17 @@ static int acpi_add_item(struct acpi_ctx *ctx, struct udevice *dev,
item = &acpi_item[item_count]; item->dev = dev; + item->writer = writer; item->type = type; item->size = end - start; if (!item->size) return 0; - item->buf = malloc(item->size); - if (!item->buf) - return log_msg_ret("mem", -ENOMEM); - memcpy(item->buf, start, item->size); + if (type != TYPE_OTHER) { + item->buf = malloc(item->size); + if (!item->buf) + return log_msg_ret("mem", -ENOMEM); + memcpy(item->buf, start, item->size); + } item_count++; log_debug("* %s: Added type %d, %p, size %x\n", dev->name, type, start, item->size); @@ -139,6 +154,12 @@ static int acpi_add_item(struct acpi_ctx *ctx, struct udevice *dev, return 0; }
+int acpi_add_other_item(struct acpi_ctx *ctx, const struct acpi_writer *writer, + void *start) +{ + return add_item(ctx, NULL, writer, TYPE_OTHER, start); +} + void acpi_dump_items(enum acpi_dump_option option) { int i; @@ -162,7 +183,7 @@ static struct acpi_item *find_acpi_item(const char *devname) for (i = 0; i < item_count; i++) { struct acpi_item *item = &acpi_item[i];
- if (!strcmp(devname, item->dev->name)) + if (item->dev && !strcmp(devname, item->dev->name)) return item; }
@@ -277,7 +298,7 @@ int acpi_recurse_method(struct acpi_ctx *ctx, struct udevice *parent,
/* Add the item to the internal list */ if (type != TYPE_NONE) { - ret = acpi_add_item(ctx, parent, type, ctx->tab_start); + ret = add_item(ctx, parent, NULL, type, ctx->tab_start); if (ret) return log_msg_ret("add", ret); } diff --git a/include/dm/acpi.h b/include/dm/acpi.h index bdde0152758..94ec51ad0ab 100644 --- a/include/dm/acpi.h +++ b/include/dm/acpi.h @@ -262,6 +262,20 @@ int acpi_inject_dsdt(struct acpi_ctx *ctx); */ int acpi_setup_nhlt(struct acpi_ctx *ctx, struct nhlt *nhlt);
+/** + * acpi_add_other_item() - Add a new table to the list of ACPI tables + * + * This adds an entry of type ACPIT_TYPE_OTHER + * + * @ctx: ACPI context + * @writer: Writer entry that generated the data + * @type: Table type it refers to + * @start: The start of the data (the end is obtained from ctx->current) + * @return 0 if OK, -ENOSPC if too many items, -ENOMEM if out of memory + */ +int acpi_add_other_item(struct acpi_ctx *ctx, const struct acpi_writer *writer, + void *start); + /** * acpi_dump_items() - Dump out the collected ACPI items * diff --git a/lib/acpi/acpi_writer.c b/lib/acpi/acpi_writer.c index 9b0aa23fd78..946f90e8e7b 100644 --- a/lib/acpi/acpi_writer.c +++ b/lib/acpi/acpi_writer.c @@ -40,6 +40,11 @@ int acpi_write_one(struct acpi_ctx *ctx, const struct acpi_writer *entry) else acpi_align(ctx);
+ /* Add the item to the internal list */ + ret = acpi_add_other_item(ctx, entry, ctx->tab_start); + if (ret) + return log_msg_ret("add", ret); + return 0; }

At present this list is used to collect items within the DSDT and SSDT tables. It is useful for it to collect the whole tables as well, so there is a list of what was created and which write created each one.
Refactor the code accordingly.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/core/acpi.c | 43 +++++++++++++++++++++++++++++++----------- include/dm/acpi.h | 14 ++++++++++++++ lib/acpi/acpi_writer.c | 5 +++++ 3 files changed, 51 insertions(+), 11 deletions(-)
Applied to u-boot-dm, thanks!

At present this is really just a debugging aid, but it is a bit untidy. Add proper columns and display the type name instead of a number.
Sample output for coral:
=> acpi items Seq Type Addr Size Device/Writer --- ----- -------- ---- ------------- 0 other 79925000 240 0base 1 other 79925240 40 1facs 2 dsdt 799252a4 58 board 3 dsdt 799252fc 10 lpc 4 other 79925280 32f0 3dsdt 5 other 79928570 1000 4gnvs 6 other 79929570 100 5fact 7 other 79929670 30 5mcfg 8 other 799296a0 50 5spcr 9 other 799296f0 50 5tpm2 a other 79929740 70 5x86 b ssdt 799297d4 fe maxim-codec c ssdt 799298d2 28 i2c2@16,0 d ssdt 799298fa 270 da-codec e ssdt 79929b6a 28 i2c2@16,1 f ssdt 79929b92 28 i2c2@16,2 10 ssdt 79929bba 83 tpm@50 11 ssdt 79929c3d 28 i2c2@16,3 12 ssdt 79929c65 282 elan-touchscreen@10 13 ssdt 79929ee7 285 raydium-touchscreen@39 14 ssdt 7992a16c 28 i2c2@17,0 15 ssdt 7992a194 d8 elan-touchpad@15 16 ssdt 7992a26c 163 synaptics-touchpad@2c 17 ssdt 7992a3cf 28 i2c2@17,1 18 ssdt 7992a3f7 111 wacom-digitizer@9 19 ssdt 7992a508 8f sdmmc@1b,0 1a ssdt 7992a597 4b wifi 1b ssdt 7992a5e2 1a0 cpu@0 1c ssdt 7992a782 1a0 cpu@1 1d ssdt 7992a922 1a0 cpu@2 1e ssdt 7992aac2 211 cpu@3 1f other 799297b0 1530 6ssdt 20 other 7992ace0 2f10 8dev
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/core/acpi.c | 24 ++++++++++++++++++++---- test/dm/acpi.c | 20 ++++++++++++++------ 2 files changed, 34 insertions(+), 10 deletions(-)
diff --git a/drivers/core/acpi.c b/drivers/core/acpi.c index bb186444dd3..7a0653ddb0a 100644 --- a/drivers/core/acpi.c +++ b/drivers/core/acpi.c @@ -12,6 +12,7 @@ #include <dm.h> #include <log.h> #include <malloc.h> +#include <mapmem.h> #include <acpi/acpi_device.h> #include <dm/acpi.h> #include <dm/device-internal.h> @@ -34,6 +35,13 @@ enum gen_type_t { TYPE_OTHER, };
+const char *gen_type_str[] = { + "-", + "ssdt", + "dsdt", + "other", +}; + /* Type of method to call */ enum method_t { METHOD_WRITE_TABLES, @@ -51,13 +59,15 @@ typedef int (*acpi_method)(const struct udevice *dev, struct acpi_ctx *ctx); * @dev: Device that generated this data * @type: Table type it refers to * @writer: Writer that wrote this table - * @buf: Buffer containing the data + * @base: Pointer to base of table in its original location + * @buf: Buffer allocated to contain the data (NULL if not allocated) * @size: Size of the data in bytes */ struct acpi_item { struct udevice *dev; const struct acpi_writer *writer; enum gen_type_t type; + const char *base; char *buf; int size; }; @@ -139,6 +149,7 @@ static int add_item(struct acpi_ctx *ctx, struct udevice *dev, item->writer = writer; item->type = type; item->size = end - start; + item->base = start; if (!item->size) return 0; if (type != TYPE_OTHER) { @@ -164,13 +175,18 @@ void acpi_dump_items(enum acpi_dump_option option) { int i;
+ printf("Seq Type Base Size Device/Writer\n"); + printf("--- ----- -------- ---- -------------\n"); for (i = 0; i < item_count; i++) { struct acpi_item *item = &acpi_item[i];
- printf("dev '%s', type %d, size %x\n", item->dev->name, - item->type, item->size); + printf("%3x %-5s %8lx %5x %s\n", i, + gen_type_str[item->type], + (ulong)map_to_sysmem(item->base), item->size, + item->dev ? item->dev->name : item->writer->name); if (option == ACPI_DUMP_CONTENTS) { - print_buffer(0, item->buf, 1, item->size, 0); + print_buffer(0, item->buf ? item->buf : item->base, 1, + item->size, 0); printf("\n"); } } diff --git a/test/dm/acpi.c b/test/dm/acpi.c index da728692528..d648f3003a3 100644 --- a/test/dm/acpi.c +++ b/test/dm/acpi.c @@ -566,18 +566,22 @@ DM_TEST(dm_test_acpi_inject_dsdt, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); static int dm_test_acpi_cmd_items(struct unit_test_state *uts) { struct acpi_ctx ctx; + ulong addr; void *buf;
buf = malloc(BUF_SIZE); ut_assertnonnull(buf); + addr = map_to_sysmem(buf);
acpi_reset_items(); ctx.current = buf; ut_assertok(acpi_fill_ssdt(&ctx)); console_record_reset(); run_command("acpi items", 0); - ut_assert_nextline("dev 'acpi-test', type 1, size 2"); - ut_assert_nextline("dev 'acpi-test2', type 1, size 2"); + ut_assert_nextline("Seq Type Base Size Device/Writer"); + ut_assert_nextline("--- ----- -------- ---- -------------"); + ut_assert_nextline(" 0 ssdt %8lx 2 acpi-test", addr); + ut_assert_nextline(" 1 ssdt %8lx 2 acpi-test2", addr + 2); ut_assert_console_end();
acpi_reset_items(); @@ -585,16 +589,20 @@ static int dm_test_acpi_cmd_items(struct unit_test_state *uts) ut_assertok(acpi_inject_dsdt(&ctx)); console_record_reset(); run_command("acpi items", 0); - ut_assert_nextline("dev 'acpi-test', type 2, size 2"); - ut_assert_nextline("dev 'acpi-test2', type 2, size 2"); + ut_assert_nextlinen("Seq"); + ut_assert_nextlinen("---"); + ut_assert_nextline(" 0 dsdt %8lx 2 acpi-test", addr); + ut_assert_nextline(" 1 dsdt %8lx 2 acpi-test2", addr + 2); ut_assert_console_end();
console_record_reset(); run_command("acpi items -d", 0); - ut_assert_nextline("dev 'acpi-test', type 2, size 2"); + ut_assert_nextlinen("Seq"); + ut_assert_nextlinen("---"); + ut_assert_nextline(" 0 dsdt %8lx 2 acpi-test", addr); ut_assert_nextlines_are_dump(2); ut_assert_nextline("%s", ""); - ut_assert_nextline("dev 'acpi-test2', type 2, size 2"); + ut_assert_nextline(" 1 dsdt %8lx 2 acpi-test2", addr + 2); ut_assert_nextlines_are_dump(2); ut_assert_nextline("%s", ""); ut_assert_console_end();

At present this is really just a debugging aid, but it is a bit untidy. Add proper columns and display the type name instead of a number.
Sample output for coral:
=> acpi items Seq Type Addr Size Device/Writer --- ----- -------- ---- ------------- 0 other 79925000 240 0base 1 other 79925240 40 1facs 2 dsdt 799252a4 58 board 3 dsdt 799252fc 10 lpc 4 other 79925280 32f0 3dsdt 5 other 79928570 1000 4gnvs 6 other 79929570 100 5fact 7 other 79929670 30 5mcfg 8 other 799296a0 50 5spcr 9 other 799296f0 50 5tpm2 a other 79929740 70 5x86 b ssdt 799297d4 fe maxim-codec c ssdt 799298d2 28 i2c2@16,0 d ssdt 799298fa 270 da-codec e ssdt 79929b6a 28 i2c2@16,1 f ssdt 79929b92 28 i2c2@16,2 10 ssdt 79929bba 83 tpm@50 11 ssdt 79929c3d 28 i2c2@16,3 12 ssdt 79929c65 282 elan-touchscreen@10 13 ssdt 79929ee7 285 raydium-touchscreen@39 14 ssdt 7992a16c 28 i2c2@17,0 15 ssdt 7992a194 d8 elan-touchpad@15 16 ssdt 7992a26c 163 synaptics-touchpad@2c 17 ssdt 7992a3cf 28 i2c2@17,1 18 ssdt 7992a3f7 111 wacom-digitizer@9 19 ssdt 7992a508 8f sdmmc@1b,0 1a ssdt 7992a597 4b wifi 1b ssdt 7992a5e2 1a0 cpu@0 1c ssdt 7992a782 1a0 cpu@1 1d ssdt 7992a922 1a0 cpu@2 1e ssdt 7992aac2 211 cpu@3 1f other 799297b0 1530 6ssdt 20 other 7992ace0 2f10 8dev
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/core/acpi.c | 24 ++++++++++++++++++++---- test/dm/acpi.c | 20 ++++++++++++++------ 2 files changed, 34 insertions(+), 10 deletions(-)
Applied to u-boot-dm, thanks!

At present this is really just a debugging aid, but it is a bit untidy. Add proper columns so it is easier to read.
Sample output for coral:
=> acpi list Name Base Size Detail ---- -------- ----- ------ RSDP 79925000 24 v02 U-BOOT RSDT 79925030 48 v01 U-BOOT U-BOOTBL 20220101 INTL 0 XSDT 799250e0 6c v01 U-BOOT U-BOOTBL 20220101 INTL 0 FACP 79929570 f4 v04 U-BOOT U-BOOTBL 20220101 INTL 1 DSDT 79925280 32ea v02 U-BOOT U-BOOTBL 20110725 INTL 20180105 FACS 79925240 40 MCFG 79929670 2c v01 U-BOOT U-BOOTBL 20220101 INTL 0 SPCR 799296a0 50 v02 U-BOOT U-BOOTBL 20220101 INTL 0 TPM2 799296f0 4c v04 U-BOOT U-BOOTBL 20220101 INTL 0 APIC 79929740 6c v02 U-BOOT U-BOOTBL 20220101 INTL 0 SSDT 799297b0 1523 v02 U-BOOT U-BOOTBL 20220101 INTL 1 NHLT 7992ace0 e60 v05 coral coral 3 INTL 0 DBG2 7992db40 61 v00 U-BOOT U-BOOTBL 20220101 INTL 0 HPET 7992dbb0 38 v01 U-BOOT U-BOOTBL 20220101 INTL 0
Signed-off-by: Simon Glass sjg@chromium.org ---
cmd/acpi.c | 9 +++++---- test/dm/acpi.c | 15 ++++++++------- 2 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/cmd/acpi.c b/cmd/acpi.c index 92ac0f5d490..535aeef57f7 100644 --- a/cmd/acpi.c +++ b/cmd/acpi.c @@ -24,10 +24,10 @@ static void dump_hdr(struct acpi_table_header *hdr) { bool has_hdr = memcmp(hdr->signature, "FACS", ACPI_NAME_LEN);
- printf("%.*s %08lx %06x", ACPI_NAME_LEN, hdr->signature, + printf("%.*s %08lx %5x", ACPI_NAME_LEN, hdr->signature, (ulong)map_to_sysmem(hdr), hdr->length); if (has_hdr) { - printf(" (v%02d %.6s %.8s %x %.4s %x)\n", hdr->revision, + printf(" v%02d %.6s %.8s %x %.4s %x\n", hdr->revision, hdr->oem_id, hdr->oem_table_id, hdr->oem_revision, hdr->aslc_id, hdr->aslc_revision); } else { @@ -129,7 +129,7 @@ static int list_rsdp(struct acpi_rsdp *rsdp) struct acpi_rsdt *rsdt; struct acpi_xsdt *xsdt;
- printf("RSDP %08lx %06x (v%02d %.6s)\n", (ulong)map_to_sysmem(rsdp), + printf("RSDP %08lx %5x v%02d %.6s\n", (ulong)map_to_sysmem(rsdp), rsdp->length, rsdp->revision, rsdp->oem_id); rsdt = map_sysmem(rsdp->rsdt_address, 0); xsdt = map_sysmem(rsdp->xsdt_address, 0); @@ -148,7 +148,8 @@ static int do_acpi_list(struct cmd_tbl *cmdtp, int flag, int argc, printf("No ACPI tables present\n"); return 0; } - printf("ACPI tables start at %lx\n", gd_acpi_start()); + printf("Name Base Size Detail\n"); + printf("---- -------- ----- ------\n"); list_rsdp(rsdp);
return 0; diff --git a/test/dm/acpi.c b/test/dm/acpi.c index d648f3003a3..edad91329f9 100644 --- a/test/dm/acpi.c +++ b/test/dm/acpi.c @@ -393,25 +393,26 @@ static int dm_test_acpi_cmd_list(struct unit_test_state *uts)
console_record_reset(); run_command("acpi list", 0); - ut_assert_nextline("ACPI tables start at %lx", addr); - ut_assert_nextline("RSDP %08lx %06zx (v02 U-BOOT)", addr, + ut_assert_nextline("Name Base Size Detail"); + ut_assert_nextline("---- -------- ----- ------"); + ut_assert_nextline("RSDP %08lx %5zx v02 U-BOOT", addr, sizeof(struct acpi_rsdp)); addr = ALIGN(addr + sizeof(struct acpi_rsdp), 16); - ut_assert_nextline("RSDT %08lx %06zx (v01 U-BOOT U-BOOTBL %x INTL 0)", + ut_assert_nextline("RSDT %08lx %5zx v01 U-BOOT U-BOOTBL %x INTL 0", addr, sizeof(struct acpi_table_header) + 3 * sizeof(u32), OEM_REVISION); addr = ALIGN(addr + sizeof(struct acpi_rsdt), 16); - ut_assert_nextline("XSDT %08lx %06zx (v01 U-BOOT U-BOOTBL %x INTL 0)", + ut_assert_nextline("XSDT %08lx %5zx v01 U-BOOT U-BOOTBL %x INTL 0", addr, sizeof(struct acpi_table_header) + 3 * sizeof(u64), OEM_REVISION); addr = ALIGN(addr + sizeof(struct acpi_xsdt), 64); - ut_assert_nextline("DMAR %08lx %06zx (v01 U-BOOT U-BOOTBL %x INTL 0)", + ut_assert_nextline("DMAR %08lx %5zx v01 U-BOOT U-BOOTBL %x INTL 0", addr, sizeof(struct acpi_dmar), OEM_REVISION); addr = ALIGN(addr + sizeof(struct acpi_dmar), 16); - ut_assert_nextline("DMAR %08lx %06zx (v01 U-BOOT U-BOOTBL %x INTL 0)", + ut_assert_nextline("DMAR %08lx %5zx v01 U-BOOT U-BOOTBL %x INTL 0", addr, sizeof(struct acpi_dmar), OEM_REVISION); addr = ALIGN(addr + sizeof(struct acpi_dmar), 16); - ut_assert_nextline("DMAR %08lx %06zx (v01 U-BOOT U-BOOTBL %x INTL 0)", + ut_assert_nextline("DMAR %08lx %5zx v01 U-BOOT U-BOOTBL %x INTL 0", addr, sizeof(struct acpi_dmar), OEM_REVISION); ut_assert_console_end();

At present this is really just a debugging aid, but it is a bit untidy. Add proper columns so it is easier to read.
Sample output for coral:
=> acpi list Name Base Size Detail ---- -------- ----- ------ RSDP 79925000 24 v02 U-BOOT RSDT 79925030 48 v01 U-BOOT U-BOOTBL 20220101 INTL 0 XSDT 799250e0 6c v01 U-BOOT U-BOOTBL 20220101 INTL 0 FACP 79929570 f4 v04 U-BOOT U-BOOTBL 20220101 INTL 1 DSDT 79925280 32ea v02 U-BOOT U-BOOTBL 20110725 INTL 20180105 FACS 79925240 40 MCFG 79929670 2c v01 U-BOOT U-BOOTBL 20220101 INTL 0 SPCR 799296a0 50 v02 U-BOOT U-BOOTBL 20220101 INTL 0 TPM2 799296f0 4c v04 U-BOOT U-BOOTBL 20220101 INTL 0 APIC 79929740 6c v02 U-BOOT U-BOOTBL 20220101 INTL 0 SSDT 799297b0 1523 v02 U-BOOT U-BOOTBL 20220101 INTL 1 NHLT 7992ace0 e60 v05 coral coral 3 INTL 0 DBG2 7992db40 61 v00 U-BOOT U-BOOTBL 20220101 INTL 0 HPET 7992dbb0 38 v01 U-BOOT U-BOOTBL 20220101 INTL 0
Signed-off-by: Simon Glass sjg@chromium.org ---
cmd/acpi.c | 9 +++++---- test/dm/acpi.c | 15 ++++++++------- 2 files changed, 13 insertions(+), 11 deletions(-)
Applied to u-boot-dm, thanks!

Add some documentation for this command.
Signed-off-by: Simon Glass sjg@chromium.org ---
doc/usage/acpi.rst | 235 ++++++++++++++++++++++++++++++++++++++++++++ doc/usage/index.rst | 1 + 2 files changed, 236 insertions(+) create mode 100644 doc/usage/acpi.rst
diff --git a/doc/usage/acpi.rst b/doc/usage/acpi.rst new file mode 100644 index 00000000000..14bafc8e352 --- /dev/null +++ b/doc/usage/acpi.rst @@ -0,0 +1,235 @@ +.. SPDX-License-Identifier: GPL-2.0+: + +acpi command +============ + +Synopis +------- + +:: + + acpi list + acpi items [-d] + acpi dump <name> + +Description +----------- + +The *acpi* command is used to dump the ACPI tables generated by U-Boot for passing +to the operating systems. + +ACPI tables can be generated by various output functions and even devices can +output material to include in the Differentiated System Description Table (DSDT) +and SSDT tables (Secondary System Description Table). U-Boot keeps track of +which device or table-writer produced each piece of the ACPI tables. + +The ACPI tables are stored contiguously in memory. + + +acpi list +~~~~~~~~~ + +List the ACPI tables that have been generated. Each table has a 4-character +table name (e.g. SSDT, FACS) and has a format defined by the +`ACPI specification`_. + +U-Boot does not currently support decoding the tables. Unlike devicetree, ACPI +tables have no regular schema and also some include bytecode, so decoding the +tables requires a lot of code. + +The table shows the following information: + +Name + Table name, e.g. `MCFG` + +Base + Base address of table in memory + +Size + Size of table in bytes + +Detail + More information depending on the table type + + Revision + Table revision number (two decimal digits) + + OEM ID + ID for the Original Equipment Manufacturer. Typically this is "U-BOOT". + + OEM Table ID + Table ID for the Original Equipment Manufacturer. Typically this is + "U-BOOTBL" (U-Boot bootloader) + + OEM Revision + Revision string for the Original Equipment Manufacturer. Typically this + is the U-Boot release number, e.g. 20220101 (meaning v2022.01 since the + final 01 is not used). For DSDT, this is set by the source code in + the parameters of DefinitionBlock(). + + ACPI compiler-vendor ID + This is normally `INTL` for Intel + + ACPI compiler revision + This is the compiler revision. It is set to the version string for the + DSDT table but other tables just use the value 0 or 1, since U-Boot does + not actually use the compiler in these cases. It generates the code + itself. + +acpi items +~~~~~~~~~~ + +List the ACPI data that was generated, broken down by item. An item is either +an ACPI table generated by a writer function, or the part of a table that was +generated by a particular device. + +The `-d` flag also shows a binary dump of the table. + +The table shows the following information about each item: + +Seq + Sequence number in hex + +Type + Type of item + + ===== ============================================================ + Type Meaning + ===== ============================================================ + dsdt Fragment of a DSDT table, as generated by a device + ssdt Fragment of a SSDT table, as generated by a device + other A whole table of a particular type. as generated by a writer + ===== ============================================================ + +Base + Base address of table in memory + +Size + Size of table in bytes + +Device / Writer + Name of device (for ssdt/dsdt) that wrong this fragment of the table, or + name of the registered writer function (otherwise) that wrote the table. + +acpi dump +~~~~~~~~~ + +Dump a paticular ACPI table in binary format. This can be used to read the table +if you have the specification handy. + + +Example +------- + +:: + + => acpi list + Name Base Size Detail + ---- -------- ----- ------ + RSDP 79925000 24 v02 U-BOOT + RSDT 79925030 48 v01 U-BOOT U-BOOTBL 20220101 INTL 0 + XSDT 799250e0 6c v01 U-BOOT U-BOOTBL 20220101 INTL 0 + FACP 79929570 f4 v04 U-BOOT U-BOOTBL 20220101 INTL 1 + DSDT 79925280 32ea v02 U-BOOT U-BOOTBL 20110725 INTL 20180105 + FACS 79925240 40 + MCFG 79929670 2c v01 U-BOOT U-BOOTBL 20220101 INTL 0 + SPCR 799296a0 50 v02 U-BOOT U-BOOTBL 20220101 INTL 0 + TPM2 799296f0 4c v04 U-BOOT U-BOOTBL 20220101 INTL 0 + APIC 79929740 6c v02 U-BOOT U-BOOTBL 20220101 INTL 0 + SSDT 799297b0 1523 v02 U-BOOT U-BOOTBL 20220101 INTL 1 + NHLT 7992ace0 e60 v05 coral coral 3 INTL 0 + DBG2 7992db40 61 v00 U-BOOT U-BOOTBL 20220101 INTL 0 + HPET 7992dbb0 38 v01 U-BOOT U-BOOTBL 20220101 INTL 0 + => acpi items + Seq Type Base Size Device/Writer + --- ----- -------- ---- ------------- + 0 other 79925000 240 0base + 1 other 79925240 40 1facs + 2 dsdt 799252a4 58 board + 3 dsdt 799252fc 10 lpc + 4 other 79925280 32f0 3dsdt + 5 other 79928570 1000 4gnvs + 6 other 79929570 100 5fact + 7 other 79929670 30 5mcfg + 8 other 799296a0 50 5spcr + 9 other 799296f0 50 5tpm2 + a other 79929740 70 5x86 + b ssdt 799297d4 fe maxim-codec + c ssdt 799298d2 28 i2c2@16,0 + d ssdt 799298fa 270 da-codec + e ssdt 79929b6a 28 i2c2@16,1 + f ssdt 79929b92 28 i2c2@16,2 + 10 ssdt 79929bba 83 tpm@50 + 11 ssdt 79929c3d 28 i2c2@16,3 + 12 ssdt 79929c65 282 elan-touchscreen@10 + 13 ssdt 79929ee7 285 raydium-touchscreen@39 + 14 ssdt 7992a16c 28 i2c2@17,0 + 15 ssdt 7992a194 d8 elan-touchpad@15 + 16 ssdt 7992a26c 163 synaptics-touchpad@2c + 17 ssdt 7992a3cf 28 i2c2@17,1 + 18 ssdt 7992a3f7 111 wacom-digitizer@9 + 19 ssdt 7992a508 8f sdmmc@1b,0 + 1a ssdt 7992a597 4b wifi + 1b ssdt 7992a5e2 1a0 cpu@0 + 1c ssdt 7992a782 1a0 cpu@1 + 1d ssdt 7992a922 1a0 cpu@2 + 1e ssdt 7992aac2 211 cpu@3 + 1f other 799297b0 1530 6ssdt + 20 other 7992ace0 2f10 8dev + => acpi dump mcfg + MCFG @ 79929670 + 00000000: 4d 43 46 47 2c 00 00 00 01 41 55 2d 42 4f 4f 54 MCFG,....AU-BOOT + 00000010: 55 2d 42 4f 4f 54 42 4c 01 01 22 20 49 4e 54 4c U-BOOTBL.." INTL + 00000020: 00 00 00 00 00 00 00 00 00 00 00 00 ............ + => acpi items -d + Seq Type Base Size Device/Writer + --- ----- -------- ---- ------------- + 0 other 79925000 240 0base + 00000000: 52 53 44 20 50 54 52 20 9e 55 2d 42 4f 4f 54 02 RSD PTR .U-BOOT. + 00000010: 30 50 92 79 24 00 00 00 e0 50 92 79 00 00 00 00 0P.y$....P.y.... + 00000020: a1 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 00000030: 52 53 44 54 48 00 00 00 01 8b 55 2d 42 4f 4f 54 RSDTH.....U-BOOT + 00000040: 55 2d 42 4f 4f 54 42 4c 01 01 22 20 49 4e 54 4c U-BOOTBL.." INTL + 00000050: 00 00 00 00 70 95 92 79 70 96 92 79 a0 96 92 79 ....p..yp..y...y + 00000060: f0 96 92 79 40 97 92 79 b0 97 92 79 e0 ac 92 79 ...y@..y...y...y + 00000070: 40 db 92 79 b0 db 92 79 00 00 00 00 00 00 00 00 @..y...y........ + 00000080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 00000090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 000000a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 000000b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 000000c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 000000d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 000000e0: 58 53 44 54 6c 00 00 00 01 61 55 2d 42 4f 4f 54 XSDTl....aU-BOOT + 000000f0: 55 2d 42 4f 4f 54 42 4c 01 01 22 20 49 4e 54 4c U-BOOTBL.." INTL + 00000100: 00 00 00 00 70 95 92 79 00 00 00 00 70 96 92 79 ....p..y....p..y + 00000110: 00 00 00 00 a0 96 92 79 00 00 00 00 f0 96 92 79 .......y.......y + 00000120: 00 00 00 00 40 97 92 79 00 00 00 00 b0 97 92 79 ....@..y.......y + 00000130: 00 00 00 00 e0 ac 92 79 00 00 00 00 40 db 92 79 .......y....@..y + 00000140: 00 00 00 00 b0 db 92 79 00 00 00 00 00 00 00 00 .......y........ + 00000150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 00000160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + ... + + 1 other 79925240 40 1facs + 00000000: 46 41 43 53 40 00 00 00 00 00 00 00 00 00 00 00 FACS@........... + 00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 00000020: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + + 2 dsdt 799252a4 58 board + 00000000: 10 87 05 00 5c 00 08 4f 49 50 47 12 8c 04 00 03 ......OIPG..... + 00000010: 12 8b 01 00 04 01 01 0e ff ff ff ff ff ff ff ff ................ + 00000020: 0d 49 4e 54 33 34 35 32 3a 30 31 00 12 85 01 00 .INT3452:01..... + 00000030: 04 0a 03 01 0a 23 0d 49 4e 54 33 34 35 32 3a 30 .....#.INT3452:0 + 00000040: 31 00 12 85 01 00 04 0a 04 01 0a 0a 0d 49 4e 54 1............INT + 00000050: 33 34 35 32 3a 30 30 00 3452:00. + + 3 dsdt 799252fc 10 lpc + 00000000: 10 8f 00 00 5c 00 08 4e 56 53 41 0c 10 50 93 79 ......NVSA..P.y + + 4 other 79925280 32f0 3dsdt + 00000000: 44 53 44 54 ea 32 00 00 02 eb 55 2d 42 4f 4f 54 DSDT.2....U-BOOT + 00000010: 55 2d 42 4f 4f 54 42 4c 25 07 11 20 49 4e 54 4c U-BOOTBL%.. INTL + + +.. _`ACPI specification`: https://uefi.org/sites/default/files/resources/ACPI_6_3_final_Jan30.pdf diff --git a/doc/usage/index.rst b/doc/usage/index.rst index 3905540735c..70fc3db8628 100644 --- a/doc/usage/index.rst +++ b/doc/usage/index.rst @@ -19,6 +19,7 @@ Shell commands .. toctree:: :maxdepth: 1
+ acpi addrmap askenv base

Add some documentation for this command.
Signed-off-by: Simon Glass sjg@chromium.org ---
doc/usage/acpi.rst | 235 ++++++++++++++++++++++++++++++++++++++++++++ doc/usage/index.rst | 1 + 2 files changed, 236 insertions(+) create mode 100644 doc/usage/acpi.rst
Applied to u-boot-dm, thanks!

Add some tables needed for ARM devices, including more MADT subtables, a CSRT descriptor, GTDT and PPTT.
WIP: This needs comments added.
Signed-off-by: Simon Glass sjg@chromium.org ---
include/acpi/acpi_table.h | 205 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 205 insertions(+)
diff --git a/include/acpi/acpi_table.h b/include/acpi/acpi_table.h index 80646a44b2b..88750d044a6 100644 --- a/include/acpi/acpi_table.h +++ b/include/acpi/acpi_table.h @@ -162,6 +162,9 @@ enum acpi_pm_profile { #define ACPI_FADT_HW_REDUCED_ACPI BIT(20) #define ACPI_FADT_LOW_PWR_IDLE_S0 BIT(21)
+/* ARM boot flags */ +#define ACPI_ARM_PSCI_COMPLIANT BIT(0) + enum acpi_address_space_type { ACPI_ADDRESS_SPACE_MEMORY = 0, /* System memory */ ACPI_ADDRESS_SPACE_IO, /* System I/O */ @@ -237,6 +240,9 @@ struct __packed acpi_fadt { struct acpi_gen_regaddr x_pm_tmr_blk; struct acpi_gen_regaddr x_gpe0_blk; struct acpi_gen_regaddr x_gpe1_blk; + struct acpi_gen_regaddr sleep_control_reg; + struct acpi_gen_regaddr sleep_status_reg; + u64 hyp_vendor_id; };
/* FADT TABLE Revision values - note these do not match the ACPI revision */ @@ -302,6 +308,8 @@ enum acpi_apic_types { ACPI_APIC_PLATFORM_IRQ_SRC, /* Platform interrupt sources */ ACPI_APIC_LX2APIC, /* Processor local x2APIC */ ACPI_APIC_LX2APIC_NMI, /* Local x2APIC NMI */ + ACPI_APIC_GICC, /* Generic Interrupt Ctlr CPU i/f */ + ACPI_APIC_GICD /* Generic Interrupt Ctlr Distributor */ };
/* MADT: Processor Local APIC Structure */ @@ -345,6 +353,57 @@ struct __packed acpi_madt_lapic_nmi { u8 lint; /* Local APIC LINT# */ };
+/* flags for acpi_madr_gicc flags word */ +enum { + ACPI_MADRF_ENABLED = BIT(0), + ACPI_MADRF_PERF = BIT(1), + ACPI_MADRF_VGIC = BIT(2), +}; + +/** + * struct __packed acpi_madr_gicc - GIC CPU interface (type 0xb) + * + * This holds information about the Generic Interrupt Controller (GIC) CPU + * interface. See ACPI Spec v6.3 section 5.2.12.14 + */ +struct __packed acpi_madr_gicc { + u8 type; + u8 length; + u16 reserved; + u32 cpu_if_num; + u32 processor_id; + u32 flags; + u32 parking_proto; + u32 perf_gsiv; + u64 parked_addr; + u64 phys_base; + u64 gicv; + u64 gich; + u32 vgic_maint_irq; + u64 gicr_base; + u64 mpidr; + u8 efficiency; + u8 reserved2; + u16 spi_overflow_irq; +}; + +/** + * struct __packed acpi_madr_gicc - GIC distributor (type 0xc) + * + * This holds information about the Generic Interrupt Controller (GIC) + * Distributor interface. See ACPI Spec v6.3 section 5.2.12.15 + */ +struct __packed acpi_madr_gicd { + u8 type; + u8 length; + u16 reserved; + u32 gic_id; + u64 phys_base; + u32 reserved2; + u8 gic_version; + u8 reserved3[3]; +}; + /* MCFG (PCI Express MMIO config space BAR description table) */ struct acpi_mcfg { struct acpi_table_header header; @@ -371,6 +430,19 @@ struct acpi_csrt { struct acpi_table_header header; };
+/** + * struct acpi_csrt_group - header for a group within the CSRT + * + * The CSRT consists of one or more groups and this is the header for each + * + * See Core System Resources Table (CSRT), March 13, 2017, Microsoft Corporation + * for details + * + * https://uefi.org/sites/default/files/resources/CSRT%20v2.pdf + * + * @shared_info_length indicates the number of shared-info bytes following this + * struct (which may be 0) + */ struct acpi_csrt_group { u32 length; u32 vendor_id; @@ -382,6 +454,25 @@ struct acpi_csrt_group { u32 shared_info_length; };
+/** + * struct acpi_csrt_descriptor - describes the information that follows + * + * See the spec as above for details + */ +struct acpi_csrt_descriptor { + u32 length; + u16 type; + u16 subtype; + u32 uid; +}; + +/** + * struct acpi_csrt_shared_info - shared info for Intel tangier + * + * This provides the shared info for this particular board. Notes that the CSRT + * does not describe the format of data, so this format may not be used by any + * other board. + */ struct acpi_csrt_shared_info { u16 major_version; u16 minor_version; @@ -559,6 +650,120 @@ struct __packed acpi_spcr { u32 reserved2; };
+/** + * struct acpi_gtdt - Generic Timer Description Table (GTDT) + * + * See ACPI Spec v6.3 section 5.2.24 for details + */ +struct __packed acpi_gtdt { + struct acpi_table_header header; + u64 cnt_ctrl_base; + u32 reserved0; + u32 sec_el1_gsiv; + u32 sec_el1_flags; + u32 el1_gsiv; + u32 el1_flags; + u32 virt_el1_gsiv; + u32 virt_el1_flags; + u32 el2_gsiv; + u32 el2_flags; + u64 cnt_read_base; + u32 plat_timer_count; + u32 plat_timer_offset; + u32 virt_el2_gsiv; + u32 virt_el2_flags; +}; + +/** + * struct acpi_bgrt - Boot Graphics Resource Table (BGRT) + * + * Optional table that provides a mechanism to indicate that an image was drawn + * on the screen during boot, and some information about the image. + * + * See ACPI Spec v6.3 section 5.2.22 for details + */ +struct __packed acpi_bgrt { + struct acpi_table_header header; + u16 version; + u8 status; + u8 image_type; + u64 addr; + u32 offset_x; + u32 offset_y; +}; + +/* Types for PPTT */ +#define ACPI_PPTT_TYPE_PROC 0 +#define ACPI_PPTT_TYPE_CACHE 1 + +/* Flags for PPTT */ +#define ACPI_PPTT_PHYSICAL_PACKAGE BIT(0) +#define ACPI_PPTT_PROC_ID_VALID BIT(1) +#define ACPI_PPTT_PROC_IS_THREAD BIT(2) +#define ACPI_PPTT_NODE_IS_LEAF BIT(3) +#define ACPI_PPTT_CHILDREN_IDENTICAL BIT(4) + +/** + * struct acpi_pptt_header - Processor Properties Topology Table (PPTT) header + * + * Describes the topological structure of processors and their shared resources, + * such as caches. + * + * See ACPI Spec v6.3 section 5.2.29 for details + */ +struct __packed acpi_pptt_header { + u8 type; /* ACPI_PPTT_TYPE_... */ + u8 length; + u16 reserved; +}; + +/** + * struct acpi_pptt_proc - a processor as described by PPTT + */ +struct __packed acpi_pptt_proc { + struct acpi_pptt_header hdr; + u32 flags; + u32 parent; + u32 proc_id; + u32 num_resources; +}; + +/* Cache flags for acpi_pptt_cache */ +#define ACPI_PPTT_SIZE_VALID BIT(0) +#define ACPI_PPTT_SETS_VALID BIT(1) +#define ACPI_PPTT_ASSOC_VALID BIT(2) +#define ACPI_PPTT_ALLOC_TYPE_VALID BIT(3) +#define ACPI_PPTT_CACHE_TYPE_VALID BIT(4) +#define ACPI_PPTT_WRITE_POLICY_VALID BIT(5) +#define ACPI_PPTT_LINE_SIZE_VALID BIT(6) + +#define ACPI_PPTT_ALL_VALID 0x7f +#define ACPI_PPTT_ALL_BUT_WRITE_POL 0x5f + +#define ACPI_PPTT_READ_ALLOC BIT(0) +#define ACPI_PPTT_WRITE_ALLOC BIT(1) +#define ACPI_PPTT_CACHE_TYPE_SHIFT 2 +#define ACPI_PPTT_CACHE_TYPE_MASK (3 << ACPI_PPTT_CACHE_TYPE_SHIFT) +#define ACPI_PPTT_CACHE_TYPE_DATA 0 +#define ACPI_PPTT_CACHE_TYPE_INSTR 1 +#define ACPI_PPTT_CACHE_TYPE_UNIFIED 2 +#define ACPI_PPTT_CACHE_TYPE_DATA 0 +#define ACPI_PPTT_WRITE_THROUGH BIT(4) + +/** + * struct acpi_pptt_cache - a cache as described by PPTT + */ +struct __packed acpi_pptt_cache { + struct acpi_pptt_header hdr; + u32 flags; + u32 next_cache_level; + u32 size; + u32 sets; + u8 assoc; + u8 attributes; + u16 line_size; +}; + /* Tables defined/reserved by ACPI and generated by U-Boot */ enum acpi_tables { ACPITAB_BERT,

Add some tables needed for ARM devices, including more MADT subtables, a CSRT descriptor, GTDT and PPTT.
WIP: This needs comments added.
Signed-off-by: Simon Glass sjg@chromium.org ---
include/acpi/acpi_table.h | 205 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 205 insertions(+)
Applied to u-boot-dm, thanks!

Add myself as maintainer of the generic ACPI code, until someone else steps up to take it on.
Signed-off-by: Simon Glass sjg@chromium.org ---
MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS index 9045e509d73..062679ed3a8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -50,6 +50,12 @@ so much easier [Ed] Maintainers List (try to look for most precise areas first)
----------------------------------- +ACPI: +M: Simon Glass sjg@chromium.org +S: Maintained +F: cmd/acpi.c +F: lib/acpi/ + ANDROID AB M: Igor Opaniuk igor.opaniuk@gmail.com R: Sam Protsenko joe.skb7@gmail.com

Add myself as maintainer of the generic ACPI code, until someone else steps up to take it on.
Signed-off-by: Simon Glass sjg@chromium.org ---
MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+)
Applied to u-boot-dm, thanks!

Turn this on for debugging purposes.
Signed-off-by: Simon Glass sjg@chromium.org ---
lib/acpi/acpi_writer.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/lib/acpi/acpi_writer.c b/lib/acpi/acpi_writer.c index 946f90e8e7b..98965cc443d 100644 --- a/lib/acpi/acpi_writer.c +++ b/lib/acpi/acpi_writer.c @@ -6,6 +6,7 @@ */
#define LOG_CATEGORY LOGC_ACPI +#define LOG_DEBUG
#include <common.h> #include <log.h>

At present it seems possible to pass ACPI tables using bootefi but in practice an error is produced about not beling allowed to pass devicetree as well.
Add some workarounds for this. Presumably I am missing something and this should already work. Perhaps fdt should be set to 0?
Not to be applied.
Signed-off-by: Simon Glass sjg@chromium.org ---
cmd/bootefi.c | 44 +++++++++++++++++------------------------ lib/efi_loader/Makefile | 2 -- 2 files changed, 18 insertions(+), 28 deletions(-)
diff --git a/cmd/bootefi.c b/cmd/bootefi.c index 83eab0bd7f1..9815f5766cc 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -142,8 +142,6 @@ static efi_status_t efi_env_set_load_options(efi_handle_t handle, return ret; }
-#if !CONFIG_IS_ENABLED(GENERATE_ACPI_TABLE) - /** * copy_fdt() - Copy the device tree to a new location available to EFI * @@ -230,8 +228,6 @@ static void *get_config_table(const efi_guid_t *guid) return NULL; }
-#endif /* !CONFIG_IS_ENABLED(GENERATE_ACPI_TABLE) */ - /** * efi_install_fdt() - install device tree * @@ -251,16 +247,6 @@ static void *get_config_table(const efi_guid_t *guid) */ efi_status_t efi_install_fdt(void *fdt) { - /* - * The EBBR spec requires that we have either an FDT or an ACPI table - * but not both. - */ -#if CONFIG_IS_ENABLED(GENERATE_ACPI_TABLE) - if (fdt) { - log_err("ERROR: can't have ACPI table and device tree.\n"); - return EFI_LOAD_ERROR; - } -#else bootm_headers_t img = { 0 }; efi_status_t ret;
@@ -316,7 +302,6 @@ efi_status_t efi_install_fdt(void *fdt) log_err("ERROR: failed to install device tree\n"); return ret; } -#endif /* GENERATE_ACPI_TABLE */
return EFI_SUCCESS; } @@ -625,19 +610,26 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int flag, int argc, return CMD_RET_FAILURE; }
- if (argc > 2) { - uintptr_t fdt_addr; + /* + * The EBBR spec requires that we have either an FDT or an ACPI table + * but not both. + */ + if (!IS_ENABLED(CONFIG_GENERATE_ACPI_TABLE)) { + if (argc > 2) { + uintptr_t fdt_addr; + + fdt_addr = hextoul(argv[2], NULL); + fdt = map_sysmem(fdt_addr, 0); + } else { + fdt = EFI_FDT_USE_INTERNAL; + }
- fdt_addr = hextoul(argv[2], NULL); - fdt = map_sysmem(fdt_addr, 0); - } else { - fdt = EFI_FDT_USE_INTERNAL; + ret = efi_install_fdt(fdt); + if (ret == EFI_INVALID_PARAMETER) + return CMD_RET_USAGE; + else if (ret != EFI_SUCCESS) + return CMD_RET_FAILURE; } - ret = efi_install_fdt(fdt); - if (ret == EFI_INVALID_PARAMETER) - return CMD_RET_USAGE; - else if (ret != EFI_SUCCESS) - return CMD_RET_FAILURE;
if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) { if (!strcmp(argv[1], "bootmgr")) diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index fd344cea29b..1f8edecb983 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -30,9 +30,7 @@ obj-y += efi_console.o obj-y += efi_device_path.o obj-$(CONFIG_EFI_DEVICE_PATH_TO_TEXT) += efi_device_path_to_text.o obj-$(CONFIG_EFI_DEVICE_PATH_UTIL) += efi_device_path_utilities.o -ifeq ($(CONFIG_GENERATE_ACPI_TABLE),) obj-y += efi_dt_fixup.o -endif obj-y += efi_file.o obj-$(CONFIG_EFI_LOADER_HII) += efi_hii.o obj-y += efi_image_loader.o

Bring in some ACPI files, some of which are needed to build the ACPI tables for Raspberry Pi.
This needs to be sorted out.
Signed-off-by: Simon Glass sjg@chromium.org ---
board/raspberrypi/rpi/acpitables.h | 189 ++++++ board/raspberrypi/rpi/acpitables.inf | 79 +++ board/raspberrypi/rpi/csrt.aslc | 330 ++++++++++ board/raspberrypi/rpi/dbg2miniuart.aslc | 81 +++ board/raspberrypi/rpi/dbg2pl011.aslc | 81 +++ board/raspberrypi/rpi/dsdt.asl | 285 +++++++++ board/raspberrypi/rpi/emmc.asl | 166 +++++ board/raspberrypi/rpi/fadt.aslc | 96 +++ board/raspberrypi/rpi/gpudevs.asl | 397 ++++++++++++ board/raspberrypi/rpi/gtdt.aslc | 55 ++ board/raspberrypi/rpi/iort.aslc | 100 +++ board/raspberrypi/rpi/madt.aslc | 78 +++ board/raspberrypi/rpi/pci.asl | 168 +++++ board/raspberrypi/rpi/pep.asl | 90 +++ board/raspberrypi/rpi/pep.c | 79 +++ board/raspberrypi/rpi/pep.h | 121 ++++ board/raspberrypi/rpi/pptt.aslc | 191 ++++++ board/raspberrypi/rpi/rhpx.asl | 195 ++++++ board/raspberrypi/rpi/rpi4.dsc | 790 ++++++++++++++++++++++++ board/raspberrypi/rpi/sdhc.asl | 119 ++++ board/raspberrypi/rpi/spcrminiuart.aslc | 91 +++ board/raspberrypi/rpi/spcrpl011.aslc | 91 +++ board/raspberrypi/rpi/ssdtthermal.asl | 77 +++ board/raspberrypi/rpi/uart.asl | 202 ++++++ board/raspberrypi/rpi/xhci.asl | 165 +++++ 25 files changed, 4316 insertions(+) create mode 100644 board/raspberrypi/rpi/acpitables.h create mode 100644 board/raspberrypi/rpi/acpitables.inf create mode 100644 board/raspberrypi/rpi/csrt.aslc create mode 100644 board/raspberrypi/rpi/dbg2miniuart.aslc create mode 100644 board/raspberrypi/rpi/dbg2pl011.aslc create mode 100644 board/raspberrypi/rpi/dsdt.asl create mode 100644 board/raspberrypi/rpi/emmc.asl create mode 100644 board/raspberrypi/rpi/fadt.aslc create mode 100644 board/raspberrypi/rpi/gpudevs.asl create mode 100644 board/raspberrypi/rpi/gtdt.aslc create mode 100644 board/raspberrypi/rpi/iort.aslc create mode 100644 board/raspberrypi/rpi/madt.aslc create mode 100644 board/raspberrypi/rpi/pci.asl create mode 100644 board/raspberrypi/rpi/pep.asl create mode 100644 board/raspberrypi/rpi/pep.c create mode 100644 board/raspberrypi/rpi/pep.h create mode 100644 board/raspberrypi/rpi/pptt.aslc create mode 100644 board/raspberrypi/rpi/rhpx.asl create mode 100644 board/raspberrypi/rpi/rpi4.dsc create mode 100644 board/raspberrypi/rpi/sdhc.asl create mode 100644 board/raspberrypi/rpi/spcrminiuart.aslc create mode 100644 board/raspberrypi/rpi/spcrpl011.aslc create mode 100644 board/raspberrypi/rpi/ssdtthermal.asl create mode 100644 board/raspberrypi/rpi/uart.asl create mode 100644 board/raspberrypi/rpi/xhci.asl
diff --git a/board/raspberrypi/rpi/acpitables.h b/board/raspberrypi/rpi/acpitables.h new file mode 100644 index 00000000000..74461350f19 --- /dev/null +++ b/board/raspberrypi/rpi/acpitables.h @@ -0,0 +1,189 @@ +/** @file + * + * RPi defines for constructing ACPI tables + * + * Copyright (c) 2020, Pete Batard pete@akeo.ie + * Copyright (c) 2019, ARM Ltd. All rights reserved. + * Copyright (c) 2018, Andrei Warkentin andrey.warkentin@gmail.com + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-2-Clause-Patent + * + **/ + +#ifndef __RPI_ACPITABLES_H__ +#define __RPI_ACPITABLES_H__ + +#include <acpi/acpi_table.h> + +#ifdef CONFIG_TARGET_RPI_4 +#define RPI_MODEL 4 +#elif CONFIG_TARGET_RPI_3 +#define RPI_MODEL 3 +#else +#error "Unsupported rpi module for ACPI tables" +#endif + +/* These are taken from rpi.dsc */ +#define PcdBcm283xRegistersAddress 0xfe000000 +#define PcdBcmGenetRegistersAddress 0xfd580000 + +#define FixedPcdGet64(x) x + +// The ASL compiler can't perform arithmetic on MEMORY32FIXED () +// parameters so you can't pass a constant like BASE + OFFSET. +// We therefore define a macro that can perform arithmetic base +// address update with an offset. +#define MEMORY32SETBASE(BufName, MemName, VarName, Offset) \ + CreateDwordField (^BufName, ^MemName._BAS, VarName) \ + Add (BCM2836_SOC_REGISTERS, Offset, VarName) + +#define EFI_ACPI_OEM_ID {'R','P','I','F','D','N'} +#if (RPI_MODEL == 3) +#define EFI_ACPI_OEM_TABLE_ID SIGNATURE_64 ('R','P','I','3',' ',' ',' ',' ') +#elif (RPI_MODEL == 4) +#define EFI_ACPI_OEM_TABLE_ID SIGNATURE_64 ('R','P','I','4',' ',' ',' ',' ') +#endif +#define EFI_ACPI_OEM_REVISION 0x00000200 +#define EFI_ACPI_CREATOR_ID SIGNATURE_32 ('E','D','K','2') +#define EFI_ACPI_CREATOR_REVISION 0x00000300 + +#define EFI_ACPI_VENDOR_ID SIGNATURE_32 ('R','P','I','F') + +// A macro to initialise the common header part of EFI ACPI tables as defined by +// EFI_ACPI_DESCRIPTION_HEADER structure. +#define ACPI_HEADER(Signature, Type, Revision) { \ + Signature, /* u32 Signature */ \ + sizeof (Type), /* u32 Length */ \ + Revision, /* u8 Revision */ \ + 0, /* u8 Checksum */ \ + EFI_ACPI_OEM_ID, /* u8 OemId[6] */ \ + EFI_ACPI_OEM_TABLE_ID, /* u64 OemTableId */ \ + EFI_ACPI_OEM_REVISION, /* u32 OemRevision */ \ + EFI_ACPI_CREATOR_ID, /* u32 CreatorId */ \ + EFI_ACPI_CREATOR_REVISION /* u32 CreatorRevision */ \ + } + +#define EFI_ACPI_CSRT_REVISION 0x00000005 +#define EFI_ACPI_CSRT_DEVICE_ID_DMA 0x00000009 // Fixed id +#define EFI_ACPI_CSRT_RESOURCE_ID_IN_DMA_GRP 0x0 // Count up from 0 + +#define RPI_DMA_CHANNEL_COUNT 10 // All 10 DMA channels are listed, including the reserved ones +#define RPI_DMA_USED_CHANNEL_COUNT 5 // Use 5 DMA channels + +#if (RPI_MODEL == 3) +#define RPI_SYSTEM_TIMER_BASE_ADDRESS 0x4000001c +#elif (RPI_MODEL == 4) +#define RPI_SYSTEM_TIMER_BASE_ADDRESS 0xff80001c +#else +#error "Unknown RPI_DMA_CHANNEL_COUNT model" +#endif + +#define EFI_ACPI_6_3_CSRT_REVISION 0x00000000 + +#if !defined(__ACPI__) + +typedef enum +{ + EFI_ACPI_CSRT_RESOURCE_TYPE_RESERVED, // 0 + EFI_ACPI_CSRT_RESOURCE_TYPE_INTERRUPT, // 1 + EFI_ACPI_CSRT_RESOURCE_TYPE_TIMER, // 2 + EFI_ACPI_CSRT_RESOURCE_TYPE_DMA, // 3 + EFI_ACPI_CSRT_RESOURCE_TYPE_CACHE, // 4 +} +CSRT_RESOURCE_TYPE; + +typedef enum +{ + EFI_ACPI_CSRT_RESOURCE_SUBTYPE_DMA_CHANNEL, // 0 + EFI_ACPI_CSRT_RESOURCE_SUBTYPE_DMA_CONTROLLER // 1 +} +CSRT_DMA_SUBTYPE; + +//------------------------------------------------------------------------ +// CSRT Resource Group header 24 bytes long +//------------------------------------------------------------------------ +typedef struct +{ + u32 Length; // Length + u32 VendorID; // 4 bytes + u32 SubVendorId; // 4 bytes + u16 DeviceId; // 2 bytes + u16 SubdeviceId; // 2 bytes + u16 Revision; // 2 bytes + u16 Reserved; // 2 bytes + u32 SharedInfoLength; // 4 bytes +} EFI_ACPI_6_3_CSRT_RESOURCE_GROUP_HEADER; + +//------------------------------------------------------------------------ +// CSRT Resource Descriptor 12 bytes total +//------------------------------------------------------------------------ +typedef struct +{ + u32 Length; // 4 bytes + u16 ResourceType; // 2 bytes + u16 ResourceSubType; // 2 bytes + u32 UID; // 4 bytes +} EFI_ACPI_6_3_CSRT_RESOURCE_DESCRIPTOR_HEADER; + +#endif /* __ACPI__ */ + + +//------------------------------------------------------------------------ +// Interrupts. These are specific to each platform +//------------------------------------------------------------------------ +#if (RPI_MODEL == 3) +#define BCM2836_V3D_BUS_INTERRUPT 0x2A +#define BCM2836_DMA_INTERRUPT 0x3B +#define BCM2836_SPI1_INTERRUPT 0x3D +#define BCM2836_SPI2_INTERRUPT 0x3D +#define BCM2836_HVS_INTERRUPT 0x41 +#define BCM2836_HDMI0_INTERRUPT 0x48 +#define BCM2836_HDMI1_INTERRUPT 0x49 +#define BCM2836_PV2_INTERRUPT 0x4A +#define BCM2836_PV0_INTERRUPT 0x4D +#define BCM2836_PV1_INTERRUPT 0x4E +#define BCM2836_MBOX_INTERRUPT 0x61 +#define BCM2836_VCHIQ_INTERRUPT 0x62 +#define BCM2386_GPIO_INTERRUPT0 0x51 +#define BCM2386_GPIO_INTERRUPT1 0x52 +#define BCM2386_GPIO_INTERRUPT2 0x53 +#define BCM2386_GPIO_INTERRUPT3 0x54 +#define BCM2836_I2C1_INTERRUPT 0x55 +#define BCM2836_I2C2_INTERRUPT 0x55 +#define BCM2836_SPI0_INTERRUPT 0x56 +#define BCM2836_USB_INTERRUPT 0x29 +#define BCM2836_SDHOST_INTERRUPT 0x58 +#define BCM2836_MMCHS1_INTERRUPT 0x5E +#define BCM2836_MINI_UART_INTERRUPT 0x3D +#define BCM2836_PL011_UART_INTERRUPT 0x59 +#elif (RPI_MODEL == 4) +#define BCM2836_V3D_BUS_INTERRUPT 0x2A +#define BCM2836_DMA_INTERRUPT 0x3B +#define BCM2836_SPI1_INTERRUPT 0x7D +#define BCM2836_SPI2_INTERRUPT 0x7D +#define BCM2836_HVS_INTERRUPT 0x41 +#define BCM2836_HDMI0_INTERRUPT 0x48 +#define BCM2836_HDMI1_INTERRUPT 0x49 +#define BCM2836_PV2_INTERRUPT 0x4A +#define BCM2836_PV0_INTERRUPT 0x4D +#define BCM2836_PV1_INTERRUPT 0x4E +#define BCM2836_MBOX_INTERRUPT 0x41 +#define BCM2836_VCHIQ_INTERRUPT 0x42 +#define BCM2386_GPIO_INTERRUPT0 0x91 +#define BCM2386_GPIO_INTERRUPT1 0x92 +#define BCM2386_GPIO_INTERRUPT2 0x93 +#define BCM2386_GPIO_INTERRUPT3 0x94 +#define BCM2836_I2C1_INTERRUPT 0x95 +#define BCM2836_I2C2_INTERRUPT 0x95 +#define BCM2836_SPI0_INTERRUPT 0x96 +#define BCM2836_USB_INTERRUPT 0x69 +#define BCM2836_SDHOST_INTERRUPT 0x98 +#define BCM2836_MMCHS1_INTERRUPT 0x9E +#define BCM2836_MINI_UART_INTERRUPT 0x7D +#define BCM2836_PL011_UART_INTERRUPT 0x99 +#define GENET_INTERRUPT0 0xBD +#define GENET_INTERRUPT1 0xBE +#endif + +#endif // __ACPITABLES_H__ diff --git a/board/raspberrypi/rpi/acpitables.inf b/board/raspberrypi/rpi/acpitables.inf new file mode 100644 index 00000000000..11aca9be39e --- /dev/null +++ b/board/raspberrypi/rpi/acpitables.inf @@ -0,0 +1,79 @@ +#/** @file +# +# ACPI table data and ASL sources required to boot the platform. +# +# Copyright (c) 2019-2021, ARM Limited. All rights reserved. +# Copyright (c) 2017, Andrey Warkentin andrey.warkentin@gmail.com +# Copyright (c) Microsoft Corporation. All rights reserved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +#**/ + +[Defines] + INF_VERSION = 0x0001001A + BASE_NAME = AcpiTables + FILE_GUID = 7E374E25-8E01-4FEE-87F2-390C23C606CD + MODULE_TYPE = USER_DEFINED + VERSION_STRING = 1.0 + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = AARCH64 +# + +[Sources] + AcpiTables.h + Emmc.asl + Madt.aslc + Fadt.aslc + Dbg2MiniUart.aslc + Dbg2Pl011.aslc + Gtdt.aslc + Iort.aslc + Dsdt.asl + Csrt.aslc + SpcrMiniUart.aslc + SpcrPl011.aslc + Pptt.aslc + SsdtThermal.asl + Xhci.asl + Pci.asl + +[Packages] + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + EmbeddedPkg/EmbeddedPkg.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + Platform/RaspberryPi/RaspberryPi.dec + Silicon/Broadcom/Bcm27xx/Bcm27xx.dec + Silicon/Broadcom/Bcm283x/Bcm283x.dec + Silicon/Broadcom/Drivers/Net/BcmNet.dec + +[FixedPcd] + gArmTokenSpaceGuid.PcdArmArchTimerIntrNum + gArmTokenSpaceGuid.PcdArmArchTimerHypIntrNum + gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum + gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum + gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase + gArmTokenSpaceGuid.PcdGicDistributorBase + gBcm27xxTokenSpaceGuid.PcdBcm27xxPciCpuMmioAdr + gBcm27xxTokenSpaceGuid.PcdBcm27xxPciBusMmioAdr + gBcm27xxTokenSpaceGuid.PcdBcm27xxPciBusMmioLen + gBcm27xxTokenSpaceGuid.PcdBcm27xxPciRegBase + gBcm27xxTokenSpaceGuid.PcdBcmGenetRegistersAddress + gBcm283xTokenSpaceGuid.PcdBcm283xRegistersAddress + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate + gEmbeddedTokenSpaceGuid.PcdInterruptBaseAddress + gRaspberryPiTokenSpaceGuid.PcdGicInterruptInterfaceHBase + gRaspberryPiTokenSpaceGuid.PcdGicInterruptInterfaceVBase + gRaspberryPiTokenSpaceGuid.PcdGicGsivId + gRaspberryPiTokenSpaceGuid.PcdGicPmuIrq0 + gRaspberryPiTokenSpaceGuid.PcdGicPmuIrq1 + gRaspberryPiTokenSpaceGuid.PcdGicPmuIrq2 + gRaspberryPiTokenSpaceGuid.PcdGicPmuIrq3 + +[BuildOptions] + GCC:*_*_*_ASL_FLAGS = -vw3133 -vw3150 diff --git a/board/raspberrypi/rpi/csrt.aslc b/board/raspberrypi/rpi/csrt.aslc new file mode 100644 index 00000000000..b230f95ed07 --- /dev/null +++ b/board/raspberrypi/rpi/csrt.aslc @@ -0,0 +1,330 @@ +/** @file + * + * Core System Resource Table (CSRT) + * + * Copyright (c) 2019, ARM Ltd. All rights reserved. + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-2-Clause-Patent + * + **/ + +#include <IndustryStandard/Acpi.h> +#include <IndustryStandard/Bcm2836.h> + +#include "AcpiTables.h" + +#define RPI_DMA_MAX_REQ_LINES 32 + +#pragma pack (push, 1) + +//------------------------------------------------------------------------ +// DMA Controller Vendor Data +//------------------------------------------------------------------------ +typedef struct +{ + UINT32 Length; + UINT32 Type; + UINT64 ChannelsBaseAddress; + UINT32 ChannelsBaseSize; + UINT64 ControllerBaseAddress; + UINT32 ControllerBaseSize; + UINT32 ChannelCount; + UINT32 ControllerInterrupt; + UINT32 MinimumRequestLine; + UINT32 MaximumRequestLine; + BOOLEAN CacheCoherent; +} DMA_CONTROLLER_VENDOR_DATA; + +//------------------------------------------------------------------------ +// DMA Controller +//------------------------------------------------------------------------ +typedef struct +{ + EFI_ACPI_6_3_CSRT_RESOURCE_DESCRIPTOR_HEADER DmaControllerHeader; + DMA_CONTROLLER_VENDOR_DATA ControllerVendorData; +} RD_DMA_CONTROLLER; + +//------------------------------------------------------------------------ +// DMA Channel Vendor Data +//------------------------------------------------------------------------ +typedef struct +{ + UINT32 ChannelNumber; + UINT32 ChannelInterrupt; + UINT16 IsReservedChannel; + UINT16 NoSrcNoDestAddrIncr; +} DMA_CHANNEL_VENDOR_DATA; + +//------------------------------------------------------------------------ +// DMA Channel +//------------------------------------------------------------------------ +typedef struct +{ + EFI_ACPI_6_3_CSRT_RESOURCE_DESCRIPTOR_HEADER DmaChannelHeader; + DMA_CHANNEL_VENDOR_DATA ChannelVendorData; +} RD_DMA_CHANNEL; + +//------------------------------------------------------------------------ +// DMA Resource Group +//------------------------------------------------------------------------ + +typedef struct +{ + EFI_ACPI_6_3_CSRT_RESOURCE_GROUP_HEADER ResGroupHeader; + RD_DMA_CONTROLLER DmaController; + RD_DMA_CHANNEL DmaChannels[RPI_DMA_CHANNEL_COUNT]; +} RG_DMA; + +//---------------------------------------------------------------------------- +// CSRT table structure - current revision only includes DMA +//---------------------------------------------------------------------------- +typedef struct +{ +// Standard ACPI Header + EFI_ACPI_DESCRIPTION_HEADER CsrtHeader; + +// DMA Resource Group + RG_DMA DmaResourceGroup; + +} EFI_ACPI_6_3_CSRT_TABLE; + +EFI_ACPI_6_3_CSRT_TABLE Csrt = +{ + //------------------------------------------------------------------------ + // ACPI Table Header + //------------------------------------------------------------------------ + { + EFI_ACPI_6_3_CORE_SYSTEM_RESOURCE_TABLE_SIGNATURE, // Signature "CSRT" + sizeof (EFI_ACPI_DESCRIPTION_HEADER) + sizeof (RG_DMA), // Length + EFI_ACPI_6_3_CSRT_REVISION, // Revision + 0x00, // Checksum calculated at runtime. + EFI_ACPI_OEM_ID, // OEMID is a 6 bytes long field + EFI_ACPI_OEM_TABLE_ID, // OEM table identification (8 bytes long) + EFI_ACPI_OEM_REVISION, // OEM revision number. + EFI_ACPI_CREATOR_ID, // ASL compiler vendor ID. + EFI_ACPI_CREATOR_REVISION // ASL compiler revision number. + }, + + //------------------------------------------------------------------------ + // DMA Resource Group + //------------------------------------------------------------------------ + { + + //------------------------------------------------------------------------ + // DMA Resource Group Header + //------------------------------------------------------------------------ + { + sizeof (RG_DMA), // Resource Group Length + EFI_ACPI_VENDOR_ID, // VendorId + 0, // SubvendorId + EFI_ACPI_CSRT_DEVICE_ID_DMA, // DeviceId 9 + 0, // SubdeviceId + 0, // Revision + 0, // Reserved + 0 // SharedInfoLength + }, + + //------------------------------------------------------------------------------- + // Resource Descriptor - DMA Controller + //------------------------------------------------------------------------------- + { + { + sizeof (RD_DMA_CONTROLLER), // Length of this Resource Descriptor + EFI_ACPI_CSRT_RESOURCE_TYPE_DMA, // Type for this resource 3=DMA + EFI_ACPI_CSRT_RESOURCE_SUBTYPE_DMA_CONTROLLER, // Subtype for this resource 1=DMA Controller + EFI_ACPI_CSRT_RESOURCE_ID_IN_DMA_GRP + 0, // ResourceId - 1st DMA controller + }, + { + sizeof (DMA_CONTROLLER_VENDOR_DATA), // Controller vendor data here + 1, + BCM2836_DMA0_BASE_ADDRESS, // Base address for channels + RPI_DMA_CHANNEL_COUNT * BCM2836_DMA_CHANNEL_LENGTH, // Base size = Number of channels x channel size + BCM2836_DMA_CTRL_BASE_ADDRESS,// Base address for controller + 8, // Base size = two registers + RPI_DMA_USED_CHANNEL_COUNT, + 0, // cannot use controller interrupt + 0, // Minimum Request Line + RPI_DMA_MAX_REQ_LINES - 1, // Maximum Request Line + FALSE, + }, + }, + + //------------------------------------------------------------------------ + // Resource Descriptor(s) - DMA Channels 0 to n-1 + //------------------------------------------------------------------------ + { + + // Channel 0 + { + { + sizeof (RD_DMA_CHANNEL), // Length of this Resource Descriptor + EFI_ACPI_CSRT_RESOURCE_TYPE_DMA, // Type for this resource 3=DMA + EFI_ACPI_CSRT_RESOURCE_SUBTYPE_DMA_CHANNEL, // Subtype for this resource 0=DMA Channel + EFI_ACPI_CSRT_RESOURCE_ID_IN_DMA_GRP + 1, // ResourceId + }, + { + 0, // Channel vendor data here + 0x30, // 16+32 dma_int[0] + 0, + 0 + }, + }, + + // Channel 1 reserved + { + { + sizeof (RD_DMA_CHANNEL), + EFI_ACPI_CSRT_RESOURCE_TYPE_DMA, + EFI_ACPI_CSRT_RESOURCE_SUBTYPE_DMA_CHANNEL, + EFI_ACPI_CSRT_RESOURCE_ID_IN_DMA_GRP + 2, // ResourceId + }, + { + 1, // Channel vendor data here + 0x31, // 17+32 dma_int[1] + 1, + 0 + }, + }, + + // Channel 2 - VC4 use only + { + { + sizeof (RD_DMA_CHANNEL), + EFI_ACPI_CSRT_RESOURCE_TYPE_DMA, + EFI_ACPI_CSRT_RESOURCE_SUBTYPE_DMA_CHANNEL, + EFI_ACPI_CSRT_RESOURCE_ID_IN_DMA_GRP + 3, // ResourceId + }, + { + 2, // Channel vendor data here + 0x32, // 18+32 dma_int[2] + 1, + 0 + }, + }, + + // Channel 3 - VC4 use only + { + { + sizeof (RD_DMA_CHANNEL), + EFI_ACPI_CSRT_RESOURCE_TYPE_DMA, + EFI_ACPI_CSRT_RESOURCE_SUBTYPE_DMA_CHANNEL, + EFI_ACPI_CSRT_RESOURCE_ID_IN_DMA_GRP + 4, + }, + { + 3, // Channel vendor data here + 0x33, // 19+32 dma_int[3] + 1, + 0 + }, + }, + + // channel 4 + { + { + sizeof (RD_DMA_CHANNEL), + EFI_ACPI_CSRT_RESOURCE_TYPE_DMA, + EFI_ACPI_CSRT_RESOURCE_SUBTYPE_DMA_CHANNEL, + EFI_ACPI_CSRT_RESOURCE_ID_IN_DMA_GRP + 5, + }, + { + 4, // Channel vendor data here + 0x34, // 20+32 dma_int[4] + 0, + 1 // SD host controller candidate + }, + }, + + // Channel 5 + { + { + sizeof (RD_DMA_CHANNEL), + EFI_ACPI_CSRT_RESOURCE_TYPE_DMA, + EFI_ACPI_CSRT_RESOURCE_SUBTYPE_DMA_CHANNEL, + EFI_ACPI_CSRT_RESOURCE_ID_IN_DMA_GRP + 6, + }, + { + 5, // Channel vendor data here + 0x35, // 21+32 dma_int[5] + 0, + 0 + }, + }, + + // Channel 6 is reserved + { + { + sizeof (RD_DMA_CHANNEL), + EFI_ACPI_CSRT_RESOURCE_TYPE_DMA, + EFI_ACPI_CSRT_RESOURCE_SUBTYPE_DMA_CHANNEL, + EFI_ACPI_CSRT_RESOURCE_ID_IN_DMA_GRP + 7, + }, + { + 6, // Channel vendor data here + 0x36, // 22+32 dma_int[6] + 1, + 0 + }, + }, + + // Channel 7 is reserved + { + { + sizeof (RD_DMA_CHANNEL), + EFI_ACPI_CSRT_RESOURCE_TYPE_DMA, + EFI_ACPI_CSRT_RESOURCE_SUBTYPE_DMA_CHANNEL, + EFI_ACPI_CSRT_RESOURCE_ID_IN_DMA_GRP + 8, + }, + { + 7, // Channel vendor data here + 0x37, // 23+32 dma_int[7] + 1, + 0 + }, + }, + + // Channel 8 + { + { + sizeof (RD_DMA_CHANNEL), + EFI_ACPI_CSRT_RESOURCE_TYPE_DMA, + EFI_ACPI_CSRT_RESOURCE_SUBTYPE_DMA_CHANNEL, + EFI_ACPI_CSRT_RESOURCE_ID_IN_DMA_GRP + 9, + }, + { + 8, // Channel vendor data here + 0x38, // 24+32 dma_int[8] + 0, + 0 + }, + }, + + // Channel 9 + { + { + sizeof (RD_DMA_CHANNEL), + EFI_ACPI_CSRT_RESOURCE_TYPE_DMA, + EFI_ACPI_CSRT_RESOURCE_SUBTYPE_DMA_CHANNEL, + EFI_ACPI_CSRT_RESOURCE_ID_IN_DMA_GRP + 10, + }, + { + 9, // channel vendor data here + 0x39, // 25+32 dma_int[9] + 0, + 0 + }, + } + + } // End DMA Channels 0 to 14 + + } // End DMA Resource group + +}; + +#pragma pack(pop) + +// +// Reference the table being generated to prevent the optimizer from removing the +// data structure from the executable +// +VOID* CONST ReferenceAcpiTable = &Csrt; diff --git a/board/raspberrypi/rpi/dbg2miniuart.aslc b/board/raspberrypi/rpi/dbg2miniuart.aslc new file mode 100644 index 00000000000..518d8a33e0c --- /dev/null +++ b/board/raspberrypi/rpi/dbg2miniuart.aslc @@ -0,0 +1,81 @@ +/** @file + * + * Debug Port Table (DBG2) + * + * Copyright (c) 2019, Pete Batard pete@akeo.ie + * Copyright (c) 2012-2021, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-2-Clause-Patent + * + **/ + +#include <IndustryStandard/Acpi.h> +#include <IndustryStandard/Bcm2836.h> +#include <IndustryStandard/RpiDebugPort2Table.h> +#include <Library/AcpiLib.h> +#include <Library/PcdLib.h> + +#include "AcpiTables.h" + +#pragma pack(1) + +#define RPI_UART_INTERFACE_TYPE EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_BCM2835_UART +#define RPI_UART_BASE_ADDRESS BCM2836_MINI_UART_BASE_ADDRESS +#define RPI_UART_LENGTH BCM2836_MINI_UART_LENGTH +// +// RPI_UART_STR should match the value used Uart.asl +// +#define RPI_UART_STR { '\', '_', 'S', 'B', '.', 'G', 'D', 'V', '0', '.', 'U', 'R', 'T', 'M', 0x00 } + +#define DBG2_DEBUG_PORT_DDI(NumReg, SubType, UartBase, UartAddrLen, UartNameStr) { \ + { \ + EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION, /* UINT8 Revision */ \ + sizeof (DBG2_DEBUG_DEVICE_INFORMATION), /* UINT16 Length */ \ + NumReg, /* UINT8 NumberofGenericAddressRegisters */ \ + RPI_DBG2_NAMESPACESTRING_FIELD_SIZE, /* UINT16 NameSpaceStringLength */ \ + OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, NameSpaceString), /* UINT16 NameSpaceStringOffset */ \ + 0, /* UINT16 OemDataLength */ \ + 0, /* UINT16 OemDataOffset */ \ + EFI_ACPI_DBG2_PORT_TYPE_SERIAL, /* UINT16 Port Type */ \ + SubType, /* UINT16 Port Subtype */ \ + {EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE}, /* UINT8 Reserved[2] */ \ + OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, BaseAddressRegister), /* UINT16 BaseAddressRegister Offset */ \ + OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, AddressSize) /* UINT16 AddressSize Offset */ \ + }, \ + ARM_GAS32 (UartBase), /* EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE BaseAddressRegister */ \ + UartAddrLen, /* UINT32 AddressSize */ \ + UartNameStr /* UINT8 NameSpaceString[MAX_DBG2_NAME_LEN] */ \ + } + + +STATIC DBG2_TABLE Dbg2 = { + { + ACPI_HEADER ( + EFI_ACPI_6_3_DEBUG_PORT_2_TABLE_SIGNATURE, + DBG2_TABLE, + EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION + ), + OFFSET_OF (DBG2_TABLE, Dbg2DeviceInfo), + RPI_DBG2_NUM_DEBUG_PORTS /* UINT32 NumberDbgDeviceInfo */ + }, + { + /* + * Kernel Debug Port + */ + DBG2_DEBUG_PORT_DDI ( + RPI_DBG2_NUMBER_OF_GENERIC_ADDRESS_REGISTERS, + RPI_UART_INTERFACE_TYPE, + RPI_UART_BASE_ADDRESS, + RPI_UART_LENGTH, + RPI_UART_STR + ), + } +}; + +#pragma pack() + +// +// Reference the table being generated to prevent the optimizer from removing +// the data structure from the executable +// +VOID* CONST ReferenceAcpiTable = &Dbg2; diff --git a/board/raspberrypi/rpi/dbg2pl011.aslc b/board/raspberrypi/rpi/dbg2pl011.aslc new file mode 100644 index 00000000000..1a87fb8bfa6 --- /dev/null +++ b/board/raspberrypi/rpi/dbg2pl011.aslc @@ -0,0 +1,81 @@ +/** @file + * + * Debug Port Table (DBG2) + * + * Copyright (c) 2019, Pete Batard pete@akeo.ie + * Copyright (c) 2012-2021, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-2-Clause-Patent + * + **/ + +#include <IndustryStandard/Acpi.h> +#include <IndustryStandard/Bcm2836.h> +#include <IndustryStandard/RpiDebugPort2Table.h> +#include <Library/AcpiLib.h> +#include <Library/PcdLib.h> + +#include "AcpiTables.h" + +#pragma pack(1) + +#define RPI_UART_INTERFACE_TYPE EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_PL011_UART +#define RPI_UART_BASE_ADDRESS BCM2836_PL011_UART_BASE_ADDRESS +#define RPI_UART_LENGTH BCM2836_PL011_UART_LENGTH +// +// RPI_UART_STR should match the value used Uart.asl +// +#define RPI_UART_STR { '\', '_', 'S', 'B', '.', 'G', 'D', 'V', '0', '.', 'U', 'R', 'T', '0', 0x00 } + +#define DBG2_DEBUG_PORT_DDI(NumReg, SubType, UartBase, UartAddrLen, UartNameStr) { \ + { \ + EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION, /* UINT8 Revision */ \ + sizeof (DBG2_DEBUG_DEVICE_INFORMATION), /* UINT16 Length */ \ + NumReg, /* UINT8 NumberofGenericAddressRegisters */ \ + RPI_DBG2_NAMESPACESTRING_FIELD_SIZE, /* UINT16 NameSpaceStringLength */ \ + OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, NameSpaceString), /* UINT16 NameSpaceStringOffset */ \ + 0, /* UINT16 OemDataLength */ \ + 0, /* UINT16 OemDataOffset */ \ + EFI_ACPI_DBG2_PORT_TYPE_SERIAL, /* UINT16 Port Type */ \ + SubType, /* UINT16 Port Subtype */ \ + {EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE}, /* UINT8 Reserved[2] */ \ + OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, BaseAddressRegister), /* UINT16 BaseAddressRegister Offset */ \ + OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, AddressSize) /* UINT16 AddressSize Offset */ \ + }, \ + ARM_GAS32 (UartBase), /* EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE BaseAddressRegister */ \ + UartAddrLen, /* UINT32 AddressSize */ \ + UartNameStr /* UINT8 NameSpaceString[MAX_DBG2_NAME_LEN] */ \ + } + + +STATIC DBG2_TABLE Dbg2 = { + { + ACPI_HEADER ( + EFI_ACPI_6_3_DEBUG_PORT_2_TABLE_SIGNATURE, + DBG2_TABLE, + EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION + ), + OFFSET_OF (DBG2_TABLE, Dbg2DeviceInfo), + RPI_DBG2_NUM_DEBUG_PORTS /* UINT32 NumberDbgDeviceInfo */ + }, + { + /* + * Kernel Debug Port + */ + DBG2_DEBUG_PORT_DDI ( + RPI_DBG2_NUMBER_OF_GENERIC_ADDRESS_REGISTERS, + RPI_UART_INTERFACE_TYPE, + RPI_UART_BASE_ADDRESS, + RPI_UART_LENGTH, + RPI_UART_STR + ), + } +}; + +#pragma pack() + +// +// Reference the table being generated to prevent the optimizer from removing +// the data structure from the executable +// +VOID* CONST ReferenceAcpiTable = &Dbg2; diff --git a/board/raspberrypi/rpi/dsdt.asl b/board/raspberrypi/rpi/dsdt.asl new file mode 100644 index 00000000000..4dddbd068b8 --- /dev/null +++ b/board/raspberrypi/rpi/dsdt.asl @@ -0,0 +1,285 @@ +/** @file + * + * Differentiated System Definition Table (DSDT) + * + * Copyright (c) 2020, Pete Batard pete@akeo.ie + * Copyright (c) 2018-2020, Andrey Warkentin andrey.warkentin@gmail.com + * Copyright (c) Microsoft Corporation. All rights reserved. + * Copyright (c) 2021, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-2-Clause-Patent + * + **/ + +#include <asm/arch/acpi/bcm2711.h> +#include <asm/arch/acpi/bcm2836.h> +#include <asm/arch/acpi/bcm2836_gpio.h> +#include <asm/arch/acpi/bcm2836_gpu.h> +#include <asm/arch/acpi/bcm2836_pwm.h> +#include <asm/arch/acpi/bcm2836_sdio.h> +#include <asm/arch/acpi/bcm2836_sdhost.h> + +#include "acpitables.h" + +#define BCM_ALT0 0x4 +#define BCM_ALT1 0x5 +#define BCM_ALT2 0x6 +#define BCM_ALT3 0x7 +#define BCM_ALT4 0x3 +#define BCM_ALT5 0x2 + +// +// The ASL compiler does not support argument arithmetic in functions +// like QWordMemory (). So we need to instantiate dummy qword regions +// that we can then update the Min, Max and Length attributes of. +// The three macros below help accomplish this. +// +// QWORDMEMORYSET specifies a CPU memory range (whose base address is +// BCM2836_SOC_REGISTERS + Offset), and QWORDBUSMEMORYSET specifies +// a VPU memory range (whose base address is provided directly). +// +#define QWORDMEMORYBUF(Index) \ + QWordMemory (ResourceProducer,, \ + MinFixed, MaxFixed, NonCacheable, ReadWrite, \ + 0x0, 0x0, 0x0, 0x0, 0x1,,, RB ## Index) + +#define QWORDMEMORYSET(Index, Offset, Length) \ + CreateQwordField (RBUF, RB ## Index._MIN, MI ## Index) \ + CreateQwordField (RBUF, RB ## Index._MAX, MA ## Index) \ + CreateQwordField (RBUF, RB ## Index._LEN, LE ## Index) \ + Store (Length, LE ## Index) \ + Add (BCM2836_SOC_REGISTERS, Offset, MI ## Index) \ + Add (MI ## Index, LE ## Index - 1, MA ## Index) + +#define QWORDBUSMEMORYSET(Index, Base, Length) \ + CreateQwordField (RBUF, RB ## Index._MIN, MI ## Index) \ + CreateQwordField (RBUF, RB ## Index._MAX, MA ## Index) \ + CreateQwordField (RBUF, RB ## Index._LEN, LE ## Index) \ + Store (Base, MI ## Index) \ + Store (Length, LE ## Index) \ + Add (MI ## Index, LE ## Index - 1, MA ## Index) + +DefinitionBlock ("Dsdt.aml", "DSDT", 2, "RPIFDN", "RPI", 2) +{ + Scope (_SB_) + { + include ("pep.asl") + + Device (CPU0) + { + Name (_HID, "ACPI0007") + Name (_UID, 0x0) + Method (_STA) + { + Return (0xf) + } + } + + Device (CPU1) + { + Name (_HID, "ACPI0007") + Name (_UID, 0x1) + Method (_STA) + { + Return (0xf) + } + } + + Device (CPU2) + { + Name (_HID, "ACPI0007") + Name (_UID, 0x2) + Method (_STA) + { + Return (0xf) + } + } + + Device (CPU3) + { + Name (_HID, "ACPI0007") + Name (_UID, 0x3) + Method (_STA) + { + Return (0xf) + } + } + + // + // GPU device container describes the DMA translation required + // when a device behind the GPU wants to access Arm memory. + // Only the first GB can be addressed. + // + Device (GDV0) + { + Name (_HID, "ACPI0004") + Name (_UID, 0x1) + Name (_CCA, 0x0) + + Method (_CRS, 0, Serialized) { + // + // Container devices with _DMA must have _CRS, meaning GDV0 + // to provide all resources that GpuDevs.asl consume (except + // interrupts). + // + Name (RBUF, ResourceTemplate () { + QWORDMEMORYBUF(01) + QWORDMEMORYBUF(02) + QWORDMEMORYBUF(03) + // QWORDMEMORYBUF(04) + // QWORDMEMORYBUF(05) + QWORDMEMORYBUF(06) + QWORDMEMORYBUF(07) + QWORDMEMORYBUF(08) + QWORDMEMORYBUF(09) + QWORDMEMORYBUF(10) + QWORDMEMORYBUF(11) + QWORDMEMORYBUF(12) + QWORDMEMORYBUF(13) + QWORDMEMORYBUF(14) + QWORDMEMORYBUF(15) + // QWORDMEMORYBUF(16) + QWORDMEMORYBUF(17) + QWORDMEMORYBUF(18) + QWORDMEMORYBUF(19) + QWORDMEMORYBUF(20) + QWORDMEMORYBUF(21) + QWORDMEMORYBUF(22) + QWORDMEMORYBUF(23) + QWORDMEMORYBUF(24) + QWORDMEMORYBUF(25) + }) + + // USB + QWORDMEMORYSET(01, BCM2836_USB_OFFSET, BCM2836_USB_LENGTH) + + // GPU + QWORDMEMORYSET(02, BCM2836_V3D_BUS_OFFSET, BCM2836_V3D_BUS_LENGTH) + QWORDMEMORYSET(03, BCM2836_HVS_OFFSET, BCM2836_HVS_LENGTH) + // QWORDMEMORYSET(04, BCM2836_PV0_OFFSET, BCM2836_PV0_LENGTH) + // QWORDMEMORYSET(05, BCM2836_PV1_OFFSET, BCM2836_PV1_LENGTH) + QWORDMEMORYSET(06, BCM2836_PV2_OFFSET, BCM2836_PV2_LENGTH) + QWORDMEMORYSET(07, BCM2836_HDMI0_OFFSET, BCM2836_HDMI0_LENGTH) + QWORDMEMORYSET(08, BCM2836_HDMI1_OFFSET, BCM2836_HDMI1_LENGTH) + + // Mailbox + QWORDMEMORYSET(09, BCM2836_MBOX_OFFSET, BCM2836_MBOX_LENGTH) + + // VCHIQ + QWORDMEMORYSET(10, BCM2836_VCHIQ_OFFSET, BCM2836_VCHIQ_LENGTH) + + // GPIO + QWORDMEMORYSET(11, GPIO_OFFSET, GPIO_LENGTH) + + // I2C + QWORDMEMORYSET(12, BCM2836_I2C1_OFFSET, BCM2836_I2C1_LENGTH) + QWORDMEMORYSET(13, BCM2836_I2C2_OFFSET, BCM2836_I2C2_LENGTH) + + // SPI + QWORDMEMORYSET(14, BCM2836_SPI0_OFFSET, BCM2836_SPI0_LENGTH) + QWORDMEMORYSET(15, BCM2836_SPI1_OFFSET, BCM2836_SPI1_LENGTH) + // QWORDMEMORYSET(16, BCM2836_SPI2_OFFSET, BCM2836_SPI2_LENGTH) + + // PWM + QWORDMEMORYSET(17, BCM2836_PWM_DMA_OFFSET, BCM2836_PWM_DMA_LENGTH) + QWORDMEMORYSET(18, BCM2836_PWM_CTRL_OFFSET, BCM2836_PWM_CTRL_LENGTH) + QWORDBUSMEMORYSET(19, BCM2836_PWM_BUS_BASE_ADDRESS, BCM2836_PWM_BUS_LENGTH) + QWORDBUSMEMORYSET(20, BCM2836_PWM_CTRL_UNCACHED_BASE_ADDRESS, BCM2836_PWM_CTRL_UNCACHED_LENGTH) + QWORDMEMORYSET(21, BCM2836_PWM_CLK_OFFSET, BCM2836_PWM_CLK_LENGTH) + + // UART + QWORDMEMORYSET(22, BCM2836_PL011_UART_OFFSET, BCM2836_PL011_UART_LENGTH) + QWORDMEMORYSET(23, BCM2836_MINI_UART_OFFSET, BCM2836_MINI_UART_LENGTH) + + // SDC + QWORDMEMORYSET(24, MMCHS1_OFFSET, MMCHS1_LENGTH) + QWORDMEMORYSET(25, SDHOST_OFFSET, SDHOST_LENGTH) + + Return (RBUF) + } + + Name (_DMA, ResourceTemplate() { + // + // Only the first GB is available. + // Bus 0xC0000000 -> CPU 0x00000000. + // + QWordMemory (ResourceProducer, + , + MinFixed, + MaxFixed, + NonCacheable, + ReadWrite, + 0x0, + 0x00000000C0000000, // MIN + 0x00000000FFFFFFFF, // MAX + 0xFFFFFFFF40000000, // TRA + 0x0000000040000000, // LEN + , + , + ) + }) +#include "gpudevs.asl" + } + + Device (ETH0) + { + Name (_HID, "BCM6E4E") + Name (_CID, "BCM6E4E") + Name (_UID, 0x0) + Name (_CCA, 0x0) + Method (_STA) + { + Return (0xf) + } + Method (_CRS, 0x0, Serialized) + { + Name (RBUF, ResourceTemplate () + { + // No need for MEMORY32SETBASE on Genet as we have a straight base address constant + MEMORY32FIXED (ReadWrite, GENET_BASE_ADDRESS, GENET_LENGTH, ) + Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { GENET_INTERRUPT0, GENET_INTERRUPT1 } + }) + Return (RBUF) + } + Name (_DSD, Package () { + ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + Package () { + Package () { "brcm,max-dma-burst-size", 0x08 }, + Package () { "phy-mode", "rgmii-rxid" }, + } + }) + } + + // Define a simple thermal zone. The idea here is we compute the SOC temp + // via a register we can read, and give it to the OS. This enables basic + // reports from the "sensors" utility, and the OS can then poll and take + // actions if that temp exceeds any of the given thresholds. + Device (EC00) + { + Name (_HID, EISAID ("PNP0C06")) + Name (_CCA, 0x0) + + // all temps in are tenths of K (aka 2732 is the min temps in Linux (aka 0C)) + ThermalZone (TZ00) { + Method (_TMP, 0, Serialized) { + OperationRegion (TEMS, SystemMemory, THERM_SENSOR, 0x8) + Field (TEMS, DWordAcc, NoLock, Preserve) { + TMPS, 32 + } + return (((410040 - ((TMPS & 0x3ff) * 487)) / 100) + 2732); + } + Method (_SCP, 3) { } // receive cooling policy from OS + + Method (_CRT) { Return (3632) } // (90C) Critical temp point (immediate power-off) + Method (_HOT) { Return (3582) } // (85C) HOT state where OS should hibernate + Method (_PSV) { Return (3532) } // (80C) Passive cooling (CPU throttling) trip point + + // SSDT inserts _AC0/_AL0 @60C here, if a FAN is configured + + Name (_TZP, 10) //The OSPM must poll this device every 1 seconds + Name (_PSL, Package () { _SB_.CPU0, _SB_.CPU1, _SB_.CPU2, _SB_.CPU3 }) + } + } + + } +} diff --git a/board/raspberrypi/rpi/emmc.asl b/board/raspberrypi/rpi/emmc.asl new file mode 100644 index 00000000000..900612cbcfa --- /dev/null +++ b/board/raspberrypi/rpi/emmc.asl @@ -0,0 +1,166 @@ +/** @file + * + * Copyright (c) 2021, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-2-Clause-Patent + * + **/ + +#include <asm/arch/acpi/Bcm2836SdHost.h> +#include <asm/arch/acpi/Bcm2836Sdio.h> +#include <asm/arch/acpi/Bcm2711.h> + +#include "acpitables.h" + +DefinitionBlock (__FILE__, "SSDT", 2, "RPIFDN", "RPI4EMMC", 2) +{ + Scope (_SB_) + { +#if (RPI_MODEL == 4) + Device (GDV1) { + Name (_HID, "ACPI0004") + Name (_UID, 0x2) + Name (_CCA, 0x0) + + Name (RBUF, ResourceTemplate () + { + MEMORY32FIXED (ReadWrite, 0, MMCHS2_LENGTH, RMEM) + }) + Method (_CRS, 0x0, Serialized) + { + MEMORY32SETBASE (RBUF, RMEM, RBAS, MMCHS2_OFFSET) + Return (^RBUF) + } + + // Translated DMA region for BCM2711 silicon revisions older than C0 + Name (DMTR, ResourceTemplate() { + QWordMemory (ResourceProducer, + , + MinFixed, + MaxFixed, + NonCacheable, + ReadWrite, + 0x0, + 0x00000000C0000000, // MIN + 0x00000000FFFFFFFF, // MAX + 0xFFFFFFFF40000000, // TRA + 0x0000000040000000, // LEN + , + , + ) + }) + + // Non translated DMA region for BCM2711 revisions C0 and newer + Name (DMNT, ResourceTemplate() { + QWordMemory (ResourceProducer, + , + MinFixed, + MaxFixed, + NonCacheable, + ReadWrite, + 0x0, + 0x0000000000000000, // MIN + 0x000000FFFFFFFFFF, // MAX + 0x0000000000000000, // TRA + 0x0000010000000000, // LEN + , + , + ) + }) + + Method (_DMA, 0x0, Serialized) + { + OperationRegion (CHPR, SystemMemory, ID_CHIPREV, 0x4) + Field (CHPR, DWordAcc, NoLock, Preserve) { + SOCI, 32 + } + + if ((SOCI & 0xFF) >= 0x20) + { + return (^DMNT); + } + else + { + return (^DMTR); + } + } + + // emmc2 Host Controller. (brcm,bcm2711-emmc2) + Device (SDC3) + { + Name (_HID, "BRCME88C") + Name (_UID, 0x1) + Name (_CCA, 0x0) + Name (_S1D, 0x1) + Name (_S2D, 0x1) + Name (_S3D, 0x1) + Name (_S4D, 0x1) + Name (SDMA, 0x2) + Method (_STA) + { + Return(0xf) + } + Name (RBUF, ResourceTemplate () + { + MEMORY32FIXED (ReadWrite, 0, MMCHS2_LENGTH, RMEM) + Interrupt (ResourceConsumer, Level, ActiveHigh, Shared) { BCM2836_MMCHS1_INTERRUPT } + }) + Method (_CRS, 0x0, Serialized) + { + MEMORY32SETBASE (RBUF, RMEM, RBAS, MMCHS2_OFFSET) + Return (^RBUF) + } + + // Unfortunately this controller doesn't honor the + // standard SDHCI voltage control registers + // (or at least Linux's standard code can't + // lower the voltage) So, UHS mode is disabled with caps + Name (DSD1, Package () { + ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + Package () { + Package () { "sdhci-caps-mask", 0x0000000500080000 }, + } + }) + // Along with disabling UHS, here both SDMA and ADMA2 + // are also disabled until the linux _DMA() mask/translate + // works properly. + Name (DSD2, Package () { + ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + Package () { + Package () { "sdhci-caps-mask", 0x0000000504480000 }, + } + }) + Method (_DSD, 0x0, Serialized) + { + // Select one of the sdhci-caps-mask definitions + // depending on whether we also want to disable DMA + if (SDMA == 0) + { + return (^DSD2) + } + else + { + return (^DSD1) + } + } + + // + // A child device that represents the + // sd card, which is marked as non-removable. + // + Device (SDMM) + { + Method (_ADR) + { + Return (0) + } + Method (_RMV) // Is removable + { + Return (0) // 0 - fixed + } + } + } //SDC3 + } //GDV1 +#endif + } //\SB +} diff --git a/board/raspberrypi/rpi/fadt.aslc b/board/raspberrypi/rpi/fadt.aslc new file mode 100644 index 00000000000..aae47bcce41 --- /dev/null +++ b/board/raspberrypi/rpi/fadt.aslc @@ -0,0 +1,96 @@ +/** @file + * + * Fixed ACPI Description Table (FADT) + * + * Copyright (c) 2019, Pete Batard pete@akeo.ie + * Copyright (c) 2018, Andrey Warkentin andrey.warkentin@gmail.com + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-2-Clause-Patent + * + **/ + +#include <IndustryStandard/Acpi.h> +#include <Library/AcpiLib.h> +#include <Library/PcdLib.h> + +#include "AcpiTables.h" + +/* + * Windows 10 on the Raspberry Pi 3 requires a specific OEM Id for FADT. + * We replace the one that was defined in "AcpiTables.h", so that it is + * picked by the ACPI_HEADER () macro. + */ +#if (RPI_MODEL == 3) +#undef EFI_ACPI_OEM_ID +#define EFI_ACPI_OEM_ID {'B','C','2','8','3','6'} +#endif + +EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE Fadt = { + ACPI_HEADER ( + EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, + EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE, + EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_REVISION + ), + 0, // UINT32 FirmwareCtrl + 0, // UINT32 Dsdt + EFI_ACPI_RESERVED_BYTE, // UINT8 Reserved0 + EFI_ACPI_6_3_PM_PROFILE_APPLIANCE_PC, // UINT8 PreferredPmProfile + 0, // UINT16 SciInt + 0, // UINT32 SmiCmd + 0, // UINT8 AcpiEnable + 0, // UINT8 AcpiDisable + 0, // UINT8 S4BiosReq + 0, // UINT8 PstateCnt + 0, // UINT32 Pm1aEvtBlk + 0, // UINT32 Pm1bEvtBlk + 0, // UINT32 Pm1aCntBlk + 0, // UINT32 Pm1bCntBlk + 0, // UINT32 Pm2CntBlk + 0, // UINT32 PmTmrBlk + 0, // UINT32 Gpe0Blk + 0, // UINT32 Gpe1Blk + 0, // UINT8 Pm1EvtLen + 0, // UINT8 Pm1CntLen + 0, // UINT8 Pm2CntLen + 0, // UINT8 PmTmrLen + 0, // UINT8 Gpe0BlkLen + 0, // UINT8 Gpe1BlkLen + 0, // UINT8 Gpe1Base + 0, // UINT8 CstCnt + 0, // UINT16 PLvl2Lat + 0, // UINT16 PLvl3Lat + 0, // UINT16 FlushSize + 0, // UINT16 FlushStride + 0, // UINT8 DutyOffset + 0, // UINT8 DutyWidth + 0, // UINT8 DayAlrm + 0, // UINT8 MonAlrm + 0, // UINT8 Century + EFI_ACPI_RESERVED_WORD, // UINT16 IaPcBootArch (Reserved on ARM) + EFI_ACPI_RESERVED_BYTE, // UINT8 Reserved1 + EFI_ACPI_6_3_WBINVD | EFI_ACPI_6_3_SLP_BUTTON | // UINT32 Flags + EFI_ACPI_6_3_HW_REDUCED_ACPI, + NULL_GAS, // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE ResetReg + 0, // UINT8 ResetValue + EFI_ACPI_6_3_ARM_PSCI_COMPLIANT, // UINT16 ArmBootArchFlags + EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION, // UINT8 MinorRevision + 0, // UINT64 XFirmwareCtrl + 0, // UINT64 XDsdt + NULL_GAS, // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE XPm1aEvtBlk + NULL_GAS, // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE XPm1bEvtBlk + NULL_GAS, // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE XPm1aCntBlk + NULL_GAS, // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE XPm1bCntBlk + NULL_GAS, // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE XPm2CntBlk + NULL_GAS, // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE XPmTmrBlk + NULL_GAS, // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE XGpe0Blk + NULL_GAS, // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE XGpe1Blk + NULL_GAS, // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE SleepControlReg + NULL_GAS // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE SleepStatusReg +}; + +// +// Reference the table being generated to prevent the optimizer from removing the +// data structure from the executable +// +VOID* CONST ReferenceAcpiTable = &Fadt; diff --git a/board/raspberrypi/rpi/gpudevs.asl b/board/raspberrypi/rpi/gpudevs.asl new file mode 100644 index 00000000000..aa23651ac4a --- /dev/null +++ b/board/raspberrypi/rpi/gpudevs.asl @@ -0,0 +1,397 @@ +/** @file + * + * [DSDT] Devices behind the GPU. + * + * Copyright (c) 2018-2020, Andrey Warkentin andrey.warkentin@gmail.com + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-2-Clause-Patent + * + **/ + +// DWC OTG Controller +Device (USB0) +{ + Name (_HID, "BCM2848") +#if (RPI_MODEL == 3) + Name (_CID, "DWC_OTG") +#elif (RPI_MODEL == 4) + Name (_CID, "BCM2848") +#endif + Name (_UID, 0x0) + Name (_CCA, 0x0) + Method (_STA) + { + Return (0xf) + } + Name (RBUF, ResourceTemplate () + { + MEMORY32FIXED (ReadWrite, 0, BCM2836_USB_LENGTH, RMEM) + Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_USB_INTERRUPT } + }) + Method (_CRS, 0x0, Serialized) + { + MEMORY32SETBASE (RBUF, RMEM, RBAS, BCM2836_USB_OFFSET) + Return (^RBUF) + } +} + +// Video Core 4 GPU +Device (GPU0) +{ + Name (_HID, "BCM2850") + Name (_CID, "BCM2850") + Name (_UID, 0x0) + Name (_CCA, 0x0) + Method (_STA) + { + Return (0xf) + } + Name (RBUF, ResourceTemplate () + { + // Memory and interrupt for the GPU + MEMORY32FIXED (ReadWrite, 0, BCM2836_V3D_BUS_LENGTH, RM01) + Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_V3D_BUS_INTERRUPT } + + // HVS - Hardware Video Scalar + MEMORY32FIXED (ReadWrite, 0, BCM2836_HVS_LENGTH, RM02) + // The HVS interrupt is reserved by the VPU + // Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_HVS_INTERRUPT } + + // PixelValve0 - DSI0 or DPI + // MEMORY32FIXED (ReadWrite, BCM2836_PV0_BASE_ADDRESS, BCM2836_PV0_LENGTH, RM03) + // Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_PV0_INTERRUPT } + + // PixelValve1 - DS1 or SMI + // MEMORY32FIXED (ReadWrite, BCM2836_PV1_BASE_ADDRESS, BCM2836_PV1_LENGTH, RM04) + // Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_PV1_INTERRUPT } + + // PixelValve2 - HDMI output - connected to HVS display FIFO 1 + MEMORY32FIXED (ReadWrite, 0, BCM2836_PV2_LENGTH, RM05) + Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_PV2_INTERRUPT } + + // HDMI registers + MEMORY32FIXED (ReadWrite, 0, BCM2836_HDMI0_LENGTH, RM06) + MEMORY32FIXED (ReadWrite, 0, BCM2836_HDMI1_LENGTH, RM07) + // hdmi_int[0] + // Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_HDMI0_INTERRUPT } + // hdmi_int[1] + // Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_HDMI1_INTERRUPT } + + // HDMI DDC connection + I2CSerialBus (0x50,, 100000,, "\_SB.GDV0.I2C2",,,,) // EDID + I2CSerialBus (0x30,, 100000,, "\_SB.GDV0.I2C2",,,,) // E-DDC Segment Pointer + }) + Method (_CRS, 0x0, Serialized) + { + MEMORY32SETBASE (RBUF, RM01, RB01, BCM2836_V3D_BUS_OFFSET) + MEMORY32SETBASE (RBUF, RM02, RB02, BCM2836_HVS_OFFSET) + MEMORY32SETBASE (RBUF, RM05, RB05, BCM2836_PV2_OFFSET) + MEMORY32SETBASE (RBUF, RM06, RB06, BCM2836_HDMI0_OFFSET) + MEMORY32SETBASE (RBUF, RM07, RB07, BCM2836_HDMI1_OFFSET) + Return (^RBUF) + } + + // GPU Power Management Component Data + // Reference : https://github.com/Microsoft/graphics-driver-samples/wiki/Install-Driver-in-... + Method (PMCD, 0, Serialized) + { + Name (RBUF, Package () + { + 1, // Version + 1, // Number of graphics power components + Package () // Power components package + { + Package () // GPU component package + { + 0, // Component Index + 0, // DXGK_POWER_COMPONENT_MAPPING.ComponentType (0 = DXGK_POWER_COMPONENT_ENGINE) + 0, // DXGK_POWER_COMPONENT_MAPPING.NodeIndex + + Buffer () // DXGK_POWER_RUNTIME_COMPONENT.ComponentGuid + { // 9B2D1E26-1575-4747-8FC0-B9EB4BAA2D2B + 0x26, 0x1E, 0x2D, 0x9B, 0x75, 0x15, 0x47, 0x47, + 0x8f, 0xc0, 0xb9, 0xeb, 0x4b, 0xaa, 0x2d, 0x2b + }, + + "VC4_Engine_00",// DXGK_POWER_RUNTIME_COMPONENT.ComponentName + 2, // DXGK_POWER_RUNTIME_COMPONENT.StateCount + + Package () // DXGK_POWER_RUNTIME_COMPONENT.States[] package + { + Package () // F0 + { + 0, // DXGK_POWER_RUNTIME_STATE.TransitionLatency + 0, // DXGK_POWER_RUNTIME_STATE.ResidencyRequirement + 1210000, // DXGK_POWER_RUNTIME_STATE.NominalPower (microwatt) + }, + + Package () // F1 - Placeholder + { + 10000, // DXGK_POWER_RUNTIME_STATE.TransitionLatency + 10000, // DXGK_POWER_RUNTIME_STATE.ResidencyRequirement + 4, // DXGK_POWER_RUNTIME_STATE.NominalPower + }, + } + } + } + }) + Return (RBUF) + } +} + +// PiQ Mailbox Driver +Device (RPIQ) +{ + Name (_HID, "BCM2849") + Name (_CID, "BCM2849") + Name (_UID, 0) + Name (_CCA, 0x0) + Method (_STA) + { + Return (0xf) + } + Name (RBUF, ResourceTemplate () + { + MEMORY32FIXED (ReadWrite, 0, BCM2836_MBOX_LENGTH, RMEM) + Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_MBOX_INTERRUPT } + }) + + Method (_CRS, 0x0, Serialized) + { + MEMORY32SETBASE (RBUF, RMEM, RBAS, BCM2836_MBOX_OFFSET) + Return (^RBUF) + } +} + +// VCHIQ Driver +Device (VCIQ) +{ + Name (_HID, "BCM2835") + Name (_CID, "BCM2835") + Name (_UID, 0) + Name (_CCA, 0x0) + Name (_DEP, Package() { _SB.GDV0.RPIQ }) + Method (_STA) + { + Return (0xf) + } + Name (RBUF, ResourceTemplate () + { + MEMORY32FIXED (ReadWrite, 0, BCM2836_VCHIQ_LENGTH, RMEM) + Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_VCHIQ_INTERRUPT } + }) + + Method (_CRS, 0x0, Serialized) + { + MEMORY32SETBASE (RBUF, RMEM, RBAS, BCM2836_VCHIQ_OFFSET) + Return (^RBUF) + } +} + +// VC Shared Memory Driver +Device (VCSM) +{ + Name (_HID, "BCM2856") + Name (_CID, "BCM2856") + Name (_UID, 0) + Name (_CCA, 0x0) + Name (_DEP, Package() { _SB.GDV0.VCIQ }) + Method (_STA) + { + Return (0xf) + } +} + +// Description: GPIO +Device (GPI0) +{ + Name (_HID, "BCM2845") + Name (_CID, "BCM2845") + Name (_UID, 0x0) + Name (_CCA, 0x0) + Method (_STA) + { + Return(0xf) + } + Name (RBUF, ResourceTemplate () + { + MEMORY32FIXED (ReadWrite, 0, GPIO_LENGTH, RMEM) + Interrupt (ResourceConsumer, Level, ActiveHigh, Shared) + { + BCM2386_GPIO_INTERRUPT0, BCM2386_GPIO_INTERRUPT1, + BCM2386_GPIO_INTERRUPT2, BCM2386_GPIO_INTERRUPT3 + } + }) + Method (_CRS, 0x0, Serialized) + { + MEMORY32SETBASE (RBUF, RMEM, RBAS, GPIO_OFFSET) + Return (^RBUF) + } +} + +// Description: I2C +Device (I2C1) +{ + Name (_HID, "BCM2841") + Name (_CID, "BCM2841") + Name (_UID, 0x1) + Name (_CCA, 0x0) + Method (_STA) + { + Return(0xf) + } + Name (RBUF, ResourceTemplate () + { + MEMORY32FIXED (ReadWrite, 0, BCM2836_I2C1_LENGTH, RMEM) + Interrupt (ResourceConsumer, Level, ActiveHigh, Shared) { BCM2836_I2C1_INTERRUPT } + PinFunction (Exclusive, PullUp, BCM_ALT0, "\_SB.GDV0.GPI0", 0, ResourceConsumer, , ) { 2, 3 } + }) + Method (_CRS, 0x0, Serialized) + { + MEMORY32SETBASE (RBUF, RMEM, RBAS, BCM2836_I2C1_OFFSET) + Return (^RBUF) + } +} + +// I2C2 is the HDMI DDC connection +Device (I2C2) +{ + Name (_HID, "BCM2841") + Name (_CID, "BCM2841") + Name (_UID, 0x2) + Name (_CCA, 0x0) + Method (_STA) + { + Return (0xf) + } + Name (RBUF, ResourceTemplate() + { + MEMORY32FIXED (ReadWrite, 0, BCM2836_I2C2_LENGTH, RMEM) + Interrupt (ResourceConsumer, Level, ActiveHigh, Shared) { BCM2836_I2C2_INTERRUPT } + }) + + Method (_CRS, 0x0, Serialized) + { + MEMORY32SETBASE (RBUF, RMEM, RBAS, BCM2836_I2C2_OFFSET) + Return (^RBUF) + } +} + +// SPI +Device (SPI0) +{ + Name (_HID, "BCM2838") + Name (_CID, "BCM2838") + Name (_UID, 0x0) + Name (_CCA, 0x0) + Method (_STA) + { + Return (0xf) + } + Name (RBUF, ResourceTemplate () + { + MEMORY32FIXED (ReadWrite, 0, BCM2836_SPI0_LENGTH, RMEM) + Interrupt (ResourceConsumer, Level, ActiveHigh, Shared) { BCM2836_SPI0_INTERRUPT } + PinFunction (Exclusive, PullDown, BCM_ALT0, "\_SB.GDV0.GPI0", 0, ResourceConsumer, , ) { 9, 10, 11 } // MISO, MOSI, SCLK + PinFunction (Exclusive, PullUp, BCM_ALT0, "\_SB.GDV0.GPI0", 0, ResourceConsumer, , ) { 8 } // CE0 + PinFunction (Exclusive, PullUp, BCM_ALT0, "\_SB.GDV0.GPI0", 0, ResourceConsumer, , ) { 7 } // CE1 + }) + + Method (_CRS, 0x0, Serialized) + { + MEMORY32SETBASE (RBUF, RMEM, RBAS, BCM2836_SPI0_OFFSET) + Return (^RBUF) + } +} + +Device (SPI1) +{ + Name (_HID, "BCM2839") + Name (_CID, "BCM2839") + Name (_UID, 0x1) + Name (_CCA, 0x0) + Name (_DEP, Package() { _SB.GDV0.RPIQ }) + Method (_STA) + { + Return (0xf) + } + Name (RBUF, ResourceTemplate () + { + MEMORY32FIXED (ReadWrite, 0, BCM2836_SPI1_LENGTH, RMEM) + Interrupt (ResourceConsumer, Level, ActiveHigh, Shared,) { BCM2836_SPI1_INTERRUPT } + PinFunction (Exclusive, PullDown, BCM_ALT4, "\_SB.GDV0.GPI0", 0, ResourceConsumer, , ) { 19, 20, 21 } // MISO, MOSI, SCLK + PinFunction (Exclusive, PullDown, BCM_ALT4, "\_SB.GDV0.GPI0", 0, ResourceConsumer, , ) { 16 } // CE2 + }) + + Method (_CRS, 0x0, Serialized) + { + MEMORY32SETBASE (RBUF, RMEM, RBAS, BCM2836_SPI1_OFFSET) + Return (^RBUF) + } +} + +// SPI2 has no pins on GPIO header +// Device (SPI2) +// { +// Name (_HID, "BCM2839") +// Name (_CID, "BCM2839") +// Name (_UID, 0x2) +// Name (_CCA, 0x0) +// Name (_DEP, Package() { _SB.GDV0.RPIQ }) +// Method (_STA) +// { +// Return (0xf) // Disabled +// } +// Method (_CRS, 0x0, Serialized) +// { +// Name (RBUF, ResourceTemplate () +// { +// MEMORY32FIXED (ReadWrite, BCM2836_SPI2_BASE_ADDRESS, BCM2836_SPI2_LENGTH, RMEM) +// Interrupt (ResourceConsumer, Level, ActiveHigh, Shared,) { BCM2836_SPI2_INTERRUPT } +// }) +// Return (RBUF) +// } +// } + +// PWM Driver +Device (PWM0) +{ + Name (_HID, "BCM2844") + Name (_CID, "BCM2844") + Name (_UID, 0) + Name (_CCA, 0x0) + Method (_STA) + { + Return (0xf) + } + Name (RBUF, ResourceTemplate () + { + // DMA channel 11 control + MEMORY32FIXED (ReadWrite, 0, BCM2836_PWM_DMA_LENGTH, RM01) + // PWM control + MEMORY32FIXED (ReadWrite, 0, BCM2836_PWM_CTRL_LENGTH, RM02) + // PWM control bus + MEMORY32FIXED (ReadWrite, BCM2836_PWM_BUS_BASE_ADDRESS, BCM2836_PWM_BUS_LENGTH, ) + // PWM control uncached + MEMORY32FIXED (ReadWrite, BCM2836_PWM_CTRL_UNCACHED_BASE_ADDRESS, BCM2836_PWM_CTRL_UNCACHED_LENGTH, ) + // PWM clock control + MEMORY32FIXED (ReadWrite, 0, BCM2836_PWM_CLK_LENGTH, RM03) + // Interrupt DMA channel 11 + Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_DMA_INTERRUPT } + // DMA channel 11, DREQ 5 for PWM + FixedDMA (5, 11, Width32Bit, ) + }) + + Method (_CRS, 0x0, Serialized) + { + MEMORY32SETBASE (RBUF, RM01, RB01, BCM2836_PWM_DMA_OFFSET) + MEMORY32SETBASE (RBUF, RM02, RB02, BCM2836_PWM_CTRL_OFFSET) + MEMORY32SETBASE (RBUF, RM03, RB03, BCM2836_PWM_CLK_OFFSET) + Return (^RBUF) + } +} + +#include "uart.asl" +#include "rhpx.asl" +#include "sdhc.asl" diff --git a/board/raspberrypi/rpi/gtdt.aslc b/board/raspberrypi/rpi/gtdt.aslc new file mode 100644 index 00000000000..13181b5b716 --- /dev/null +++ b/board/raspberrypi/rpi/gtdt.aslc @@ -0,0 +1,55 @@ +/** @file +* Generic Timer Description Table (GTDT) +* +* Copyright (c) 2018, Linaro Limited. All rights reserved. +* Copyright (c) 2012 - 2016, ARM Limited. All rights reserved. +* +* SPDX-License-Identifier: BSD-2-Clause-Patent +* +**/ + +#include <IndustryStandard/Acpi.h> +#include <Library/AcpiLib.h> +#include <Library/PcdLib.h> + +#include "AcpiTables.h" + +#define RPI_GTDT_GLOBAL_FLAGS 0 +#define RPI_GTDT_GTIMER_FLAGS EFI_ACPI_6_3_GTDT_TIMER_FLAG_TIMER_INTERRUPT_POLARITY + +#pragma pack (1) + +typedef struct { + EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE Gtdt; +} EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLES; + +#pragma pack () + +EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLES Gtdt = { + { + ACPI_HEADER( + EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE, + EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLES, + EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION + ), + RPI_SYSTEM_TIMER_BASE_ADDRESS, // UINT64 PhysicalAddress + 0, // UINT32 Reserved + FixedPcdGet32 (PcdArmArchTimerSecIntrNum), // UINT32 SecurePL1TimerGSIV + RPI_GTDT_GTIMER_FLAGS, // UINT32 SecurePL1TimerFlags + FixedPcdGet32 (PcdArmArchTimerIntrNum), // UINT32 NonSecurePL1TimerGSIV + RPI_GTDT_GTIMER_FLAGS, // UINT32 NonSecurePL1TimerFlags + FixedPcdGet32 (PcdArmArchTimerVirtIntrNum), // UINT32 VirtualTimerGSIV + RPI_GTDT_GTIMER_FLAGS, // UINT32 VirtualTimerFlags + FixedPcdGet32 (PcdArmArchTimerHypIntrNum), // UINT32 NonSecurePL2TimerGSIV + RPI_GTDT_GTIMER_FLAGS, // UINT32 NonSecurePL2TimerFlags + 0xFFFFFFFFFFFFFFFF, // UINT64 CntReadBasePhysicalAddress + 0, // UINT32 PlatformTimerCount + 0 // UINT32 PlatfromTimerOffset + }, +}; + +// +// Reference the table being generated to prevent the optimizer +// from removing the data structure from the executable +// +VOID* CONST ReferenceAcpiTable = &Gtdt; diff --git a/board/raspberrypi/rpi/iort.aslc b/board/raspberrypi/rpi/iort.aslc new file mode 100644 index 00000000000..86c16a25596 --- /dev/null +++ b/board/raspberrypi/rpi/iort.aslc @@ -0,0 +1,100 @@ +/** @file + + Copyright (c) 2020, Arm, Ltd. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <IndustryStandard/IoRemappingTable.h> + +#include "AcpiTables.h" + +#pragma pack(1) + +typedef struct { + EFI_ACPI_6_0_IO_REMAPPING_NAMED_COMP_NODE Node; + CONST CHAR8 Name[16]; +} RPI4_NC_NODE; + +typedef struct { + EFI_ACPI_6_0_IO_REMAPPING_TABLE Iort; + RPI4_NC_NODE NamedCompNode; + RPI4_NC_NODE NamedCompNode2; + RPI4_NC_NODE NamedCompNode3; +} RPI4_IO_REMAPPING_STRUCTURE; + +STATIC RPI4_IO_REMAPPING_STRUCTURE Iort = { + { + ACPI_HEADER (EFI_ACPI_6_0_IO_REMAPPING_TABLE_SIGNATURE, + RPI4_IO_REMAPPING_STRUCTURE, + EFI_ACPI_IO_REMAPPING_TABLE_REVISION), + 3, // NumNodes + sizeof (EFI_ACPI_6_0_IO_REMAPPING_TABLE), // NodeOffset + 0 // Reserved + }, { + // XHCI named component node + { + { + EFI_ACPI_IORT_TYPE_NAMED_COMP, // Type + sizeof (RPI4_NC_NODE), // Length + 0x0, // Revision + 0x0, // Reserved + 0x0, // NumIdMappings + 0x0, // IdReference + }, + 0x0, // Flags + 0x0, // CacheCoherent + 0x0, // AllocationHints + 0x0, // Reserved + 0x0, // MemoryAccessFlags + 31, // AddressSizeLimit + }, { + "\_SB_.SCB0.XHC0" // ObjectName + } + }, { + // gpu/dwc usb named component node + { + { + EFI_ACPI_IORT_TYPE_NAMED_COMP, // Type + sizeof (RPI4_NC_NODE), // Length + 0x0, // Revision + 0x0, // Reserved + 0x0, // NumIdMappings + 0x0, // IdReference + }, + 0x0, // Flags + 0x0, // CacheCoherent + 0x0, // AllocationHints + 0x0, // Reserved + 0x0, // MemoryAccessFlags + 30, // AddressSizeLimit + }, { + "\_SB_.GDV0.USB0" // ObjectName + } + }, { + // emmc2 named component node + { + { + EFI_ACPI_IORT_TYPE_NAMED_COMP, // Type + sizeof (RPI4_NC_NODE), // Length + 0x0, // Revision + 0x0, // Reserved + 0x0, // NumIdMappings + 0x0, // IdReference + }, + 0x0, // Flags + 0x0, // CacheCoherent + 0x0, // AllocationHints + 0x0, // Reserved + 0x0, // MemoryAccessFlags + 30, // AddressSizeLimit + }, { + "\_SB_.GDV1.SDC3" // ObjectName + } + } +}; + +#pragma pack() + +VOID* CONST ReferenceAcpiTable = &Iort; diff --git a/board/raspberrypi/rpi/madt.aslc b/board/raspberrypi/rpi/madt.aslc new file mode 100644 index 00000000000..cfdebab759c --- /dev/null +++ b/board/raspberrypi/rpi/madt.aslc @@ -0,0 +1,78 @@ +/** @file +* Multiple APIC Description Table (MADT) +* +* Copyright (c) 2016 Linaro Ltd. All rights reserved. +* Copyright (c) 2012 - 2015, ARM Limited. All rights reserved. +* +* SPDX-License-Identifier: BSD-2-Clause-Patent +* +**/ + +#include <IndustryStandard/Acpi.h> +#include <Library/AcpiLib.h> +#include <Library/ArmLib.h> +#include <Library/PcdLib.h> + +#include "AcpiTables.h" + +// +// Multiple APIC Description Table +// +#pragma pack (1) + +typedef struct { + EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER Header; + EFI_ACPI_6_3_GIC_STRUCTURE GicInterfaces[4]; +#if (RPI_MODEL != 3) + EFI_ACPI_6_3_GIC_DISTRIBUTOR_STRUCTURE GicDistributor; +#endif +} PI_MULTIPLE_APIC_DESCRIPTION_TABLE; + +#pragma pack () + +PI_MULTIPLE_APIC_DESCRIPTION_TABLE Madt = { + { + ACPI_HEADER ( + EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, + PI_MULTIPLE_APIC_DESCRIPTION_TABLE, + EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION + ), + // + // MADT specific fields + // + 0, // LocalApicAddress + 0, // Flags + }, + { + EFI_ACPI_6_3_GICC_STRUCTURE_INIT ( + 0, 0, GET_MPID(0, 0), EFI_ACPI_6_0_GIC_ENABLED, FixedPcdGet32 (PcdGicPmuIrq0), + FixedPcdGet64 (PcdGicInterruptInterfaceBase), FixedPcdGet64 (PcdGicInterruptInterfaceVBase), + // + // Use 1 for GICR Base Address below, since Windows 10 on Raspberry Pi 3 does not + // boot otherwise, and this is the value that Microsoft had in their IoT blobs. + // Kept to 1 for GICv2-based Pi 4, since this field only matters for GICv3. + // + FixedPcdGet64 (PcdGicInterruptInterfaceHBase), FixedPcdGet32 (PcdGicGsivId), 0, 1, 0), + EFI_ACPI_6_3_GICC_STRUCTURE_INIT ( + 1, 1, GET_MPID(0, 1), EFI_ACPI_6_0_GIC_ENABLED, FixedPcdGet32 (PcdGicPmuIrq1), + FixedPcdGet64 (PcdGicInterruptInterfaceBase), FixedPcdGet64 (PcdGicInterruptInterfaceVBase), + FixedPcdGet64 (PcdGicInterruptInterfaceHBase), FixedPcdGet32 (PcdGicGsivId), 0, 1, 0), + EFI_ACPI_6_3_GICC_STRUCTURE_INIT ( + 2, 2, GET_MPID(0, 2), EFI_ACPI_6_0_GIC_ENABLED, FixedPcdGet32 (PcdGicPmuIrq2), + FixedPcdGet64 (PcdGicInterruptInterfaceBase), FixedPcdGet64 (PcdGicInterruptInterfaceVBase), + FixedPcdGet64 (PcdGicInterruptInterfaceHBase), FixedPcdGet32 (PcdGicGsivId), 0, 1, 0), + EFI_ACPI_6_3_GICC_STRUCTURE_INIT ( + 3, 3, GET_MPID(0, 3), EFI_ACPI_6_0_GIC_ENABLED, FixedPcdGet32 (PcdGicPmuIrq3), + FixedPcdGet64 (PcdGicInterruptInterfaceBase), FixedPcdGet64 (PcdGicInterruptInterfaceVBase), + FixedPcdGet64 (PcdGicInterruptInterfaceHBase), FixedPcdGet32 (PcdGicGsivId), 0, 1, 0), + }, +#if (RPI_MODEL != 3) + EFI_ACPI_6_0_GIC_DISTRIBUTOR_INIT (0, FixedPcdGet64 (PcdGicDistributorBase), 0, 2) +#endif +}; + +// +// Reference the table being generated to prevent the optimizer from removing the +// data structure from the executable +// +VOID* CONST ReferenceAcpiTable = &Madt; diff --git a/board/raspberrypi/rpi/pci.asl b/board/raspberrypi/rpi/pci.asl new file mode 100644 index 00000000000..19eb62a2043 --- /dev/null +++ b/board/raspberrypi/rpi/pci.asl @@ -0,0 +1,168 @@ +/** @file + * + * Copyright (c) 2019 Linaro, Limited. All rights reserved. + * Copyright (c) 2021 Arm + * + * SPDX-License-Identifier: BSD-2-Clause-Patent + * + **/ + +#include <asm/arch/acpi/Bcm2711.h> + +#include "acpitables.h" + +/* + * The following can be used to remove parenthesis from + * defined macros that the compiler complains about. + */ +#define ISOLATE_ARGS(...) __VA_ARGS__ +#define REMOVE_PARENTHESES(x) ISOLATE_ARGS x + +#define SANITIZED_PCIE_CPU_MMIO_WINDOW REMOVE_PARENTHESES(PCIE_CPU_MMIO_WINDOW) +#define SANITIZED_PCIE_MMIO_LEN REMOVE_PARENTHESES(PCIE_BRIDGE_MMIO_LEN) +#define SANITIZED_PCIE_PCI_MMIO_BEGIN REMOVE_PARENTHESES(PCIE_TOP_OF_MEM_WIN) + +DefinitionBlock (__FILE__, "SSDT", 5, "RPIFDN", "RPI4PCIE", 2) +{ + Scope (_SB_) + { + Device(PCI0) + { + Name(_HID, EISAID("PNP0A08")) // PCI Express Root Bridge + Name(_CID, EISAID("PNP0A03")) // Compatible PCI Root Bridge + Name(_SEG, Zero) // PCI Segment Group number + Name(_BBN, Zero) // PCI Base Bus Number + Name(_CCA, 0) // Mark the PCI noncoherent + + // PCIe can only DMA to first 3GB with early SOC's + // But we keep the restriction on the later ones + // To avoid DMA translation problems. + Name (_DMA, ResourceTemplate() { + QWordMemory (ResourceProducer, + , + MinFixed, + MaxFixed, + NonCacheable, + ReadWrite, + 0x0, + 0x0, // MIN + 0xbfffffff, // MAX + 0x0, // TRA + 0xc0000000, // LEN + , + , + ) + }) + + // PCI Routing Table + Name(_PRT, Package() { + Package (4) { 0x0000FFFF, 0, zero, 175 }, + Package (4) { 0x0000FFFF, 1, zero, 176 }, + Package (4) { 0x0000FFFF, 2, zero, 177 }, + Package (4) { 0x0000FFFF, 3, zero, 178 } + }) + + Name (_DSD, Package () { + ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + Package () { + Package () { "linux-ecam-quirk-id", "bcm2711" }, + } + }) + + // Root complex resources + Method (_CRS, 0, Serialized) { + Name (RBUF, ResourceTemplate () { + + // bus numbers assigned to this root + WordBusNumber ( + ResourceProducer, + MinFixed, MaxFixed, PosDecode, + 0, // AddressGranularity + 0, // AddressMinimum - Minimum Bus Number + 255, // AddressMaximum - Maximum Bus Number + 0, // AddressTranslation - Set to 0 + 256 // RangeLength - Number of Busses + ) + + // 32-bit mmio window in 64-bit addr + QWordMemory ( + ResourceProducer, PosDecode, + MinFixed, MaxFixed, + NonCacheable, ReadWrite, // cacheable + 0x00000000, // Granularity + 0, // SANITIZED_PCIE_PCI_MMIO_BEGIN + 1, // SANITIZED_PCIE_MMIO_LEN + SANITIZED_PCIE_PCI_MMIO_BEGIN + SANITIZED_PCIE_CPU_MMIO_WINDOW, // SANITIZED_PCIE_PCI_MMIO_BEGIN - SANITIZED_PCIE_CPU_MMIO_WINDOW + 2 // SANITIZED_PCIE_MMIO_LEN + 1 + ,,,MMI1 + ) + + // root port registers, not to be used if SMCCC is utilized + QWordMemory ( + ResourceConsumer, , + MinFixed, MaxFixed, + NonCacheable, ReadWrite, // cacheable + 0x00000000, // Granularity + 0xFD500000, // Root port begin + 0xFD509FFF, // Root port end + 0x00000000, // no translation + 0x0000A000, // size + ,, + ) + }) // end Name(RBUF) + + // Work around ASL's inability to add in a resource definition + // or for that matter compute the min,max,len properly + CreateQwordField (RBUF, MMI1._MIN, MMIB) + CreateQwordField (RBUF, MMI1._MAX, MMIE) + CreateQwordField (RBUF, MMI1._TRA, MMIT) + CreateQwordField (RBUF, MMI1._LEN, MMIL) + Add (MMIB, SANITIZED_PCIE_PCI_MMIO_BEGIN, MMIB) + Add (SANITIZED_PCIE_MMIO_LEN, SANITIZED_PCIE_PCI_MMIO_BEGIN, MMIE) + Subtract (MMIT, SANITIZED_PCIE_PCI_MMIO_BEGIN, MMIT) + Add (SANITIZED_PCIE_MMIO_LEN, 1 , MMIL) + + Return (RBUF) + } // end Method(_CRS) + + // OS Control Handoff + Name(SUPP, Zero) // PCI _OSC Support Field value + Name(CTRL, Zero) // PCI _OSC Control Field value + + // See [1] 6.2.10, [2] 4.5 + Method(_OSC,4) { + // Note, This code is very similar to the code in the PCIe firmware + // specification which can be used as a reference + // Check for proper UUID + If(LEqual(Arg0,ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) { + // Create DWord-adressable fields from the Capabilities Buffer + CreateDWordField(Arg3,0,CDW1) + CreateDWordField(Arg3,4,CDW2) + CreateDWordField(Arg3,8,CDW3) + // Save Capabilities DWord2 & 3 + Store(CDW2,SUPP) + Store(CDW3,CTRL) + // Mask out Native HotPlug + And(CTRL,0x1E,CTRL) + // Always allow native PME, AER (no dependencies) + // Never allow SHPC (no SHPC controller in this system) + And(CTRL,0x1D,CTRL) + + If(LNotEqual(Arg1,One)) { // Unknown revision + Or(CDW1,0x08,CDW1) + } + + If(LNotEqual(CDW3,CTRL)) { // Capabilities bits were masked + Or(CDW1,0x10,CDW1) + } + // Update DWORD3 in the buffer + Store(CTRL,CDW3) + Return(Arg3) + } Else { + Or(CDW1,4,CDW1) // Unrecognized UUID + Return(Arg3) + } + } // End _OSC + } // PCI0 + } //end scope sb +} //end definition block diff --git a/board/raspberrypi/rpi/pep.asl b/board/raspberrypi/rpi/pep.asl new file mode 100644 index 00000000000..87469e2e5a9 --- /dev/null +++ b/board/raspberrypi/rpi/pep.asl @@ -0,0 +1,90 @@ +/** @file + * + * Platform Extension Plugin (PEP). + * + * Copyright (c) 2019, ARM Ltd. All rights reserved. + * Copyright (c) 2018, Andrey Warkentin andrey.warkentin@gmail.com + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-2-Clause-Patent + * + **/ + +Device(PEPD) +{ + // + // PEP virtual device. + // + Name (_HID, "BCM2854") // Note: Since PEP on RPi is a virtual device, + Name (_CID, "BCM2854") // its device id needs to be generated by Microsoft + Name (_UID, 0x0) + Name (_CRS, ResourceTemplate () + { + // No hardware resources for PEP driver are needed. + }) + + // + // Processor info. PEP proprietary method to return + // PEP_PROCESSOR_TABLE_PLAT structure. + // + // See Pep.h and Pep.c. + // + Name (_GPI, Buffer() + { + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x5F, 0x00, 0x53, + 0x00, 0x42, 0x00, 0x2E, 0x00, 0x43, 0x00, 0x50, 0x00, 0x55, 0x00, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }) + + // + // Coordinated state info. PEP proprietary method to return + // PEP_COORDINATED_STATE_TABLE_PLAT structure. + // + // See Pep.h and Pep.c. + // + Name (_GCI, Buffer() + { + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 + }) + + // + // Device info. PEP proprietary method to return + // PEP_DEVICE_TABLE_PLAT structure. + // + // See Pep.h and Pep.c. + // + Name (_GDI, Buffer() + { + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x5F, 0x00, 0x53, + 0x00, 0x42, 0x00, 0x2E, 0x00, 0x49, 0x00, 0x32, 0x00, 0x43, 0x00, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }) +} diff --git a/board/raspberrypi/rpi/pep.c b/board/raspberrypi/rpi/pep.c new file mode 100644 index 00000000000..50d22e13190 --- /dev/null +++ b/board/raspberrypi/rpi/pep.c @@ -0,0 +1,79 @@ +/** @file + * + * PEP device tables + * + * Copyright (c) 2019, ARM Ltd. All rights reserved. + * Copyright (c) 2018, Andrei Warkentin andrey.warkentin@gmail.com + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-2-Clause-Patent + * + **/ + +#include "Pep.h" + +PEP_PROCESSOR_TABLE_PLAT RpiProcessors = { + 1, // Version + 1, // NumberProcessors + { // ProcessorInfo + { // [0] + L"\_SB.CPU0", // DevicePath, wchar_t[16] + 0, // FeedbackCounterCount + 0x00000000, // Flags + 0, // NumberIdleStates + 0, // NumberPerfStates + { // IdleInfo + }, + { // perfinfo + } + } + } +}; + +PEP_COORDINATED_STATE_TABLE_PLAT RpiCoordinatedStates = { + 1, // Version + 1, // CoordinatedStateCount + { // CordinatedStates[] + { // [0] + { // DependencyInfo + { // [0] + 1, // ExpectedState + 0, // TargetProcessor + 0x0 | 0x2 | 0x4, // LooseDependency = FALSE, InitialState = TRUE, DependentState = TRUE + } + }, + SOC_STATE_TYPE, // StateType + 0x1, // Flags + 0, // Latency + 0, // BreakEvenDuration + 1, // DependencyCount + 1, // MaximumDependencySize + } + } +}; + +PEP_DEVICE_TABLE_PLAT RpiDevices = { + 1, // Version + 1, // NumberDevices + { // DeviceInfo + { // [1] + L"\_SB.I2C0", // DevicePath, wchar_t[16] + 0x1 | (1 << 3), // DStateSupportMask (D0 and D3) + 1, // NumberCompoenents + { // DStateRequirement + { // [0] + PowerDeviceD3 // DState + } + }, + { // FStateRequirement + { // [0] + { // FState + { // [0] + 0 + } + } + } + } + } + } +}; diff --git a/board/raspberrypi/rpi/pep.h b/board/raspberrypi/rpi/pep.h new file mode 100644 index 00000000000..c7be3109e6e --- /dev/null +++ b/board/raspberrypi/rpi/pep.h @@ -0,0 +1,121 @@ +/** @file + * + * PEP device defines + * + * Copyright (c) 2019, ARM Ltd. All rights reserved. + * Copyright (c) 2018, Andrei Warkentin andrey.warkentin@gmail.com + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-2-Clause-Patent + * + **/ + +/* + * Note: Not everything is here. At least SOC_STATE_TYPE is missing. + */ + +#ifndef _RPI_PEP_H_INCLUDED_ +#define _RPI_PEP_H_INCLUDED_ + +#include <asm/arch/acpi/Acpi.h> + +#define PEP_MAX_DEPENDENCIES_PER_STATE 16 +#define MAX_PROCESSOR_PATH_LENGTH 16 +#define MAX_DEVICE_PATH_LENGTH 32 +#define MAX_COMPONENT_COUNT 8 +#define P_NUMBER_PROCESSORS 1 +#define P_NUMBER_IDLE_STATES 1 +#define P_NUMBER_PERF_STATES 0 +#define P_NUMBER_DEVICES 1 +#define P_NUMBER_COORDINATED_STATS 1 + +typedef struct _PEP_PROCESSOR_IDLE_STATE_INFO { + UINT32 Ulong; + UINT32 Latency; + UINT32 BreakEvenDuration; +} PEP_PROCESSOR_IDLE_STATE_INFO, *PEP_PROCESSOR_IDLE_STATE_INFO; + +typedef struct _PEP_PROCESSOR_IDLE_INFO_PLAT { + // + // Processor idle states. + // + PEP_PROCESSOR_IDLE_STATE_INFO IdleStates[P_NUMBER_IDLE_STATES]; +} PEP_PROCESSOR_IDLE_INFO_PLAT, *PPEP_PROCESSOR_IDLE_INFO_PLAT; + +typedef struct COORDINATED_DEPENDENCY_INFO { + UINT32 ExpectedState; + UINT32 TargetProcessor; + UINT32 Ulong; +} COORDINATED_DEPENDENCY_INFO, *PCOORDINATED_DEPENDENCY_INFO; + +typedef struct { + COORDINATED_DEPENDENCY_INFO DependencyInfo[PEP_MAX_DEPENDENCIES_PER_STATE]; + UINT32 StateType; + UINT32 Ulong; + UINT32 Latency; + UINT32 BreakEvenDuration; + UINT32 DependencyCount; + UINT32 MaximumDependencySize; +} COORDINATED_STATE_INFO; + +typedef struct { + UINT32 Unused; +} PEP_PROCESSOR_PERF_INFO; + +typedef struct { + UINT32 FState[MAX_COMPONENT_COUNT]; +} COORDINATED_FSTATE_REQUIREMENT; + +typedef struct { + UINT32 DState; +} COORDINATED_DSTATE_REQUIREMENT; + +// +// Top level device table +// *N.B. The exact length of the structure is determined by the NumberIdleStates/NumberPerfStates variables. +// + +typedef struct _PEP_PROCESSOR_INFO_PLAT { + WCHAR DevicePath[MAX_PROCESSOR_PATH_LENGTH]; // Null-terminated ACPI name + ULONG FeedbackCounterCount; + ULONG Flags; + + // + // We are putting the idle/perf state count here (instead + // of the PEP_PROCESSOR_xxx_INFO structure for the ease of parsing. + // + ULONG NumberIdleStates; + ULONG NumberPerfStates; + + PEP_PROCESSOR_IDLE_INFO_PLAT IdleInfo; + PEP_PROCESSOR_PERF_INFO PerfInfo; +} PEP_PROCESSOR_INFO_PLAT, *PPEP_PROCESSOR_INFO_PLAT; + +typedef struct _PEP_PROCESSOR_TABLE_PLAT { + UINT32 Version; + UINT32 NumberProcessors; + PEP_PROCESSOR_INFO_PLAT ProcessorInfo[P_NUMBER_PROCESSORS]; +} PEP_PROCESSOR_TABLE_PLAT; + +typedef struct _PEP_COORDINATED_STATE_TABLE_PLAT { + ULONG Version; + ULONG CoordinatedStateCount; + COORDINATED_STATE_INFO CoordinatedStates[P_NUMBER_COORDINATED_STATS]; +} PEP_COORDINATED_STATE_TABLE_PLAT, *PPEP_COORDINATED_STATE_TABLE_PLAT; + +typedef struct _PEP_DEVICE_INFO_PLAT { + WCHAR DevicePath[MAX_DEVICE_PATH_LENGTH]; // Null-terminated ACPI name + ULONG DStateSupportMask; + ULONG NumberComponents; + + COORDINATED_DSTATE_REQUIREMENT DStateRequirement[P_NUMBER_COORDINATED_STATS]; + COORDINATED_FSTATE_REQUIREMENT FStateRequirement[P_NUMBER_COORDINATED_STATS]; +} PEP_DEVICE_INFO_PLAT, *PPEP_DEVICE_INFO_PLAT; + +typedef struct _PEP_DEVICE_TABLE_PLAT { + ULONG Version; + ULONG NumberDevices; + PEP_DEVICE_INFO_PLAT DeviceInfo[P_NUMBER_DEVICES]; +} PEP_DEVICE_TABLE_PLAT, *PPEP_DEVICE_TABLE_PLAT; + +#endif // _RPI_PEP_H_INCLUDED_ diff --git a/board/raspberrypi/rpi/pptt.aslc b/board/raspberrypi/rpi/pptt.aslc new file mode 100644 index 00000000000..9769a5b25e0 --- /dev/null +++ b/board/raspberrypi/rpi/pptt.aslc @@ -0,0 +1,191 @@ +/** @file + * + * Processor Properties Topology Table (PPTT) + * + * Copyright (c) 2018, Linaro Ltd. All rights reserved.<BR> + * + * SPDX-License-Identifier: BSD-2-Clause-Patent + * + **/ + +#include <IndustryStandard/Acpi.h> + +#include "AcpiTables.h" + +#define NUM_CORES 4 +#define NUM_CLUSTERS 1 + +#if (RPI_MODEL == 3) +#define CORTEX_L1D_SIZE SIZE_16KB +#define CORTEX_L1D_SETS 64 +#define CORTEX_L1D_ASSC 4 +#define CORTEX_L1I_SIZE SIZE_16KB +#define CORTEX_L1I_SETS 128 +#define CORTEX_L1I_ASSC 2 +#define CORTEX_L2_SIZE SIZE_512KB +#define CORTEX_L2_SETS 512 +#define CORTEX_L2_ASSC 16 +#elif (RPI_MODEL == 4) +#define CORTEX_L1D_SIZE SIZE_32KB +#define CORTEX_L1D_SETS 256 +#define CORTEX_L1D_ASSC 2 +#define CORTEX_L1I_SIZE (3*SIZE_16KB) +#define CORTEX_L1I_SETS 256 +#define CORTEX_L1I_ASSC 3 +#define CORTEX_L2_SIZE SIZE_1MB +#define CORTEX_L2_SETS 1024 +#define CORTEX_L2_ASSC 16 +#endif + +#define FIELD_OFFSET(type, name) __builtin_offsetof(type, name) + +#pragma pack(1) +typedef struct { + EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR Core; + UINT32 Offset[2]; + EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE DCache; + EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE ICache; +} ACPI_6_3_PPTT_CORE; + +typedef struct { + EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR Cluster; + UINT32 Offset[1]; + EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE L2Cache; + ACPI_6_3_PPTT_CORE Cores[NUM_CORES]; +} ACPI_6_3_PPTT_CLUSTER; + +typedef struct { + EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER Pptt; + ACPI_6_3_PPTT_CLUSTER Packages[NUM_CLUSTERS]; +} ACPI_6_3_PPTT_STRUCTURE; +#pragma pack() + +#define PPTT_CORE(pid, cid, id) { \ + { \ + EFI_ACPI_6_3_PPTT_TYPE_PROCESSOR, \ + FIELD_OFFSET (ACPI_6_3_PPTT_CORE, DCache), \ + {}, \ + { \ + EFI_ACPI_6_3_PPTT_PACKAGE_NOT_PHYSICAL, /* Not PhysicalPackage */ \ + EFI_ACPI_6_3_PPTT_PROCESSOR_ID_VALID, /* AcpiProcessorIdValid */ \ + EFI_ACPI_6_3_PPTT_PROCESSOR_IS_NOT_THREAD, /* Is not a Thread */ \ + EFI_ACPI_6_3_PPTT_NODE_IS_LEAF, /* Leaf */ \ + EFI_ACPI_6_3_PPTT_IMPLEMENTATION_IDENTICAL, /* identical ignored */ \ + }, \ + FIELD_OFFSET (ACPI_6_3_PPTT_STRUCTURE, \ + Packages[pid]), /* Parent */ \ + 256 * (cid) + (id), /* AcpiProcessorId */ \ + 2, /* NumberOfPrivateResources */ \ + }, { \ + FIELD_OFFSET (ACPI_6_3_PPTT_STRUCTURE, \ + Packages[pid].Cores[id].DCache), \ + FIELD_OFFSET (ACPI_6_3_PPTT_STRUCTURE, \ + Packages[pid].Cores[id].ICache), \ + }, { \ + EFI_ACPI_6_3_PPTT_TYPE_CACHE, \ + sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE), \ + {}, \ + { \ + 1, /* SizePropertyValid */ \ + 1, /* NumberOfSetsValid */ \ + 1, /* AssociativityValid */ \ + 1, /* AllocationTypeValid */ \ + 1, /* CacheTypeValid */ \ + 1, /* WritePolicyValid */ \ + 1, /* LineSizeValid */ \ + }, \ + 0, /* NextLevelOfCache */ \ + CORTEX_L1D_SIZE, /* Size */ \ + CORTEX_L1D_SETS, /* NumberOfSets */ \ + CORTEX_L1D_ASSC, /* Associativity */ \ + { \ + EFI_ACPI_6_3_CACHE_ATTRIBUTES_ALLOCATION_READ_WRITE, \ + EFI_ACPI_6_3_CACHE_ATTRIBUTES_CACHE_TYPE_DATA, \ + EFI_ACPI_6_3_CACHE_ATTRIBUTES_WRITE_POLICY_WRITE_BACK, \ + }, \ + 64 /* LineSize */ \ + }, { \ + EFI_ACPI_6_3_PPTT_TYPE_CACHE, \ + sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE), \ + {}, \ + { \ + 1, /* SizePropertyValid */ \ + 1, /* NumberOfSetsValid */ \ + 1, /* AssociativityValid */ \ + 1, /* AllocationTypeValid */ \ + 1, /* CacheTypeValid */ \ + 0, /* WritePolicyValid */ \ + 1, /* LineSizeValid */ \ + }, \ + 0, /* NextLevelOfCache */ \ + CORTEX_L1I_SIZE, /* Size */ \ + CORTEX_L1I_SETS, /* NumberOfSets */ \ + CORTEX_L1I_ASSC, /* Associativity */ \ + { \ + EFI_ACPI_6_3_CACHE_ATTRIBUTES_ALLOCATION_READ, /* AllocationType */ \ + EFI_ACPI_6_3_CACHE_ATTRIBUTES_CACHE_TYPE_INSTRUCTION, \ + 0, /* WritePolicy */ \ + }, \ + 64 /* LineSize */ \ + } \ +} + +#define PPTT_CLUSTER(pid, cid) { \ + { \ + EFI_ACPI_6_3_PPTT_TYPE_PROCESSOR, \ + FIELD_OFFSET (ACPI_6_3_PPTT_CLUSTER, L2Cache), \ + {}, \ + { \ + EFI_ACPI_6_3_PPTT_PACKAGE_PHYSICAL, /* PhysicalPackage */ \ + EFI_ACPI_6_3_PPTT_PROCESSOR_ID_INVALID, /* AcpiProcessorIdValid */ \ + EFI_ACPI_6_3_PPTT_PROCESSOR_IS_NOT_THREAD, /* Is not a Thread */ \ + EFI_ACPI_6_3_PPTT_NODE_IS_NOT_LEAF, /* not Leaf */ \ + EFI_ACPI_6_3_PPTT_IMPLEMENTATION_IDENTICAL, /* identical cores */ \ + }, \ + 0, /* Parent */ \ + 0, /* AcpiProcessorId */ \ + 1, /* NumberOfPrivateResources */ \ + }, { \ + FIELD_OFFSET (ACPI_6_3_PPTT_STRUCTURE, Packages[pid].L2Cache), \ + }, { \ + EFI_ACPI_6_3_PPTT_TYPE_CACHE, \ + sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE), \ + {}, \ + { \ + 1, /* SizePropertyValid */ \ + 1, /* NumberOfSetsValid */ \ + 1, /* AssociativityValid */ \ + 1, /* AllocationTypeValid */ \ + 1, /* CacheTypeValid */ \ + 1, /* WritePolicyValid */ \ + 1, /* LineSizeValid */ \ + }, \ + 0, /* NextLevelOfCache */ \ + CORTEX_L2_SIZE, /* Size */ \ + CORTEX_L2_SETS, /* NumberOfSets */ \ + CORTEX_L2_ASSC, /* Associativity */ \ + { \ + EFI_ACPI_6_3_CACHE_ATTRIBUTES_ALLOCATION_READ_WRITE, \ + EFI_ACPI_6_3_CACHE_ATTRIBUTES_CACHE_TYPE_UNIFIED, \ + EFI_ACPI_6_3_CACHE_ATTRIBUTES_WRITE_POLICY_WRITE_BACK, \ + }, \ + 64 /* LineSize */ \ + }, { \ + PPTT_CORE(pid, cid, 0), \ + PPTT_CORE(pid, cid, 1), \ + PPTT_CORE(pid, cid, 2), \ + PPTT_CORE(pid, cid, 3), \ + } \ +} + +ACPI_6_3_PPTT_STRUCTURE Pptt = { + { + ACPI_HEADER(EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE, + ACPI_6_3_PPTT_STRUCTURE, + EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_REVISION), + }, { + PPTT_CLUSTER (0, 0), + } +}; + +VOID * CONST ReferenceAcpiTable = &Pptt; diff --git a/board/raspberrypi/rpi/rhpx.asl b/board/raspberrypi/rpi/rhpx.asl new file mode 100644 index 00000000000..214b55c6564 --- /dev/null +++ b/board/raspberrypi/rpi/rhpx.asl @@ -0,0 +1,195 @@ +/** @file + * + * [DSDT] RHProxy device to enable WinRT API (RHPX) + * + * Copyright (c) 2018, Andrey Warkentin andrey.warkentin@gmail.com + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-2-Clause-Patent + * + **/ + +Device (RHPX) +{ + Name (_HID, "MSFT8000") + Name (_CID, "MSFT8000") + Name (_UID, 1) + + Name(_CRS, ResourceTemplate () + { + // Index 0 + SPISerialBus ( // SCKL - GPIO 11 - Pin 23 + // MOSI - GPIO 10 - Pin 19 + // MISO - GPIO 9 - Pin 21 + // CE0 - GPIO 8 - Pin 24 + 0, // Device selection (CE0) + PolarityLow, // Device selection polarity + FourWireMode, // WireMode + 8, // DataBit len + ControllerInitiated, // Slave mode + 4000000, // Connection speed + ClockPolarityLow, // Clock polarity + ClockPhaseFirst, // Clock phase + "\_SB.GDV0.SPI0", // ResourceSource: SPI bus controller name + 0, // ResourceSourceIndex + // Resource usage + // DescriptorName: creates name for offset of resource descriptor + ) // Vendor Data + + // Index 1 + SPISerialBus ( // SCKL - GPIO 11 - Pin 23 + // MOSI - GPIO 10 - Pin 19 + // MISO - GPIO 9 - Pin 21 + // CE1 - GPIO 7 - Pin 26 + 1, // Device selection (CE1) + PolarityLow, // Device selection polarity + FourWireMode, // WireMode + 8, // DataBit len + ControllerInitiated, // Slave mode + 4000000, // Connection speed + ClockPolarityLow, // Clock polarity + ClockPhaseFirst, // Clock phase + "\_SB.GDV0.SPI0", // ResourceSource: SPI bus controller name + 0, // ResourceSourceIndex + // Resource usage + // DescriptorName: creates name for offset of resource descriptor + ) // Vendor Data + + // Index 2 + I2CSerialBus ( // Pin 3 (GPIO2, SDA1), 5 (GPIO3, SCL1) + 0xFFFF, // SlaveAddress: placeholder + , // SlaveMode: default to ControllerInitiated + 0, // ConnectionSpeed: placeholder + , // Addressing Mode: default to 7 bit + "\_SB.GDV0.I2C1", // ResourceSource: I2C bus controller name + , + , + , // Descriptor Name: creates name for offset of resource descriptor + ) // Vendor Data + + // Index 3 + SPISerialBus ( // SPI1_SCLK - GPIO21 + // SPI1_MOSI - GPIO20 + // SPI1_MISO - GPIO19 + // SPI1_CE2_N - GPIO16 + 2, // Device selection (CE2) + PolarityLow, // Device selection polarity + FourWireMode, // WireMode + 8, // DataBit len + ControllerInitiated, // Slave mode + 4000000, // Connection speed + ClockPolarityLow, // Clock polarity + ClockPhaseFirst, // Clock phase + "\_SB.GDV0.SPI1", // ResourceSource: SPI bus controller name + 0, // ResourceSourceIndex + // Resource usage + // DescriptorName: creates name for offset of resource descriptor + ) // Vendor Data + + // GPIO 2 + GpioIO (Shared, PullUp, 0, 0, IoRestrictionNone, "\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 2 } + GpioInt (Edge, ActiveBoth, Shared, PullUp, 0, "\_SB.GDV0.GPI0",) { 2 } + // GPIO 3 + GpioIO (Shared, PullUp, 0, 0, IoRestrictionNone, "\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 3 } + GpioInt (Edge, ActiveBoth, Shared, PullUp, 0, "\_SB.GDV0.GPI0",) { 3 } + // GPIO 4 + GpioIO (Shared, PullUp, 0, 0, IoRestrictionNone, "\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 4 } + GpioInt (Edge, ActiveBoth, Shared, PullUp, 0, "\_SB.GDV0.GPI0",) { 4 } + // GPIO 5 + GpioIO (Shared, PullUp, 0, 0, IoRestrictionNone, "\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 5 } + GpioInt (Edge, ActiveBoth, Shared, PullUp, 0, "\_SB.GDV0.GPI0",) { 5 } + // GPIO 6 + GpioIO (Shared, PullUp, 0, 0, IoRestrictionNone, "\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 6 } + GpioInt (Edge, ActiveBoth, Shared, PullUp, 0, "\_SB.GDV0.GPI0",) { 6 } + // GPIO 7 + GpioIO (Shared, PullUp, 0, 0, IoRestrictionNone, "\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 7 } + GpioInt (Edge, ActiveBoth, Shared, PullUp, 0, "\_SB.GDV0.GPI0",) { 7 } + // GPIO 8 + GpioIO (Shared, PullUp, 0, 0, IoRestrictionNone, "\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 8 } + GpioInt (Edge, ActiveBoth, Shared, PullUp, 0, "\_SB.GDV0.GPI0",) { 8 } + // GPIO 9 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 9 } + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\_SB.GDV0.GPI0",) { 9 } + // GPIO 10 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 10 } + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\_SB.GDV0.GPI0",) { 10 } + // GPIO 11 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 11 } + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\_SB.GDV0.GPI0",) { 11 } + // GPIO 12 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 12 } + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\_SB.GDV0.GPI0",) { 12 } + // GPIO 13 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 13 } + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\_SB.GDV0.GPI0",) { 13 } + // NTRAID#MSFT-7141401-2016/04/7-jordanrh - disable UART muxing + // until a proper solution can be created for the dmap conflict + // GPIO 14 - UART TX + // GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 14 } + // GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\_SB.GDV0.GPI0",) { 14 } + // GPIO 15 - UART RX + // GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 15 } + // GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\_SB.GDV0.GPI0",) { 15 } + // GPIO 16 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 16 } + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\_SB.GDV0.GPI0",) { 16 } + // GPIO 17 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 17 } + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\_SB.GDV0.GPI0",) { 17 } + // GPIO 18 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 18 } + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\_SB.GDV0.GPI0",) { 18 } + // GPIO 19 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 19 } + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\_SB.GDV0.GPI0",) { 19 } + // GPIO 20 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 20 } + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\_SB.GDV0.GPI0",) { 20 } + // GPIO 21 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 21 } + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\_SB.GDV0.GPI0",) { 21 } + // GPIO 22 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 22 } + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\_SB.GDV0.GPI0",) { 22 } + // GPIO 23 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 23 } + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\_SB.GDV0.GPI0",) { 23 } + // GPIO 24 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 24 } + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\_SB.GDV0.GPI0",) { 24 } + // GPIO 25 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 25 } + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\_SB.GDV0.GPI0",) { 25 } + // GPIO 26 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 26 } + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\_SB.GDV0.GPI0",) { 26 } + // GPIO 27 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 27 } + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\_SB.GDV0.GPI0",) { 27 } + }) + + Name (_DSD, Package() + { + ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + Package () + { + // Reference http://www.raspberrypi.org/documentation/hardware/raspberrypi/spi/README.md + // SPI 0 + Package (2) { "bus-SPI-SPI0", Package() { 0, 1 } }, // Index 0 & 1 + Package (2) { "SPI0-MinClockInHz", 7629 }, // 7629 Hz + Package (2) { "SPI0-MaxClockInHz", 125000000 }, // 125 MHz + Package (2) { "SPI0-SupportedDataBitLengths", Package() { 8 } }, // Data Bit Length + // I2C1 + Package (2) { "bus-I2C-I2C1", Package() { 2 } }, + // GPIO Pin Count and supported drive modes + Package (2) { "GPIO-PinCount", 54 }, + Package (2) { "GPIO-UseDescriptorPinNumbers", 1 }, + Package (2) { "GPIO-SupportedDriveModes", 0xf }, // InputHighImpedance, InputPullUp, InputPullDown, OutputCmos + // SPI 1 + Package (2) { "bus-SPI-SPI1", Package() { 3 }}, // Index 3 + Package (2) { "SPI1-MinClockInHz", 30511 }, // 30.5 kHz + Package (2) { "SPI1-MaxClockInHz", 20000000 }, // 20 MHz + Package (2) { "SPI1-SupportedDataBitLengths", Package() { 8 } }, // Data Bit Length + } + }) +} diff --git a/board/raspberrypi/rpi/rpi4.dsc b/board/raspberrypi/rpi/rpi4.dsc new file mode 100644 index 00000000000..5694cf0973e --- /dev/null +++ b/board/raspberrypi/rpi/rpi4.dsc @@ -0,0 +1,790 @@ +# @file +# +# Copyright (c) 2011 - 2020, ARM Limited. All rights reserved. +# Copyright (c) 2017 - 2018, Andrei Warkentin andrey.warkentin@gmail.com +# Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved. +# Copyright (c) 2014, Linaro Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + PLATFORM_NAME = RPi4 + PLATFORM_GUID = a7eca3b4-21b0-4989-8c18-c08f3ae87837 + PLATFORM_VERSION = 1.0 + DSC_SPECIFICATION = 0x0001001A + OUTPUT_DIRECTORY = Build/$(PLATFORM_NAME) + SUPPORTED_ARCHITECTURES = AARCH64 + BUILD_TARGETS = DEBUG|RELEASE|NOOPT + SKUID_IDENTIFIER = DEFAULT + FLASH_DEFINITION = Platform/RaspberryPi/$(PLATFORM_NAME)/$(PLATFORM_NAME).fdf + + # + # Defines for default states. These can be changed on the command line. + # -D FLAG=VALUE + # + DEFINE SECURE_BOOT_ENABLE = FALSE + DEFINE INCLUDE_TFTP_COMMAND = FALSE + DEFINE DEBUG_PRINT_ERROR_LEVEL = 0x8000004F + +!ifndef TFA_BUILD_ARTIFACTS + # + # Default TF-A binary checked into edk2-non-osi. + # + DEFINE TFA_BUILD_BL31 = Platform/RaspberryPi/$(PLATFORM_NAME)/TrustedFirmware/bl31.bin +!else + # + # Usually we use the checked-in binaries, but for developers working + # on the firmware, being able to use a local TF-A build without extra copy + # operations ends up being very helpful. + # + DEFINE TFA_BUILD_BL31 = $(TFA_BUILD_ARTIFACTS)/bl31.bin +!endif + +################################################################################ +# +# Library Class section - list of all Library Classes needed by this Platform. +# +################################################################################ + +!include MdePkg/MdeLibs.dsc.inc + +[LibraryClasses.common] +!if $(TARGET) == RELEASE + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf +!else + DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf +!endif + DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf + + BaseLib|MdePkg/Library/BaseLib/BaseLib.inf + SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf + BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf + SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf + PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf + ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf + PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf + PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf + PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf + UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf + CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf + + UefiLib|MdePkg/Library/UefiLib/UefiLib.inf + HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf + UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf + DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf + DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf + DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf + UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf + UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf + HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf + UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf + SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf + + UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf + OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf + + # + # Ramdisk Requirements + # + FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf + + # Allow dynamic PCDs + # + PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf + + # use the accelerated BaseMemoryLibOptDxe by default, overrides for SEC/PEI below + BaseMemoryLib|MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf + + # + # It is not possible to prevent the ARM compiler from inserting calls to intrinsic functions. + # This library provides the instrinsic functions such a compiler may generate calls to. + # + NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf + + # Add support for GCC stack protector + NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf + + # ARM Architectural Libraries + CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf + DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf + CpuExceptionHandlerLib|ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.inf + ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf + ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicLib.inf + ArmGicArchLib|ArmPkg/Library/ArmGicArchLib/ArmGicArchLib.inf + DmaLib|EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.inf + TimeBaseLib|EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.inf + ArmPlatformStackLib|ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf + ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf + ArmHvcLib|ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf + ArmGenericTimerCounterLib|ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf + + # Dual serial port library + PL011UartClockLib|ArmPlatformPkg/Library/PL011UartClockLib/PL011UartClockLib.inf + PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf + SerialPortLib|Platform/RaspberryPi/Library/DualSerialPortLib/DebugDualSerialPortLib.inf + + # Cryptographic libraries + RngLib|MdePkg/Library/DxeRngLib/DxeRngLib.inf + IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf + OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf + TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf + + # + # Uncomment (and comment out the next line) For RealView Debugger. The Standard IO window + # in the debugger will show load and unload commands for symbols. You can cut and paste this + # into the command window to load symbols. We should be able to use a script to do this, but + # the version of RVD I have does not support scripts accessing system memory. + # + #PeCoffExtraActionLib|ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.inf + PeCoffExtraActionLib|ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf + #PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf + + DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf + DebugAgentTimerLib|EmbeddedPkg/Library/DebugAgentTimerLibNull/DebugAgentTimerLibNull.inf + + # Flattened Device Tree (FDT) access library + FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf + + # USB Libraries + UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf + + # + # Secure Boot dependencies + # +!if $(SECURE_BOOT_ENABLE) == TRUE + TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf + AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf + SecureBootVariableLib|SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf + SecureBootVariableProvisionLib|SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.inf + + # re-use the UserPhysicalPresent() dummy implementation from the ovmf tree + PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf +!else + TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf + AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf +!endif + VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf + VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf + VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf + GpioLib|Silicon/Broadcom/Bcm283x/Library/GpioLib/GpioLib.inf + + # + # PCI dependencies + # + # PCI root port configuation and description + PciHostBridgeLib|Silicon/Broadcom/Bcm27xx/Library/Bcm2711PciHostBridgeLib/Bcm2711PciHostBridgeLib.inf + # The "segment lib" provides the CAM accessors/etc when they aren't ECAM standard + PciSegmentLib|Silicon/Broadcom/Bcm27xx/Library/Bcm2711PciSegmentLib/PciSegmentLib.inf + +[LibraryClasses.common.SEC] + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf + MemoryInitPeiLib|Platform/RaspberryPi/Library/MemoryInitPeiLib/MemoryInitPeiLib.inf + PlatformPeiLib|ArmPlatformPkg/PlatformPei/PlatformPeiLib.inf + ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf + LzmaDecompressLib|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf + PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf + HobLib|EmbeddedPkg/Library/PrePiHobLib/PrePiHobLib.inf + PrePiHobListPointerLib|ArmPlatformPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf + MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf + +[LibraryClasses.common.DXE_CORE] + HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf + MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf + DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf + ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf + PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf + +[LibraryClasses.common.DXE_DRIVER] + SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf + PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf +!if $(INCLUDE_TFTP_COMMAND) == TRUE + ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf + FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf +!endif + +[LibraryClasses.common.UEFI_APPLICATION] + PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf + ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf + FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf + +[LibraryClasses.common.UEFI_DRIVER] + ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf + PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + +[LibraryClasses.common.DXE_RUNTIME_DRIVER] + # Runtime debug messages may crash an OS unless serial output to MMIO mapped UARTs is inhibited + DebugLib|MdePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntimeDebugLibSerialPort.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf + EfiResetSystemLib|Platform/RaspberryPi/Library/ResetLib/ResetLib.inf + ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf + VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf + +!if $(SECURE_BOOT_ENABLE) == TRUE + BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf +!endif + +################################################################################################### +# BuildOptions Section - Define the module specific tool chain flags that should be used as +# the default flags for a module. These flags are appended to any +# standard flags that are defined by the build process. +################################################################################################### + +[BuildOptions] + GCC:*_*_*_CC_FLAGS = -DRPI_MODEL=4 + GCC:*_*_*_PP_FLAGS = -DRPI_MODEL=4 + GCC:*_*_*_ASLPP_FLAGS = -DRPI_MODEL=4 + GCC:*_*_*_ASLCC_FLAGS = -DRPI_MODEL=4 + GCC:*_*_*_VFRPP_FLAGS = -DRPI_MODEL=4 + GCC:RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG -DNDEBUG + +[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER] + GCC:*_*_AARCH64_DLINK_FLAGS = -z common-page-size=0x10000 + +################################################################################ +# +# Pcd Section - list of all EDK II PCD Entries defined by this Platform +# +################################################################################ + +[PcdsFeatureFlag.common] + # Use the Vector Table location in CpuDxe. We will not copy the Vector Table at PcdCpuVectorBaseAddress + gArmTokenSpaceGuid.PcdRelocateVectorTable|FALSE + + gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob|TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport|TRUE + + ## If TRUE, Graphics Output Protocol will be installed on virtual handle created by ConsplitterDxe. + # It could be set FALSE to save size. + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport|FALSE + gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport|FALSE + +[PcdsFixedAtBuild.common] + gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000 + gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|1000000 + gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|1000000 + gEfiMdePkgTokenSpaceGuid.PcdSpinLockTimeout|10000000 + gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue|0xAF + gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|1 + gEfiMdePkgTokenSpaceGuid.PcdPostCodePropertyMask|0 + gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|320 + + # DEBUG_ASSERT_ENABLED 0x01 + # DEBUG_PRINT_ENABLED 0x02 + # DEBUG_CODE_ENABLED 0x04 + # CLEAR_MEMORY_ENABLED 0x08 + # ASSERT_BREAKPOINT_ENABLED 0x10 + # ASSERT_DEADLOOP_ENABLED 0x20 +!if $(TARGET) == RELEASE + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x21 +!else + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2f +!endif + + # DEBUG_INIT 0x00000001 // Initialization + # DEBUG_WARN 0x00000002 // Warnings + # DEBUG_LOAD 0x00000004 // Load events + # DEBUG_FS 0x00000008 // EFI File system + # DEBUG_POOL 0x00000010 // Alloc & Free (pool) + # DEBUG_PAGE 0x00000020 // Alloc & Free (page) + # DEBUG_INFO 0x00000040 // Informational debug messages + # DEBUG_DISPATCH 0x00000080 // PEI/DXE/SMM Dispatchers + # DEBUG_VARIABLE 0x00000100 // Variable + # DEBUG_BM 0x00000400 // Boot Manager + # DEBUG_BLKIO 0x00001000 // BlkIo Driver + # DEBUG_NET 0x00004000 // SNP Driver + # DEBUG_UNDI 0x00010000 // UNDI Driver + # DEBUG_LOADFILE 0x00020000 // LoadFile + # DEBUG_EVENT 0x00080000 // Event messages + # DEBUG_GCD 0x00100000 // Global Coherency Database changes + # DEBUG_CACHE 0x00200000 // Memory range cachability changes + # DEBUG_VERBOSE 0x00400000 // Detailed debug messages that may + # // significantly impact boot performance + # DEBUG_ERROR 0x80000000 // Error + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|$(DEBUG_PRINT_ERROR_LEVEL) + + gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07 + + # + # Optional feature to help prevent EFI memory map fragments + # Turned on and off via: PcdPrePiProduceMemoryTypeInformationHob + # Values are in EFI Pages (4K). DXE Core will make sure that + # at least this much of each type of memory can be allocated + # from a single memory range. This way you only end up with + # maximum of two fragments for each type in the memory map + # (the memory used, and the free memory that was prereserved + # but not used). + # + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory|0 + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS|0 + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType|0 +!if $(SECURE_BOOT_ENABLE) == TRUE + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData|600 + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode|400 + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode|1500 +!else + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData|300 + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode|150 + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode|1000 +!endif + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData|12000 + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode|20 + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData|0 + + gEmbeddedTokenSpaceGuid.PcdDmaDeviceOffset|0xc0000000 + gEmbeddedTokenSpaceGuid.PcdDmaDeviceLimit|0xffffffff + + gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"EDK2-DEV" + +!if $(SECURE_BOOT_ENABLE) == TRUE + # override the default values from SecurityPkg to ensure images from all sources are verified in secure boot + gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x04 + gEfiSecurityPkgTokenSpaceGuid.PcdFixedMediaImageVerificationPolicy|0x04 + gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolicy|0x04 +!endif + + gEfiNetworkPkgTokenSpaceGuid.PcdAllowHttpConnections|TRUE + + # Default platform supported RFC 4646 languages: (American) English + gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLangCodes|"en-US" + +[LibraryClasses.common] + ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf + ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf + ArmPlatformLib|Platform/RaspberryPi/Library/PlatformLib/PlatformLib.inf + TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf + CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf + UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf + BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf + PlatformBootManagerLib|Platform/RaspberryPi/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf + CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf + FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf + AcpiLib|EmbeddedPkg/Library/AcpiLib/AcpiLib.inf + +[LibraryClasses.common.UEFI_DRIVER] + UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf + +################################################################################ +# +# Pcd Section - list of all EDK II PCD Entries defined by this Platform +# +################################################################################ + +[PcdsFeatureFlag.common] + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport|FALSE + gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE + +[PcdsFixedAtBuild.common] + gArmPlatformTokenSpaceGuid.PcdCoreCount|4 + gArmTokenSpaceGuid.PcdVFPEnabled|1 + + gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0x4000 + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000 + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800 + + # Size of the region used by UEFI in permanent memory (Reserved 64MB) + gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize|0x04000000 + # + # 0x00000000 - 0x001F0000 FD (PcdFdBaseAddress, PcdFdSize) + # 0x001F0000 - 0x00200000 DTB (PcdFdtBaseAddress, PcdFdtSize) + # 0x00200000 - ... RAM (PcdSystemMemoryBase, PcdSystemMemorySize) + # + # This matches PcdFvBaseAddress, since everything less is the FD, and + # will be reserved away. + # + gArmTokenSpaceGuid.PcdSystemMemoryBase|0x00200000 + gArmTokenSpaceGuid.PcdSystemMemorySize|0x3fe00000 + + # + # Device specific addresses + # + gBcm27xxTokenSpaceGuid.PcdBcm27xxRegistersAddress|0xfc000000 + gBcm27xxTokenSpaceGuid.PcdBcmGenetRegistersAddress|0xfd580000 + gBcm283xTokenSpaceGuid.PcdBcm283xRegistersAddress|0xfe000000 + + # PCIe specific addresses + gBcm27xxTokenSpaceGuid.PcdBcm27xxPciRegBase|0xfd500000 + gBcm27xxTokenSpaceGuid.PcdBcm27xxPciBusMmioAdr|0xf8000000 + gBcm27xxTokenSpaceGuid.PcdBcm27xxPciBusMmioLen|0x3ffffff + gBcm27xxTokenSpaceGuid.PcdBcm27xxPciCpuMmioAdr|0x600000000 + + # UARTs + gArmPlatformTokenSpaceGuid.PL011UartInteger|0 + gArmPlatformTokenSpaceGuid.PL011UartFractional|0 + gArmPlatformTokenSpaceGuid.PL011UartClkInHz|48000000 + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio|TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride|4 + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialFifoControl|0x27 + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialExtendedTxFifoSize|8 + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|115200 + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultReceiveFifoDepth|0 + + # + # ARM General Interrupt Controller + # + gArmTokenSpaceGuid.PcdGicDistributorBase|0xFF841000 + gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0xFF842000 + gRaspberryPiTokenSpaceGuid.PcdGicInterruptInterfaceHBase|0xFF844000 + gRaspberryPiTokenSpaceGuid.PcdGicInterruptInterfaceVBase|0xFF846000 + gRaspberryPiTokenSpaceGuid.PcdGicGsivId|0x19 + gRaspberryPiTokenSpaceGuid.PcdGicPmuIrq0|0x30 + gRaspberryPiTokenSpaceGuid.PcdGicPmuIrq1|0x31 + gRaspberryPiTokenSpaceGuid.PcdGicPmuIrq2|0x32 + gRaspberryPiTokenSpaceGuid.PcdGicPmuIrq3|0x33 + + # + # Fixed CPU settings. + # + gRaspberryPiTokenSpaceGuid.PcdCpuLowSpeedMHz|800 + gRaspberryPiTokenSpaceGuid.PcdCpuDefSpeedMHz|1500 + gRaspberryPiTokenSpaceGuid.PcdCpuMaxSpeedMHz|2200 + + ## Default Terminal Type + ## 0-PCANSI, 1-VT100, 2-VT00+, 3-UTF8, 4-TTYTERM + gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|4 + + gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE + gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 } + + gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVendor|L"EDK2" + gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|TRUE + +[PcdsPatchableInModule] + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate|500000000 + +[PcdsDynamicHii.common.DEFAULT] + + # + # Clock overrides. + # + + gRaspberryPiTokenSpaceGuid.PcdCpuClock|L"CpuClock"|gConfigDxeFormSetGuid|0x0|1 + gRaspberryPiTokenSpaceGuid.PcdCustomCpuClock|L"CustomCpuClock"|gConfigDxeFormSetGuid|0x0|gRaspberryPiTokenSpaceGuid.PcdCpuDefSpeedMHz + + # + # SD-related. + # + + gRaspberryPiTokenSpaceGuid.PcdSdIsArasan|L"SdIsArasan"|gConfigDxeFormSetGuid|0x0|0 + gRaspberryPiTokenSpaceGuid.PcdMmcForce1Bit|L"MmcForce1Bit"|gConfigDxeFormSetGuid|0x0|0 + gRaspberryPiTokenSpaceGuid.PcdMmcForceDefaultSpeed|L"MmcForceDefaultSpeed"|gConfigDxeFormSetGuid|0x0|0 + gRaspberryPiTokenSpaceGuid.PcdMmcSdDefaultSpeedMHz|L"MmcSdDefaultSpeedMHz"|gConfigDxeFormSetGuid|0x0|25 + gRaspberryPiTokenSpaceGuid.PcdMmcSdHighSpeedMHz|L"MmcSdHighSpeedMHz"|gConfigDxeFormSetGuid|0x0|50 + gRaspberryPiTokenSpaceGuid.PcdMmcDisableMulti|L"MmcDisableMulti"|gConfigDxeFormSetGuid|0x0|0 + gRaspberryPiTokenSpaceGuid.PcdMmcEnableDma|L"MmcEnableDma"|gConfigDxeFormSetGuid|0x0|1 + + # + # Debug-related. + # + + gRaspberryPiTokenSpaceGuid.PcdDebugEnableJTAG|L"DebugEnableJTAG"|gConfigDxeFormSetGuid|0x0|0 + + # + # Display-related. + # + + # + # Just enable native resolution by default. + # + gRaspberryPiTokenSpaceGuid.PcdDisplayEnableScaledVModes|L"DisplayEnableScaledVModes"|gConfigDxeFormSetGuid|0x0|0x20 + gRaspberryPiTokenSpaceGuid.PcdDisplayEnableSShot|L"DisplayEnableSShot"|gConfigDxeFormSetGuid|0x0|1 + + # + # Supporting > 3GB of memory. + # + gRaspberryPiTokenSpaceGuid.PcdRamMoreThan3GB|L"RamMoreThan3GB"|gConfigDxeFormSetGuid|0x0|0 + gRaspberryPiTokenSpaceGuid.PcdRamLimitTo3GB|L"RamLimitTo3GB"|gConfigDxeFormSetGuid|0x0|1 + + # + # Device Tree and ACPI selection. + # + # 0 - SYSTEM_TABLE_MODE_ACPI (default) + # 1 - SYSTEM_TABLE_MODE_BOTH + # 2 - SYSTEM_TABLE_MODE_DT + # + gRaspberryPiTokenSpaceGuid.PcdSystemTableMode|L"SystemTableMode"|gConfigDxeFormSetGuid|0x0|0 + + # + # Enable a fan in the ACPI thermal zone on GPIO pin # + # + # 0 - DISABLED + # 19 - Enabled on pin 19 + # + gRaspberryPiTokenSpaceGuid.PcdFanOnGpio|L"FanOnGpio"|gConfigDxeFormSetGuid|0x0|0 + gRaspberryPiTokenSpaceGuid.PcdFanTemp|L"FanTemp"|gConfigDxeFormSetGuid|0x0|60 + + # + # Reset-related. + # + + gRaspberryPiTokenSpaceGuid.PcdPlatformResetDelay|L"ResetDelay"|gRaspberryPiTokenSpaceGuid|0x0|0 + + # Select XHCI/PCIe mode + # + # 0 - XHCI Enabled (default on !cm4) + # 1 - PCIe Enabled + # 2 - PCIe Enabled (default on cm4) + # + gRaspberryPiTokenSpaceGuid.PcdXhciPci|L"XhciPci"|gConfigDxeFormSetGuid|0x0|0 + + # + # Common UEFI ones. + # + + gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|5 + # + # This is silly, but by pointing SetupConXXX and ConXXX PCDs to + # the same variables, I can use the graphical configuration to + # change the mode used by ConSplitter. + # + gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutColumn|L"Columns"|gRaspberryPiTokenSpaceGuid|0x0|80 + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn|L"Columns"|gRaspberryPiTokenSpaceGuid|0x0|80 + gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutRow|L"Rows"|gRaspberryPiTokenSpaceGuid|0x0|25 + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow|L"Rows"|gRaspberryPiTokenSpaceGuid|0x0|25 + gEfiMdeModulePkgTokenSpaceGuid.PcdBootDiscoveryPolicy|L"BootDiscoveryPolicy"|gBootDiscoveryPolicyMgrFormsetGuid|0 + +[PcdsDynamicDefault.common] + # + # Set video resolution for boot options and for text setup. + # + gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|0 + gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|0 + gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|640 + gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|480 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|0 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0 + + # + # UART in use + # This value will be synchronized with the setting in config.txt + # 0 - PL011_UART_IN_USE + # 1 - MINI_UART_IN_USE + # + gRaspberryPiTokenSpaceGuid.PcdUartInUse|0 + +################################################################################ +# +# Components Section - list of all EDK II Modules needed by this Platform +# +################################################################################ +[Components.common] + # + # PEI Phase modules + # + ArmPlatformPkg/PrePi/PeiUniCore.inf { + <LibraryClasses> + SerialPortLib|Platform/RaspberryPi/Library/DualSerialPortLib/DualSerialPortLib.inf + } + + # + # DXE + # + MdeModulePkg/Core/Dxe/DxeMain.inf { + <LibraryClasses> + NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf + } + MdeModulePkg/Universal/PCD/Dxe/Pcd.inf { + <LibraryClasses> + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + } + + # + # Architectural Protocols + # + ArmPkg/Drivers/CpuDxe/CpuDxe.inf + MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf + Platform/RaspberryPi/Drivers/VarBlockServiceDxe/VarBlockServiceDxe.inf + MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf + MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf { + <LibraryClasses> + NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf + } +!if $(SECURE_BOOT_ENABLE) == TRUE + MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf { + <LibraryClasses> + NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf + } + SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf + SecurityPkg/EnrollFromDefaultKeysApp/EnrollFromDefaultKeysApp.inf + SecurityPkg/VariableAuthenticated/SecureBootDefaultKeysDxe/SecureBootDefaultKeysDxe.inf +!else + MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf +!endif + MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf + MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf + EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf + EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf { + <LibraryClasses> + RealTimeClockLib|EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.inf + } + EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf + + MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf + MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf + MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf + MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf + MdeModulePkg/Universal/SerialDxe/SerialDxe.inf { + <LibraryClasses> + SerialPortLib|Platform/RaspberryPi/Library/DualSerialPortLib/DualSerialPortDxeLib.inf + } + Platform/RaspberryPi/Drivers/DisplayDxe/DisplayDxe.inf + EmbeddedPkg/Drivers/ConsolePrefDxe/ConsolePrefDxe.inf + + MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf + + ArmPkg/Drivers/ArmGic/ArmGicDxe.inf + Platform/RaspberryPi/Drivers/RpiFirmwareDxe/RpiFirmwareDxe.inf + Platform/RaspberryPi/Drivers/FdtDxe/FdtDxe.inf + Platform/RaspberryPi/Drivers/ConfigDxe/ConfigDxe.inf + ArmPkg/Drivers/TimerDxe/TimerDxe.inf + MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf + MdeModulePkg/Universal/EbcDxe/EbcDxe.inf + + # + # FAT filesystem + GPT/MBR partitioning + # + MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf + MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf + MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf + FatPkg/EnhancedFatDxe/Fat.inf + + # + # ACPI Support + # + MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf + MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf + Platform/RaspberryPi/AcpiTables/AcpiTables.inf + + # + # SMBIOS Support + # + Platform/RaspberryPi/Drivers/PlatformSmbiosDxe/PlatformSmbiosDxe.inf + MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf + + # + # RAM Disk Support + # + MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf + + # + # Bds + # + MdeModulePkg/Universal/BootManagerPolicyDxe/BootManagerPolicyDxe.inf + MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf + MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf + MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf + MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf + MdeModulePkg/Universal/BdsDxe/BdsDxe.inf + Platform/RaspberryPi/Drivers/LogoDxe/LogoDxe.inf + MdeModulePkg/Application/UiApp/UiApp.inf { + <LibraryClasses> + NULL|MdeModulePkg/Library/BootDiscoveryPolicyUiLib/BootDiscoveryPolicyUiLib.inf + NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf + NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf + NULL|Platform/RaspberryPi/Library/PlatformUiAppLib/PlatformUiAppLib.inf + NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf + } + + # + # SCSI Bus and Disk Driver + # + MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf + MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf + + # + # USB Support + # + MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf + Platform/RaspberryPi/Drivers/DwUsbHostDxe/DwUsbHostDxe.inf + MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf + MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf + MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf + + # + # SD/MMC support + # + # Platform/RaspberryPi/Drivers/SdHostDxe/SdHostDxe.inf + Platform/RaspberryPi/Drivers/ArasanMmcHostDxe/ArasanMmcHostDxe.inf + Platform/RaspberryPi/Drivers/MmcDxe/MmcDxe.inf + + # + # Networking stack + # +!include NetworkPkg/Network.dsc.inc + Silicon/Broadcom/Drivers/Net/BcmGenetDxe/BcmGenetDxe.inf { + <PcdsFixedAtBuild> + gEmbeddedTokenSpaceGuid.PcdDmaDeviceOffset|0x00000000 + gEmbeddedTokenSpaceGuid.PcdDmaDeviceLimit|0xffffffffff + } + + # + # RNG + # + Silicon/Broadcom/Bcm283x/Drivers/Bcm2838RngDxe/Bcm2838RngDxe.inf + + # + # PCI Support + # + ArmPkg/Drivers/ArmPciCpuIo2Dxe/ArmPciCpuIo2Dxe.inf + MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf + MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf + EmbeddedPkg/Drivers/NonCoherentIoMmuDxe/NonCoherentIoMmuDxe.inf { + <PcdsFixedAtBuild> + gEmbeddedTokenSpaceGuid.PcdDmaDeviceOffset|0x00000000 + gEmbeddedTokenSpaceGuid.PcdDmaDeviceLimit|0xbfffffff + } + + # + # NVMe boot devices + # + MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf + + # + # UEFI application (Shell Embedded Boot Loader) + # + ShellPkg/Application/Shell/Shell.inf { + <LibraryClasses> + ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf + NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf + NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf + NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf + NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf + NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf + NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf + NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf + NULL|ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf + HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf + PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf + BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf + + <PcdsFixedAtBuild> + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF + gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE + gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000 + gEfiShellPkgTokenSpaceGuid.PcdShellFileOperationSize|0x200000 + } +!if $(INCLUDE_TFTP_COMMAND) == TRUE + ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf { + <PcdsFixedAtBuild> + gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE + } +!endif diff --git a/board/raspberrypi/rpi/sdhc.asl b/board/raspberrypi/rpi/sdhc.asl new file mode 100644 index 00000000000..4e1f280a03e --- /dev/null +++ b/board/raspberrypi/rpi/sdhc.asl @@ -0,0 +1,119 @@ +/** @file + * + * [DSDT] SD controller/card definition (SDHC) + * + * Copyright (c) 2020, Pete Batard pete@akeo.ie + * Copyright (c) 2018, Andrey Warkentin andrey.warkentin@gmail.com + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-2-Clause-Patent + * + **/ + +#include <asm/arch/acpi/bcm2836_sdhost.h> +#include <asm/arch/acpi/bcm2836_sdio.h> + +#include "acpitables.h" + +// +// Note: UEFI can use either SDHost or Arasan. We expose both to the OS. +// + +// ArasanSD 3.0 SD Host Controller. (brcm,bcm2835-sdhci) +Device (SDC1) +{ + Name (_HID, "BCM2847") + Name (_CID, "BCM2847") + Name (_UID, 0x0) + Name (_CCA, 0x0) + Name (_S1D, 0x1) + Name (_S2D, 0x1) + Name (_S3D, 0x1) + Name (_S4D, 0x1) + Method (_STA) + { + Return(0xf) + } + Name (RBUF, ResourceTemplate () + { + MEMORY32FIXED (ReadWrite, 0, MMCHS1_LENGTH, RMEM) + Interrupt (ResourceConsumer, Level, ActiveHigh, Shared) { BCM2836_MMCHS1_INTERRUPT } + }) + Method (_CRS, 0x0, Serialized) + { + MEMORY32SETBASE (RBUF, RMEM, RBAS, MMCHS1_OFFSET) + Return (^RBUF) + } + + // The standard CAPs registers on this controller + // appear to be 0, lets set some minimal defaults + // Since this cap doesn't indicate DMA capability + // we don't need a _DMA() + Name (_DSD, Package () { + ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + Package () { + Package () { "sdhci-caps", 0x0120fa81 }, + } + }) + + // + // A child device that represents the + // sd card, which is marked as non-removable. + // + Device (SDMM) + { + Method (_ADR) + { + Return (0) + } + Method (_RMV) // Is removable + { + Return (0) // 0 - fixed + } + } +} + +#if (RPI_MODEL < 4) +// Broadcom SDHost 2.0 SD Host Controller +Device (SDC2) +{ + Name (_HID, "BCM2855") + Name (_CID, "BCM2855") + Name (_UID, 0x0) + Name (_CCA, 0x0) + Name (_S1D, 0x1) + Name (_S2D, 0x1) + Name (_S3D, 0x1) + Name (_S4D, 0x1) + Method (_STA) + { + Return (0xf) + } + Name (RBUF, ResourceTemplate () + { + MEMORY32FIXED (ReadWrite, 0, SDHOST_LENGTH, RMEM) + Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_SDHOST_INTERRUPT } + }) + Method (_CRS, 0x0, Serialized) + { + MEMORY32SETBASE (RBUF, RMEM, RBAS, SDHOST_OFFSET) + Return (^RBUF) + } + + // + // A child device that represents the + // sd card, which is marked as non-removable. + // + Device (SDMM) + { + Method (_ADR) + { + Return (0) + } + Method (_RMV) // Is removable + { + Return (0) // 0 - fixed + } + } +} +#endif // !RPI4 diff --git a/board/raspberrypi/rpi/spcrminiuart.aslc b/board/raspberrypi/rpi/spcrminiuart.aslc new file mode 100644 index 00000000000..4823cab2681 --- /dev/null +++ b/board/raspberrypi/rpi/spcrminiuart.aslc @@ -0,0 +1,91 @@ +/** @file +* SPCR Table +* +* Copyright (c) 2019 Pete Batard pete@akeo.ie +* Copyright (c) 2014-2021, ARM Limited. All rights reserved. +* +* SPDX-License-Identifier: BSD-2-Clause-Patent +* +**/ + +#include <IndustryStandard/Acpi.h> +#include <IndustryStandard/Bcm2836.h> +#include <IndustryStandard/SerialPortConsoleRedirectionTable.h> +#include <Library/AcpiLib.h> +#include <Library/PcdLib.h> + +#include "AcpiTables.h" + +#define RPI_UART_FLOW_CONTROL_NONE 0 + +#define RPI_UART_INTERFACE_TYPE EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERFACE_TYPE_BCM2835_UART +#define RPI_UART_BASE_ADDRESS BCM2836_MINI_UART_BASE_ADDRESS +#define RPI_UART_INTERRUPT BCM2836_MINI_UART_INTERRUPT + +STATIC EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE Spcr = { + ACPI_HEADER ( + EFI_ACPI_6_3_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE, + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE, + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_REVISION + ), + // UINT8 InterfaceType; + RPI_UART_INTERFACE_TYPE, + // UINT8 Reserved1[3]; + { + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE + }, + // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE BaseAddress; + ARM_GAS32 (RPI_UART_BASE_ADDRESS), + // UINT8 InterruptType; + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERRUPT_TYPE_GIC, + // UINT8 Irq; + 0, // Not used on ARM + // UINT32 GlobalSystemInterrupt; + RPI_UART_INTERRUPT, + // UINT8 BaudRate; +#if (FixedPcdGet64 (PcdUartDefaultBaudRate) == 9600) + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_9600, +#elif (FixedPcdGet64 (PcdUartDefaultBaudRate) == 19200) + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_19200, +#elif (FixedPcdGet64 (PcdUartDefaultBaudRate) == 57600) + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_57600, +#elif (FixedPcdGet64 (PcdUartDefaultBaudRate) == 115200) + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_115200, +#else +#error Unsupported SPCR Baud Rate +#endif + // UINT8 Parity; + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_PARITY_NO_PARITY, + // UINT8 StopBits; + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_STOP_BITS_1, + // UINT8 FlowControl; + RPI_UART_FLOW_CONTROL_NONE, + // UINT8 TerminalType; + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_TERMINAL_TYPE_VT_UTF8, + // UINT8 Reserved2; + EFI_ACPI_RESERVED_BYTE, + // UINT16 PciDeviceId; + 0xFFFF, + // UINT16 PciVendorId; + 0xFFFF, + // UINT8 PciBusNumber; + 0x00, + // UINT8 PciDeviceNumber; + 0x00, + // UINT8 PciFunctionNumber; + 0x00, + // UINT32 PciFlags; + 0x00000000, + // UINT8 PciSegment; + 0x00, + // UINT32 Reserved3; + EFI_ACPI_RESERVED_DWORD +}; + +// +// Reference the table being generated to prevent the optimizer from removing the +// data structure from the executable +// +VOID* CONST ReferenceAcpiTable = &Spcr; diff --git a/board/raspberrypi/rpi/spcrpl011.aslc b/board/raspberrypi/rpi/spcrpl011.aslc new file mode 100644 index 00000000000..5a540adf083 --- /dev/null +++ b/board/raspberrypi/rpi/spcrpl011.aslc @@ -0,0 +1,91 @@ +/** @file +* SPCR Table +* +* Copyright (c) 2019 Pete Batard pete@akeo.ie +* Copyright (c) 2014-2021, ARM Limited. All rights reserved. +* +* SPDX-License-Identifier: BSD-2-Clause-Patent +* +**/ + +#include <IndustryStandard/Acpi.h> +#include <IndustryStandard/Bcm2836.h> +#include <IndustryStandard/SerialPortConsoleRedirectionTable.h> +#include <Library/AcpiLib.h> +#include <Library/PcdLib.h> + +#include "AcpiTables.h" + +#define RPI_UART_FLOW_CONTROL_NONE 0 + +#define RPI_UART_INTERFACE_TYPE EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERFACE_TYPE_ARM_PL011_UART +#define RPI_UART_BASE_ADDRESS BCM2836_PL011_UART_BASE_ADDRESS +#define RPI_UART_INTERRUPT BCM2836_PL011_UART_INTERRUPT + +STATIC EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE Spcr = { + ACPI_HEADER ( + EFI_ACPI_6_3_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE, + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE, + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_REVISION + ), + // UINT8 InterfaceType; + RPI_UART_INTERFACE_TYPE, + // UINT8 Reserved1[3]; + { + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE, + EFI_ACPI_RESERVED_BYTE + }, + // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE BaseAddress; + ARM_GAS32 (RPI_UART_BASE_ADDRESS), + // UINT8 InterruptType; + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERRUPT_TYPE_GIC, + // UINT8 Irq; + 0, // Not used on ARM + // UINT32 GlobalSystemInterrupt; + RPI_UART_INTERRUPT, + // UINT8 BaudRate; +#if (FixedPcdGet64 (PcdUartDefaultBaudRate) == 9600) + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_9600, +#elif (FixedPcdGet64 (PcdUartDefaultBaudRate) == 19200) + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_19200, +#elif (FixedPcdGet64 (PcdUartDefaultBaudRate) == 57600) + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_57600, +#elif (FixedPcdGet64 (PcdUartDefaultBaudRate) == 115200) + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_115200, +#else +#error Unsupported SPCR Baud Rate +#endif + // UINT8 Parity; + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_PARITY_NO_PARITY, + // UINT8 StopBits; + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_STOP_BITS_1, + // UINT8 FlowControl; + RPI_UART_FLOW_CONTROL_NONE, + // UINT8 TerminalType; + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_TERMINAL_TYPE_VT_UTF8, + // UINT8 Reserved2; + EFI_ACPI_RESERVED_BYTE, + // UINT16 PciDeviceId; + 0xFFFF, + // UINT16 PciVendorId; + 0xFFFF, + // UINT8 PciBusNumber; + 0x00, + // UINT8 PciDeviceNumber; + 0x00, + // UINT8 PciFunctionNumber; + 0x00, + // UINT32 PciFlags; + 0x00000000, + // UINT8 PciSegment; + 0x00, + // UINT32 Reserved3; + EFI_ACPI_RESERVED_DWORD +}; + +// +// Reference the table being generated to prevent the optimizer from removing the +// data structure from the executable +// +VOID* CONST ReferenceAcpiTable = &Spcr; diff --git a/board/raspberrypi/rpi/ssdtthermal.asl b/board/raspberrypi/rpi/ssdtthermal.asl new file mode 100644 index 00000000000..5a20ee1d9f7 --- /dev/null +++ b/board/raspberrypi/rpi/ssdtthermal.asl @@ -0,0 +1,77 @@ +/** @file + * + * Secondary System Description Table (SSDT) for active (fan) cooling + * + * Copyright (c) 2020, Arm Ltd. All rights reserved. + * + * SPDX-License-Identifier: BSD-2-Clause-Patent + * + **/ + +#include <asm/arch/acpi/bcm2711.h> +#include <asm/arch/acpi/bcm2836.h> +#include <asm/arch/acpi/bcm2836_gpio.h> + +#include <asm/arch/acpi/acpi.h> + +DefinitionBlock (__FILE__, "SSDT", 2, "RPIFDN", "RPITHFAN", 2) +{ + External (_SB_.EC00, DeviceObj) + External (_SB_.EC00.TZ00, DeviceObj) + + Scope (_SB_.EC00) + { + // Define a NameOp we will modify during InstallTable + Name (GIOP, 0x2) //08 47 49 4f 50 0a 02 (value must be >1) + Name (FTMP, 0x2) + // Describe a fan + PowerResource (PFAN, 0, 0) { + OperationRegion (GPIO, SystemMemory, GPIO_BASE_ADDRESS, 0x1000) + Field (GPIO, DWordAcc, NoLock, Preserve) { + Offset (0x1C), + GPS0, 32, + GPS1, 32, + RES1, 32, + GPC0, 32, + GPC1, 32, + RES2, 32, + GPL1, 32, + GPL2, 32 + } + // We are hitting a GPIO pin to on/off a fan. + // This assumes that UEFI has programmed the + // direction as OUT. Given the current limitations + // on the GPIO pins, its recommended to use + // the GPIO to switch a larger voltage/current + // for the fan rather than driving it directly. + Method (_STA) { + if (GPL1 & (1 << GIOP)) { + Return (1) // present and enabled + } + Return (0) + } + Method (_ON) { // turn fan on + Store (1 << GIOP, GPS0) + } + Method (_OFF) { // turn fan off + Store (1 << GIOP, GPC0) + } + } + Device (FAN0) { + // Note, not currently an ACPIv4 fan + // the latter adds speed control/detection + // but in the case of linux needs FIF, FPS, FSL, and FST + Name (_HID, EISAID ("PNP0C0B")) + Name (_PR0, Package () { PFAN }) + } + } + + // merge in an active cooling point. + Scope (_SB_.EC00.TZ00) + { + Method (_AC0) { Return ( (FTMP * 10) + 2732) } // (60C) active cooling trip point, + // if this is lower than PSV then we + // prefer active cooling + Name (_AL0, Package () { _SB_.EC00.FAN0 }) // the fan used for AC0 above + } +} diff --git a/board/raspberrypi/rpi/uart.asl b/board/raspberrypi/rpi/uart.asl new file mode 100644 index 00000000000..9cca1a5c27d --- /dev/null +++ b/board/raspberrypi/rpi/uart.asl @@ -0,0 +1,202 @@ +/** @file + * + * [DSDT] Serial devices (UART). + * + * Copyright (c) 2021, ARM Limited. All rights reserved. + * Copyright (c) 2020, Pete Batard pete@akeo.ie + * Copyright (c) 2018, Andrey Warkentin andrey.warkentin@gmail.com + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-2-Clause-Patent + * + **/ + +#include <asm/arch/acpi/bcm2836.h> + +#include "acpitables.h" + +// PL011 based UART. +Device (URT0) +{ + Name (_HID, "BCM2837") + Name (_CID, "ARMH0011") + Name (_UID, 0x4) + Name (_CCA, 0x0) + Method (_STA) + { + Return (0xf) + } + Name (RBUF, ResourceTemplate () + { + MEMORY32FIXED (ReadWrite, 0, BCM2836_PL011_UART_LENGTH, RMEM) + Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_PL011_UART_INTERRUPT } + }) + Method (_CRS, 0x0, Serialized) + { + MEMORY32SETBASE (RBUF, RMEM, RBAS, BCM2836_PL011_UART_OFFSET) + Return (^RBUF) + } + + Name (CLCK, 48000000) + + Name (_DSD, Package () + { + ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), Package () + { + Package (2) { "clock-frequency", CLCK }, + } + }) +} + +// +// UART Mini. +// +// This device is referenced in the DBG2 table, which will cause the system to +// not start the driver when the debugger is enabled and to mark the device +// with problem code 53 (CM_PROB_USED_BY_DEBUGGER). +// + +Device (URTM) +{ + Name (_HID, "BCM2836") + Name (_CID, "BCM2836") + Name (_UID, 0x0) + Name (_CCA, 0x0) + Method (_STA) + { + Return (0xf) + } + Name (RBUF, ResourceTemplate () + { + MEMORY32FIXED (ReadWrite, 0, BCM2836_MINI_UART_LENGTH, RMEM) + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared) { BCM2836_MINI_UART_INTERRUPT } + + }) + Method (_CRS, 0x0, Serialized) + { + MEMORY32SETBASE (RBUF, RMEM, RBAS, BCM2836_MINI_UART_OFFSET) + Return (^RBUF) + } +} + +// +// Multifunction serial bus device to support Bluetooth function. +// +Device(BTH0) +{ + Name (_HID, "BCM2EA6") + Name (_CID, "BCM2EA6") + + // + // UART In Use will be dynamically updated during boot + // 0x55 0x52 0x49 0x55 0xA 0x2 (Value must > 1) + // + Name (URIU, 0x2) + + Method (_STA) + { + Return (0xf) + } + + // + // Resource for URT0 (PL011) + // + Name (BTPL, ResourceTemplate () + { + UARTSerialBus( + 115200, // InitialBaudRate: in BPS + , // BitsPerByte: default to 8 bits + , // StopBits: Defaults to one bit + 0x00, // LinesInUse: 8 1-bit flags to + // declare enabled control lines. + // Raspberry Pi does not exposed + // HW control signals -> not supported. + // Optional bits: + // - Bit 7 (0x80) Request To Send (RTS) + // - Bit 6 (0x40) Clear To Send (CTS) + // - Bit 5 (0x20) Data Terminal Ready (DTR) + // - Bit 4 (0x10) Data Set Ready (DSR) + // - Bit 3 (0x08) Ring Indicator (RI) + // - Bit 2 (0x04) Data Carrier Detect (DTD) + // - Bit 1 (0x02) Reserved. Must be 0. + // - Bit 0 (0x01) Reserved. Must be 0. + , // IsBigEndian: + // default to LittleEndian. + , // Parity: Defaults to no parity + , // FlowControl: Defaults to + // no flow control. + 16, // ReceiveBufferSize + 16, // TransmitBufferSize + "\_SB.GDV0.URT0", // ResourceSource: + // UART bus controller name + , // ResourceSourceIndex: assumed to be 0 + , // ResourceUsage: assumed to be + // ResourceConsumer + UAR0, // DescriptorName: creates name + // for offset of resource descriptor + ) // Vendor data + }) + + // + // Resource for URTM (miniUART) + // + Name (BTMN, ResourceTemplate () + { + // + // BT UART: ResourceSource will be dynamically updated to + // either URT0 (PL011) or URTM (miniUART) during boot + // + UARTSerialBus( + 115200, // InitialBaudRate: in BPS + , // BitsPerByte: default to 8 bits + , // StopBits: Defaults to one bit + 0x00, // LinesInUse: 8 1-bit flags to + // declare enabled control lines. + // Raspberry Pi does not exposed + // HW control signals -> not supported. + // Optional bits: + // - Bit 7 (0x80) Request To Send (RTS) + // - Bit 6 (0x40) Clear To Send (CTS) + // - Bit 5 (0x20) Data Terminal Ready (DTR) + // - Bit 4 (0x10) Data Set Ready (DSR) + // - Bit 3 (0x08) Ring Indicator (RI) + // - Bit 2 (0x04) Data Carrier Detect (DTD) + // - Bit 1 (0x02) Reserved. Must be 0. + // - Bit 0 (0x01) Reserved. Must be 0. + , // IsBigEndian: + // default to LittleEndian. + , // Parity: Defaults to no parity + , // FlowControl: Defaults to + // no flow control. + 16, // ReceiveBufferSize + 16, // TransmitBufferSize + "\_SB.GDV0.URTM", // ResourceSource: + // UART bus controller name + , // ResourceSourceIndex: assumed to be 0 + , // ResourceUsage: assumed to be + // ResourceConsumer + UARM, // DescriptorName: creates name + // for offset of resource descriptor + ) // Vendor data + }) + + Method (_CRS, 0x0, Serialized) + { + if (URIU == 0) + { + // + // PL011 UART is configured for console output + // Return Mini UART for Bluetooth + // + return (^BTMN) + } + else + { + // + // Mini UART is configured for console output + // Return PL011 UART for Bluetooth + // + return (^BTPL) + } + } +} diff --git a/board/raspberrypi/rpi/xhci.asl b/board/raspberrypi/rpi/xhci.asl new file mode 100644 index 00000000000..d6b92da5c09 --- /dev/null +++ b/board/raspberrypi/rpi/xhci.asl @@ -0,0 +1,165 @@ +/** @file + * + * Copyright (c) 2019 Linaro, Limited. All rights reserved. + * Copyright (c) 2019 Andrei Warkentin andrey.warkentin@gmail.com + * + * SPDX-License-Identifier: BSD-2-Clause-Patent + * + **/ + +#include <asm/arch/acpi/Bcm2711.h> + +#include "acpitables.h" + +/* + * The following can be used to remove parenthesis from + * defined macros that the compiler complains about. + */ +#define ISOLATE_ARGS(...) __VA_ARGS__ +#define REMOVE_PARENTHESES(x) ISOLATE_ARGS x + +#define SANITIZED_PCIE_CPU_MMIO_WINDOW REMOVE_PARENTHESES(PCIE_CPU_MMIO_WINDOW) +#define SANITIZED_PCIE_REG_BASE REMOVE_PARENTHESES(PCIE_REG_BASE) + +/* + * According to UEFI boot log for the VLI device on Pi 4. + */ +#define XHCI_REG_LENGTH 0x1000 + +DefinitionBlock (__FILE__, "SSDT", 5, "RPIFDN", "RPI4XHCI", 2) +{ + Scope (_SB_) + { + + Device (SCB0) { + Name (_HID, "ACPI0004") + Name (_UID, 0x0) + Name (_CCA, 0x0) + + Method (_CRS, 0, Serialized) { // _CRS: Current Resource Settings + /* + * Container devices with _DMA must have _CRS, meaning SCB0 + * to provide all resources that XHC0 consumes (except + * interrupts). + */ + Name (RBUF, ResourceTemplate () { + QWordMemory (ResourceProducer, + , + MinFixed, + MaxFixed, + NonCacheable, + ReadWrite, + 0x0, + SANITIZED_PCIE_CPU_MMIO_WINDOW, // MIN + SANITIZED_PCIE_CPU_MMIO_WINDOW, // MAX + 0x0, + 0x1, // LEN + , + , + MMIO + ) + }) + CreateQwordField (RBUF, MMIO._MAX, MMBE) + CreateQwordField (RBUF, MMIO._LEN, MMLE) + Add (MMBE, XHCI_REG_LENGTH - 1, MMBE) + Add (MMLE, XHCI_REG_LENGTH - 1, MMLE) + Return (RBUF) + } + + Name (_DMA, ResourceTemplate() { + /* + * XHC0 is limited to DMA to first 3GB. Note this + * only applies to PCIe, not GENET or other devices + * next to the A72. + */ + QWordMemory (ResourceProducer, + , + MinFixed, + MaxFixed, + NonCacheable, + ReadWrite, + 0x0, + 0x0, // MIN + 0xbfffffff, // MAX + 0x0, // TRA + 0xc0000000, // LEN + , + , + ) + }) + + Device (XHC0) + { + Name (_HID, "PNP0D10") // _HID: Hardware ID + Name (_UID, 0x0) // _UID: Unique ID + Name (_CCA, 0x0) // _CCA: Cache Coherency Attribute + + Method (_CRS, 0, Serialized) { // _CRS: Current Resource Settings + Name (RBUF, ResourceTemplate () { + QWordMemory (ResourceConsumer, + , + MinFixed, + MaxFixed, + NonCacheable, + ReadWrite, + 0x0, + SANITIZED_PCIE_CPU_MMIO_WINDOW, // MIN + SANITIZED_PCIE_CPU_MMIO_WINDOW, // MAX + 0x0, + 0x1, // LEN + , + , + MMIO + ) + Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive, ,, ) { + 175 + } + }) + CreateQwordField (RBUF, MMIO._MAX, MMBE) + CreateQwordField (RBUF, MMIO._LEN, MMLE) + Add (MMBE, XHCI_REG_LENGTH - 1, MMBE) + Add (MMLE, XHCI_REG_LENGTH - 1, MMLE) + Return (RBUF) + } + + Method (_INI, 0, Serialized) { + OperationRegion (PCFG, SystemMemory, SANITIZED_PCIE_REG_BASE + PCIE_EXT_CFG_DATA, 0x1000) + Field (PCFG, AnyAcc, NoLock, Preserve) { + VNID, 16, // Vendor ID + DVID, 16, // Device ID + CMND, 16, // Command register + STAT, 16, // Status register + } + + // Set command register to: + // 1) decode MMIO (set bit 1) + // 2) enable DMA (set bit 2) + // 3) enable interrupts (clear bit 10) + Debug = "xHCI enable" + Store (0x6, CMND) + } + + /* + * Microsoft's USB Device-Specific Methods. See: + * https://docs.microsoft.com/en-us/windows-hardware/drivers/bringup/usb-device... + */ + Name (DSMU, ToUUID ("ce2ee385-00e6-48cb-9f05-2edb927c4899")) + + Method (_DSM, 4, Serialized) { + If (LEqual (Arg0, DSMU)) { // USB capabilities UUID + Switch (ToInteger (Arg2)) { + Case (0) { // Function 0: List of supported functions + Return (Buffer () { 0x41 }) // 0x41 - Functions 0 and 6 supported + } + Case (6) { // Function 6: RegisterAccessType + Return (Buffer () { 0x01 }) // 0x01 - Must use 32bit register access + } + Default { } // Unsupported + } + } + return (Buffer () { 0x00 }) // Return 0x00 for anything unsupported + } + } // end XHC0 + } //end SCB0 + } //end scope sb +} //end definition block

These header files presumably duplicate things already in the U-Boot devicetree. For now, bring them in to get the ASL code to build.
This needs to be sorted out.
Signed-off-by: Simon Glass sjg@chromium.org ---
.../mach-bcm283x/include/mach/acpi/bcm2711.h | 93 ++++++++ .../mach-bcm283x/include/mach/acpi/bcm2836.h | 124 +++++++++++ .../include/mach/acpi/bcm2836_gpio.h | 85 ++++++++ .../include/mach/acpi/bcm2836_gpu.h | 48 +++++ .../include/mach/acpi/bcm2836_pwm.h | 34 +++ .../include/mach/acpi/bcm2836_sdhost.h | 90 ++++++++ .../include/mach/acpi/bcm2836_sdio.h | 203 ++++++++++++++++++ 7 files changed, 677 insertions(+) create mode 100644 arch/arm/mach-bcm283x/include/mach/acpi/bcm2711.h create mode 100644 arch/arm/mach-bcm283x/include/mach/acpi/bcm2836.h create mode 100644 arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_gpio.h create mode 100644 arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_gpu.h create mode 100644 arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_pwm.h create mode 100644 arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_sdhost.h create mode 100644 arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_sdio.h
diff --git a/arch/arm/mach-bcm283x/include/mach/acpi/bcm2711.h b/arch/arm/mach-bcm283x/include/mach/acpi/bcm2711.h new file mode 100644 index 00000000000..dd0874280ef --- /dev/null +++ b/arch/arm/mach-bcm283x/include/mach/acpi/bcm2711.h @@ -0,0 +1,93 @@ +/** @file + * + * Copyright (c) 2019, Jeremy Linton + * Copyright (c) 2019, Pete Batard pete@akeo.ie. + * + * SPDX-License-Identifier: BSD-2-Clause-Patent + * + **/ + +#ifndef BCM2711_H__ +#define BCM2711_H__ + +#define BCM2711_SOC_REGISTERS (FixedPcdGet64 (PcdBcm27xxRegistersAddress)) +#define BCM2711_SOC_REGISTER_LENGTH 0x02000000 + +/* Generic PCI addresses */ +#define PCIE_TOP_OF_MEM_WIN (FixedPcdGet64 (PcdBcm27xxPciBusMmioAdr)) +#define PCIE_CPU_MMIO_WINDOW (FixedPcdGet64 (PcdBcm27xxPciCpuMmioAdr)) +#define PCIE_BRIDGE_MMIO_LEN (FixedPcdGet32 (PcdBcm27xxPciBusMmioLen)) + +/* PCI root bridge control registers location */ +#define PCIE_REG_BASE (FixedPcdGet32 (PcdBcm27xxPciRegBase)) +#define PCIE_REG_LIMIT 0x9310 + +/* PCI root bridge control registers */ +#define BRCM_PCIE_CAP_REGS 0x00ac /* Offset to ecam like range for root port */ +#define PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1 0x0188 +#define BRCM_PCIE_CLASS 0x043c +#define PCIE_MISC_MISC_CTRL 0x4008 +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO 0x400c +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI 0x4010 +#define PCIE_MISC_RC_BAR1_CONFIG_LO 0x402c +#define PCIE_MISC_RC_BAR2_CONFIG_LO 0x4034 +#define PCIE_MISC_RC_BAR2_CONFIG_HI 0x4038 +#define PCIE_MISC_RC_BAR3_CONFIG_LO 0x403c +#define PCIE_MISC_PCIE_STATUS 0x4068 +#define PCIE_MISC_REVISION 0x406c +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT 0x4070 +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI 0x4080 +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI 0x4084 +#define PCIE_MISC_HARD_PCIE_HARD_DEBUG 0x4204 + +#define PCIE_INTR2_CPU_STATUS 0x4300 +#define PCIE_INTR2_CPU_SET 0x4304 +#define PCIE_INTR2_CPU_CLR 0x4308 +#define PCIE_INTR2_CPU_MASK_STATUS 0x430c +#define PCIE_INTR2_CPU_MASK_SET 0x4310 +#define PCIE_INTR2_CPU_MASK_CLR 0x4314 + +#define PCIE_RGR1_SW_INIT_1 0x9210 +#define PCIE_EXT_CFG_INDEX 0x9000 +/* A small window pointing at the ECAM of the device selected by CFG_INDEX */ +#define PCIE_EXT_CFG_DATA 0x8000 + +#define PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_MASK 0xc +#define PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK 0xffffff + +#define PCIE_MISC_MISC_CTRL_SCB_ACCESS_EN_MASK 0x1000 +#define PCIE_MISC_MISC_CTRL_CFG_READ_UR_MODE_MASK 0x2000 +#define PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_MASK 0x300000 +#define PCIE_MISC_MISC_CTRL_SCB0_SIZE_MASK 0xf8000000 +#define PCIE_MISC_MISC_CTRL_SCB1_SIZE_MASK 0x7c00000 +#define PCIE_MISC_MISC_CTRL_SCB2_SIZE_MASK 0x1f +#define PCIE_MISC_RC_BAR2_CONFIG_LO_SIZE_MASK 0x1f + +#define PCIE_RGR1_SW_INIT_1_INIT_MASK 0x2 +#define PCIE_RGR1_SW_INIT_1_PERST_MASK 0x1 + +#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK 0x08000000 + +#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK 0x2 + +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_MASK 0xfff00000 +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_MASK 0xfff0 +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI_BASE_MASK 0xff +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI_LIMIT_MASK 0xff +#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_MASK_BITS 0xc + + +#define PCIE_MISC_REVISION_MAJMIN_MASK 0xffff + +#define BURST_SIZE_128 0 +#define BURST_SIZE_256 1 +#define BURST_SIZE_512 2 + +#define GENET_BASE_ADDRESS FixedPcdGet64 (PcdBcmGenetRegistersAddress) +#define GENET_LENGTH 0x00010000 + +#define THERM_SENSOR 0xfd5d2200 + +#define ID_CHIPREV 0xfc404000 + +#endif /* BCM2711_H__ */ diff --git a/arch/arm/mach-bcm283x/include/mach/acpi/bcm2836.h b/arch/arm/mach-bcm283x/include/mach/acpi/bcm2836.h new file mode 100644 index 00000000000..db0fe0262a6 --- /dev/null +++ b/arch/arm/mach-bcm283x/include/mach/acpi/bcm2836.h @@ -0,0 +1,124 @@ +/** @file + * + * Copyright (c) 2019, ARM Limited. All rights reserved. + * Copyright (c) 2017, Andrei Warkentin andrey.warkentin@gmail.com + * Copyright (c) 2016, Linaro Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-2-Clause-Patent + * + **/ + +#ifndef __BCM2836_H__ +#define __BCM2836_H__ + +/* + * Both "core" and SoC perpherals (1M each). + */ +#define BCM2836_SOC_REGISTERS (FixedPcdGet64 (PcdBcm283xRegistersAddress)) +#define BCM2836_SOC_REGISTER_LENGTH 0x02000000 + +/* + * Offset between the CPU's view and the VC's view of system memory. + */ +#define BCM2836_DMA_DEVICE_OFFSET 0xc0000000 + +/* watchdog constants */ +#define BCM2836_WDOG_OFFSET 0x00100000 +#define BCM2836_WDOG_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_WDOG_OFFSET) +#define BCM2836_WDOG_PASSWORD 0x5a000000 +#define BCM2836_WDOG_RSTC_OFFSET 0x0000001c +#define BCM2836_WDOG_WDOG_OFFSET 0x00000024 +#define BCM2836_WDOG_RSTC_WRCFG_MASK 0x00000030 +#define BCM2836_WDOG_RSTC_WRCFG_FULL_RESET 0x00000020 + +/* clock manager constants */ +#define BCM2836_CM_OFFSET 0x00101000 +#define BCM2836_CM_BASE (BCM2836_SOC_REGISTERS + BCM2836_CM_OFFSET) +#define BCM2836_CM_GEN_CLOCK_CONTROL 0x0000 +#define BCM2836_CM_GEN_CLOCK_DIVISOR 0x0004 +#define BCM2836_CM_VPU_CLOCK_CONTROL 0x0008 +#define BCM2836_CM_VPU_CLOCK_DIVISOR 0x000c +#define BCM2836_CM_SYSTEM_CLOCK_CONTROL 0x0010 +#define BCM2836_CM_SYSTEM_CLOCK_DIVISOR 0x0014 +#define BCM2836_CM_H264_CLOCK_CONTROL 0x0028 +#define BCM2836_CM_H264_CLOCK_DIVISOR 0x002c +#define BCM2836_CM_PWM_CLOCK_CONTROL 0x00a0 +#define BCM2836_CM_PWM_CLOCK_DIVISOR 0x00a4 +#define BCM2836_CM_UART_CLOCK_CONTROL 0x00f0 +#define BCM2836_CM_UART_CLOCK_DIVISOR 0x00f4 +#define BCM2836_CM_SDC_CLOCK_CONTROL 0x01a8 +#define BCM2836_CM_SDC_CLOCK_DIVISOR 0x01ac +#define BCM2836_CM_ARM_CLOCK_CONTROL 0x01b0 +#define BCM2836_CM_ARM_CLOCK_DIVISOR 0x01b4 +#define BCM2836_CM_EMMC_CLOCK_CONTROL 0x01c0 +#define BCM2836_CM_EMMC_CLOCK_DIVISOR 0x01c4 + +/* mailbox interface constants */ +#define BCM2836_MBOX_OFFSET 0x0000b880 +#define BCM2836_MBOX_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_MBOX_OFFSET) +#define BCM2836_MBOX_LENGTH 0x00000024 +#define BCM2836_MBOX_READ_OFFSET 0x00000000 +#define BCM2836_MBOX_STATUS_OFFSET 0x00000018 +#define BCM2836_MBOX_CONFIG_OFFSET 0x0000001c +#define BCM2836_MBOX_WRITE_OFFSET 0x00000020 + +#define BCM2836_MBOX_STATUS_FULL 0x1f +#define BCM2836_MBOX_STATUS_EMPTY 0x1e + +#define BCM2836_MBOX_NUM_CHANNELS 16 + +/* interrupt controller constants */ +#define BCM2836_INTC_TIMER_CONTROL_OFFSET 0x00000040 +#define BCM2836_INTC_TIMER_PENDING_OFFSET 0x00000060 + +/* usb constants */ +#define BCM2836_USB_OFFSET 0x00980000 +#define BCM2836_USB_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_USB_OFFSET) +#define BCM2836_USB_LENGTH 0x00010000 + +/* serial based protocol constants */ +#define BCM2836_PL011_UART_OFFSET 0x00201000 +#define BCM2836_PL011_UART_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_PL011_UART_OFFSET) +#define BCM2836_PL011_UART_LENGTH 0x00001000 + +#define BCM2836_MINI_UART_OFFSET 0x00215000 +#define BCM2836_MINI_UART_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_MINI_UART_OFFSET) +#define BCM2836_MINI_UART_LENGTH 0x00000070 + +#define BCM2836_I2C0_OFFSET 0x00205000 +#define BCM2836_I2C0_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_I2C0_OFFSET) +#define BCM2836_I2C0_LENGTH 0x00000020 + +#define BCM2836_I2C1_OFFSET 0x00804000 +#define BCM2836_I2C1_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_I2C1_OFFSET) +#define BCM2836_I2C1_LENGTH 0x00000020 + +#define BCM2836_I2C2_OFFSET 0x00805000 +#define BCM2836_I2C2_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_I2C2_OFFSET) +#define BCM2836_I2C2_LENGTH 0x00000020 + +#define BCM2836_SPI0_OFFSET 0x00204000 +#define BCM2836_SPI0_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_SPI0_OFFSET) +#define BCM2836_SPI0_LENGTH 0x00000020 + +#define BCM2836_SPI1_OFFSET 0x00215080 +#define BCM2836_SPI1_LENGTH 0x00000040 +#define BCM2836_SPI1_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_SPI1_OFFSET) + +#define BCM2836_SPI2_OFFSET 0x002150C0 +#define BCM2836_SPI2_LENGTH 0x00000040 +#define BCM2836_SPI2_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_SPI2_OFFSET) + +/* dma constants */ +#define BCM2836_DMA0_OFFSET 0x00007000 +#define BCM2836_DMA0_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_DMA0_OFFSET) + +#define BCM2836_DMA15_OFFSET 0x00E05000 +#define BCM2836_DMA15_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_DMA15_OFFSET) + +#define BCM2836_DMA_CTRL_OFFSET 0x00007FE0 +#define BCM2836_DMA_CTRL_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_DMA_CTRL_OFFSET) + +#define BCM2836_DMA_CHANNEL_LENGTH 0x00000100 + +#endif /*__BCM2836_H__ */ diff --git a/arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_gpio.h b/arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_gpio.h new file mode 100644 index 00000000000..a64cecaef3a --- /dev/null +++ b/arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_gpio.h @@ -0,0 +1,85 @@ +/** @file + * + * Copyright (c) 2020, Pete Batard pete@akeo.ie + * Copyright (c) 2018, Andrei Warkentin andrey.warkentin@gmail.com + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-2-Clause-Patent + * + **/ + +#include <asm/arch/acpi/bcm2836.h> + +#ifndef __BCM2836_GPIO_H__ +#define __BCM2836_GPIO_H__ + +#define GPIO_OFFSET 0x00200000 +#define GPIO_BASE_ADDRESS (BCM2836_SOC_REGISTERS + GPIO_OFFSET) +#define GPIO_LENGTH 0x000000B4 + +#define GPIO_GPFSEL0 (GPIO_BASE_ADDRESS + 0x00) +#define GPIO_GPFSEL1 (GPIO_BASE_ADDRESS + 0x04) +#define GPIO_GPFSEL2 (GPIO_BASE_ADDRESS + 0x08) +#define GPIO_GPFSEL3 (GPIO_BASE_ADDRESS + 0x0C) +#define GPIO_GPFSEL4 (GPIO_BASE_ADDRESS + 0x10) +#define GPIO_GPFSEL5 (GPIO_BASE_ADDRESS + 0x14) + +#define GPIO_GPSET0 (GPIO_BASE_ADDRESS + 0x1C) +#define GPIO_GPSET1 (GPIO_BASE_ADDRESS + 0x20) + +#define GPIO_GPCLR0 (GPIO_BASE_ADDRESS + 0x28) +#define GPIO_GPCLR1 (GPIO_BASE_ADDRESS + 0x2C) + +#define GPIO_GPLEV0 (GPIO_BASE_ADDRESS + 0x34) +#define GPIO_GPLEV1 (GPIO_BASE_ADDRESS + 0x38) + +#define GPIO_GPEDS0 (GPIO_BASE_ADDRESS + 0x40) +#define GPIO_GPEDS1 (GPIO_BASE_ADDRESS + 0x44) + +#define GPIO_GPREN0 (GPIO_BASE_ADDRESS + 0x4C) +#define GPIO_GPREN1 (GPIO_BASE_ADDRESS + 0x50) + +#define GPIO_GPFEN0 (GPIO_BASE_ADDRESS + 0x58) +#define GPIO_GPFEN1 (GPIO_BASE_ADDRESS + 0x5C) + +#define GPIO_GPHEN0 (GPIO_BASE_ADDRESS + 0x64) +#define GPIO_GPHEN1 (GPIO_BASE_ADDRESS + 0x68) + +#define GPIO_GPLEN0 (GPIO_BASE_ADDRESS + 0x70) +#define GPIO_GPLEN1 (GPIO_BASE_ADDRESS + 0x74) + +#define GPIO_GPAREN0 (GPIO_BASE_ADDRESS + 0x7C) +#define GPIO_GPAREN1 (GPIO_BASE_ADDRESS + 0x80) + +#define GPIO_GPAFEN0 (GPIO_BASE_ADDRESS + 0x88) +#define GPIO_GPAFEN1 (GPIO_BASE_ADDRESS + 0x8C) + +#define GPIO_GPPUD (GPIO_BASE_ADDRESS + 0x94) +#define GPIO_GPPUDCLK0 (GPIO_BASE_ADDRESS + 0x98) +#define GPIO_GPPUDCLK1 (GPIO_BASE_ADDRESS + 0x9C) + +#define GPIO_GPPUPPDN0 (GPIO_BASE_ADDRESS + 0xE4) +#define GPIO_GPPUPPDN1 (GPIO_BASE_ADDRESS + 0xE8) +#define GPIO_GPPUPPDN2 (GPIO_BASE_ADDRESS + 0xEC) +#define GPIO_GPPUPPDN3 (GPIO_BASE_ADDRESS + 0xF0) + +#define GPIO_FSEL_INPUT 0x0 +#define GPIO_FSEL_OUTPUT 0x1 +#define GPIO_FSEL_ALT0 0x4 +#define GPIO_FSEL_ALT1 0x5 +#define GPIO_FSEL_ALT2 0x6 +#define GPIO_FSEL_ALT3 0x7 +#define GPIO_FSEL_ALT4 0x3 +#define GPIO_FSEL_ALT5 0x2 + +#define GPIO_FSEL_PINS_PER_REGISTER 10 +#define GPIO_FSEL_BITS_PER_PIN 3 +#define GPIO_FSEL_MASK ((1 << GPIO_FSEL_BITS_PER_PIN) - 1) + +#define GPIO_PINS 54 + +#define GPIO_PULL_NONE 0x00 +#define GPIO_PULL_DOWN 0x01 +#define GPIO_PULL_UP 0x02 + +#endif /* __BCM2836_GPIO_H__ */ diff --git a/arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_gpu.h b/arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_gpu.h new file mode 100644 index 00000000000..49be0206d40 --- /dev/null +++ b/arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_gpu.h @@ -0,0 +1,48 @@ +/** @file + * + * Copyright (c) 2020, Pete Batard pete@akeo.ie + * + * SPDX-License-Identifier: BSD-2-Clause-Patent + * + **/ + +#include <asm/arch/acpi/bcm2836.h> + +#ifndef __BCM2836_GPU_H__ +#define __BCM2836_GPU_H__ + +/* VideoCore constants */ + +#define BCM2836_VCHIQ_OFFSET 0x0000B840 +#define BCM2836_VCHIQ_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_VCHIQ_OFFSET) +#define BCM2836_VCHIQ_LENGTH 0x00000010 + +#define BCM2836_V3D_BUS_OFFSET 0x00C00000 +#define BCM2836_V3D_BUS_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_V3D_BUS_OFFSET) +#define BCM2836_V3D_BUS_LENGTH 0x00001000 + +#define BCM2836_HVS_OFFSET 0x00400000 +#define BCM2836_HVS_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_HVS_OFFSET) +#define BCM2836_HVS_LENGTH 0x00006000 + +#define BCM2836_PV0_OFFSET 0x00206000 +#define BCM2836_PV0_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_PV0_OFFSET) +#define BCM2836_PV0_LENGTH 0x00000100 + +#define BCM2836_PV1_OFFSET 0x00207000 +#define BCM2836_PV1_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_PV1_OFFSET) +#define BCM2836_PV1_LENGTH 0x00000100 + +#define BCM2836_PV2_OFFSET 0x00807000 +#define BCM2836_PV2_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_PV2_OFFSET) +#define BCM2836_PV2_LENGTH 0x00000100 + +#define BCM2836_HDMI0_OFFSET 0x00902000 +#define BCM2836_HDMI0_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_HDMI0_OFFSET) +#define BCM2836_HDMI0_LENGTH 0x00000600 + +#define BCM2836_HDMI1_OFFSET 0x00808000 +#define BCM2836_HDMI1_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_HDMI1_OFFSET) +#define BCM2836_HDMI1_LENGTH 0x00000100 + +#endif /* __BCM2836_MISC_H__ */ diff --git a/arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_pwm.h b/arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_pwm.h new file mode 100644 index 00000000000..12050f34b17 --- /dev/null +++ b/arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_pwm.h @@ -0,0 +1,34 @@ +/** @file + * + * Copyright (c) 2020, Pete Batard pete@akeo.ie + * + * SPDX-License-Identifier: BSD-2-Clause-Patent + * + **/ + +#include <asm/arch/acpi/bcm2836.h> + +#ifndef __BCM2836_PWM_H__ +#define __BCM2836_PWM_H__ + +/* PWM controller constants */ + +#define BCM2836_PWM_DMA_OFFSET 0x00007B00 +#define BCM2836_PWM_DMA_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_PWM_DMA_OFFSET) +#define BCM2836_PWM_DMA_LENGTH 0x00000100 + +#define BCM2836_PWM_CLK_OFFSET 0x001010A0 +#define BCM2836_PWM_CLK_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_PWM_CLK_OFFSET) +#define BCM2836_PWM_CLK_LENGTH 0x00000008 + +#define BCM2836_PWM_CTRL_OFFSET 0x0020C000 +#define BCM2836_PWM_CTRL_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_PWM_CTRL_OFFSET) +#define BCM2836_PWM_CTRL_LENGTH 0x00000028 + +#define BCM2836_PWM_BUS_BASE_ADDRESS 0x7E20C000 +#define BCM2836_PWM_BUS_LENGTH 0x00000028 + +#define BCM2836_PWM_CTRL_UNCACHED_BASE_ADDRESS 0xFF20C000 +#define BCM2836_PWM_CTRL_UNCACHED_LENGTH 0x00000028 + +#endif /* __BCM2836_PWM_H__ */ diff --git a/arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_sdhost.h b/arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_sdhost.h new file mode 100644 index 00000000000..1c62d668a48 --- /dev/null +++ b/arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_sdhost.h @@ -0,0 +1,90 @@ +/** @file + * + * Copyright (c) 2017, Andrei Warkentin andrey.warkentin@gmail.com + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-2-Clause-Patent + * + **/ + +#include <asm/arch/acpi/bcm2836.h> + +#ifndef __BCM2836_SDHOST_H__ +#define __BCM2836_SDHOST_H__ + +#define SDHOST_OFFSET 0x00202000 +#define SDHOST_BASE_ADDRESS (BCM2836_SOC_REGISTERS + SDHOST_OFFSET) +#define SDHOST_LENGTH 0x00000100 +#define SDHOST_REG(X) (SDHOST_BASE_ADDRESS + (X)) +#define SDHOST_CMD SDHOST_REG(0x0) +#define SDHOST_ARG SDHOST_REG(0x4) +#define SDHOST_TOUT SDHOST_REG(0x8) +#define SDHOST_CDIV SDHOST_REG(0xC) +#define SDHOST_RSP0 SDHOST_REG(0x10) // [31:0] +#define SDHOST_RSP1 SDHOST_REG(0x14) // [63:32] +#define SDHOST_RSP2 SDHOST_REG(0x18) // [95:64] +#define SDHOST_RSP3 SDHOST_REG(0x1C) // [127:96] +#define SDHOST_HSTS SDHOST_REG(0x20) +#define SDHOST_VDD SDHOST_REG(0x30) +#define SDHOST_EDM SDHOST_REG(0x34) +#define SDHOST_HCFG SDHOST_REG(0x38) +#define SDHOST_HBCT SDHOST_REG(0x3C) +#define SDHOST_DATA SDHOST_REG(0x40) +#define SDHOST_HBLC SDHOST_REG(0x50) + +// +// CMD +// +#define SDHOST_CMD_READ_CMD BIT6 +#define SDHOST_CMD_WRITE_CMD BIT7 +#define SDHOST_CMD_RESPONSE_CMD_LONG_RESP BIT9 +#define SDHOST_CMD_RESPONSE_CMD_NO_RESP BIT10 +#define SDHOST_CMD_BUSY_CMD BIT11 +#define SDHOST_CMD_FAIL_FLAG BIT14 +#define SDHOST_CMD_NEW_FLAG BIT15 + +// +// VDD +// +#define SDHOST_VDD_POWER_ON BIT0 + +// +// HSTS +// +#define SDHOST_HSTS_CLEAR 0x7F8 +#define SDHOST_HSTS_BLOCK_IRPT BIT9 +#define SDHOST_HSTS_REW_TIME_OUT BIT7 +#define SDHOST_HSTS_CMD_TIME_OUT BIT6 +#define SDHOST_HSTS_CRC16_ERROR BIT5 +#define SDHOST_HSTS_CRC7_ERROR BIT4 +#define SDHOST_HSTS_FIFO_ERROR BIT3 +#define SDHOST_HSTS_DATA_FLAG BIT0 + +#define SDHOST_HSTS_TIMOUT_ERROR (SDHOST_HSTS_CMD_TIME_OUT | SDHOST_HSTS_REW_TIME_OUT) +#define SDHOST_HSTS_TRANSFER_ERROR (SDHOST_HSTS_FIFO_ERROR | SDHOST_HSTS_CRC7_ERROR | SDHOST_HSTS_CRC16_ERROR) +#define SDHOST_HSTS_ERROR (SDHOST_HSTS_TIMOUT_ERROR | SDHOST_HSTS_TRANSFER_ERROR) + +// +// HCFG +// +#define SDHOST_HCFG_SLOW_CARD BIT3 +#define SDHOST_HCFG_WIDE_EXT_BUS BIT2 +#define SDHOST_HCFG_WIDE_INT_BUS BIT1 +#define SDHOST_HCFG_DATA_IRPT_EN BIT4 +#define SDHOST_HCFG_BLOCK_IRPT_EN BIT8 +#define SDHOST_HCFG_BUSY_IRPT_EN BIT10 + +// +// EDM +// +#define SDHOST_EDM_FIFO_CLEAR BIT21 +#define SDHOST_EDM_WRITE_THRESHOLD_SHIFT 9 +#define SDHOST_EDM_READ_THRESHOLD_SHIFT 14 +#define SDHOST_EDM_THRESHOLD_MASK 0x1F +#define SDHOST_EDM_READ_THRESHOLD(X) ((X) << SDHOST_EDM_READ_THRESHOLD_SHIFT) +#define SDHOST_EDM_WRITE_THRESHOLD(X) ((X) << SDHOST_EDM_WRITE_THRESHOLD_SHIFT) + +#define CMD8_SD_ARG (0x0UL << 12 | BIT8 | 0xCEUL << 0) +#define CMD8_MMC_ARG (0) + +#endif /*__BCM2836_SDHOST_H__ */ diff --git a/arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_sdio.h b/arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_sdio.h new file mode 100644 index 00000000000..aba422b9751 --- /dev/null +++ b/arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_sdio.h @@ -0,0 +1,203 @@ +/** @file + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-2-Clause-Patent + * + **/ + +#include <asm/arch/acpi/bcm2836.h> + +#ifndef __BCM2836_SDIO_H__ +#define __BCM2836_SDIO_H__ + +// MMC/SD/SDIO1 register definitions. +#define MMCHS1_OFFSET 0x00300000 +#define MMCHS2_OFFSET 0x00340000 +#define MMCHS1_BASE (BCM2836_SOC_REGISTERS + MMCHS1_OFFSET) +#define MMCHS2_BASE (BCM2836_SOC_REGISTERS + MMCHS2_OFFSET) +#define MMCHS1_LENGTH 0x00000100 +#define MMCHS2_LENGTH 0x00000100 + +#define MMCHS_BLK (mMmcHsBase + 0x4) +#define BLEN_512BYTES (0x200UL << 0) + +#define MMCHS_ARG (mMmcHsBase + 0x8) + +#define MMCHS_CMD (mMmcHsBase + 0xC) +#define BCE_ENABLE BIT1 +#define DDIR_READ BIT4 +#define DDIR_WRITE (0x0UL << 4) +#define MSBS_SGLEBLK (0x0UL << 5) +#define MSBS_MULTBLK BIT5 +#define RSP_TYPE_MASK (0x3UL << 16) +#define RSP_TYPE_136BITS BIT16 +#define RSP_TYPE_48BITS (0x2UL << 16) +#define RSP_TYPE_48BUSY (0x3UL << 16) +#define CCCE_ENABLE BIT19 +#define CICE_ENABLE BIT20 +#define DP_ENABLE BIT21 + +#define CMD_TYPE_NORMAL 0 +#define CMD_TYPE_ABORT 3 +#define TYPE(CMD_TYPE) (((CMD_TYPE) & 0x3) << 22) +#define _INDX(CMD_INDX) ((CMD_INDX & 0x3F) << 24) +#define MMC_CMD_NUM(CMD) (((CMD) >> 24) & 0x3F) +#define INDX(CMD_INDX) (TYPE(CMD_TYPE_NORMAL) | _INDX(CMD_INDX)) +#define INDX_ABORT(CMD_INDX) (TYPE(CMD_TYPE_ABORT) | _INDX(CMD_INDX)) + +#define MMCHS_RSP10 (mMmcHsBase + 0x10) +#define MMCHS_RSP32 (mMmcHsBase + 0x14) +#define MMCHS_RSP54 (mMmcHsBase + 0x18) +#define MMCHS_RSP76 (mMmcHsBase + 0x1C) +#define MMCHS_DATA (mMmcHsBase + 0x20) + +#define MMCHS_PRES_STATE (mMmcHsBase + 0x24) +#define CMDI_MASK BIT0 +#define CMDI_ALLOWED (0x0UL << 0) +#define CMDI_NOT_ALLOWED BIT0 +#define DATI_MASK BIT1 +#define DATI_ALLOWED (0x0UL << 1) +#define DATI_NOT_ALLOWED BIT1 +#define WRITE_PROTECT_OFF BIT19 + +#define MMCHS_HCTL (mMmcHsBase + 0x28) +#define DTW_1_BIT (0x0UL << 1) +#define DTW_4_BIT BIT1 +#define SDBP_MASK BIT8 +#define SDBP_OFF (0x0UL << 8) +#define SDBP_ON BIT8 +#define SDVS_MASK (0x7UL << 9) +#define SDVS_1_8_V (0x5UL << 9) +#define SDVS_3_0_V (0x6UL << 9) +#define SDVS_3_3_V (0x7UL << 9) +#define IWE BIT24 + +#define MMCHS_SYSCTL (mMmcHsBase + 0x2C) +#define ICE BIT0 +#define ICS_MASK BIT1 +#define ICS BIT1 +#define CEN BIT2 +#define CLKD_MASK (0x3FFUL << 6) +#define CLKD_80KHZ (0x258UL) //(96*1000/80)/2 +#define CLKD_400KHZ (0xF0UL) +#define CLKD_12500KHZ (0x200UL) +#define DTO_MASK (0xFUL << 16) +#define DTO_VAL (0xEUL << 16) +#define SRA BIT24 +#define SRC_MASK BIT25 +#define SRC BIT25 +#define SRD BIT26 + +#define MMCHS_INT_STAT (mMmcHsBase + 0x30) +#define CC BIT0 +#define TC BIT1 +#define BWR BIT4 +#define BRR BIT5 +#define CARD_INS BIT6 +#define ERRI BIT15 +#define CTO BIT16 +#define DTO BIT20 +#define DCRC BIT21 +#define DEB BIT22 + +#define MMCHS_IE (mMmcHsBase + 0x34) +#define CC_EN BIT0 +#define TC_EN BIT1 +#define BWR_EN BIT4 +#define BRR_EN BIT5 +#define CTO_EN BIT16 +#define CCRC_EN BIT17 +#define CEB_EN BIT18 +#define CIE_EN BIT19 +#define DTO_EN BIT20 +#define DCRC_EN BIT21 +#define DEB_EN BIT22 +#define CERR_EN BIT28 +#define BADA_EN BIT29 +#define ALL_EN 0xFFFFFFFF + +#define MMCHS_ISE (mMmcHsBase + 0x38) +#define CC_SIGEN BIT0 +#define TC_SIGEN BIT1 +#define BWR_SIGEN BIT4 +#define BRR_SIGEN BIT5 +#define CTO_SIGEN BIT16 +#define CCRC_SIGEN BIT17 +#define CEB_SIGEN BIT18 +#define CIE_SIGEN BIT19 +#define DTO_SIGEN BIT20 +#define DCRC_SIGEN BIT21 +#define DEB_SIGEN BIT22 +#define CERR_SIGEN BIT28 +#define BADA_SIGEN BIT29 + +#define MMCHS_AC12 (mMmcHsBase + 0x3C) +#define MMCHS_HC2R (mMmcHsBase + 0x3E) + +#define MMCHS_CAPA (mMmcHsBase + 0x40) +#define VS30 BIT25 +#define VS18 BIT26 + +#define MMCHS_CUR_CAPA (mMmcHsBase + 0x48) +#define MMCHS_REV (mMmcHsBase + 0xFC) + +#define BLOCK_COUNT_SHIFT 16 +#define RCA_SHIFT 16 + +#define CMD_R1 (RSP_TYPE_48BITS | CCCE_ENABLE | CICE_ENABLE) +#define CMD_R1B (RSP_TYPE_48BUSY | CCCE_ENABLE | CICE_ENABLE) +#define CMD_R2 (RSP_TYPE_136BITS | CCCE_ENABLE) +#define CMD_R3 (RSP_TYPE_48BITS) +#define CMD_R6 (RSP_TYPE_48BITS | CCCE_ENABLE | CICE_ENABLE) +#define CMD_R7 (RSP_TYPE_48BITS | CCCE_ENABLE | CICE_ENABLE) + +#define CMD_R1_ADTC (CMD_R1 | DP_ENABLE) +#define CMD_R1_ADTC_READ (CMD_R1_ADTC | DDIR_READ) +#define CMD_R1_ADTC_WRITE (CMD_R1_ADTC | DDIR_WRITE) + +#define CMD0 (INDX(0)) // Go idle +#define CMD1 (INDX(1) | CMD_R3) // MMC: Send Op Cond +#define CMD2 (INDX(2) | CMD_R2) // Send CID +#define CMD3 (INDX(3) | CMD_R6) // Set Relative Addr +#define CMD4 (INDX(4)) // Set DSR +#define CMD5 (INDX(5) | CMD_R1B) // SDIO: Sleep/Awake +#define CMD6 (INDX(6) | CMD_R1_ADTC_READ) // Switch +#define CMD7 (INDX(7) | CMD_R1B) // Select/Deselect +#define CMD8_SD (INDX(8) | CMD_R7) // Send If Cond +#define CMD8_SD_ARG (0x0UL << 12 | BIT8 | 0xCEUL << 0) +#define CMD8_MMC (INDX(8) | CMD_R1_ADTC_READ) // Send Ext Csd +#define CMD8_MMC_ARG (0) +#define CMD9 (INDX(9) | CMD_R2) // Send CSD +#define CMD10 (INDX(10) | CMD_R2) // Send CID +#define CMD11 (INDX(11) | CMD_R1) // Voltage Switch +#define CMD12 (INDX_ABORT(12) | CMD_R1B) // Stop Transmission +#define CMD13 (INDX(13) | CMD_R1) // Send Status +#define CMD15 (INDX(15)) // Go inactive state +#define CMD16 (INDX(16) | CMD_R1) // Set Blocklen +#define CMD17 (INDX(17) | CMD_R1_ADTC_READ) // Read Single Block +#define CMD18 (INDX(18) | CMD_R1_ADTC_READ | MSBS_MULTBLK) // Read Multiple Blocks +#define CMD19 (INDX(19) | CMD_R1_ADTC_READ) // SD: Send Tuning Block (64 bytes) +#define CMD20 (INDX(20) | CMD_R1B) // SD: Speed Class Control +#define CMD23 (INDX(23) | CMD_R1) // Set Block Count for CMD18 and CMD25 +#define CMD24 (INDX(24) | CMD_R1_ADTC_WRITE) // Write Block +#define CMD25 (INDX(25) | CMD_R1_ADTC_WRITE | MSBS_MULTBLK) // Write Multiple Blocks +#define CMD55 (INDX(55) | CMD_R1) // App Cmd + +#define ACMD6 (INDX(6) | CMD_R1) // Set Bus Width +#define ACMD22 (INDX(22) | CMD_R1_ADTC_READ) // SEND_NUM_WR_BLOCKS +#define ACMD41 (INDX(41) | CMD_R3) // Send Op Cond +#define ACMD51 (INDX(51) | CMD_R1_ADTC_READ) // Send SCR + +// User-friendly command names +#define CMD_IO_SEND_OP_COND CMD5 +#define CMD_SEND_CSD CMD9 // CSD: Card-Specific Data +#define CMD_STOP_TRANSMISSION CMD12 +#define CMD_SEND_STATUS CMD13 +#define CMD_READ_SINGLE_BLOCK CMD17 +#define CMD_READ_MULTIPLE_BLOCK CMD18 +#define CMD_SET_BLOCK_COUNT CMD23 +#define CMD_WRITE_SINGLE_BLOCK CMD24 +#define CMD_WRITE_MULTIPLE_BLOCK CMD25 + +#endif /* __BCM2836_SDIO_H__ */

This is only partially implemented and includes RFC patches.
So far it boots into grub but is unable to read the OS from the USB stick, presumably because the XHCI SSDT is missing.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/arm/include/asm/acpi_table.h | 15 + board/raspberrypi/rpi/Makefile | 2 + board/raspberrypi/rpi/rpi.c | 460 +++++++++++++++++++++++++++++- configs/rpi_4_defconfig | 2 + 4 files changed, 478 insertions(+), 1 deletion(-)
diff --git a/arch/arm/include/asm/acpi_table.h b/arch/arm/include/asm/acpi_table.h index e69de29bb2d..930e857edeb 100644 --- a/arch/arm/include/asm/acpi_table.h +++ b/arch/arm/include/asm/acpi_table.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2019 Google LLC + */ + +#ifndef __ASM_ACPI_TABLE_H__ +#define __ASM_ACPI_TABLE_H__ + +#ifndef __ACPI__ + +ulong write_acpi_tables(ulong start); + +#endif + +#endif /* __ASM_ACPI_TABLE_H__ */ diff --git a/board/raspberrypi/rpi/Makefile b/board/raspberrypi/rpi/Makefile index b1186cdf100..67f6b05e654 100644 --- a/board/raspberrypi/rpi/Makefile +++ b/board/raspberrypi/rpi/Makefile @@ -4,3 +4,5 @@
obj-y := rpi.o obj-y += lowlevel_init.o + +obj-$(CONFIG_GENERATE_ACPI_TABLE) += dsdt.o diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c index 55afaa54d9f..3fe69c66da2 100644 --- a/board/raspberrypi/rpi/rpi.c +++ b/board/raspberrypi/rpi/rpi.c @@ -3,6 +3,8 @@ * (C) Copyright 2012-2016 Stephen Warren */
+#define LOG_CATEGORY LOGC_BOARD + #include <common.h> #include <config.h> #include <dm.h> @@ -12,19 +14,29 @@ #include <fdt_simplefb.h> #include <init.h> #include <lcd.h> +#include <log.h> #include <memalign.h> #include <mmc.h> +#include <signatures.h> +#include <tables_csum.h> +#include <acpi/acpi_table.h> +#include <asm/acpi_table.h> +#include <asm/global_data.h> #include <asm/gpio.h> #include <asm/arch/mbox.h> #include <asm/arch/msg.h> #include <asm/arch/sdhci.h> -#include <asm/global_data.h> +#include <asm/arch/acpi/bcm2836.h> +#include <dm/acpi.h> #include <dm/platform_data/serial_bcm283x_mu.h> #ifdef CONFIG_ARM64 #include <asm/armv8/mmu.h> #endif #include <watchdog.h> #include <dm/pinctrl.h> +#ifdef CONFIG_GENERATE_ACPI_TABLE +#include "acpitables.h" +#endif
DECLARE_GLOBAL_DATA_PTR;
@@ -515,3 +527,449 @@ int ft_board_setup(void *blob, struct bd_info *bd)
return 0; } + +#ifdef CONFIG_GENERATE_ACPI_TABLE +int last_stage_init(void) +{ + int ret; + + ret = write_acpi_tables(0x10000); + if (ret < 0) { + log_err("Failed to write tables\n"); + return log_msg_ret("table", ret); + } + + return 0; +} + +static int rpi_write_facp(struct acpi_ctx *ctx, const struct acpi_writer *entry) +{ + struct acpi_table_header *header; + struct acpi_fadt *fadt; + + fadt = ctx->current; + header = &fadt->header; + + memset(fadt, '\0', sizeof(struct acpi_fadt)); + + acpi_fill_header(header, "FACP"); + header->length = sizeof(struct acpi_fadt); + header->revision = ACPI_FADT_REV_ACPI_6_0; + + fadt->firmware_ctrl = (ulong)ctx->facs; + fadt->dsdt = (ulong)ctx->dsdt; + fadt->preferred_pm_profile = ACPI_PM_APPLIANCE_PC; + + fadt->flags = ACPI_FADT_WBINVD | ACPI_FADT_SLEEP_BUTTON | + ACPI_FADT_HW_REDUCED_ACPI; + fadt->arm_boot_arch = ACPI_ARM_PSCI_COMPLIANT; + fadt->minor_revision = 3; + + fadt->x_firmware_ctl_l = (ulong)ctx->facs; + fadt->x_firmware_ctl_h = (ulong)ctx->facs >> 32; + fadt->x_dsdt_l = (ulong)ctx->dsdt; + fadt->x_dsdt_h = (ulong)ctx->dsdt >> 32; + + header->checksum = table_compute_checksum(fadt, header->length); + + acpi_add_table(ctx, fadt); + + acpi_inc(ctx, sizeof(struct acpi_fadt)); + + return 0; +} +ACPI_WRITER(5facp, "FACP", rpi_write_facp, 0); + +#define GTDT_FLAG_INT_ACTIVE_LOW BIT(1) +#define RPI_GTDT_GTIMER_FLAGS GTDT_FLAG_INT_ACTIVE_LOW + +/* ARM Architectural Timer Interrupt(GIC PPI) numbers */ +#define PcdArmArchTimerSecIntrNum 29 +#define PcdArmArchTimerIntrNum 30 +#define PcdArmArchTimerHypIntrNum 26 +#define PcdArmArchTimerVirtIntrNum 27 + +static int rpi_write_gtdt(struct acpi_ctx *ctx, const struct acpi_writer *entry) +{ + struct acpi_table_header *header; + struct acpi_gtdt *gtdt; + + gtdt = ctx->current; + header = >dt->header; + + memset(gtdt, '\0', sizeof(struct acpi_gtdt)); + + acpi_fill_header(header, "GTDT"); + header->length = sizeof(struct acpi_gtdt); + header->revision = 3; + + gtdt->cnt_ctrl_base = RPI_SYSTEM_TIMER_BASE_ADDRESS; + gtdt->sec_el1_gsiv = PcdArmArchTimerSecIntrNum; + gtdt->sec_el1_flags = RPI_GTDT_GTIMER_FLAGS; + gtdt->el1_gsiv = PcdArmArchTimerIntrNum; + gtdt->el1_flags = RPI_GTDT_GTIMER_FLAGS; + gtdt->virt_el1_gsiv = PcdArmArchTimerVirtIntrNum; + gtdt->virt_el1_flags = RPI_GTDT_GTIMER_FLAGS; + gtdt->el2_gsiv = PcdArmArchTimerHypIntrNum; + gtdt->el2_flags = RPI_GTDT_GTIMER_FLAGS; + gtdt->cnt_read_base = 0xffffffffffffffff; + acpi_add_table(ctx, gtdt); + + acpi_inc(ctx, sizeof(struct acpi_gtdt)); + + return 0; +}; +ACPI_WRITER(5gtdt, "GTDT", rpi_write_gtdt, 0); + +static int rpi_write_dbg2(struct acpi_ctx *ctx, const struct acpi_writer *entry) +{ + struct acpi_table_header *header; + struct acpi_dbg2_header *dbg2; + struct acpi_dbg2_device *ddev; + struct acpi_gen_regaddr *addr; + u32 *addr_size; + char *name; + void *end; + + dbg2 = ctx->current; + header = &dbg2->header; + + /* Note this doesn't zero everything */ + memset(dbg2, '\0', sizeof(struct acpi_dbg2_header)); + + acpi_fill_header(header, "DBG2"); + header->revision = 0; + + dbg2->devices_offset = sizeof(*dbg2); + dbg2->devices_count = 1; + + ddev = (void *)(dbg2 + 1); + ddev->revision = 0; + ddev->length = 0x35; + ddev->address_count = 1; + ddev->namespace_string_length = 0xf; + ddev->namespace_string_offset = 0x26; + ddev->oem_data_length = 0; + ddev->oem_data_offset = 0; + ddev->port_type = ACPI_DBG2_SERIAL_PORT; + ddev->port_subtype = ACPI_DBG2_ARM_PL011; + + addr = (void *)(ddev + 1); + ddev->base_address_offset = sizeof(*ddev); + ddev->address_size_offset = sizeof(*ddev) + sizeof(*addr); + + addr->space_id = ACPI_ADDRESS_SPACE_MEMORY; + addr->bit_width = 32; + addr->bit_offset = 0; + addr->access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS; + addr->addrl = 0xfe201000; + addr->addrh = 0; + + addr_size = (u32 *)(addr + 1); + *addr_size = 0x1000; + + name = (char *)(addr_size + 1); + strcpy(name, "\_SB.GDV0.URT0"); + end = name + strlen(name) + 1; + header->length = end - ctx->current; + acpi_add_table(ctx, dbg2); + + acpi_inc(ctx, header->length); + + return 0; +}; +ACPI_WRITER(5dbg2, "DBG2", rpi_write_dbg2, 0); + +#if 0 +/* Need to add a logo first */ +static int rpi_write_bgrt(struct acpi_ctx *ctx, const struct acpi_writer *entry) +{ + struct acpi_table_header *header; + struct acpi_bgrt_header *bgrt; + + bgrt = ctx->current; + header = &dbg2->header; + + memset(bgrt, '\0', sizeof(struct acpi_bgrt)); + + acpi_fill_header(header, "BGRT"); + header->revision = 0; + + acpi_inc(ctx, header->length); + + return 0; +}; +ACPI_WRITER(5bgrt, "BGRT", rpi_write_bgrt, 0); +#endif + +static u32 *add_proc(struct acpi_ctx *ctx, int flags, int parent, int proc_id, + int num_resources) +{ + struct acpi_pptt_proc *proc = ctx->current; + u32 *resource_list; + + proc->hdr.type = ACPI_PPTT_TYPE_PROC; + proc->flags = flags; + proc->parent = parent; + proc->proc_id = proc_id; + proc->num_resources = num_resources; + proc->hdr.length = sizeof(struct acpi_pptt_proc) + + sizeof(u32) * num_resources; + resource_list = ctx->current + sizeof(struct acpi_pptt_proc); + acpi_inc(ctx, proc->hdr.length); + + return resource_list; +} + +static int add_cache(struct acpi_ctx *ctx, int flags, int size, int sets, + int assoc, int attributes, int line_size) +{ + struct acpi_pptt_cache *cache = ctx->current; + int ofs; + + ofs = ctx->current - ctx->tab_start; + cache->hdr.type = ACPI_PPTT_TYPE_CACHE; + cache->hdr.length = sizeof(struct acpi_pptt_cache); + cache->flags = flags; + cache->next_cache_level = 0; + cache->size = size; + cache->sets = sets; + cache->assoc = assoc; + cache->attributes = attributes; + cache->line_size = line_size; + acpi_inc(ctx, cache->hdr.length); + + return ofs; +} + +static int rpi_write_pptt(struct acpi_ctx *ctx, const struct acpi_writer *entry) +{ + struct acpi_table_header *header; + int proc_ofs; + u32 *proc_ptr; + int ofs, ofs0, ofs1, i; + + header = ctx->current; + ctx->tab_start = ctx->current; + + memset(header, '\0', sizeof(struct acpi_table_header)); + + acpi_fill_header(header, "PPTT"); + header->revision = 0; + acpi_inc(ctx, sizeof(*header)); + + proc_ofs = ctx->current - ctx->tab_start; + proc_ptr = add_proc(ctx, ACPI_PPTT_PHYSICAL_PACKAGE | + ACPI_PPTT_CHILDREN_IDENTICAL, 0, 0, 1); + + ofs = add_cache(ctx, ACPI_PPTT_ALL_VALID, 0x100000, 0x400, 0x10, + ACPI_PPTT_WRITE_ALLOC | + (ACPI_PPTT_CACHE_TYPE_UNIFIED << + ACPI_PPTT_CACHE_TYPE_SHIFT), 0x40); + *proc_ptr = ofs; + + for (i = 0; i < 4; i++) { + proc_ptr = add_proc(ctx, ACPI_PPTT_CHILDREN_IDENTICAL | + ACPI_PPTT_NODE_IS_LEAF | ACPI_PPTT_PROC_ID_VALID, + proc_ofs, i, 2); + + ofs0 = add_cache(ctx, ACPI_PPTT_ALL_VALID, 0x8000, 0x100, 2, + ACPI_PPTT_WRITE_ALLOC, 0x40); + + ofs1 = add_cache(ctx, ACPI_PPTT_ALL_BUT_WRITE_POL, 0xc000, 0x100, 3, + ACPI_PPTT_CACHE_TYPE_INSTR << + ACPI_PPTT_CACHE_TYPE_SHIFT, 0x40); + proc_ptr[0] = ofs0; + proc_ptr[1] = ofs1; + } + + header->length = ctx->current - ctx->tab_start; + header->checksum = table_compute_checksum(header, header->length); + + acpi_inc(ctx, header->length); + acpi_add_table(ctx, header); + + return 0; +}; +ACPI_WRITER(5pptt, "PPTT", rpi_write_pptt, 0); + +static void acpi_write_madt_gicc(struct acpi_ctx *ctx, uint cpu_num, + uint perf_gsiv, ulong phys_base, ulong gicv, + ulong gich, uint vgic_maint_irq, ulong mpidr, + uint efficiency) +{ + struct acpi_madr_gicc *gicc = ctx->current; + + memset(gicc, '\0', sizeof(struct acpi_madr_gicc)); + gicc->type = ACPI_APIC_GICC; + gicc->length = sizeof(struct acpi_madr_gicc); + gicc->cpu_if_num = cpu_num; + gicc->processor_id = cpu_num; + gicc->flags = ACPI_MADRF_ENABLED; + gicc->perf_gsiv = perf_gsiv; + gicc->phys_base = phys_base; + gicc->gicv = gicv; + gicc->gich = gich; + gicc->vgic_maint_irq = vgic_maint_irq; + gicc->mpidr = mpidr; + gicc->efficiency = efficiency; + acpi_inc(ctx, gicc->length); +} + +static void acpi_write_madt_gicd(struct acpi_ctx *ctx, uint gic_id, + ulong phys_base, uint gic_version) +{ + struct acpi_madr_gicd *gicd = ctx->current; + + memset(gicd, '\0', sizeof(struct acpi_madr_gicd)); + gicd->type = ACPI_APIC_GICD; + gicd->length = sizeof(struct acpi_madr_gicd); + gicd->gic_id = gic_id; + gicd->phys_base = phys_base; + gicd->gic_version = gic_version; + + acpi_inc(ctx, gicd->length); +} + +static int rpi_write_madt(struct acpi_ctx *ctx, const struct acpi_writer *entry) +{ + struct acpi_table_header *header; + struct acpi_madt *madt; + int i; + + ctx->tab_start = ctx->current; + madt = ctx->current; + + memset(madt, '\0', sizeof(struct acpi_madt)); + header = &madt->header; + + /* Fill out header fields */ + acpi_fill_header(header, "APIC"); + header->length = sizeof(struct acpi_madt); + header->revision = ACPI_MADT_REV_ACPI_6_0; + + madt->lapic_addr = 0; + madt->flags = 0; + acpi_inc(ctx, sizeof(*madt)); + + for (i = 0; i < 4; i++) { + acpi_write_madt_gicc(ctx, i, 0x30 + i, 0xff842000, 0xff846000, + 0xff844000, 0x19, i, 1); + } + acpi_write_madt_gicd(ctx, 0, 0xff841000, 2); + + /* (Re)calculate length and checksum */ + header->length = (u32)(ctx->current - ctx->tab_start); + + header->checksum = table_compute_checksum((void *)madt, header->length); + acpi_add_table(ctx, madt); + acpi_inc(ctx, madt->header.length); + + return 0; +} +ACPI_WRITER(5madt, "APIC", rpi_write_madt, 0); + +/* DMA Controller Vendor Data */ +struct __packed dma_ctlr_vendor_data { + u32 length; + u32 type; + u64 chan_base; + u32 chan_size; + u64 ctlr_base; + u32 ctlr_size; + u32 chan_count; + u32 ctlr_irq; + u32 min_req_line; + u32 max_req_line; + u8 cache_coherent; +}; + +/* DMA Controller */ +struct __packed rd_dma_ctlr { + struct acpi_csrt_descriptor hdr; + struct dma_ctlr_vendor_data data; +}; + +/* dma chan vendor data */ +struct __packed dma_chan_vendor_data { + u32 chan; + u32 chan_irq; + u16 is_reserved; + u16 addr_incr; +}; + +/* dma chan */ +struct __packed rd_dma_chan { + struct acpi_csrt_descriptor hdr; + struct dma_chan_vendor_data data; +}; + +/* dma resource group */ +struct __packed rg_dma { + struct acpi_csrt_group hdr; + struct rd_dma_ctlr ctlr; + struct rd_dma_chan chan[]; +}; + +#define RPI_DMA_MAX_REQ_LINES 32 + +static void add_cmd_chan(struct rd_dma_chan *dmac, uint uid, uint chan, + uint chan_irq, bool is_reserved, int addr_incr) +{ + memset(dmac, '\0', sizeof(*dmac)); + dmac->hdr.length = sizeof(struct rd_dma_chan); + dmac->hdr.type = EFI_ACPI_CSRT_RESOURCE_TYPE_DMA; + dmac->hdr.subtype = EFI_ACPI_CSRT_RESOURCE_SUBTYPE_DMA_CHANNEL; + dmac->hdr.uid = uid; + + dmac->data.chan = chan; + dmac->data.chan_irq = chan_irq; + dmac->data.is_reserved = is_reserved; + dmac->data.addr_incr = addr_incr; +} + +int acpi_fill_csrt(struct acpi_ctx *ctx) +{ + struct dma_ctlr_vendor_data *data; + struct acpi_csrt_group *hdr; + struct rg_dma *dma; + int i; + + dma = ctx->current; + hdr = &dma->hdr; + memset(hdr, '\0', sizeof(*hdr)); + hdr->length = 0; + hdr->vendor_id = SIGNATURE_32('R', 'P', 'I', 'F'); + hdr->device_id = EFI_ACPI_CSRT_DEVICE_ID_DMA; + + dma->ctlr.hdr.length = sizeof(struct rd_dma_ctlr); + dma->ctlr.hdr.type = EFI_ACPI_CSRT_RESOURCE_TYPE_DMA; + dma->ctlr.hdr.subtype = EFI_ACPI_CSRT_RESOURCE_SUBTYPE_DMA_CONTROLLER; + dma->ctlr.hdr.uid = EFI_ACPI_CSRT_RESOURCE_ID_IN_DMA_GRP; + + data = &dma->ctlr.data; + data->length = sizeof(struct dma_ctlr_vendor_data); + data->type = 1; + data->chan_base = BCM2836_DMA0_BASE_ADDRESS; + data->chan_size = RPI_DMA_CHANNEL_COUNT * BCM2836_DMA_CHANNEL_LENGTH; + data->ctlr_base = BCM2836_DMA_CTRL_BASE_ADDRESS; + data->ctlr_size = 8; + data->chan_count = RPI_DMA_USED_CHANNEL_COUNT; + data->max_req_line = RPI_DMA_MAX_REQ_LINES - 1; + + acpi_inc(ctx, sizeof(struct rg_dma)); + + for (i = 0; i < 10; i++) { + add_cmd_chan(&dma->chan[i], + EFI_ACPI_CSRT_RESOURCE_ID_IN_DMA_GRP + 1 + i, i, + 0x30 + i, + i == 1 || i == 2 || i == 3 || i == 6 || i == 7, + i == 4); + acpi_inc(ctx, sizeof(struct rd_dma_chan)); + } + + hdr->length = (u32)(ctx->current - (void *)dma); + + return 0; +} +#endif diff --git a/configs/rpi_4_defconfig b/configs/rpi_4_defconfig index 0720505c6a5..4a81f3e1f38 100644 --- a/configs/rpi_4_defconfig +++ b/configs/rpi_4_defconfig @@ -11,6 +11,7 @@ CONFIG_USE_PREBOOT=y CONFIG_PREBOOT="pci enum; usb start;" # CONFIG_DISPLAY_CPUINFO is not set # CONFIG_DISPLAY_BOARDINFO is not set +CONFIG_LAST_STAGE_INIT=y CONFIG_MISC_INIT_R=y CONFIG_SYS_PROMPT="U-Boot> " CONFIG_CMD_DFU=y @@ -60,4 +61,5 @@ CONFIG_DM_VIDEO=y CONFIG_SYS_WHITE_ON_BLACK=y CONFIG_CONSOLE_SCROLL_LINES=10 CONFIG_PHYS_TO_BUS=y +CONFIG_GENERATE_ACPI_TABLE=y CONFIG_OF_LIBFDT_OVERLAY=y

On Wed, Dec 1, 2021 at 6:15 PM Simon Glass sjg@chromium.org wrote:
This is only partially implemented and includes RFC patches.
So far it boots into grub but is unable to read the OS from the USB stick, presumably because the XHCI SSDT is missing.
I would recommend enabling SPCR and then pass `earlycon` to see if it gives anything.
Nevertheless, I'm in favour of this series, thanks! For patches 21 and 27 (are they the only ones that touch tangier?) take my Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com

Hi Andy,
On Wed, 1 Dec 2021 at 09:25, Andy Shevchenko andy.shevchenko@gmail.com wrote:
On Wed, Dec 1, 2021 at 6:15 PM Simon Glass sjg@chromium.org wrote:
This is only partially implemented and includes RFC patches.
So far it boots into grub but is unable to read the OS from the USB stick, presumably because the XHCI SSDT is missing.
I would recommend enabling SPCR and then pass `earlycon` to see if it gives anything.
OK I will give that a try once I get to the kernel. For now it might be stuck in grub?
https://drive.google.com/file/d/1k_4zik7UGyOS3czknKi2-WyGz-j1f6Q6/view?usp=s...
Here is the console output:
$ int.sh rpi4 tbot starting ... ├─Calling interactive_board ... │ ├─POWERON (rpi4) │ ├─Entering interactive shell (CTRL+D to exit) ...
U-Boot 2022.01-rc3-00119-g7bc37ec5293 (Dec 01 2021 - 12:19:09 -0700)
DRAM: 3.9 GiB RPI 4 Model B (0xc03111) MMC: mmcnr@7e300000: 1, mmc@7e340000: 0 Loading Environment from FAT... Unable to read "uboot.env" from mmc0:1... In: serial Out: vidconsole Err: vidconsole Net: eth0: ethernet@7d580000 ACPI: Writing ACPI tables at 10000 0base: writing table '<NULL>' 1facs: writing table 'FACS' 3dsdt: writing table 'DSDT' 5csrt: writing table 'CSRT' 5dbg2: writing table 'DBG2' 5facp: writing table 'FACP' 5gtdt: writing table 'GTDT' 5madt: writing table 'APIC' 5pptt: writing table 'PPTT' 6ssdt: writing table 'SSDT' 6ssdt: Omitted due to being empty 8dev: writing table '<NULL>' ACPI current = 12eb0 PCIe BRCM: link up, 5.0 Gbps x1 (SSC) starting USB... Bus xhci_pci: Register 5000420 NbrPorts 5 Starting the controller USB XHCI 1.00 scanning bus xhci_pci for devices... 3 USB Device(s) found scanning usb for storage devices... 1 Storage Device(s) found Hit any key to stop autoboot: 0 switch to partitions #0, OK mmc0 is current device Scanning mmc 0:1... libfdt fdt_check_header(): FDT_ERR_BADMAGIC Card did not respond to voltage select! : -110 Scanning disk mmcnr@7e300000.blk... Disk mmcnr@7e300000.blk not ready Scanning disk mmc@7e340000.blk... Scanning disk usb_mass_storage.lun0... Found 5 disks ** Unable to read file ubootefi.var ** Failed to load EFI variables ACPI: Writing ACPI tables at 39f17000 0base: writing table '<NULL>' 1facs: writing table 'FACS' 3dsdt: writing table 'DSDT' 5csrt: writing table 'CSRT' 5dbg2: writing table 'DBG2' 5facp: writing table 'FACP' 5gtdt: writing table 'GTDT' 5madt: writing table 'APIC' 5pptt: writing table 'PPTT' 6ssdt: writing table 'SSDT' 6ssdt: Omitted due to being empty 8dev: writing table '<NULL>' ACPI current = 39f19eb0 BootOrder not defined EFI boot manager: Cannot load any image Card did not respond to voltage select! : -110
Device 0: Vendor: Lexar Rev: PMAP Prod: USB Flash Drive Type: Removable Hard Disk Capacity: 30560.0 MB = 29.8 GB (62586880 x 512) ... is now current device Scanning usb 0:2... libfdt fdt_check_header(): FDT_ERR_BADMAGIC BootOrder not defined EFI boot manager: Cannot load any image Found EFI removable media binary efi/boot/bootaa64.efi 1865600 bytes read in 50 ms (35.6 MiB/s) libfdt fdt_check_header(): FDT_ERR_BADMAGIC Booting /efi\boot\bootaa64.efi ethernet@7d580000 Waiting for PHY auto negotiation to complete......... TIMEOUT ! bcmgenet: PHY startup failed: -110 EFI stub: ERROR: FIRMWARE BUG: kernel image not aligned on 64k boundary
Nevertheless, I'm in favour of this series, thanks! For patches 21 and 27 (are they the only ones that touch tangier?) take my Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com
Thanks!
I think tangier may be affected by anything with the x86 tag, since it is moving the ACPI code around. Worth a test if you have time. So far I tested it on coral but will do also on minnowmax which I have in my lab.
Regards, Simon

On Wed, Dec 1, 2021 at 6:56 PM Simon Glass sjg@chromium.org wrote:
At present in U-Boot ACPI tables are only generated for x86 devices. It is possible to build them for ARM as well. That is the subject of this series.
The goal is to allow a rpi4 boot into Linux on ARM using ACPI rather than devicetree. This is not due to any feeling that ACPI offers advantages to the boot flow, merely because it can be done.
This goal is not yet achieved. Mostly all that is achieved is some refactoring of the ACPI code, but that is enough to get things at least building on ARM. The rpi-4 the tables are installed and the board boots to grub, where it is then unable to find the OS on the USB stick that is inserted. Further work is needed to complete things, but the ACPI changes can be applied as is.
In terms of review, please ignore the RFC/WIP patches as they need to be reworked. I am sending this series in this state to avoid sitting on patches for too long and risking duplicate effort.
The following tables are emitted with this series:
- GTDT - Generic Timer Description Table
- APIC - Multiple Advanced Programmable Interrupt Controller Description Table (some new records for ARM)
- DSDT - Differentiated System Description Table
- DBG2 - Debug Port Table 2
- FACP - Firmware ACPI Control Structure
- CSRT - Core System Resource Table
- PPTT - Processor Properties Topology Table
Missing still are:
- SSDR - Secondary System Description Table
SSDT
- BGRT - Boot Graphics Resource Table
And SPCR
Future work is needed to:
- Finish the remaining two tables
- Get things booting nicely on rpi4
- Find a nice way to select between ACPI and devicetree at runtime
- Obtain the ACPI information from the devicetree instead of #defines
- Use the U-Boot bcm headers instead of importing new ones
- Drop the unused files
- Add some documentation
To test it, boot U-Boot on a rpi_4 with a suitable distribution.
This series is available at u-boot-dm/acpi-working
Simon Glass (40): Makefile: Allow LTO to be disabled for a build x86: Allow any arch to generate ACPI tables x86: Move the acpi table to generic global_data arm: Allow supporting ACPI-table generation x86: Tidy up use of CONFIG_ACPIGEN sandbox: Allow building with GENERATE_ACPI_TABLE efi: Correct call to write_acpi_tables() efi: Correct address handling with ACPI tables acpi: Use finer-grained control of ACPI-table generation acpi: Allow include files within the board directory acpi: Move acpi_fill_header() to the generic header acpi: Add a table start acpi: Add a linker list for ACPI tables x86: acpi: Split out context creation from base tables x86: Use the ACPI table writer x86: Move base tables to a writer function x86: Move FACS table to a writer function x86: Move DSDT table to a writer function x86: Move GNVS table to a writer function x86: Move FADT table to a writer function x86: Move FACP table into separate functions x86: Move SSDT table to a writer function x86: Move TPM2 table to a writer function x86: Move MADT table to a writer function x86: Move TCPA table to a writer function x86: Move CSRT table to a writer function x86: acpi: Update acpi_fill_csrt() to use acpi_ctx x86: Move device-specific ACPI tables to a writer function x86: Move acpi_get_rsdp_addr() ACPI tables to the writer acpi: Collect tables in the acpi_item list acpi: Tidy up the item list acpi: Tidy up the table list doc: Add usage information for the acpi command acpi: Add some tables needed by ARM devices acpi: Add myself as maintainer WIP: Add debugging for ACPI emission RFC: Allow passing ACPI tables to bootefi WIP: Add ASL files from tianocore WIP: Bring in some header files from tianocore RFC: rpi: Enable booting with ACPI tables
MAINTAINERS | 6 + Makefile | 18 +- arch/Kconfig | 6 +- arch/arm/config.mk | 4 +- arch/arm/include/asm/acpi_table.h | 15 + arch/arm/include/asm/global_data.h | 2 +- .../mach-bcm283x/include/mach/acpi/bcm2711.h | 93 +++ .../mach-bcm283x/include/mach/acpi/bcm2836.h | 124 +++ .../include/mach/acpi/bcm2836_gpio.h | 85 ++ .../include/mach/acpi/bcm2836_gpu.h | 48 ++ .../include/mach/acpi/bcm2836_pwm.h | 34 + .../include/mach/acpi/bcm2836_sdhost.h | 90 ++ .../include/mach/acpi/bcm2836_sdio.h | 203 +++++ arch/sandbox/include/asm/acpi_table.h | 2 + arch/sandbox/include/asm/global_data.h | 1 - arch/sandbox/include/asm/tables.h | 0 arch/x86/Kconfig | 9 - arch/x86/cpu/apollolake/acpi.c | 17 +- arch/x86/cpu/baytrail/acpi.c | 27 +- arch/x86/cpu/quark/acpi.c | 27 +- arch/x86/cpu/tangier/acpi.c | 34 +- arch/x86/include/asm/acpi_table.h | 4 - arch/x86/include/asm/global_data.h | 1 - arch/x86/lib/Makefile | 2 +- arch/x86/lib/acpi_table.c | 374 +++------ board/raspberrypi/rpi/Makefile | 2 + board/raspberrypi/rpi/acpitables.h | 189 +++++ board/raspberrypi/rpi/acpitables.inf | 79 ++ board/raspberrypi/rpi/csrt.aslc | 330 ++++++++ board/raspberrypi/rpi/dbg2miniuart.aslc | 81 ++ board/raspberrypi/rpi/dbg2pl011.aslc | 81 ++ board/raspberrypi/rpi/dsdt.asl | 285 +++++++ board/raspberrypi/rpi/emmc.asl | 166 ++++ board/raspberrypi/rpi/fadt.aslc | 96 +++ board/raspberrypi/rpi/gpudevs.asl | 397 +++++++++ board/raspberrypi/rpi/gtdt.aslc | 55 ++ board/raspberrypi/rpi/iort.aslc | 100 +++ board/raspberrypi/rpi/madt.aslc | 78 ++ board/raspberrypi/rpi/pci.asl | 168 ++++ board/raspberrypi/rpi/pep.asl | 90 ++ board/raspberrypi/rpi/pep.c | 79 ++ board/raspberrypi/rpi/pep.h | 121 +++ board/raspberrypi/rpi/pptt.aslc | 191 +++++ board/raspberrypi/rpi/rhpx.asl | 195 +++++ board/raspberrypi/rpi/rpi.c | 460 +++++++++- board/raspberrypi/rpi/rpi4.dsc | 790 ++++++++++++++++++ board/raspberrypi/rpi/sdhc.asl | 119 +++ board/raspberrypi/rpi/spcrminiuart.aslc | 91 ++ board/raspberrypi/rpi/spcrpl011.aslc | 91 ++ board/raspberrypi/rpi/ssdtthermal.asl | 77 ++ board/raspberrypi/rpi/uart.asl | 202 +++++ board/raspberrypi/rpi/xhci.asl | 165 ++++ cmd/acpi.c | 13 +- cmd/bootefi.c | 44 +- configs/cherryhill_defconfig | 1 + configs/chromebook_link64_defconfig | 1 + configs/chromebook_link_defconfig | 1 + configs/chromebook_samus_tpl_defconfig | 1 + configs/coreboot64_defconfig | 1 + configs/coreboot_defconfig | 1 + configs/crownbay_defconfig | 1 + configs/efi-x86_payload32_defconfig | 1 + configs/efi-x86_payload64_defconfig | 1 + configs/rpi_4_defconfig | 2 + configs/slimbootloader_defconfig | 1 + configs/tools-only_defconfig | 1 + doc/build/gcc.rst | 17 + doc/usage/acpi.rst | 235 ++++++ doc/usage/index.rst | 1 + drivers/core/acpi.c | 70 +- drivers/misc/qfw.c | 3 +- include/acpi/acpi_table.h | 235 +++++- include/asm-generic/global_data.h | 8 + include/dm/acpi.h | 110 +++ lib/Kconfig | 18 + lib/Makefile | 2 +- lib/acpi/Makefile | 23 +- lib/acpi/acpi_table.c | 82 -- lib/acpi/acpi_writer.c | 132 +++ lib/acpi/base.c | 94 +++ lib/acpi/csrt.c | 49 ++ lib/acpi/dsdt.c | 55 ++ lib/acpi/facs.c | 35 + lib/acpi/ssdt.c | 49 ++ lib/efi_loader/Makefile | 2 - lib/efi_loader/efi_acpi.c | 5 +- scripts/Makefile.lib | 3 +- test/dm/acpi.c | 79 +- 88 files changed, 6875 insertions(+), 506 deletions(-) create mode 100644 arch/arm/mach-bcm283x/include/mach/acpi/bcm2711.h create mode 100644 arch/arm/mach-bcm283x/include/mach/acpi/bcm2836.h create mode 100644 arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_gpio.h create mode 100644 arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_gpu.h create mode 100644 arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_pwm.h create mode 100644 arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_sdhost.h create mode 100644 arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_sdio.h create mode 100644 arch/sandbox/include/asm/tables.h create mode 100644 board/raspberrypi/rpi/acpitables.h create mode 100644 board/raspberrypi/rpi/acpitables.inf create mode 100644 board/raspberrypi/rpi/csrt.aslc create mode 100644 board/raspberrypi/rpi/dbg2miniuart.aslc create mode 100644 board/raspberrypi/rpi/dbg2pl011.aslc create mode 100644 board/raspberrypi/rpi/dsdt.asl create mode 100644 board/raspberrypi/rpi/emmc.asl create mode 100644 board/raspberrypi/rpi/fadt.aslc create mode 100644 board/raspberrypi/rpi/gpudevs.asl create mode 100644 board/raspberrypi/rpi/gtdt.aslc create mode 100644 board/raspberrypi/rpi/iort.aslc create mode 100644 board/raspberrypi/rpi/madt.aslc create mode 100644 board/raspberrypi/rpi/pci.asl create mode 100644 board/raspberrypi/rpi/pep.asl create mode 100644 board/raspberrypi/rpi/pep.c create mode 100644 board/raspberrypi/rpi/pep.h create mode 100644 board/raspberrypi/rpi/pptt.aslc create mode 100644 board/raspberrypi/rpi/rhpx.asl create mode 100644 board/raspberrypi/rpi/rpi4.dsc create mode 100644 board/raspberrypi/rpi/sdhc.asl create mode 100644 board/raspberrypi/rpi/spcrminiuart.aslc create mode 100644 board/raspberrypi/rpi/spcrpl011.aslc create mode 100644 board/raspberrypi/rpi/ssdtthermal.asl create mode 100644 board/raspberrypi/rpi/uart.asl create mode 100644 board/raspberrypi/rpi/xhci.asl create mode 100644 doc/usage/acpi.rst create mode 100644 lib/acpi/acpi_writer.c create mode 100644 lib/acpi/base.c create mode 100644 lib/acpi/csrt.c create mode 100644 lib/acpi/dsdt.c create mode 100644 lib/acpi/facs.c create mode 100644 lib/acpi/ssdt.c
-- 2.34.0.rc2.393.gf8c9666880-goog

Hi
Le mer. 1 déc. 2021 à 18:16, Andy Shevchenko andy.shevchenko@gmail.com a écrit :
On Wed, Dec 1, 2021 at 6:56 PM Simon Glass sjg@chromium.org wrote:
At present in U-Boot ACPI tables are only generated for x86 devices. It
is
possible to build them for ARM as well. That is the subject of this series.
in the case of RPI4 what is needed is a translator from DT handed by Videocore. If you mean generated from an assumed configuration, that may not be good. Doing static ACPI based on assumptions as a first step is a dangerous path.
The goal is to allow a rpi4 boot into Linux on ARM using ACPI rather than devicetree. This is not due to any feeling that ACPI offers advantages to the boot flow, merely because it can be done.
This goal is not yet achieved. Mostly all that is achieved is some refactoring of the ACPI code, but that is enough to get things at least building on ARM. The rpi-4 the tables are installed and the board boots to grub, where it is then unable to find the OS on the USB stick that is inserted. Further work is needed to complete things, but the ACPI changes can be applied as is.
In terms of review, please ignore the RFC/WIP patches as they need to be reworked. I am sending this series in this state to avoid sitting on patches for too long and risking duplicate effort.
The following tables are emitted with this series:
- GTDT - Generic Timer Description Table
- APIC - Multiple Advanced Programmable Interrupt Controller Description Table (some new records for ARM)
- DSDT - Differentiated System Description Table
- DBG2 - Debug Port Table 2
- FACP - Firmware ACPI Control Structure
- CSRT - Core System Resource Table
- PPTT - Processor Properties Topology Table
Missing still are:
- SSDR - Secondary System Description Table
SSDT
- BGRT - Boot Graphics Resource Table
And SPCR
Future work is needed to:
- Finish the remaining two tables
- Get things booting nicely on rpi4
- Find a nice way to select between ACPI and devicetree at runtime
- Obtain the ACPI information from the devicetree instead of #defines
- Use the U-Boot bcm headers instead of importing new ones
- Drop the unused files
- Add some documentation
To test it, boot U-Boot on a rpi_4 with a suitable distribution.
This series is available at u-boot-dm/acpi-working
Simon Glass (40): Makefile: Allow LTO to be disabled for a build x86: Allow any arch to generate ACPI tables x86: Move the acpi table to generic global_data arm: Allow supporting ACPI-table generation x86: Tidy up use of CONFIG_ACPIGEN sandbox: Allow building with GENERATE_ACPI_TABLE efi: Correct call to write_acpi_tables() efi: Correct address handling with ACPI tables acpi: Use finer-grained control of ACPI-table generation acpi: Allow include files within the board directory acpi: Move acpi_fill_header() to the generic header acpi: Add a table start acpi: Add a linker list for ACPI tables x86: acpi: Split out context creation from base tables x86: Use the ACPI table writer x86: Move base tables to a writer function x86: Move FACS table to a writer function x86: Move DSDT table to a writer function x86: Move GNVS table to a writer function x86: Move FADT table to a writer function x86: Move FACP table into separate functions x86: Move SSDT table to a writer function x86: Move TPM2 table to a writer function x86: Move MADT table to a writer function x86: Move TCPA table to a writer function x86: Move CSRT table to a writer function x86: acpi: Update acpi_fill_csrt() to use acpi_ctx x86: Move device-specific ACPI tables to a writer function x86: Move acpi_get_rsdp_addr() ACPI tables to the writer acpi: Collect tables in the acpi_item list acpi: Tidy up the item list acpi: Tidy up the table list doc: Add usage information for the acpi command acpi: Add some tables needed by ARM devices acpi: Add myself as maintainer WIP: Add debugging for ACPI emission RFC: Allow passing ACPI tables to bootefi WIP: Add ASL files from tianocore WIP: Bring in some header files from tianocore RFC: rpi: Enable booting with ACPI tables
MAINTAINERS | 6 + Makefile | 18 +- arch/Kconfig | 6 +- arch/arm/config.mk | 4 +- arch/arm/include/asm/acpi_table.h | 15 + arch/arm/include/asm/global_data.h | 2 +- .../mach-bcm283x/include/mach/acpi/bcm2711.h | 93 +++ .../mach-bcm283x/include/mach/acpi/bcm2836.h | 124 +++ .../include/mach/acpi/bcm2836_gpio.h | 85 ++ .../include/mach/acpi/bcm2836_gpu.h | 48 ++ .../include/mach/acpi/bcm2836_pwm.h | 34 + .../include/mach/acpi/bcm2836_sdhost.h | 90 ++ .../include/mach/acpi/bcm2836_sdio.h | 203 +++++ arch/sandbox/include/asm/acpi_table.h | 2 + arch/sandbox/include/asm/global_data.h | 1 - arch/sandbox/include/asm/tables.h | 0 arch/x86/Kconfig | 9 - arch/x86/cpu/apollolake/acpi.c | 17 +- arch/x86/cpu/baytrail/acpi.c | 27 +- arch/x86/cpu/quark/acpi.c | 27 +- arch/x86/cpu/tangier/acpi.c | 34 +- arch/x86/include/asm/acpi_table.h | 4 - arch/x86/include/asm/global_data.h | 1 - arch/x86/lib/Makefile | 2 +- arch/x86/lib/acpi_table.c | 374 +++------ board/raspberrypi/rpi/Makefile | 2 + board/raspberrypi/rpi/acpitables.h | 189 +++++ board/raspberrypi/rpi/acpitables.inf | 79 ++ board/raspberrypi/rpi/csrt.aslc | 330 ++++++++ board/raspberrypi/rpi/dbg2miniuart.aslc | 81 ++ board/raspberrypi/rpi/dbg2pl011.aslc | 81 ++ board/raspberrypi/rpi/dsdt.asl | 285 +++++++ board/raspberrypi/rpi/emmc.asl | 166 ++++ board/raspberrypi/rpi/fadt.aslc | 96 +++ board/raspberrypi/rpi/gpudevs.asl | 397 +++++++++ board/raspberrypi/rpi/gtdt.aslc | 55 ++ board/raspberrypi/rpi/iort.aslc | 100 +++ board/raspberrypi/rpi/madt.aslc | 78 ++ board/raspberrypi/rpi/pci.asl | 168 ++++ board/raspberrypi/rpi/pep.asl | 90 ++ board/raspberrypi/rpi/pep.c | 79 ++ board/raspberrypi/rpi/pep.h | 121 +++ board/raspberrypi/rpi/pptt.aslc | 191 +++++ board/raspberrypi/rpi/rhpx.asl | 195 +++++ board/raspberrypi/rpi/rpi.c | 460 +++++++++- board/raspberrypi/rpi/rpi4.dsc | 790 ++++++++++++++++++ board/raspberrypi/rpi/sdhc.asl | 119 +++ board/raspberrypi/rpi/spcrminiuart.aslc | 91 ++ board/raspberrypi/rpi/spcrpl011.aslc | 91 ++ board/raspberrypi/rpi/ssdtthermal.asl | 77 ++ board/raspberrypi/rpi/uart.asl | 202 +++++ board/raspberrypi/rpi/xhci.asl | 165 ++++ cmd/acpi.c | 13 +- cmd/bootefi.c | 44 +- configs/cherryhill_defconfig | 1 + configs/chromebook_link64_defconfig | 1 + configs/chromebook_link_defconfig | 1 + configs/chromebook_samus_tpl_defconfig | 1 + configs/coreboot64_defconfig | 1 + configs/coreboot_defconfig | 1 + configs/crownbay_defconfig | 1 + configs/efi-x86_payload32_defconfig | 1 + configs/efi-x86_payload64_defconfig | 1 + configs/rpi_4_defconfig | 2 + configs/slimbootloader_defconfig | 1 + configs/tools-only_defconfig | 1 + doc/build/gcc.rst | 17 + doc/usage/acpi.rst | 235 ++++++ doc/usage/index.rst | 1 + drivers/core/acpi.c | 70 +- drivers/misc/qfw.c | 3 +- include/acpi/acpi_table.h | 235 +++++- include/asm-generic/global_data.h | 8 + include/dm/acpi.h | 110 +++ lib/Kconfig | 18 + lib/Makefile | 2 +- lib/acpi/Makefile | 23 +- lib/acpi/acpi_table.c | 82 -- lib/acpi/acpi_writer.c | 132 +++ lib/acpi/base.c | 94 +++ lib/acpi/csrt.c | 49 ++ lib/acpi/dsdt.c | 55 ++ lib/acpi/facs.c | 35 + lib/acpi/ssdt.c | 49 ++ lib/efi_loader/Makefile | 2 - lib/efi_loader/efi_acpi.c | 5 +- scripts/Makefile.lib | 3 +- test/dm/acpi.c | 79 +- 88 files changed, 6875 insertions(+), 506 deletions(-) create mode 100644 arch/arm/mach-bcm283x/include/mach/acpi/bcm2711.h create mode 100644 arch/arm/mach-bcm283x/include/mach/acpi/bcm2836.h create mode 100644
arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_gpio.h
create mode 100644 arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_gpu.h create mode 100644 arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_pwm.h create mode 100644
arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_sdhost.h
create mode 100644
arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_sdio.h
create mode 100644 arch/sandbox/include/asm/tables.h create mode 100644 board/raspberrypi/rpi/acpitables.h create mode 100644 board/raspberrypi/rpi/acpitables.inf create mode 100644 board/raspberrypi/rpi/csrt.aslc create mode 100644 board/raspberrypi/rpi/dbg2miniuart.aslc create mode 100644 board/raspberrypi/rpi/dbg2pl011.aslc create mode 100644 board/raspberrypi/rpi/dsdt.asl create mode 100644 board/raspberrypi/rpi/emmc.asl create mode 100644 board/raspberrypi/rpi/fadt.aslc create mode 100644 board/raspberrypi/rpi/gpudevs.asl create mode 100644 board/raspberrypi/rpi/gtdt.aslc create mode 100644 board/raspberrypi/rpi/iort.aslc create mode 100644 board/raspberrypi/rpi/madt.aslc create mode 100644 board/raspberrypi/rpi/pci.asl create mode 100644 board/raspberrypi/rpi/pep.asl create mode 100644 board/raspberrypi/rpi/pep.c create mode 100644 board/raspberrypi/rpi/pep.h create mode 100644 board/raspberrypi/rpi/pptt.aslc create mode 100644 board/raspberrypi/rpi/rhpx.asl create mode 100644 board/raspberrypi/rpi/rpi4.dsc create mode 100644 board/raspberrypi/rpi/sdhc.asl create mode 100644 board/raspberrypi/rpi/spcrminiuart.aslc create mode 100644 board/raspberrypi/rpi/spcrpl011.aslc create mode 100644 board/raspberrypi/rpi/ssdtthermal.asl create mode 100644 board/raspberrypi/rpi/uart.asl create mode 100644 board/raspberrypi/rpi/xhci.asl create mode 100644 doc/usage/acpi.rst create mode 100644 lib/acpi/acpi_writer.c create mode 100644 lib/acpi/base.c create mode 100644 lib/acpi/csrt.c create mode 100644 lib/acpi/dsdt.c create mode 100644 lib/acpi/facs.c create mode 100644 lib/acpi/ssdt.c
-- 2.34.0.rc2.393.gf8c9666880-goog
-- With Best Regards, Andy Shevchenko

On Wed, Dec 01, 2021 at 06:50:05PM +0100, François Ozog wrote:
Hi
Le mer. 1 déc. 2021 à 18:16, Andy Shevchenko andy.shevchenko@gmail.com a écrit :
On Wed, Dec 1, 2021 at 6:56 PM Simon Glass sjg@chromium.org wrote:
At present in U-Boot ACPI tables are only generated for x86 devices. It
is
possible to build them for ARM as well. That is the subject of this series.
in the case of RPI4 what is needed is a translator from DT handed by Videocore. If you mean generated from an assumed configuration, that may not be good. Doing static ACPI based on assumptions as a first step is a dangerous path.
There are certainly some downsides to using a Pi, which is a lowest common denominator platform, and so yes, some things we need to keep in mind moving forward with more platforms.

Hi Bin,
On Wed, 1 Dec 2021 at 09:04, Simon Glass sjg@chromium.org wrote:
At present in U-Boot ACPI tables are only generated for x86 devices. It is possible to build them for ARM as well. That is the subject of this series.
The goal is to allow a rpi4 boot into Linux on ARM using ACPI rather than devicetree. This is not due to any feeling that ACPI offers advantages to the boot flow, merely because it can be done.
This goal is not yet achieved. Mostly all that is achieved is some refactoring of the ACPI code, but that is enough to get things at least building on ARM. The rpi-4 the tables are installed and the board boots to grub, where it is then unable to find the OS on the USB stick that is inserted. Further work is needed to complete things, but the ACPI changes can be applied as is.
In terms of review, please ignore the RFC/WIP patches as they need to be reworked. I am sending this series in this state to avoid sitting on patches for too long and risking duplicate effort.
The following tables are emitted with this series:
- GTDT - Generic Timer Description Table
- APIC - Multiple Advanced Programmable Interrupt Controller Description Table (some new records for ARM)
- DSDT - Differentiated System Description Table
- DBG2 - Debug Port Table 2
- FACP - Firmware ACPI Control Structure
- CSRT - Core System Resource Table
- PPTT - Processor Properties Topology Table
Missing still are:
- SSDR - Secondary System Description Table
- BGRT - Boot Graphics Resource Table
Future work is needed to:
- Finish the remaining two tables
- Get things booting nicely on rpi4
- Find a nice way to select between ACPI and devicetree at runtime
- Obtain the ACPI information from the devicetree instead of #defines
- Use the U-Boot bcm headers instead of importing new ones
- Drop the unused files
- Add some documentation
To test it, boot U-Boot on a rpi_4 with a suitable distribution.
This series is available at u-boot-dm/acpi-working
Simon Glass (40): Makefile: Allow LTO to be disabled for a build x86: Allow any arch to generate ACPI tables x86: Move the acpi table to generic global_data arm: Allow supporting ACPI-table generation x86: Tidy up use of CONFIG_ACPIGEN sandbox: Allow building with GENERATE_ACPI_TABLE efi: Correct call to write_acpi_tables() efi: Correct address handling with ACPI tables acpi: Use finer-grained control of ACPI-table generation acpi: Allow include files within the board directory acpi: Move acpi_fill_header() to the generic header acpi: Add a table start acpi: Add a linker list for ACPI tables x86: acpi: Split out context creation from base tables x86: Use the ACPI table writer x86: Move base tables to a writer function x86: Move FACS table to a writer function x86: Move DSDT table to a writer function x86: Move GNVS table to a writer function x86: Move FADT table to a writer function x86: Move FACP table into separate functions x86: Move SSDT table to a writer function x86: Move TPM2 table to a writer function x86: Move MADT table to a writer function x86: Move TCPA table to a writer function x86: Move CSRT table to a writer function x86: acpi: Update acpi_fill_csrt() to use acpi_ctx x86: Move device-specific ACPI tables to a writer function x86: Move acpi_get_rsdp_addr() ACPI tables to the writer acpi: Collect tables in the acpi_item list acpi: Tidy up the item list acpi: Tidy up the table list doc: Add usage information for the acpi command acpi: Add some tables needed by ARM devices acpi: Add myself as maintainer WIP: Add debugging for ACPI emission RFC: Allow passing ACPI tables to bootefi WIP: Add ASL files from tianocore WIP: Bring in some header files from tianocore RFC: rpi: Enable booting with ACPI tables
MAINTAINERS | 6 + Makefile | 18 +- arch/Kconfig | 6 +- arch/arm/config.mk | 4 +- arch/arm/include/asm/acpi_table.h | 15 + arch/arm/include/asm/global_data.h | 2 +- .../mach-bcm283x/include/mach/acpi/bcm2711.h | 93 +++ .../mach-bcm283x/include/mach/acpi/bcm2836.h | 124 +++ .../include/mach/acpi/bcm2836_gpio.h | 85 ++ .../include/mach/acpi/bcm2836_gpu.h | 48 ++ .../include/mach/acpi/bcm2836_pwm.h | 34 + .../include/mach/acpi/bcm2836_sdhost.h | 90 ++ .../include/mach/acpi/bcm2836_sdio.h | 203 +++++ arch/sandbox/include/asm/acpi_table.h | 2 + arch/sandbox/include/asm/global_data.h | 1 - arch/sandbox/include/asm/tables.h | 0 arch/x86/Kconfig | 9 - arch/x86/cpu/apollolake/acpi.c | 17 +- arch/x86/cpu/baytrail/acpi.c | 27 +- arch/x86/cpu/quark/acpi.c | 27 +- arch/x86/cpu/tangier/acpi.c | 34 +- arch/x86/include/asm/acpi_table.h | 4 - arch/x86/include/asm/global_data.h | 1 - arch/x86/lib/Makefile | 2 +- arch/x86/lib/acpi_table.c | 374 +++------ board/raspberrypi/rpi/Makefile | 2 + board/raspberrypi/rpi/acpitables.h | 189 +++++ board/raspberrypi/rpi/acpitables.inf | 79 ++ board/raspberrypi/rpi/csrt.aslc | 330 ++++++++ board/raspberrypi/rpi/dbg2miniuart.aslc | 81 ++ board/raspberrypi/rpi/dbg2pl011.aslc | 81 ++ board/raspberrypi/rpi/dsdt.asl | 285 +++++++ board/raspberrypi/rpi/emmc.asl | 166 ++++ board/raspberrypi/rpi/fadt.aslc | 96 +++ board/raspberrypi/rpi/gpudevs.asl | 397 +++++++++ board/raspberrypi/rpi/gtdt.aslc | 55 ++ board/raspberrypi/rpi/iort.aslc | 100 +++ board/raspberrypi/rpi/madt.aslc | 78 ++ board/raspberrypi/rpi/pci.asl | 168 ++++ board/raspberrypi/rpi/pep.asl | 90 ++ board/raspberrypi/rpi/pep.c | 79 ++ board/raspberrypi/rpi/pep.h | 121 +++ board/raspberrypi/rpi/pptt.aslc | 191 +++++ board/raspberrypi/rpi/rhpx.asl | 195 +++++ board/raspberrypi/rpi/rpi.c | 460 +++++++++- board/raspberrypi/rpi/rpi4.dsc | 790 ++++++++++++++++++ board/raspberrypi/rpi/sdhc.asl | 119 +++ board/raspberrypi/rpi/spcrminiuart.aslc | 91 ++ board/raspberrypi/rpi/spcrpl011.aslc | 91 ++ board/raspberrypi/rpi/ssdtthermal.asl | 77 ++ board/raspberrypi/rpi/uart.asl | 202 +++++ board/raspberrypi/rpi/xhci.asl | 165 ++++ cmd/acpi.c | 13 +- cmd/bootefi.c | 44 +- configs/cherryhill_defconfig | 1 + configs/chromebook_link64_defconfig | 1 + configs/chromebook_link_defconfig | 1 + configs/chromebook_samus_tpl_defconfig | 1 + configs/coreboot64_defconfig | 1 + configs/coreboot_defconfig | 1 + configs/crownbay_defconfig | 1 + configs/efi-x86_payload32_defconfig | 1 + configs/efi-x86_payload64_defconfig | 1 + configs/rpi_4_defconfig | 2 + configs/slimbootloader_defconfig | 1 + configs/tools-only_defconfig | 1 + doc/build/gcc.rst | 17 + doc/usage/acpi.rst | 235 ++++++ doc/usage/index.rst | 1 + drivers/core/acpi.c | 70 +- drivers/misc/qfw.c | 3 +- include/acpi/acpi_table.h | 235 +++++- include/asm-generic/global_data.h | 8 + include/dm/acpi.h | 110 +++ lib/Kconfig | 18 + lib/Makefile | 2 +- lib/acpi/Makefile | 23 +- lib/acpi/acpi_table.c | 82 -- lib/acpi/acpi_writer.c | 132 +++ lib/acpi/base.c | 94 +++ lib/acpi/csrt.c | 49 ++ lib/acpi/dsdt.c | 55 ++ lib/acpi/facs.c | 35 + lib/acpi/ssdt.c | 49 ++ lib/efi_loader/Makefile | 2 - lib/efi_loader/efi_acpi.c | 5 +- scripts/Makefile.lib | 3 +- test/dm/acpi.c | 79 +- 88 files changed, 6875 insertions(+), 506 deletions(-) create mode 100644 arch/arm/mach-bcm283x/include/mach/acpi/bcm2711.h create mode 100644 arch/arm/mach-bcm283x/include/mach/acpi/bcm2836.h create mode 100644 arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_gpio.h create mode 100644 arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_gpu.h create mode 100644 arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_pwm.h create mode 100644 arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_sdhost.h create mode 100644 arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_sdio.h create mode 100644 arch/sandbox/include/asm/tables.h create mode 100644 board/raspberrypi/rpi/acpitables.h create mode 100644 board/raspberrypi/rpi/acpitables.inf create mode 100644 board/raspberrypi/rpi/csrt.aslc create mode 100644 board/raspberrypi/rpi/dbg2miniuart.aslc create mode 100644 board/raspberrypi/rpi/dbg2pl011.aslc create mode 100644 board/raspberrypi/rpi/dsdt.asl create mode 100644 board/raspberrypi/rpi/emmc.asl create mode 100644 board/raspberrypi/rpi/fadt.aslc create mode 100644 board/raspberrypi/rpi/gpudevs.asl create mode 100644 board/raspberrypi/rpi/gtdt.aslc create mode 100644 board/raspberrypi/rpi/iort.aslc create mode 100644 board/raspberrypi/rpi/madt.aslc create mode 100644 board/raspberrypi/rpi/pci.asl create mode 100644 board/raspberrypi/rpi/pep.asl create mode 100644 board/raspberrypi/rpi/pep.c create mode 100644 board/raspberrypi/rpi/pep.h create mode 100644 board/raspberrypi/rpi/pptt.aslc create mode 100644 board/raspberrypi/rpi/rhpx.asl create mode 100644 board/raspberrypi/rpi/rpi4.dsc create mode 100644 board/raspberrypi/rpi/sdhc.asl create mode 100644 board/raspberrypi/rpi/spcrminiuart.aslc create mode 100644 board/raspberrypi/rpi/spcrpl011.aslc create mode 100644 board/raspberrypi/rpi/ssdtthermal.asl create mode 100644 board/raspberrypi/rpi/uart.asl create mode 100644 board/raspberrypi/rpi/xhci.asl create mode 100644 doc/usage/acpi.rst create mode 100644 lib/acpi/acpi_writer.c create mode 100644 lib/acpi/base.c create mode 100644 lib/acpi/csrt.c create mode 100644 lib/acpi/dsdt.c create mode 100644 lib/acpi/facs.c create mode 100644 lib/acpi/ssdt.c
-- 2.34.0.rc2.393.gf8c9666880-goog
Any thoughts on this series? It affects x86 quite a bit, so I would appreciate any testing you can do. I have tried on coral, which uses ACPI a lot.
Regards, Simon

Hi,
On Tue, 14 Dec 2021 at 20:28, Simon Glass sjg@chromium.org wrote:
Hi Bin,
On Wed, 1 Dec 2021 at 09:04, Simon Glass sjg@chromium.org wrote:
At present in U-Boot ACPI tables are only generated for x86 devices. It is possible to build them for ARM as well. That is the subject of this series.
The goal is to allow a rpi4 boot into Linux on ARM using ACPI rather than devicetree. This is not due to any feeling that ACPI offers advantages to the boot flow, merely because it can be done.
This goal is not yet achieved. Mostly all that is achieved is some refactoring of the ACPI code, but that is enough to get things at least building on ARM. The rpi-4 the tables are installed and the board boots to grub, where it is then unable to find the OS on the USB stick that is inserted. Further work is needed to complete things, but the ACPI changes can be applied as is.
In terms of review, please ignore the RFC/WIP patches as they need to be reworked. I am sending this series in this state to avoid sitting on patches for too long and risking duplicate effort.
The following tables are emitted with this series:
- GTDT - Generic Timer Description Table
- APIC - Multiple Advanced Programmable Interrupt Controller Description Table (some new records for ARM)
- DSDT - Differentiated System Description Table
- DBG2 - Debug Port Table 2
- FACP - Firmware ACPI Control Structure
- CSRT - Core System Resource Table
- PPTT - Processor Properties Topology Table
Missing still are:
- SSDR - Secondary System Description Table
- BGRT - Boot Graphics Resource Table
Future work is needed to:
- Finish the remaining two tables
- Get things booting nicely on rpi4
- Find a nice way to select between ACPI and devicetree at runtime
- Obtain the ACPI information from the devicetree instead of #defines
- Use the U-Boot bcm headers instead of importing new ones
- Drop the unused files
- Add some documentation
To test it, boot U-Boot on a rpi_4 with a suitable distribution.
This series is available at u-boot-dm/acpi-working
[..]
Thanks Andy for the review. I'm going to apply the first part of this tomorrow and see if we can get it in before rc1. Then I'll give the rpi bit another crack.
Regards, Simon
participants (6)
-
Andy Shevchenko
-
François Ozog
-
Heinrich Schuchardt
-
Mark Kettenis
-
Simon Glass
-
Tom Rini