From 7e3c1ced40e83e0a266cde519eea49eab4709807 Mon Sep 17 00:00:00 2001 From: Martin Roth Date: Fri, 14 Oct 2022 14:08:22 -0600 Subject: [PATCH] soc/amd/common: Add code to print AMD STB to boot log This allows platforms that support AMD's STB (Smart Trace Buffer) to print the buffer at various points in the boot process. The STB is roughly a hardware assisted postcode that captures the time stamp of when the postcode was added to the buffer. Reading from the STB clears the data. Signed-off-by: Martin Roth Change-Id: I8d78c0e86b244f3bd16248edf3850447fb0a9e2c Reviewed-on: https://review.coreboot.org/c/coreboot/+/68543 Tested-by: build bot (Jenkins) Reviewed-by: Fred Reitberger --- .../amd/common/block/include/amdblocks/stb.h | 21 ++++++ src/soc/amd/common/block/stb/Kconfig | 17 +++++ src/soc/amd/common/block/stb/Makefile.inc | 7 ++ src/soc/amd/common/block/stb/stb.c | 67 +++++++++++++++++++ 4 files changed, 112 insertions(+) create mode 100644 src/soc/amd/common/block/include/amdblocks/stb.h create mode 100644 src/soc/amd/common/block/stb/Kconfig create mode 100644 src/soc/amd/common/block/stb/Makefile.inc create mode 100644 src/soc/amd/common/block/stb/stb.c diff --git a/src/soc/amd/common/block/include/amdblocks/stb.h b/src/soc/amd/common/block/include/amdblocks/stb.h new file mode 100644 index 0000000000..51b01948f8 --- /dev/null +++ b/src/soc/amd/common/block/include/amdblocks/stb.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef AMD_BLOCK_STB_H +#define AMD_BLOCK_STB_H + +#include + +#define AMD_STB_PMI_0 0x30600 + +#define AMD_STB_COREBOOT_MARKER 0xBAADF00D + +struct stb_entry_struct { + uint32_t ts; + uint32_t val; +}; + +void write_stb_to_console(void); +void init_spill_buffer(void); +void add_stb_to_timestamp_buffer(void); + +#endif /* AMD_BLOCK_STB_H */ diff --git a/src/soc/amd/common/block/stb/Kconfig b/src/soc/amd/common/block/stb/Kconfig new file mode 100644 index 0000000000..8935e92556 --- /dev/null +++ b/src/soc/amd/common/block/stb/Kconfig @@ -0,0 +1,17 @@ +config SOC_AMD_COMMON_BLOCK_STB + bool + select SOC_AMD_COMMON_BLOCK_SMN + help + Select in the SOC if it supports the Smart Trace Buffer + +if SOC_AMD_COMMON_BLOCK_STB + +config WRITE_STB_BUFFER_TO_CONSOLE + bool "Write STB entries to the console log" + default n + help + This option will tell coreboot to print the STB buffer at various + points through the boot process. Note that this will prevent the + entries from being stored if the Spill-to-DRAM feature is enabled. + +endif diff --git a/src/soc/amd/common/block/stb/Makefile.inc b/src/soc/amd/common/block/stb/Makefile.inc new file mode 100644 index 0000000000..5ce9c4b228 --- /dev/null +++ b/src/soc/amd/common/block/stb/Makefile.inc @@ -0,0 +1,7 @@ +ifeq ($(CONFIG_SOC_AMD_COMMON_BLOCK_STB),y) + +bootblock-y += stb.c +romstage-y += stb.c +ramstage-y += stb.c + +endif # CONFIG_SOC_AMD_COMMON_BLOCK_STB diff --git a/src/soc/amd/common/block/stb/stb.c b/src/soc/amd/common/block/stb/stb.c new file mode 100644 index 0000000000..074a4ed714 --- /dev/null +++ b/src/soc/amd/common/block/stb/stb.c @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include + +#define STB_ENTRIES_PER_ROW 4 + +static void stb_write32(uint32_t reg, uint32_t val) +{ + smn_write32(STB_CFG_SMN_ADDR + reg, val); +} + +static uint32_t stb_read32(uint32_t reg) +{ + return smn_read32(STB_CFG_SMN_ADDR + reg); +} + +void write_stb_to_console(void) +{ + int i; + int printed_data = 0; + struct stb_entry_struct stb_val; + + /* Add a marker into the STB so it's easy to see where the end is. */ + stb_write32(AMD_STB_PMI_0, AMD_STB_COREBOOT_MARKER); + + for (i = 0; i < AMD_STB_SDRAM_FIFO_SIZE; i++) { + /* + * It's possible to do a single read and leave the timestamp as the first + * value of a pair, but by default the value will be first and time stamp + * second. We're just assuming that nothing has messed up the ordering. + */ + stb_val.val = stb_read32(AMD_STB_PMI_0); + stb_val.ts = stb_read32(AMD_STB_PMI_0); + + if (stb_val.val == AMD_STB_COREBOOT_MARKER) { + if (!printed_data) + printk(BIOS_DEBUG, "No Smart Trace Buffer Data available.\n"); + else + // Don't print the coreboot marker + printk(BIOS_DEBUG, "\n"); + return; + } + + if (i == 0) + printk(BIOS_DEBUG, "Available Smart Trace Buffer data:\n"); + if ((i % STB_ENTRIES_PER_ROW) == 0) + printk(BIOS_DEBUG, "%04d,", i); + printk(BIOS_DEBUG, " 0x%08x,0x%08x, ", stb_val.ts, stb_val.val); + if ((i % STB_ENTRIES_PER_ROW) == STB_ENTRIES_PER_ROW - 1) + printk(BIOS_DEBUG, "\n"); + printed_data = 1; + + } + +} + +static void final_stb_console(void *unused) +{ + if (CONFIG(WRITE_STB_BUFFER_TO_CONSOLE)) + write_stb_to_console(); +} + +BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_BOOT, BS_ON_ENTRY, final_stb_console, NULL);