"Das U-Boot" Source Tree

Merge patch series "Implement ACPI on aarch64"

Patrick Rudolph <patrick.rudolph@9elements.com> says:

Based on the existing work done by Simon Glass this series adds
support for booting aarch64 devices using ACPI only.
As first target QEMU SBSA support is added, which relies on ACPI
only to boot an OS. As secondary target the Raspberry Pi4 was used,
which is broadly available and allows easy testing of the proposed
solution.

The series is split into ACPI cleanups and code movements, adding
Arm specific ACPI tables and finally SoC and mainboard related
changes to boot a Linux on the QEMU SBSA and RPi4. Currently only the
mandatory ACPI tables are supported, allowing to boot into Linux
without errors.

The QEMU SBSA support is feature complete and provides the same
functionality as the EDK2 implementation.

The changes were tested on real hardware as well on QEMU v9.0:

qemu-system-aarch64 -machine sbsa-ref -nographic -cpu cortex-a57 \
-pflash secure-world.rom \
-pflash unsecure-world.rom

qemu-system-aarch64 -machine raspi4b -kernel u-boot.bin -cpu cortex-a72 \
-smp 4 -m 2G -drive file=raspbian.img,format=raw,index=0 \
-dtb bcm2711-rpi-4-b.dtb -nographic

Tested against FWTS V24.03.00.

Known issues:
- The QEMU rpi4 support is currently limited as it doesn't emulate PCI,
USB or ethernet devices!
- The SMP bringup doesn't work on RPi4, but works in QEMU (Possibly
cache related).
- PCI on RPI4 isn't working on real hardware since the pcie_brcmstb
Linux kernel module doesn't support ACPI yet.

Link: https://lore.kernel.org/r/20241023132116.970117-1-patrick.rudolph@9elements.com

+6518 -541
+8
.azure-pipelines.yml
··· 255 255 wget -O - https://github.com/riscv-software-src/opensbi/releases/download/v1.3.1/opensbi-1.3.1-rv-bin.tar.xz | tar -C /tmp -xJ; 256 256 export OPENSBI=/tmp/opensbi-1.3.1-rv-bin/share/opensbi/lp64/generic/firmware/fw_dynamic.bin; 257 257 fi 258 + if [[ "\${TEST_PY_BD}" == "qemu-arm-sbsa" ]]; then 259 + wget -O /tmp/bl1.bin https://artifacts.codelinaro.org/artifactory/linaro-419-sbsa-ref/latest/tf-a/bl1.bin; 260 + wget -O /tmp/fip.bin https://artifacts.codelinaro.org/artifactory/linaro-419-sbsa-ref/latest/tf-a/fip.bin; 261 + export BINMAN_INDIRS=/tmp 262 + fi 258 263 # the below corresponds to .gitlab-ci.yml "script" 259 264 cd \${WORK_DIR} 260 265 export UBOOT_TRAVIS_BUILD_DIR=/tmp/\${TEST_PY_BD} ··· 426 431 qemu_arm64_lwip: 427 432 TEST_PY_BD: "qemu_arm64_lwip" 428 433 TEST_PY_TEST_SPEC: "test_net_dhcp or test_net_ping or test_net_tftpboot" 434 + qemu_arm_sbsa_ref: 435 + TEST_PY_BD: "qemu-arm-sbsa" 436 + TEST_PY_TEST_SPEC: "not sleep" 429 437 qemu_m68k: 430 438 TEST_PY_BD: "M5208EVBE" 431 439 TEST_PY_ID: "--id qemu"
+11
.gitlab-ci.yml
··· 42 42 wget -O - https://github.com/riscv-software-src/opensbi/releases/download/v1.3.1/opensbi-1.3.1-rv-bin.tar.xz | tar -C /tmp -xJ; 43 43 export OPENSBI=/tmp/opensbi-1.3.1-rv-bin/share/opensbi/lp64/generic/firmware/fw_dynamic.bin; 44 44 fi 45 + - if [[ "${TEST_PY_BD}" == "qemu-arm-sbsa" ]]; then 46 + wget -O /tmp/bl1.bin https://artifacts.codelinaro.org/artifactory/linaro-419-sbsa-ref/latest/tf-a/bl1.bin; 47 + wget -O /tmp/fip.bin https://artifacts.codelinaro.org/artifactory/linaro-419-sbsa-ref/latest/tf-a/fip.bin; 48 + export BINMAN_INDIRS=/tmp; 49 + fi 45 50 46 51 after_script: 47 52 - cp -v /tmp/${TEST_PY_BD}/*.{html,css,xml} . ··· 355 360 variables: 356 361 TEST_PY_BD: "qemu_arm64_lwip" 357 362 TEST_PY_TEST_SPEC: "test_net_dhcp or test_net_ping or test_net_tftpboot" 363 + <<: *buildman_and_testpy_dfn 364 + 365 + qemu_arm_sbsa test.py: 366 + variables: 367 + TEST_PY_BD: "qemu-arm-sbsa" 368 + TEST_PY_TEST_SPEC: "not sleep" 358 369 <<: *buildman_and_testpy_dfn 359 370 360 371 qemu_m68k test.py:
+1 -1
MAINTAINERS
··· 355 355 T: git https://source.denx.de/u-boot/custodians/u-boot-marvell.git 356 356 F: arch/arm/mach-kirkwood/ 357 357 F: arch/arm/mach-mvebu/ 358 - F: drivers/ata/ahci_mvebu.c 358 + F: drivers/ata/ahci_generic.c 359 359 F: drivers/clk/mvebu/ 360 360 F: drivers/ddr/marvell/ 361 361 F: drivers/gpio/mvebu_gpio.c
+10 -1
arch/arm/Kconfig
··· 113 113 config GICV3 114 114 bool 115 115 116 + config DRIVER_GICV2 117 + bool "ARM GICV2 driver" 118 + select IRQ 119 + help 120 + ARM GICV2 driver. 121 + Basic support for parsing the GICV2 node and generate ACPI tables. 122 + 116 123 config GIC_V3_ITS 117 124 bool "ARM GICV3 ITS" 118 125 select IRQ ··· 644 651 645 652 config ARCH_BCM283X 646 653 bool "Broadcom BCM283X family" 654 + select CPU 647 655 select DM 648 656 select DM_GPIO 649 657 select DM_SERIAL ··· 1047 1055 imply DM_RNG 1048 1056 imply DM_RTC 1049 1057 imply RTC_PL031 1050 - imply OF_HAS_PRIOR_STAGE 1058 + imply OF_HAS_PRIOR_STAGE if !TARGET_QEMU_ARM_SBSA 1051 1059 imply VIDEO 1052 1060 imply VIDEO_BOCHS 1053 1061 imply SYS_WHITE_ON_BLACK ··· 2374 2382 source "board/cavium/thunderx/Kconfig" 2375 2383 source "board/eets/pdu001/Kconfig" 2376 2384 source "board/emulation/qemu-arm/Kconfig" 2385 + source "board/emulation/qemu-sbsa/Kconfig" 2377 2386 source "board/freescale/ls2080aqds/Kconfig" 2378 2387 source "board/freescale/ls2080ardb/Kconfig" 2379 2388 source "board/freescale/ls1088a/Kconfig"
+1
arch/arm/cpu/armv8/Makefile
··· 29 29 30 30 ifndef CONFIG_XPL_BUILD 31 31 obj-$(CONFIG_ARMV8_SPIN_TABLE) += spin_table.o spin_table_v8.o 32 + obj-$(CONFIG_ACPI_PARKING_PROTOCOL) += acpi_park_v8.o 32 33 else 33 34 obj-$(CONFIG_ARCH_SUNXI) += fel_utils.o 34 35 endif
+113
arch/arm/cpu/armv8/acpi_park_v8.S
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + /* 3 + * Copyright (C) 2024 9elements GmbH 4 + * Author: Patrick Rudolph <patrick.rudolph@9elements.com> 5 + * 6 + * This file provides ARMv8 specific code for the generic part of the 7 + * ACPI parking protocol implementation. It contains the spinning code 8 + * that will be installed into the parking protocol and it points the 9 + * secondary CPUs to their own parking protocol page once it has been 10 + * set up by the generic part. 11 + */ 12 + 13 + #include <asm/acpi_table.h> 14 + #include <linux/linkage.h> 15 + 16 + /* Filled by C code */ 17 + .global acpi_pp_tables 18 + acpi_pp_tables: 19 + .quad 0 20 + 21 + .global acpi_pp_etables 22 + acpi_pp_etables: 23 + .quad 0 24 + 25 + /* Read by C code */ 26 + .global acpi_pp_code_size 27 + acpi_pp_code_size: 28 + .word __secondary_pp_code_end - __secondary_pp_code_start 29 + 30 + .global acpi_pp_secondary_jump 31 + ENTRY(acpi_pp_secondary_jump) 32 + 0: 33 + /* 34 + * Cannot use atomic operations since the MMU and D-cache 35 + * might be off. Use the MPIDR instead to find the spintable. 36 + */ 37 + 38 + /* Check if parking protocol table is ready */ 39 + ldr x1, =acpi_pp_tables 40 + ldr x0, [x1] 41 + cbnz x0, 0f 42 + wfe 43 + b 0b 44 + 45 + 0: /* Get end of page tables in x3 */ 46 + ldr x1, =acpi_pp_etables 47 + ldr x3, [x1] 48 + 49 + /* Get own CPU ID in w2 */ 50 + mrs x2, mpidr_el1 51 + lsr x9, x2, #32 52 + bfi x2, x9, #24, #8 /* w2 is aff3:aff2:aff1:aff0 */ 53 + 54 + 0: /* Loop over all parking protocol pages */ 55 + cmp x0, x3 56 + b.ge hlt 57 + 58 + /* Fetch CPU_ID from current page */ 59 + ldr x1, [x0, #ACPI_PP_CPU_ID_OFFSET] 60 + lsr x9, x1, #32 61 + bfi x1, x9, #24, #8 /* w1 is aff3:aff2:aff1:aff0 */ 62 + 63 + /* Compare CPU_IDs */ 64 + cmp w1, w2 65 + b.eq 0f 66 + 67 + add x0, x0, #ACPI_PP_PAGE_SIZE 68 + b 0b 69 + 70 + hlt: wfi 71 + b hlt /* Should never happen. */ 72 + 73 + 0: /* x0 points to the 4K-aligned, parking protocol page */ 74 + add x2, x0, #ACPI_PP_CPU_CODE_OFFSET 75 + 76 + /* Jump to spin code in own parking protocol page */ 77 + br x2 78 + ENDPROC(acpi_pp_secondary_jump) 79 + 80 + .align 8 81 + __secondary_pp_code_start: 82 + .global acpi_pp_code_start 83 + ENTRY(acpi_pp_code_start) 84 + /* x0 points to the 4K-aligned, parking protocol page */ 85 + 86 + /* Prepare defines for spinning code */ 87 + mov w3, #ACPI_PP_CPU_ID_INVALID 88 + mov x2, #ACPI_PP_JMP_ADR_INVALID 89 + 90 + /* Mark parking protocol page as ready */ 91 + str w3, [x0, #ACPI_PP_CPU_ID_OFFSET] 92 + dsb sy 93 + 94 + 0: wfe 95 + ldr w1, [x0, #ACPI_PP_CPU_ID_OFFSET] 96 + 97 + /* Check CPU ID is valid */ 98 + cmp w1, w3 99 + b.eq 0b 100 + 101 + /* Check jump address valid */ 102 + ldr x1, [x0, #ACPI_PP_CPU_JMP_OFFSET] 103 + cmp x1, x2 104 + b.eq 0b 105 + 106 + /* Clear jump address before jump */ 107 + str x2, [x0, #ACPI_PP_CPU_JMP_OFFSET] 108 + dsb sy 109 + 110 + br x1 111 + ENDPROC(acpi_pp_code_start) 112 + /* Secondary Boot Code ends here */ 113 + __secondary_pp_code_end:
+12
arch/arm/cpu/armv8/start.S
··· 178 178 branch_if_master x0, master_cpu 179 179 b spin_table_secondary_jump 180 180 /* never return */ 181 + #elif defined(CONFIG_ACPI_PARKING_PROTOCOL) && !defined(CONFIG_SPL_BUILD) 182 + branch_if_master x0, master_cpu 183 + /* 184 + * Waits for ACPI parking protocol memory to be allocated and the spin-table 185 + * code to be written. Once ready the secondary CPUs will jump and spin in 186 + * their own 4KiB memory region, which is also used as mailbox, until released 187 + * by the OS. 188 + * The mechanism is similar to the DT enable-method = "spin-table", but works 189 + * with ACPI enabled platforms. 190 + */ 191 + b acpi_pp_secondary_jump 192 + /* never return */ 181 193 #elif defined(CONFIG_ARMV8_MULTIENTRY) 182 194 branch_if_master x0, master_cpu 183 195
+138
arch/arm/dts/qemu-sbsa.dts
··· 1 + // SPDX-License-Identifier: GPL-2.0+ OR MIT 2 + /* 3 + * Devicetree with onboard devices for qemu_sbsa-ref for internal use only! 4 + * DO NOT PASS TO THE OS! 5 + * 6 + * As QEMU provides only a minimal devicetree this one is merged with 7 + * it and then fixed at runtime. 8 + * 9 + * Copyright 2024 9elements GmbH 10 + */ 11 + #include "configs/qemu-sbsa.h" 12 + #include <dt-bindings/interrupt-controller/arm-gic.h> 13 + 14 + /dts-v1/; 15 + 16 + / { 17 + #address-cells = <2>; 18 + #size-cells = <2>; 19 + interrupt-parent = <&intc>; 20 + compatible = "linux,sbsa-ref"; 21 + 22 + binman: binman { 23 + multiple-images; 24 + }; 25 + 26 + cpus { 27 + /* Filled by fdtdec_board_setup() */ 28 + }; 29 + 30 + memory { 31 + /* Filled by fdtdec_board_setup() */ 32 + }; 33 + 34 + soc { 35 + compatible = "simple-bus"; 36 + #address-cells = <2>; 37 + #size-cells = <2>; 38 + ranges; 39 + 40 + cfi_flash { 41 + compatible = "cfi-flash"; 42 + reg = /bits/ 64 <SBSA_FLASH_BASE_ADDR 43 + SBSA_FLASH_LENGTH>; 44 + status = "okay"; 45 + }; 46 + 47 + uart0 { 48 + compatible = "arm,pl011"; 49 + status = "okay"; 50 + reg = /bits/ 64 <SBSA_UART_BASE_ADDR 51 + SBSA_UART_LENGTH>; 52 + }; 53 + 54 + ahci { 55 + compatible = "generic-ahci"; 56 + status = "okay"; 57 + reg = /bits/ 64 <0x60100000 0x00010000>; 58 + }; 59 + 60 + xhci { 61 + compatible = "generic-xhci"; 62 + status = "okay"; 63 + reg = /bits/ 64 <0x60110000 0x00010000>; 64 + }; 65 + 66 + pci { 67 + #address-cells = <3>; 68 + #size-cells = <2>; 69 + compatible = "pci-host-ecam-generic"; 70 + device_type = "pci"; 71 + status = "okay"; 72 + reg = /bits/ 64 <0xf0000000 0x10000000>; 73 + bus-range = <0 0xff>; 74 + ranges = /bits/ 32 <0x01000000>, 75 + /bits/ 64 <0 76 + SBSA_PIO_BASE_ADDR 77 + SBSA_PIO_LENGTH>, 78 + /bits/ 32 <0x02000000>, 79 + /bits/ 64 <SBSA_PCIE_MMIO_BASE_ADDR 80 + SBSA_PCIE_MMIO_BASE_ADDR 81 + SBSA_PCIE_MMIO_LENGTH>, 82 + /bits/ 32 <0x43000000>, 83 + /bits/ 64 <SBSA_PCIE_MMIO_HIGH_BASE_ADDR 84 + SBSA_PCIE_MMIO_HIGH_BASE_ADDR 85 + SBSA_PCIE_MMIO_HIGH_LENGTH>; 86 + }; 87 + }; 88 + 89 + intc: interrupt-controller { 90 + compatible = "arm,gic-v3"; 91 + #interrupt-cells = <3>; 92 + status = "okay"; 93 + interrupt-controller; 94 + interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; 95 + reg = /bits/ 64 <SBSA_GIC_DIST_BASE_ADDR SBSA_GIC_DIST_LENGTH>, 96 + /bits/ 64 <SBSA_GIC_REDIST_BASE_ADDR SBSA_GIC_REDIST_LENGTH>, 97 + /bits/ 64 <0 0>, 98 + /bits/ 64 <SBSA_GIC_HBASE_ADDR SBSA_GIC_HBASE_LENGTH>, 99 + /bits/ 64 <SBSA_GIC_VBASE_ADDR SBSA_GIC_VBASE_LENGTH>; 100 + }; 101 + 102 + its { 103 + compatible = "arm,gic-v3-its"; 104 + status = "disabled"; 105 + }; 106 + }; 107 + 108 + &binman { 109 + secure-world { 110 + filename = "secure-world.rom"; 111 + size = <SBSA_SECURE_FLASH_LENGTH>; 112 + 113 + bl1 { 114 + offset = <0x0>; 115 + description = "ARM Trusted Firmware BL1"; 116 + filename = "bl1.bin"; 117 + type = "blob-ext"; 118 + }; 119 + 120 + fip { 121 + offset = <0x12000>; 122 + description = "ARM Trusted Firmware FIP"; 123 + filename = "fip.bin"; 124 + type = "blob-ext"; 125 + }; 126 + }; 127 + 128 + unsecure-world { 129 + filename = "unsecure-world.rom"; 130 + size = <SBSA_FLASH_LENGTH>; 131 + 132 + u-boot { 133 + }; 134 + u-boot-dtb { 135 + compress = "lz4"; 136 + }; 137 + }; 138 + };
+147
arch/arm/include/asm/acpi_table.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 + 3 + #ifndef __ASM_ACPI_TABLE_H__ 4 + #define __ASM_ACPI_TABLE_H__ 5 + 6 + #ifndef __ACPI__ 7 + #ifndef __ASSEMBLY__ 8 + 9 + #include <acpi/acpi_table.h> 10 + 11 + /** 12 + * acpi_write_madt_gicc() - Write out a MADT GICC sub-table 13 + * 14 + * Write out the GIC CPU Interface sub-table. 15 + * 16 + * @gicc: Pointer to place to put the sub-table 17 + * @cpu_num: GIC's CPU Interface Number 18 + * @perf_gsiv: The GSIV used for Performance Monitoring Interrupts 19 + * @phys_base: Address at which the processor can access this 20 + * GIC CPU Interface 21 + * @gicv: Address of the GIC virtual CPU interface registers 22 + * @gich: Address of the GIC virtual interface control block 23 + * registers 24 + * @vgic_maint_irq: GSIV for Virtual GIC maintenance interrupt 25 + * @gicr_base: Physical address of the associated Redistributor 26 + * @mpidr: MPIDR as defined by ARM architecture 27 + * @efficiency: Describes the relative power efficiency 28 + */ 29 + void acpi_write_madt_gicc(struct acpi_madt_gicc *gicc, uint cpu_num, 30 + uint perf_gsiv, ulong phys_base, ulong gicv, 31 + ulong gich, uint vgic_maint_irq, u64 gicr_base, 32 + ulong mpidr, uint efficiency); 33 + 34 + /** 35 + * acpi_write_madt_gicd() - Write out a MADT GICD sub-table 36 + * 37 + * Write out the GIC Distributor sub-table. 38 + * 39 + * @gicd: Pointer to place to put the sub-table 40 + * @gic_id: This GIC Distributor's hardware ID 41 + * @phys_base: The 64-bit physical address for this Distributor 42 + * @gic_version: GIC version 43 + */ 44 + void acpi_write_madt_gicd(struct acpi_madt_gicd *gicd, uint gic_id, 45 + ulong phys_base, uint gic_version); 46 + 47 + /** 48 + * acpi_write_madt_gicr() - Write out a MADT GICR sub-table 49 + * 50 + * Write out the GIC Redistributor sub-table. 51 + * 52 + * @gicr: Pointer to place to put the sub-table 53 + * @discovery_range_base_address: Physical address of a page range 54 + * containing all GIC Redistributors 55 + * @discovery_range_length: Length of the GIC Redistributor 56 + * Discovery page range 57 + */ 58 + void acpi_write_madt_gicr(struct acpi_madt_gicr *gicr, 59 + u64 discovery_range_base_address, 60 + u32 discovery_range_length); 61 + 62 + /** 63 + * acpi_write_madt_its() - Write out a MADT ITS sub-table 64 + * 65 + * Write out the GIC Interrupt Translation Service sub-table. 66 + * 67 + * @its: Pointer to place to put the sub-table 68 + * @its_id: Uniqueue GIC ITS ID 69 + * @physical_base_address: Physical address for the Interrupt 70 + * Translation Service 71 + */ 72 + void acpi_write_madt_its(struct acpi_madt_its *its, 73 + u32 its_id, 74 + u64 physical_base_address); 75 + 76 + /** 77 + * acpi_pptt_add_proc() - Write out a PPTT processor sub-table 78 + * 79 + * Write out the Processor Properties Topology Table processor sub-table. 80 + * 81 + * @ctx: ACPI context pointer 82 + * @flags: Processor Structure Flags 83 + * @parent: Reference to parent processor 84 + * @proc_id: ACPI processor ID as defined in MADT 85 + * @num_resources: Number of resource structure references 86 + * @resource_list: References to other PPTT structures 87 + * Return: offset from start of PPTT in bytes 88 + */ 89 + int acpi_pptt_add_proc(struct acpi_ctx *ctx, const u32 flags, const u32 parent, 90 + const u32 proc_id, const u32 num_resources, 91 + const u32 *resource_list); 92 + 93 + /** 94 + * acpi_pptt_add_cache() - Write out a PPTT cache sub-table 95 + * 96 + * Write out the Processor Properties Topology Table cache sub-table. 97 + * 98 + * @ctx: ACPI context pointer 99 + * @flags: Cache Structure Flags 100 + * @next_cache_level: Reference to next level of cache 101 + * @size: Size of the cache in bytes 102 + * @sets: Number of sets in the cache 103 + * @assoc: Integer number of ways 104 + * @attributes: Allocation type, Cache type, policy 105 + * @line_size: Line size in bytes 106 + * Return: offset from start of PPTT in bytes 107 + */ 108 + int acpi_pptt_add_cache(struct acpi_ctx *ctx, const u32 flags, 109 + const u32 next_cache_level, const u32 size, 110 + const u32 sets, const u8 assoc, const u8 attributes, 111 + const u16 line_size); 112 + 113 + /* Multi-processor Startup for ARM Platforms */ 114 + /** 115 + * struct acpi_pp_page - MP startup handshake mailbox 116 + * 117 + * Defines a 4096 byte memory region that is used for starting secondary CPUs on 118 + * an Arm system that follows the "Multi-processor Startup for ARM Platforms" spec. 119 + * 120 + * @cpu_id: MPIDR as returned by the Multiprocessor Affinity Register. 121 + * On 32bit Arm systems the upper bits are unused. 122 + * @jumping_address: On 32bit Arm systems the address must be below 4 GiB 123 + * @os_reserved: Reserved for OS use. Firmware must not access this memory. 124 + * @spinning_code: Reserved for firmware use. OS must not access this memory. 125 + * The spinning code will be installed by firmware and the secondary 126 + * CPUs will enter it before the control is handed over to the OS. 127 + */ 128 + struct acpi_pp_page { 129 + u64 cpu_id; 130 + u64 jumping_address; 131 + u8 os_reserved[2032]; 132 + u8 spinning_code[2048]; 133 + } __packed; 134 + 135 + #endif /* !__ASSEMBLY__ */ 136 + #endif /* !__ACPI__ */ 137 + 138 + /* Multi-processor Startup for ARM Platforms defines */ 139 + #define ACPI_PP_CPU_ID_INVALID 0xffffffff 140 + #define ACPI_PP_JMP_ADR_INVALID 0 141 + #define ACPI_PP_PAGE_SIZE 4096 142 + #define ACPI_PP_CPU_ID_OFFSET 0 143 + #define ACPI_PP_CPU_JMP_OFFSET 8 144 + #define ACPI_PP_CPU_CODE_OFFSET 2048 145 + #define ACPI_PP_VERSION 1 146 + 147 + #endif /* __ASM_ACPI_TABLE_H__ */
+34
arch/arm/include/asm/arch-qemu-sbsa/boot0.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + /* 3 + * sbsa-ref starts U-Boot in XIP memory. Need to relocate U-Boot 4 + * to DRAM which is already up. Instead of using SPL this simple loader 5 + * is being used. 6 + */ 7 + relocate_check: 8 + /* x0 contains the pointer to FDT provided by ATF */ 9 + adr x1, _start /* x1 <- Runtime value of _start */ 10 + ldr x2, _TEXT_BASE /* x2 <- Linked value of _start */ 11 + subs x9, x1, x2 /* x9 <- Run-vs-link offset */ 12 + beq reset 13 + 14 + adrp x1, __image_copy_start /* x2 <- address bits [31:12] */ 15 + add x1, x1, :lo12:__image_copy_start/* x2 <- address bits [11:00] */ 16 + adrp x3, __image_copy_end /* x3 <- address bits [31:12] */ 17 + add x3, x3, :lo12:__image_copy_end /* x3 <- address bits [11:00] */ 18 + add x3, x3, #0x100000 /* 1 MiB for the DTB found at _end */ 19 + 20 + copy_loop: 21 + ldp x10, x11, [x1], #16 /* copy from source address [x1] */ 22 + stp x10, x11, [x2], #16 /* copy to target address [x2] */ 23 + cmp x1, x3 /* until source end address [x3] */ 24 + b.lo copy_loop 25 + 26 + isb 27 + ldr x2, _TEXT_BASE /* x2 <- Linked value of _start */ 28 + br x2 /* Jump to linked address */ 29 + /* Never reaches this point */ 30 + 1: 31 + wfi 32 + b 1b 33 + 34 + relocate_done:
+9
arch/arm/include/asm/system.h
··· 394 394 #define wfi() 395 395 #endif 396 396 397 + static inline unsigned long read_mpidr(void) 398 + { 399 + unsigned long val; 400 + 401 + asm volatile("mrc p15, 0, %0, c0, c0, 5" : "=r" (val)); 402 + 403 + return val; 404 + } 405 + 397 406 static inline unsigned long get_cpsr(void) 398 407 { 399 408 unsigned long cpsr;
+2
arch/arm/lib/Makefile
··· 68 68 ifneq ($(CONFIG_GICV2)$(CONFIG_GICV3),) 69 69 obj-y += gic_64.o 70 70 endif 71 + obj-$(CONFIG_DRIVER_GICV2) += gic-v2.o 71 72 obj-$(CONFIG_GIC_V3_ITS) += gic-v3-its.o 72 73 obj-y += interrupts_64.o 73 74 else ··· 86 87 obj-$(CONFIG_DEBUG_LL) += debug.o 87 88 88 89 obj-$(CONFIG_BLOBLIST) += xferlist.o 90 + obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi_table.o 89 91 90 92 # For EABI conformant tool chains, provide eabi_compat() 91 93 ifneq (,$(findstring -mabi=aapcs-linux,$(PLATFORM_CPPFLAGS)))
+276
arch/arm/lib/acpi_table.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Based on acpi.c from coreboot 4 + * 5 + * Copyright (C) 2024 9elements GmbH 6 + */ 7 + 8 + #define LOG_CATEGORY LOGC_ACPI 9 + 10 + #include <bloblist.h> 11 + #include <cpu_func.h> 12 + #include <efi_loader.h> 13 + #include <malloc.h> 14 + #include <string.h> 15 + #include <tables_csum.h> 16 + #include <acpi/acpigen.h> 17 + #include <acpi/acpi_device.h> 18 + #include <acpi/acpi_table.h> 19 + #include <asm-generic/io.h> 20 + #include <dm/acpi.h> 21 + #include <dm/uclass.h> 22 + #include <linux/log2.h> 23 + #include <linux/sizes.h> 24 + 25 + /* defined in assembly file */ 26 + /** 27 + * acpi_pp_code_size - Spinloop code size * 28 + */ 29 + extern u16 acpi_pp_code_size; 30 + 31 + /** 32 + * acpi_pp_tables - Start of ACPI PP tables. 33 + */ 34 + extern ulong acpi_pp_tables; 35 + 36 + /** 37 + * acpi_pp_etables - End of ACPI PP tables. 38 + */ 39 + extern ulong acpi_pp_etables; 40 + 41 + /** 42 + * acpi_pp_code_start() - Spinloop code 43 + * 44 + * Architectural spinloop code to be installed in each parking protocol 45 + * page. The spinloop code must be less than 2048 bytes. 46 + * 47 + * The spinloop code will be entered after calling 48 + * acpi_parking_protocol_install(). 49 + * 50 + */ 51 + void acpi_pp_code_start(void); 52 + 53 + void acpi_write_madt_gicc(struct acpi_madt_gicc *gicc, uint cpu_num, 54 + uint perf_gsiv, ulong phys_base, ulong gicv, 55 + ulong gich, uint vgic_maint_irq, u64 gicr_base, 56 + ulong mpidr, uint efficiency) 57 + { 58 + memset(gicc, '\0', sizeof(struct acpi_madt_gicc)); 59 + gicc->type = ACPI_APIC_GICC; 60 + gicc->length = sizeof(struct acpi_madt_gicc); 61 + gicc->cpu_if_num = cpu_num; 62 + gicc->processor_id = cpu_num; 63 + gicc->flags = ACPI_MADTF_ENABLED; 64 + gicc->perf_gsiv = perf_gsiv; 65 + gicc->phys_base = phys_base; 66 + gicc->gicv = gicv; 67 + gicc->gich = gich; 68 + gicc->vgic_maint_irq = vgic_maint_irq; 69 + gicc->gicr_base = gicr_base; 70 + gicc->mpidr = mpidr; 71 + gicc->efficiency = efficiency; 72 + } 73 + 74 + void acpi_write_madt_gicd(struct acpi_madt_gicd *gicd, uint gic_id, 75 + ulong phys_base, uint gic_version) 76 + { 77 + memset(gicd, '\0', sizeof(struct acpi_madt_gicd)); 78 + gicd->type = ACPI_APIC_GICD; 79 + gicd->length = sizeof(struct acpi_madt_gicd); 80 + gicd->gic_id = gic_id; 81 + gicd->phys_base = phys_base; 82 + gicd->gic_version = gic_version; 83 + } 84 + 85 + void acpi_write_madt_gicr(struct acpi_madt_gicr *gicr, 86 + u64 discovery_range_base_address, 87 + u32 discovery_range_length) 88 + { 89 + memset(gicr, '\0', sizeof(struct acpi_madt_gicr)); 90 + gicr->type = ACPI_APIC_GICR; 91 + gicr->length = sizeof(struct acpi_madt_gicr); 92 + gicr->discovery_range_base_address = discovery_range_base_address; 93 + gicr->discovery_range_length = discovery_range_length; 94 + } 95 + 96 + void acpi_write_madt_its(struct acpi_madt_its *its, 97 + u32 its_id, 98 + u64 physical_base_address) 99 + { 100 + memset(its, '\0', sizeof(struct acpi_madt_its)); 101 + its->type = ACPI_APIC_ITS; 102 + its->length = sizeof(struct acpi_madt_its); 103 + its->gic_its_id = its_id; 104 + its->physical_base_address = physical_base_address; 105 + } 106 + 107 + int acpi_pptt_add_proc(struct acpi_ctx *ctx, const u32 flags, const u32 parent, 108 + const u32 proc_id, const u32 num_resources, 109 + const u32 *resource_list) 110 + { 111 + struct acpi_pptt_proc *proc = ctx->current; 112 + int offset; 113 + 114 + offset = ctx->current - ctx->tab_start; 115 + proc->hdr.type = ACPI_PPTT_TYPE_PROC; 116 + proc->flags = flags; 117 + proc->parent = parent; 118 + proc->proc_id = proc_id; 119 + proc->num_resources = num_resources; 120 + proc->hdr.length = sizeof(struct acpi_pptt_proc) + 121 + sizeof(u32) * num_resources; 122 + 123 + if (resource_list) 124 + memcpy(proc + 1, resource_list, sizeof(u32) * num_resources); 125 + 126 + acpi_inc(ctx, proc->hdr.length); 127 + 128 + return offset; 129 + } 130 + 131 + int acpi_pptt_add_cache(struct acpi_ctx *ctx, const u32 flags, 132 + const u32 next_cache_level, const u32 size, 133 + const u32 sets, const u8 assoc, const u8 attributes, 134 + const u16 line_size) 135 + { 136 + struct acpi_pptt_cache *cache = ctx->current; 137 + int offset; 138 + 139 + offset = ctx->current - ctx->tab_start; 140 + cache->hdr.type = ACPI_PPTT_TYPE_CACHE; 141 + cache->hdr.length = sizeof(struct acpi_pptt_cache); 142 + cache->flags = flags; 143 + cache->next_cache_level = next_cache_level; 144 + cache->size = size; 145 + cache->sets = sets; 146 + cache->assoc = assoc; 147 + cache->attributes = attributes; 148 + cache->line_size = line_size; 149 + acpi_inc(ctx, cache->hdr.length); 150 + 151 + return offset; 152 + } 153 + 154 + void *acpi_fill_madt(struct acpi_madt *madt, struct acpi_ctx *ctx) 155 + { 156 + uclass_probe_all(UCLASS_CPU); 157 + uclass_probe_all(UCLASS_IRQ); 158 + 159 + /* All SoCs must use the driver model */ 160 + acpi_fill_madt_subtbl(ctx); 161 + 162 + return ctx->current; 163 + } 164 + 165 + /** 166 + * acpi_write_pp_setup_one_page() - Fill out one page used by the PP 167 + * 168 + * Fill out the struct acpi_pp_page to contain the spin-loop 169 + * code and the mailbox area. After this function the page is ready for 170 + * the secondary core's to enter the spin-loop code. 171 + * 172 + * @page: Pointer to current parking protocol page 173 + * @gicc: Pointer to corresponding GICC sub-table 174 + */ 175 + static void acpi_write_pp_setup_one_page(struct acpi_pp_page *page, 176 + struct acpi_madt_gicc *gicc) 177 + { 178 + void *reloc; 179 + 180 + /* Update GICC. Mark parking protocol as available. */ 181 + gicc->parking_proto = ACPI_PP_VERSION; 182 + gicc->parked_addr = virt_to_phys(page); 183 + 184 + /* Prepare parking protocol page */ 185 + memset(page, '\0', sizeof(struct acpi_pp_page)); 186 + 187 + /* Init mailbox. Set MPIDR so core's will find their page. */ 188 + page->cpu_id = gicc->mpidr; 189 + page->jumping_address = ACPI_PP_JMP_ADR_INVALID; 190 + 191 + /* Relocate spinning code */ 192 + reloc = &page->spinning_code[0]; 193 + 194 + log_debug("Relocating spin table from %lx to %lx (size %x)\n", 195 + (ulong)&acpi_pp_code_start, (ulong)reloc, acpi_pp_code_size); 196 + memcpy(reloc, &acpi_pp_code_start, acpi_pp_code_size); 197 + 198 + if (!CONFIG_IS_ENABLED(SYS_DCACHE_OFF)) 199 + flush_dcache_range((unsigned long)page, 200 + (unsigned long)(page + 1)); 201 + } 202 + 203 + void acpi_write_park(struct acpi_madt *madt) 204 + { 205 + struct acpi_pp_page *start, *page; 206 + struct acpi_madt_gicc *gicc; 207 + int ret, i, ncpus = 0; 208 + 209 + /* 210 + * According to the "Multi-processor Startup for ARM Platforms": 211 + * - Every CPU as specified by MADT GICC has it's own 4K page 212 + * - Every page is divided into two sections: OS and FW reserved 213 + * - Memory occupied by "Parking Protocol" must be marked 'Reserved' 214 + * - Spinloop code should reside in FW reserved 2048 bytes 215 + * - Spinloop code will check the mailbox in OS reserved area 216 + */ 217 + 218 + if (acpi_pp_code_size > sizeof(page->spinning_code)) { 219 + log_err("Spinning code too big to fit: %d\n", 220 + acpi_pp_code_size); 221 + return; 222 + } 223 + 224 + /* Count all MADT GICCs including BSP */ 225 + for (i = sizeof(struct acpi_madt); i < madt->header.length; 226 + i += gicc->length) { 227 + gicc = (struct acpi_madt_gicc *)((void *)madt + i); 228 + if (gicc->type != ACPI_APIC_GICC) 229 + continue; 230 + ncpus++; 231 + } 232 + log_debug("Found %#x GICCs in MADT\n", ncpus); 233 + 234 + /* Allocate pages linearly due to assembly code requirements */ 235 + start = bloblist_add(BLOBLISTT_ACPI_PP, ACPI_PP_PAGE_SIZE * ncpus, 236 + ilog2(SZ_4K)); 237 + if (!start) { 238 + log_err("Failed to allocate memory for ACPI-parking-protocol pages\n"); 239 + return; 240 + } 241 + log_debug("Allocated parking protocol at %p\n", start); 242 + page = start; 243 + 244 + if (IS_ENABLED(CONFIG_EFI_LOADER)) { 245 + /* Default mapping is 'BOOT CODE'. Mark as reserved instead. */ 246 + ret = efi_add_memory_map((u64)(uintptr_t)start, 247 + ncpus * ACPI_PP_PAGE_SIZE, 248 + EFI_RESERVED_MEMORY_TYPE); 249 + 250 + if (ret) 251 + log_err("Reserved memory mapping failed addr %p size %x\n", 252 + start, ncpus * ACPI_PP_PAGE_SIZE); 253 + } 254 + 255 + /* Prepare the parking protocol pages */ 256 + for (i = sizeof(struct acpi_madt); i < madt->header.length; 257 + i += gicc->length) { 258 + gicc = (struct acpi_madt_gicc *)((void *)madt + i); 259 + if (gicc->type != ACPI_APIC_GICC) 260 + continue; 261 + 262 + acpi_write_pp_setup_one_page(page++, gicc); 263 + } 264 + 265 + acpi_pp_etables = virt_to_phys(start) + 266 + ACPI_PP_PAGE_SIZE * ncpus; 267 + acpi_pp_tables = virt_to_phys(start); 268 + 269 + /* Make sure other cores see written value in memory */ 270 + if (!CONFIG_IS_ENABLED(SYS_DCACHE_OFF)) 271 + flush_dcache_all(); 272 + 273 + /* Send an event to wake up the secondary CPU. */ 274 + asm("dsb ishst\n" 275 + "sev"); 276 + }
+89
arch/arm/lib/gic-v2.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Copyright 2019 Broadcom. 4 + */ 5 + #include <dm.h> 6 + #include <irq.h> 7 + #include <asm/gic.h> 8 + #include <asm/acpi_table.h> 9 + #include <cpu_func.h> 10 + #include <dm/acpi.h> 11 + #include <dt-bindings/interrupt-controller/arm-gic.h> 12 + 13 + #ifdef CONFIG_ACPIGEN 14 + /** 15 + * acpi_gicv2_fill_madt() - Fill out the body of the MADT 16 + * 17 + * Write GICD and GICR tables based on collected devicetree data. 18 + * 19 + * @dev: Device to write ACPI tables for 20 + * @ctx: ACPI context to write MADT sub-tables to 21 + * Return: 0 if OK 22 + */ 23 + static int acpi_gicv2_fill_madt(const struct udevice *dev, struct acpi_ctx *ctx) 24 + { 25 + struct acpi_madt_gicd *gicd; 26 + fdt_addr_t addr; 27 + 28 + addr = dev_read_addr_index(dev, 0); 29 + if (addr == FDT_ADDR_T_NONE) { 30 + pr_err("%s: failed to get GICD address\n", __func__); 31 + return -EINVAL; 32 + } 33 + 34 + gicd = ctx->current; 35 + acpi_write_madt_gicd(gicd, dev_seq(dev), addr, 2); 36 + acpi_inc(ctx, gicd->length); 37 + 38 + return 0; 39 + } 40 + 41 + static struct acpi_ops gic_v2_acpi_ops = { 42 + .fill_madt = acpi_gicv2_fill_madt, 43 + }; 44 + #endif 45 + 46 + static const struct udevice_id gic_v2_ids[] = { 47 + { .compatible = "arm,arm11mp-gic" }, 48 + { .compatible = "arm,cortex-a15-gic" }, 49 + { .compatible = "arm,cortex-a7-gic" }, 50 + { .compatible = "arm,cortex-a5-gic" }, 51 + { .compatible = "arm,cortex-a9-gic" }, 52 + { .compatible = "arm,eb11mp-gic" }, 53 + { .compatible = "arm,gic-400" }, 54 + { .compatible = "arm,pl390" }, 55 + { .compatible = "arm,tc11mp-gic" }, 56 + { .compatible = "qcom,msm-8660-qgic" }, 57 + { .compatible = "qcom,msm-qgic2" }, 58 + {} 59 + }; 60 + 61 + static int arm_gic_v2_of_xlate(struct irq *irq, struct ofnode_phandle_args *args) 62 + { 63 + if (args->args_count != 3) { 64 + log_debug("Invalid args_count: %d\n", args->args_count); 65 + return -EINVAL; 66 + } 67 + 68 + /* ARM Generic Interrupt Controller v1 and v2 */ 69 + if (args->args[0] == GIC_SPI) 70 + irq->id = args->args[1] + 32; 71 + else 72 + irq->id = args->args[1] + 16; 73 + 74 + irq->flags = args->args[2]; 75 + 76 + return 0; 77 + } 78 + 79 + static const struct irq_ops arm_gic_v2_ops = { 80 + .of_xlate = arm_gic_v2_of_xlate, 81 + }; 82 + 83 + U_BOOT_DRIVER(arm_gic_v2) = { 84 + .name = "gic-v2", 85 + .id = UCLASS_IRQ, 86 + .of_match = gic_v2_ids, 87 + .ops = &arm_gic_v2_ops, 88 + ACPI_OPS_PTR(&gic_v2_acpi_ops) 89 + };
+116 -5
arch/arm/lib/gic-v3-its.c
··· 4 4 */ 5 5 #include <cpu_func.h> 6 6 #include <dm.h> 7 + #include <irq.h> 8 + #include <asm/acpi_table.h> 7 9 #include <asm/gic.h> 8 10 #include <asm/gic-v3.h> 9 11 #include <asm/io.h> 12 + #include <dm/acpi.h> 13 + #include <dt-bindings/interrupt-controller/arm-gic.h> 10 14 #include <linux/bitops.h> 11 15 #include <linux/printk.h> 12 16 #include <linux/sizes.h> ··· 26 30 struct gic_v3_its_priv { 27 31 ulong gicd_base; 28 32 ulong gicr_base; 33 + ulong gicr_length; 29 34 }; 30 35 31 36 static int gic_v3_its_get_gic_addr(struct gic_v3_its_priv *priv) 32 37 { 33 38 struct udevice *dev; 34 39 fdt_addr_t addr; 40 + fdt_size_t size; 35 41 int ret; 36 42 37 43 ret = uclass_get_device_by_driver(UCLASS_IRQ, 38 - DM_DRIVER_GET(arm_gic_v3_its), &dev); 44 + DM_DRIVER_GET(arm_gic_v3), &dev); 39 45 if (ret) { 40 46 pr_err("%s: failed to get %s irq device\n", __func__, 41 - DM_DRIVER_GET(arm_gic_v3_its)->name); 47 + DM_DRIVER_GET(arm_gic_v3)->name); 42 48 return ret; 43 49 } 44 50 ··· 49 55 } 50 56 priv->gicd_base = addr; 51 57 52 - addr = dev_read_addr_index(dev, 1); 58 + addr = dev_read_addr_size_index(dev, 1, &size); 53 59 if (addr == FDT_ADDR_T_NONE) { 54 60 pr_err("%s: failed to get GICR address\n", __func__); 55 61 return -EINVAL; 56 62 } 57 63 priv->gicr_base = addr; 64 + priv->gicr_length = size; 58 65 59 66 return 0; 60 67 } ··· 158 165 return 0; 159 166 } 160 167 168 + #ifdef CONFIG_ACPIGEN 169 + /** 170 + * acpi_gicv3_fill_madt() - Fill out the body of the MADT 171 + * 172 + * Write GICD and GICR tables based on collected devicetree data. 173 + * 174 + * @dev: Device to write ACPI tables for 175 + * @ctx: ACPI context to write MADT sub-tables to 176 + * Return: 0 if OK 177 + */ 178 + static int acpi_gicv3_fill_madt(const struct udevice *dev, struct acpi_ctx *ctx) 179 + { 180 + struct acpi_madt_gicd *gicd; 181 + struct acpi_madt_gicr *gicr; 182 + 183 + struct gic_v3_its_priv priv; 184 + 185 + if (gic_v3_its_get_gic_addr(&priv)) 186 + return -EINVAL; 187 + 188 + gicd = ctx->current; 189 + acpi_write_madt_gicd(gicd, dev_seq(dev), priv.gicd_base, 3); 190 + acpi_inc(ctx, gicd->length); 191 + 192 + gicr = ctx->current; 193 + acpi_write_madt_gicr(gicr, priv.gicr_base, priv.gicr_length); 194 + acpi_inc(ctx, gicr->length); 195 + 196 + return 0; 197 + } 198 + 199 + struct acpi_ops gic_v3_acpi_ops = { 200 + .fill_madt = acpi_gicv3_fill_madt, 201 + }; 202 + #endif 203 + 204 + static const struct udevice_id gic_v3_ids[] = { 205 + { .compatible = "arm,gic-v3" }, 206 + {} 207 + }; 208 + 209 + static int arm_gic_v3_of_xlate(struct irq *irq, struct ofnode_phandle_args *args) 210 + { 211 + if (args->args_count < 3) { 212 + log_debug("Invalid args_count: %d\n", args->args_count); 213 + return -EINVAL; 214 + } 215 + 216 + if (args->args[0] == GIC_SPI) 217 + irq->id = args->args[1] + 32; 218 + else 219 + irq->id = args->args[1] + 16; 220 + 221 + irq->flags = args->args[2]; 222 + 223 + return 0; 224 + } 225 + 226 + static const struct irq_ops arm_gic_v3_ops = { 227 + .of_xlate = arm_gic_v3_of_xlate, 228 + }; 229 + 230 + U_BOOT_DRIVER(arm_gic_v3) = { 231 + .name = "gic-v3", 232 + .id = UCLASS_IRQ, 233 + .of_match = gic_v3_ids, 234 + .ops = &arm_gic_v3_ops, 235 + ACPI_OPS_PTR(&gic_v3_acpi_ops) 236 + }; 237 + 238 + #ifdef CONFIG_ACPIGEN 239 + /** 240 + * acpi_gic_its_fill_madt() - Fill out the body of the MADT 241 + * 242 + * Write ITS tables based on collected devicetree data. 243 + * 244 + * @dev: Device to write ACPI tables for 245 + * @ctx: ACPI context to write MADT sub-tables to 246 + * Return: 0 if OK 247 + */ 248 + static int acpi_gic_its_fill_madt(const struct udevice *dev, struct acpi_ctx *ctx) 249 + { 250 + struct acpi_madt_its *its; 251 + fdt_addr_t addr; 252 + 253 + addr = dev_read_addr_index(dev, 0); 254 + if (addr == FDT_ADDR_T_NONE) { 255 + pr_err("%s: failed to get GIC ITS address\n", __func__); 256 + return -EINVAL; 257 + } 258 + 259 + its = ctx->current; 260 + acpi_write_madt_its(its, dev_seq(dev), addr); 261 + acpi_inc(ctx, its->length); 262 + 263 + return 0; 264 + } 265 + 266 + struct acpi_ops gic_v3_its_acpi_ops = { 267 + .fill_madt = acpi_gic_its_fill_madt, 268 + }; 269 + #endif 270 + 161 271 static const struct udevice_id gic_v3_its_ids[] = { 162 - { .compatible = "arm,gic-v3" }, 272 + { .compatible = "arm,gic-v3-its" }, 163 273 {} 164 274 }; 165 275 166 276 U_BOOT_DRIVER(arm_gic_v3_its) = { 167 - .name = "gic-v3", 277 + .name = "gic-v3-its", 168 278 .id = UCLASS_IRQ, 169 279 .of_match = gic_v3_its_ids, 280 + ACPI_OPS_PTR(&gic_v3_its_acpi_ops) 170 281 };
+15 -1
arch/arm/mach-bcm283x/Kconfig
··· 24 24 bool "Broadcom BCM2837 SoC 64-bit support" 25 25 depends on ARCH_BCM283X 26 26 select BCM2837 27 + select DRIVER_GICV2 27 28 select ARM64 29 + select CPU_ARMV8 30 + select ARMV8_MULTIENTRY if GENERATE_ACPI_TABLE 31 + select BLOBLIST if GENERATE_ACPI_TABLE 32 + select BLOBLIST_ALLOC if GENERATE_ACPI_TABLE 33 + select BLOBLIST_TABLES if GENERATE_ACPI_TABLE 28 34 29 35 config BCM2711 30 36 bool "Broadcom BCM2711 SoC support" ··· 42 48 bool "Broadcom BCM2711 SoC 64-bit support" 43 49 depends on ARCH_BCM283X 44 50 select BCM2711 51 + select DRIVER_GICV2 45 52 select ARM64 53 + select CPU_ARMV8 54 + select ARMV8_MULTIENTRY if GENERATE_ACPI_TABLE 55 + select BLOBLIST if GENERATE_ACPI_TABLE 56 + select BLOBLIST_ALLOC if GENERATE_ACPI_TABLE 57 + select BLOBLIST_TABLES if GENERATE_ACPI_TABLE 46 58 47 59 menu "Broadcom BCM283X family" 48 60 depends on ARCH_BCM283X 49 - 50 61 choice 51 62 prompt "Broadcom BCM283X board select" 52 63 optional ··· 209 220 210 221 config SYS_CONFIG_NAME 211 222 default "rpi" 223 + 224 + config BLOBLIST_SIZE_RELOC 225 + default 0x20000 212 226 213 227 source "board/raspberrypi/rpi/Kconfig" 214 228
+4
arch/arm/mach-bcm283x/Makefile
··· 4 4 5 5 obj-$(CONFIG_BCM2835) += lowlevel_init.o 6 6 obj-y += init.o reset.o mbox.o msg.o phys2bus.o 7 + 8 + ifeq ($(CONFIG_GENERATE_ACPI_TABLE),y) 9 + obj-$(CONFIG_BCM2711) += bcm2711_acpi.o 10 + endif
+128
arch/arm/mach-bcm283x/bcm2711_acpi.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * (C) Copyright 2024 9elements GmbH 4 + * 5 + * See file CREDITS for list of people who contributed to this 6 + * project. 7 + */ 8 + 9 + #include <string.h> 10 + #include <tables_csum.h> 11 + #include <acpi/acpi_table.h> 12 + #include <asm/acpi_table.h> 13 + #include <asm/armv8/sec_firmware.h> 14 + #include <asm/arch/acpi/bcm2711.h> 15 + #include <dm/uclass.h> 16 + 17 + void acpi_fill_fadt(struct acpi_fadt *fadt) 18 + { 19 + fadt->flags = ACPI_FADT_HW_REDUCED_ACPI | ACPI_FADT_LOW_PWR_IDLE_S0; 20 + 21 + if (CONFIG_IS_ENABLED(SEC_FIRMWARE_ARMV8_PSCI) && 22 + sec_firmware_support_psci_version() != PSCI_INVALID_VER) 23 + fadt->arm_boot_arch = ACPI_ARM_PSCI_COMPLIANT; 24 + } 25 + 26 + #define L3_ATTRIBUTES (ACPI_PPTT_READ_ALLOC | ACPI_PPTT_WRITE_ALLOC | \ 27 + (ACPI_PPTT_CACHE_TYPE_UNIFIED << \ 28 + ACPI_PPTT_CACHE_TYPE_SHIFT)) 29 + #define L3_SIZE 0x100000 30 + #define L3_SETS 0x400 31 + #define L3_WAYS 0x10 32 + 33 + #define L1D_ATTRIBUTES (ACPI_PPTT_READ_ALLOC | ACPI_PPTT_WRITE_ALLOC | \ 34 + (ACPI_PPTT_CACHE_TYPE_DATA << \ 35 + ACPI_PPTT_CACHE_TYPE_SHIFT)) 36 + #define L1D_SIZE 0x8000 37 + #define L1D_SETS 0x100 38 + #define L1D_WAYS 2 39 + 40 + #define L1I_ATTRIBUTES (ACPI_PPTT_READ_ALLOC | \ 41 + (ACPI_PPTT_CACHE_TYPE_INSTR << \ 42 + ACPI_PPTT_CACHE_TYPE_SHIFT)) 43 + #define L1I_SIZE 0xc000 44 + #define L1I_SETS 0x100 45 + #define L1I_WAYS 3 46 + 47 + static int acpi_write_pptt(struct acpi_ctx *ctx, const struct acpi_writer *entry) 48 + { 49 + struct acpi_table_header *header; 50 + int cluster_offset, l3_offset; 51 + u32 offsets[2]; 52 + 53 + header = ctx->current; 54 + ctx->tab_start = ctx->current; 55 + 56 + memset(header, '\0', sizeof(struct acpi_table_header)); 57 + 58 + acpi_fill_header(header, "PPTT"); 59 + header->revision = acpi_get_table_revision(ACPITAB_PPTT); 60 + acpi_inc(ctx, sizeof(*header)); 61 + 62 + l3_offset = acpi_pptt_add_cache(ctx, ACPI_PPTT_ALL_VALID, 0, L3_SIZE, 63 + L3_SETS, L3_WAYS, L3_ATTRIBUTES, 64); 64 + 65 + cluster_offset = acpi_pptt_add_proc(ctx, ACPI_PPTT_PHYSICAL_PACKAGE | 66 + ACPI_PPTT_CHILDREN_IDENTICAL, 67 + 0, 0, 1, &l3_offset); 68 + 69 + offsets[0] = acpi_pptt_add_cache(ctx, ACPI_PPTT_ALL_VALID, 0, L1D_SIZE, 70 + L1D_SETS, L1D_WAYS, L1D_ATTRIBUTES, 64); 71 + 72 + offsets[1] = acpi_pptt_add_cache(ctx, ACPI_PPTT_ALL_BUT_WRITE_POL, 0, 73 + L1I_SIZE, L1I_SETS, L1I_WAYS, 74 + L1I_ATTRIBUTES, 64); 75 + 76 + for (int i = 0; i < uclass_id_count(UCLASS_CPU); i++) { 77 + acpi_pptt_add_proc(ctx, ACPI_PPTT_CHILDREN_IDENTICAL | 78 + ACPI_PPTT_NODE_IS_LEAF | 79 + ACPI_PPTT_PROC_ID_VALID, 80 + cluster_offset, i, 2, offsets); 81 + } 82 + 83 + header->length = ctx->current - ctx->tab_start; 84 + header->checksum = table_compute_checksum(header, header->length); 85 + 86 + acpi_inc(ctx, header->length); 87 + acpi_add_table(ctx, header); 88 + 89 + return 0; 90 + }; 91 + 92 + ACPI_WRITER(5pptt, "PPTT", acpi_write_pptt, 0); 93 + 94 + static int rpi_write_gtdt(struct acpi_ctx *ctx, const struct acpi_writer *entry) 95 + { 96 + struct acpi_table_header *header; 97 + struct acpi_gtdt *gtdt; 98 + 99 + gtdt = ctx->current; 100 + header = &gtdt->header; 101 + 102 + memset(gtdt, '\0', sizeof(struct acpi_gtdt)); 103 + 104 + acpi_fill_header(header, "GTDT"); 105 + header->length = sizeof(struct acpi_gtdt); 106 + header->revision = acpi_get_table_revision(ACPITAB_GTDT); 107 + 108 + gtdt->cnt_ctrl_base = BCM2711_ARM_LOCAL_BASE_ADDRESS + 0x1c; 109 + gtdt->sec_el1_gsiv = 29; 110 + gtdt->sec_el1_flags = GTDT_FLAG_INT_ACTIVE_LOW; 111 + gtdt->el1_gsiv = 30; 112 + gtdt->el1_flags = GTDT_FLAG_INT_ACTIVE_LOW; 113 + gtdt->virt_el1_gsiv = 27; 114 + gtdt->virt_el1_flags = GTDT_FLAG_INT_ACTIVE_LOW; 115 + gtdt->el2_gsiv = 26; 116 + gtdt->el2_flags = GTDT_FLAG_INT_ACTIVE_LOW; 117 + gtdt->cnt_read_base = 0xffffffffffffffff; 118 + 119 + header->checksum = table_compute_checksum(header, header->length); 120 + 121 + acpi_add_table(ctx, gtdt); 122 + 123 + acpi_inc(ctx, sizeof(struct acpi_gtdt)); 124 + 125 + return 0; 126 + }; 127 + 128 + ACPI_WRITER(5gtdt, "GTDT", rpi_write_gtdt, 0);
+152
arch/arm/mach-bcm283x/include/mach/acpi/bcm2711.h
··· 1 + /* SPDX-License-Identifier: BSD-2-Clause-Patent */ 2 + /** 3 + * 4 + * Copyright (c) 2019, Jeremy Linton 5 + * Copyright (c) 2019, Pete Batard <pete@akeo.ie>. 6 + * 7 + **/ 8 + 9 + #ifndef BCM2711_H__ 10 + #define BCM2711_H__ 11 + 12 + #define BCM2711_SOC_REGISTERS 0xfc000000 13 + #define BCM2711_SOC_REGISTER_LENGTH 0x02000000 14 + 15 + #define BCM2711_ARM_LOCAL_REGISTERS 0xfe000000 16 + #define BCM2711_ARM_LOCAL_REGISTER_LENGTH 0x02000000 17 + 18 + /* arm local addresses */ 19 + #define BCM2711_ARMC_OFFSET 0x0000b000 20 + #define BCM2711_ARMC_BASE_ADDRESS (BCM2711_ARM_LOCAL_REGISTERS + BCM2711_ARMC_OFFSET) 21 + #define BCM2711_ARMC_LENGTH 0x00000400 22 + 23 + #define BCM2711_ARM_LOCAL_OFFSET 0x01800000 24 + #define BCM2711_ARM_LOCAL_BASE_ADDRESS (BCM2711_ARM_LOCAL_REGISTERS + BCM2711_ARM_LOCAL_OFFSET) 25 + #define BCM2711_ARM_LOCAL_LENGTH 0x00000080 26 + 27 + #define BCM2711_GIC400_OFFSET 0x01840000 28 + #define BCM2711_GIC400_BASE_ADDRESS (BCM2711_ARM_LOCAL_REGISTERS + BCM2711_GIC400_OFFSET) 29 + #define BCM2711_GIC400_LENGTH 0x00008000 30 + 31 + /* Generic PCI addresses */ 32 + #define PCIE_TOP_OF_MEM_WIN 0xf8000000 33 + #define PCIE_CPU_MMIO_WINDOW 0x600000000 34 + #define PCIE_BRIDGE_MMIO_LEN 0x3ffffff 35 + 36 + /* PCI root bridge control registers location */ 37 + #define PCIE_REG_BASE 0xfd500000 38 + #define PCIE_REG_LIMIT 0x9310 39 + 40 + /* PCI root bridge control registers */ 41 + #define BRCM_PCIE_CAP_REGS 0x00ac 42 + #define PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1 0x0188 43 + #define VENDOR_SPECIFIC_REG1_LITTLE_ENDIAN 0x0 44 + #define PCIE_RC_CFG_PRIV1_ID_VAL3 0x043c 45 + #define PCIE_RC_CFG_PRIV1_LINK_CAPABILITY 0x04dc 46 + #define LINK_CAPABILITY_ASPM_SUPPORT_MASK 0xc00 47 + 48 + #define PCIE_RC_DL_MDIO_ADDR 0x1100 49 + #define PCIE_RC_DL_MDIO_WR_DATA 0x1104 50 + #define PCIE_RC_DL_MDIO_RD_DATA 0x1108 51 + 52 + #define PCIE_MISC_MISC_CTRL 0x4008 53 + #define MISC_CTRL_SCB_ACCESS_EN_MASK 0x1000 54 + #define MISC_CTRL_CFG_READ_UR_MODE_MASK 0x2000 55 + #define MISC_CTRL_MAX_BURST_SIZE_MASK 0x300000 56 + #define MISC_CTRL_MAX_BURST_SIZE_128 0x0 57 + #define MISC_CTRL_SCB0_SIZE_MASK 0xf8000000 58 + 59 + #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO 0x400c 60 + #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI 0x4010 61 + #define PCIE_MEM_WIN0_LO(win) \ 62 + PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO + ((win) * 4) 63 + 64 + #define PCIE_MEM_WIN0_HI(win) \ 65 + PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI + ((win) * 4) 66 + #define PCIE_MISC_RC_BAR1_CONFIG_LO 0x402c 67 + #define RC_BAR1_CONFIG_LO_SIZE_MASK 0x1f 68 + #define PCIE_MISC_RC_BAR2_CONFIG_LO 0x4034 69 + #define RC_BAR2_CONFIG_LO_SIZE_MASK 0x1f 70 + #define PCIE_MISC_RC_BAR2_CONFIG_HI 0x4038 71 + #define PCIE_MISC_RC_BAR3_CONFIG_LO 0x403c 72 + #define RC_BAR3_CONFIG_LO_SIZE_MASK 0x1f 73 + #define PCIE_MISC_PCIE_STATUS 0x4068 74 + #define STATUS_PCIE_PORT_MASK 0x80 75 + #define STATUS_PCIE_PORT_SHIFT 7 76 + #define STATUS_PCIE_DL_ACTIVE_MASK 0x20 77 + #define STATUS_PCIE_DL_ACTIVE_SHIFT 5 78 + #define STATUS_PCIE_PHYLINKUP_MASK 0x10 79 + #define STATUS_PCIE_PHYLINKUP_SHIFT 4 80 + #define PCIE_MISC_REVISION 0x406c 81 + #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT 0x4070 82 + #define MEM_WIN0_BASE_LIMIT_LIMIT_MASK 0xfff00000 83 + #define MEM_WIN0_BASE_LIMIT_BASE_MASK 0xfff0 84 + #define MEM_WIN0_BASE_LIMIT_BASE_HI_SHIFT 12 85 + #define PCIE_MEM_WIN0_BASE_LIMIT(win) \ 86 + PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT + ((win) * 4) 87 + #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI 0x4080 88 + #define MEM_WIN0_BASE_HI_BASE_MASK 0xff 89 + #define PCIE_MEM_WIN0_BASE_HI(win) \ 90 + PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI + ((win) * 8) 91 + #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI 0x4084 92 + #define PCIE_MEM_WIN0_LIMIT_HI_LIMIT_MASK 0xff 93 + #define PCIE_MEM_WIN0_LIMIT_HI(win) \ 94 + PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI + ((win) * 8) 95 + 96 + #define PCIE_MISC_HARD_PCIE_HARD_DEBUG 0x4204 97 + #define PCIE_HARD_DEBUG_SERDES_IDDQ_MASK 0x08000000 98 + 99 + #define PCIE_INTR2_CPU_STATUS 0x4300 100 + #define PCIE_INTR2_CPU_SET 0x4304 101 + #define PCIE_INTR2_CPU_CLR 0x4308 102 + #define PCIE_INTR2_CPU_MASK_STATUS 0x430c 103 + #define PCIE_INTR2_CPU_MASK_SET 0x4310 104 + #define PCIE_INTR2_CPU_MASK_CLR 0x4314 105 + 106 + #define PCIE_MSI_INTR2_CLR 0x4508 107 + #define PCIE_MSI_INTR2_MASK_SET 0x4510 108 + 109 + #define PCIE_RGR1_SW_INIT_1 0x9210 110 + #define PCIE_EXT_CFG_INDEX 0x9000 111 + /* A small window pointing at the ECAM of the device selected by CFG_INDEX */ 112 + #define PCIE_EXT_CFG_DATA 0x8000 113 + 114 + #define PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_MASK 0xc 115 + #define PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK 0xffffff 116 + 117 + #define PCIE_MISC_MISC_CTRL_SCB_ACCESS_EN_MASK 0x1000 118 + #define PCIE_MISC_MISC_CTRL_CFG_READ_UR_MODE_MASK 0x2000 119 + #define PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_MASK 0x300000 120 + #define PCIE_MISC_MISC_CTRL_SCB0_SIZE_MASK 0xf8000000 121 + #define PCIE_MISC_MISC_CTRL_SCB1_SIZE_MASK 0x7c00000 122 + #define PCIE_MISC_MISC_CTRL_SCB2_SIZE_MASK 0x1f 123 + #define PCIE_MISC_RC_BAR2_CONFIG_LO_SIZE_MASK 0x1f 124 + 125 + #define PCIE_RGR1_SW_INIT_1_INIT_MASK 0x2 126 + #define PCIE_RGR1_SW_INIT_1_PERST_MASK 0x1 127 + 128 + #define PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK 0x08000000 129 + 130 + #define PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK 0x2 131 + 132 + #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_MASK 0xfff00000 133 + #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_MASK 0xfff0 134 + #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI_BASE_MASK 0xff 135 + #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI_LIMIT_MASK 0xff 136 + #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_MASK_BITS 0xc 137 + 138 + #define PCIE_MISC_REVISION_MAJMIN_MASK 0xffff 139 + 140 + #define BURST_SIZE_128 0 141 + #define BURST_SIZE_256 1 142 + #define BURST_SIZE_512 2 143 + 144 + #define BCM2711_THERM_SENSOR_OFFSET 0x015d2200 145 + #define BCM2711_THERM_SENSOR_BASE_ADDRESS (BCM2711_SOC_REGISTERS + BCM2711_THERM_SENSOR_OFFSET) 146 + #define BCM2711_THERM_SENSOR_LENGTH 0x00000008 147 + 148 + #define BCM2711_GENET_BASE_OFFSET 0x01580000 149 + #define BCM2711_GENET_BASE_ADDRESS (BCM2711_SOC_REGISTERS + BCM2711_GENET_BASE_OFFSET) 150 + #define BCM2711_GENET_LENGTH 0x10000 151 + 152 + #endif /* BCM2711_H__ */
+127
arch/arm/mach-bcm283x/include/mach/acpi/bcm2836.h
··· 1 + /* SPDX-License-Identifier: BSD-2-Clause-Patent */ 2 + /** 3 + * 4 + * Copyright (c) 2019, ARM Limited. All rights reserved. 5 + * Copyright (c) 2017, Andrei Warkentin <andrey.warkentin@gmail.com> 6 + * Copyright (c) 2016, Linaro Limited. All rights reserved. 7 + * 8 + **/ 9 + 10 + #ifndef __BCM2836_H__ 11 + #define __BCM2836_H__ 12 + 13 + /* 14 + * Both "core" and SoC perpherals (1M each). 15 + */ 16 + #define BCM2836_SOC_REGISTERS 0xfe000000 17 + #define BCM2836_SOC_REGISTER_LENGTH 0x02000000 18 + 19 + /* 20 + * Offset between the CPU's view and the VC's view of system memory. 21 + */ 22 + #define BCM2836_DMA_DEVICE_OFFSET 0xc0000000 23 + 24 + /* watchdog constants */ 25 + #define BCM2836_WDOG_OFFSET 0x00100000 26 + #define BCM2836_WDOG_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_WDOG_OFFSET) 27 + #define BCM2836_WDOG_PASSWORD 0x5a000000 28 + #define BCM2836_WDOG_RSTC_OFFSET 0x0000001c 29 + #define BCM2836_WDOG_WDOG_OFFSET 0x00000024 30 + #define BCM2836_WDOG_RSTC_WRCFG_MASK 0x00000030 31 + #define BCM2836_WDOG_RSTC_WRCFG_FULL_RESET 0x00000020 32 + 33 + /* clock manager constants */ 34 + #define BCM2836_CM_OFFSET 0x00101000 35 + #define BCM2836_CM_BASE (BCM2836_SOC_REGISTERS + BCM2836_CM_OFFSET) 36 + #define BCM2836_CM_GEN_CLOCK_CONTROL 0x0000 37 + #define BCM2836_CM_GEN_CLOCK_DIVISOR 0x0004 38 + #define BCM2836_CM_VPU_CLOCK_CONTROL 0x0008 39 + #define BCM2836_CM_VPU_CLOCK_DIVISOR 0x000c 40 + #define BCM2836_CM_SYSTEM_CLOCK_CONTROL 0x0010 41 + #define BCM2836_CM_SYSTEM_CLOCK_DIVISOR 0x0014 42 + #define BCM2836_CM_H264_CLOCK_CONTROL 0x0028 43 + #define BCM2836_CM_H264_CLOCK_DIVISOR 0x002c 44 + #define BCM2836_CM_PWM_CLOCK_CONTROL 0x00a0 45 + #define BCM2836_CM_PWM_CLOCK_DIVISOR 0x00a4 46 + #define BCM2836_CM_UART_CLOCK_CONTROL 0x00f0 47 + #define BCM2836_CM_UART_CLOCK_DIVISOR 0x00f4 48 + #define BCM2836_CM_SDC_CLOCK_CONTROL 0x01a8 49 + #define BCM2836_CM_SDC_CLOCK_DIVISOR 0x01ac 50 + #define BCM2836_CM_ARM_CLOCK_CONTROL 0x01b0 51 + #define BCM2836_CM_ARM_CLOCK_DIVISOR 0x01b4 52 + #define BCM2836_CM_EMMC_CLOCK_CONTROL 0x01c0 53 + #define BCM2836_CM_EMMC_CLOCK_DIVISOR 0x01c4 54 + 55 + /* mailbox interface constants */ 56 + #define BCM2836_MBOX_OFFSET 0x0000b880 57 + #define BCM2836_MBOX_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_MBOX_OFFSET) 58 + #define BCM2836_MBOX_LENGTH 0x00000024 59 + #define BCM2836_MBOX_READ_OFFSET 0x00000000 60 + #define BCM2836_MBOX_STATUS_OFFSET 0x00000018 61 + #define BCM2836_MBOX_CONFIG_OFFSET 0x0000001c 62 + #define BCM2836_MBOX_WRITE_OFFSET 0x00000020 63 + 64 + #define BCM2836_MBOX_STATUS_FULL 0x1f 65 + #define BCM2836_MBOX_STATUS_EMPTY 0x1e 66 + 67 + #define BCM2836_MBOX_NUM_CHANNELS 16 68 + 69 + /* interrupt controller constants */ 70 + #define BCM2836_INTC_TIMER_CONTROL_OFFSET 0x00000040 71 + #define BCM2836_INTC_TIMER_PENDING_OFFSET 0x00000060 72 + 73 + /* usb constants */ 74 + #define BCM2836_USB_OFFSET 0x00980000 75 + #define BCM2836_USB_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_USB_OFFSET) 76 + #define BCM2836_USB_LENGTH 0x00010000 77 + 78 + /* serial based protocol constants */ 79 + #define BCM2836_PL011_UART_OFFSET 0x00201000 80 + #define BCM2836_PL011_UART_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_PL011_UART_OFFSET) 81 + #define BCM2836_PL011_UART_LENGTH 0x00001000 82 + 83 + #define BCM2836_MINI_UART_OFFSET 0x00215000 84 + #define BCM2836_MINI_UART_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_MINI_UART_OFFSET) 85 + #define BCM2836_MINI_UART_LENGTH 0x00000070 86 + 87 + #define BCM2836_I2C0_OFFSET 0x00205000 88 + #define BCM2836_I2C0_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_I2C0_OFFSET) 89 + #define BCM2836_I2C0_LENGTH 0x00000020 90 + 91 + #define BCM2836_I2C1_OFFSET 0x00804000 92 + #define BCM2836_I2C1_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_I2C1_OFFSET) 93 + #define BCM2836_I2C1_LENGTH 0x00000020 94 + 95 + #define BCM2836_I2C2_OFFSET 0x00805000 96 + #define BCM2836_I2C2_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_I2C2_OFFSET) 97 + #define BCM2836_I2C2_LENGTH 0x00000020 98 + 99 + #define BCM2836_SPI0_OFFSET 0x00204000 100 + #define BCM2836_SPI0_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_SPI0_OFFSET) 101 + #define BCM2836_SPI0_LENGTH 0x00000020 102 + 103 + #define BCM2836_SPI1_OFFSET 0x00215080 104 + #define BCM2836_SPI1_LENGTH 0x00000040 105 + #define BCM2836_SPI1_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_SPI1_OFFSET) 106 + 107 + #define BCM2836_SPI2_OFFSET 0x002150C0 108 + #define BCM2836_SPI2_LENGTH 0x00000040 109 + #define BCM2836_SPI2_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_SPI2_OFFSET) 110 + 111 + #define BCM2836_SYSTEM_TIMER_OFFSET 0x00003000 112 + #define BCM2836_SYSTEM_TIMER_LENGTH 0x00000020 113 + #define BCM2836_SYSTEM_TIMER_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_SYSTEM_TIMER_OFFSET) 114 + 115 + /* dma constants */ 116 + #define BCM2836_DMA0_OFFSET 0x00007000 117 + #define BCM2836_DMA0_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_DMA0_OFFSET) 118 + 119 + #define BCM2836_DMA15_OFFSET 0x00E05000 120 + #define BCM2836_DMA15_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_DMA15_OFFSET) 121 + 122 + #define BCM2836_DMA_CTRL_OFFSET 0x00007FE0 123 + #define BCM2836_DMA_CTRL_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_DMA_CTRL_OFFSET) 124 + 125 + #define BCM2836_DMA_CHANNEL_LENGTH 0x00000100 126 + 127 + #endif /*__BCM2836_H__ */
+19
arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_gpio.h
··· 1 + /* SPDX-License-Identifier: BSD-2-Clause-Patent */ 2 + /** 3 + * 4 + * Copyright (c) 2020, Pete Batard <pete@akeo.ie> 5 + * Copyright (c) 2018, Andrei Warkentin <andrey.warkentin@gmail.com> 6 + * Copyright (c) Microsoft Corporation. All rights reserved. 7 + * 8 + **/ 9 + 10 + #include <asm/arch/acpi/bcm2836.h> 11 + 12 + #ifndef __BCM2836_GPIO_H__ 13 + #define __BCM2836_GPIO_H__ 14 + 15 + #define GPIO_OFFSET 0x00200000 16 + #define GPIO_BASE_ADDRESS (BCM2836_SOC_REGISTERS + GPIO_OFFSET) 17 + #define GPIO_LENGTH 0x000000B4 18 + 19 + #endif /* __BCM2836_GPIO_H__ */
+47
arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_gpu.h
··· 1 + /* SPDX-License-Identifier: BSD-2-Clause-Patent */ 2 + /** 3 + * 4 + * Copyright (c) 2020, Pete Batard <pete@akeo.ie> 5 + * 6 + **/ 7 + 8 + #include <asm/arch/acpi/bcm2836.h> 9 + 10 + #ifndef __BCM2836_GPU_H__ 11 + #define __BCM2836_GPU_H__ 12 + 13 + /* VideoCore constants */ 14 + 15 + #define BCM2836_VCHIQ_OFFSET 0x0000B840 16 + #define BCM2836_VCHIQ_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_VCHIQ_OFFSET) 17 + #define BCM2836_VCHIQ_LENGTH 0x00000010 18 + 19 + #define BCM2836_V3D_BUS_OFFSET 0x00C00000 20 + #define BCM2836_V3D_BUS_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_V3D_BUS_OFFSET) 21 + #define BCM2836_V3D_BUS_LENGTH 0x00001000 22 + 23 + #define BCM2836_HVS_OFFSET 0x00400000 24 + #define BCM2836_HVS_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_HVS_OFFSET) 25 + #define BCM2836_HVS_LENGTH 0x00006000 26 + 27 + #define BCM2836_PV0_OFFSET 0x00206000 28 + #define BCM2836_PV0_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_PV0_OFFSET) 29 + #define BCM2836_PV0_LENGTH 0x00000100 30 + 31 + #define BCM2836_PV1_OFFSET 0x00207000 32 + #define BCM2836_PV1_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_PV1_OFFSET) 33 + #define BCM2836_PV1_LENGTH 0x00000100 34 + 35 + #define BCM2836_PV2_OFFSET 0x00807000 36 + #define BCM2836_PV2_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_PV2_OFFSET) 37 + #define BCM2836_PV2_LENGTH 0x00000100 38 + 39 + #define BCM2836_HDMI0_OFFSET 0x00902000 40 + #define BCM2836_HDMI0_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_HDMI0_OFFSET) 41 + #define BCM2836_HDMI0_LENGTH 0x00000600 42 + 43 + #define BCM2836_HDMI1_OFFSET 0x00808000 44 + #define BCM2836_HDMI1_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_HDMI1_OFFSET) 45 + #define BCM2836_HDMI1_LENGTH 0x00000100 46 + 47 + #endif /* __BCM2836_MISC_H__ */
+33
arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_pwm.h
··· 1 + /* SPDX-License-Identifier: BSD-2-Clause-Patent */ 2 + /** 3 + * 4 + * Copyright (c) 2020, Pete Batard <pete@akeo.ie> 5 + * 6 + **/ 7 + 8 + #include <asm/arch/acpi/bcm2836.h> 9 + 10 + #ifndef __BCM2836_PWM_H__ 11 + #define __BCM2836_PWM_H__ 12 + 13 + /* PWM controller constants */ 14 + 15 + #define BCM2836_PWM_DMA_OFFSET 0x00007B00 16 + #define BCM2836_PWM_DMA_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_PWM_DMA_OFFSET) 17 + #define BCM2836_PWM_DMA_LENGTH 0x00000100 18 + 19 + #define BCM2836_PWM_CLK_OFFSET 0x001010A0 20 + #define BCM2836_PWM_CLK_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_PWM_CLK_OFFSET) 21 + #define BCM2836_PWM_CLK_LENGTH 0x00000008 22 + 23 + #define BCM2836_PWM_CTRL_OFFSET 0x0020C000 24 + #define BCM2836_PWM_CTRL_BASE_ADDRESS (BCM2836_SOC_REGISTERS + BCM2836_PWM_CTRL_OFFSET) 25 + #define BCM2836_PWM_CTRL_LENGTH 0x00000028 26 + 27 + #define BCM2836_PWM_BUS_BASE_ADDRESS 0x7E20C000 28 + #define BCM2836_PWM_BUS_LENGTH 0x00000028 29 + 30 + #define BCM2836_PWM_CTRL_UNCACHED_BASE_ADDRESS 0xFF20C000 31 + #define BCM2836_PWM_CTRL_UNCACHED_LENGTH 0x00000028 32 + 33 + #endif /* __BCM2836_PWM_H__ */
+18
arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_sdhost.h
··· 1 + /* SPDX-License-Identifier: BSD-2-Clause-Patent */ 2 + /** 3 + * 4 + * Copyright (c) 2017, Andrei Warkentin <andrey.warkentin@gmail.com> 5 + * Copyright (c) Microsoft Corporation. All rights reserved. 6 + * 7 + **/ 8 + 9 + #include <asm/arch/acpi/bcm2836.h> 10 + 11 + #ifndef __BCM2836_SDHOST_H__ 12 + #define __BCM2836_SDHOST_H__ 13 + 14 + #define SDHOST_OFFSET 0x00202000 15 + #define SDHOST_BASE_ADDRESS (BCM2836_SOC_REGISTERS + SDHOST_OFFSET) 16 + #define SDHOST_LENGTH 0x00000100 17 + 18 + #endif /*__BCM2836_SDHOST_H__ */
+21
arch/arm/mach-bcm283x/include/mach/acpi/bcm2836_sdio.h
··· 1 + /* SPDX-License-Identifier: BSD-2-Clause-Patent */ 2 + /** 3 + * 4 + * Copyright (c) Microsoft Corporation. All rights reserved. 5 + * 6 + **/ 7 + 8 + #include <asm/arch/acpi/bcm2836.h> 9 + 10 + #ifndef __BCM2836_SDIO_H__ 11 + #define __BCM2836_SDIO_H__ 12 + 13 + // MMC/SD/SDIO1 register definitions. 14 + #define MMCHS1_OFFSET 0x00300000 15 + #define MMCHS2_OFFSET 0x00340000 16 + #define MMCHS1_BASE (BCM2836_SOC_REGISTERS + MMCHS1_OFFSET) 17 + #define MMCHS2_BASE (BCM2836_SOC_REGISTERS + MMCHS2_OFFSET) 18 + #define MMCHS1_LENGTH 0x00000100 19 + #define MMCHS2_LENGTH 0x00000100 20 + 21 + #endif /* __BCM2836_SDIO_H__ */
+1 -1
arch/arm/mach-bcm283x/init.c
··· 50 50 }, { 51 51 .virt = 0xfc000000UL, 52 52 .phys = 0xfc000000UL, 53 - .size = 0x03800000UL, 53 + .size = 0x04000000UL, 54 54 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | 55 55 PTE_BLOCK_NON_SHARE | 56 56 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+30 -6
arch/arm/mach-qemu/Kconfig
··· 3 3 config SYS_VENDOR 4 4 default "emulation" 5 5 6 - config SYS_BOARD 7 - default "qemu-arm" 8 - 9 - config SYS_CONFIG_NAME 10 - default "qemu-arm" 11 - 12 6 choice 13 7 prompt "QEMU ARM architecture" 14 8 default TARGET_QEMU_ARM_64BIT ··· 25 19 select ARM64 26 20 select BOARD_LATE_INIT 27 21 22 + config TARGET_QEMU_ARM_SBSA 23 + bool "SBSA Reference" 24 + select ARM64 25 + select BINMAN 26 + select BOARD_LATE_INIT 27 + select ENABLE_ARM_SOC_BOOT0_HOOK 28 + select MISC_INIT_R 28 29 endchoice 30 + 31 + if TARGET_QEMU_ARM_32BIT || TARGET_QEMU_ARM_64BIT 32 + 33 + config SYS_BOARD 34 + default "qemu-arm" 35 + 36 + config SYS_CONFIG_NAME 37 + default "qemu-arm" 38 + 39 + endif 40 + 41 + if TARGET_QEMU_ARM_SBSA 42 + 43 + config SYS_BOARD 44 + default "qemu-sbsa" 45 + 46 + config SYS_CONFIG_NAME 47 + default "qemu-sbsa" 48 + 49 + config SYS_SOC 50 + default "qemu-sbsa" 51 + 52 + endif 29 53 30 54 endif
+3
arch/sandbox/dts/test.dts
··· 527 527 }; 528 528 529 529 f-test { 530 + #interrupt-cells = <2>; 531 + interrupt-parent = <&irq>; 532 + interrupts = <4 0>; 530 533 compatible = "denx,u-boot-fdt-test"; 531 534 }; 532 535
+5 -4
arch/sandbox/lib/Makefile
··· 5 5 # (C) Copyright 2002-2006 6 6 # Wolfgang Denk, DENX Software Engineering, wd@denx.de. 7 7 8 - obj-y += fdt_fixup.o interrupts.o 9 - obj-$(CONFIG_PCI) += pci_io.o 10 - obj-$(CONFIG_CMD_BOOTM) += bootm.o 11 - obj-$(CONFIG_CMD_BOOTZ) += bootm.o 8 + obj-y += fdt_fixup.o interrupts.o 9 + obj-$(CONFIG_PCI) += pci_io.o 10 + obj-$(CONFIG_CMD_BOOTM) += bootm.o 11 + obj-$(CONFIG_CMD_BOOTZ) += bootm.o 12 + obj-$(CONFIG_$(SPL_)ACPIGEN) += acpi_table.o
+11
arch/sandbox/lib/acpi_table.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + #include <acpi/acpi_table.h> 3 + 4 + void acpi_fill_fadt(struct acpi_fadt *fadt) 5 + { 6 + } 7 + 8 + void *acpi_fill_madt(struct acpi_madt *madt, struct acpi_ctx *ctx) 9 + { 10 + return ctx->current; 11 + }
+4 -16
arch/x86/cpu/apollolake/acpi.c
··· 128 128 return MP_IRQ_POLARITY_LOW; 129 129 } 130 130 131 - void fill_fadt(struct acpi_fadt *fadt) 131 + void acpi_fill_fadt(struct acpi_fadt *fadt) 132 132 { 133 + intel_acpi_fill_fadt(fadt); 134 + 133 135 fadt->pm_tmr_blk = IOMAP_ACPI_BASE + PM1_TMR; 134 136 135 137 fadt->p_lvl2_lat = ACPI_FADT_C2_NOT_SUPPORTED; ··· 143 145 fadt->x_pm_tmr_blk.space_id = 1; 144 146 fadt->x_pm_tmr_blk.bit_width = fadt->pm_tmr_len * 8; 145 147 fadt->x_pm_tmr_blk.addrl = IOMAP_ACPI_BASE + PM1_TMR; 146 - } 147 - 148 - static int apl_write_fadt(struct acpi_ctx *ctx, const struct acpi_writer *entry) 149 - { 150 - struct acpi_table_header *header; 151 - struct acpi_fadt *fadt; 152 148 153 - fadt = ctx->current; 154 - acpi_fadt_common(fadt, ctx->facs, ctx->dsdt); 155 - intel_acpi_fill_fadt(fadt); 156 - fill_fadt(fadt); 157 - header = &fadt->header; 158 - header->checksum = table_compute_checksum(fadt, header->length); 159 - 160 - return acpi_add_fadt(ctx, fadt); 149 + fadt->preferred_pm_profile = ACPI_PM_MOBILE; 161 150 } 162 - ACPI_WRITER(5fadt, "FADT", apl_write_fadt, 0); 163 151 164 152 int apl_acpi_fill_dmar(struct acpi_ctx *ctx) 165 153 {
+1 -16
arch/x86/cpu/baytrail/acpi.c
··· 15 15 #include <asm/arch/iomap.h> 16 16 #include <dm/uclass-internal.h> 17 17 18 - static int baytrail_write_fadt(struct acpi_ctx *ctx, 19 - const struct acpi_writer *entry) 18 + void acpi_fill_fadt(struct acpi_fadt *fadt) 20 19 { 21 20 struct acpi_table_header *header; 22 - struct acpi_fadt *fadt; 23 21 24 - fadt = ctx->current; 25 22 header = &fadt->header; 26 23 u16 pmbase = ACPI_BASE_ADDRESS; 27 24 28 - memset(fadt, '\0', sizeof(struct acpi_fadt)); 29 - 30 - acpi_fill_header(header, "FACP"); 31 - header->length = sizeof(struct acpi_fadt); 32 25 header->revision = 4; 33 26 34 27 fadt->preferred_pm_profile = ACPI_PM_MOBILE; ··· 77 70 fadt->reset_reg.addrh = 0; 78 71 fadt->reset_value = SYS_RST | RST_CPU | FULL_RST; 79 72 80 - fadt->x_firmware_ctrl = map_to_sysmem(ctx->facs); 81 - fadt->x_dsdt = map_to_sysmem(ctx->dsdt); 82 - 83 73 fadt->x_pm1a_evt_blk.space_id = ACPI_ADDRESS_SPACE_IO; 84 74 fadt->x_pm1a_evt_blk.bit_width = fadt->pm1_evt_len * 8; 85 75 fadt->x_pm1a_evt_blk.bit_offset = 0; ··· 135 125 fadt->x_gpe1_blk.access_size = 0; 136 126 fadt->x_gpe1_blk.addrl = 0x0; 137 127 fadt->x_gpe1_blk.addrh = 0x0; 138 - 139 - header->checksum = table_compute_checksum(fadt, header->length); 140 - 141 - return acpi_add_fadt(ctx, fadt); 142 128 } 143 - ACPI_WRITER(5fadt, "FADT", baytrail_write_fadt, 0); 144 129 145 130 int acpi_create_gnvs(struct acpi_global_nvs *gnvs) 146 131 {
+15 -7
arch/x86/cpu/intel_common/acpi.c
··· 19 19 #include <asm/global_data.h> 20 20 #include <asm/intel_acpi.h> 21 21 #include <asm/ioapic.h> 22 + #include <asm/lapic.h> 22 23 #include <asm/mpspec.h> 23 24 #include <asm/smm.h> 24 25 #include <asm/turbo.h> ··· 80 81 return sci_irq; 81 82 } 82 83 83 - static unsigned long acpi_madt_irq_overrides(unsigned long current) 84 + static void *acpi_madt_irq_overrides(void *current) 84 85 { 85 86 int sci = acpi_sci_irq(); 86 87 u16 flags = MP_IRQ_TRIGGER_LEVEL; 87 88 88 - if (sci < 0) 89 - return log_msg_ret("sci irq", sci); 89 + if (sci < 0) { 90 + log_err("sci irq %d", sci); 91 + return current; 92 + } 90 93 91 94 /* INT_SRC_OVR */ 92 - current += acpi_create_madt_irqoverride((void *)current, 0, 0, 2, 0); 95 + current += acpi_create_madt_irqoverride(current, 0, 0, 2, 0); 93 96 94 97 flags |= arch_madt_sci_irq_polarity(sci); 95 98 96 99 /* SCI */ 97 100 current += 98 - acpi_create_madt_irqoverride((void *)current, 0, sci, sci, flags); 101 + acpi_create_madt_irqoverride(current, 0, sci, sci, flags); 99 102 100 103 return current; 101 104 } 102 105 103 - u32 acpi_fill_madt(u32 current) 106 + void *acpi_fill_madt(struct acpi_madt *madt, struct acpi_ctx *ctx) 104 107 { 108 + void *current = ctx->current; 109 + 110 + madt->lapic_addr = LAPIC_DEFAULT_BASE; 111 + madt->flags = ACPI_MADT_PCAT_COMPAT; 112 + 105 113 /* Local APICs */ 106 114 current += acpi_create_madt_lapics(current); 107 115 108 116 /* IOAPIC */ 109 - current += acpi_create_madt_ioapic((void *)current, 2, IO_APIC_ADDR, 0); 117 + current += acpi_create_madt_ioapic(current, 2, IO_APIC_ADDR, 0); 110 118 111 119 return acpi_madt_irq_overrides(current); 112 120 }
+1 -18
arch/x86/cpu/quark/acpi.c
··· 11 11 #include <asm/arch/iomap.h> 12 12 #include <linux/string.h> 13 13 14 - static int quark_write_fadt(struct acpi_ctx *ctx, 15 - const struct acpi_writer *entry) 14 + void acpi_fill_fadt(struct acpi_fadt *fadt) 16 15 { 17 16 u16 pmbase = ACPI_PM1_BASE_ADDRESS; 18 17 struct acpi_table_header *header; 19 - struct acpi_fadt *fadt; 20 18 21 - fadt = ctx->current; 22 19 header = &fadt->header; 23 - 24 - memset(fadt, '\0', sizeof(struct acpi_fadt)); 25 - 26 - acpi_fill_header(header, "FACP"); 27 - header->length = sizeof(struct acpi_fadt); 28 20 header->revision = 4; 29 21 30 - fadt->preferred_pm_profile = ACPI_PM_UNSPECIFIED; 31 22 fadt->sci_int = 9; 32 23 fadt->smi_cmd = 0; 33 24 fadt->acpi_enable = 0; ··· 72 63 fadt->reset_reg.addrl = IO_PORT_RESET; 73 64 fadt->reset_reg.addrh = 0; 74 65 fadt->reset_value = SYS_RST | RST_CPU | FULL_RST; 75 - 76 - fadt->x_firmware_ctrl = map_to_sysmem(ctx->facs); 77 - fadt->x_dsdt = map_to_sysmem(ctx->dsdt); 78 66 79 67 fadt->x_pm1a_evt_blk.space_id = ACPI_ADDRESS_SPACE_IO; 80 68 fadt->x_pm1a_evt_blk.bit_width = fadt->pm1_evt_len * 8; ··· 131 119 fadt->x_gpe1_blk.access_size = 0; 132 120 fadt->x_gpe1_blk.addrl = 0x0; 133 121 fadt->x_gpe1_blk.addrh = 0x0; 134 - 135 - header->checksum = table_compute_checksum(fadt, header->length); 136 - 137 - return acpi_add_fadt(ctx, fadt); 138 122 } 139 - ACPI_WRITER(5fadt, "FADT", quark_write_fadt, 0); 140 123 141 124 int acpi_create_gnvs(struct acpi_global_nvs *gnvs) 142 125 {
+8 -25
arch/x86/cpu/tangier/acpi.c
··· 10 10 #include <mapmem.h> 11 11 #include <acpi/acpi_table.h> 12 12 #include <asm/ioapic.h> 13 + #include <asm/lapic.h> 13 14 #include <asm/mpspec.h> 14 15 #include <asm/tables.h> 15 16 #include <asm/arch/global_nvs.h> 16 17 #include <asm/arch/iomap.h> 17 18 #include <dm/uclass-internal.h> 18 19 19 - static int tangier_write_fadt(struct acpi_ctx *ctx, 20 - const struct acpi_writer *entry) 20 + void acpi_fill_fadt(struct acpi_fadt *fadt) 21 21 { 22 - struct acpi_table_header *header; 23 - struct acpi_fadt *fadt; 24 - 25 - fadt = ctx->current; 26 - header = &fadt->header; 27 - 28 - memset(fadt, '\0', sizeof(struct acpi_fadt)); 29 - 30 - acpi_fill_header(header, "FACP"); 31 - header->length = sizeof(struct acpi_fadt); 32 - header->revision = 6; 33 - 34 22 fadt->preferred_pm_profile = ACPI_PM_UNSPECIFIED; 35 23 36 24 fadt->iapc_boot_arch = ACPI_FADT_VGA_NOT_PRESENT | ··· 40 28 ACPI_FADT_POWER_BUTTON | ACPI_FADT_SLEEP_BUTTON | 41 29 ACPI_FADT_SEALED_CASE | ACPI_FADT_HEADLESS | 42 30 ACPI_FADT_HW_REDUCED_ACPI; 31 + } 43 32 44 - fadt->minor_revision = 2; 45 - 46 - fadt->x_firmware_ctrl = map_to_sysmem(ctx->facs); 47 - fadt->x_dsdt = map_to_sysmem(ctx->dsdt); 48 - 49 - header->checksum = table_compute_checksum(fadt, header->length); 33 + void *acpi_fill_madt(struct acpi_madt *madt, struct acpi_ctx *ctx) 34 + { 35 + void *current = ctx->current; 50 36 51 - return acpi_add_fadt(ctx, fadt); 52 - } 53 - ACPI_WRITER(5fadt, "FADT", tangier_write_fadt, 0); 37 + madt->lapic_addr = LAPIC_DEFAULT_BASE; 38 + madt->flags = ACPI_MADT_PCAT_COMPAT; 54 39 55 - u32 acpi_fill_madt(u32 current) 56 - { 57 40 current += acpi_create_madt_lapics(current); 58 41 59 42 current += acpi_create_madt_ioapic((struct acpi_madt_ioapic *)current,
+1 -27
arch/x86/include/asm/acpi_table.h
··· 24 24 25 25 /* These can be used by the target port */ 26 26 27 - int acpi_create_madt_lapics(u32 current); 27 + int acpi_create_madt_lapics(void *current); 28 28 int acpi_create_madt_ioapic(struct acpi_madt_ioapic *ioapic, u8 id, 29 29 u32 addr, u32 gsi_base); 30 30 int acpi_create_madt_irqoverride(struct acpi_madt_irqoverride *irqoverride, 31 31 u8 bus, u8 source, u32 gsirq, u16 flags); 32 32 int acpi_create_madt_lapic_nmi(struct acpi_madt_lapic_nmi *lapic_nmi, 33 33 u8 cpu, u16 flags, u8 lint); 34 - u32 acpi_fill_madt(u32 current); 35 - int acpi_create_mcfg_mmconfig(struct acpi_mcfg_mmconfig *mmconfig, u32 base, 36 - u16 seg_nr, u8 start, u8 end); 37 34 38 35 /** 39 36 * acpi_write_hpet() - Write out a HPET table ··· 44 41 * Return: 0 if OK, -ve on error 45 42 */ 46 43 int acpi_write_hpet(struct acpi_ctx *ctx); 47 - 48 - /** 49 - * acpi_write_dbg2_pci_uart() - Write out a DBG2 table 50 - * 51 - * @ctx: Current ACPI context 52 - * @dev: Debug UART device to describe 53 - * @access_size: Access size for UART (e.g. ACPI_ACCESS_SIZE_DWORD_ACCESS) 54 - * Return: 0 if OK, -ve on error 55 - */ 56 - int acpi_write_dbg2_pci_uart(struct acpi_ctx *ctx, struct udevice *dev, 57 - uint access_size); 58 44 59 45 /** 60 46 * acpi_create_gnvs() - Create a GNVS (Global Non Volatile Storage) table ··· 178 164 */ 179 165 int acpi_create_dmar_ds_msi_hpet(struct acpi_ctx *ctx, uint enumeration_id, 180 166 pci_dev_t bdf); 181 - 182 - /** 183 - * acpi_fadt_common() - Handle common parts of filling out an FADT 184 - * 185 - * This sets up the Fixed ACPI Description Table 186 - * 187 - * @fadt: Pointer to place to put FADT 188 - * @facs: Pointer to the FACS 189 - * @dsdt: Pointer to the DSDT 190 - */ 191 - void acpi_fadt_common(struct acpi_fadt *fadt, struct acpi_facs *facs, 192 - void *dsdt); 193 167 194 168 /** 195 169 * intel_acpi_fill_fadt() - Set up the contents of the FADT
+10 -235
arch/x86/lib/acpi_table.c
··· 40 40 return lapic->length; 41 41 } 42 42 43 - int acpi_create_madt_lapics(u32 current) 43 + int acpi_create_madt_lapics(void *current) 44 44 { 45 45 struct udevice *dev; 46 46 int total_length = 0; ··· 100 100 return lapic_nmi->length; 101 101 } 102 102 103 - static int acpi_create_madt_irq_overrides(u32 current) 103 + static int acpi_create_madt_irq_overrides(void *current) 104 104 { 105 105 struct acpi_madt_irqoverride *irqovr; 106 106 u16 sci_flags = MP_IRQ_TRIGGER_LEVEL | MP_IRQ_POLARITY_HIGH; 107 107 int length = 0; 108 108 109 - irqovr = (void *)current; 109 + irqovr = current; 110 110 length += acpi_create_madt_irqoverride(irqovr, 0, 0, 2, 0); 111 111 112 - irqovr = (void *)(current + length); 112 + irqovr = current + length; 113 113 length += acpi_create_madt_irqoverride(irqovr, 0, 9, 9, sci_flags); 114 114 115 115 return length; 116 116 } 117 117 118 - __weak u32 acpi_fill_madt(u32 current) 118 + __weak void *acpi_fill_madt(struct acpi_madt *madt, struct acpi_ctx *ctx) 119 119 { 120 + void *current = ctx->current; 121 + 122 + madt->lapic_addr = LAPIC_DEFAULT_BASE; 123 + madt->flags = ACPI_MADT_PCAT_COMPAT; 124 + 120 125 current += acpi_create_madt_lapics(current); 121 126 122 127 current += acpi_create_madt_ioapic((struct acpi_madt_ioapic *)current, ··· 127 132 return current; 128 133 } 129 134 130 - int acpi_write_madt(struct acpi_ctx *ctx, const struct acpi_writer *entry) 131 - { 132 - struct acpi_table_header *header; 133 - struct acpi_madt *madt; 134 - u32 current; 135 - 136 - madt = ctx->current; 137 - 138 - memset(madt, '\0', sizeof(struct acpi_madt)); 139 - header = &madt->header; 140 - 141 - /* Fill out header fields */ 142 - acpi_fill_header(header, "APIC"); 143 - header->length = sizeof(struct acpi_madt); 144 - header->revision = ACPI_MADT_REV_ACPI_3_0; 145 - 146 - madt->lapic_addr = LAPIC_DEFAULT_BASE; 147 - madt->flags = ACPI_MADT_PCAT_COMPAT; 148 - 149 - current = (u32)madt + sizeof(struct acpi_madt); 150 - current = acpi_fill_madt(current); 151 - 152 - /* (Re)calculate length and checksum */ 153 - header->length = current - (u32)madt; 154 - 155 - header->checksum = table_compute_checksum((void *)madt, header->length); 156 - acpi_add_table(ctx, madt); 157 - acpi_inc(ctx, madt->header.length); 158 - 159 - return 0; 160 - } 161 - ACPI_WRITER(5x86, NULL, acpi_write_madt, 0); 162 - 163 135 /** 164 136 * acpi_create_tcpa() - Create a TCPA table 165 137 * ··· 279 251 } 280 252 ACPI_WRITER(5tpm2, "TPM2", acpi_write_tpm2, 0); 281 253 282 - int acpi_write_spcr(struct acpi_ctx *ctx, const struct acpi_writer *entry) 283 - { 284 - struct serial_device_info serial_info = {0}; 285 - ulong serial_address, serial_offset; 286 - struct acpi_table_header *header; 287 - struct acpi_spcr *spcr; 288 - struct udevice *dev; 289 - uint serial_config; 290 - uint serial_width; 291 - int access_size; 292 - int space_id; 293 - int ret = -ENODEV; 294 - 295 - spcr = ctx->current; 296 - header = &spcr->header; 297 - 298 - memset(spcr, '\0', sizeof(struct acpi_spcr)); 299 - 300 - /* Fill out header fields */ 301 - acpi_fill_header(header, "SPCR"); 302 - header->length = sizeof(struct acpi_spcr); 303 - header->revision = 2; 304 - 305 - /* Read the device once, here. It is reused below */ 306 - dev = gd->cur_serial_dev; 307 - if (dev) 308 - ret = serial_getinfo(dev, &serial_info); 309 - if (ret) 310 - serial_info.type = SERIAL_CHIP_UNKNOWN; 311 - 312 - /* Encode chip type */ 313 - switch (serial_info.type) { 314 - case SERIAL_CHIP_16550_COMPATIBLE: 315 - spcr->interface_type = ACPI_DBG2_16550_COMPATIBLE; 316 - break; 317 - case SERIAL_CHIP_UNKNOWN: 318 - default: 319 - spcr->interface_type = ACPI_DBG2_UNKNOWN; 320 - break; 321 - } 322 - 323 - /* Encode address space */ 324 - switch (serial_info.addr_space) { 325 - case SERIAL_ADDRESS_SPACE_MEMORY: 326 - space_id = ACPI_ADDRESS_SPACE_MEMORY; 327 - break; 328 - case SERIAL_ADDRESS_SPACE_IO: 329 - default: 330 - space_id = ACPI_ADDRESS_SPACE_IO; 331 - break; 332 - } 333 - 334 - serial_width = serial_info.reg_width * 8; 335 - serial_offset = serial_info.reg_offset << serial_info.reg_shift; 336 - serial_address = serial_info.addr + serial_offset; 337 - 338 - /* Encode register access size */ 339 - switch (serial_info.reg_shift) { 340 - case 0: 341 - access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS; 342 - break; 343 - case 1: 344 - access_size = ACPI_ACCESS_SIZE_WORD_ACCESS; 345 - break; 346 - case 2: 347 - access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS; 348 - break; 349 - case 3: 350 - access_size = ACPI_ACCESS_SIZE_QWORD_ACCESS; 351 - break; 352 - default: 353 - access_size = ACPI_ACCESS_SIZE_UNDEFINED; 354 - break; 355 - } 356 - 357 - debug("UART type %u @ %lx\n", spcr->interface_type, serial_address); 358 - 359 - /* Fill GAS */ 360 - spcr->serial_port.space_id = space_id; 361 - spcr->serial_port.bit_width = serial_width; 362 - spcr->serial_port.bit_offset = 0; 363 - spcr->serial_port.access_size = access_size; 364 - spcr->serial_port.addrl = lower_32_bits(serial_address); 365 - spcr->serial_port.addrh = upper_32_bits(serial_address); 366 - 367 - /* Encode baud rate */ 368 - switch (serial_info.baudrate) { 369 - case 9600: 370 - spcr->baud_rate = 3; 371 - break; 372 - case 19200: 373 - spcr->baud_rate = 4; 374 - break; 375 - case 57600: 376 - spcr->baud_rate = 6; 377 - break; 378 - case 115200: 379 - spcr->baud_rate = 7; 380 - break; 381 - default: 382 - spcr->baud_rate = 0; 383 - break; 384 - } 385 - 386 - serial_config = SERIAL_DEFAULT_CONFIG; 387 - if (dev) 388 - ret = serial_getconfig(dev, &serial_config); 389 - 390 - spcr->parity = SERIAL_GET_PARITY(serial_config); 391 - spcr->stop_bits = SERIAL_GET_STOP(serial_config); 392 - 393 - /* No PCI devices for now */ 394 - spcr->pci_device_id = 0xffff; 395 - spcr->pci_vendor_id = 0xffff; 396 - 397 - /* 398 - * SPCR has no clue if the UART base clock speed is different 399 - * to the default one. However, the SPCR 1.04 defines baud rate 400 - * 0 as a preconfigured state of UART and OS is supposed not 401 - * to touch the configuration of the serial device. 402 - */ 403 - if (serial_info.clock != SERIAL_DEFAULT_CLOCK) 404 - spcr->baud_rate = 0; 405 - 406 - /* Fix checksum */ 407 - header->checksum = table_compute_checksum((void *)spcr, header->length); 408 - 409 - acpi_add_table(ctx, spcr); 410 - acpi_inc(ctx, spcr->header.length); 411 - 412 - return 0; 413 - } 414 - ACPI_WRITER(5spcr, "SPCR", acpi_write_spcr, 0); 415 - 416 254 int acpi_write_gnvs(struct acpi_ctx *ctx, const struct acpi_writer *entry) 417 255 { 418 256 ulong addr; ··· 513 351 return log_msg_ret("add", ret); 514 352 515 353 return 0; 516 - } 517 - 518 - int acpi_write_dbg2_pci_uart(struct acpi_ctx *ctx, struct udevice *dev, 519 - uint access_size) 520 - { 521 - struct acpi_dbg2_header *dbg2 = ctx->current; 522 - char path[ACPI_PATH_MAX]; 523 - struct acpi_gen_regaddr address; 524 - phys_addr_t addr; 525 - int ret; 526 - 527 - if (!device_active(dev)) { 528 - log_info("Device not enabled\n"); 529 - return -EACCES; 530 - } 531 - /* 532 - * PCI devices don't remember their resource allocation information in 533 - * U-Boot at present. We assume that MMIO is used for the UART and that 534 - * the address space is 32 bytes: ns16550 uses 8 registers of up to 535 - * 32-bits each. This is only for debugging so it is not a big deal. 536 - */ 537 - addr = dm_pci_read_bar32(dev, 0); 538 - log_debug("UART addr %lx\n", (ulong)addr); 539 - 540 - memset(&address, '\0', sizeof(address)); 541 - address.space_id = ACPI_ADDRESS_SPACE_MEMORY; 542 - address.addrl = (uint32_t)addr; 543 - address.addrh = (uint32_t)((addr >> 32) & 0xffffffff); 544 - address.access_size = access_size; 545 - 546 - ret = acpi_device_path(dev, path, sizeof(path)); 547 - if (ret) 548 - return log_msg_ret("path", ret); 549 - acpi_create_dbg2(dbg2, ACPI_DBG2_SERIAL_PORT, 550 - ACPI_DBG2_16550_COMPATIBLE, &address, 0x1000, path); 551 - 552 - acpi_inc_align(ctx, dbg2->header.length); 553 - acpi_add_table(ctx, dbg2); 554 - 555 - return 0; 556 - } 557 - 558 - void acpi_fadt_common(struct acpi_fadt *fadt, struct acpi_facs *facs, 559 - void *dsdt) 560 - { 561 - struct acpi_table_header *header = &fadt->header; 562 - 563 - memset((void *)fadt, '\0', sizeof(struct acpi_fadt)); 564 - 565 - acpi_fill_header(header, "FACP"); 566 - header->length = sizeof(struct acpi_fadt); 567 - header->revision = 4; 568 - memcpy(header->oem_id, OEM_ID, 6); 569 - memcpy(header->oem_table_id, OEM_TABLE_ID, 8); 570 - memcpy(header->creator_id, ASLC_ID, 4); 571 - 572 - fadt->x_firmware_ctrl = map_to_sysmem(facs); 573 - fadt->x_dsdt = map_to_sysmem(dsdt); 574 - 575 - fadt->preferred_pm_profile = ACPI_PM_MOBILE; 576 - 577 - /* Use ACPI 3.0 revision */ 578 - fadt->header.revision = 4; 579 354 } 580 355 581 356 void acpi_create_dmar_drhd(struct acpi_ctx *ctx, uint flags, uint segment,
+2
board/emulation/qemu-arm/MAINTAINERS
··· 4 4 F: board/emulation/qemu-arm/ 5 5 F: board/emulation/common/ 6 6 F: include/configs/qemu-arm.h 7 + F: include/configs/qemu-sbsa.h 7 8 F: configs/qemu_arm_defconfig 8 9 F: configs/qemu_arm64_defconfig 10 + F: configs/qemu-arm-sbsa_defconfig
+59
board/emulation/qemu-sbsa/Kconfig
··· 1 + if TARGET_QEMU_ARM_SBSA 2 + 3 + config SYS_SOC 4 + default "qemu-sbsa" 5 + 6 + config TEXT_BASE 7 + default 0x10000100000 8 + 9 + config SYS_LOAD_ADDR 10 + default 0x10000100000 11 + 12 + config PRE_CON_BUF_ADDR 13 + default 0x100000FF000 14 + 15 + config DEFAULT_DEVICE_TREE 16 + default "qemu-sbsa" 17 + 18 + config BOARD_SPECIFIC_OPTIONS # dummy 19 + def_bool y 20 + select AHCI 21 + select ACPIGEN 22 + select ACPI 23 + select BLOBLIST 24 + select CPU 25 + select CPU_ARMV8 26 + select DM 27 + select DM_USB 28 + select DM_MTD 29 + select GENERATE_ACPI_TABLE 30 + select HAS_ROM 31 + select MTD 32 + select OF_LIBFDT_OVERLAY 33 + select OF_SEPARATE 34 + select PCI 35 + select PCIE_ECAM_GENERIC 36 + select USB 37 + select GIC_V3 38 + select GIC_V3_ITS 39 + select SYS_FLASH_CFI_WIDTH_16BIT 40 + imply AHCI_GENERIC 41 + imply USB_XHCI_HCD 42 + imply USB_XHCI_GENERIC 43 + imply USB_STORAGE 44 + imply E1000 45 + imply E1000_NO_NVM 46 + imply NET_RANDOM_ETHADDR 47 + imply VIDEO_BOCHS 48 + imply CFI_FLASH 49 + imply SYS_MTDPARTS_RUNTIME 50 + imply SET_DFU_ALT_INFO 51 + 52 + if DEBUG_UART 53 + 54 + config DEBUG_UART_BASE 55 + default 0x60000000 56 + endif 57 + 58 + source "board/emulation/common/Kconfig" 59 + endif
+8
board/emulation/qemu-sbsa/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0+ 2 + 3 + obj-y += qemu-sbsa.o 4 + obj-y += lowlevel_init.o 5 + obj-y += smc.o 6 + 7 + obj-$(CONFIG_GENERATE_ACPI_TABLE) += dsdt_generated.o 8 + obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi.o
+192
board/emulation/qemu-sbsa/acpi.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Copyright (c) 2024 9elements GmbH 4 + */ 5 + 6 + #include <cpu.h> 7 + #include <tables_csum.h> 8 + #include <string.h> 9 + #include <acpi/acpi_table.h> 10 + #include <asm/acpi_table.h> 11 + #include <asm/armv8/sec_firmware.h> 12 + #include <configs/qemu-sbsa.h> 13 + #include <dm/uclass.h> 14 + #include <dm/device.h> 15 + #include "qemu-sbsa.h" 16 + 17 + #define SBSAQEMU_MADT_GIC_VBASE 0x2c020000 18 + #define SBSAQEMU_MADT_GIC_HBASE 0x2c010000 19 + #define SBSAQEMU_MADT_GIC_PMU_IRQ 23 20 + 21 + #define SBSA_PLATFORM_WATCHDOG_COUNT 1 22 + #define SBSA_PLATFORM_TIMER_COUNT (SBSA_PLATFORM_WATCHDOG_COUNT) 23 + 24 + #define L2_ATTRIBUTES (ACPI_PPTT_READ_ALLOC | ACPI_PPTT_WRITE_ALLOC | \ 25 + (ACPI_PPTT_CACHE_TYPE_UNIFIED << \ 26 + ACPI_PPTT_CACHE_TYPE_SHIFT)) 27 + #define L2_SIZE 0x80000 28 + #define L2_SETS 0x400 29 + #define L2_WAYS 8 30 + 31 + #define L1D_ATTRIBUTES (ACPI_PPTT_READ_ALLOC | ACPI_PPTT_WRITE_ALLOC | \ 32 + (ACPI_PPTT_CACHE_TYPE_DATA << \ 33 + ACPI_PPTT_CACHE_TYPE_SHIFT)) 34 + #define L1D_SIZE 0x8000 35 + #define L1D_SETS 0x100 36 + #define L1D_WAYS 2 37 + 38 + #define L1I_ATTRIBUTES (ACPI_PPTT_READ_ALLOC | \ 39 + (ACPI_PPTT_CACHE_TYPE_INSTR << \ 40 + ACPI_PPTT_CACHE_TYPE_SHIFT)) 41 + #define L1I_SIZE 0x8000 42 + #define L1I_SETS 0x100 43 + #define L1I_WAYS 2 44 + 45 + int acpi_fill_iort(struct acpi_ctx *ctx) 46 + { 47 + u32 its_offset, smmu_offset; 48 + u64 gic_its_base = 0; 49 + 50 + smc_get_gic_its_base(&gic_its_base); 51 + if (gic_its_base == 0) 52 + return 0; 53 + 54 + u32 identifiers[] = { 0 }; 55 + 56 + its_offset = acpi_iort_add_its_group(ctx, ARRAY_SIZE(identifiers), 57 + identifiers); 58 + 59 + struct acpi_iort_id_mapping map_smmu[] = {{ 60 + 0, 0xffff, 0, its_offset, 0 61 + }}; 62 + 63 + smmu_offset = acpi_iort_add_smmu_v3(ctx, 64 + SBSA_SMMU_BASE_ADDR, // Base address 65 + ACPI_IORT_SMMU_V3_COHACC_OVERRIDE, // Flags 66 + 0, // VATOS address 67 + 0, // SMMUv3 Model 68 + 74, // Event 69 + 75, // Pri 70 + 77, // Gerror 71 + 76, // Sync 72 + 0, // Proximity domain 73 + 1, // DevIDMappingIndex 74 + ARRAY_SIZE(map_smmu), 75 + map_smmu); 76 + 77 + struct acpi_iort_id_mapping map_rc[] = {{ 78 + 0, 0xffff, 0, smmu_offset, 0 79 + }}; 80 + 81 + acpi_iort_add_rc(ctx, 82 + BIT(0) | BIT(56), // CacheCoherent + CPM 83 + 0, // AtsAttribute 84 + 0, // PciSegmentNumber 85 + 64, // MemoryAddressSizeLimit 86 + ARRAY_SIZE(map_rc), 87 + map_rc); 88 + return 0; 89 + } 90 + 91 + void acpi_fill_fadt(struct acpi_fadt *fadt) 92 + { 93 + fadt->flags = ACPI_FADT_HW_REDUCED_ACPI | ACPI_FADT_LOW_PWR_IDLE_S0; 94 + fadt->preferred_pm_profile = ACPI_PM_PERFORMANCE_SERVER; 95 + fadt->arm_boot_arch = ACPI_ARM_PSCI_COMPLIANT; 96 + } 97 + 98 + int acpi_fill_mcfg(struct acpi_ctx *ctx) 99 + { 100 + size_t size; 101 + 102 + /* PCI Segment Group 0, Start Bus Number 0, End Bus Number is 255 */ 103 + size = acpi_create_mcfg_mmconfig((void *)ctx->current, 104 + SBSA_PCIE_ECAM_BASE_ADDR, 0, 0, 255); 105 + acpi_inc(ctx, size); 106 + 107 + return 0; 108 + } 109 + 110 + static int sbsa_write_gtdt(struct acpi_ctx *ctx, const struct acpi_writer *entry) 111 + { 112 + struct acpi_table_header *header; 113 + struct acpi_gtdt *gtdt; 114 + 115 + gtdt = ctx->current; 116 + header = &gtdt->header; 117 + 118 + memset(gtdt, '\0', sizeof(struct acpi_gtdt)); 119 + 120 + acpi_fill_header(header, "GTDT"); 121 + header->length = sizeof(struct acpi_gtdt); 122 + header->revision = acpi_get_table_revision(ACPITAB_GTDT); 123 + 124 + gtdt->cnt_ctrl_base = 0xFFFFFFFFFFFFFFFF; 125 + gtdt->sec_el1_gsiv = 29; 126 + gtdt->sec_el1_flags = GTDT_FLAG_INT_ACTIVE_LOW; 127 + gtdt->el1_gsiv = 30; 128 + gtdt->el1_flags = GTDT_FLAG_INT_ACTIVE_LOW; 129 + gtdt->virt_el1_gsiv = 27; 130 + gtdt->virt_el1_flags = GTDT_FLAG_INT_ACTIVE_LOW; 131 + gtdt->el2_gsiv = 26; 132 + gtdt->el2_flags = GTDT_FLAG_INT_ACTIVE_LOW; 133 + gtdt->cnt_read_base = 0xffffffffffffffff; 134 + 135 + // FIXME: VirtualPL2Timer 136 + header->checksum = table_compute_checksum(header, header->length); 137 + 138 + acpi_add_table(ctx, gtdt); 139 + 140 + acpi_inc(ctx, sizeof(struct acpi_gtdt)); 141 + 142 + return 0; 143 + }; 144 + 145 + ACPI_WRITER(5gtdt, "GTDT", sbsa_write_gtdt, 0); 146 + 147 + static int acpi_write_pptt(struct acpi_ctx *ctx, const struct acpi_writer *entry) 148 + { 149 + struct acpi_table_header *header; 150 + int cluster_offset, l2_offset; 151 + u32 offsets[2]; 152 + 153 + header = ctx->current; 154 + ctx->tab_start = ctx->current; 155 + 156 + memset(header, '\0', sizeof(struct acpi_table_header)); 157 + 158 + acpi_fill_header(header, "PPTT"); 159 + header->revision = acpi_get_table_revision(ACPITAB_PPTT); 160 + acpi_inc(ctx, sizeof(*header)); 161 + 162 + cluster_offset = acpi_pptt_add_proc(ctx, ACPI_PPTT_PHYSICAL_PACKAGE | 163 + ACPI_PPTT_CHILDREN_IDENTICAL, 164 + 0, 0, 0, NULL); 165 + 166 + l2_offset = acpi_pptt_add_cache(ctx, ACPI_PPTT_ALL_VALID, 0, L2_SIZE, 167 + L2_SETS, L2_WAYS, L2_ATTRIBUTES, 64); 168 + 169 + offsets[0] = acpi_pptt_add_cache(ctx, ACPI_PPTT_ALL_VALID, l2_offset, 170 + L1D_SIZE, L1D_SETS, L1D_WAYS, 171 + L1D_ATTRIBUTES, 64); 172 + 173 + offsets[1] = acpi_pptt_add_cache(ctx, ACPI_PPTT_ALL_BUT_WRITE_POL, 174 + l2_offset, L1I_SIZE, L1I_SETS, 175 + L1I_WAYS, L1I_ATTRIBUTES, 64); 176 + 177 + for (int i = 0; i < uclass_id_count(UCLASS_CPU); i++) { 178 + acpi_pptt_add_proc(ctx, ACPI_PPTT_CHILDREN_IDENTICAL | 179 + ACPI_PPTT_NODE_IS_LEAF | ACPI_PPTT_PROC_ID_VALID, 180 + cluster_offset, i, 2, offsets); 181 + } 182 + 183 + header->length = ctx->current - ctx->tab_start; 184 + header->checksum = table_compute_checksum(header, header->length); 185 + 186 + acpi_inc(ctx, header->length); 187 + acpi_add_table(ctx, header); 188 + 189 + return 0; 190 + }; 191 + 192 + ACPI_WRITER(5pptt, "PPTT", acpi_write_pptt, 0);
+483
board/emulation/qemu-sbsa/dsdt.asl
··· 1 + /** @file 2 + * Differentiated System Description Table Fields (DSDT). 3 + * 4 + * Copyright (c) 2020, Linaro Ltd. All rights reserved. 5 + * 6 + * SPDX-License-Identifier: BSD-2-Clause-Patent 7 + **/ 8 + 9 + #include <configs/qemu-sbsa.h> 10 + 11 + #define LINK_DEVICE(Uid, LinkName, Irq) \ 12 + Device (LinkName) { \ 13 + Name (_HID, EISAID("PNP0C0F")) \ 14 + Name (_UID, Uid) \ 15 + Name (_PRS, ResourceTemplate() { \ 16 + Interrupt (ResourceProducer, Level, ActiveHigh, Exclusive) { Irq } \ 17 + }) \ 18 + Method (_STA) { \ 19 + Return (0xF) \ 20 + } \ 21 + Method (_CRS, 0) { Return (_PRS) } \ 22 + Method (_SRS, 1) { } \ 23 + Method (_DIS) { } \ 24 + } 25 + 26 + #define PRT_ENTRY(Address, Pin, Link) \ 27 + Package (4) { \ 28 + Address, Pin, Link, Zero \ 29 + } 30 + 31 + DefinitionBlock ("Dsdt.aml", "DSDT", 2, "U-Boot", "SBSAQEMU", 2) { 32 + Scope (_SB) { 33 + // UART PL011 34 + Device (COM0) { 35 + Name (_HID, "ARMH0011") 36 + Name (_UID, Zero) 37 + Name (_CRS, ResourceTemplate () { 38 + Memory32Fixed (ReadWrite, 39 + SBSA_UART_BASE_ADDR, 40 + SBSA_UART_LENGTH) 41 + Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { 33 } 42 + }) 43 + Method (_STA) { 44 + Return (0xF) 45 + } 46 + } 47 + 48 + // AHCI Host Controller 49 + Device (AHC0) { 50 + Name (_HID, "LNRO001E") 51 + Name (_CLS, Package (3) { 52 + 0x01, 53 + 0x06, 54 + 0x01, 55 + }) 56 + Name (_CCA, 1) 57 + Name (_CRS, ResourceTemplate() { 58 + Memory32Fixed (ReadWrite, 59 + SBSA_AHCI_BASE_ADDR, 60 + SBSA_AHCI_LENGTH) 61 + Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { 42 } 62 + }) 63 + Method (_STA) { 64 + Return (0xF) 65 + } 66 + } 67 + 68 + 69 + // USB XHCI Host Controller 70 + Device (USB0) { 71 + Name (_HID, "PNP0D10") // _HID: Hardware ID 72 + Name (_UID, 0x00) // _UID: Unique ID 73 + Name (_CCA, 0x01) // _CCA: Cache Coherency Attribute 74 + Name (XHCI, 0xF) // will be set using AcpiLib 75 + Method (_STA) { 76 + Return (XHCI) 77 + } 78 + Name (_CRS, ResourceTemplate() { 79 + Memory32Fixed (ReadWrite, 80 + SBSA_XHCI_BASE_ADDR, 81 + SBSA_XHCI_LENGTH) 82 + Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { 43 } 83 + }) 84 + 85 + // Root Hub 86 + Device (RHUB) { 87 + Name (_ADR, 0x00000000) // Address of Root Hub should be 0 as per ACPI 5.0 spec 88 + Method (_STA) { 89 + Return (0xF) 90 + } 91 + 92 + // Ports connected to Root Hub 93 + Device (HUB1) { 94 + Name (_ADR, 0x00000001) 95 + Name (_UPC, Package() { 96 + 0x00, // Port is NOT connectable 97 + 0xFF, // Don't care 98 + 0x00000000, // Reserved 0 must be zero 99 + 0x00000000 // Reserved 1 must be zero 100 + }) 101 + Method (_STA) { 102 + Return (0xF) 103 + } 104 + 105 + Device (PRT1) { 106 + Name (_ADR, 0x00000001) 107 + Name (_UPC, Package() { 108 + 0xFF, // Port is connectable 109 + 0x00, // Port connector is A 110 + 0x00000000, 111 + 0x00000000 112 + }) 113 + Name (_PLD, Package() { 114 + Buffer(0x10) { 115 + 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 116 + 0x31, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 117 + } 118 + }) 119 + Method (_STA) { 120 + Return (0xF) 121 + } 122 + } // USB0_RHUB_HUB1_PRT1 123 + Device (PRT2) { 124 + Name (_ADR, 0x00000002) 125 + Name (_UPC, Package() { 126 + 0xFF, // Port is connectable 127 + 0x00, // Port connector is A 128 + 0x00000000, 129 + 0x00000000 130 + }) 131 + Name (_PLD, Package() { 132 + Buffer(0x10) { 133 + 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 134 + 0x31, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 135 + } 136 + }) 137 + Method (_STA) { 138 + Return (0xF) 139 + } 140 + } // USB0_RHUB_HUB1_PRT2 141 + 142 + Device (PRT3) { 143 + Name (_ADR, 0x00000003) 144 + Name (_UPC, Package() { 145 + 0xFF, // Port is connectable 146 + 0x09, // Type C connector - USB2 and SS with Switch 147 + 0x00000000, 148 + 0x00000000 149 + }) 150 + Name (_PLD, Package() { 151 + Buffer (0x10) { 152 + 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 153 + 0x31, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 154 + } 155 + }) 156 + Method (_STA) { 157 + Return (0xF) 158 + } 159 + } // USB0_RHUB_HUB1_PRT3 160 + 161 + Device (PRT4) { 162 + Name (_ADR, 0x00000004) 163 + Name (_UPC, Package() { 164 + 0xFF, // Port is connectable 165 + 0x09, // Type C connector - USB2 and SS with Switch 166 + 0x00000000, 167 + 0x00000000 168 + }) 169 + Name (_PLD, Package() { 170 + Buffer (0x10){ 171 + 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 172 + 0x31, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 173 + } 174 + }) 175 + Method (_STA) { 176 + Return (0xF) 177 + } 178 + } // USB0_RHUB_HUB1_PRT4 179 + } // USB0_RHUB_HUB1 180 + } // USB0_RHUB 181 + } // USB0 182 + 183 + Device (PCI0) 184 + { 185 + Name (_HID, EISAID ("PNP0A08")) // PCI Express Root Bridge 186 + Name (_CID, EISAID ("PNP0A03")) // Compatible PCI Root Bridge 187 + Name (_SEG, Zero) // PCI Segment Group number 188 + Name (_BBN, Zero) // PCI Base Bus Number 189 + Name (_UID, "PCI0") 190 + Name (_CCA, One) // Initially mark the PCI coherent (for JunoR1) 191 + 192 + Method (_STA) { 193 + Return (0xF) 194 + } 195 + 196 + Method (_CBA, 0, NotSerialized) { 197 + return (SBSA_PCIE_ECAM_BASE_ADDR) 198 + } 199 + 200 + LINK_DEVICE(0, GSI0, 0x23) 201 + LINK_DEVICE(1, GSI1, 0x24) 202 + LINK_DEVICE(2, GSI2, 0x25) 203 + LINK_DEVICE(3, GSI3, 0x26) 204 + 205 + Name (_PRT, Package () // _PRT: PCI Routing Table 206 + { 207 + PRT_ENTRY(0x0000FFFF, 0, GSI0), 208 + PRT_ENTRY(0x0000FFFF, 0, GSI1), 209 + PRT_ENTRY(0x0000FFFF, 0, GSI2), 210 + PRT_ENTRY(0x0000FFFF, 0, GSI3), 211 + 212 + PRT_ENTRY(0x0001FFFF, 0, GSI1), 213 + PRT_ENTRY(0x0001FFFF, 1, GSI2), 214 + PRT_ENTRY(0x0001FFFF, 2, GSI3), 215 + PRT_ENTRY(0x0001FFFF, 3, GSI0), 216 + 217 + PRT_ENTRY(0x0002FFFF, 0, GSI2), 218 + PRT_ENTRY(0x0002FFFF, 1, GSI3), 219 + PRT_ENTRY(0x0002FFFF, 2, GSI0), 220 + PRT_ENTRY(0x0002FFFF, 3, GSI1), 221 + 222 + PRT_ENTRY(0x0003FFFF, 0, GSI3), 223 + PRT_ENTRY(0x0003FFFF, 1, GSI0), 224 + PRT_ENTRY(0x0003FFFF, 2, GSI1), 225 + PRT_ENTRY(0x0003FFFF, 3, GSI2), 226 + 227 + PRT_ENTRY(0x0004FFFF, 0, GSI0), 228 + PRT_ENTRY(0x0004FFFF, 1, GSI1), 229 + PRT_ENTRY(0x0004FFFF, 2, GSI2), 230 + PRT_ENTRY(0x0004FFFF, 3, GSI3), 231 + 232 + PRT_ENTRY(0x0005FFFF, 0, GSI1), 233 + PRT_ENTRY(0x0005FFFF, 1, GSI2), 234 + PRT_ENTRY(0x0005FFFF, 2, GSI3), 235 + PRT_ENTRY(0x0005FFFF, 3, GSI0), 236 + 237 + PRT_ENTRY(0x0006FFFF, 0, GSI2), 238 + PRT_ENTRY(0x0006FFFF, 1, GSI3), 239 + PRT_ENTRY(0x0006FFFF, 2, GSI0), 240 + PRT_ENTRY(0x0006FFFF, 3, GSI1), 241 + 242 + PRT_ENTRY(0x0007FFFF, 0, GSI3), 243 + PRT_ENTRY(0x0007FFFF, 1, GSI0), 244 + PRT_ENTRY(0x0007FFFF, 2, GSI1), 245 + PRT_ENTRY(0x0007FFFF, 3, GSI2), 246 + 247 + PRT_ENTRY(0x0008FFFF, 0, GSI0), 248 + PRT_ENTRY(0x0008FFFF, 1, GSI1), 249 + PRT_ENTRY(0x0008FFFF, 2, GSI2), 250 + PRT_ENTRY(0x0008FFFF, 3, GSI3), 251 + 252 + PRT_ENTRY(0x0009FFFF, 0, GSI1), 253 + PRT_ENTRY(0x0009FFFF, 1, GSI2), 254 + PRT_ENTRY(0x0009FFFF, 2, GSI3), 255 + PRT_ENTRY(0x0009FFFF, 3, GSI0), 256 + 257 + PRT_ENTRY(0x000AFFFF, 0, GSI2), 258 + PRT_ENTRY(0x000AFFFF, 1, GSI3), 259 + PRT_ENTRY(0x000AFFFF, 2, GSI0), 260 + PRT_ENTRY(0x000AFFFF, 3, GSI1), 261 + 262 + PRT_ENTRY(0x000BFFFF, 0, GSI3), 263 + PRT_ENTRY(0x000BFFFF, 1, GSI0), 264 + PRT_ENTRY(0x000BFFFF, 2, GSI1), 265 + PRT_ENTRY(0x000BFFFF, 3, GSI2), 266 + 267 + PRT_ENTRY(0x000CFFFF, 0, GSI0), 268 + PRT_ENTRY(0x000CFFFF, 1, GSI1), 269 + PRT_ENTRY(0x000CFFFF, 2, GSI2), 270 + PRT_ENTRY(0x000CFFFF, 3, GSI3), 271 + 272 + PRT_ENTRY(0x000DFFFF, 0, GSI1), 273 + PRT_ENTRY(0x000DFFFF, 1, GSI2), 274 + PRT_ENTRY(0x000DFFFF, 2, GSI3), 275 + PRT_ENTRY(0x000DFFFF, 3, GSI0), 276 + 277 + PRT_ENTRY(0x000EFFFF, 0, GSI2), 278 + PRT_ENTRY(0x000EFFFF, 1, GSI3), 279 + PRT_ENTRY(0x000EFFFF, 2, GSI0), 280 + PRT_ENTRY(0x000EFFFF, 3, GSI1), 281 + 282 + PRT_ENTRY(0x000FFFFF, 0, GSI3), 283 + PRT_ENTRY(0x000FFFFF, 1, GSI0), 284 + PRT_ENTRY(0x000FFFFF, 2, GSI1), 285 + PRT_ENTRY(0x000FFFFF, 3, GSI2), 286 + 287 + PRT_ENTRY(0x0010FFFF, 0, GSI0), 288 + PRT_ENTRY(0x0010FFFF, 1, GSI1), 289 + PRT_ENTRY(0x0010FFFF, 2, GSI2), 290 + PRT_ENTRY(0x0010FFFF, 3, GSI3), 291 + 292 + PRT_ENTRY(0x0011FFFF, 0, GSI1), 293 + PRT_ENTRY(0x0011FFFF, 1, GSI2), 294 + PRT_ENTRY(0x0011FFFF, 2, GSI3), 295 + PRT_ENTRY(0x0011FFFF, 3, GSI0), 296 + 297 + PRT_ENTRY(0x0012FFFF, 0, GSI2), 298 + PRT_ENTRY(0x0012FFFF, 1, GSI3), 299 + PRT_ENTRY(0x0012FFFF, 2, GSI0), 300 + PRT_ENTRY(0x0012FFFF, 3, GSI1), 301 + 302 + PRT_ENTRY(0x0013FFFF, 0, GSI3), 303 + PRT_ENTRY(0x0013FFFF, 1, GSI0), 304 + PRT_ENTRY(0x0013FFFF, 2, GSI1), 305 + PRT_ENTRY(0x0013FFFF, 3, GSI2), 306 + 307 + PRT_ENTRY(0x0014FFFF, 0, GSI0), 308 + PRT_ENTRY(0x0014FFFF, 1, GSI1), 309 + PRT_ENTRY(0x0014FFFF, 2, GSI2), 310 + PRT_ENTRY(0x0014FFFF, 3, GSI3), 311 + 312 + PRT_ENTRY(0x0015FFFF, 0, GSI1), 313 + PRT_ENTRY(0x0015FFFF, 1, GSI2), 314 + PRT_ENTRY(0x0015FFFF, 2, GSI3), 315 + PRT_ENTRY(0x0015FFFF, 3, GSI0), 316 + 317 + PRT_ENTRY(0x0016FFFF, 0, GSI2), 318 + PRT_ENTRY(0x0016FFFF, 1, GSI3), 319 + PRT_ENTRY(0x0016FFFF, 2, GSI0), 320 + PRT_ENTRY(0x0016FFFF, 3, GSI1), 321 + 322 + PRT_ENTRY(0x0017FFFF, 0, GSI3), 323 + PRT_ENTRY(0x0017FFFF, 1, GSI0), 324 + PRT_ENTRY(0x0017FFFF, 2, GSI1), 325 + PRT_ENTRY(0x0017FFFF, 3, GSI2), 326 + 327 + PRT_ENTRY(0x0018FFFF, 0, GSI0), 328 + PRT_ENTRY(0x0018FFFF, 1, GSI1), 329 + PRT_ENTRY(0x0018FFFF, 2, GSI2), 330 + PRT_ENTRY(0x0018FFFF, 3, GSI3), 331 + 332 + PRT_ENTRY(0x0019FFFF, 0, GSI1), 333 + PRT_ENTRY(0x0019FFFF, 1, GSI2), 334 + PRT_ENTRY(0x0019FFFF, 2, GSI3), 335 + PRT_ENTRY(0x0019FFFF, 3, GSI0), 336 + 337 + PRT_ENTRY(0x001AFFFF, 0, GSI2), 338 + PRT_ENTRY(0x001AFFFF, 1, GSI3), 339 + PRT_ENTRY(0x001AFFFF, 2, GSI0), 340 + PRT_ENTRY(0x001AFFFF, 3, GSI1), 341 + 342 + PRT_ENTRY(0x001BFFFF, 0, GSI3), 343 + PRT_ENTRY(0x001BFFFF, 1, GSI0), 344 + PRT_ENTRY(0x001BFFFF, 2, GSI1), 345 + PRT_ENTRY(0x001BFFFF, 3, GSI2), 346 + 347 + PRT_ENTRY(0x001CFFFF, 0, GSI0), 348 + PRT_ENTRY(0x001CFFFF, 1, GSI1), 349 + PRT_ENTRY(0x001CFFFF, 2, GSI2), 350 + PRT_ENTRY(0x001CFFFF, 3, GSI3), 351 + 352 + PRT_ENTRY(0x001DFFFF, 0, GSI1), 353 + PRT_ENTRY(0x001DFFFF, 1, GSI2), 354 + PRT_ENTRY(0x001DFFFF, 2, GSI3), 355 + PRT_ENTRY(0x001DFFFF, 3, GSI0), 356 + 357 + PRT_ENTRY(0x001EFFFF, 0, GSI2), 358 + PRT_ENTRY(0x001EFFFF, 1, GSI3), 359 + PRT_ENTRY(0x001EFFFF, 2, GSI0), 360 + PRT_ENTRY(0x001EFFFF, 3, GSI1), 361 + 362 + PRT_ENTRY(0x001FFFFF, 0, GSI3), 363 + PRT_ENTRY(0x001FFFFF, 1, GSI0), 364 + PRT_ENTRY(0x001FFFFF, 2, GSI1), 365 + PRT_ENTRY(0x001FFFFF, 3, GSI2), 366 + }) 367 + 368 + // Root complex resources 369 + Name (_CRS, ResourceTemplate () { 370 + WordBusNumber ( // Bus numbers assigned to this root 371 + ResourceProducer, 372 + MinFixed, MaxFixed, PosDecode, 373 + 0, // AddressGranularity 374 + 0, // AddressMinimum - Minimum Bus Number 375 + 0xff,// AddressMaximum - Maximum Bus Number 376 + 0, // AddressTranslation - Set to 0 377 + 256 // RangeLength - Number of Busses 378 + ) 379 + 380 + // IO to mmio window 381 + QWordIO ( 382 + ResourceProducer, MinFixed, 383 + MaxFixed, PosDecode, 384 + EntireRange, 385 + 0x00000000, // Granularity 386 + 0x0000, // Min Base Address 387 + 0xffff, // Max Base Address 388 + SBSA_PIO_BASE_ADDR, // Translate 389 + SBSA_PIO_LENGTH // Length 390 + ) 391 + 392 + DWordMemory ( // 32-bit BAR Windows 393 + ResourceProducer, PosDecode, 394 + MinFixed, MaxFixed, 395 + Cacheable, ReadWrite, 396 + 0x00000000, // Granularity 397 + SBSA_PCIE_MMIO_BASE_ADDR, // Min Base Address 398 + SBSA_PCIE_MMIO_END, // Max Base Address 399 + 0, // Translate 400 + SBSA_PCIE_MMIO_LENGTH // Length 401 + ) 402 + 403 + QWordMemory ( // 64-bit BAR Windows 404 + ResourceProducer, PosDecode, 405 + MinFixed, MaxFixed, 406 + Cacheable, ReadWrite, 407 + 0x00000000, // Granularity 408 + SBSA_PCIE_MMIO_HIGH_BASE_ADDR, // Min Base Address 409 + SBSA_PCIE_MMIO_HIGH_END, // Max Base Address 410 + 0, // Translate 411 + SBSA_PCIE_MMIO_HIGH_LENGTH // Length 412 + ) 413 + }) // Name(_CRS) 414 + 415 + Device (RES0) 416 + { 417 + Name (_HID, "PNP0C02" /* PNP Motherboard Resources */) // _HID: Hardware ID 418 + Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings 419 + { 420 + QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite, 421 + 0x0000000000000000, // Granularity 422 + SBSA_PCIE_ECAM_BASE_ADDR, // Range Minimum 423 + SBSA_PCIE_ECAM_END, // Range Maximum 424 + 0x0000000000000000, // Translation Offset 425 + SBSA_PCIE_ECAM_LENGTH, // Length 426 + ,, , AddressRangeMemory, TypeStatic) 427 + }) 428 + Method (_STA) { 429 + Return (0xF) 430 + } 431 + } 432 + 433 + // OS Control Handoff 434 + Name (SUPP, Zero) // PCI _OSC Support Field value 435 + Name (CTRL, Zero) // PCI _OSC Control Field value 436 + 437 + /* 438 + * See [1] 6.2.10, [2] 4.5 439 + */ 440 + Method (_OSC,4) { 441 + // Check for proper UUID 442 + If (Arg0 == ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766")) { 443 + // Create DWord-adressable fields from the Capabilities Buffer 444 + CreateDWordField (Arg3,0,CDW1) 445 + CreateDWordField (Arg3,4,CDW2) 446 + CreateDWordField (Arg3,8,CDW3) 447 + 448 + // Save Capabilities DWord2 & 3 449 + Store (CDW2,SUPP) 450 + Store (CDW3,CTRL) 451 + 452 + // Only allow native hot plug control if OS supports: 453 + // * ASPM 454 + // * Clock PM 455 + // * MSI/MSI-X 456 + If ((SUPP & 0x16) != 0x16) { 457 + CTRL &= 0x1E // Mask bit 0 (and undefined bits) 458 + } 459 + 460 + // Always allow native PME, AER (no dependencies) 461 + 462 + // Never allow SHPC (no SHPC controller in this system) 463 + CTRL &= 0x1D 464 + 465 + If (Arg1 != One) { // Unknown revision 466 + CDW1 |= 0x08 467 + } 468 + 469 + If (CDW3 != CTRL) { // Capabilities bits were masked 470 + CDW1 |= 0x10 471 + } 472 + 473 + // Update DWORD3 in the buffer 474 + Store (CTRL,CDW3) 475 + Return (Arg3) 476 + } Else { 477 + CDW1 |= 4 // Unrecognized UUID 478 + Return (Arg3) 479 + } 480 + } // End _OSC 481 + } 482 + } // Scope (_SB) 483 + }
+22
board/emulation/qemu-sbsa/lowlevel_init.S
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + /* 3 + * (C) Copyright 2016 4 + * Cédric Schieli <cschieli@gmail.com> 5 + */ 6 + 7 + #include <config.h> 8 + 9 + /* 10 + * Routine: save_boot_params (called after reset from start.S) 11 + * Description: save ATAG/FDT address provided by the firmware at boot time 12 + */ 13 + 14 + .global save_boot_params 15 + save_boot_params: 16 + /* The firmware provided ATAG/FDT address can be found in r2/x0 */ 17 + adr x8, fw_dtb_pointer 18 + str x0, [x8] 19 + 20 + 21 + /* Returns */ 22 + b save_boot_params_ret
+273
board/emulation/qemu-sbsa/qemu-sbsa.c
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + /* 3 + * Copyright (c) 2017 Tuomas Tynkkynen 4 + */ 5 + 6 + #include <cpu_func.h> 7 + #include <dm.h> 8 + #include <env.h> 9 + #include <fdtdec.h> 10 + #include <fdt_support.h> 11 + #include <init.h> 12 + #include <log.h> 13 + #include <usb.h> 14 + #include <asm/armv8/mmu.h> 15 + 16 + #include "qemu-sbsa.h" 17 + 18 + /* Assigned in lowlevel_init.S 19 + * Push the variable into the .data section so that it 20 + * does not get cleared later. 21 + */ 22 + unsigned long __section(".data") fw_dtb_pointer; 23 + 24 + static struct mm_region qemu_sbsa_mem_map[] = { 25 + { 26 + /* Secure flash */ 27 + .virt = SBSA_SECURE_FLASH_BASE_ADDR, 28 + .phys = SBSA_SECURE_FLASH_BASE_ADDR, 29 + .size = SBSA_SECURE_FLASH_LENGTH, 30 + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | 31 + PTE_BLOCK_INNER_SHARE | 32 + PTE_BLOCK_PXN | PTE_BLOCK_UXN 33 + }, { 34 + /* Flash */ 35 + .virt = SBSA_FLASH_BASE_ADDR, 36 + .phys = SBSA_FLASH_BASE_ADDR, 37 + .size = SBSA_FLASH_LENGTH, 38 + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | 39 + PTE_BLOCK_INNER_SHARE 40 + }, { 41 + /* Lowmem peripherals */ 42 + .virt = SBSA_PERIPH_BASE_ADDR, 43 + .phys = SBSA_PERIPH_BASE_ADDR, 44 + .size = SBSA_PCIE_MMIO_BASE_ADDR - SBSA_PERIPH_BASE_ADDR, 45 + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | 46 + PTE_BLOCK_NON_SHARE | 47 + PTE_BLOCK_PXN | PTE_BLOCK_UXN 48 + }, { 49 + /* 32-bit address PCIE MMIO space */ 50 + .virt = SBSA_PCIE_MMIO_BASE_ADDR, 51 + .phys = SBSA_PCIE_MMIO_BASE_ADDR, 52 + .size = SBSA_PCIE_MMIO_LENGTH, 53 + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | 54 + PTE_BLOCK_NON_SHARE | 55 + PTE_BLOCK_PXN | PTE_BLOCK_UXN 56 + }, { 57 + /* PCI-E ECAM memory area */ 58 + .virt = SBSA_PCIE_ECAM_BASE_ADDR, 59 + .phys = SBSA_PCIE_ECAM_BASE_ADDR, 60 + .size = SBSA_PCIE_ECAM_LENGTH, 61 + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | 62 + PTE_BLOCK_NON_SHARE | 63 + PTE_BLOCK_PXN | PTE_BLOCK_UXN 64 + }, { 65 + /* Highmem PCI-E MMIO memory area */ 66 + .virt = SBSA_PCIE_MMIO_HIGH_BASE_ADDR, 67 + .phys = SBSA_PCIE_MMIO_HIGH_BASE_ADDR, 68 + .size = SBSA_PCIE_MMIO_HIGH_LENGTH, 69 + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | 70 + PTE_BLOCK_NON_SHARE | 71 + PTE_BLOCK_PXN | PTE_BLOCK_UXN 72 + }, { 73 + /* DRAM */ 74 + .virt = SBSA_MEM_BASE_ADDR, 75 + .phys = SBSA_MEM_BASE_ADDR, 76 + .size = 0x800000000000ULL, 77 + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | 78 + PTE_BLOCK_INNER_SHARE 79 + }, { 80 + /* List terminator */ 81 + 0, 82 + } 83 + }; 84 + 85 + struct mm_region *mem_map = qemu_sbsa_mem_map; 86 + 87 + int board_late_init(void) 88 + { 89 + /* start usb so that usb keyboard can be used as input device */ 90 + if (CONFIG_IS_ENABLED(USB_KEYBOARD)) 91 + usb_init(); 92 + 93 + return 0; 94 + } 95 + 96 + int board_init(void) 97 + { 98 + return 0; 99 + } 100 + 101 + /** 102 + * dtb_dt_qemu - Return the address of the QEMU provided FDT. 103 + * 104 + * @return: Pointer to FDT or NULL on failure 105 + */ 106 + static void *dtb_dt_qemu(void) 107 + { 108 + /* FDT might be at start of DRAM */ 109 + if (fdt_magic(SBSA_MEM_BASE_ADDR) == FDT_MAGIC) 110 + return (void *)(u64)SBSA_MEM_BASE_ADDR; 111 + 112 + /* When ARM_LINUX_KERNEL_AS_BL33 is enabled in ATF, it's passed in x0 */ 113 + if (fw_dtb_pointer >= SBSA_MEM_BASE_ADDR && 114 + fdt_magic(fw_dtb_pointer) == FDT_MAGIC) { 115 + return (void *)fw_dtb_pointer; 116 + } 117 + 118 + return NULL; 119 + } 120 + 121 + /* 122 + * QEMU doesn't set compatible on cpus. 123 + * Add them to make sure the U-Boot driver properly bind. 124 + */ 125 + static int fdtdec_fix_cpus(void *fdt_blob) 126 + { 127 + int cpus_offset, off, ret; 128 + u64 mpidr, i = 0; 129 + 130 + cpus_offset = fdt_path_offset(fdt_blob, "/cpus"); 131 + if (cpus_offset < 0) { 132 + puts("couldn't find /cpus node\n"); 133 + return cpus_offset; 134 + } 135 + 136 + fdt_for_each_subnode(off, fdt_blob, cpus_offset) { 137 + if (strncmp(fdt_get_name(fdt_blob, off, NULL), "cpu@", 4)) 138 + continue; 139 + 140 + mpidr = 0; 141 + ret = smc_get_mpidr(i, &mpidr); 142 + if (ret) { 143 + log_warning("Failed to get MPIDR for processor %lld from SMC: %d\n", 144 + i, ret); 145 + mpidr = i; 146 + } 147 + 148 + ret = fdt_setprop_string(fdt_blob, off, "compatible", "arm,armv8"); 149 + if (ret < 0) 150 + return ret; 151 + 152 + ret = fdt_setprop_string(fdt_blob, off, "device_type", "cpu"); 153 + if (ret < 0) 154 + return ret; 155 + 156 + ret = fdt_setprop_u64(fdt_blob, off, "reg", mpidr); 157 + if (ret < 0) 158 + return ret; 159 + i++; 160 + } 161 + return 0; 162 + } 163 + 164 + /* 165 + * Update the GIC node when necessary and add optional ITS when it has a 166 + * non zero base-address. 167 + */ 168 + static int fdtdec_fix_gic(void *fdt) 169 + { 170 + u64 gic_dist_base = SBSA_GIC_DIST_BASE_ADDR; 171 + u64 gic_redist_base = SBSA_GIC_REDIST_BASE_ADDR; 172 + u64 gic_its_base = 0; 173 + int offs, ret; 174 + u64 reg[10]; 175 + 176 + /* Invoke SMC to get real base-address */ 177 + smc_get_gic_dist_base(&gic_dist_base); 178 + smc_get_gic_redist_base(&gic_redist_base); 179 + 180 + if ((gic_dist_base != SBSA_GIC_DIST_BASE_ADDR) || 181 + (gic_redist_base != SBSA_GIC_REDIST_BASE_ADDR)) { 182 + offs = fdt_path_offset(fdt, "/interrupt-controller"); 183 + if (offs < 0) { 184 + puts("couldn't find /interrupt-controller node\n"); 185 + return offs; 186 + } 187 + 188 + reg[0] = cpu_to_fdt64(gic_dist_base); 189 + reg[1] = cpu_to_fdt64((u64)SBSA_GIC_DIST_LENGTH); 190 + reg[2] = cpu_to_fdt64(gic_redist_base); 191 + reg[3] = cpu_to_fdt64((u64)SBSA_GIC_REDIST_LENGTH); 192 + reg[4] = cpu_to_fdt64(0); 193 + reg[5] = cpu_to_fdt64(0); 194 + reg[6] = cpu_to_fdt64(SBSA_GIC_HBASE_ADDR); 195 + reg[7] = cpu_to_fdt64((u64)SBSA_GIC_HBASE_LENGTH); 196 + reg[8] = cpu_to_fdt64(SBSA_GIC_VBASE_ADDR); 197 + reg[9] = cpu_to_fdt64((u64)SBSA_GIC_VBASE_LENGTH); 198 + 199 + ret = fdt_setprop_inplace(fdt, offs, "reg", reg, sizeof(reg)); 200 + } 201 + 202 + smc_get_gic_its_base(&gic_its_base); 203 + 204 + if (gic_its_base != 0) { 205 + offs = fdt_path_offset(fdt, "/its"); 206 + if (offs < 0) 207 + return offs; 208 + 209 + ret = fdt_setprop_string(fdt, offs, "status", "okay"); 210 + if (ret < 0) 211 + return ret; 212 + 213 + reg[0] = cpu_to_fdt64(gic_its_base); 214 + reg[1] = 0; 215 + 216 + ret = fdt_setprop(fdt, offs, "reg", reg, sizeof(u64) * 2); 217 + if (ret < 0) 218 + return ret; 219 + } 220 + 221 + return 0; 222 + } 223 + 224 + int fdtdec_board_setup(const void *fdt_blob) 225 + { 226 + void *qemu_fdt; 227 + int ret; 228 + 229 + /* 230 + * Locate the QEMU provided DTB that contains the CPUs and amount of DRAM. 231 + */ 232 + qemu_fdt = dtb_dt_qemu(); 233 + if (!qemu_fdt) { 234 + log_err("QEMU FDT not found\n"); 235 + return -ENODEV; 236 + } 237 + 238 + ret = fdt_increase_size((void *)fdt_blob, 1024 + fdt_totalsize(qemu_fdt)); 239 + if (ret) 240 + return -ENOMEM; 241 + 242 + /* 243 + * Merge the QEMU DTB as overlay into the U-Boot provided DTB. 244 + */ 245 + ret = fdt_overlay_apply_node((void *)fdt_blob, 0, qemu_fdt, 0); 246 + if (ret < 0) 247 + log_err("Failed to apply overlay: %d\n", ret); 248 + 249 + /* Fix QEMU nodes to make sure U-Boot drivers are properly working */ 250 + ret = fdtdec_fix_cpus((void *)fdt_blob); 251 + if (ret < 0) 252 + log_err("Failed to fix CPUs in FDT: %d\n", ret); 253 + 254 + ret = fdtdec_fix_gic((void *)fdt_blob); 255 + if (ret < 0) 256 + log_err("Failed to fix INTC in FDT: %d\n", ret); 257 + 258 + return 0; 259 + } 260 + 261 + int misc_init_r(void) 262 + { 263 + return env_set_hex("fdt_addr", (uintptr_t)gd->fdt_blob); 264 + } 265 + 266 + void reset_cpu(void) 267 + { 268 + } 269 + 270 + int dram_init(void) 271 + { 272 + return fdtdec_setup_mem_size_base(); 273 + }
+14
board/emulation/qemu-sbsa/qemu-sbsa.env
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + 3 + /* environment for qemu-arm and qemu-arm64 */ 4 + 5 + stdin=serial,usbkbd 6 + stdout=serial,vidconsole 7 + stderr=serial,vidconsole 8 + fdt_high=0xffffffffffffffff 9 + initrd_high=0xffffffffffffffff 10 + scriptaddr=0x100000300000 11 + pxefile_addr_r=0x10000400000 12 + kernel_addr_r=0x10000200000 13 + ramdisk_addr_r=0x10001000000 14 + boot_targets=qfw usb scsi virtio nvme dhcp
+38
board/emulation/qemu-sbsa/qemu-sbsa.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + /* 3 + * Copyright (c) 2024 9elements GmbH 4 + */ 5 + 6 + /** 7 + * smc_get_mpidr() - Call into SMC and get the MPIDR for given CPU 8 + * 9 + * @id: CPU index 10 + * @mpidr: Pointer where to place the MPIDR 11 + * @return 0 if OK, other -ve on error 12 + */ 13 + int smc_get_mpidr(unsigned long id, u64 *mpidr); 14 + 15 + /** 16 + * smc_get_gic_dist_base() - Call into SMC and get GIC dist base address 17 + * 18 + * @mpidr: Pointer where to place the base address 19 + * @return 0 if OK, other -ve on error 20 + */ 21 + int smc_get_gic_dist_base(u64 *base); 22 + 23 + /** 24 + * smc_get_gic_redist_base() - Call into SMC and get the GIC redistributor 25 + * base address 26 + * 27 + * @mpidr: Pointer where to place the base address 28 + * @return 0 if OK, other -ve on error 29 + */ 30 + int smc_get_gic_redist_base(u64 *base); 31 + 32 + /** 33 + * smc_get_gic_its_base() - Call into SMC and get the ITS base address 34 + * 35 + * @mpidr: Pointer where to place the base address 36 + * @return 0 if OK, other -ve on error 37 + */ 38 + int smc_get_gic_its_base(u64 *base);
+71
board/emulation/qemu-sbsa/smc.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Copyright (c) 2024 9elements GmbH 4 + */ 5 + 6 + #include <cpu.h> 7 + #include <init.h> 8 + #include <log.h> 9 + #include <linux/arm-smccc.h> 10 + 11 + #define SMC_SIP_FUNCTION_ID(n) (0xC2000000 | (n)) 12 + 13 + #define SIP_SVC_VERSION SMC_SIP_FUNCTION_ID(1) 14 + #define SIP_SVC_GET_GIC SMC_SIP_FUNCTION_ID(100) 15 + #define SIP_SVC_GET_GIC_ITS SMC_SIP_FUNCTION_ID(101) 16 + #define SIP_SVC_GET_CPU_COUNT SMC_SIP_FUNCTION_ID(200) 17 + #define SIP_SVC_GET_CPU_NODE SMC_SIP_FUNCTION_ID(201) 18 + #define SIP_SVC_GET_MEMORY_NODE_COUNT SMC_SIP_FUNCTION_ID(300) 19 + #define SIP_SVC_GET_MEMORY_NODE SMC_SIP_FUNCTION_ID(301) 20 + 21 + int smc_get_mpidr(unsigned long id, u64 *mpidr) 22 + { 23 + struct arm_smccc_res res; 24 + 25 + res.a0 = ~0; 26 + arm_smccc_smc(SIP_SVC_GET_CPU_NODE, id, 0, 0, 0, 0, 0, 0, &res); 27 + 28 + if (!res.a0) 29 + *mpidr = res.a2; 30 + 31 + return res.a0; 32 + } 33 + 34 + int smc_get_gic_dist_base(u64 *base) 35 + { 36 + struct arm_smccc_res res; 37 + 38 + res.a0 = ~0; 39 + arm_smccc_smc(SIP_SVC_GET_GIC, 0, 0, 0, 0, 0, 0, 0, &res); 40 + 41 + if (!res.a0) 42 + *base = res.a1; 43 + 44 + return res.a0; 45 + } 46 + 47 + int smc_get_gic_redist_base(u64 *base) 48 + { 49 + struct arm_smccc_res res; 50 + 51 + res.a0 = ~0; 52 + arm_smccc_smc(SIP_SVC_GET_GIC, 0, 0, 0, 0, 0, 0, 0, &res); 53 + 54 + if (!res.a0) 55 + *base = res.a2; 56 + 57 + return res.a0; 58 + } 59 + 60 + int smc_get_gic_its_base(u64 *base) 61 + { 62 + struct arm_smccc_res res; 63 + 64 + res.a0 = ~0; 65 + arm_smccc_smc(SIP_SVC_GET_GIC_ITS, 0, 0, 0, 0, 0, 0, 0, &res); 66 + 67 + if (!res.a0) 68 + *base = res.a1; 69 + 70 + return res.a0; 71 + }
+3
board/raspberrypi/rpi/.gitignore
··· 1 + dsdt_generated.aml 2 + dsdt_generated.asl.tmp 3 + dsdt_generated.c
+2
board/raspberrypi/rpi/Makefile
··· 4 4 5 5 obj-y := rpi.o 6 6 obj-y += lowlevel_init.o 7 + 8 + obj-$(CONFIG_GENERATE_ACPI_TABLE) += dsdt_generated.o
+90
board/raspberrypi/rpi/acpitables.h
··· 1 + /** @file 2 + * 3 + * RPi defines for constructing ACPI tables 4 + * 5 + * Copyright (c) 2020, Pete Batard <pete@akeo.ie> 6 + * Copyright (c) 2019, ARM Ltd. All rights reserved. 7 + * Copyright (c) 2018, Andrei Warkentin <andrey.warkentin@gmail.com> 8 + * Copyright (c) Microsoft Corporation. All rights reserved. 9 + * 10 + * SPDX-License-Identifier: BSD-2-Clause-Patent 11 + * 12 + **/ 13 + 14 + #ifndef __RPI_ACPITABLES_H__ 15 + #define __RPI_ACPITABLES_H__ 16 + 17 + #include <acpi/acpi_table.h> 18 + 19 + // The ASL compiler can't perform arithmetic on MEMORY32FIXED () 20 + // parameters so you can't pass a constant like BASE + OFFSET. 21 + // We therefore define a macro that can perform arithmetic base 22 + // address update with an offset. 23 + #define MEMORY32SETBASE(BufName, MemName, VarName, Offset) \ 24 + CreateDwordField (^BufName, ^MemName._BAS, VarName) \ 25 + Add (BCM2836_SOC_REGISTERS, Offset, VarName) 26 + 27 + //------------------------------------------------------------------------ 28 + // Interrupts. These are specific to each platform 29 + //------------------------------------------------------------------------ 30 + #if defined(CONFIG_TARGET_RPI_3) 31 + #define BCM2836_V3D_BUS_INTERRUPT 0x2A 32 + #define BCM2836_DMA_INTERRUPT 0x3B 33 + #define BCM2836_SPI1_INTERRUPT 0x3D 34 + #define BCM2836_SPI2_INTERRUPT 0x3D 35 + #define BCM2836_HVS_INTERRUPT 0x41 36 + #define BCM2836_HDMI0_INTERRUPT 0x48 37 + #define BCM2836_HDMI1_INTERRUPT 0x49 38 + #define BCM2836_PV2_INTERRUPT 0x4A 39 + #define BCM2836_PV0_INTERRUPT 0x4D 40 + #define BCM2836_PV1_INTERRUPT 0x4E 41 + #define BCM2836_MBOX_INTERRUPT 0x61 42 + #define BCM2836_VCHIQ_INTERRUPT 0x62 43 + #define BCM2386_GPIO_INTERRUPT0 0x51 44 + #define BCM2386_GPIO_INTERRUPT1 0x52 45 + #define BCM2386_GPIO_INTERRUPT2 0x53 46 + #define BCM2386_GPIO_INTERRUPT3 0x54 47 + #define BCM2836_I2C1_INTERRUPT 0x55 48 + #define BCM2836_I2C2_INTERRUPT 0x55 49 + #define BCM2836_SPI0_INTERRUPT 0x56 50 + #define BCM2836_USB_INTERRUPT 0x29 51 + #define BCM2836_SDHOST_INTERRUPT 0x58 52 + #define BCM2836_MMCHS1_INTERRUPT 0x5E 53 + #define BCM2836_MINI_UART_INTERRUPT 0x3D 54 + #define BCM2836_PL011_UART_INTERRUPT 0x59 55 + #elif defined(CONFIG_TARGET_RPI_4) 56 + #define BCM2836_V3D_BUS_INTERRUPT 0x2A 57 + #define BCM2836_DMA_INTERRUPT 0x3B 58 + #define BCM2836_SPI1_INTERRUPT 0x7D 59 + #define BCM2836_SPI2_INTERRUPT 0x7D 60 + #define BCM2836_HVS_INTERRUPT 0x41 61 + #define BCM2836_HDMI0_INTERRUPT 0x48 62 + #define BCM2836_HDMI1_INTERRUPT 0x49 63 + #define BCM2836_PV2_INTERRUPT 0x4A 64 + #define BCM2836_PV0_INTERRUPT 0x4D 65 + #define BCM2836_PV1_INTERRUPT 0x4E 66 + #define BCM2836_MBOX_INTERRUPT 0x41 67 + #define BCM2836_VCHIQ_INTERRUPT 0x42 68 + #define BCM2386_GPIO_INTERRUPT0 0x91 69 + #define BCM2386_GPIO_INTERRUPT1 0x92 70 + #define BCM2386_GPIO_INTERRUPT2 0x93 71 + #define BCM2386_GPIO_INTERRUPT3 0x94 72 + #define BCM2836_I2C1_INTERRUPT 0x95 73 + #define BCM2836_I2C2_INTERRUPT 0x95 74 + #define BCM2836_SPI0_INTERRUPT 0x96 75 + #define BCM2836_USB_INTERRUPT 0x69 76 + #define BCM2836_SDHOST_INTERRUPT 0x98 77 + #define BCM2836_MMCHS1_INTERRUPT 0x9E 78 + #define BCM2836_MINI_UART_INTERRUPT 0x7D 79 + #define BCM2836_PL011_UART_INTERRUPT 0x99 80 + #define GENET_INTERRUPT0 0xBD 81 + #define GENET_INTERRUPT1 0xBE 82 + #define GENET_BASE_ADDRESS 0xFD580000 83 + #define GENET_LENGTH 0x10000 84 + #define THERM_SENSOR_BASE_ADDRESS 0xFD5d2200 85 + #define THERM_SENSOR_LENGTH 0x8 86 + #else 87 + #error "Unsupported rpi module for ACPI tables" 88 + #endif 89 + 90 + #endif // __ACPITABLES_H__
+254
board/raspberrypi/rpi/dsdt.asl
··· 1 + /** @file 2 + * 3 + * Differentiated System Definition Table (DSDT) 4 + * 5 + * Copyright (c) 2020, Pete Batard <pete@akeo.ie> 6 + * Copyright (c) 2018-2020, Andrey Warkentin <andrey.warkentin@gmail.com> 7 + * Copyright (c) Microsoft Corporation. All rights reserved. 8 + * Copyright (c) 2021, ARM Limited. All rights reserved. 9 + * 10 + * SPDX-License-Identifier: BSD-2-Clause-Patent 11 + * 12 + **/ 13 + 14 + #include <asm/arch/acpi/bcm2711.h> 15 + #include <asm/arch/acpi/bcm2836.h> 16 + #include <asm/arch/acpi/bcm2836_gpio.h> 17 + #include <asm/arch/acpi/bcm2836_gpu.h> 18 + #include <asm/arch/acpi/bcm2836_pwm.h> 19 + #include <asm/arch/acpi/bcm2836_sdio.h> 20 + #include <asm/arch/acpi/bcm2836_sdhost.h> 21 + 22 + #include "acpitables.h" 23 + 24 + #define BCM_ALT0 0x4 25 + #define BCM_ALT1 0x5 26 + #define BCM_ALT2 0x6 27 + #define BCM_ALT3 0x7 28 + #define BCM_ALT4 0x3 29 + #define BCM_ALT5 0x2 30 + 31 + // 32 + // The ASL compiler does not support argument arithmetic in functions 33 + // like QWordMemory (). So we need to instantiate dummy qword regions 34 + // that we can then update the Min, Max and Length attributes of. 35 + // The three macros below help accomplish this. 36 + // 37 + // QWORDMEMORYSET specifies a CPU memory range (whose base address is 38 + // BCM2836_SOC_REGISTERS + Offset), and QWORDBUSMEMORYSET specifies 39 + // a VPU memory range (whose base address is provided directly). 40 + // 41 + #define QWORDMEMORYBUF(Index) \ 42 + QWordMemory (ResourceProducer,, \ 43 + MinFixed, MaxFixed, NonCacheable, ReadWrite, \ 44 + 0x0, 0x0, 0x0, 0x0, 0x1,,, RB ## Index) 45 + 46 + #define QWORDMEMORYSET(Index, Offset, Length) \ 47 + CreateQwordField (RBUF, RB ## Index._MIN, MI ## Index) \ 48 + CreateQwordField (RBUF, RB ## Index._MAX, MA ## Index) \ 49 + CreateQwordField (RBUF, RB ## Index._LEN, LE ## Index) \ 50 + Store (Length, LE ## Index) \ 51 + Add (BCM2836_SOC_REGISTERS, Offset, MI ## Index) \ 52 + Add (MI ## Index, LE ## Index - 1, MA ## Index) 53 + 54 + #define QWORDBUSMEMORYSET(Index, Base, Length) \ 55 + CreateQwordField (RBUF, RB ## Index._MIN, MI ## Index) \ 56 + CreateQwordField (RBUF, RB ## Index._MAX, MA ## Index) \ 57 + CreateQwordField (RBUF, RB ## Index._LEN, LE ## Index) \ 58 + Store (Base, MI ## Index) \ 59 + Store (Length, LE ## Index) \ 60 + Add (MI ## Index, LE ## Index - 1, MA ## Index) 61 + 62 + DefinitionBlock ("Dsdt.aml", "DSDT", 2, "RPIFDN", "RPI", 2) 63 + { 64 + External (\_PR.CP00, DeviceObj) 65 + External (\_PR.CP01, DeviceObj) 66 + External (\_PR.CP02, DeviceObj) 67 + External (\_PR.CP03, DeviceObj) 68 + Scope (\_SB_) 69 + { 70 + include ("pep.asl") 71 + 72 + // 73 + // GPU device container describes the DMA translation required 74 + // when a device behind the GPU wants to access Arm memory. 75 + // Only the first GB can be addressed. 76 + // 77 + Device (GDV0) 78 + { 79 + Name (_HID, "ACPI0004") 80 + Name (_UID, 0x1) 81 + Name (_CCA, 0x0) 82 + 83 + Method (_CRS, 0, Serialized) { 84 + // 85 + // Container devices with _DMA must have _CRS, meaning GDV0 86 + // to provide all resources that GpuDevs.asl consume (except 87 + // interrupts). 88 + // 89 + Name (RBUF, ResourceTemplate () { 90 + QWORDMEMORYBUF(01) 91 + QWORDMEMORYBUF(02) 92 + QWORDMEMORYBUF(03) 93 + // QWORDMEMORYBUF(04) 94 + // QWORDMEMORYBUF(05) 95 + QWORDMEMORYBUF(06) 96 + QWORDMEMORYBUF(07) 97 + QWORDMEMORYBUF(08) 98 + QWORDMEMORYBUF(09) 99 + QWORDMEMORYBUF(10) 100 + QWORDMEMORYBUF(11) 101 + QWORDMEMORYBUF(12) 102 + QWORDMEMORYBUF(13) 103 + QWORDMEMORYBUF(14) 104 + QWORDMEMORYBUF(15) 105 + // QWORDMEMORYBUF(16) 106 + QWORDMEMORYBUF(17) 107 + QWORDMEMORYBUF(18) 108 + QWORDMEMORYBUF(19) 109 + QWORDMEMORYBUF(20) 110 + QWORDMEMORYBUF(21) 111 + QWORDMEMORYBUF(22) 112 + QWORDMEMORYBUF(23) 113 + QWORDMEMORYBUF(24) 114 + QWORDMEMORYBUF(25) 115 + }) 116 + 117 + // USB 118 + QWORDMEMORYSET(01, BCM2836_USB_OFFSET, BCM2836_USB_LENGTH) 119 + 120 + // GPU 121 + QWORDMEMORYSET(02, BCM2836_V3D_BUS_OFFSET, BCM2836_V3D_BUS_LENGTH) 122 + QWORDMEMORYSET(03, BCM2836_HVS_OFFSET, BCM2836_HVS_LENGTH) 123 + // QWORDMEMORYSET(04, BCM2836_PV0_OFFSET, BCM2836_PV0_LENGTH) 124 + // QWORDMEMORYSET(05, BCM2836_PV1_OFFSET, BCM2836_PV1_LENGTH) 125 + QWORDMEMORYSET(06, BCM2836_PV2_OFFSET, BCM2836_PV2_LENGTH) 126 + QWORDMEMORYSET(07, BCM2836_HDMI0_OFFSET, BCM2836_HDMI0_LENGTH) 127 + QWORDMEMORYSET(08, BCM2836_HDMI1_OFFSET, BCM2836_HDMI1_LENGTH) 128 + 129 + // Mailbox 130 + QWORDMEMORYSET(09, BCM2836_MBOX_OFFSET, BCM2836_MBOX_LENGTH) 131 + 132 + // VCHIQ 133 + QWORDMEMORYSET(10, BCM2836_VCHIQ_OFFSET, BCM2836_VCHIQ_LENGTH) 134 + 135 + // GPIO 136 + QWORDMEMORYSET(11, GPIO_OFFSET, GPIO_LENGTH) 137 + 138 + // I2C 139 + QWORDMEMORYSET(12, BCM2836_I2C1_OFFSET, BCM2836_I2C1_LENGTH) 140 + QWORDMEMORYSET(13, BCM2836_I2C2_OFFSET, BCM2836_I2C2_LENGTH) 141 + 142 + // SPI 143 + QWORDMEMORYSET(14, BCM2836_SPI0_OFFSET, BCM2836_SPI0_LENGTH) 144 + QWORDMEMORYSET(15, BCM2836_SPI1_OFFSET, BCM2836_SPI1_LENGTH) 145 + // QWORDMEMORYSET(16, BCM2836_SPI2_OFFSET, BCM2836_SPI2_LENGTH) 146 + 147 + // PWM 148 + QWORDMEMORYSET(17, BCM2836_PWM_DMA_OFFSET, BCM2836_PWM_DMA_LENGTH) 149 + QWORDMEMORYSET(18, BCM2836_PWM_CTRL_OFFSET, BCM2836_PWM_CTRL_LENGTH) 150 + QWORDBUSMEMORYSET(19, BCM2836_PWM_BUS_BASE_ADDRESS, BCM2836_PWM_BUS_LENGTH) 151 + QWORDBUSMEMORYSET(20, BCM2836_PWM_CTRL_UNCACHED_BASE_ADDRESS, BCM2836_PWM_CTRL_UNCACHED_LENGTH) 152 + QWORDMEMORYSET(21, BCM2836_PWM_CLK_OFFSET, BCM2836_PWM_CLK_LENGTH) 153 + 154 + // UART 155 + QWORDMEMORYSET(22, BCM2836_PL011_UART_OFFSET, BCM2836_PL011_UART_LENGTH) 156 + QWORDMEMORYSET(23, BCM2836_MINI_UART_OFFSET, BCM2836_MINI_UART_LENGTH) 157 + 158 + // SDC 159 + QWORDMEMORYSET(24, MMCHS1_OFFSET, MMCHS1_LENGTH) 160 + QWORDMEMORYSET(25, SDHOST_OFFSET, SDHOST_LENGTH) 161 + 162 + Return (RBUF) 163 + } 164 + 165 + Name (_DMA, ResourceTemplate() { 166 + // 167 + // Only the first GB is available. 168 + // Bus 0xC0000000 -> CPU 0x00000000. 169 + // 170 + QWordMemory (ResourceProducer, 171 + , 172 + MinFixed, 173 + MaxFixed, 174 + NonCacheable, 175 + ReadWrite, 176 + 0x0, 177 + 0x00000000C0000000, // MIN 178 + 0x00000000FFFFFFFF, // MAX 179 + 0xFFFFFFFF40000000, // TRA 180 + 0x0000000040000000, // LEN 181 + , 182 + , 183 + ) 184 + }) 185 + #include "gpudevs.asl" 186 + } 187 + 188 + #if defined(CONFIG_TARGET_RPI_4) 189 + Device (ETH0) 190 + { 191 + Name (_HID, "BCM6E4E") 192 + Name (_CID, "BCM6E4E") 193 + Name (_UID, 0x0) 194 + Name (_CCA, 0x0) 195 + 196 + Method (_CRS, 0x0, Serialized) 197 + { 198 + Return (ResourceTemplate () 199 + { 200 + // No need for MEMORY32SETBASE on Genet as we have a straight base address constant 201 + MEMORY32FIXED (ReadWrite, GENET_BASE_ADDRESS, GENET_LENGTH, ) 202 + Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { GENET_INTERRUPT0, GENET_INTERRUPT1 } 203 + }) 204 + } 205 + Name (_DSD, Package () { 206 + ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), 207 + Package () { 208 + Package () { "brcm,max-dma-burst-size", 0x08 }, 209 + Package () { "phy-mode", "rgmii-rxid" }, 210 + } 211 + }) 212 + } 213 + 214 + // Define a simple thermal zone. The idea here is we compute the SOC temp 215 + // via a register we can read, and give it to the OS. This enables basic 216 + // reports from the "sensors" utility, and the OS can then poll and take 217 + // actions if that temp exceeds any of the given thresholds. 218 + Device (EC00) 219 + { 220 + Name (_HID, EISAID ("PNP0C06")) 221 + Name (_CCA, 0x0) 222 + 223 + // all temps in are tenths of K (aka 2732 is the min temps in Linux (aka 0C)) 224 + ThermalZone (TZ00) { 225 + OperationRegion (TEMS, SystemMemory, THERM_SENSOR_BASE_ADDRESS, THERM_SENSOR_LENGTH) 226 + Field (TEMS, DWordAcc, NoLock, Preserve) { 227 + TMPS, 32 228 + } 229 + Method (_TMP, 0, Serialized) { 230 + return (((410040 - ((TMPS & 0x3ff) * 487)) / 100) + 2732); 231 + } 232 + 233 + Method (_SCP, 3) { } // receive cooling policy from OS 234 + 235 + Method (_CRT) { Return (3632) } // (90C) Critical temp point (immediate power-off) 236 + Method (_HOT) { Return (3582) } // (85C) HOT state where OS should hibernate 237 + Method (_PSV) { Return (3532) } // (80C) Passive cooling (CPU throttling) trip point 238 + 239 + // SSDT inserts _AC0/_AL0 @60C here, if a FAN is configured 240 + 241 + Name (_TZP, 10) //The OSPM must poll this device every 1 seconds 242 + Name (_PSL, Package () { \_PR.CP00, \_PR.CP01, \_PR.CP02, \_PR.CP03 }) 243 + } 244 + } 245 + #endif 246 + 247 + 248 + #include "uart.asl" 249 + #include "rhpx.asl" 250 + #include "sdhc.asl" 251 + #include "emmc.asl" 252 + #include "pci.asl" 253 + } 254 + }
+136
board/raspberrypi/rpi/emmc.asl
··· 1 + /** @file 2 + * 3 + * Copyright (c) 2021, ARM Limited. All rights reserved. 4 + * 5 + * SPDX-License-Identifier: BSD-2-Clause-Patent 6 + * 7 + **/ 8 + 9 + #include <asm/arch/acpi/bcm2836_sdhost.h> 10 + #include <asm/arch/acpi/bcm2836_sdio.h> 11 + #include <asm/arch/acpi/bcm2711.h> 12 + 13 + Device (GDV1) { 14 + Name (_HID, "ACPI0004") 15 + Name (_UID, 0x2) 16 + Name (_CCA, 0x0) 17 + 18 + Name (RBUF, ResourceTemplate () 19 + { 20 + MEMORY32FIXED (ReadWrite, 0, MMCHS2_LENGTH, RMEM) 21 + }) 22 + Method (_CRS, 0x0, Serialized) 23 + { 24 + MEMORY32SETBASE (RBUF, RMEM, RBAS, MMCHS2_OFFSET) 25 + Return (^RBUF) 26 + } 27 + 28 + // Translated DMA region for BCM2711 silicon revisions older than C0 29 + Name (DMTR, ResourceTemplate() { 30 + QWordMemory (ResourceProducer, 31 + , 32 + MinFixed, 33 + MaxFixed, 34 + NonCacheable, 35 + ReadWrite, 36 + 0x0, 37 + 0x00000000C0000000, // MIN 38 + 0x00000000FFFFFFFF, // MAX 39 + 0xFFFFFFFF40000000, // TRA 40 + 0x0000000040000000, // LEN 41 + , 42 + , 43 + ) 44 + }) 45 + 46 + // Non translated DMA region for BCM2711 revisions C0 and newer 47 + Name (DMNT, ResourceTemplate() { 48 + QWordMemory (ResourceProducer, 49 + , 50 + MinFixed, 51 + MaxFixed, 52 + NonCacheable, 53 + ReadWrite, 54 + 0x0, 55 + 0x0000000000000000, // MIN 56 + 0x000000FFFFFFFFFF, // MAX 57 + 0x0000000000000000, // TRA 58 + 0x0000010000000000, // LEN 59 + , 60 + , 61 + ) 62 + }) 63 + 64 + // emmc2 Host Controller. (brcm,bcm2711-emmc2) 65 + Device (SDC3) 66 + { 67 + Name (_HID, "BRCME88C") 68 + Name (_UID, 0x1) 69 + Name (_CCA, 0x0) 70 + Name (_S1D, 0x1) 71 + Name (_S2D, 0x1) 72 + Name (_S3D, 0x1) 73 + Name (_S4D, 0x1) 74 + Name (SDMA, 0x2) 75 + 76 + Name (RBUF, ResourceTemplate () 77 + { 78 + MEMORY32FIXED (ReadWrite, 0, MMCHS2_LENGTH, RMEM) 79 + Interrupt (ResourceConsumer, Level, ActiveHigh, Shared) { BCM2836_MMCHS1_INTERRUPT } 80 + }) 81 + Method (_CRS, 0x0, Serialized) 82 + { 83 + MEMORY32SETBASE (RBUF, RMEM, RBAS, MMCHS2_OFFSET) 84 + Return (^RBUF) 85 + } 86 + 87 + // Unfortunately this controller doesn't honor the 88 + // standard SDHCI voltage control registers 89 + // (or at least Linux's standard code can't 90 + // lower the voltage) So, UHS mode is disabled with caps 91 + Name (DSD1, Package () { 92 + ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), 93 + Package () { 94 + Package () { "sdhci-caps-mask", 0x0000000500080000 }, 95 + } 96 + }) 97 + // Along with disabling UHS, here both SDMA and ADMA2 98 + // are also disabled until the linux _DMA() mask/translate 99 + // works properly. 100 + Name (DSD2, Package () { 101 + ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), 102 + Package () { 103 + Package () { "sdhci-caps-mask", 0x0000000504480000 }, 104 + } 105 + }) 106 + Method (_DSD, 0x0, Serialized) 107 + { 108 + // Select one of the sdhci-caps-mask definitions 109 + // depending on whether we also want to disable DMA 110 + if (SDMA == 0) 111 + { 112 + return (^DSD2) 113 + } 114 + else 115 + { 116 + return (^DSD1) 117 + } 118 + } 119 + 120 + // 121 + // A child device that represents the 122 + // sd card, which is marked as non-removable. 123 + // 124 + Device (SDMM) 125 + { 126 + Method (_ADR) 127 + { 128 + Return (0) 129 + } 130 + Method (_RMV) // Is removable 131 + { 132 + Return (0) // 0 - fixed 133 + } 134 + } 135 + } //SDC3 136 + } //GDV1
+372
board/raspberrypi/rpi/gpudevs.asl
··· 1 + /** @file 2 + * 3 + * [DSDT] Devices behind the GPU. 4 + * 5 + * Copyright (c) 2018-2020, Andrey Warkentin <andrey.warkentin@gmail.com> 6 + * Copyright (c) Microsoft Corporation. All rights reserved. 7 + * 8 + * SPDX-License-Identifier: BSD-2-Clause-Patent 9 + * 10 + **/ 11 + 12 + // DWC OTG Controller 13 + Device (USB0) 14 + { 15 + Name (_HID, "BCM2848") 16 + #if defined(CONFIG_TARGET_RPI_3) 17 + Name (_CID, "DWC_OTG") 18 + #elif defined(CONFIG_TARGET_RPI_4) 19 + Name (_CID, "BCM2848") 20 + #endif 21 + Name (_UID, 0x0) 22 + Name (_CCA, 0x0) 23 + Method (_STA) 24 + { 25 + Return (0xf) 26 + } 27 + Name (RBUF, ResourceTemplate () 28 + { 29 + MEMORY32FIXED (ReadWrite, 0, BCM2836_USB_LENGTH, RMEM) 30 + Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_USB_INTERRUPT } 31 + }) 32 + Method (_CRS, 0x0, Serialized) 33 + { 34 + MEMORY32SETBASE (RBUF, RMEM, RBAS, BCM2836_USB_OFFSET) 35 + Return (^RBUF) 36 + } 37 + } 38 + 39 + // Video Core 4 GPU 40 + Device (GPU0) 41 + { 42 + Name (_HID, "BCM2850") 43 + Name (_CID, "BCM2850") 44 + Name (_UID, 0x0) 45 + Name (_CCA, 0x0) 46 + Method (_STA) 47 + { 48 + Return (0xf) 49 + } 50 + Name (RBUF, ResourceTemplate () 51 + { 52 + // Memory and interrupt for the GPU 53 + MEMORY32FIXED (ReadWrite, 0, BCM2836_V3D_BUS_LENGTH, RM01) 54 + Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_V3D_BUS_INTERRUPT } 55 + 56 + // HVS - Hardware Video Scalar 57 + MEMORY32FIXED (ReadWrite, 0, BCM2836_HVS_LENGTH, RM02) 58 + // The HVS interrupt is reserved by the VPU 59 + // Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_HVS_INTERRUPT } 60 + 61 + // PixelValve0 - DSI0 or DPI 62 + // MEMORY32FIXED (ReadWrite, BCM2836_PV0_BASE_ADDRESS, BCM2836_PV0_LENGTH, RM03) 63 + // Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_PV0_INTERRUPT } 64 + 65 + // PixelValve1 - DS1 or SMI 66 + // MEMORY32FIXED (ReadWrite, BCM2836_PV1_BASE_ADDRESS, BCM2836_PV1_LENGTH, RM04) 67 + // Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_PV1_INTERRUPT } 68 + 69 + // PixelValve2 - HDMI output - connected to HVS display FIFO 1 70 + MEMORY32FIXED (ReadWrite, 0, BCM2836_PV2_LENGTH, RM05) 71 + Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_PV2_INTERRUPT } 72 + 73 + // HDMI registers 74 + MEMORY32FIXED (ReadWrite, 0, BCM2836_HDMI0_LENGTH, RM06) 75 + MEMORY32FIXED (ReadWrite, 0, BCM2836_HDMI1_LENGTH, RM07) 76 + // hdmi_int[0] 77 + // Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_HDMI0_INTERRUPT } 78 + // hdmi_int[1] 79 + // Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_HDMI1_INTERRUPT } 80 + 81 + // HDMI DDC connection 82 + I2CSerialBus (0x50,, 100000,, "\\_SB.GDV0.I2C2",,,,) // EDID 83 + I2CSerialBus (0x30,, 100000,, "\\_SB.GDV0.I2C2",,,,) // E-DDC Segment Pointer 84 + }) 85 + Method (_CRS, 0x0, Serialized) 86 + { 87 + MEMORY32SETBASE (RBUF, RM01, RB01, BCM2836_V3D_BUS_OFFSET) 88 + MEMORY32SETBASE (RBUF, RM02, RB02, BCM2836_HVS_OFFSET) 89 + MEMORY32SETBASE (RBUF, RM05, RB05, BCM2836_PV2_OFFSET) 90 + MEMORY32SETBASE (RBUF, RM06, RB06, BCM2836_HDMI0_OFFSET) 91 + MEMORY32SETBASE (RBUF, RM07, RB07, BCM2836_HDMI1_OFFSET) 92 + Return (^RBUF) 93 + } 94 + 95 + // GPU Power Management Component Data 96 + // Reference : https://github.com/Microsoft/graphics-driver-samples/wiki/Install-Driver-in-a-Windows-VM 97 + Method (PMCD, 0, Serialized) 98 + { 99 + Name (RBUF, Package () 100 + { 101 + 1, // Version 102 + 1, // Number of graphics power components 103 + Package () // Power components package 104 + { 105 + Package () // GPU component package 106 + { 107 + 0, // Component Index 108 + 0, // DXGK_POWER_COMPONENT_MAPPING.ComponentType (0 = DXGK_POWER_COMPONENT_ENGINE) 109 + 0, // DXGK_POWER_COMPONENT_MAPPING.NodeIndex 110 + 111 + Buffer () // DXGK_POWER_RUNTIME_COMPONENT.ComponentGuid 112 + { // 9B2D1E26-1575-4747-8FC0-B9EB4BAA2D2B 113 + 0x26, 0x1E, 0x2D, 0x9B, 0x75, 0x15, 0x47, 0x47, 114 + 0x8f, 0xc0, 0xb9, 0xeb, 0x4b, 0xaa, 0x2d, 0x2b 115 + }, 116 + 117 + "VC4_Engine_00",// DXGK_POWER_RUNTIME_COMPONENT.ComponentName 118 + 2, // DXGK_POWER_RUNTIME_COMPONENT.StateCount 119 + 120 + Package () // DXGK_POWER_RUNTIME_COMPONENT.States[] package 121 + { 122 + Package () // F0 123 + { 124 + 0, // DXGK_POWER_RUNTIME_STATE.TransitionLatency 125 + 0, // DXGK_POWER_RUNTIME_STATE.ResidencyRequirement 126 + 1210000, // DXGK_POWER_RUNTIME_STATE.NominalPower (microwatt) 127 + }, 128 + 129 + Package () // F1 - Placeholder 130 + { 131 + 10000, // DXGK_POWER_RUNTIME_STATE.TransitionLatency 132 + 10000, // DXGK_POWER_RUNTIME_STATE.ResidencyRequirement 133 + 4, // DXGK_POWER_RUNTIME_STATE.NominalPower 134 + }, 135 + } 136 + } 137 + } 138 + }) 139 + Return (RBUF) 140 + } 141 + } 142 + 143 + // PiQ Mailbox Driver 144 + Device (RPIQ) 145 + { 146 + Name (_HID, "BCM2849") 147 + Name (_CID, "BCM2849") 148 + Name (_UID, 0) 149 + Name (_CCA, 0x0) 150 + 151 + Name (RBUF, ResourceTemplate () 152 + { 153 + MEMORY32FIXED (ReadWrite, 0, BCM2836_MBOX_LENGTH, RMEM) 154 + Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_MBOX_INTERRUPT } 155 + }) 156 + 157 + Method (_CRS, 0x0, Serialized) 158 + { 159 + MEMORY32SETBASE (RBUF, RMEM, RBAS, BCM2836_MBOX_OFFSET) 160 + Return (^RBUF) 161 + } 162 + } 163 + 164 + // VCHIQ Driver 165 + Device (VCIQ) 166 + { 167 + Name (_HID, "BCM2835") 168 + Name (_CID, "BCM2835") 169 + Name (_UID, 0) 170 + Name (_CCA, 0x0) 171 + Name (_DEP, Package() { \_SB.GDV0.RPIQ }) 172 + Method (_STA) 173 + { 174 + Return (0xf) 175 + } 176 + Name (RBUF, ResourceTemplate () 177 + { 178 + MEMORY32FIXED (ReadWrite, 0, BCM2836_VCHIQ_LENGTH, RMEM) 179 + Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_VCHIQ_INTERRUPT } 180 + }) 181 + 182 + Method (_CRS, 0x0, Serialized) 183 + { 184 + MEMORY32SETBASE (RBUF, RMEM, RBAS, BCM2836_VCHIQ_OFFSET) 185 + Return (^RBUF) 186 + } 187 + } 188 + 189 + // VC Shared Memory Driver 190 + Device (VCSM) 191 + { 192 + Name (_HID, "BCM2856") 193 + Name (_CID, "BCM2856") 194 + Name (_UID, 0) 195 + Name (_CCA, 0x0) 196 + Name (_DEP, Package() { \_SB.GDV0.VCIQ }) 197 + Method (_STA) 198 + { 199 + Return (0xf) 200 + } 201 + } 202 + 203 + // Description: GPIO 204 + Device (GPI0) 205 + { 206 + Name (_HID, "BCM2845") 207 + Name (_CID, "BCM2845") 208 + Name (_UID, 0x0) 209 + Name (_CCA, 0x0) 210 + 211 + Name (RBUF, ResourceTemplate () 212 + { 213 + MEMORY32FIXED (ReadWrite, 0, GPIO_LENGTH, RMEM) 214 + Interrupt (ResourceConsumer, Level, ActiveHigh, Shared) 215 + { 216 + BCM2386_GPIO_INTERRUPT0, BCM2386_GPIO_INTERRUPT1, 217 + BCM2386_GPIO_INTERRUPT2, BCM2386_GPIO_INTERRUPT3 218 + } 219 + }) 220 + Method (_CRS, 0x0, Serialized) 221 + { 222 + MEMORY32SETBASE (RBUF, RMEM, RBAS, GPIO_OFFSET) 223 + Return (^RBUF) 224 + } 225 + } 226 + 227 + // Description: I2C 228 + Device (I2C1) 229 + { 230 + Name (_HID, "BCM2841") 231 + Name (_CID, "BCM2841") 232 + Name (_UID, 0x1) 233 + Name (_CCA, 0x0) 234 + 235 + Name (RBUF, ResourceTemplate () 236 + { 237 + MEMORY32FIXED (ReadWrite, 0, BCM2836_I2C1_LENGTH, RMEM) 238 + Interrupt (ResourceConsumer, Level, ActiveHigh, Shared) { BCM2836_I2C1_INTERRUPT } 239 + PinFunction (Exclusive, PullUp, BCM_ALT0, "\\_SB.GDV0.GPI0", 0, ResourceConsumer, , ) { 2, 3 } 240 + }) 241 + Method (_CRS, 0x0, Serialized) 242 + { 243 + MEMORY32SETBASE (RBUF, RMEM, RBAS, BCM2836_I2C1_OFFSET) 244 + Return (^RBUF) 245 + } 246 + } 247 + 248 + // I2C2 is the HDMI DDC connection 249 + Device (I2C2) 250 + { 251 + Name (_HID, "BCM2841") 252 + Name (_CID, "BCM2841") 253 + Name (_UID, 0x2) 254 + Name (_CCA, 0x0) 255 + 256 + Name (RBUF, ResourceTemplate() 257 + { 258 + MEMORY32FIXED (ReadWrite, 0, BCM2836_I2C2_LENGTH, RMEM) 259 + Interrupt (ResourceConsumer, Level, ActiveHigh, Shared) { BCM2836_I2C2_INTERRUPT } 260 + }) 261 + 262 + Method (_CRS, 0x0, Serialized) 263 + { 264 + MEMORY32SETBASE (RBUF, RMEM, RBAS, BCM2836_I2C2_OFFSET) 265 + Return (^RBUF) 266 + } 267 + } 268 + 269 + // SPI 270 + Device (SPI0) 271 + { 272 + Name (_HID, "BCM2838") 273 + Name (_CID, "BCM2838") 274 + Name (_UID, 0x0) 275 + Name (_CCA, 0x0) 276 + 277 + Name (RBUF, ResourceTemplate () 278 + { 279 + MEMORY32FIXED (ReadWrite, 0, BCM2836_SPI0_LENGTH, RMEM) 280 + Interrupt (ResourceConsumer, Level, ActiveHigh, Shared) { BCM2836_SPI0_INTERRUPT } 281 + PinFunction (Exclusive, PullDown, BCM_ALT0, "\\_SB.GDV0.GPI0", 0, ResourceConsumer, , ) { 9, 10, 11 } // MISO, MOSI, SCLK 282 + PinFunction (Exclusive, PullUp, BCM_ALT0, "\\_SB.GDV0.GPI0", 0, ResourceConsumer, , ) { 8 } // CE0 283 + PinFunction (Exclusive, PullUp, BCM_ALT0, "\\_SB.GDV0.GPI0", 0, ResourceConsumer, , ) { 7 } // CE1 284 + }) 285 + 286 + Method (_CRS, 0x0, Serialized) 287 + { 288 + MEMORY32SETBASE (RBUF, RMEM, RBAS, BCM2836_SPI0_OFFSET) 289 + Return (^RBUF) 290 + } 291 + } 292 + 293 + Device (SPI1) 294 + { 295 + Name (_HID, "BCM2839") 296 + Name (_CID, "BCM2839") 297 + Name (_UID, 0x1) 298 + Name (_CCA, 0x0) 299 + Name (_DEP, Package() { \_SB.GDV0.RPIQ }) 300 + 301 + Name (RBUF, ResourceTemplate () 302 + { 303 + MEMORY32FIXED (ReadWrite, 0, BCM2836_SPI1_LENGTH, RMEM) 304 + Interrupt (ResourceConsumer, Level, ActiveHigh, Shared,) { BCM2836_SPI1_INTERRUPT } 305 + PinFunction (Exclusive, PullDown, BCM_ALT4, "\\_SB.GDV0.GPI0", 0, ResourceConsumer, , ) { 19, 20, 21 } // MISO, MOSI, SCLK 306 + PinFunction (Exclusive, PullDown, BCM_ALT4, "\\_SB.GDV0.GPI0", 0, ResourceConsumer, , ) { 16 } // CE2 307 + }) 308 + 309 + Method (_CRS, 0x0, Serialized) 310 + { 311 + MEMORY32SETBASE (RBUF, RMEM, RBAS, BCM2836_SPI1_OFFSET) 312 + Return (^RBUF) 313 + } 314 + } 315 + 316 + // SPI2 has no pins on GPIO header 317 + // Device (SPI2) 318 + // { 319 + // Name (_HID, "BCM2839") 320 + // Name (_CID, "BCM2839") 321 + // Name (_UID, 0x2) 322 + // Name (_CCA, 0x0) 323 + // Name (_DEP, Package() { \_SB.GDV0.RPIQ }) 324 + // Method (_STA) 325 + // { 326 + // Return (0xf) // Disabled 327 + // } 328 + // Method (_CRS, 0x0, Serialized) 329 + // { 330 + // Name (RBUF, ResourceTemplate () 331 + // { 332 + // MEMORY32FIXED (ReadWrite, BCM2836_SPI2_BASE_ADDRESS, BCM2836_SPI2_LENGTH, RMEM) 333 + // Interrupt (ResourceConsumer, Level, ActiveHigh, Shared,) { BCM2836_SPI2_INTERRUPT } 334 + // }) 335 + // Return (RBUF) 336 + // } 337 + // } 338 + 339 + // PWM Driver 340 + Device (PWM0) 341 + { 342 + Name (_HID, "BCM2844") 343 + Name (_CID, "BCM2844") 344 + Name (_UID, 0) 345 + Name (_CCA, 0x0) 346 + 347 + Name (RBUF, ResourceTemplate () 348 + { 349 + // DMA channel 11 control 350 + MEMORY32FIXED (ReadWrite, 0, BCM2836_PWM_DMA_LENGTH, RM01) 351 + // PWM control 352 + MEMORY32FIXED (ReadWrite, 0, BCM2836_PWM_CTRL_LENGTH, RM02) 353 + // PWM control bus 354 + MEMORY32FIXED (ReadWrite, BCM2836_PWM_BUS_BASE_ADDRESS, BCM2836_PWM_BUS_LENGTH, ) 355 + // PWM control uncached 356 + MEMORY32FIXED (ReadWrite, BCM2836_PWM_CTRL_UNCACHED_BASE_ADDRESS, BCM2836_PWM_CTRL_UNCACHED_LENGTH, ) 357 + // PWM clock control 358 + MEMORY32FIXED (ReadWrite, 0, BCM2836_PWM_CLK_LENGTH, RM03) 359 + // Interrupt DMA channel 11 360 + Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_DMA_INTERRUPT } 361 + // DMA channel 11, DREQ 5 for PWM 362 + FixedDMA (5, 11, Width32Bit, ) 363 + }) 364 + 365 + Method (_CRS, 0x0, Serialized) 366 + { 367 + MEMORY32SETBASE (RBUF, RM01, RB01, BCM2836_PWM_DMA_OFFSET) 368 + MEMORY32SETBASE (RBUF, RM02, RB02, BCM2836_PWM_CTRL_OFFSET) 369 + MEMORY32SETBASE (RBUF, RM03, RB03, BCM2836_PWM_CLK_OFFSET) 370 + Return (^RBUF) 371 + } 372 + }
+177
board/raspberrypi/rpi/pci.asl
··· 1 + /** @file 2 + * 3 + * Copyright (c) 2019 Linaro, Limited. All rights reserved. 4 + * Copyright (c) 2021 Arm 5 + * 6 + * SPDX-License-Identifier: BSD-2-Clause-Patent 7 + * 8 + **/ 9 + 10 + Device(PCI0) 11 + { 12 + Name(_HID, EISAID("PNP0A08")) // PCI Express Root Bridge 13 + Name(_CID, EISAID("PNP0A03")) // Compatible PCI Root Bridge 14 + Name(_SEG, Zero) // PCI Segment Group number 15 + Name(_BBN, Zero) // PCI Base Bus Number 16 + Name(_CCA, 0) // Mark the PCI noncoherent 17 + 18 + // PCIe can only DMA to first 3GB with early SOC's 19 + // But we keep the restriction on the later ones 20 + // To avoid DMA translation problems. 21 + Name (_DMA, ResourceTemplate() { 22 + QWordMemory (ResourceProducer, 23 + , 24 + MinFixed, 25 + MaxFixed, 26 + NonCacheable, 27 + ReadWrite, 28 + 0x0, 29 + 0x0, // MIN 30 + 0xbfffffff, // MAX 31 + 0x0, // TRA 32 + 0xc0000000, // LEN 33 + , 34 + , 35 + ) 36 + }) 37 + 38 + // PCI Routing Table 39 + Name(_PRT, Package() { 40 + Package (4) { 0x0000FFFF, 0, zero, 175 }, 41 + Package (4) { 0x0000FFFF, 1, zero, 176 }, 42 + Package (4) { 0x0000FFFF, 2, zero, 177 }, 43 + Package (4) { 0x0000FFFF, 3, zero, 178 } 44 + }) 45 + 46 + Name (_DSD, Package () { 47 + ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), 48 + Package () { 49 + Package () { "linux-ecam-quirk-id", "bcm2711" }, 50 + } 51 + }) 52 + 53 + // Root complex resources 54 + Method (_CRS, 0, Serialized) { 55 + Name (RBUF, ResourceTemplate () { 56 + 57 + // bus numbers assigned to this root 58 + WordBusNumber ( 59 + ResourceProducer, 60 + MinFixed, MaxFixed, PosDecode, 61 + 0, // AddressGranularity 62 + 0, // AddressMinimum - Minimum Bus Number 63 + 255, // AddressMaximum - Maximum Bus Number 64 + 0, // AddressTranslation - Set to 0 65 + 256 // RangeLength - Number of Busses 66 + ) 67 + 68 + // 32-bit mmio window in 64-bit addr 69 + QWordMemory ( 70 + ResourceProducer, PosDecode, 71 + MinFixed, MaxFixed, 72 + NonCacheable, ReadWrite, // cacheable 73 + 0x00000000, // Granularity 74 + 0, // PCIE_PCI_MMIO_BEGIN 75 + 1, // PCIE_MMIO_LEN + PCIE_PCI_MMIO_BEGIN 76 + PCIE_CPU_MMIO_WINDOW, // PCIE_PCI_MMIO_BEGIN - PCIE_CPU_MMIO_WINDOW 77 + 2 // PCIE_MMIO_LEN + 1 78 + ,,,MMI1 79 + ) 80 + 81 + // root port registers, not to be used if SMCCC is utilized 82 + QWordMemory ( 83 + ResourceConsumer, , 84 + MinFixed, MaxFixed, 85 + NonCacheable, ReadWrite, // cacheable 86 + 0x00000000, // Granularity 87 + 0xFD500000, // Root port begin 88 + 0xFD509FFF, // Root port end 89 + 0x00000000, // no translation 90 + 0x0000A000, // size 91 + ,, 92 + ) 93 + }) // end Name(RBUF) 94 + 95 + // Work around ASL's inability to add in a resource definition 96 + // or for that matter compute the min,max,len properly 97 + CreateQwordField (RBUF, MMI1._MIN, MMIB) 98 + CreateQwordField (RBUF, MMI1._MAX, MMIE) 99 + CreateQwordField (RBUF, MMI1._TRA, MMIT) 100 + CreateQwordField (RBUF, MMI1._LEN, MMIL) 101 + Add (MMIB, PCIE_TOP_OF_MEM_WIN, MMIB) 102 + Add (PCIE_BRIDGE_MMIO_LEN, PCIE_TOP_OF_MEM_WIN, MMIE) 103 + Subtract (MMIT, PCIE_TOP_OF_MEM_WIN, MMIT) 104 + Add (PCIE_BRIDGE_MMIO_LEN, 1 , MMIL) 105 + 106 + Return (RBUF) 107 + } // end Method(_CRS) 108 + 109 + // OS Control Handoff 110 + Name(SUPP, Zero) // PCI _OSC Support Field value 111 + Name(CTRL, Zero) // PCI _OSC Control Field value 112 + 113 + // See [1] 6.2.10, [2] 4.5 114 + Method(_OSC,4) { 115 + // Note, This code is very similar to the code in the PCIe firmware 116 + // specification which can be used as a reference 117 + // Check for proper UUID 118 + If(LEqual(Arg0,ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) { 119 + // Create DWord-adressable fields from the Capabilities Buffer 120 + CreateDWordField(Arg3,0,CDW1) 121 + CreateDWordField(Arg3,4,CDW2) 122 + CreateDWordField(Arg3,8,CDW3) 123 + // Save Capabilities DWord2 & 3 124 + Store(CDW2,SUPP) 125 + Store(CDW3,CTRL) 126 + // Mask out Native HotPlug 127 + And(CTRL,0x1E,CTRL) 128 + // Always allow native PME, AER (no dependencies) 129 + // Never allow SHPC (no SHPC controller in this system) 130 + And(CTRL,0x1D,CTRL) 131 + 132 + If(LNotEqual(Arg1,One)) { // Unknown revision 133 + Or(CDW1,0x08,CDW1) 134 + } 135 + 136 + If(LNotEqual(CDW3,CTRL)) { // Capabilities bits were masked 137 + Or(CDW1,0x10,CDW1) 138 + } 139 + // Update DWORD3 in the buffer 140 + Store(CTRL,CDW3) 141 + Return(Arg3) 142 + } Else { 143 + Or(CDW1,4,CDW1) // Unrecognized UUID 144 + Return(Arg3) 145 + } 146 + } // End _OSC 147 + 148 + Device (XHC0) 149 + { 150 + Name (_ADR, 0x00010000) 151 + Name (_CID, "PNP0D10") 152 + Name (_UID, 0x0) // _UID: Unique ID 153 + Name (_CCA, 0x0) // _CCA: Cache Coherency Attribute 154 + 155 + /* 156 + * Microsoft's USB Device-Specific Methods. See: 157 + * https://docs.microsoft.com/en-us/windows-hardware/drivers/bringup/usb-device-specific-method---dsm- 158 + */ 159 + Name (DSMU, ToUUID ("ce2ee385-00e6-48cb-9f05-2edb927c4899")) 160 + 161 + Method (_DSM, 4, Serialized) { 162 + If (LEqual (Arg0, DSMU)) { // USB capabilities UUID 163 + Switch (ToInteger (Arg2)) { 164 + Case (0) { // Function 0: List of supported functions 165 + Return (Buffer () { 0x41 }) // 0x41 - Functions 0 and 6 supported 166 + } 167 + Case (6) { // Function 6: RegisterAccessType 168 + Return (Buffer () { 0x01 }) // 0x01 - Must use 32bit register access 169 + } 170 + Default { } // Unsupported 171 + } 172 + } 173 + return (Buffer () { 0x00 }) // Return 0x00 for anything unsupported 174 + } 175 + } // end XHC0 176 + 177 + } // PCI0
+90
board/raspberrypi/rpi/pep.asl
··· 1 + /** @file 2 + * 3 + * Platform Extension Plugin (PEP). 4 + * 5 + * Copyright (c) 2019, ARM Ltd. All rights reserved. 6 + * Copyright (c) 2018, Andrey Warkentin <andrey.warkentin@gmail.com> 7 + * Copyright (c) Microsoft Corporation. All rights reserved. 8 + * 9 + * SPDX-License-Identifier: BSD-2-Clause-Patent 10 + * 11 + **/ 12 + 13 + Device(PEPD) 14 + { 15 + // 16 + // PEP virtual device. 17 + // 18 + Name (_HID, "BCM2854") // Note: Since PEP on RPi is a virtual device, 19 + Name (_CID, "BCM2854") // its device id needs to be generated by Microsoft 20 + Name (_UID, 0x0) 21 + Name (_CRS, ResourceTemplate () 22 + { 23 + // No hardware resources for PEP driver are needed. 24 + }) 25 + 26 + // 27 + // Processor info. PEP proprietary method to return 28 + // PEP_PROCESSOR_TABLE_PLAT structure. 29 + // 30 + // See Pep.h and Pep.c. 31 + // 32 + Name (_GPI, Buffer() 33 + { 34 + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x5F, 0x00, 0x53, 35 + 0x00, 0x42, 0x00, 0x2E, 0x00, 0x43, 0x00, 0x50, 0x00, 0x55, 0x00, 0x30, 36 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 37 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 38 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 39 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 40 + }) 41 + 42 + // 43 + // Coordinated state info. PEP proprietary method to return 44 + // PEP_COORDINATED_STATE_TABLE_PLAT structure. 45 + // 46 + // See Pep.h and Pep.c. 47 + // 48 + Name (_GCI, Buffer() 49 + { 50 + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 51 + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 52 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 53 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 54 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 55 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 56 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 57 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 58 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 59 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 60 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 61 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 62 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 63 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 64 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 65 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 66 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 67 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 68 + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 69 + }) 70 + 71 + // 72 + // Device info. PEP proprietary method to return 73 + // PEP_DEVICE_TABLE_PLAT structure. 74 + // 75 + // See Pep.h and Pep.c. 76 + // 77 + Name (_GDI, Buffer() 78 + { 79 + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x5F, 0x00, 0x53, 80 + 0x00, 0x42, 0x00, 0x2E, 0x00, 0x49, 0x00, 0x32, 0x00, 0x43, 0x00, 0x30, 81 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 82 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 83 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 84 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 85 + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 86 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 87 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 88 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 89 + }) 90 + }
+195
board/raspberrypi/rpi/rhpx.asl
··· 1 + /** @file 2 + * 3 + * [DSDT] RHProxy device to enable WinRT API (RHPX) 4 + * 5 + * Copyright (c) 2018, Andrey Warkentin <andrey.warkentin@gmail.com> 6 + * Copyright (c) Microsoft Corporation. All rights reserved. 7 + * 8 + * SPDX-License-Identifier: BSD-2-Clause-Patent 9 + * 10 + **/ 11 + 12 + Device (RHPX) 13 + { 14 + Name (_HID, "MSFT8000") 15 + Name (_CID, "MSFT8000") 16 + Name (_UID, 1) 17 + 18 + Name(_CRS, ResourceTemplate () 19 + { 20 + // Index 0 21 + SPISerialBus ( // SCKL - GPIO 11 - Pin 23 22 + // MOSI - GPIO 10 - Pin 19 23 + // MISO - GPIO 9 - Pin 21 24 + // CE0 - GPIO 8 - Pin 24 25 + 0, // Device selection (CE0) 26 + PolarityLow, // Device selection polarity 27 + FourWireMode, // WireMode 28 + 8, // DataBit len 29 + ControllerInitiated, // Slave mode 30 + 4000000, // Connection speed 31 + ClockPolarityLow, // Clock polarity 32 + ClockPhaseFirst, // Clock phase 33 + "\\_SB.GDV0.SPI0", // ResourceSource: SPI bus controller name 34 + 0, // ResourceSourceIndex 35 + // Resource usage 36 + // DescriptorName: creates name for offset of resource descriptor 37 + ) // Vendor Data 38 + 39 + // Index 1 40 + SPISerialBus ( // SCKL - GPIO 11 - Pin 23 41 + // MOSI - GPIO 10 - Pin 19 42 + // MISO - GPIO 9 - Pin 21 43 + // CE1 - GPIO 7 - Pin 26 44 + 1, // Device selection (CE1) 45 + PolarityLow, // Device selection polarity 46 + FourWireMode, // WireMode 47 + 8, // DataBit len 48 + ControllerInitiated, // Slave mode 49 + 4000000, // Connection speed 50 + ClockPolarityLow, // Clock polarity 51 + ClockPhaseFirst, // Clock phase 52 + "\\_SB.GDV0.SPI0", // ResourceSource: SPI bus controller name 53 + 0, // ResourceSourceIndex 54 + // Resource usage 55 + // DescriptorName: creates name for offset of resource descriptor 56 + ) // Vendor Data 57 + 58 + // Index 2 59 + I2CSerialBus ( // Pin 3 (GPIO2, SDA1), 5 (GPIO3, SCL1) 60 + 0xFFFF, // SlaveAddress: placeholder 61 + , // SlaveMode: default to ControllerInitiated 62 + 0, // ConnectionSpeed: placeholder 63 + , // Addressing Mode: default to 7 bit 64 + "\\_SB.GDV0.I2C1", // ResourceSource: I2C bus controller name 65 + , 66 + , 67 + , // Descriptor Name: creates name for offset of resource descriptor 68 + ) // Vendor Data 69 + 70 + // Index 3 71 + SPISerialBus ( // SPI1_SCLK - GPIO21 72 + // SPI1_MOSI - GPIO20 73 + // SPI1_MISO - GPIO19 74 + // SPI1_CE2_N - GPIO16 75 + 2, // Device selection (CE2) 76 + PolarityLow, // Device selection polarity 77 + FourWireMode, // WireMode 78 + 8, // DataBit len 79 + ControllerInitiated, // Slave mode 80 + 4000000, // Connection speed 81 + ClockPolarityLow, // Clock polarity 82 + ClockPhaseFirst, // Clock phase 83 + "\\_SB.GDV0.SPI1", // ResourceSource: SPI bus controller name 84 + 0, // ResourceSourceIndex 85 + // Resource usage 86 + // DescriptorName: creates name for offset of resource descriptor 87 + ) // Vendor Data 88 + 89 + // GPIO 2 90 + GpioIO (Shared, PullUp, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 2 } 91 + GpioInt (Edge, ActiveBoth, Shared, PullUp, 0, "\\_SB.GDV0.GPI0",) { 2 } 92 + // GPIO 3 93 + GpioIO (Shared, PullUp, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 3 } 94 + GpioInt (Edge, ActiveBoth, Shared, PullUp, 0, "\\_SB.GDV0.GPI0",) { 3 } 95 + // GPIO 4 96 + GpioIO (Shared, PullUp, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 4 } 97 + GpioInt (Edge, ActiveBoth, Shared, PullUp, 0, "\\_SB.GDV0.GPI0",) { 4 } 98 + // GPIO 5 99 + GpioIO (Shared, PullUp, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 5 } 100 + GpioInt (Edge, ActiveBoth, Shared, PullUp, 0, "\\_SB.GDV0.GPI0",) { 5 } 101 + // GPIO 6 102 + GpioIO (Shared, PullUp, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 6 } 103 + GpioInt (Edge, ActiveBoth, Shared, PullUp, 0, "\\_SB.GDV0.GPI0",) { 6 } 104 + // GPIO 7 105 + GpioIO (Shared, PullUp, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 7 } 106 + GpioInt (Edge, ActiveBoth, Shared, PullUp, 0, "\\_SB.GDV0.GPI0",) { 7 } 107 + // GPIO 8 108 + GpioIO (Shared, PullUp, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 8 } 109 + GpioInt (Edge, ActiveBoth, Shared, PullUp, 0, "\\_SB.GDV0.GPI0",) { 8 } 110 + // GPIO 9 111 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 9 } 112 + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 9 } 113 + // GPIO 10 114 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 10 } 115 + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 10 } 116 + // GPIO 11 117 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 11 } 118 + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 11 } 119 + // GPIO 12 120 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 12 } 121 + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 12 } 122 + // GPIO 13 123 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 13 } 124 + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 13 } 125 + // NTRAID#MSFT-7141401-2016/04/7-jordanrh - disable UART muxing 126 + // until a proper solution can be created for the dmap conflict 127 + // GPIO 14 - UART TX 128 + // GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 14 } 129 + // GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 14 } 130 + // GPIO 15 - UART RX 131 + // GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 15 } 132 + // GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 15 } 133 + // GPIO 16 134 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 16 } 135 + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 16 } 136 + // GPIO 17 137 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 17 } 138 + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 17 } 139 + // GPIO 18 140 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 18 } 141 + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 18 } 142 + // GPIO 19 143 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 19 } 144 + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 19 } 145 + // GPIO 20 146 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 20 } 147 + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 20 } 148 + // GPIO 21 149 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 21 } 150 + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 21 } 151 + // GPIO 22 152 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 22 } 153 + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 22 } 154 + // GPIO 23 155 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 23 } 156 + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 23 } 157 + // GPIO 24 158 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 24 } 159 + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 24 } 160 + // GPIO 25 161 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 25 } 162 + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 25 } 163 + // GPIO 26 164 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 26 } 165 + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 26 } 166 + // GPIO 27 167 + GpioIO (Shared, PullDown, 0, 0, IoRestrictionNone, "\\_SB.GDV0.GPI0", 0, ResourceConsumer,,) { 27 } 168 + GpioInt (Edge, ActiveBoth, Shared, PullDown, 0, "\\_SB.GDV0.GPI0",) { 27 } 169 + }) 170 + 171 + Name (_DSD, Package() 172 + { 173 + ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), 174 + Package () 175 + { 176 + // Reference http://www.raspberrypi.org/documentation/hardware/raspberrypi/spi/README.md 177 + // SPI 0 178 + Package (2) { "bus-SPI-SPI0", Package() { 0, 1 } }, // Index 0 & 1 179 + Package (2) { "SPI0-MinClockInHz", 7629 }, // 7629 Hz 180 + Package (2) { "SPI0-MaxClockInHz", 125000000 }, // 125 MHz 181 + Package (2) { "SPI0-SupportedDataBitLengths", Package() { 8 } }, // Data Bit Length 182 + // I2C1 183 + Package (2) { "bus-I2C-I2C1", Package() { 2 } }, 184 + // GPIO Pin Count and supported drive modes 185 + Package (2) { "GPIO-PinCount", 54 }, 186 + Package (2) { "GPIO-UseDescriptorPinNumbers", 1 }, 187 + Package (2) { "GPIO-SupportedDriveModes", 0xf }, // InputHighImpedance, InputPullUp, InputPullDown, OutputCmos 188 + // SPI 1 189 + Package (2) { "bus-SPI-SPI1", Package() { 3 }}, // Index 3 190 + Package (2) { "SPI1-MinClockInHz", 30511 }, // 30.5 kHz 191 + Package (2) { "SPI1-MaxClockInHz", 20000000 }, // 20 MHz 192 + Package (2) { "SPI1-SupportedDataBitLengths", Package() { 8 } }, // Data Bit Length 193 + } 194 + }) 195 + }
+183
board/raspberrypi/rpi/rpi.c
··· 23 23 #endif 24 24 #include <watchdog.h> 25 25 #include <dm/pinctrl.h> 26 + #include <dm/ofnode.h> 27 + #include <acpi/acpi_table.h> 28 + #include <acpi/acpigen.h> 29 + #include <dm/lists.h> 30 + #include <tables_csum.h> 26 31 27 32 DECLARE_GLOBAL_DATA_PTR; 28 33 ··· 583 588 584 589 return 0; 585 590 } 591 + 592 + #if CONFIG_IS_ENABLED(GENERATE_ACPI_TABLE) 593 + static bool is_rpi4(void) 594 + { 595 + return of_machine_is_compatible("brcm,bcm2711") || 596 + of_machine_is_compatible("brcm,bcm2712"); 597 + } 598 + 599 + static bool is_rpi3(void) 600 + { 601 + return of_machine_is_compatible("brcm,bcm2837"); 602 + } 603 + 604 + static int acpi_rpi_board_fill_ssdt(struct acpi_ctx *ctx) 605 + { 606 + int node, ret, uart_in_use, mini_clock_rate; 607 + bool enabled; 608 + struct udevice *dev; 609 + struct { 610 + const char *fdt_compatible; 611 + const char *acpi_scope; 612 + bool on_rpi4; 613 + bool on_rpi3; 614 + u32 mmio_address; 615 + } map[] = { 616 + {"brcm,bcm2711-pcie", "\\_SB.PCI0", true, false}, 617 + {"brcm,bcm2711-emmc2", "\\_SB.GDV1.SDC3", true, false}, 618 + {"brcm,bcm2835-pwm", "\\_SB.GDV0.PWM0", true, true}, 619 + {"brcm,bcm2711-genet-v5", "\\_SB.ETH0", true, false}, 620 + {"brcm,bcm2711-thermal", "\\_SB.EC00", true, true}, 621 + {"brcm,bcm2835-sdhci", "\\_SB.SDC1", true, true}, 622 + {"brcm,bcm2835-sdhost", "\\_SB.SDC2", false, true}, 623 + {"brcm,bcm2835-mbox", "\\_SB.GDV0.RPIQ", true, true}, 624 + {"brcm,bcm2835-i2c", "\\_SB.GDV0.I2C1", true, true, 0xfe205000}, 625 + {"brcm,bcm2835-i2c", "\\_SB.GDV0.I2C2", true, true, 0xfe804000}, 626 + {"brcm,bcm2835-spi", "\\_SB.GDV0.SPI0", true, true}, 627 + {"brcm,bcm2835-aux-spi", "\\_SB.GDV0.SPI1", true, true, 0xfe215080}, 628 + {"arm,pl011", "\\_SB.URT0", true, true}, 629 + {"brcm,bcm2835-aux-uart", "\\_SB.URTM", true, true}, 630 + { /* Sentinel */ } 631 + }; 632 + 633 + /* Device enable */ 634 + for (int i = 0; map[i].fdt_compatible; i++) { 635 + if ((is_rpi4() && !map[i].on_rpi4) || 636 + (is_rpi3() && !map[i].on_rpi3)) { 637 + enabled = false; 638 + } else { 639 + node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, 640 + map[i].fdt_compatible); 641 + while (node != -FDT_ERR_NOTFOUND && map[i].mmio_address) { 642 + struct fdt_resource r; 643 + 644 + ret = fdt_get_resource(gd->fdt_blob, node, "reg", 0, &r); 645 + if (ret) { 646 + node = -FDT_ERR_NOTFOUND; 647 + break; 648 + } 649 + 650 + if (r.start == map[i].mmio_address) 651 + break; 652 + 653 + node = fdt_node_offset_by_compatible(gd->fdt_blob, node, 654 + map[i].fdt_compatible); 655 + } 656 + 657 + enabled = (node > 0) ? fdtdec_get_is_enabled(gd->fdt_blob, node) : 0; 658 + } 659 + acpigen_write_scope(ctx, map[i].acpi_scope); 660 + acpigen_write_name_integer(ctx, "_STA", enabled ? 0xf : 0); 661 + acpigen_pop_len(ctx); 662 + } 663 + 664 + /* GPIO quirks */ 665 + node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, "brcm,bcm2835-gpio"); 666 + if (node <= 0) 667 + node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, "brcm,bcm2711-gpio"); 668 + 669 + acpigen_write_scope(ctx, "\\_SB.GDV0.GPI0"); 670 + enabled = (node > 0) ? fdtdec_get_is_enabled(gd->fdt_blob, node) : 0; 671 + acpigen_write_name_integer(ctx, "_STA", enabled ? 0xf : 0); 672 + acpigen_pop_len(ctx); 673 + 674 + if (is_rpi4()) { 675 + /* eMMC quirks */ 676 + node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, "brcm,bcm2711-emmc2"); 677 + if (node) { 678 + phys_addr_t cpu; 679 + dma_addr_t bus; 680 + u64 size; 681 + 682 + ret = fdt_get_dma_range(gd->fdt_blob, node, &cpu, &bus, &size); 683 + 684 + acpigen_write_scope(ctx, "\\_SB.GDV1"); 685 + acpigen_write_method_serialized(ctx, "_DMA", 0); 686 + acpigen_emit_byte(ctx, RETURN_OP); 687 + 688 + if (!ret && bus != cpu) /* Translated DMA range */ 689 + acpigen_emit_namestring(ctx, "\\_SB.GDV1.DMTR"); 690 + else if (!ret && bus == cpu) /* Non translated DMA */ 691 + acpigen_emit_namestring(ctx, "\\_SB.GDV1.DMNT"); 692 + else /* Silicon revisions older than C0: Translated DMA range */ 693 + acpigen_emit_namestring(ctx, "\\_SB.GDV1.DMTR"); 694 + acpigen_pop_len(ctx); 695 + } 696 + } 697 + 698 + /* Serial */ 699 + uart_in_use = ~0; 700 + mini_clock_rate = 0x1000000; 701 + 702 + ret = uclass_get_device_by_driver(UCLASS_SERIAL, 703 + DM_DRIVER_GET(bcm283x_pl011_uart), 704 + &dev); 705 + if (!ret) 706 + uart_in_use = 0; 707 + 708 + ret = uclass_get_device_by_driver(UCLASS_SERIAL, 709 + DM_DRIVER_GET(serial_bcm283x_mu), 710 + &dev); 711 + if (!ret) { 712 + if (uart_in_use == 0) 713 + log_err("Invalid config: PL011 and MiniUART are both enabled."); 714 + else 715 + uart_in_use = 1; 716 + 717 + mini_clock_rate = dev_read_u32_default(dev, "clock", 0x1000000); 718 + } 719 + if (uart_in_use > 1) 720 + log_err("No working serial: PL011 and MiniUART are both disabled."); 721 + 722 + acpigen_write_scope(ctx, "\\_SB.BTH0"); 723 + acpigen_write_name_integer(ctx, "URIU", uart_in_use); 724 + acpigen_pop_len(ctx); 725 + 726 + acpigen_write_scope(ctx, "\\_SB.URTM"); 727 + acpigen_write_name_integer(ctx, "MUCR", mini_clock_rate); 728 + acpigen_pop_len(ctx); 729 + 730 + return 0; 731 + } 732 + 733 + static int rpi_acpi_write_ssdt(struct acpi_ctx *ctx, const struct acpi_writer *entry) 734 + { 735 + struct acpi_table_header *ssdt; 736 + int ret; 737 + 738 + ssdt = ctx->current; 739 + memset(ssdt, '\0', sizeof(struct acpi_table_header)); 740 + 741 + acpi_fill_header(ssdt, "SSDT"); 742 + ssdt->revision = acpi_get_table_revision(ACPITAB_SSDT); 743 + ssdt->creator_revision = 1; 744 + ssdt->length = sizeof(struct acpi_table_header); 745 + 746 + acpi_inc(ctx, sizeof(struct acpi_table_header)); 747 + 748 + ret = acpi_rpi_board_fill_ssdt(ctx); 749 + if (ret) { 750 + ctx->current = ssdt; 751 + return log_msg_ret("fill", ret); 752 + } 753 + 754 + /* (Re)calculate length and checksum */ 755 + ssdt->length = ctx->current - (void *)ssdt; 756 + ssdt->checksum = table_compute_checksum((void *)ssdt, ssdt->length); 757 + log_debug("SSDT at %p, length %x\n", ssdt, ssdt->length); 758 + 759 + /* Drop the table if it is empty */ 760 + if (ssdt->length == sizeof(struct acpi_table_header)) 761 + return log_msg_ret("fill", -ENOENT); 762 + acpi_add_table(ctx, ssdt); 763 + 764 + return 0; 765 + } 766 + 767 + ACPI_WRITER(5ssdt, "SSDT", rpi_acpi_write_ssdt, 0); 768 + #endif
+111
board/raspberrypi/rpi/sdhc.asl
··· 1 + /** @file 2 + * 3 + * [DSDT] SD controller/card definition (SDHC) 4 + * 5 + * Copyright (c) 2020, Pete Batard <pete@akeo.ie> 6 + * Copyright (c) 2018, Andrey Warkentin <andrey.warkentin@gmail.com> 7 + * Copyright (c) Microsoft Corporation. All rights reserved. 8 + * 9 + * SPDX-License-Identifier: BSD-2-Clause-Patent 10 + * 11 + **/ 12 + 13 + #include <asm/arch/acpi/bcm2836_sdhost.h> 14 + #include <asm/arch/acpi/bcm2836_sdio.h> 15 + 16 + #include "acpitables.h" 17 + 18 + // 19 + // Note: UEFI can use either SDHost or Arasan. We expose both to the OS. 20 + // 21 + 22 + // ArasanSD 3.0 SD Host Controller. (brcm,bcm2835-sdhci) 23 + Device (SDC1) 24 + { 25 + Name (_HID, "BCM2847") 26 + Name (_CID, "BCM2847") 27 + Name (_UID, 0x0) 28 + Name (_CCA, 0x0) 29 + Name (_S1D, 0x1) 30 + Name (_S2D, 0x1) 31 + Name (_S3D, 0x1) 32 + Name (_S4D, 0x1) 33 + 34 + Name (RBUF, ResourceTemplate () 35 + { 36 + MEMORY32FIXED (ReadWrite, 0, MMCHS1_LENGTH, RMEM) 37 + Interrupt (ResourceConsumer, Level, ActiveHigh, Shared) { BCM2836_MMCHS1_INTERRUPT } 38 + }) 39 + Method (_CRS, 0x0, Serialized) 40 + { 41 + MEMORY32SETBASE (RBUF, RMEM, RBAS, MMCHS1_OFFSET) 42 + Return (^RBUF) 43 + } 44 + 45 + // The standard CAPs registers on this controller 46 + // appear to be 0, lets set some minimal defaults 47 + // Since this cap doesn't indicate DMA capability 48 + // we don't need a _DMA() 49 + Name (_DSD, Package () { 50 + ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), 51 + Package () { 52 + Package () { "sdhci-caps", 0x0120fa81 }, 53 + } 54 + }) 55 + 56 + // 57 + // A child device that represents the 58 + // sd card, which is marked as non-removable. 59 + // 60 + Device (SDMM) 61 + { 62 + Method (_ADR) 63 + { 64 + Return (0) 65 + } 66 + Method (_RMV) // Is removable 67 + { 68 + Return (0) // 0 - fixed 69 + } 70 + } 71 + } 72 + 73 + // Broadcom SDHost 2.0 SD Host Controller 74 + Device (SDC2) 75 + { 76 + Name (_HID, "BCM2855") 77 + Name (_CID, "BCM2855") 78 + Name (_UID, 0x0) 79 + Name (_CCA, 0x0) 80 + Name (_S1D, 0x1) 81 + Name (_S2D, 0x1) 82 + Name (_S3D, 0x1) 83 + Name (_S4D, 0x1) 84 + 85 + Name (RBUF, ResourceTemplate () 86 + { 87 + MEMORY32FIXED (ReadWrite, 0, SDHOST_LENGTH, RMEM) 88 + Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_SDHOST_INTERRUPT } 89 + }) 90 + Method (_CRS, 0x0, Serialized) 91 + { 92 + MEMORY32SETBASE (RBUF, RMEM, RBAS, SDHOST_OFFSET) 93 + Return (^RBUF) 94 + } 95 + 96 + // 97 + // A child device that represents the 98 + // sd card, which is marked as non-removable. 99 + // 100 + Device (SDMM) 101 + { 102 + Method (_ADR) 103 + { 104 + Return (0) 105 + } 106 + Method (_RMV) // Is removable 107 + { 108 + Return (0) // 0 - fixed 109 + } 110 + } 111 + }
+208
board/raspberrypi/rpi/uart.asl
··· 1 + /** @file 2 + * 3 + * [DSDT] Serial devices (UART). 4 + * 5 + * Copyright (c) 2021, ARM Limited. All rights reserved. 6 + * Copyright (c) 2020, Pete Batard <pete@akeo.ie> 7 + * Copyright (c) 2018, Andrey Warkentin <andrey.warkentin@gmail.com> 8 + * Copyright (c) Microsoft Corporation. All rights reserved. 9 + * 10 + * SPDX-License-Identifier: BSD-2-Clause-Patent 11 + * 12 + **/ 13 + 14 + #include <asm/arch/acpi/bcm2836.h> 15 + 16 + #include "acpitables.h" 17 + 18 + // PL011 based UART. 19 + Device (URT0) 20 + { 21 + Name (_HID, "BCM2837") 22 + Name (_CID, "ARMH0011") 23 + Name (_UID, 0x4) 24 + Name (_CCA, 0x0) 25 + 26 + Name (RBUF, ResourceTemplate () 27 + { 28 + MEMORY32FIXED (ReadWrite, 0, BCM2836_PL011_UART_LENGTH, RMEM) 29 + Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { BCM2836_PL011_UART_INTERRUPT } 30 + }) 31 + Method (_CRS, 0x0, Serialized) 32 + { 33 + MEMORY32SETBASE (RBUF, RMEM, RBAS, BCM2836_PL011_UART_OFFSET) 34 + Return (^RBUF) 35 + } 36 + 37 + Name (CLCK, 48000000) 38 + 39 + Name (_DSD, Package () 40 + { 41 + ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), Package () 42 + { 43 + Package (2) { "clock-frequency", CLCK }, 44 + } 45 + }) 46 + } 47 + 48 + // 49 + // UART Mini. 50 + // 51 + // This device is referenced in the DBG2 table, which will cause the system to 52 + // not start the driver when the debugger is enabled and to mark the device 53 + // with problem code 53 (CM_PROB_USED_BY_DEBUGGER). 54 + // 55 + 56 + Device (URTM) 57 + { 58 + Name (_HID, "BCM2836") 59 + Name (_CID, "BCM2836") 60 + Name (_UID, 0x0) 61 + Name (_CCA, 0x0) 62 + 63 + Name (RBUF, ResourceTemplate () 64 + { 65 + MEMORY32FIXED (ReadWrite, 0, BCM2836_MINI_UART_LENGTH, RMEM) 66 + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared) { BCM2836_MINI_UART_INTERRUPT } 67 + 68 + }) 69 + Method (_CRS, 0x0, Serialized) 70 + { 71 + MEMORY32SETBASE (RBUF, RMEM, RBAS, BCM2836_MINI_UART_OFFSET) 72 + Return (^RBUF) 73 + } 74 + 75 + // 76 + // Mini Uart Clock Rate will be dynamically updated during boot 77 + // 78 + External (\_SB.URTM.MUCR, IntObj) 79 + 80 + Name (_DSD, Package () 81 + { 82 + ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), Package () 83 + { 84 + Package (2) { "clock-frequency", MUCR }, 85 + } 86 + }) 87 + } 88 + 89 + // 90 + // Multifunction serial bus device to support Bluetooth function. 91 + // 92 + Device(BTH0) 93 + { 94 + Name (_HID, "BCM2EA6") 95 + Name (_CID, "BCM2EA6") 96 + 97 + // 98 + // UART In Use will be dynamically updated during boot 99 + // 100 + External (\_SB.BTH0.URIU, IntObj) 101 + 102 + Method (_STA) 103 + { 104 + Return (0xf) 105 + } 106 + 107 + // 108 + // Resource for URT0 (PL011) 109 + // 110 + Name (BTPL, ResourceTemplate () 111 + { 112 + UARTSerialBus( 113 + 115200, // InitialBaudRate: in BPS 114 + , // BitsPerByte: default to 8 bits 115 + , // StopBits: Defaults to one bit 116 + 0x00, // LinesInUse: 8 1-bit flags to 117 + // declare enabled control lines. 118 + // Raspberry Pi does not exposed 119 + // HW control signals -> not supported. 120 + // Optional bits: 121 + // - Bit 7 (0x80) Request To Send (RTS) 122 + // - Bit 6 (0x40) Clear To Send (CTS) 123 + // - Bit 5 (0x20) Data Terminal Ready (DTR) 124 + // - Bit 4 (0x10) Data Set Ready (DSR) 125 + // - Bit 3 (0x08) Ring Indicator (RI) 126 + // - Bit 2 (0x04) Data Carrier Detect (DTD) 127 + // - Bit 1 (0x02) Reserved. Must be 0. 128 + // - Bit 0 (0x01) Reserved. Must be 0. 129 + , // IsBigEndian: 130 + // default to LittleEndian. 131 + , // Parity: Defaults to no parity 132 + , // FlowControl: Defaults to 133 + // no flow control. 134 + 16, // ReceiveBufferSize 135 + 16, // TransmitBufferSize 136 + "\\_SB.GDV0.URT0", // ResourceSource: 137 + // UART bus controller name 138 + , // ResourceSourceIndex: assumed to be 0 139 + , // ResourceUsage: assumed to be 140 + // ResourceConsumer 141 + UAR0, // DescriptorName: creates name 142 + // for offset of resource descriptor 143 + ) // Vendor data 144 + }) 145 + 146 + // 147 + // Resource for URTM (miniUART) 148 + // 149 + Name (BTMN, ResourceTemplate () 150 + { 151 + // 152 + // BT UART: ResourceSource will be dynamically updated to 153 + // either URT0 (PL011) or URTM (miniUART) during boot 154 + // 155 + UARTSerialBus( 156 + 115200, // InitialBaudRate: in BPS 157 + , // BitsPerByte: default to 8 bits 158 + , // StopBits: Defaults to one bit 159 + 0x00, // LinesInUse: 8 1-bit flags to 160 + // declare enabled control lines. 161 + // Raspberry Pi does not exposed 162 + // HW control signals -> not supported. 163 + // Optional bits: 164 + // - Bit 7 (0x80) Request To Send (RTS) 165 + // - Bit 6 (0x40) Clear To Send (CTS) 166 + // - Bit 5 (0x20) Data Terminal Ready (DTR) 167 + // - Bit 4 (0x10) Data Set Ready (DSR) 168 + // - Bit 3 (0x08) Ring Indicator (RI) 169 + // - Bit 2 (0x04) Data Carrier Detect (DTD) 170 + // - Bit 1 (0x02) Reserved. Must be 0. 171 + // - Bit 0 (0x01) Reserved. Must be 0. 172 + , // IsBigEndian: 173 + // default to LittleEndian. 174 + , // Parity: Defaults to no parity 175 + , // FlowControl: Defaults to 176 + // no flow control. 177 + 16, // ReceiveBufferSize 178 + 16, // TransmitBufferSize 179 + "\\_SB.GDV0.URTM", // ResourceSource: 180 + // UART bus controller name 181 + , // ResourceSourceIndex: assumed to be 0 182 + , // ResourceUsage: assumed to be 183 + // ResourceConsumer 184 + UARM, // DescriptorName: creates name 185 + // for offset of resource descriptor 186 + ) // Vendor data 187 + }) 188 + 189 + Method (_CRS, 0x0, Serialized) 190 + { 191 + if (URIU == 0) 192 + { 193 + // 194 + // PL011 UART is configured for console output 195 + // Return Mini UART for Bluetooth 196 + // 197 + return (^BTMN) 198 + } 199 + else 200 + { 201 + // 202 + // Mini UART is configured for console output 203 + // Return PL011 UART for Bluetooth 204 + // 205 + return (^BTPL) 206 + } 207 + } 208 + }
+6 -2
boot/bootflow.c
··· 936 936 return ret; 937 937 938 938 *buf = '\0'; 939 - if (!strcmp("earlycon", arg)) { 939 + if (!strcmp("earlycon", arg) && info.type == SERIAL_CHIP_16550_COMPATIBLE) { 940 940 snprintf(buf, sizeof(buf), 941 941 "uart8250,mmio32,%#lx,%dn8", info.addr, 942 942 info.baudrate); 943 - } else if (!strcmp("console", arg)) { 943 + } else if (!strcmp("earlycon", arg) && info.type == SERIAL_CHIP_PL01X) { 944 + snprintf(buf, sizeof(buf), 945 + "pl011,mmio32,%#lx,%dn8", info.addr, 946 + info.baudrate); 947 + } else if (!strcmp("console", arg) && info.type == SERIAL_CHIP_16550_COMPATIBLE) { 944 948 snprintf(buf, sizeof(buf), 945 949 "ttyS0,%dn8", info.baudrate); 946 950 }
+1
common/Kconfig
··· 1081 1081 hex "Size of bloblist after relocation" 1082 1082 default BLOBLIST_SIZE if BLOBLIST_FIXED || BLOBLIST_ALLOC 1083 1083 default 0x0 if BLOBLIST_PASSAGE 1084 + default 0x20000 if (ARM && EFI_LOADER && GENERATE_ACPI_TABLE) 1084 1085 help 1085 1086 Sets the size of the bloblist in bytes after relocation. Since U-Boot 1086 1087 has a lot more memory available then, it is possible to use a larger
+1 -1
common/bloblist.c
··· 499 499 { 500 500 bool fixed = IS_ENABLED(CONFIG_BLOBLIST_FIXED); 501 501 int ret = -ENOENT; 502 - ulong addr, size; 502 + ulong addr = 0, size; 503 503 /* 504 504 * If U-Boot is not in the first phase, an existing bloblist must be 505 505 * at a fixed address.
+1 -1
configs/clearfog_defconfig
··· 53 53 CONFIG_NET_RETRY_COUNT=50 54 54 CONFIG_NET_RANDOM_ETHADDR=y 55 55 CONFIG_SPL_OF_TRANSLATE=y 56 - CONFIG_AHCI_MVEBU=y 56 + CONFIG_AHCI_GENERIC=y 57 57 CONFIG_DM_PCA953X=y 58 58 CONFIG_DM_I2C=y 59 59 CONFIG_SYS_I2C_MVTWSI=y
+1 -1
configs/clearfog_gt_8k_defconfig
··· 46 46 CONFIG_ARP_TIMEOUT=200 47 47 CONFIG_NET_RETRY_COUNT=50 48 48 CONFIG_NET_RANDOM_ETHADDR=y 49 - CONFIG_AHCI_MVEBU=y 49 + CONFIG_AHCI_GENERIC=y 50 50 CONFIG_LBA48=y 51 51 CONFIG_SYS_64BIT_LBA=y 52 52 CONFIG_DM_I2C=y
+1 -1
configs/clearfog_sata_defconfig
··· 53 53 CONFIG_NET_RETRY_COUNT=50 54 54 CONFIG_NET_RANDOM_ETHADDR=y 55 55 CONFIG_SPL_OF_TRANSLATE=y 56 - CONFIG_AHCI_MVEBU=y 56 + CONFIG_AHCI_GENERIC=y 57 57 CONFIG_DM_PCA953X=y 58 58 CONFIG_DM_I2C=y 59 59 CONFIG_SYS_I2C_MVTWSI=y
+1 -1
configs/clearfog_spi_defconfig
··· 53 53 CONFIG_NET_RETRY_COUNT=50 54 54 CONFIG_NET_RANDOM_ETHADDR=y 55 55 CONFIG_SPL_OF_TRANSLATE=y 56 - CONFIG_AHCI_MVEBU=y 56 + CONFIG_AHCI_GENERIC=y 57 57 CONFIG_DM_PCA953X=y 58 58 CONFIG_DM_I2C=y 59 59 CONFIG_SYS_I2C_MVTWSI=y
+1 -1
configs/db-88f6820-gp_defconfig
··· 58 58 CONFIG_ARP_TIMEOUT=200 59 59 CONFIG_NET_RETRY_COUNT=50 60 60 CONFIG_SPL_OF_TRANSLATE=y 61 - CONFIG_AHCI_MVEBU=y 61 + CONFIG_AHCI_GENERIC=y 62 62 CONFIG_SYS_I2C_LEGACY=y 63 63 CONFIG_SPL_SYS_I2C_LEGACY=y 64 64 CONFIG_SYS_I2C_MVTWSI=y
+1 -1
configs/ds116_defconfig
··· 65 65 CONFIG_NET_RANDOM_ETHADDR=y 66 66 CONFIG_NETCONSOLE=y 67 67 CONFIG_SPL_OF_TRANSLATE=y 68 - CONFIG_AHCI_MVEBU=y 68 + CONFIG_AHCI_GENERIC=y 69 69 CONFIG_LBA48=y 70 70 CONFIG_SYS_64BIT_LBA=y 71 71 CONFIG_DM_I2C=y
+1 -1
configs/helios4_defconfig
··· 53 53 CONFIG_NET_RETRY_COUNT=50 54 54 CONFIG_NET_RANDOM_ETHADDR=y 55 55 CONFIG_SPL_OF_TRANSLATE=y 56 - CONFIG_AHCI_MVEBU=y 56 + CONFIG_AHCI_GENERIC=y 57 57 CONFIG_DM_PCA953X=y 58 58 CONFIG_DM_I2C=y 59 59 CONFIG_SYS_I2C_MVTWSI=y
+1 -1
configs/mvebu_crb_cn9130_defconfig
··· 46 46 CONFIG_SYS_MMC_ENV_DEV=1 47 47 CONFIG_ARP_TIMEOUT=200 48 48 CONFIG_NET_RETRY_COUNT=50 49 - CONFIG_AHCI_MVEBU=y 49 + CONFIG_AHCI_GENERIC=y 50 50 CONFIG_LBA48=y 51 51 CONFIG_SYS_64BIT_LBA=y 52 52 CONFIG_DM_I2C=y
+1 -1
configs/mvebu_db-88f3720_defconfig
··· 43 43 CONFIG_SYS_RELOC_GD_ENV_ADDR=y 44 44 CONFIG_ARP_TIMEOUT=200 45 45 CONFIG_NET_RETRY_COUNT=50 46 - CONFIG_AHCI_MVEBU=y 46 + CONFIG_AHCI_GENERIC=y 47 47 CONFIG_LBA48=y 48 48 CONFIG_SYS_64BIT_LBA=y 49 49 CONFIG_CLK=y
+1 -1
configs/mvebu_db_armada8k_defconfig
··· 42 42 CONFIG_SYS_RELOC_GD_ENV_ADDR=y 43 43 CONFIG_ARP_TIMEOUT=200 44 44 CONFIG_NET_RETRY_COUNT=50 45 - CONFIG_AHCI_MVEBU=y 45 + CONFIG_AHCI_GENERIC=y 46 46 CONFIG_LBA48=y 47 47 CONFIG_SYS_64BIT_LBA=y 48 48 CONFIG_DM_I2C=y
+1 -1
configs/mvebu_db_cn9130_defconfig
··· 47 47 CONFIG_SYS_MMC_ENV_DEV=1 48 48 CONFIG_ARP_TIMEOUT=200 49 49 CONFIG_NET_RETRY_COUNT=50 50 - CONFIG_AHCI_MVEBU=y 50 + CONFIG_AHCI_GENERIC=y 51 51 CONFIG_LBA48=y 52 52 CONFIG_SYS_64BIT_LBA=y 53 53 CONFIG_DM_GPIO_LOOKUP_LABEL=y
+1 -1
configs/mvebu_espressobin-88f3720_defconfig
··· 54 54 CONFIG_NET_RETRY_COUNT=50 55 55 CONFIG_NET_RANDOM_ETHADDR=y 56 56 CONFIG_AHCI_PCI=y 57 - CONFIG_AHCI_MVEBU=y 57 + CONFIG_AHCI_GENERIC=y 58 58 CONFIG_LBA48=y 59 59 CONFIG_SYS_64BIT_LBA=y 60 60 CONFIG_CLK=y
+1 -1
configs/mvebu_espressobin_ultra-88f3720_defconfig
··· 53 53 CONFIG_NET_RETRY_COUNT=50 54 54 CONFIG_NET_RANDOM_ETHADDR=y 55 55 CONFIG_AHCI_PCI=y 56 - CONFIG_AHCI_MVEBU=y 56 + CONFIG_AHCI_GENERIC=y 57 57 CONFIG_LBA48=y 58 58 CONFIG_SYS_64BIT_LBA=y 59 59 CONFIG_CLK=y
+1 -1
configs/mvebu_mcbin-88f8040_defconfig
··· 46 46 CONFIG_ARP_TIMEOUT=200 47 47 CONFIG_NET_RETRY_COUNT=50 48 48 CONFIG_NET_RANDOM_ETHADDR=y 49 - CONFIG_AHCI_MVEBU=y 49 + CONFIG_AHCI_GENERIC=y 50 50 CONFIG_LBA48=y 51 51 CONFIG_SYS_64BIT_LBA=y 52 52 CONFIG_DM_I2C=y
+1 -1
configs/mvebu_puzzle-m801-88f8040_defconfig
··· 50 50 CONFIG_ARP_TIMEOUT=200 51 51 CONFIG_NET_RETRY_COUNT=50 52 52 CONFIG_NET_RANDOM_ETHADDR=y 53 - CONFIG_AHCI_MVEBU=y 53 + CONFIG_AHCI_GENERIC=y 54 54 CONFIG_LBA48=y 55 55 CONFIG_SYS_64BIT_LBA=y 56 56 CONFIG_DM_PCA953X=y
+1 -1
configs/n2350_defconfig
··· 65 65 CONFIG_NET_RANDOM_ETHADDR=y 66 66 CONFIG_NETCONSOLE=y 67 67 CONFIG_SPL_OF_TRANSLATE=y 68 - CONFIG_AHCI_MVEBU=y 68 + CONFIG_AHCI_GENERIC=y 69 69 CONFIG_LBA48=y 70 70 CONFIG_SYS_64BIT_LBA=y 71 71 CONFIG_DM_I2C=y
+1 -1
configs/octeon_nic23_defconfig
··· 46 46 CONFIG_ENV_IS_IN_SPI_FLASH=y 47 47 CONFIG_TFTP_TSIZE=y 48 48 CONFIG_SATA=y 49 - CONFIG_AHCI_MVEBU=y 49 + CONFIG_AHCI_GENERIC=y 50 50 CONFIG_LBA48=y 51 51 CONFIG_SYS_64BIT_LBA=y 52 52 CONFIG_CLK=y
+12
configs/qemu-arm-sbsa_defconfig
··· 1 + CONFIG_ARM=y 2 + CONFIG_ARCH_QEMU=y 3 + CONFIG_TARGET_QEMU_ARM_SBSA=y 4 + CONFIG_USE_BOOTCOMMAND=y 5 + CONFIG_BOOTCOMMAND="bootflow scan" 6 + CONFIG_EFI_PARTITION=y 7 + CONFIG_PARTITION_TYPE_GUID=y 8 + CONFIG_EFI_MEDIA=y 9 + CONFIG_FS_FAT=y 10 + CONFIG_EFI_VARIABLE_NO_STORE=y 11 + CONFIG_BLOBLIST_ALLOC=y 12 + CONFIG_BLOBLIST_SIZE_RELOC=0x20000
+10
configs/rpi_4_acpi_defconfig
··· 1 + #include <configs/rpi_4_defconfig> 2 + 3 + CONFIG_ARM=y 4 + CONFIG_ARCH_BCM283X=y 5 + CONFIG_TARGET_RPI_4=y 6 + CONFIG_BLOBLIST_ALLOC=y 7 + CONFIG_OF_BOARD=y 8 + CONFIG_ACPI=y 9 + CONFIG_GENERATE_ACPI_TABLE=y 10 +
+1 -1
configs/turris_omnia_defconfig
··· 90 90 CONFIG_NETCONSOLE=y 91 91 CONFIG_SPL_OF_TRANSLATE=y 92 92 CONFIG_AHCI_PCI=y 93 - CONFIG_AHCI_MVEBU=y 93 + CONFIG_AHCI_GENERIC=y 94 94 CONFIG_DM_PCA953X=y 95 95 CONFIG_MMC_SDHCI=y 96 96 CONFIG_MMC_SDHCI_MV=y
+1
doc/board/emulation/index.rst
··· 13 13 qemu-mips 14 14 qemu-ppce500 15 15 qemu-riscv 16 + qemu-sbsa 16 17 qemu-x86 17 18 qemu-xtensa
+98
doc/board/emulation/qemu-sbsa.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0+ 2 + .. Copyright (C) 2024, Patrick Rudolph <patrick.rudolph@9elements.com> 3 + 4 + QEMU ARM SBSA 5 + ============= 6 + 7 + QEMU for ARM supports Arm Server Base System Architecture Reference board, 8 + short 'sbsa-ref' that utilizes ACPI over FDT. This document describes how to run 9 + U-Boot under it. Only AArch64 is supported. 10 + 11 + The 'sbsa' platform provides the following as the basic functionality: 12 + 13 + - A freely configurable amount of CPU cores 14 + - U-Boot loaded and executing in the emulated flash at address 0x10000000 15 + - No device tree blob 16 + - A freely configurable amount of RAM 17 + - A PL011 serial port 18 + - An ARMv7/ARMv8 architected timer 19 + - PSCI for rebooting the system 20 + - A generic ECAM-based PCI host controller 21 + 22 + Additionally, a number of optional peripherals can be added to the PCI bus. 23 + 24 + Compile ARM Trusted Firmware (ATF) 25 + ---------------------------------- 26 + 27 + Get and Build the ARM Trusted firmware 28 + -------------------------------------- 29 + 30 + Note: srctree is U-Boot source directory 31 + Get ATF from: https://github.com/ARM-software/arm-trusted-firmware 32 + 33 + .. code-block:: bash 34 + 35 + git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git tfa 36 + cd tfa 37 + make CROSS_COMPILE=aarch64-linux-gnu- all fip \ 38 + ARM_LINUX_KERNEL_AS_BL33=1 DEBUG=1 PLAT=qemu_sbsa 39 + 40 + Copy the resulting FIP and BL1 binary 41 + 42 + .. code-block:: bash 43 + 44 + cp build/qemu_sbsa/debug/fip.bin ../ 45 + cp build/qemu_sbsa/debug/bl1.bin ../ 46 + 47 + Building U-Boot 48 + --------------- 49 + Set the CROSS_COMPILE environment variable as usual, and run: 50 + 51 + .. code-block:: bash 52 + 53 + make qemu-arm-sbsa_defconfig 54 + make 55 + 56 + Running U-Boot 57 + -------------- 58 + The minimal QEMU command line to get U-Boot up and running is: 59 + 60 + .. code-block:: bash 61 + 62 + qemu-system-aarch64 -machine sbsa-ref -nographic -cpu cortex-a57 \ 63 + -pflash secure-world.rom \ 64 + -pflash unsecure-world.rom 65 + 66 + Note that for some odd reason qemu-system-aarch64 needs to be explicitly 67 + told to use a 64-bit CPU or it will boot in 32-bit mode. The -nographic argument 68 + ensures that output appears on the terminal. Use Ctrl-A X to quit. 69 + 70 + Booting distros 71 + --------------- 72 + 73 + It is possible to install and boot a standard Linux distribution using 74 + sbsa by setting up a root disk:: 75 + 76 + .. code-block:: bash 77 + 78 + qemu-img create root.img 20G 79 + 80 + then using the installer to install. For example, with Debian 12:: 81 + 82 + .. code-block:: bash 83 + 84 + qemu-system-aarch64 \ 85 + -machine sbsa-ref -cpu cortex-a57 -m 4G -smp 4 \ 86 + -pflash secure-world.rom \ 87 + -pflash unsecure-world.rom \ 88 + -device virtio-rng-pci \ 89 + -device usb-kbd -device usb-tablet \ 90 + -cdrom debian-12.0.0-arm64-netinst.iso \ 91 + -hda root.img 92 + 93 + Debug UART 94 + ---------- 95 + 96 + The debug UART on the ARM sbsa board uses these settings:: 97 + 98 + CONFIG_DEBUG_UART=y
+1
doc/develop/driver-model/virtio.rst
··· 34 34 35 35 - qemu_arm_defconfig 36 36 - qemu_arm64_defconfig 37 + - qemu-arm-sbsa_defconfig 37 38 - qemu-riscv32_defconfig 38 39 - qemu-riscv64_defconfig 39 40 - qemu-x86_defconfig
+7 -5
drivers/ata/Kconfig
··· 78 78 Enable this driver to support Sata devices through 79 79 Mediatek AHCI controller (e.g. MT7622). 80 80 81 - config AHCI_MVEBU 82 - bool "Marvell EBU AHCI SATA support" 83 - depends on ARCH_MVEBU || ARCH_OCTEON 81 + config AHCI_GENERIC 82 + bool "Generic AHCI SATA support" 83 + depends on OF_CONTROL 84 84 select SCSI_AHCI 85 85 select SCSI 86 86 help 87 - This option enables support for the Marvell EBU SoC's 88 - onboard AHCI SATA. 87 + This option enables support for generic onboard AHCI SATA controller 88 + that do not need platform specific quirks, like emulated devices, 89 + Marvell EBU SoC's onboard AHCI SATA controllers or Cavium's Octeon 90 + 7130 AHCI controllers. 89 91 90 92 If unsure, say N. 91 93
+1 -1
drivers/ata/Makefile
··· 14 14 obj-$(CONFIG_SATA_CEVA) += sata_ceva.o 15 15 obj-$(CONFIG_SATA_MV) += sata_mv.o 16 16 obj-$(CONFIG_SATA_SIL) += sata_sil.o 17 - obj-$(CONFIG_AHCI_MVEBU) += ahci_mvebu.o 17 + obj-$(CONFIG_AHCI_GENERIC) += ahci_generic.o 18 18 obj-$(CONFIG_SUNXI_AHCI) += ahci_sunxi.o 19 19 obj-$(CONFIG_MTK_AHCI) += mtk_ahci.o
+9 -8
drivers/ata/ahci_mvebu.c drivers/ata/ahci_generic.c
··· 16 16 return 0; 17 17 } 18 18 19 - static int mvebu_ahci_bind(struct udevice *dev) 19 + static int generic_ahci_bind(struct udevice *dev) 20 20 { 21 21 struct udevice *scsi_dev; 22 22 int ret; ··· 30 30 return 0; 31 31 } 32 32 33 - static int mvebu_ahci_probe(struct udevice *dev) 33 + static int generic_ahci_probe(struct udevice *dev) 34 34 { 35 35 /* 36 36 * Board specific SATA / AHCI enable code, e.g. enable the ··· 43 43 return 0; 44 44 } 45 45 46 - static const struct udevice_id mvebu_ahci_ids[] = { 46 + static const struct udevice_id generic_ahci_ids[] = { 47 47 { .compatible = "marvell,armada-380-ahci" }, 48 48 { .compatible = "marvell,armada-3700-ahci" }, 49 49 { .compatible = "marvell,armada-8k-ahci" }, 50 50 { .compatible = "cavium,octeon-7130-ahci" }, 51 + { .compatible = "generic-ahci" }, 51 52 { } 52 53 }; 53 54 54 - U_BOOT_DRIVER(ahci_mvebu_drv) = { 55 - .name = "ahci_mvebu", 55 + U_BOOT_DRIVER(ahci_generic_drv) = { 56 + .name = "ahci_generic", 56 57 .id = UCLASS_AHCI, 57 - .of_match = mvebu_ahci_ids, 58 - .bind = mvebu_ahci_bind, 59 - .probe = mvebu_ahci_probe, 58 + .of_match = generic_ahci_ids, 59 + .bind = generic_ahci_bind, 60 + .probe = generic_ahci_probe, 60 61 };
+16
drivers/core/acpi.c
··· 48 48 METHOD_FILL_SSDT, 49 49 METHOD_INJECT_DSDT, 50 50 METHOD_SETUP_NHLT, 51 + METHOD_FILL_MADT, 51 52 }; 52 53 53 54 /* Prototype for all methods */ ··· 282 283 switch (method) { 283 284 case METHOD_WRITE_TABLES: 284 285 return aops->write_tables; 286 + case METHOD_FILL_MADT: 287 + return aops->fill_madt; 285 288 case METHOD_FILL_SSDT: 286 289 return aops->fill_ssdt; 287 290 case METHOD_INJECT_DSDT: ··· 326 329 } 327 330 328 331 return 0; 332 + } 333 + 334 + int acpi_fill_madt_subtbl(struct acpi_ctx *ctx) 335 + { 336 + int ret; 337 + 338 + log_debug("Writing MADT table\n"); 339 + ret = acpi_recurse_method(ctx, dm_root(), METHOD_FILL_MADT, TYPE_NONE); 340 + log_debug("Writing MADT finished, err=%d\n", ret); 341 + if (ret) 342 + return log_msg_ret("build", ret); 343 + 344 + return ret; 329 345 } 330 346 331 347 int acpi_fill_ssdt(struct acpi_ctx *ctx)
+7
drivers/cpu/Kconfig
··· 26 26 help 27 27 Support CPU cores for RISC-V architecture. 28 28 29 + config CPU_ARMV8 30 + bool "Enable generic ARMv8 CPU driver" 31 + depends on CPU && ARM64 32 + select IRQ 33 + help 34 + Support CPU cores for armv8 architecture. 35 + 29 36 config CPU_MICROBLAZE 30 37 bool "Enable Microblaze CPU driver" 31 38 depends on CPU && MICROBLAZE
+2
drivers/cpu/Makefile
··· 6 6 7 7 obj-$(CONFIG_CPU) += cpu-uclass.o 8 8 9 + obj-$(CONFIG_ARCH_BCM283X) += bcm283x_cpu.o 9 10 obj-$(CONFIG_ARCH_BMIPS) += bmips_cpu.o 10 11 obj-$(CONFIG_ARCH_IMX8) += imx8_cpu.o 11 12 obj-$(CONFIG_ARCH_AT91) += at91_cpu.o 12 13 obj-$(CONFIG_ARCH_MEDIATEK) += mtk_cpu.o 14 + obj-$(CONFIG_CPU_ARMV8) += armv8_cpu.o 13 15 obj-$(CONFIG_CPU_IMX) += imx8_cpu.o 14 16 obj-$(CONFIG_CPU_MPC83XX) += mpc83xx_cpu.o 15 17 obj-$(CONFIG_CPU_RISCV) += riscv_cpu.o
+151
drivers/cpu/armv8_cpu.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Copyright 2024 9elements GmbH 4 + */ 5 + #include <cpu.h> 6 + #include <dm.h> 7 + #include <irq.h> 8 + #include <acpi/acpigen.h> 9 + #include <asm/armv8/cpu.h> 10 + #include <asm/io.h> 11 + #include <dm/acpi.h> 12 + #include <linux/bitops.h> 13 + #include <linux/printk.h> 14 + #include <linux/sizes.h> 15 + 16 + static int armv8_cpu_get_desc(const struct udevice *dev, char *buf, int size) 17 + { 18 + int cpuid; 19 + 20 + cpuid = (read_midr() & MIDR_PARTNUM_MASK) >> MIDR_PARTNUM_SHIFT; 21 + 22 + snprintf(buf, size, "CPU MIDR %04x", cpuid); 23 + 24 + return 0; 25 + } 26 + 27 + static int armv8_cpu_get_info(const struct udevice *dev, 28 + struct cpu_info *info) 29 + { 30 + info->cpu_freq = 0; 31 + info->features = BIT(CPU_FEAT_L1_CACHE) | BIT(CPU_FEAT_MMU); 32 + 33 + return 0; 34 + } 35 + 36 + static int armv8_cpu_get_count(const struct udevice *dev) 37 + { 38 + return uclass_id_count(UCLASS_CPU); 39 + } 40 + 41 + #ifdef CONFIG_ACPIGEN 42 + int armv8_cpu_fill_ssdt(const struct udevice *dev, struct acpi_ctx *ctx) 43 + { 44 + uint core_id = dev_seq(dev); 45 + 46 + acpigen_write_processor_device(ctx, core_id); 47 + 48 + return 0; 49 + } 50 + 51 + int armv8_cpu_fill_madt(const struct udevice *dev, struct acpi_ctx *ctx) 52 + { 53 + struct acpi_madt_gicc *gicc; 54 + struct cpu_plat *cpu_plat; 55 + struct udevice *gic; 56 + u64 gicc_gicv = 0; 57 + u64 gicc_gich = 0; 58 + u64 gicc_gicr_base = 0; 59 + u64 gicc_phys_base = 0; 60 + u32 gicc_perf_gsiv = 0; 61 + u64 gicc_mpidr; 62 + u32 gicc_vgic_maint_irq = 0; 63 + int addr_index; 64 + fdt_addr_t addr; 65 + int ret; 66 + struct irq req_irq; 67 + 68 + cpu_plat = dev_get_parent_plat(dev); 69 + if (!cpu_plat) 70 + return 0; 71 + 72 + ret = irq_get_interrupt_parent(dev, &gic); 73 + if (ret) { 74 + log_err("%s: Failed to find interrupt parent for %s\n", 75 + __func__, dev->name); 76 + return -ENODEV; 77 + } 78 + 79 + addr_index = 1; 80 + 81 + if (device_is_compatible(gic, "arm,gic-v3")) { 82 + addr = dev_read_addr_index(gic, addr_index++); 83 + if (addr != FDT_ADDR_T_NONE) 84 + gicc_gicr_base = addr; 85 + } 86 + 87 + addr = dev_read_addr_index(gic, addr_index++); 88 + if (addr != FDT_ADDR_T_NONE) 89 + gicc_phys_base = addr; 90 + 91 + addr = dev_read_addr_index(gic, addr_index++); 92 + if (addr != FDT_ADDR_T_NONE) 93 + gicc_gich = addr; 94 + 95 + addr = dev_read_addr_index(gic, addr_index++); 96 + if (addr != FDT_ADDR_T_NONE) 97 + gicc_gicv = addr; 98 + 99 + ret = irq_get_by_index(gic, 0, &req_irq); 100 + if (!ret) 101 + gicc_vgic_maint_irq = req_irq.id; 102 + 103 + gicc_mpidr = dev_read_u64_default(dev, "reg", 0); 104 + if (!gicc_mpidr) 105 + gicc_mpidr = dev_read_u32_default(dev, "reg", 0); 106 + 107 + /* 108 + * gicc_vgic_maint_irq and gicc_gicv are the same for every CPU 109 + */ 110 + gicc = ctx->current; 111 + acpi_write_madt_gicc(gicc, 112 + dev_seq(dev), 113 + gicc_perf_gsiv, /* FIXME: needs a PMU driver */ 114 + gicc_phys_base, 115 + gicc_gicv, 116 + gicc_gich, 117 + gicc_vgic_maint_irq, 118 + gicc_gicr_base, 119 + gicc_mpidr, 120 + 0); /* FIXME: Not defined in DT */ 121 + 122 + acpi_inc(ctx, gicc->length); 123 + 124 + return 0; 125 + } 126 + 127 + struct acpi_ops armv8_cpu_acpi_ops = { 128 + .fill_ssdt = armv8_cpu_fill_ssdt, 129 + .fill_madt = armv8_cpu_fill_madt, 130 + }; 131 + #endif 132 + 133 + static const struct cpu_ops cpu_ops = { 134 + .get_count = armv8_cpu_get_count, 135 + .get_desc = armv8_cpu_get_desc, 136 + .get_info = armv8_cpu_get_info, 137 + }; 138 + 139 + static const struct udevice_id cpu_ids[] = { 140 + { .compatible = "arm,armv8" }, 141 + {} 142 + }; 143 + 144 + U_BOOT_DRIVER(arm_cpu) = { 145 + .name = "arm-cpu", 146 + .id = UCLASS_CPU, 147 + .of_match = cpu_ids, 148 + .ops = &cpu_ops, 149 + .flags = DM_FLAG_PRE_RELOC, 150 + ACPI_OPS_PTR(&armv8_cpu_acpi_ops) 151 + };
+31
drivers/cpu/armv8_cpu.h
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Copyright 2024 9elements GmbH 4 + */ 5 + #include <dm/acpi.h> 6 + #include <dm/device.h> 7 + 8 + #ifndef _ARMV8_CPU_H_ 9 + #define _ARMV8_CPU_H_ 10 + 11 + /** 12 + * armv8_cpu_fill_ssdt() - Fill the SSDT 13 + * Parses the FDT and writes the SSDT nodes. 14 + * 15 + * @dev: cpu device to generate ACPI tables for 16 + * @ctx: ACPI context pointer 17 + * @return: 0 if OK, or a negative error code. 18 + */ 19 + int armv8_cpu_fill_ssdt(const struct udevice *dev, struct acpi_ctx *ctx); 20 + 21 + /** 22 + * armv8_cpu_fill_madt() - Fill the MADT 23 + * Parses the FDT and writes the MADT subtables. 24 + * 25 + * @dev: cpu device to generate ACPI tables for 26 + * @ctx: ACPI context pointer 27 + * @return: 0 if OK, or a negative error code. 28 + */ 29 + int armv8_cpu_fill_madt(const struct udevice *dev, struct acpi_ctx *ctx); 30 + 31 + #endif
+214
drivers/cpu/bcm283x_cpu.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Copyright 2024 9elements GmbH 4 + */ 5 + 6 + #include <cpu.h> 7 + #include <cpu_func.h> 8 + #include <dm.h> 9 + #include <fdt_support.h> 10 + #include <acpi/acpigen.h> 11 + #include <asm/armv8/cpu.h> 12 + #include <asm/cache.h> 13 + #include <asm/io.h> 14 + #include <asm/global_data.h> 15 + #include <asm/system.h> 16 + #include <asm-generic/sections.h> 17 + #include <linux/bitops.h> 18 + #include <linux/clk-provider.h> 19 + #include <linux/delay.h> 20 + #include "armv8_cpu.h" 21 + 22 + DECLARE_GLOBAL_DATA_PTR; 23 + 24 + struct bcm_plat { 25 + u64 release_addr; 26 + }; 27 + 28 + static int cpu_bcm_get_desc(const struct udevice *dev, char *buf, int size) 29 + { 30 + struct cpu_plat *plat = dev_get_parent_plat(dev); 31 + const char *name; 32 + 33 + if (size < 32) 34 + return -ENOSPC; 35 + 36 + if (device_is_compatible(dev, "arm,cortex-a53")) 37 + name = "A53"; 38 + else if (device_is_compatible(dev, "arm,cortex-a72")) 39 + name = "A72"; 40 + else 41 + name = "?"; 42 + 43 + snprintf(buf, size, "Broadcom Cortex-%s at %u MHz\n", 44 + name, plat->timebase_freq); 45 + 46 + return 0; 47 + } 48 + 49 + static int cpu_bcm_get_info(const struct udevice *dev, struct cpu_info *info) 50 + { 51 + struct cpu_plat *plat = dev_get_parent_plat(dev); 52 + 53 + info->cpu_freq = plat->timebase_freq * 1000; 54 + info->features = BIT(CPU_FEAT_L1_CACHE) | BIT(CPU_FEAT_MMU); 55 + 56 + return 0; 57 + } 58 + 59 + static int cpu_bcm_get_count(const struct udevice *dev) 60 + { 61 + return uclass_id_count(UCLASS_CPU); 62 + } 63 + 64 + static int cpu_bcm_get_vendor(const struct udevice *dev, char *buf, int size) 65 + { 66 + snprintf(buf, size, "Broadcom"); 67 + 68 + return 0; 69 + } 70 + 71 + static int cpu_bcm_is_current(struct udevice *dev) 72 + { 73 + struct cpu_plat *plat = dev_get_parent_plat(dev); 74 + 75 + if (plat->cpu_id == (read_mpidr() & 0xffff)) 76 + return 1; 77 + 78 + return 0; 79 + } 80 + 81 + /** 82 + * bcm_cpu_on - Releases the secondary CPU from it's spintable 83 + * 84 + * Write the CPU's spintable mailbox and let the CPU enter U-Boot. 85 + * 86 + * @dev: Device to start 87 + * @return: zero on success or error code on failure. 88 + */ 89 + static int bcm_cpu_on(struct udevice *dev) 90 + { 91 + struct bcm_plat *plat = dev_get_plat(dev); 92 + ulong *start_address; 93 + 94 + if (plat->release_addr == ~0ULL) 95 + return -ENODATA; 96 + 97 + start_address = map_physmem(plat->release_addr, sizeof(uintptr_t), MAP_NOCACHE); 98 + 99 + /* Point secondary CPU to U-Boot entry */ 100 + *start_address = (uintptr_t)_start; 101 + 102 + /* Make sure the other CPUs see the written start address */ 103 + if (!CONFIG_IS_ENABLED(SYS_DCACHE_OFF)) 104 + flush_dcache_all(); 105 + 106 + /* Send an event to wake up the secondary CPU. */ 107 + asm("dsb ishst\n" 108 + "sev"); 109 + 110 + unmap_physmem(start_address, MAP_NOCACHE); 111 + 112 + return 0; 113 + } 114 + 115 + static const struct cpu_ops cpu_bcm_ops = { 116 + .get_desc = cpu_bcm_get_desc, 117 + .get_info = cpu_bcm_get_info, 118 + .get_count = cpu_bcm_get_count, 119 + .get_vendor = cpu_bcm_get_vendor, 120 + .is_current = cpu_bcm_is_current, 121 + }; 122 + 123 + static const struct udevice_id cpu_bcm_ids[] = { 124 + { .compatible = "arm,cortex-a53" }, /* RPi 3 */ 125 + { .compatible = "arm,cortex-a72" }, /* RPi 4 */ 126 + { } 127 + }; 128 + 129 + static int bcm_cpu_bind(struct udevice *dev) 130 + { 131 + struct cpu_plat *plat = dev_get_parent_plat(dev); 132 + 133 + plat->cpu_id = dev_read_addr(dev); 134 + 135 + return 0; 136 + } 137 + 138 + /** 139 + * bcm_cpu_of_to_plat - Gather spin-table release address 140 + * 141 + * Read the spin-table release address to allow all seconary CPUs to enter 142 + * U-Boot when necessary. 143 + * 144 + * @dev: Device to start 145 + */ 146 + static int bcm_cpu_of_to_plat(struct udevice *dev) 147 + { 148 + struct bcm_plat *plat = dev_get_plat(dev); 149 + const char *prop; 150 + 151 + if (CONFIG_IS_ENABLED(ARMV8_MULTIENTRY)) { 152 + plat->release_addr = ~0ULL; 153 + 154 + prop = dev_read_string(dev, "enable-method"); 155 + if (!prop || strcmp(prop, "spin-table")) 156 + return -ENODEV; 157 + 158 + plat->release_addr = dev_read_u64_default(dev, "cpu-release-addr", ~0ULL); 159 + 160 + if (plat->release_addr == ~0ULL) 161 + return -ENODEV; 162 + } 163 + 164 + return 0; 165 + } 166 + 167 + static int bcm_cpu_probe(struct udevice *dev) 168 + { 169 + struct cpu_plat *plat = dev_get_parent_plat(dev); 170 + struct clk clk; 171 + int ret; 172 + 173 + /* Get a clock if it exists */ 174 + ret = clk_get_by_index(dev, 0, &clk); 175 + if (!ret) { 176 + ret = clk_enable(&clk); 177 + if (ret && (ret != -ENOSYS || ret != -EOPNOTSUPP)) 178 + return ret; 179 + ret = clk_get_rate(&clk); 180 + if (IS_ERR_VALUE(ret)) 181 + return ret; 182 + plat->timebase_freq = ret; 183 + } 184 + 185 + /* 186 + * The armstub holds the secondary CPUs in a spinloop. When 187 + * ARMV8_MULTIENTRY is enabled release the secondary CPUs and 188 + * let them enter U-Boot as well. 189 + */ 190 + if (CONFIG_IS_ENABLED(ARMV8_MULTIENTRY)) { 191 + ret = bcm_cpu_on(dev); 192 + if (ret) 193 + return ret; 194 + } 195 + 196 + return ret; 197 + } 198 + 199 + struct acpi_ops bcm283x_cpu_acpi_ops = { 200 + .fill_ssdt = armv8_cpu_fill_ssdt, 201 + .fill_madt = armv8_cpu_fill_madt, 202 + }; 203 + 204 + U_BOOT_DRIVER(cpu_bcm_drv) = { 205 + .name = "bcm283x_cpu", 206 + .id = UCLASS_CPU, 207 + .of_match = cpu_bcm_ids, 208 + .ops = &cpu_bcm_ops, 209 + .probe = bcm_cpu_probe, 210 + .bind = bcm_cpu_bind, 211 + .of_to_plat = bcm_cpu_of_to_plat, 212 + .plat_auto = sizeof(struct bcm_plat), 213 + ACPI_OPS_PTR(&bcm283x_cpu_acpi_ops) 214 + };
+65 -1
drivers/misc/irq-uclass.c
··· 62 62 return ops->read_and_clear(irq); 63 63 } 64 64 65 + int irq_get_interrupt_parent(const struct udevice *dev, 66 + struct udevice **interrupt_parent) 67 + { 68 + struct ofnode_phandle_args phandle_args; 69 + struct udevice *irq = NULL; 70 + ofnode node; 71 + int ret; 72 + 73 + if (!dev || !interrupt_parent) 74 + return -EINVAL; 75 + 76 + *interrupt_parent = NULL; 77 + 78 + node = dev_ofnode(dev); 79 + if (!ofnode_valid(node)) 80 + return -EINVAL; 81 + 82 + while (ofnode_valid(node)) { 83 + ret = ofnode_parse_phandle_with_args(node, "interrupt-parent", 84 + NULL, 0, 0, &phandle_args); 85 + if (!ret && !device_get_global_by_ofnode(phandle_args.node, &irq)) 86 + break; 87 + node = ofnode_get_parent(node); 88 + } 89 + 90 + if (!irq) { 91 + log_err("Cannot find an interrupt parent for device %s\n", dev->name); 92 + return -ENODEV; 93 + } 94 + *interrupt_parent = irq; 95 + 96 + return 0; 97 + } 98 + 65 99 #if CONFIG_IS_ENABLED(OF_PLATDATA) 66 100 int irq_get_by_phandle(struct udevice *dev, const struct phandle_2_arg *cells, 67 101 struct irq *irq) ··· 142 176 int irq_get_by_index(struct udevice *dev, int index, struct irq *irq) 143 177 { 144 178 struct ofnode_phandle_args args; 145 - int ret; 179 + struct udevice *interrupt_parent; 180 + int ret, size, i; 181 + const __be32 *list; 182 + u32 count; 146 183 147 184 ret = dev_read_phandle_with_args(dev, "interrupts-extended", 148 185 "#interrupt-cells", 0, index, &args); 186 + if (ret) { 187 + list = dev_read_prop(dev, "interrupts", &size); 188 + if (!list) 189 + return -ENOENT; 190 + 191 + ret = irq_get_interrupt_parent(dev, &interrupt_parent); 192 + if (ret) 193 + return -ENODEV; 194 + args.node = dev_ofnode(interrupt_parent); 195 + 196 + if (dev_read_u32(interrupt_parent, "#interrupt-cells", &count)) { 197 + log_err("%s: could not get #interrupt-cells for %s\n", 198 + __func__, dev->name); 199 + return -ENOENT; 200 + } 201 + 202 + if (index * count >= size / sizeof(*list)) 203 + return -ENOENT; 204 + if (count > OF_MAX_PHANDLE_ARGS) 205 + count = OF_MAX_PHANDLE_ARGS; 206 + args.args_count = count; 207 + for (i = 0; i < count; i++) 208 + args.args[i] = be32_to_cpup(&list[index * count + i]); 209 + 210 + return irq_get_by_index_tail(ret, dev_ofnode(dev), &args, 211 + "interrupts", index, irq); 212 + } 149 213 150 214 return irq_get_by_index_tail(ret, dev_ofnode(dev), &args, 151 215 "interrupts-extended", index > 0, irq);
+10 -91
drivers/pci/pcie_brcmstb.c
··· 12 12 * Copyright (C) 2020 Nicolas Saenz Julienne <nsaenzjulienne@suse.de> 13 13 */ 14 14 15 + #include <asm/arch/acpi/bcm2711.h> 15 16 #include <errno.h> 16 17 #include <dm.h> 17 18 #include <dm/ofnode.h> ··· 20 21 #include <linux/bitfield.h> 21 22 #include <linux/log2.h> 22 23 #include <linux/iopoll.h> 23 - 24 - /* Offset of the mandatory PCIe capability config registers */ 25 - #define BRCM_PCIE_CAP_REGS 0x00ac 26 - 27 - /* The PCIe controller register offsets */ 28 - #define PCIE_RC_CFG_VENDOR_SPECIFIC_REG1 0x0188 29 - #define VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_MASK 0xc 30 - #define VENDOR_SPECIFIC_REG1_LITTLE_ENDIAN 0x0 31 - 32 - #define PCIE_RC_CFG_PRIV1_ID_VAL3 0x043c 33 - #define CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK 0xffffff 34 - 35 - #define PCIE_RC_CFG_PRIV1_LINK_CAPABILITY 0x04dc 36 - #define PCIE_RC_CFG_PRIV1_LINK_CAPABILITY_ASPM_SUPPORT_MASK 0xc00 37 - 38 - #define PCIE_RC_DL_MDIO_ADDR 0x1100 39 - #define PCIE_RC_DL_MDIO_WR_DATA 0x1104 40 - #define PCIE_RC_DL_MDIO_RD_DATA 0x1108 41 - 42 - #define PCIE_MISC_MISC_CTRL 0x4008 43 - #define MISC_CTRL_SCB_ACCESS_EN_MASK 0x1000 44 - #define MISC_CTRL_CFG_READ_UR_MODE_MASK 0x2000 45 - #define MISC_CTRL_MAX_BURST_SIZE_MASK 0x300000 46 - #define MISC_CTRL_MAX_BURST_SIZE_128 0x0 47 - #define MISC_CTRL_SCB0_SIZE_MASK 0xf8000000 48 - 49 - #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO 0x400c 50 - #define PCIE_MEM_WIN0_LO(win) \ 51 - PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO + ((win) * 4) 52 - 53 - #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI 0x4010 54 - #define PCIE_MEM_WIN0_HI(win) \ 55 - PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI + ((win) * 4) 56 - 57 - #define PCIE_MISC_RC_BAR1_CONFIG_LO 0x402c 58 - #define RC_BAR1_CONFIG_LO_SIZE_MASK 0x1f 59 - 60 - #define PCIE_MISC_RC_BAR2_CONFIG_LO 0x4034 61 - #define RC_BAR2_CONFIG_LO_SIZE_MASK 0x1f 62 - #define PCIE_MISC_RC_BAR2_CONFIG_HI 0x4038 63 - 64 - #define PCIE_MISC_RC_BAR3_CONFIG_LO 0x403c 65 - #define RC_BAR3_CONFIG_LO_SIZE_MASK 0x1f 66 - 67 - #define PCIE_MISC_PCIE_STATUS 0x4068 68 - #define STATUS_PCIE_PORT_MASK 0x80 69 - #define STATUS_PCIE_PORT_SHIFT 7 70 - #define STATUS_PCIE_DL_ACTIVE_MASK 0x20 71 - #define STATUS_PCIE_DL_ACTIVE_SHIFT 5 72 - #define STATUS_PCIE_PHYLINKUP_MASK 0x10 73 - #define STATUS_PCIE_PHYLINKUP_SHIFT 4 74 - 75 - #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT 0x4070 76 - #define MEM_WIN0_BASE_LIMIT_LIMIT_MASK 0xfff00000 77 - #define MEM_WIN0_BASE_LIMIT_BASE_MASK 0xfff0 78 - #define MEM_WIN0_BASE_LIMIT_BASE_HI_SHIFT 12 79 - #define PCIE_MEM_WIN0_BASE_LIMIT(win) \ 80 - PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT + ((win) * 4) 81 - 82 - #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI 0x4080 83 - #define MEM_WIN0_BASE_HI_BASE_MASK 0xff 84 - #define PCIE_MEM_WIN0_BASE_HI(win) \ 85 - PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI + ((win) * 8) 86 - 87 - #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI 0x4084 88 - #define PCIE_MEM_WIN0_LIMIT_HI_LIMIT_MASK 0xff 89 - #define PCIE_MEM_WIN0_LIMIT_HI(win) \ 90 - PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI + ((win) * 8) 91 - 92 - #define PCIE_MISC_HARD_PCIE_HARD_DEBUG 0x4204 93 - #define PCIE_HARD_DEBUG_SERDES_IDDQ_MASK 0x08000000 94 - 95 - #define PCIE_MSI_INTR2_CLR 0x4508 96 - #define PCIE_MSI_INTR2_MASK_SET 0x4510 97 - 98 - #define PCIE_EXT_CFG_DATA 0x8000 99 - 100 - #define PCIE_EXT_CFG_INDEX 0x9000 101 - 102 - #define PCIE_RGR1_SW_INIT_1 0x9210 103 - #define RGR1_SW_INIT_1_PERST_MASK 0x1 104 - #define RGR1_SW_INIT_1_INIT_MASK 0x2 105 24 106 25 /* PCIe parameters */ 107 26 #define BRCM_NUM_PCIE_OUT_WINS 4 ··· 447 366 * This will need to be changed when support for other SoCs is added. 448 367 */ 449 368 setbits_le32(base + PCIE_RGR1_SW_INIT_1, 450 - RGR1_SW_INIT_1_INIT_MASK | RGR1_SW_INIT_1_PERST_MASK); 369 + PCIE_RGR1_SW_INIT_1_INIT_MASK | PCIE_RGR1_SW_INIT_1_PERST_MASK); 451 370 /* 452 371 * The delay is a safety precaution to preclude the reset signal 453 372 * from looking like a glitch. ··· 455 374 udelay(100); 456 375 457 376 /* Take the bridge out of reset */ 458 - clrbits_le32(base + PCIE_RGR1_SW_INIT_1, RGR1_SW_INIT_1_INIT_MASK); 377 + clrbits_le32(base + PCIE_RGR1_SW_INIT_1, PCIE_RGR1_SW_INIT_1_INIT_MASK); 459 378 460 379 clrbits_le32(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG, 461 380 PCIE_HARD_DEBUG_SERDES_IDDQ_MASK); ··· 508 427 509 428 /* Unassert the fundamental reset */ 510 429 clrbits_le32(pcie->base + PCIE_RGR1_SW_INIT_1, 511 - RGR1_SW_INIT_1_PERST_MASK); 430 + PCIE_RGR1_SW_INIT_1_PERST_MASK); 512 431 513 432 /* 514 433 * Wait for 100ms after PERST# deassertion; see PCIe CEM specification ··· 552 471 * a PCIe-PCIe bridge (the default setting is to be EP mode). 553 472 */ 554 473 clrsetbits_le32(base + PCIE_RC_CFG_PRIV1_ID_VAL3, 555 - CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK, 0x060400); 474 + PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK, 0x060400); 556 475 557 476 if (pcie->ssc) { 558 477 ret = brcm_pcie_set_ssc(pcie->base); ··· 570 489 nlw, ssc_good ? "(SSC)" : "(!SSC)"); 571 490 572 491 /* PCIe->SCB endian mode for BAR */ 573 - clrsetbits_le32(base + PCIE_RC_CFG_VENDOR_SPECIFIC_REG1, 574 - VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_MASK, 492 + clrsetbits_le32(base + PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1, 493 + PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_MASK, 575 494 VENDOR_SPECIFIC_REG1_LITTLE_ENDIAN); 576 495 577 496 /* ··· 584 503 * let's instead just unadvertise ASPM support. 585 504 */ 586 505 clrbits_le32(base + PCIE_RC_CFG_PRIV1_LINK_CAPABILITY, 587 - PCIE_RC_CFG_PRIV1_LINK_CAPABILITY_ASPM_SUPPORT_MASK); 506 + LINK_CAPABILITY_ASPM_SUPPORT_MASK); 588 507 589 508 return 0; 590 509 } ··· 595 514 void __iomem *base = pcie->base; 596 515 597 516 /* Assert fundamental reset */ 598 - setbits_le32(base + PCIE_RGR1_SW_INIT_1, RGR1_SW_INIT_1_PERST_MASK); 517 + setbits_le32(base + PCIE_RGR1_SW_INIT_1, PCIE_RGR1_SW_INIT_1_PERST_MASK); 599 518 600 519 /* Turn off SerDes */ 601 520 setbits_le32(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG, 602 521 PCIE_HARD_DEBUG_SERDES_IDDQ_MASK); 603 522 604 523 /* Shutdown bridge */ 605 - setbits_le32(base + PCIE_RGR1_SW_INIT_1, RGR1_SW_INIT_1_INIT_MASK); 524 + setbits_le32(base + PCIE_RGR1_SW_INIT_1, PCIE_RGR1_SW_INIT_1_INIT_MASK); 606 525 607 526 return 0; 608 527 }
+24
drivers/serial/serial_pl01x.c
··· 19 19 #include <watchdog.h> 20 20 #include <asm/io.h> 21 21 #include <serial.h> 22 + #include <spl.h> 22 23 #include <dm/device_compat.h> 23 24 #include <dm/platform_data/serial_pl01x.h> 24 25 #include <linux/compiler.h> ··· 272 273 return &pl01x_serial_drv; 273 274 } 274 275 #else 276 + 277 + static int pl01x_serial_getinfo(struct udevice *dev, 278 + struct serial_device_info *info) 279 + { 280 + struct pl01x_serial_plat *plat = dev_get_plat(dev); 281 + 282 + /* save code size */ 283 + if (!not_xpl()) 284 + return -ENOSYS; 285 + 286 + info->type = SERIAL_CHIP_PL01X; 287 + info->addr_space = SERIAL_ADDRESS_SPACE_MEMORY; 288 + info->addr = plat->base; 289 + info->size = 0x1000; 290 + info->reg_width = 4; 291 + info->reg_shift = 2; 292 + info->reg_offset = 0; 293 + info->clock = plat->clock; 294 + 295 + return 0; 296 + } 297 + 275 298 int pl01x_serial_setbrg(struct udevice *dev, int baudrate) 276 299 { 277 300 struct pl01x_serial_plat *plat = dev_get_plat(dev); ··· 341 364 .pending = pl01x_serial_pending, 342 365 .getc = pl01x_serial_getc, 343 366 .setbrg = pl01x_serial_setbrg, 367 + .getinfo = pl01x_serial_getinfo, 344 368 }; 345 369 346 370 #if CONFIG_IS_ENABLED(OF_REAL)
+8
drivers/usb/host/Kconfig
··· 68 68 SoCs, which includes Armada8K, Armada3700 and other Armada 69 69 family SoCs. 70 70 71 + config USB_XHCI_GENERIC 72 + bool "Generic SoC USB 3.0 support" 73 + depends on OF_CONTROL 74 + default n 75 + help 76 + Choose this option to add support for USB 3.0 driver for SoCs 77 + that do not need platform specific code, like on emulated targets. 78 + 71 79 config USB_XHCI_OCTEON 72 80 bool "Support for Marvell Octeon family on-chip xHCI USB controller" 73 81 depends on ARCH_OCTEON
+1
drivers/usb/host/Makefile
··· 50 50 obj-$(CONFIG_USB_XHCI_FSL) += xhci-fsl.o 51 51 obj-$(CONFIG_USB_XHCI_MTK) += xhci-mtk.o 52 52 obj-$(CONFIG_USB_XHCI_MVEBU) += xhci-mvebu.o 53 + obj-$(CONFIG_USB_XHCI_GENERIC) += xhci-generic.o 53 54 obj-$(CONFIG_USB_XHCI_OMAP) += xhci-omap.o 54 55 obj-$(CONFIG_USB_XHCI_PCI) += xhci-pci.o 55 56 obj-$(CONFIG_USB_XHCI_RCAR) += xhci-rcar.o
+75
drivers/usb/host/xhci-generic.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Copyright (C) 2024 9elements GmbH 4 + * 5 + * GENERIC USB HOST xHCI Controller 6 + */ 7 + #include <dm.h> 8 + #include <fdtdec.h> 9 + #include <log.h> 10 + #include <usb.h> 11 + #include <asm/io.h> 12 + #include <dm/device_compat.h> 13 + #include <usb/xhci.h> 14 + 15 + struct generic_xhci_plat { 16 + fdt_addr_t hcd_base; 17 + }; 18 + 19 + /** 20 + * Contains pointers to register base addresses 21 + * for the usb controller. 22 + */ 23 + struct generic_xhci { 24 + struct xhci_ctrl ctrl; /* Needs to come first in this struct! */ 25 + struct usb_plat usb_plat; 26 + struct xhci_hccr *hcd; 27 + }; 28 + 29 + static int xhci_usb_probe(struct udevice *dev) 30 + { 31 + struct generic_xhci_plat *plat = dev_get_plat(dev); 32 + struct generic_xhci *ctx = dev_get_priv(dev); 33 + struct xhci_hcor *hcor; 34 + int len; 35 + 36 + ctx->hcd = (struct xhci_hccr *)phys_to_virt(plat->hcd_base); 37 + len = HC_LENGTH(xhci_readl(&ctx->hcd->cr_capbase)); 38 + hcor = (struct xhci_hcor *)((uintptr_t)ctx->hcd + len); 39 + 40 + return xhci_register(dev, ctx->hcd, hcor); 41 + } 42 + 43 + static int xhci_usb_of_to_plat(struct udevice *dev) 44 + { 45 + struct generic_xhci_plat *plat = dev_get_plat(dev); 46 + 47 + /* 48 + * Get the base address for XHCI controller from the device node 49 + */ 50 + plat->hcd_base = dev_read_addr(dev); 51 + if (plat->hcd_base == FDT_ADDR_T_NONE) { 52 + dev_dbg(dev, "Can't get the XHCI register base address\n"); 53 + return -ENXIO; 54 + } 55 + 56 + return 0; 57 + } 58 + 59 + static const struct udevice_id xhci_usb_ids[] = { 60 + { .compatible = "generic-xhci" }, 61 + { } 62 + }; 63 + 64 + U_BOOT_DRIVER(usb_xhci) = { 65 + .name = "xhci_generic", 66 + .id = UCLASS_USB, 67 + .of_match = xhci_usb_ids, 68 + .of_to_plat = xhci_usb_of_to_plat, 69 + .probe = xhci_usb_probe, 70 + .remove = xhci_deregister, 71 + .ops = &xhci_usb_ops, 72 + .plat_auto = sizeof(struct generic_xhci_plat), 73 + .priv_auto = sizeof(struct generic_xhci), 74 + .flags = DM_FLAG_ALLOC_PRIV_DMA, 75 + };
+314 -10
include/acpi/acpi_table.h
··· 290 290 #define ACPI_MADT_REV_ACPI_3_0 2 291 291 #define ACPI_MADT_REV_ACPI_4_0 3 292 292 #define ACPI_MADT_REV_ACPI_5_0 3 293 - #define ACPI_MADT_REV_ACPI_6_0 5 293 + #define ACPI_MADT_REV_ACPI_6_2 4 294 + #define ACPI_MADT_REV_ACPI_6_3 5 294 295 295 296 #define ACPI_MCFG_REV_ACPI_3_0 1 296 297 ··· 342 343 ACPI_APIC_LX2APIC, /* Processor local x2APIC */ 343 344 ACPI_APIC_LX2APIC_NMI, /* Local x2APIC NMI */ 344 345 ACPI_APIC_GICC, /* Generic Interrupt Ctlr CPU i/f */ 345 - ACPI_APIC_GICD /* Generic Interrupt Ctlr Distributor */ 346 + ACPI_APIC_GICD, /* Generic Interrupt Ctlr Distributor */ 347 + ACPI_APIC_MSI_FRAME, /* Generic Interrupt MSI Frame */ 348 + ACPI_APIC_GICR, /* Generic Interrupt Ctlr Redistributor */ 349 + ACPI_APIC_ITS, /* Interrupt Translation Service */ 346 350 }; 347 351 348 352 /* MADT: Processor Local APIC Structure */ ··· 386 390 u8 lint; /* Local APIC LINT# */ 387 391 }; 388 392 389 - /* flags for acpi_madr_gicc flags word */ 393 + /* flags for acpi_madt_gicc flags word */ 390 394 enum { 391 - ACPI_MADRF_ENABLED = BIT(0), 392 - ACPI_MADRF_PERF = BIT(1), 393 - ACPI_MADRF_VGIC = BIT(2), 395 + ACPI_MADTF_ENABLED = BIT(0), 396 + ACPI_MADTF_PERF = BIT(1), 397 + ACPI_MADTF_VGIC = BIT(2), 394 398 }; 395 399 396 400 /** 397 - * struct __packed acpi_madr_gicc - GIC CPU interface (type 0xb) 401 + * struct __packed acpi_madt_gicc - GIC CPU interface (type 0xb) 398 402 * 399 403 * This holds information about the Generic Interrupt Controller (GIC) CPU 400 404 * interface. See ACPI Spec v6.3 section 5.2.12.14 401 405 */ 402 - struct acpi_madr_gicc { 406 + struct acpi_madt_gicc { 403 407 u8 type; 404 408 u8 length; 405 409 u16 reserved; ··· 421 425 } __packed; 422 426 423 427 /** 424 - * struct __packed acpi_madr_gicc - GIC distributor (type 0xc) 428 + * struct __packed acpi_madt_gicc - GIC distributor (type 0xc) 425 429 * 426 430 * This holds information about the Generic Interrupt Controller (GIC) 427 431 * Distributor interface. See ACPI Spec v6.3 section 5.2.12.15 428 432 */ 429 - struct acpi_madr_gicd { 433 + struct acpi_madt_gicd { 430 434 u8 type; 431 435 u8 length; 432 436 u16 reserved; ··· 437 441 u8 reserved3[3]; 438 442 } __packed; 439 443 444 + /** 445 + * struct __packed acpi_madt_gicr - GIC Redistributor (type 0xe) 446 + * 447 + * This holds information about the Generic Interrupt Controller (GIC) 448 + * Redistributor interface. See ACPI Spec v6.3 section 5.2.12.17 449 + */ 450 + struct acpi_madt_gicr { 451 + u8 type; 452 + u8 length; 453 + u16 reserved; 454 + u64 discovery_range_base_address; 455 + u32 discovery_range_length; 456 + } __packed; 457 + 458 + /** 459 + * struct __packed acpi_madt_its - GIC Interrupt Translation Service (type 0xf) 460 + * 461 + * This holds information about the Interrupt Translation Service (ITS) 462 + * Structure. See ACPI Spec v6.3 section 5.2.12.18 463 + */ 464 + struct acpi_madt_its { 465 + u8 type; 466 + u8 length; 467 + u16 reserved; 468 + u32 gic_its_id; 469 + u64 physical_base_address; 470 + u32 reserved2; 471 + } __packed; 472 + 440 473 /* MCFG (PCI Express MMIO config space BAR description table) */ 441 474 struct acpi_mcfg { 442 475 struct acpi_table_header header; ··· 707 740 u32 virt_el2_flags; 708 741 } __packed; 709 742 743 + #define GTDT_FLAG_INT_ACTIVE_LOW BIT(1) 744 + 710 745 /** 711 746 * struct acpi_bgrt - Boot Graphics Resource Table (BGRT) 712 747 * ··· 797 832 u16 line_size; 798 833 } __packed; 799 834 835 + /** IORT - IO Remapping Table revision 6 836 + * Document number: ARM DEN 0049E.e, Sep 2022 837 + */ 838 + struct acpi_table_iort { 839 + struct acpi_table_header header; 840 + u32 node_count; 841 + u32 node_offset; 842 + u32 reserved; 843 + } __packed; 844 + 845 + /* 846 + * IORT subtables 847 + */ 848 + struct acpi_iort_node { 849 + u8 type; 850 + u16 length; 851 + u8 revision; 852 + u32 identifier; 853 + u32 mapping_count; 854 + u32 mapping_offset; 855 + char node_data[]; 856 + } __packed; 857 + 858 + /* Values for subtable Type above */ 859 + enum acpi_iort_node_type { 860 + ACPI_IORT_NODE_ITS_GROUP = 0x00, 861 + ACPI_IORT_NODE_NAMED_COMPONENT = 0x01, 862 + ACPI_IORT_NODE_PCI_ROOT_COMPLEX = 0x02, 863 + ACPI_IORT_NODE_SMMU = 0x03, 864 + ACPI_IORT_NODE_SMMU_V3 = 0x04, 865 + ACPI_IORT_NODE_PMCG = 0x05, 866 + ACPI_IORT_NODE_RMR = 0x06, 867 + }; 868 + 869 + /* ITS Group revision 1 */ 870 + struct acpi_iort_its_group { 871 + u32 its_count; 872 + u32 identifiers[]; /* GIC ITS identifier array */ 873 + } __packed; 874 + 875 + /* PCI root complex node revision 2 */ 876 + struct acpi_iort_rc { 877 + u64 mem_access_properties; 878 + u32 ats_attributes; 879 + u32 pci_segment_number; 880 + u8 memory_address_size_limit; 881 + u8 reserved[3]; 882 + } __packed; 883 + 884 + /* SMMUv3 revision 5 */ 885 + struct acpi_iort_smmu_v3 { 886 + u64 base_address; /* SMMUv3 base address */ 887 + u32 flags; 888 + u32 reserved; 889 + u64 vatos_address; 890 + u32 model; 891 + u32 event_gsiv; 892 + u32 pri_gsiv; 893 + u32 gerr_gsiv; 894 + u32 sync_gsiv; 895 + u32 pxm; 896 + u32 id_mapping_index; 897 + } __packed; 898 + 899 + /* Masks for Flags field above */ 900 + #define ACPI_IORT_SMMU_V3_COHACC_OVERRIDE (1) 901 + #define ACPI_IORT_SMMU_V3_HTTU_OVERRIDE (3 << 1) 902 + #define ACPI_IORT_SMMU_V3_PXM_VALID (1 << 3) 903 + #define ACPI_IORT_SMMU_V3_DEVICEID_VALID (1 << 4) 904 + 905 + struct acpi_iort_id_mapping { 906 + u32 input_base; /* Lowest value in input range */ 907 + u32 id_count; /* Number of IDs */ 908 + u32 output_base; /* Lowest value in output range */ 909 + u32 output_reference; /* A reference to the output node */ 910 + u32 flags; 911 + } __packed; 912 + 913 + /* Masks for Flags field above for IORT subtable */ 914 + #define ACPI_IORT_ID_SINGLE_MAPPING (1) 915 + 916 + /* Named Component revision 4 */ 917 + struct acpi_iort_named_component { 918 + u32 node_flags; 919 + u64 memory_properties; /* Memory access properties */ 920 + u8 memory_address_limit; /* Memory address size limit */ 921 + char device_name[]; /* Path of namespace object */ 922 + } __packed; 923 + 924 + /* Masks for Flags field above */ 925 + #define ACPI_IORT_NC_STALL_SUPPORTED (1) 926 + #define ACPI_IORT_NC_PASID_BITS (31 << 1) 927 + 928 + struct acpi_iort_root_complex { 929 + u64 memory_properties; /* Memory access properties */ 930 + u32 ats_attribute; 931 + u32 pci_segment_number; 932 + u8 memory_address_limit;/* Memory address size limit */ 933 + u16 pasid_capabilities; /* PASID Capabilities */ 934 + u8 reserved; /* Reserved, must be zero */ 935 + u32 flags; /* Flags */ 936 + } __packed; 937 + 938 + /* Masks for ats_attribute field above */ 939 + #define ACPI_IORT_ATS_SUPPORTED (1) /* The root complex ATS support */ 940 + #define ACPI_IORT_PRI_SUPPORTED (1 << 1) /* The root complex PRI support */ 941 + #define ACPI_IORT_PASID_FWD_SUPPORTED (1 << 2) /* The root complex PASID forward support */ 942 + 943 + /* Masks for pasid_capabilities field above */ 944 + #define ACPI_IORT_PASID_MAX_WIDTH (0x1F) /* Bits 0-4 */ 945 + 800 946 /* Tables defined/reserved by ACPI and generated by U-Boot */ 801 947 enum acpi_tables { 802 948 ACPITAB_BERT, ··· 806 952 ACPITAB_ECDT, 807 953 ACPITAB_FACS, 808 954 ACPITAB_FADT, 955 + ACPITAB_GTDT, 809 956 ACPITAB_HEST, 810 957 ACPITAB_HPET, 811 958 ACPITAB_IVRS, 812 959 ACPITAB_MADT, 813 960 ACPITAB_MCFG, 814 961 ACPITAB_NHLT, 962 + ACPITAB_PPTT, 815 963 ACPITAB_RSDP, 816 964 ACPITAB_RSDT, 817 965 ACPITAB_SLIT, ··· 845 993 * Return: 0 if OK, -ve on error 846 994 */ 847 995 int acpi_create_dmar(struct acpi_dmar *dmar, enum dmar_flags flags); 996 + 997 + /** 998 + * acpi_create_mcfg_mmconfig() - Create a MCFG table entry 999 + * 1000 + * @mmconfig: Place to put the table 1001 + * @base: Base address of the ECAM space 1002 + * @seg_nr: PCI segment number 1003 + * @start: PCI bus start number 1004 + * @end: PCI bus end number 1005 + * Return: size of data written in bytes 1006 + */ 1007 + int acpi_create_mcfg_mmconfig(struct acpi_mcfg_mmconfig *mmconfig, u32 base, 1008 + u16 seg_nr, u8 start, u8 end); 848 1009 849 1010 /** 850 1011 * acpi_create_dbg2() - Create a DBG2 table ··· 914 1075 } 915 1076 916 1077 /** 1078 + * acpi_write_dbg2_pci_uart() - Write out a DBG2 table 1079 + * 1080 + * @ctx: Current ACPI context 1081 + * @dev: Debug UART device to describe 1082 + * @access_size: Access size for UART (e.g. ACPI_ACCESS_SIZE_DWORD_ACCESS) 1083 + * Return: 0 if OK, -ve on error 1084 + */ 1085 + int acpi_write_dbg2_pci_uart(struct acpi_ctx *ctx, struct udevice *dev, 1086 + uint access_size); 1087 + 1088 + /** 917 1089 * acpi_write_rsdp() - Write out an RSDP indicating where the ACPI tables are 918 1090 * 919 1091 * @rsdp: Address to write RSDP ··· 942 1114 * @return 0 if OK, -ve on error 943 1115 */ 944 1116 int acpi_fill_csrt(struct acpi_ctx *ctx); 1117 + 1118 + /** 1119 + * acpi_fill_fadt() - Fill out the body of the FADT 1120 + * 1121 + * Must be implemented in SoC specific code or in mainboard code. 1122 + * 1123 + * @fadt: Pointer to FADT to update 1124 + */ 1125 + void acpi_fill_fadt(struct acpi_fadt *fadt); 1126 + 1127 + /** 1128 + * acpi_fill_iort() - Fill out the body of the IORT table 1129 + * 1130 + * Should be implemented in SoC specific code. 1131 + * 1132 + * @ctx: ACPI context to write to 1133 + * @offset: Offset from the start of the IORT 1134 + */ 1135 + int acpi_fill_iort(struct acpi_ctx *ctx); 1136 + 1137 + /** 1138 + * acpi_iort_add_its_group() - Add ITS group node to IORT table 1139 + * 1140 + * Called by SoC specific code within acpi_fill_iort(). 1141 + * 1142 + * @ctx: ACPI context to write to 1143 + * @its_count: Elements in identifiers 1144 + * @identifiers: The array of ITS identifiers. These IDs must match the value 1145 + * used in the Multiple APIC Description Table (MADT) GIC ITS 1146 + * structure for each relevant ITS unit. 1147 + * @return Offset of table within parent 1148 + */ 1149 + int acpi_iort_add_its_group(struct acpi_ctx *ctx, 1150 + const u32 its_count, 1151 + const u32 *identifiers); 1152 + 1153 + /** 1154 + * acpi_iort_add_named_component() - Add named component to IORT table 1155 + * 1156 + * Called by SoC specific code within acpi_fill_iort(). 1157 + * 1158 + * @ctx: ACPI context to write to 1159 + * @node_flags: Node flags 1160 + * @memory_properties: Memory properties 1161 + * @memory_address_limit: Memory address limit 1162 + * @device_name: ACPI device path 1163 + * @return Offset of table within parent 1164 + */ 1165 + int acpi_iort_add_named_component(struct acpi_ctx *ctx, 1166 + const u32 node_flags, 1167 + const u64 memory_properties, 1168 + const u8 memory_address_limit, 1169 + const char *device_name); 1170 + 1171 + /** 1172 + * acpi_iort_add_rc() - Add PCI root complex node to IORT table 1173 + * 1174 + * Called by SoC specific code within acpi_fill_iort(). 1175 + * 1176 + * @ctx: ACPI context to write to 1177 + * @mem_access_properties: Memory access properties 1178 + * @ats_attributes: Support for ATS and its ancillary feature 1179 + * @pci_segment_number: The PCI segment number, as in MCFG 1180 + * @memory_address_size_limit: The number of address bits, starting from LSB 1181 + * @num_mappings: Number of elements in map 1182 + * @map: ID mappings for this node 1183 + * @return Offset of table within parent 1184 + */ 1185 + int acpi_iort_add_rc(struct acpi_ctx *ctx, 1186 + const u64 mem_access_properties, 1187 + const u32 ats_attributes, 1188 + const u32 pci_segment_number, 1189 + const u8 memory_address_size_limit, 1190 + const int num_mappings, 1191 + const struct acpi_iort_id_mapping *map); 1192 + 1193 + /** 1194 + * acpi_iort_add_smmu_v3() - Add PCI root complex node to IORT table 1195 + * 1196 + * Called by SoC specific code within acpi_fill_iort(). 1197 + * 1198 + * @ctx: ACPI context to write to 1199 + * @base_address: Base address of SMMU 1200 + * @flags: SMMUv3 flags 1201 + * @vatos_address: Optional, set to zero if not supported 1202 + * @model: Model ID 1203 + * @event_gsiv: GSIV of the Event interrupt if SPI based 1204 + * @pri_gsiv: GSIV of the PRI interrupt if SPI based 1205 + * @gerr_gsiv: GSIV of the GERR interrupt if GSIV based 1206 + * @sync_gsiv: TGSIV of the Sync interrupt if GSIV based 1207 + * @pxm: Proximity Domain 1208 + * @id_mapping_index: If all the SMMU control interrupts are GSIV based, 1209 + * this field is ignored. Index into the array of ID 1210 + * mapping otherwise. 1211 + * @num_mappings: Number of elements in map 1212 + * @map: ID mappings for this node 1213 + * @return Offset of table within parent 1214 + */ 1215 + int acpi_iort_add_smmu_v3(struct acpi_ctx *ctx, 1216 + const u64 base_address, 1217 + const u32 flags, 1218 + const u64 vatos_address, 1219 + const u32 model, 1220 + const u32 event_gsiv, 1221 + const u32 pri_gsiv, 1222 + const u32 gerr_gsiv, 1223 + const u32 sync_gsiv, 1224 + const u32 pxm, 1225 + const u32 id_mapping_index, 1226 + const int num_mappings, 1227 + const struct acpi_iort_id_mapping *map); 1228 + 1229 + /** 1230 + * acpi_fill_madt() - Fill out the body of the MADT 1231 + * 1232 + * Must be implemented in SoC specific code. 1233 + * 1234 + * @madt: The MADT to update 1235 + * @ctx: ACPI context to write MADT sub-tables to 1236 + * @return Pointer to the end of tables, where the next tables can be written 1237 + */ 1238 + void *acpi_fill_madt(struct acpi_madt *madt, struct acpi_ctx *ctx); 1239 + 1240 + /** 1241 + * acpi_write_park() - Installs the ACPI parking protocol. 1242 + * 1243 + * Sets up the ACPI parking protocol and installs the spinning code for 1244 + * secondary CPUs. 1245 + * 1246 + * @madt: The MADT to update 1247 + */ 1248 + void acpi_write_park(struct acpi_madt *madt); 945 1249 946 1250 /** 947 1251 * acpi_get_rsdp_addr() - get ACPI RSDP table address
+12
include/acpi/acpigen.h
··· 833 833 * 834 834 * This emits a Processor package header with the required information. The 835 835 * caller must complete the information and call acpigen_pop_len() at the end 836 + * Deprecated since ACPI 6.0. 836 837 * 837 838 * @ctx: ACPI context pointer 838 839 * @cpuindex: CPU number ··· 841 842 */ 842 843 void acpigen_write_processor(struct acpi_ctx *ctx, uint cpuindex, 843 844 u32 pblock_addr, uint pblock_len); 845 + 846 + /** 847 + * acpigen_write_processor_device() - Write a Processor device 848 + * 849 + * Write a device with _HID ACPI0007 identifying a processor. 850 + * Replacement for the Processor OpCode. 851 + * 852 + * @ctx: ACPI context pointer 853 + * @cpuindex: CPU number 854 + */ 855 + void acpigen_write_processor_device(struct acpi_ctx *ctx, uint cpuindex); 844 856 845 857 /** 846 858 * acpigen_write_processor_package() - Write a package containing the processors
+1
include/bloblist.h
··· 110 110 BLOBLISTT_ACPI_TABLES = 4, 111 111 BLOBLISTT_TPM_EVLOG = 5, 112 112 BLOBLISTT_TPM_CRB_BASE = 6, 113 + BLOBLISTT_ACPI_PP = 7, 113 114 114 115 /* Standard area to allocate blobs used across firmware components */ 115 116 BLOBLISTT_AREA_FIRMWARE = 0x10,
+89
include/configs/qemu-sbsa.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + /* 3 + * Copyright (c) 2024 9elements GmbH 4 + */ 5 + 6 + #ifndef __CONFIG_H 7 + #define __CONFIG_H 8 + 9 + /* Physical memory map */ 10 + 11 + /* SECURE_FLASH */ 12 + #define SBSA_SECURE_FLASH_BASE_ADDR 0x00000000 13 + #define SBSA_SECURE_FLASH_LENGTH 0x10000000 14 + 15 + /* FLASH */ 16 + #define SBSA_FLASH_BASE_ADDR 0x10000000 17 + #define SBSA_FLASH_LENGTH 0x10000000 18 + 19 + /* PERIPH */ 20 + #define SBSA_PERIPH_BASE_ADDR 0x40000000 21 + 22 + /* GIC_DIST */ 23 + #define SBSA_GIC_DIST_BASE_ADDR 0x40060000 24 + #define SBSA_GIC_DIST_LENGTH 0x00020000 25 + 26 + #define SBSA_GIC_VBASE_ADDR 0x2c020000 27 + #define SBSA_GIC_VBASE_LENGTH 0x00010000 28 + 29 + #define SBSA_GIC_HBASE_ADDR 0x2c010000 30 + #define SBSA_GIC_HBASE_LENGTH 0x00010000 31 + 32 + /* GIC_REDIST */ 33 + #define SBSA_GIC_REDIST_BASE_ADDR 0x40080000 34 + #define SBSA_GIC_REDIST_LENGTH 0x04000000 35 + 36 + /* GIC_ITS */ 37 + #define SBSA_GIC_ITS_BASE_ADDR 0x44081000 38 + 39 + /* UART */ 40 + #define SBSA_UART_BASE_ADDR 0x60000000 41 + #define SBSA_UART_LENGTH 0x00001000 42 + 43 + /* SMMU */ 44 + #define SBSA_SMMU_BASE_ADDR 0x60050000 45 + 46 + /* SATA */ 47 + #define SBSA_AHCI_BASE_ADDR 0x60100000 48 + #define SBSA_AHCI_LENGTH 0x00010000 49 + 50 + /* xHCI */ 51 + #define SBSA_XHCI_BASE_ADDR 0x60110000 52 + #define SBSA_XHCI_LENGTH 0x00010000 53 + 54 + /* PIO */ 55 + #define SBSA_PIO_BASE_ADDR 0x7fff0000 56 + #define SBSA_PIO_LENGTH 0x00010000 57 + 58 + /* PCIE_MMIO */ 59 + #define SBSA_PCIE_MMIO_BASE_ADDR 0x80000000 60 + #define SBSA_PCIE_MMIO_LENGTH 0x70000000 61 + #define SBSA_PCIE_MMIO_END 0xefffffff 62 + 63 + /* PCIE_ECAM */ 64 + #define SBSA_PCIE_ECAM_BASE_ADDR 0xf0000000 65 + #define SBSA_PCIE_ECAM_LENGTH 0x10000000 66 + #define SBSA_PCIE_ECAM_END 0xffffffff 67 + 68 + /* PCIE_MMIO_HIGH */ 69 + #ifdef __ACPI__ 70 + #define SBSA_PCIE_MMIO_HIGH_BASE_ADDR 0x100000000 71 + #define SBSA_PCIE_MMIO_HIGH_LENGTH 0xFF00000000 72 + #define SBSA_PCIE_MMIO_HIGH_END 0xFFFFFFFFFF 73 + #else 74 + #define SBSA_PCIE_MMIO_HIGH_BASE_ADDR 0x100000000ULL 75 + #define SBSA_PCIE_MMIO_HIGH_LENGTH 0xFF00000000ULL 76 + #define SBSA_PCIE_MMIO_HIGH_END 0xFFFFFFFFFFULL 77 + #endif 78 + 79 + /* MEM */ 80 + #ifdef __ACPI__ 81 + #define SBSA_MEM_BASE_ADDR 0x10000000000 82 + #else 83 + #define SBSA_MEM_BASE_ADDR 0x10000000000ULL 84 + #endif 85 + 86 + #define CFG_SYS_INIT_RAM_ADDR SBSA_MEM_BASE_ADDR 87 + #define CFG_SYS_INIT_RAM_SIZE 0x1000000 88 + 89 + #endif /* __CONFIG_H */
+26
include/dm/acpi.h
··· 147 147 int (*write_tables)(const struct udevice *dev, struct acpi_ctx *ctx); 148 148 149 149 /** 150 + * fill_madt() - Generate MADT sub-tables for a device 151 + * 152 + * This is called to create the MADT table. The method should write out 153 + * whatever sub-table is needed by this device. It will end up in the 154 + * MADT table. 155 + * 156 + * Note that this is called 'fill' because the entire contents of the 157 + * MADT is build by calling this method on all devices. 158 + * 159 + * @dev: Device to write 160 + * @ctx: ACPI context to use 161 + * @return 0 if OK, -ve on error 162 + */ 163 + int (*fill_madt)(const struct udevice *dev, struct acpi_ctx *ctx); 164 + 165 + /** 150 166 * fill_ssdt() - Generate SSDT code for a device 151 167 * 152 168 * This is called to create the SSDT code. The method should write out ··· 230 246 * Return: 0 if OK, -ve if any device returned an error 231 247 */ 232 248 int acpi_write_dev_tables(struct acpi_ctx *ctx); 249 + 250 + /** 251 + * acpi_fill_madt_subtbl() - Generate ACPI tables for MADT 252 + * 253 + * This is called to create the MADT sub-tables for all devices. 254 + * 255 + * @ctx: ACPI context to use 256 + * Return: 0 if OK, -ve on error 257 + */ 258 + int acpi_fill_madt_subtbl(struct acpi_ctx *ctx); 233 259 234 260 /** 235 261 * acpi_fill_ssdt() - Generate ACPI tables for SSDT
+14
include/irq.h
··· 200 200 */ 201 201 int irq_read_and_clear(struct irq *irq); 202 202 203 + /** 204 + * irq_get_interrupt_parent() - returns the interrupt parent 205 + * 206 + * Walks the devicetree and returns the interrupt parent's ofnode 207 + * for the specified device. 208 + * 209 + * @dev: device 210 + * @interrupt_parent: The interrupt parent's ofnode' 211 + * Return: 0 success, or error value 212 + * 213 + */ 214 + int irq_get_interrupt_parent(const struct udevice *dev, 215 + struct udevice **interrupt_parent); 216 + 203 217 struct phandle_2_arg; 204 218 /** 205 219 * irq_get_by_phandle() - Get an irq by its phandle information (of-platadata)
+1
include/serial.h
··· 124 124 enum serial_chip_type { 125 125 SERIAL_CHIP_UNKNOWN = -1, 126 126 SERIAL_CHIP_16550_COMPATIBLE, 127 + SERIAL_CHIP_PL01X, 127 128 }; 128 129 129 130 enum adr_space_type {
+24 -5
lib/Kconfig
··· 315 315 by the operating system. It defines platform-independent interfaces 316 316 for configuration and power management monitoring. 317 317 318 + config ACPI_PARKING_PROTOCOL 319 + bool "Support ACPI parking protocol method" 320 + depends on GENERATE_ACPI_TABLE 321 + depends on ARMV8_MULTIENTRY 322 + depends on BLOBLIST_TABLES 323 + default y if !SEC_FIRMWARE_ARMV8_PSCI && !ARMV8_PSCI 324 + help 325 + Say Y here to support "ACPI parking protocol" enable method 326 + for booting Linux. 327 + 328 + To use this feature, you must do: 329 + - Bring secondary CPUs into U-Boot proper in a board-specific 330 + manner. This must be done *after* relocation. Otherwise, the 331 + secondary CPUs will spin in unprotected memory-area because the 332 + master CPU protects the relocated spin code. 333 + 318 334 config SPL_TINY_MEMSET 319 335 bool "Use a very small memset() in SPL" 320 336 depends on SPL ··· 988 1004 989 1005 config BLOBLIST_TABLES 990 1006 bool "Put tables in a bloblist" 991 - depends on X86 && BLOBLIST 1007 + depends on BLOBLIST 1008 + default y if (ARM && EFI_LOADER && GENERATE_ACPI_TABLE) 1009 + default n 992 1010 help 993 - Normally tables are placed at address 0xf0000 and can be up to 64KB 994 - long. With this option, tables are instead placed in the bloblist 995 - with a pointer from 0xf0000. The size can then be larger and the 996 - tables can be placed high in memory. 1011 + On x86 normally tables are placed at address 0xf0000 and can be up 1012 + to 64KB long. With this option, tables are instead placed in the 1013 + bloblist with a pointer from 0xf0000. The size can then be larger 1014 + and the tables can be placed high in memory. 1015 + On other architectures the tables are always placed in high memory. 997 1016 998 1017 config GENERATE_SMBIOS_TABLE 999 1018 bool "Generate an SMBIOS (System Management BIOS) table"
+594 -36
lib/acpi/acpi_table.c
··· 5 5 * Copyright 2019 Google LLC 6 6 */ 7 7 8 + #include <bloblist.h> 9 + #include <cpu.h> 8 10 #include <dm.h> 9 - #include <cpu.h> 11 + #include <efi_api.h> 12 + #include <efi_loader.h> 10 13 #include <log.h> 11 14 #include <mapmem.h> 12 15 #include <tables_csum.h> 16 + #include <serial.h> 13 17 #include <version_string.h> 14 18 #include <acpi/acpi_table.h> 19 + #include <acpi/acpi_device.h> 15 20 #include <asm/global_data.h> 16 21 #include <dm/acpi.h> 22 + #include <linux/sizes.h> 23 + #include <linux/log2.h> 24 + 25 + enum { 26 + TABLE_SIZE = SZ_64K, 27 + }; 28 + 29 + DECLARE_GLOBAL_DATA_PTR; 17 30 18 31 /* 19 32 * OEM_REVISION is 32-bit unsigned number. It should be increased only when ··· 61 74 { 62 75 switch (table) { 63 76 case ACPITAB_FADT: 64 - return ACPI_FADT_REV_ACPI_3_0; 77 + return ACPI_FADT_REV_ACPI_6_0; 65 78 case ACPITAB_MADT: 66 - return ACPI_MADT_REV_ACPI_3_0; 79 + return ACPI_MADT_REV_ACPI_6_2; 67 80 case ACPITAB_MCFG: 68 81 return ACPI_MCFG_REV_ACPI_3_0; 69 82 case ACPITAB_TCPA: ··· 105 118 return 1; 106 119 case ACPITAB_SPCR: 107 120 return 2; 121 + case ACPITAB_PPTT: /* ACPI 6.2: 1 */ 122 + return 1; 123 + case ACPITAB_GTDT: /* ACPI 6.2: 2, ACPI 6.3: 3 */ 124 + return 2; 108 125 default: 109 126 return -EINVAL; 110 127 } ··· 151 168 struct acpi_rsdt *rsdt; 152 169 struct acpi_xsdt *xsdt; 153 170 154 - /* The RSDT is mandatory while the XSDT is not */ 155 - rsdt = ctx->rsdt; 171 + /* On legacy x86 platforms the RSDT is mandatory while the XSDT is not. 172 + * On other platforms there might be no memory below 4GiB, thus RSDT is NULL. 173 + */ 174 + if (ctx->rsdt) { 175 + rsdt = ctx->rsdt; 176 + 177 + /* This should always be MAX_ACPI_TABLES */ 178 + entries_num = ARRAY_SIZE(rsdt->entry); 179 + 180 + for (i = 0; i < entries_num; i++) { 181 + if (rsdt->entry[i] == 0) 182 + break; 183 + } 184 + 185 + if (i >= entries_num) { 186 + log_err("ACPI: Error: too many tables\n"); 187 + return -E2BIG; 188 + } 156 189 157 - /* This should always be MAX_ACPI_TABLES */ 158 - entries_num = ARRAY_SIZE(rsdt->entry); 190 + /* Add table to the RSDT */ 191 + rsdt->entry[i] = nomap_to_sysmem(table); 159 192 160 - for (i = 0; i < entries_num; i++) { 161 - if (rsdt->entry[i] == 0) 162 - break; 193 + /* Fix RSDT length or the kernel will assume invalid entries */ 194 + rsdt->header.length = sizeof(struct acpi_table_header) + 195 + (sizeof(u32) * (i + 1)); 196 + 197 + /* Re-calculate checksum */ 198 + rsdt->header.checksum = 0; 199 + rsdt->header.checksum = table_compute_checksum((u8 *)rsdt, 200 + rsdt->header.length); 163 201 } 164 202 165 - if (i >= entries_num) { 166 - log_err("ACPI: Error: too many tables\n"); 167 - return -E2BIG; 203 + if (ctx->xsdt) { 204 + /* 205 + * And now the same thing for the XSDT. We use the same index as for 206 + * now we want the XSDT and RSDT to always be in sync in U-Boot 207 + */ 208 + xsdt = ctx->xsdt; 209 + 210 + /* This should always be MAX_ACPI_TABLES */ 211 + entries_num = ARRAY_SIZE(xsdt->entry); 212 + 213 + for (i = 0; i < entries_num; i++) { 214 + if (xsdt->entry[i] == 0) 215 + break; 216 + } 217 + 218 + if (i >= entries_num) { 219 + log_err("ACPI: Error: too many tables\n"); 220 + return -E2BIG; 221 + } 222 + 223 + /* Add table to the XSDT */ 224 + xsdt->entry[i] = nomap_to_sysmem(table); 225 + 226 + /* Fix XSDT length */ 227 + xsdt->header.length = sizeof(struct acpi_table_header) + 228 + (sizeof(u64) * (i + 1)); 229 + 230 + /* Re-calculate checksum */ 231 + xsdt->header.checksum = 0; 232 + xsdt->header.checksum = table_compute_checksum((u8 *)xsdt, 233 + xsdt->header.length); 168 234 } 169 235 170 - /* Add table to the RSDT */ 171 - rsdt->entry[i] = nomap_to_sysmem(table); 236 + return 0; 237 + } 238 + 239 + int acpi_write_fadt(struct acpi_ctx *ctx, const struct acpi_writer *entry) 240 + { 241 + struct acpi_table_header *header; 242 + struct acpi_fadt *fadt; 243 + 244 + fadt = ctx->current; 245 + header = &fadt->header; 246 + 247 + memset((void *)fadt, '\0', sizeof(struct acpi_fadt)); 248 + 249 + acpi_fill_header(header, "FACP"); 250 + header->length = sizeof(struct acpi_fadt); 251 + header->revision = acpi_get_table_revision(ACPITAB_FADT); 252 + memcpy(header->oem_id, OEM_ID, 6); 253 + memcpy(header->oem_table_id, OEM_TABLE_ID, 8); 254 + memcpy(header->creator_id, ASLC_ID, 4); 255 + header->creator_revision = 1; 256 + fadt->minor_revision = 2; 257 + 258 + fadt->x_firmware_ctrl = map_to_sysmem(ctx->facs); 259 + fadt->x_dsdt = map_to_sysmem(ctx->dsdt); 260 + 261 + if (fadt->x_firmware_ctrl < 0x100000000ULL) 262 + fadt->firmware_ctrl = fadt->x_firmware_ctrl; 263 + 264 + if (fadt->x_dsdt < 0x100000000ULL) 265 + fadt->dsdt = fadt->x_dsdt; 266 + 267 + fadt->preferred_pm_profile = ACPI_PM_UNSPECIFIED; 268 + 269 + acpi_fill_fadt(fadt); 270 + 271 + header->checksum = table_compute_checksum(fadt, header->length); 272 + 273 + return acpi_add_fadt(ctx, fadt); 274 + } 275 + 276 + ACPI_WRITER(5fadt, "FADT", acpi_write_fadt, 0); 277 + 278 + int acpi_write_madt(struct acpi_ctx *ctx, const struct acpi_writer *entry) 279 + { 280 + struct acpi_table_header *header; 281 + struct acpi_madt *madt; 282 + void *current; 172 283 173 - /* Fix RSDT length or the kernel will assume invalid entries */ 174 - rsdt->header.length = sizeof(struct acpi_table_header) + 175 - (sizeof(u32) * (i + 1)); 284 + madt = ctx->current; 176 285 177 - /* Re-calculate checksum */ 178 - rsdt->header.checksum = 0; 179 - rsdt->header.checksum = table_compute_checksum((u8 *)rsdt, 180 - rsdt->header.length); 286 + memset(madt, '\0', sizeof(struct acpi_madt)); 287 + header = &madt->header; 288 + 289 + /* Fill out header fields */ 290 + acpi_fill_header(header, "APIC"); 291 + header->length = sizeof(struct acpi_madt); 292 + header->revision = acpi_get_table_revision(ACPITAB_MADT); 181 293 182 - /* 183 - * And now the same thing for the XSDT. We use the same index as for 184 - * now we want the XSDT and RSDT to always be in sync in U-Boot 185 - */ 186 - xsdt = ctx->xsdt; 294 + acpi_inc(ctx, sizeof(struct acpi_madt)); 295 + /* TODO: Get rid of acpi_fill_madt and use driver model */ 296 + current = acpi_fill_madt(madt, ctx); 187 297 188 - /* Add table to the XSDT */ 189 - xsdt->entry[i] = nomap_to_sysmem(table); 298 + /* (Re)calculate length and checksum */ 299 + header->length = (uintptr_t)current - (uintptr_t)madt; 190 300 191 - /* Fix XSDT length */ 192 - xsdt->header.length = sizeof(struct acpi_table_header) + 193 - (sizeof(u64) * (i + 1)); 301 + if (IS_ENABLED(CONFIG_ACPI_PARKING_PROTOCOL)) 302 + acpi_write_park(madt); 194 303 195 - /* Re-calculate checksum */ 196 - xsdt->header.checksum = 0; 197 - xsdt->header.checksum = table_compute_checksum((u8 *)xsdt, 198 - xsdt->header.length); 304 + header->checksum = table_compute_checksum((void *)madt, header->length); 305 + acpi_add_table(ctx, madt); 306 + ctx->current = (void *)madt + madt->header.length; 199 307 200 308 return 0; 201 309 } 310 + 311 + ACPI_WRITER(5madt, "MADT", acpi_write_madt, 0); 202 312 203 313 void acpi_create_dbg2(struct acpi_dbg2_header *dbg2, 204 314 int port_type, int port_subtype, ··· 262 372 header->length = current - (uintptr_t)dbg2; 263 373 header->checksum = table_compute_checksum(dbg2, header->length); 264 374 } 375 + 376 + int acpi_write_dbg2_pci_uart(struct acpi_ctx *ctx, struct udevice *dev, 377 + uint access_size) 378 + { 379 + struct acpi_dbg2_header *dbg2 = ctx->current; 380 + char path[ACPI_PATH_MAX]; 381 + struct acpi_gen_regaddr address; 382 + u64 addr; 383 + int ret; 384 + 385 + if (!device_active(dev)) { 386 + log_info("Device not enabled\n"); 387 + return -EACCES; 388 + } 389 + /* 390 + * PCI devices don't remember their resource allocation information in 391 + * U-Boot at present. We assume that MMIO is used for the UART and that 392 + * the address space is 32 bytes: ns16550 uses 8 registers of up to 393 + * 32-bits each. This is only for debugging so it is not a big deal. 394 + */ 395 + addr = dm_pci_read_bar32(dev, 0); 396 + log_debug("UART addr %lx\n", (ulong)addr); 397 + 398 + ret = acpi_device_path(dev, path, sizeof(path)); 399 + if (ret) 400 + return log_msg_ret("path", ret); 401 + 402 + memset(&address, '\0', sizeof(address)); 403 + address.space_id = ACPI_ADDRESS_SPACE_MEMORY; 404 + address.addrl = (uint32_t)addr; 405 + address.addrh = (uint32_t)((addr >> 32) & 0xffffffff); 406 + address.access_size = access_size; 407 + 408 + ret = acpi_device_path(dev, path, sizeof(path)); 409 + if (ret) 410 + return log_msg_ret("path", ret); 411 + acpi_create_dbg2(dbg2, ACPI_DBG2_SERIAL_PORT, 412 + ACPI_DBG2_16550_COMPATIBLE, &address, 0x1000, path); 413 + 414 + acpi_inc_align(ctx, dbg2->header.length); 415 + acpi_add_table(ctx, dbg2); 416 + 417 + return 0; 418 + } 419 + 420 + static int acpi_write_spcr(struct acpi_ctx *ctx, const struct acpi_writer *entry) 421 + { 422 + struct serial_device_info serial_info = {0}; 423 + ulong serial_address, serial_offset; 424 + struct acpi_table_header *header; 425 + struct acpi_spcr *spcr; 426 + struct udevice *dev; 427 + uint serial_config; 428 + uint serial_width; 429 + int access_size; 430 + int space_id; 431 + int ret = -ENODEV; 432 + 433 + spcr = ctx->current; 434 + header = &spcr->header; 435 + 436 + memset(spcr, '\0', sizeof(struct acpi_spcr)); 437 + 438 + /* Fill out header fields */ 439 + acpi_fill_header(header, "SPCR"); 440 + header->length = sizeof(struct acpi_spcr); 441 + header->revision = 2; 442 + 443 + /* Read the device once, here. It is reused below */ 444 + dev = gd->cur_serial_dev; 445 + if (dev) 446 + ret = serial_getinfo(dev, &serial_info); 447 + if (ret) 448 + serial_info.type = SERIAL_CHIP_UNKNOWN; 449 + 450 + /* Encode chip type */ 451 + switch (serial_info.type) { 452 + case SERIAL_CHIP_16550_COMPATIBLE: 453 + spcr->interface_type = ACPI_DBG2_16550_COMPATIBLE; 454 + break; 455 + case SERIAL_CHIP_PL01X: 456 + spcr->interface_type = ACPI_DBG2_ARM_PL011; 457 + break; 458 + case SERIAL_CHIP_UNKNOWN: 459 + default: 460 + spcr->interface_type = ACPI_DBG2_UNKNOWN; 461 + break; 462 + } 463 + 464 + /* Encode address space */ 465 + switch (serial_info.addr_space) { 466 + case SERIAL_ADDRESS_SPACE_MEMORY: 467 + space_id = ACPI_ADDRESS_SPACE_MEMORY; 468 + break; 469 + case SERIAL_ADDRESS_SPACE_IO: 470 + default: 471 + space_id = ACPI_ADDRESS_SPACE_IO; 472 + break; 473 + } 474 + 475 + serial_width = serial_info.reg_width * 8; 476 + serial_offset = serial_info.reg_offset << serial_info.reg_shift; 477 + serial_address = serial_info.addr + serial_offset; 478 + 479 + /* Encode register access size */ 480 + switch (serial_info.reg_shift) { 481 + case 0: 482 + access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS; 483 + break; 484 + case 1: 485 + access_size = ACPI_ACCESS_SIZE_WORD_ACCESS; 486 + break; 487 + case 2: 488 + access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS; 489 + break; 490 + case 3: 491 + access_size = ACPI_ACCESS_SIZE_QWORD_ACCESS; 492 + break; 493 + default: 494 + access_size = ACPI_ACCESS_SIZE_UNDEFINED; 495 + break; 496 + } 497 + 498 + debug("UART type %u @ %lx\n", spcr->interface_type, serial_address); 499 + 500 + /* Fill GAS */ 501 + spcr->serial_port.space_id = space_id; 502 + spcr->serial_port.bit_width = serial_width; 503 + spcr->serial_port.bit_offset = 0; 504 + spcr->serial_port.access_size = access_size; 505 + spcr->serial_port.addrl = lower_32_bits(serial_address); 506 + spcr->serial_port.addrh = upper_32_bits(serial_address); 507 + 508 + /* Encode baud rate */ 509 + switch (serial_info.baudrate) { 510 + case 9600: 511 + spcr->baud_rate = 3; 512 + break; 513 + case 19200: 514 + spcr->baud_rate = 4; 515 + break; 516 + case 57600: 517 + spcr->baud_rate = 6; 518 + break; 519 + case 115200: 520 + spcr->baud_rate = 7; 521 + break; 522 + default: 523 + spcr->baud_rate = 0; 524 + break; 525 + } 526 + 527 + serial_config = SERIAL_DEFAULT_CONFIG; 528 + if (dev) 529 + ret = serial_getconfig(dev, &serial_config); 530 + 531 + spcr->parity = SERIAL_GET_PARITY(serial_config); 532 + spcr->stop_bits = SERIAL_GET_STOP(serial_config); 533 + 534 + /* No PCI devices for now */ 535 + spcr->pci_device_id = 0xffff; 536 + spcr->pci_vendor_id = 0xffff; 537 + 538 + /* 539 + * SPCR has no clue if the UART base clock speed is different 540 + * to the default one. However, the SPCR 1.04 defines baud rate 541 + * 0 as a preconfigured state of UART and OS is supposed not 542 + * to touch the configuration of the serial device. 543 + */ 544 + if (serial_info.clock != SERIAL_DEFAULT_CLOCK) 545 + spcr->baud_rate = 0; 546 + 547 + /* Fix checksum */ 548 + header->checksum = table_compute_checksum((void *)spcr, header->length); 549 + 550 + acpi_add_table(ctx, spcr); 551 + acpi_inc(ctx, spcr->header.length); 552 + 553 + return 0; 554 + } 555 + 556 + ACPI_WRITER(5spcr, "SPCR", acpi_write_spcr, 0); 557 + 558 + __weak int acpi_fill_iort(struct acpi_ctx *ctx) 559 + { 560 + return 0; 561 + } 562 + 563 + int acpi_iort_add_its_group(struct acpi_ctx *ctx, 564 + const u32 its_count, 565 + const u32 *identifiers) 566 + { 567 + struct acpi_iort_node *node; 568 + struct acpi_iort_its_group *group; 569 + int offset; 570 + 571 + offset = ctx->current - ctx->tab_start; 572 + 573 + node = ctx->current; 574 + memset(node, '\0', sizeof(struct acpi_iort_node)); 575 + 576 + node->type = ACPI_IORT_NODE_ITS_GROUP; 577 + node->revision = 1; 578 + 579 + node->length = sizeof(struct acpi_iort_node); 580 + node->length += sizeof(struct acpi_iort_its_group); 581 + node->length += sizeof(u32) * its_count; 582 + 583 + group = (struct acpi_iort_its_group *)node->node_data; 584 + group->its_count = its_count; 585 + memcpy(&group->identifiers, identifiers, sizeof(u32) * its_count); 586 + 587 + ctx->current += node->length; 588 + 589 + return offset; 590 + } 591 + 592 + int acpi_iort_add_named_component(struct acpi_ctx *ctx, 593 + const u32 node_flags, 594 + const u64 memory_properties, 595 + const u8 memory_address_limit, 596 + const char *device_name) 597 + { 598 + struct acpi_iort_node *node; 599 + struct acpi_iort_named_component *comp; 600 + int offset; 601 + 602 + offset = ctx->current - ctx->tab_start; 603 + 604 + node = ctx->current; 605 + memset(node, '\0', sizeof(struct acpi_iort_node)); 606 + 607 + node->type = ACPI_IORT_NODE_NAMED_COMPONENT; 608 + node->revision = 4; 609 + node->length = sizeof(struct acpi_iort_node); 610 + node->length += sizeof(struct acpi_iort_named_component); 611 + node->length += strlen(device_name) + 1; 612 + 613 + comp = (struct acpi_iort_named_component *)node->node_data; 614 + 615 + comp->node_flags = node_flags; 616 + comp->memory_properties = memory_properties; 617 + comp->memory_address_limit = memory_address_limit; 618 + memcpy(comp->device_name, device_name, strlen(device_name) + 1); 619 + 620 + ctx->current += node->length; 621 + 622 + return offset; 623 + } 624 + 625 + int acpi_iort_add_rc(struct acpi_ctx *ctx, 626 + const u64 mem_access_properties, 627 + const u32 ats_attributes, 628 + const u32 pci_segment_number, 629 + const u8 memory_address_size_limit, 630 + const int num_mappings, 631 + const struct acpi_iort_id_mapping *map) 632 + { 633 + struct acpi_iort_id_mapping *mapping; 634 + struct acpi_iort_node *node; 635 + struct acpi_iort_rc *rc; 636 + int offset; 637 + 638 + offset = ctx->current - ctx->tab_start; 639 + 640 + node = ctx->current; 641 + memset(node, '\0', sizeof(struct acpi_iort_node)); 642 + 643 + node->type = ACPI_IORT_NODE_PCI_ROOT_COMPLEX; 644 + node->revision = 2; 645 + 646 + node->length = sizeof(struct acpi_iort_node); 647 + node->length += sizeof(struct acpi_iort_rc); 648 + node->length += sizeof(struct acpi_iort_id_mapping) * num_mappings; 649 + 650 + rc = (struct acpi_iort_rc *)node->node_data; 651 + rc->mem_access_properties = mem_access_properties; 652 + rc->ats_attributes = ats_attributes; 653 + rc->pci_segment_number = pci_segment_number; 654 + rc->memory_address_size_limit = memory_address_size_limit; 655 + 656 + mapping = (struct acpi_iort_id_mapping *)(rc + 1); 657 + for (int i = 0; i < num_mappings; i++) { 658 + memcpy(mapping, &map[i], sizeof(struct acpi_iort_id_mapping)); 659 + mapping++; 660 + } 661 + 662 + ctx->current += node->length; 663 + 664 + return offset; 665 + } 666 + 667 + int acpi_iort_add_smmu_v3(struct acpi_ctx *ctx, 668 + const u64 base_address, 669 + const u32 flags, 670 + const u64 vatos_address, 671 + const u32 model, 672 + const u32 event_gsiv, 673 + const u32 pri_gsiv, 674 + const u32 gerr_gsiv, 675 + const u32 sync_gsiv, 676 + const u32 pxm, 677 + const u32 id_mapping_index, 678 + const int num_mappings, 679 + const struct acpi_iort_id_mapping *map) 680 + { 681 + struct acpi_iort_node *node; 682 + struct acpi_iort_smmu_v3 *smmu; 683 + struct acpi_iort_id_mapping *mapping; 684 + int offset; 685 + 686 + offset = ctx->current - ctx->tab_start; 687 + 688 + node = ctx->current; 689 + memset(node, '\0', sizeof(struct acpi_iort_node)); 690 + 691 + node->type = ACPI_IORT_NODE_SMMU_V3; 692 + node->revision = 5; 693 + node->mapping_count = num_mappings; 694 + node->mapping_offset = sizeof(struct acpi_iort_node) + sizeof(struct acpi_iort_smmu_v3); 695 + 696 + node->length = sizeof(struct acpi_iort_node); 697 + node->length += sizeof(struct acpi_iort_smmu_v3); 698 + node->length += sizeof(struct acpi_iort_id_mapping) * num_mappings; 699 + 700 + smmu = (struct acpi_iort_smmu_v3 *)node->node_data; 701 + 702 + smmu->base_address = base_address; 703 + smmu->flags = flags; 704 + smmu->vatos_address = vatos_address; 705 + smmu->model = model; 706 + smmu->event_gsiv = event_gsiv; 707 + smmu->pri_gsiv = pri_gsiv; 708 + smmu->gerr_gsiv = gerr_gsiv; 709 + smmu->sync_gsiv = sync_gsiv; 710 + smmu->pxm = pxm; 711 + smmu->id_mapping_index = id_mapping_index; 712 + 713 + mapping = (struct acpi_iort_id_mapping *)(smmu + 1); 714 + for (int i = 0; i < num_mappings; i++) { 715 + memcpy(mapping, &map[i], sizeof(struct acpi_iort_id_mapping)); 716 + mapping++; 717 + } 718 + 719 + ctx->current += node->length; 720 + 721 + return offset; 722 + } 723 + 724 + static int acpi_write_iort(struct acpi_ctx *ctx, const struct acpi_writer *entry) 725 + { 726 + struct acpi_table_iort *iort; 727 + struct acpi_iort_node *node; 728 + u32 offset; 729 + int ret; 730 + 731 + iort = ctx->current; 732 + ctx->tab_start = ctx->current; 733 + memset(iort, '\0', sizeof(struct acpi_table_iort)); 734 + 735 + acpi_fill_header(&iort->header, "IORT"); 736 + iort->header.revision = 1; 737 + iort->header.creator_revision = 1; 738 + iort->header.length = sizeof(struct acpi_table_iort); 739 + iort->node_offset = sizeof(struct acpi_table_iort); 740 + 741 + acpi_inc(ctx, sizeof(struct acpi_table_iort)); 742 + 743 + offset = sizeof(struct acpi_table_iort); 744 + ret = acpi_fill_iort(ctx); 745 + if (ret) { 746 + ctx->current = iort; 747 + return log_msg_ret("fill", ret); 748 + } 749 + 750 + /* Count nodes filled in */ 751 + for (node = (void *)iort + iort->node_offset; 752 + node->length > 0 && (void *)node < ctx->current; 753 + node = (void *)node + node->length) 754 + iort->node_count++; 755 + 756 + /* (Re)calculate length and checksum */ 757 + iort->header.length = ctx->current - (void *)iort; 758 + iort->header.checksum = table_compute_checksum((void *)iort, iort->header.length); 759 + log_debug("IORT at %p, length %x\n", iort, iort->header.length); 760 + 761 + /* Drop the table if it is empty */ 762 + if (iort->header.length == sizeof(struct acpi_table_iort)) 763 + return log_msg_ret("fill", -ENOENT); 764 + acpi_add_table(ctx, iort); 765 + 766 + return 0; 767 + } 768 + 769 + ACPI_WRITER(5iort, "IORT", acpi_write_iort, 0); 770 + 771 + /* 772 + * Allocate memory for ACPI tables and write ACPI tables to the 773 + * allocated buffer. 774 + * 775 + * Return: status code 776 + */ 777 + static int alloc_write_acpi_tables(void) 778 + { 779 + u64 table_end; 780 + void *addr; 781 + 782 + if (IS_ENABLED(CONFIG_X86) || 783 + IS_ENABLED(CONFIG_QFW_ACPI) || 784 + IS_ENABLED(CONFIG_SANDBOX)) { 785 + log_debug("Skipping writing ACPI tables as already done\n"); 786 + return 0; 787 + } 788 + 789 + if (!IS_ENABLED(CONFIG_BLOBLIST_TABLES)) { 790 + log_debug("Skipping writing ACPI tables as BLOBLIST_TABLES is not selected\n"); 791 + return 0; 792 + } 793 + 794 + /* Align the table to a 4KB boundary to keep EFI happy */ 795 + addr = bloblist_add(BLOBLISTT_ACPI_TABLES, TABLE_SIZE, 796 + ilog2(SZ_4K)); 797 + 798 + if (!addr) 799 + return log_msg_ret("mem", -ENOMEM); 800 + 801 + gd->arch.table_start_high = virt_to_phys(addr); 802 + gd->arch.table_end_high = gd->arch.table_start_high + TABLE_SIZE; 803 + 804 + table_end = write_acpi_tables(gd->arch.table_start_high); 805 + if (!table_end) { 806 + log_err("Can't create ACPI configuration table\n"); 807 + return -EINTR; 808 + } 809 + 810 + log_debug("- wrote 'acpi' to %lx, end %llx\n", gd->arch.table_start_high, table_end); 811 + if (table_end > gd->arch.table_end_high) { 812 + log_err("Out of space for configuration tables: need %llx, have %x\n", 813 + table_end - gd->arch.table_start_high, TABLE_SIZE); 814 + return log_msg_ret("acpi", -ENOSPC); 815 + } 816 + 817 + log_debug("- done writing tables\n"); 818 + 819 + return 0; 820 + } 821 + 822 + EVENT_SPY_SIMPLE(EVT_LAST_STAGE_INIT, alloc_write_acpi_tables);
+11
lib/acpi/acpigen.c
··· 361 361 acpigen_emit_byte(ctx, pblock_len); 362 362 } 363 363 364 + void acpigen_write_processor_device(struct acpi_ctx *ctx, uint cpuindex) 365 + { 366 + char pscope[16]; 367 + 368 + snprintf(pscope, sizeof(pscope), ACPI_CPU_STRING, cpuindex); 369 + acpigen_write_device(ctx, pscope); 370 + acpigen_write_name_string(ctx, "_HID", "ACPI0007"); 371 + acpigen_write_name_integer(ctx, "_UID", cpuindex); 372 + acpigen_pop_len(ctx); /* Device */ 373 + } 374 + 364 375 void acpigen_write_processor_package(struct acpi_ctx *ctx, 365 376 const char *const name, 366 377 const uint first_core,
+43
test/dm/acpi.c
··· 95 95 return acpi_copy_name(out_name, ACPI_TEST_DEV_NAME); 96 96 } 97 97 98 + static int testacpi_fill_madt(const struct udevice *dev, struct acpi_ctx *ctx) 99 + { 100 + u64 *data = ctx->current; 101 + 102 + /* Only fill madt once */ 103 + if (device_get_uclass_id(dev->parent) != UCLASS_TEST_ACPI) 104 + return 0; 105 + 106 + *data = 0xdeadbeef; 107 + 108 + acpi_inc(ctx, sizeof(u64)); 109 + 110 + return 0; 111 + } 112 + 98 113 static int testacpi_fill_ssdt(const struct udevice *dev, struct acpi_ctx *ctx) 99 114 { 100 115 const char *data; ··· 124 139 struct acpi_ops testacpi_ops = { 125 140 .get_name = testacpi_get_name, 126 141 .write_tables = testacpi_write_tables, 142 + .fill_madt = testacpi_fill_madt, 127 143 .fill_ssdt = testacpi_fill_ssdt, 128 144 .inject_dsdt = testacpi_inject_dsdt, 129 145 }; ··· 526 542 return 0; 527 543 } 528 544 DM_TEST(dm_test_acpi_fill_ssdt, UTF_SCAN_PDATA | UTF_SCAN_FDT); 545 + 546 + /* Test acpi_fill_madt() */ 547 + static int dm_test_acpi_fill_madt(struct unit_test_state *uts) 548 + { 549 + struct acpi_ctx ctx; 550 + u64 *buf; 551 + 552 + buf = malloc(BUF_SIZE); 553 + ut_assertnonnull(buf); 554 + 555 + acpi_reset_items(); 556 + ctx.current = buf; 557 + buf[1] = 'z'; /* sentinel */ 558 + ut_assertok(acpi_fill_madt_subtbl(&ctx)); 559 + 560 + /* 561 + * These values come from acpi-test2's acpi-ssdt-test-data property. 562 + * This device comes first because of u-boot,acpi-ssdt-order 563 + */ 564 + ut_asserteq(0xdeadbeef, buf[0]); 565 + 566 + ut_asserteq('z', buf[1]); 567 + 568 + return 0; 569 + } 570 + 571 + DM_TEST(dm_test_acpi_fill_madt, UTF_SCAN_PDATA | UTF_SCAN_FDT); 529 572 530 573 /* Test acpi_inject_dsdt() */ 531 574 static int dm_test_acpi_inject_dsdt(struct unit_test_state *uts)
+15
test/dm/irq.c
··· 76 76 } 77 77 DM_TEST(dm_test_request, UTF_SCAN_PDATA | UTF_SCAN_FDT); 78 78 79 + /* Test of irq_get_by_index() */ 80 + static int dm_test_irq_get_by_index(struct unit_test_state *uts) 81 + { 82 + struct udevice *dev; 83 + struct irq irq; 84 + 85 + ut_assertok(uclass_get_device_by_name(UCLASS_TEST_FDT, "f-test", 86 + &dev)); 87 + ut_assertok(irq_get_by_index(dev, 0, &irq)); 88 + ut_asserteq(4, irq.id); 89 + 90 + return 0; 91 + } 92 + DM_TEST(dm_test_irq_get_by_index, UTF_SCAN_PDATA | UTF_SCAN_FDT); 93 + 79 94 /* Test of irq_get_acpi() */ 80 95 static int dm_test_irq_get_acpi(struct unit_test_state *uts) 81 96 {
+1
test/py/tests/test_event_dump.py
··· 18 18 -------------------- ------------------------------ ------------------------------ 19 19 EVT_FT_FIXUP bootmeth_vbe_ft_fixup .*boot/vbe_request.c:.* 20 20 EVT_FT_FIXUP bootmeth_vbe_simple_ft_fixup .*boot/vbe_simple_os.c:.* 21 + EVT_LAST_STAGE_INIT alloc_write_acpi_tables .*lib/acpi/acpi_table.c:.* 21 22 EVT_LAST_STAGE_INIT install_smbios_table .*lib/efi_loader/efi_smbios.c:.* 22 23 EVT_MISC_INIT_F sandbox_early_getopt_check .*arch/sandbox/cpu/start.c:.* 23 24 EVT_TEST h_adder_simple .*test/common/event.c:'''