David Milosevic has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/79108?usp=email )
Change subject: mb/emulation/qemu-sbsa: Generate PPTT ACPI table ......................................................................
mb/emulation/qemu-sbsa: Generate PPTT ACPI table
In order to be compliant to the LBBR spec, we need to generate and export a Processor Properties Topology Table.
Change-Id: Iabeb138c1257488bcb364fe7b522f02c041745e2 Signed-off-by: David Milosevic David.Milosevic@9elements.com --- M src/mainboard/emulation/qemu-sbsa/Kconfig M src/mainboard/emulation/qemu-sbsa/Makefile.inc A src/mainboard/emulation/qemu-sbsa/pptt.c 3 files changed, 149 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/08/79108/1
diff --git a/src/mainboard/emulation/qemu-sbsa/Kconfig b/src/mainboard/emulation/qemu-sbsa/Kconfig index 8719d00..53d44f0 100644 --- a/src/mainboard/emulation/qemu-sbsa/Kconfig +++ b/src/mainboard/emulation/qemu-sbsa/Kconfig @@ -22,6 +22,7 @@ select HAVE_ACPI_TABLES select ACPI_GTDT select ACPI_COMMON_MADT_GICC_V3 + select ACPI_PPTT select GENERATE_SMBIOS_TABLES
config ARM64_CURRENT_EL diff --git a/src/mainboard/emulation/qemu-sbsa/Makefile.inc b/src/mainboard/emulation/qemu-sbsa/Makefile.inc index e3855ba..515f497 100644 --- a/src/mainboard/emulation/qemu-sbsa/Makefile.inc +++ b/src/mainboard/emulation/qemu-sbsa/Makefile.inc @@ -13,6 +13,7 @@ ramstage-y += mmio.c
ramstage-y += acpi.c +ramstage-y += pptt.c
bootblock-y += bootblock_custom.S
diff --git a/src/mainboard/emulation/qemu-sbsa/pptt.c b/src/mainboard/emulation/qemu-sbsa/pptt.c new file mode 100644 index 0000000..ac0172f --- /dev/null +++ b/src/mainboard/emulation/qemu-sbsa/pptt.c @@ -0,0 +1,147 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <stdlib.h> +#include <cpu/cpu.h> +#include <arch/cache.h> +#include <acpi/acpi.h> +#include <console/console.h> + +#define CACHE_NODE_FLAGS 0xd7 // everything valid except, write-policy and allocation type +#define CLUSTER_FLAGS 0x11 // physical package, ID invalid, no thread, no leaf, identical impl. +#define CORE_FLAGS 0x1a // no physical package, ID valid, no thread, leaf, identical impl. + +/* + * L2 cache (LLC) + */ +struct pptt_cache l2 = { + + .next_level = NULL +}; + +/* + * L1I cache + */ +struct pptt_cache l1i = { + + .next_level = &l2 +}; + +/* + * L1D cache + */ +struct pptt_cache l1d = { + + .next_level = &l2 +}; + +/* + * private resources of a cpu core. Same for + * each core, thus we can reuse this struture + * instead of creating it dynamically. + */ +struct pptt_cpu_resources core_resources = { + + .cache = &l1i, + + .next = &(struct pptt_cpu_resources) { + + .cache = &l1d, + .next = NULL + } +}; + +struct pptt_topology root_topology = { + + .flags.raw = CLUSTER_FLAGS, + .resources = NULL, + .sibling = NULL, + .child = NULL // updated in runtime +}; + +/* --- Helpers --- */ + +static u8 cache_attributes(const enum cache_type type) +{ + /* + * 'write-policy' and 'allocation type' currently + * unsupported. cache flags set accordingly. + * + * maybe a todo for the future. + */ + + u8 attr = 0x0; + + if (type == CACHE_INSTRUCTION) + attr |= (0x1 << 2); + else if(type == CACHE_UNIFIED) + attr |= (0x1 << 3); + + return attr; +} + +/* --- ACPI hook --- */ + +struct pptt_topology* acpi_get_pptt_topology(void) +{ + struct cache_info info; + + /* update cache information (L1I) */ + + cpu_get_cache_info(CACHE_L1, CACHE_INSTRUCTION, &info); + + l1i.size = info.size; + l1i.associativity = info.associativity; + l1i.numsets = info.numsets; + l1i.line_size = info.line_bytes; + l1i.attributes = cache_attributes(CACHE_INSTRUCTION); + l1i.flags.raw = CACHE_NODE_FLAGS; + + /* update cache information (L1D) */ + + cpu_get_cache_info(CACHE_L1, CACHE_DATA, &info); + + l1d.size = info.size; + l1d.associativity = info.associativity; + l1d.numsets = info.numsets; + l1d.line_size = info.line_bytes; + l1d.attributes = cache_attributes(CACHE_DATA); + l1d.flags.raw = CACHE_NODE_FLAGS; + + /* update cache information (L2) */ + + cpu_get_cache_info(CACHE_L2, CACHE_UNIFIED, &info); + + l2.size = info.size; + l2.associativity = info.associativity; + l2.numsets = info.numsets; + l2.line_size = info.line_bytes; + l2.attributes = cache_attributes(CACHE_UNIFIED); + l2.flags.raw = CACHE_NODE_FLAGS; + + /* add secondary CPUs */ + + u32 cpu_id = 0; + + struct device *dev = NULL; + struct pptt_topology **it = &root_topology.child; + + while ((dev = dev_find_path(dev, DEVICE_PATH_GICC_V3))) { + + if ((*it = malloc(sizeof(struct pptt_topology))) == NULL) { + + printk(BIOS_ERR, "Could not allocate pptt structure!\n"); + break; + } + + memset(*it, 0, sizeof(struct pptt_topology)); + + (*it)->processor_id = cpu_id; + (*it)->flags.raw = CORE_FLAGS; + (*it)->resources = &core_resources; + + it = &(*it)->sibling; + cpu_id += 1; + } + + return &root_topology; +}