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 <gaumless@gmail.com>
Change-Id: I8d78c0e86b244f3bd16248edf3850447fb0a9e2c
Reviewed-on: https://review.coreboot.org/c/coreboot/+/68543
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Fred Reitberger <reitbergerfred@gmail.com>
This commit is contained in:
Martin Roth 2022-10-14 14:08:22 -06:00 committed by Martin Roth
parent f7a09278b6
commit 7e3c1ced40
4 changed files with 112 additions and 0 deletions

View File

@ -0,0 +1,21 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef AMD_BLOCK_STB_H
#define AMD_BLOCK_STB_H
#include <types.h>
#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 */

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,67 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <amdblocks/smn.h>
#include <amdblocks/stb.h>
#include <bootstate.h>
#include <console/console.h>
#include <soc/stb.h>
#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);