mainboard/emulation/qemu-sbsa: Add qemu-sbsa board
Add coreboot support for qemu's sbsa-ref (Server Base System Architecture) machine (-m sbsa-ref). The qemu-sbsa coreboot port runs on EL2 and is the payload of the EL3 firmware (Arm Trusted Firmware). Note that, coreboot expects a pointer to the FDT in x0. Make sure to configure TF-A to handoff the FDT pointer. Example qemu commandline: qemu-system-aarch64 -nographic -m 2048 -M sbsa-ref \ -pflash <path/to/TFA.fd> \ -pflash <path/to/coreboot.rom> The Documentation can be found here: Documentation/mainboard/emulation/qemu-sbsa.md Change-Id: Iacc9aaf065e0d153336cbef9a9b5b46a9eb24a53 Signed-off-by: David Milosevic <David.Milosevic@9elements.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/79086 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Lean Sheng Tan <sheng.tan@9elements.com>
This commit is contained in:
committed by
Lean Sheng Tan
parent
91cda2af74
commit
ad83eb1ee6
42
Documentation/mainboard/emulation/qemu-sbsa.md
Normal file
42
Documentation/mainboard/emulation/qemu-sbsa.md
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
# QEMU SBSA emulator
|
||||||
|
This page describes how to build and run ```coreboot``` for QEMU's sbsa-ref machine.
|
||||||
|
The qemu-sbsa ```coreboot``` image acts as BL-3.3 for Arm Trusted Firmware (```TF-A```) and
|
||||||
|
mainly takes care of setting up SMBIOS and ACPI tables, hence, in order to boot,
|
||||||
|
you also need to supply a ```TF-A``` image.
|
||||||
|
|
||||||
|
## Building TF-A
|
||||||
|
|
||||||
|
You can build ```TF-A``` from source by fetching
|
||||||
|
```
|
||||||
|
https://github.com/ARM-software/arm-trusted-firmware
|
||||||
|
```
|
||||||
|
and building the qemu-sbsa platform
|
||||||
|
```
|
||||||
|
PLAT=qemu_sbsa
|
||||||
|
```
|
||||||
|
Upon entry, ```coreboot``` expects a FDT pointer in x0, so make sure to compile ```TF-A``` with
|
||||||
|
```
|
||||||
|
ARM_LINUX_KERNEL_AS_BL33=1
|
||||||
|
```
|
||||||
|
This will force ```TF-A``` to pass a pointer to the FDT in x0.
|
||||||
|
|
||||||
|
## Building coreboot
|
||||||
|
|
||||||
|
Simply select the qemu-sbsa board and, optionally, configure a payload. We recommend
|
||||||
|
the ```leanefi``` payload. ```leanefi``` will setup a minimal set of UEFI services, just enough
|
||||||
|
to boot into a linux kernel.
|
||||||
|
|
||||||
|
## Running coreboot in QEMU
|
||||||
|
|
||||||
|
Once you have obtained ```TF-A``` and ```coreboot``` images, launch qemu via
|
||||||
|
|
||||||
|
```bash
|
||||||
|
qemu-system-aarch64 -nographic -m 1024 -M sbsa-ref -pflash <path/to/TFA.fd> \
|
||||||
|
-pflash <path/to/coreboot.rom>
|
||||||
|
```
|
||||||
|
|
||||||
|
## LBBR bootflow
|
||||||
|
|
||||||
|
arm and 9elements worked together in order to create a LBBR compliant bootflow
|
||||||
|
consisting of ```TF-A```, ```coreboot```, ```leanefi``` and ```LinuxBoot```. A proof of concept
|
||||||
|
can be found here https://gitlab.arm.com/systemready/firmware-build/linuxboot/lbbr-coreboot-poc
|
@@ -90,6 +90,7 @@ The boards in this section are not real mainboards, but emulators.
|
|||||||
Spike RISC-V emulator <emulation/spike-riscv.md>
|
Spike RISC-V emulator <emulation/spike-riscv.md>
|
||||||
QEMU RISC-V emulator <emulation/qemu-riscv.md>
|
QEMU RISC-V emulator <emulation/qemu-riscv.md>
|
||||||
QEMU AArch64 emulator <emulation/qemu-aarch64.md>
|
QEMU AArch64 emulator <emulation/qemu-aarch64.md>
|
||||||
|
QEMU SBSA emulator <emulation/qemu-sbsa.md>
|
||||||
QEMU x86 Q35 <emulation/qemu-q35.md>
|
QEMU x86 Q35 <emulation/qemu-q35.md>
|
||||||
QEMU x86 PC <emulation/qemu-i440fx.md>
|
QEMU x86 PC <emulation/qemu-i440fx.md>
|
||||||
QEMU POWER9 <emulation/qemu-power9.md>
|
QEMU POWER9 <emulation/qemu-power9.md>
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
# ugly to put it in here, but unavoidable
|
# ugly to put it in here, but unavoidable
|
||||||
config SEPARATE_ROMSTAGE
|
config SEPARATE_ROMSTAGE
|
||||||
default n if BOARD_EMULATION_QEMU_RISCV
|
default n if BOARD_EMULATION_QEMU_RISCV
|
||||||
|
default n if BOARD_EMULATION_QEMU_SBSA
|
||||||
|
|
||||||
if VENDOR_EMULATION
|
if VENDOR_EMULATION
|
||||||
|
|
||||||
|
55
src/mainboard/emulation/qemu-sbsa/Kconfig
Normal file
55
src/mainboard/emulation/qemu-sbsa/Kconfig
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
if BOARD_EMULATION_QEMU_SBSA
|
||||||
|
|
||||||
|
config BOARD_SPECIFIC_OPTIONS
|
||||||
|
def_bool y
|
||||||
|
select ARCH_BOOTBLOCK_ARMV8_64
|
||||||
|
select ARCH_VERSTAGE_ARMV8_64
|
||||||
|
select ARCH_ROMSTAGE_ARMV8_64
|
||||||
|
select ARCH_RAMSTAGE_ARMV8_64
|
||||||
|
select ARM64_USE_ARCH_TIMER
|
||||||
|
select BOARD_ROMSIZE_KB_32768
|
||||||
|
select BOOTBLOCK_CUSTOM
|
||||||
|
select BOOT_DEVICE_NOT_SPI_FLASH
|
||||||
|
select DRIVERS_UART_PL011
|
||||||
|
select FLATTENED_DEVICE_TREE
|
||||||
|
select HAVE_LINEAR_FRAMEBUFFER
|
||||||
|
select MAINBOARD_FORCE_NATIVE_VGA_INIT
|
||||||
|
select MAINBOARD_HAS_NATIVE_VGA_INIT
|
||||||
|
select MISSING_BOARD_RESET
|
||||||
|
select PCI
|
||||||
|
select HAVE_ACPI_TABLES
|
||||||
|
select ACPI_GTDT
|
||||||
|
select ACPI_COMMON_MADT_GICC_V3
|
||||||
|
select GENERATE_SMBIOS_TABLES
|
||||||
|
|
||||||
|
config ARM64_CURRENT_EL
|
||||||
|
default 2
|
||||||
|
|
||||||
|
config ECAM_MMCONF_BASE_ADDRESS
|
||||||
|
default 0xf0000000
|
||||||
|
|
||||||
|
config ECAM_MMCONF_BUS_NUMBER
|
||||||
|
default 256
|
||||||
|
|
||||||
|
config FMDFILE
|
||||||
|
default "src/mainboard/emulation/qemu-sbsa/flash.fmd"
|
||||||
|
|
||||||
|
config MAINBOARD_DIR
|
||||||
|
default "emulation/qemu-sbsa"
|
||||||
|
|
||||||
|
config MAINBOARD_PART_NUMBER
|
||||||
|
default "QEMU sbsa"
|
||||||
|
|
||||||
|
config MAX_CPUS
|
||||||
|
default 128
|
||||||
|
|
||||||
|
config MAINBOARD_VENDOR
|
||||||
|
default "QEMU"
|
||||||
|
|
||||||
|
config DRAM_SIZE_MB
|
||||||
|
int
|
||||||
|
default 8388608 # The maximum dram size is 8192GiB.
|
||||||
|
|
||||||
|
endif # BOARD_EMULATION_QEMU_SBSA
|
4
src/mainboard/emulation/qemu-sbsa/Kconfig.name
Normal file
4
src/mainboard/emulation/qemu-sbsa/Kconfig.name
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
config BOARD_EMULATION_QEMU_SBSA
|
||||||
|
bool "QEMU sbsa"
|
23
src/mainboard/emulation/qemu-sbsa/Makefile.mk
Normal file
23
src/mainboard/emulation/qemu-sbsa/Makefile.mk
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
bootblock-y += bootblock.c
|
||||||
|
|
||||||
|
romstage-y += cbmem.c
|
||||||
|
|
||||||
|
bootblock-y += media.c
|
||||||
|
romstage-y += media.c
|
||||||
|
ramstage-y += media.c
|
||||||
|
|
||||||
|
bootblock-y += mmio.c
|
||||||
|
romstage-y += mmio.c
|
||||||
|
ramstage-y += mmio.c
|
||||||
|
|
||||||
|
ramstage-y += acpi.c
|
||||||
|
|
||||||
|
bootblock-y += bootblock_custom.S
|
||||||
|
|
||||||
|
CPPFLAGS_common += -mcmodel=large -I$(src)/mainboard/$(MAINBOARDDIR)/include
|
||||||
|
|
||||||
|
build_complete::
|
||||||
|
@printf "Truncating coreboot.rom to 256M\n"
|
||||||
|
truncate -s 256M $(obj)/coreboot.rom
|
60
src/mainboard/emulation/qemu-sbsa/acpi.c
Normal file
60
src/mainboard/emulation/qemu-sbsa/acpi.c
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
|
||||||
|
#include <acpi/acpi.h>
|
||||||
|
#include <mainboard/addressmap.h>
|
||||||
|
|
||||||
|
|
||||||
|
void acpi_fill_fadt(acpi_fadt_t *fadt)
|
||||||
|
{
|
||||||
|
fadt->ARM_boot_arch |= ACPI_FADT_ARM_PSCI_COMPLIANT;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long acpi_fill_madt(unsigned long current)
|
||||||
|
{
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
uintptr_t platform_get_gicd_base(void)
|
||||||
|
{
|
||||||
|
return SBSA_GIC_DIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
uintptr_t platform_get_gicr_base(void)
|
||||||
|
{
|
||||||
|
return SBSA_GIC_REDIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SEC_EL1_TIMER_GISV 0x1d
|
||||||
|
#define NONSEC_EL1_TIMER_GSIV 0x1e
|
||||||
|
#define VIRTUAL_TIMER_GSIV 0x1b
|
||||||
|
#define NONSEC_EL2_TIMER_GSIV 0x1a
|
||||||
|
|
||||||
|
#define SBSA_TIMER_FLAGS (ACPI_GTDT_INTERRUPT_POLARITY | ACPI_GTDT_ALWAYS_ON)
|
||||||
|
|
||||||
|
void acpi_soc_fill_gtdt(acpi_gtdt_t *gtdt)
|
||||||
|
{
|
||||||
|
/* This value is optional if the system implements EL3 (Security
|
||||||
|
Extensions). If not provided, this field must be 0xFFFFFFFFFFFFFFFF. */
|
||||||
|
gtdt->counter_block_address = UINT64_MAX;
|
||||||
|
gtdt->secure_el1_interrupt = SEC_EL1_TIMER_GISV;
|
||||||
|
gtdt->secure_el1_flags = SBSA_TIMER_FLAGS;
|
||||||
|
gtdt->non_secure_el1_interrupt = NONSEC_EL1_TIMER_GSIV;
|
||||||
|
gtdt->non_secure_el1_flags = SBSA_TIMER_FLAGS;
|
||||||
|
gtdt->virtual_timer_interrupt = VIRTUAL_TIMER_GSIV;
|
||||||
|
gtdt->virtual_timer_flags = SBSA_TIMER_FLAGS;
|
||||||
|
gtdt->non_secure_el2_interrupt = NONSEC_EL2_TIMER_GSIV;
|
||||||
|
gtdt->non_secure_el2_flags = SBSA_TIMER_FLAGS;
|
||||||
|
/* This value is optional if the system implements EL3
|
||||||
|
(Security Extensions). If not provided, this field must be
|
||||||
|
0xFFFFFFFFFFFFFFF. */
|
||||||
|
gtdt->counter_read_block_address = UINT64_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define WD_TIMER_GSIV 0x30
|
||||||
|
|
||||||
|
unsigned long acpi_soc_gtdt_add_timers(uint32_t *count, unsigned long current)
|
||||||
|
{
|
||||||
|
(*count)++;
|
||||||
|
return acpi_gtdt_add_watchdog(current, SBSA_GWDT_REFRESH, SBSA_GWDT_CONTROL,
|
||||||
|
WD_TIMER_GSIV, 0);
|
||||||
|
}
|
3
src/mainboard/emulation/qemu-sbsa/board_info.txt
Normal file
3
src/mainboard/emulation/qemu-sbsa/board_info.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Board name: QEMU sbsa
|
||||||
|
Category: emulation
|
||||||
|
Board URL: https://wiki.qemu.org/Main_Page
|
22
src/mainboard/emulation/qemu-sbsa/bootblock.c
Normal file
22
src/mainboard/emulation/qemu-sbsa/bootblock.c
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
|
||||||
|
#include <arch/mmu.h>
|
||||||
|
#include <bootblock_common.h>
|
||||||
|
#include <symbols.h>
|
||||||
|
|
||||||
|
void bootblock_mainboard_init(void)
|
||||||
|
{
|
||||||
|
mmu_init();
|
||||||
|
|
||||||
|
/* Everything below DRAM is device memory */
|
||||||
|
mmu_config_range((void *)0, (uintptr_t)_dram, MA_DEV | MA_RW);
|
||||||
|
/* Set a dummy value for DRAM. ramstage should update the mapping. */
|
||||||
|
mmu_config_range(_dram, ((size_t) CONFIG_DRAM_SIZE_MB) * MiB, MA_MEM | MA_RW);
|
||||||
|
|
||||||
|
mmu_config_range(_ttb, REGION_SIZE(ttb), MA_MEM | MA_S | MA_RW);
|
||||||
|
mmu_config_range(_bootblock, REGION_SIZE(bootblock), MA_MEM | MA_S | MA_RW);
|
||||||
|
mmu_config_range(_ramstage, REGION_SIZE(ramstage), MA_MEM | MA_S | MA_RW);
|
||||||
|
mmu_config_range((void *)CONFIG_ECAM_MMCONF_BASE_ADDRESS, CONFIG_ECAM_MMCONF_LENGTH,
|
||||||
|
MA_DEV | MA_RW);
|
||||||
|
mmu_enable();
|
||||||
|
}
|
55
src/mainboard/emulation/qemu-sbsa/bootblock_custom.S
Normal file
55
src/mainboard/emulation/qemu-sbsa/bootblock_custom.S
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Early initialization code for sbsa-ref machine
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <arch/asm.h>
|
||||||
|
|
||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
/* TF-A arg which contains a pointer to fdt */
|
||||||
|
ldr x1, =_fdt_pointer
|
||||||
|
str x0, [x1]
|
||||||
|
|
||||||
|
/* Setup CPU. */
|
||||||
|
/* bl arm64_init_cpu */
|
||||||
|
|
||||||
|
/* ==== stack init from arm64_init_cpu ==== */
|
||||||
|
|
||||||
|
msr SPSel, #0 /* use SP_EL0 */
|
||||||
|
|
||||||
|
ldr x2, =0xdeadbeefdeadbeef
|
||||||
|
ldr x0, =_stack
|
||||||
|
ldr x1, =_estack
|
||||||
|
1:
|
||||||
|
stp x2, x2, [x0], #16
|
||||||
|
cmp x0, x1
|
||||||
|
bne 1b
|
||||||
|
|
||||||
|
sub sp, x0, #16
|
||||||
|
|
||||||
|
/* ==== END ==== */
|
||||||
|
|
||||||
|
/* Get code positions. */
|
||||||
|
ldr x1, =_flash
|
||||||
|
ldr x0, =_bootblock
|
||||||
|
|
||||||
|
/* Calculate bootblock size. */
|
||||||
|
ldr x2, =_ebootblock
|
||||||
|
sub x2, x2, x0
|
||||||
|
|
||||||
|
/* Call memcpy in arch/arm64/memcpy.S */
|
||||||
|
bl memcpy
|
||||||
|
dmb sy
|
||||||
|
|
||||||
|
/* Calculate relocation offset between bootblock in flash and in DRAM. */
|
||||||
|
ldr x0, =_flash
|
||||||
|
ldr x1, =_bootblock
|
||||||
|
sub x1, x1, x0
|
||||||
|
|
||||||
|
/* Jump to main() in DRAM. */
|
||||||
|
adr x0, main
|
||||||
|
add x0, x0, x1
|
||||||
|
blr x0
|
||||||
|
ENDPROC(_start)
|
20
src/mainboard/emulation/qemu-sbsa/cbmem.c
Normal file
20
src/mainboard/emulation/qemu-sbsa/cbmem.c
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
#include <cbmem.h>
|
||||||
|
#include <symbols.h>
|
||||||
|
#include <device_tree.h>
|
||||||
|
#include <console/console.h>
|
||||||
|
|
||||||
|
DECLARE_REGION(fdt_pointer)
|
||||||
|
uintptr_t cbmem_top_chipset(void)
|
||||||
|
{
|
||||||
|
const uint64_t top = fdt_get_memory_top((void *) *((uintptr_t *)_fdt_pointer));
|
||||||
|
|
||||||
|
if (top == 0) {
|
||||||
|
/* corrupted FDT? */
|
||||||
|
die("Could not find top of memory in FDT!");
|
||||||
|
}
|
||||||
|
|
||||||
|
printk(BIOS_DEBUG, "%s: 0x%llx\n", __func__, top);
|
||||||
|
return (uintptr_t)top;
|
||||||
|
}
|
13
src/mainboard/emulation/qemu-sbsa/chip.h
Normal file
13
src/mainboard/emulation/qemu-sbsa/chip.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
#ifndef MAINBOARD_EMULATION_QEMU_SBSA_CHIP_H
|
||||||
|
#define MAINBOARD_EMULATION_QEMU_SBSA_CHIP_H
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
|
||||||
|
struct mainboard_emulation_qemu_sbsa_config {
|
||||||
|
uint32_t vgic_maintenance_interrupt;
|
||||||
|
uint32_t performance_interrupt_gsiv;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
12
src/mainboard/emulation/qemu-sbsa/devicetree.cb
Normal file
12
src/mainboard/emulation/qemu-sbsa/devicetree.cb
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
chip mainboard/emulation/qemu-sbsa
|
||||||
|
register "vgic_maintenance_interrupt" = "0x19"
|
||||||
|
register "performance_interrupt_gsiv" = "0x17"
|
||||||
|
|
||||||
|
device cpu_cluster 0 on ops qemu_aarch64_cpu_ops end
|
||||||
|
|
||||||
|
device domain 0 on ops qemu_aarch64_pci_domain_ops
|
||||||
|
device pci 00.0 on end
|
||||||
|
end
|
||||||
|
end
|
271
src/mainboard/emulation/qemu-sbsa/dsdt.asl
Normal file
271
src/mainboard/emulation/qemu-sbsa/dsdt.asl
Normal file
@@ -0,0 +1,271 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
|
||||||
|
#define LINK_DEVICE(Uid, LinkName, Irq) \
|
||||||
|
Device (LinkName) { \
|
||||||
|
Name (_HID, EISAID("PNP0C0F")) \
|
||||||
|
Name (_UID, Uid) \
|
||||||
|
Name (_CRS, ResourceTemplate() { \
|
||||||
|
Interrupt (ResourceProducer, Level, ActiveHigh, Exclusive) { Irq } \
|
||||||
|
}) \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define USB_PORT(PortName, Adr) \
|
||||||
|
Device (PortName) { \
|
||||||
|
Name (_ADR, Adr) \
|
||||||
|
Name (_UPC, Package() { \
|
||||||
|
0xFF, \
|
||||||
|
0x00, \
|
||||||
|
0x00000000, \
|
||||||
|
0x00000000 \
|
||||||
|
}) \
|
||||||
|
Name (_PLD, Package() { \
|
||||||
|
Buffer(0x10) { \
|
||||||
|
0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
|
||||||
|
0x31, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 \
|
||||||
|
} \
|
||||||
|
}) \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PRT_ENTRY(Address, Pin, Link) \
|
||||||
|
Package (4) { \
|
||||||
|
Address, Pin, Link, Zero \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PRT_ENTRY_GROUP(Address, Link0, Link1, Link2, Link3) \
|
||||||
|
PRT_ENTRY (Address, 0, Link0), \
|
||||||
|
PRT_ENTRY (Address, 1, Link1), \
|
||||||
|
PRT_ENTRY (Address, 2, Link2), \
|
||||||
|
PRT_ENTRY (Address, 3, Link3)
|
||||||
|
|
||||||
|
#include <acpi/acpi.h>
|
||||||
|
#include <mainboard/addressmap.h>
|
||||||
|
|
||||||
|
DefinitionBlock(
|
||||||
|
"dsdt.aml",
|
||||||
|
"DSDT",
|
||||||
|
ACPI_DSDT_REV_2,
|
||||||
|
OEM_ID,
|
||||||
|
ACPI_TABLE_CREATOR,
|
||||||
|
0x20230621
|
||||||
|
)
|
||||||
|
{
|
||||||
|
#include <acpi/dsdt_top.asl>
|
||||||
|
|
||||||
|
Scope (_SB) {
|
||||||
|
// UART PL011
|
||||||
|
Device (COM0) {
|
||||||
|
Name (_HID, "ARMH0011")
|
||||||
|
Name (_UID, Zero)
|
||||||
|
Name (_CRS, ResourceTemplate () {
|
||||||
|
Memory32Fixed (ReadWrite, SBSA_UART_BASE, 0x00001000)
|
||||||
|
Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { 33 }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// AHCI Host Controller
|
||||||
|
Device (AHC0) {
|
||||||
|
Name (_HID, "LNRO001E")
|
||||||
|
Name (_CLS, Package (3) {
|
||||||
|
0x01,
|
||||||
|
0x06,
|
||||||
|
0x01,
|
||||||
|
})
|
||||||
|
Name (_CCA, 1)
|
||||||
|
Name (_CRS, ResourceTemplate() {
|
||||||
|
Memory32Fixed (ReadWrite, SBSA_AHCI_BASE, 0x00010000)
|
||||||
|
Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { 42 }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// USB EHCI Host Controller
|
||||||
|
Device (USB0) {
|
||||||
|
Name (_HID, "LNRO0D20")
|
||||||
|
Name (_CID, "PNP0D20")
|
||||||
|
Method (_CRS, 0x0, Serialized) {
|
||||||
|
Name (RBUF, ResourceTemplate() {
|
||||||
|
Memory32Fixed (ReadWrite, SBSA_EHCI_BASE, 0x00010000)
|
||||||
|
Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { 43 }
|
||||||
|
})
|
||||||
|
Return (RBUF)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Root Hub
|
||||||
|
Device (RHUB) {
|
||||||
|
Name (_ADR, 0x00000000) // Address of Root Hub should be 0 as per ACPI 5.0 spec
|
||||||
|
|
||||||
|
// Ports connected to Root Hub
|
||||||
|
Device (HUB1) {
|
||||||
|
Name (_ADR, 0x00000001)
|
||||||
|
Name (_UPC, Package() {
|
||||||
|
0x00, // Port is NOT connectable
|
||||||
|
0xFF, // Don't care
|
||||||
|
0x00000000, // Reserved 0 must be zero
|
||||||
|
0x00000000 // Reserved 1 must be zero
|
||||||
|
})
|
||||||
|
USB_PORT (PRT1, 0x00000001) // USB0_RHUB_HUB1_PRT1
|
||||||
|
USB_PORT (PRT2, 0x00000002) // USB0_RHUB_HUB1_PRT2
|
||||||
|
USB_PORT (PRT3, 0x00000003) // USB0_RHUB_HUB1_PRT3
|
||||||
|
USB_PORT (PRT4, 0x00000004) // USB0_RHUB_HUB1_PRT4
|
||||||
|
} // USB0_RHUB_HUB1
|
||||||
|
} // USB0_RHUB
|
||||||
|
} // USB0
|
||||||
|
|
||||||
|
Device (PCI0)
|
||||||
|
{
|
||||||
|
Name (_HID, EISAID ("PNP0A08")) // PCI Express Root Bridge
|
||||||
|
Name (_CID, EISAID ("PNP0A03")) // Compatible PCI Root Bridge
|
||||||
|
Name (_SEG, Zero) // PCI Segment Group number
|
||||||
|
Name (_BBN, Zero) // PCI Base Bus Number
|
||||||
|
Name (_UID, "PCI0")
|
||||||
|
Name (_CCA, One) // Initially mark the PCI coherent (for JunoR1)
|
||||||
|
|
||||||
|
Method (_CBA, 0, NotSerialized) {
|
||||||
|
return (SBSA_PCIE_ECAM_BASE)
|
||||||
|
}
|
||||||
|
|
||||||
|
LINK_DEVICE (0, GSI0, 0x23)
|
||||||
|
LINK_DEVICE (1, GSI1, 0x24)
|
||||||
|
LINK_DEVICE (2, GSI2, 0x25)
|
||||||
|
LINK_DEVICE (3, GSI3, 0x26)
|
||||||
|
|
||||||
|
Name (_PRT, Package () {
|
||||||
|
|
||||||
|
// _PRT: PCI Routing Table
|
||||||
|
PRT_ENTRY_GROUP (0x0000FFFF, GSI0, GSI1, GSI2, GSI3),
|
||||||
|
PRT_ENTRY_GROUP (0x0001FFFF, GSI1, GSI2, GSI3, GSI0),
|
||||||
|
PRT_ENTRY_GROUP (0x0002FFFF, GSI2, GSI3, GSI0, GSI1),
|
||||||
|
PRT_ENTRY_GROUP (0x0003FFFF, GSI3, GSI0, GSI1, GSI2),
|
||||||
|
PRT_ENTRY_GROUP (0x0004FFFF, GSI0, GSI1, GSI2, GSI3),
|
||||||
|
PRT_ENTRY_GROUP (0x0005FFFF, GSI1, GSI2, GSI3, GSI0),
|
||||||
|
PRT_ENTRY_GROUP (0x0006FFFF, GSI2, GSI3, GSI0, GSI1),
|
||||||
|
PRT_ENTRY_GROUP (0x0007FFFF, GSI3, GSI0, GSI1, GSI2),
|
||||||
|
PRT_ENTRY_GROUP (0x0008FFFF, GSI0, GSI1, GSI2, GSI3),
|
||||||
|
PRT_ENTRY_GROUP (0x0009FFFF, GSI1, GSI2, GSI3, GSI0),
|
||||||
|
PRT_ENTRY_GROUP (0x000AFFFF, GSI2, GSI3, GSI0, GSI1),
|
||||||
|
PRT_ENTRY_GROUP (0x000BFFFF, GSI3, GSI0, GSI1, GSI2),
|
||||||
|
PRT_ENTRY_GROUP (0x000CFFFF, GSI0, GSI1, GSI2, GSI3),
|
||||||
|
PRT_ENTRY_GROUP (0x000DFFFF, GSI1, GSI2, GSI3, GSI0),
|
||||||
|
PRT_ENTRY_GROUP (0x000EFFFF, GSI2, GSI3, GSI0, GSI1),
|
||||||
|
PRT_ENTRY_GROUP (0x000FFFFF, GSI3, GSI0, GSI1, GSI2),
|
||||||
|
PRT_ENTRY_GROUP (0x0010FFFF, GSI0, GSI1, GSI2, GSI3),
|
||||||
|
PRT_ENTRY_GROUP (0x0011FFFF, GSI1, GSI2, GSI3, GSI0),
|
||||||
|
PRT_ENTRY_GROUP (0x0012FFFF, GSI2, GSI3, GSI0, GSI1),
|
||||||
|
PRT_ENTRY_GROUP (0x0013FFFF, GSI3, GSI0, GSI1, GSI2),
|
||||||
|
PRT_ENTRY_GROUP (0x0014FFFF, GSI0, GSI1, GSI2, GSI3),
|
||||||
|
PRT_ENTRY_GROUP (0x0015FFFF, GSI1, GSI2, GSI3, GSI0),
|
||||||
|
PRT_ENTRY_GROUP (0x0016FFFF, GSI2, GSI3, GSI0, GSI1),
|
||||||
|
PRT_ENTRY_GROUP (0x0017FFFF, GSI3, GSI0, GSI1, GSI2),
|
||||||
|
PRT_ENTRY_GROUP (0x0018FFFF, GSI0, GSI1, GSI2, GSI3),
|
||||||
|
PRT_ENTRY_GROUP (0x0019FFFF, GSI1, GSI2, GSI3, GSI0),
|
||||||
|
PRT_ENTRY_GROUP (0x001AFFFF, GSI2, GSI3, GSI0, GSI1),
|
||||||
|
PRT_ENTRY_GROUP (0x001BFFFF, GSI3, GSI0, GSI1, GSI2),
|
||||||
|
PRT_ENTRY_GROUP (0x001CFFFF, GSI0, GSI1, GSI2, GSI3),
|
||||||
|
PRT_ENTRY_GROUP (0x001DFFFF, GSI1, GSI2, GSI3, GSI0),
|
||||||
|
PRT_ENTRY_GROUP (0x001EFFFF, GSI2, GSI3, GSI0, GSI1),
|
||||||
|
PRT_ENTRY_GROUP (0x001FFFFF, GSI3, GSI0, GSI1, GSI2),
|
||||||
|
})
|
||||||
|
|
||||||
|
// Root complex resources
|
||||||
|
Method (_CRS, 0, Serialized) {
|
||||||
|
Name (RBUF, ResourceTemplate () {
|
||||||
|
WordBusNumber ( // Bus numbers assigned to this root
|
||||||
|
ResourceProducer,
|
||||||
|
MinFixed, MaxFixed, PosDecode,
|
||||||
|
0, // AddressGranularity
|
||||||
|
0, // AddressMinimum - Minimum Bus Number
|
||||||
|
255, // AddressMaximum - Maximum Bus Number
|
||||||
|
0, // AddressTranslation - Set to 0
|
||||||
|
256 // RangeLength - Number of Busses
|
||||||
|
)
|
||||||
|
|
||||||
|
DWordMemory ( // 32-bit BAR Windows
|
||||||
|
ResourceProducer, PosDecode,
|
||||||
|
MinFixed, MaxFixed,
|
||||||
|
Cacheable, ReadWrite,
|
||||||
|
0x00000000, // Granularity
|
||||||
|
SBSA_PCIE_MMIO_BASE, // Min Base Address
|
||||||
|
SBSA_PCIE_MMIO_LIMIT, // Max Base Address
|
||||||
|
0, // Translate
|
||||||
|
SBSA_PCIE_MMIO_SIZE // Length
|
||||||
|
)
|
||||||
|
|
||||||
|
QWordMemory ( // 64-bit BAR Windows
|
||||||
|
ResourceProducer, PosDecode,
|
||||||
|
MinFixed, MaxFixed,
|
||||||
|
Cacheable, ReadWrite,
|
||||||
|
0x00000000, // Granularity
|
||||||
|
SBSA_PCIE_MMIO_HIGH_BASE, // Min Base Address
|
||||||
|
SBSA_PCIE_MMIO_HIGH_LIMIT, // Max Base Address
|
||||||
|
0, // Translate
|
||||||
|
SBSA_PCIE_MMIO_HIGH_SIZE // Length
|
||||||
|
)
|
||||||
|
|
||||||
|
DWordIo ( // IO window
|
||||||
|
ResourceProducer,
|
||||||
|
MinFixed,
|
||||||
|
MaxFixed,
|
||||||
|
PosDecode,
|
||||||
|
EntireRange,
|
||||||
|
0x00000000, // Granularity
|
||||||
|
0, // Min Base Address
|
||||||
|
0xffff, // Max Base Address
|
||||||
|
SBSA_PCIE_PIO_BASE, // Translate
|
||||||
|
0x10000, // Length
|
||||||
|
,,,TypeTranslation
|
||||||
|
)
|
||||||
|
}) // Name(RBUF)
|
||||||
|
|
||||||
|
Return (RBUF)
|
||||||
|
} // Method(_CRS)
|
||||||
|
|
||||||
|
// OS Control Handoff
|
||||||
|
Name (SUPP, Zero) // PCI _OSC Support Field value
|
||||||
|
Name (CTRL, Zero) // PCI _OSC Control Field value
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See [1] 6.2.10, [2] 4.5
|
||||||
|
*/
|
||||||
|
Method (_OSC,4) {
|
||||||
|
// Check for proper UUID
|
||||||
|
If (Arg0 == ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766")) {
|
||||||
|
// Create DWord-adressable fields from the Capabilities Buffer
|
||||||
|
CreateDWordField (Arg3,0,CDW1)
|
||||||
|
CreateDWordField (Arg3,4,CDW2)
|
||||||
|
CreateDWordField (Arg3,8,CDW3)
|
||||||
|
|
||||||
|
// Save Capabilities DWord2 & 3
|
||||||
|
SUPP = CDW2
|
||||||
|
CTRL = CDW3
|
||||||
|
|
||||||
|
// Only allow native hot plug control if OS supports:
|
||||||
|
// * ASPM
|
||||||
|
// * Clock PM
|
||||||
|
// * MSI/MSI-X
|
||||||
|
If ((SUPP & 0x16) != 0x16) {
|
||||||
|
CTRL &= 0x1E // Mask bit 0 (and undefined bits)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always allow native PME, AER (no dependencies)
|
||||||
|
|
||||||
|
// Never allow SHPC (no SHPC controller in this system)
|
||||||
|
CTRL &= 0x1D
|
||||||
|
|
||||||
|
If (Arg1 != One) { // Unknown revision
|
||||||
|
CDW1 |= 0x08
|
||||||
|
}
|
||||||
|
|
||||||
|
If (CDW3 != CTRL) { // Capabilities bits were masked
|
||||||
|
CDW1 |= 0x10
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update DWORD3 in the buffer
|
||||||
|
CDW3 = CTRL
|
||||||
|
Return (Arg3)
|
||||||
|
} Else {
|
||||||
|
CDW1 |= 4 // Unrecognized UUID
|
||||||
|
Return (Arg3)
|
||||||
|
}
|
||||||
|
} // End _OSC
|
||||||
|
}
|
||||||
|
} // Scope (_SB)
|
||||||
|
}
|
23
src/mainboard/emulation/qemu-sbsa/flash.fmd
Normal file
23
src/mainboard/emulation/qemu-sbsa/flash.fmd
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#
|
||||||
|
# custom fmap which takes the additional TF-A region into account
|
||||||
|
#
|
||||||
|
# +-------------+ <-- 0x0
|
||||||
|
# | TF-A |
|
||||||
|
# +-------------+ <-- BIOS_BASE
|
||||||
|
# | bootblock |
|
||||||
|
# +-------------+ <-- BIOS_BASE + 128K
|
||||||
|
# | FMAP |
|
||||||
|
# +-------------+ <-- BIOS_BASE + 128K + FMAP_SIZE
|
||||||
|
# | CBFS |
|
||||||
|
# +-------------+ <-- ROM_SIZE
|
||||||
|
#
|
||||||
|
|
||||||
|
FLASH@0x10000000 CONFIG_ROM_SIZE {
|
||||||
|
|
||||||
|
BIOS {
|
||||||
|
|
||||||
|
BOOTBLOCK 128K
|
||||||
|
FMAP 0x200
|
||||||
|
COREBOOT(CBFS)
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,32 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Base addresses for QEMU sbsa-ref machine
|
||||||
|
* [hw/arm/sbsa-ref.c, c6f3cbca32bde9ee94d9949aa63e8a7ef2d7bc5b]
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SBSA_FLASH_BASE 0x00000000
|
||||||
|
#define SBSA_FLASH_SIZE 0x20000000
|
||||||
|
#define SBSA_GIC_DIST 0x40060000
|
||||||
|
#define SBSA_GIC_REDIST 0x40080000
|
||||||
|
#define SBSA_GWDT_REFRESH 0x50010000
|
||||||
|
#define SBSA_GWDT_CONTROL 0x50011000
|
||||||
|
#define SBSA_UART_BASE 0x60000000
|
||||||
|
#define SBSA_RTC_BASE 0x60010000
|
||||||
|
#define SBSA_GPIO_BASE 0x60020000
|
||||||
|
#define SBSA_SECURE_UART_BASE 0x60030000
|
||||||
|
#define SBSA_SMMU_BASE 0x60050000
|
||||||
|
#define SBSA_AHCI_BASE 0x60100000
|
||||||
|
#define SBSA_EHCI_BASE 0x60110000
|
||||||
|
#define SBSA_SECMEM_BASE 0x20000000
|
||||||
|
#define SBSA_SECMEM_SIZE 0x20000000
|
||||||
|
#define SBSA_PCIE_MMIO_BASE 0x80000000
|
||||||
|
#define SBSA_PCIE_MMIO_LIMIT 0xefffffff
|
||||||
|
#define SBSA_PCIE_MMIO_SIZE 0x70000000
|
||||||
|
#define SBSA_PCIE_PIO_BASE 0x7fff0000
|
||||||
|
#define SBSA_PCIE_ECAM_BASE 0xf0000000
|
||||||
|
#define SBSA_PCIE_ECAM_LIMIT 0xffffffff
|
||||||
|
#define SBSA_PCIE_ECAM_SIZE 0x10000000
|
||||||
|
#define SBSA_PCIE_MMIO_HIGH_BASE 0x100000000
|
||||||
|
#define SBSA_PCIE_MMIO_HIGH_LIMIT 0xffffffffff
|
||||||
|
#define SBSA_PCIE_MMIO_HIGH_SIZE 0xff00000000
|
170
src/mainboard/emulation/qemu-sbsa/mainboard.c
Normal file
170
src/mainboard/emulation/qemu-sbsa/mainboard.c
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
#include "chip.h"
|
||||||
|
#include <acpi/acpigen.h>
|
||||||
|
#include <arch/mmu.h>
|
||||||
|
#include <bootmem.h>
|
||||||
|
#include <cbfs.h>
|
||||||
|
#include <device/device.h>
|
||||||
|
#include <device_tree.h>
|
||||||
|
#include <bootmem.h>
|
||||||
|
#include <arch/mmu.h>
|
||||||
|
#include <mainboard/addressmap.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <symbols.h>
|
||||||
|
|
||||||
|
static size_t ram_size(void)
|
||||||
|
{
|
||||||
|
return (size_t)cbmem_top() - (uintptr_t)_dram;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mainboard_init(void *chip_info)
|
||||||
|
{
|
||||||
|
mmu_config_range(_dram, ram_size(), MA_MEM | MA_RW);
|
||||||
|
}
|
||||||
|
|
||||||
|
void smbios_cpu_get_core_counts(u16 *core_count, u16 *thread_count)
|
||||||
|
{
|
||||||
|
*core_count = 0;
|
||||||
|
struct device *dev = NULL;
|
||||||
|
while ((dev = dev_find_path(dev, DEVICE_PATH_GICC_V3)))
|
||||||
|
*core_count += 1;
|
||||||
|
|
||||||
|
*thread_count = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void qemu_aarch64_init(struct device *dev)
|
||||||
|
{
|
||||||
|
struct memory_info *mem_info;
|
||||||
|
|
||||||
|
mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(*mem_info));
|
||||||
|
if (mem_info == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
memset(mem_info, 0, sizeof(*mem_info));
|
||||||
|
|
||||||
|
mem_info->ecc_type = MEMORY_ARRAY_ECC_UNKNOWN;
|
||||||
|
mem_info->max_capacity_mib = 0x800000; // Fixed at 8 TiB for qemu-sbsa
|
||||||
|
mem_info->number_of_devices = mem_info->dimm_cnt = 1;
|
||||||
|
|
||||||
|
mem_info->dimm[0].dimm_size = ram_size() / MiB;
|
||||||
|
mem_info->dimm[0].ddr_type = MEMORY_TYPE_DRAM;
|
||||||
|
mem_info->dimm[0].ddr_frequency = 0;
|
||||||
|
mem_info->dimm[0].channel_num = mem_info->dimm[0].dimm_num = 0;
|
||||||
|
mem_info->dimm[0].bank_locator = 0;
|
||||||
|
|
||||||
|
mem_info->dimm[0].bus_width = 0x03; // 64-bit, no parity
|
||||||
|
mem_info->dimm[0].vdd_voltage = 0;
|
||||||
|
mem_info->dimm[0].max_speed_mts = mem_info->dimm[0].configured_speed_mts = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned long mb_write_acpi_tables(const struct device *dev, unsigned long current,
|
||||||
|
acpi_rsdp_t *rsdp)
|
||||||
|
{
|
||||||
|
printk(BIOS_DEBUG, "ACPI: * DBG2\n");
|
||||||
|
return acpi_pl011_write_dbg2_uart(rsdp, current, SBSA_UART_BASE, "\\_SB.COM0");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void mainboard_enable(struct device *dev)
|
||||||
|
{
|
||||||
|
dev->ops->init = qemu_aarch64_init;
|
||||||
|
dev->ops->write_acpi_tables = mb_write_acpi_tables;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct chip_operations mainboard_ops = {
|
||||||
|
.enable_dev = mainboard_enable,
|
||||||
|
.init = mainboard_init,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct chip_operations mainboard_emulation_qemu_sbsa_ops = { };
|
||||||
|
|
||||||
|
static void qemu_aarch64_domain_read_resources(struct device *dev)
|
||||||
|
{
|
||||||
|
struct resource *res;
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
/* Initialize the system-wide I/O space constraints. */
|
||||||
|
res = new_resource(dev, index++);
|
||||||
|
res->limit = 0xffffUL;
|
||||||
|
res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED;
|
||||||
|
|
||||||
|
/* Initialize the system-wide memory resources constraints. */
|
||||||
|
res = new_resource(dev, index++);
|
||||||
|
res->base = SBSA_PCIE_MMIO_BASE;
|
||||||
|
res->limit = SBSA_PCIE_MMIO_LIMIT;
|
||||||
|
res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED;
|
||||||
|
|
||||||
|
res = new_resource(dev, index++);
|
||||||
|
res->base = SBSA_PCIE_MMIO_HIGH_BASE;
|
||||||
|
res->limit = SBSA_PCIE_MMIO_HIGH_LIMIT;
|
||||||
|
res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED;
|
||||||
|
|
||||||
|
mmio_range(dev, index++, SBSA_PCIE_ECAM_BASE, SBSA_PCIE_ECAM_SIZE);
|
||||||
|
|
||||||
|
ram_range(dev, index++, (uintptr_t)_dram, ram_size());
|
||||||
|
|
||||||
|
mmio_range(dev, index++, SBSA_FLASH_BASE, SBSA_FLASH_SIZE);
|
||||||
|
reserved_ram_range(dev, index++, SBSA_SECMEM_BASE, SBSA_SECMEM_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct device_operations qemu_aarch64_pci_domain_ops = {
|
||||||
|
.read_resources = qemu_aarch64_domain_read_resources,
|
||||||
|
.set_resources = pci_domain_set_resources,
|
||||||
|
.scan_bus = pci_host_bridge_scan_bus,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void qemu_sbsa_fill_cpu_ssdt(const struct device *dev)
|
||||||
|
{
|
||||||
|
acpigen_write_processor_device(dev->path.gicc_v3.mpidr);
|
||||||
|
acpigen_write_processor_device_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct device_operations qemu_sbsa_cpu_ops = {
|
||||||
|
.acpi_fill_ssdt = qemu_sbsa_fill_cpu_ssdt,
|
||||||
|
};
|
||||||
|
|
||||||
|
DECLARE_REGION(fdt_pointer)
|
||||||
|
static void qemu_aarch64_scan_bus(struct device *dev)
|
||||||
|
{
|
||||||
|
struct bus *bus = alloc_bus(dev);
|
||||||
|
uintptr_t fdt_blob = *(uintptr_t *)_fdt_pointer;
|
||||||
|
struct device_tree *tree;
|
||||||
|
struct device_tree_node *node;
|
||||||
|
char path[14];
|
||||||
|
u16 fdt_cpu_count = 0;
|
||||||
|
struct mainboard_emulation_qemu_sbsa_config *config = dev->chip_info;
|
||||||
|
|
||||||
|
tree = fdt_unflatten((void *)fdt_blob);
|
||||||
|
if (tree == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
snprintf(path, sizeof(path), "/cpus/cpu@%d", fdt_cpu_count);
|
||||||
|
while ((node = dt_find_node_by_path(tree, path, NULL, NULL, 0)) != NULL) {
|
||||||
|
struct device_tree_property *prop;
|
||||||
|
int64_t mpidr = -1;
|
||||||
|
list_for_each(prop, node->properties, list_node) {
|
||||||
|
if (!strcmp("reg", prop->prop.name)) {
|
||||||
|
mpidr = be64toh(*(uint64_t *)prop->prop.data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mpidr >= 0) {
|
||||||
|
struct device_path devpath = { .type = DEVICE_PATH_GICC_V3,
|
||||||
|
.gicc_v3 = { .mpidr = mpidr,
|
||||||
|
.vgic_mi = config->vgic_maintenance_interrupt,
|
||||||
|
.pi_gsiv = config->performance_interrupt_gsiv, },
|
||||||
|
|
||||||
|
};
|
||||||
|
struct device *cpu = alloc_dev(bus, &devpath);
|
||||||
|
assert(cpu);
|
||||||
|
cpu->ops = &qemu_sbsa_cpu_ops;
|
||||||
|
}
|
||||||
|
snprintf(path, sizeof(path), "/cpus/cpu@%d", ++fdt_cpu_count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct device_operations qemu_aarch64_cpu_ops = {
|
||||||
|
.scan_bus = qemu_aarch64_scan_bus,
|
||||||
|
};
|
12
src/mainboard/emulation/qemu-sbsa/media.c
Normal file
12
src/mainboard/emulation/qemu-sbsa/media.c
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
#include <boot_device.h>
|
||||||
|
|
||||||
|
/* Maps directly to NOR flash up to ROM size. */
|
||||||
|
static const struct mem_region_device boot_dev =
|
||||||
|
MEM_REGION_DEV_RO_INIT((void *)0x10000000, CONFIG_ROM_SIZE);
|
||||||
|
|
||||||
|
const struct region_device *boot_device_ro(void)
|
||||||
|
{
|
||||||
|
return &boot_dev.rdev;
|
||||||
|
}
|
25
src/mainboard/emulation/qemu-sbsa/memlayout.ld
Normal file
25
src/mainboard/emulation/qemu-sbsa/memlayout.ld
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
#include <memlayout.h>
|
||||||
|
#include <arch/header.ld>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Memory map for QEMU sbsa-ref machine since
|
||||||
|
* [hw/arm/sbsa-ref.c, c6f3cbca32bde9ee94d9949aa63e8a7ef2d7bc5b]
|
||||||
|
*/
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
REGION(flash, 0x10000000, CONFIG_ROM_SIZE, 8)
|
||||||
|
|
||||||
|
DRAM_START(0x10000000000)
|
||||||
|
BOOTBLOCK(0x10020010000, 64K)
|
||||||
|
STACK(0x10020020000, 54K)
|
||||||
|
CBFS_MCACHE(0x1002002D800, 8K)
|
||||||
|
FMAP_CACHE(0x1002002F800, 2K)
|
||||||
|
TIMESTAMP(0x10020030000, 1K)
|
||||||
|
TTB(0x10020070000, 128K)
|
||||||
|
RAMSTAGE(0x100200b0000, 16M)
|
||||||
|
REGION(fdt_pointer, 0x100210b0000, ARCH_POINTER_ALIGN_SIZE, ARCH_POINTER_ALIGN_SIZE)
|
||||||
|
|
||||||
|
POSTRAM_CBFS_CACHE(0x10021200000, 1M)
|
||||||
|
}
|
9
src/mainboard/emulation/qemu-sbsa/mmio.c
Normal file
9
src/mainboard/emulation/qemu-sbsa/mmio.c
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
#include <console/uart.h>
|
||||||
|
#include <mainboard/addressmap.h>
|
||||||
|
|
||||||
|
uintptr_t uart_platform_base(unsigned int idx)
|
||||||
|
{
|
||||||
|
return SBSA_UART_BASE;
|
||||||
|
}
|
Reference in New Issue
Block a user