From 0f06d8e158e90836a640bd67791562d8e38e5f37 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Sun, 23 Feb 2025 15:34:55 +0100 Subject: [PATCH] soc/amd/common/block/lpc: Add ROM2 and ROM3 helper functions Add functions to return the position and size of the ROM2 and ROM3 MMIO windows that mmap the SPI flash. Starting from AMD Family 17h Model 30h (Zen 2) the ROM3 BAR is available. ROM3 is not supported on picasso or stoneyridge. Document ID: 56780 TEST: Verified that both functions return sane values. Change-Id: I10d4f0fe8a38e0ba2784a9839270d5dd3398d47a Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/86583 Tested-by: build bot (Jenkins) Reviewed-by: Felix Held --- .../amd/common/block/include/amdblocks/lpc.h | 5 ++ src/soc/amd/common/block/lpc/lpc_util.c | 46 +++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/soc/amd/common/block/include/amdblocks/lpc.h b/src/soc/amd/common/block/include/amdblocks/lpc.h index 558b608743..f85c4676cc 100644 --- a/src/soc/amd/common/block/include/amdblocks/lpc.h +++ b/src/soc/amd/common/block/include/amdblocks/lpc.h @@ -105,6 +105,8 @@ #define LPC_WIDEIO2_GENERIC_PORT 0x90 +#define ROM_ADDRESS_RANGE3_START 0xa8 + #define LPC_ROM_DMA_SRC_ADDR 0xb0 #define LPC_ROM_DMA_DST_ADDR 0xb4 /* LPC register 0xb8 is DWORD, here there are definitions for byte @@ -140,6 +142,9 @@ void lpc_tpm_decode(void); void lpc_tpm_decode_spi(void); void lpc_enable_rom(void); void lpc_enable_spi_prefetch(void); +uint32_t lpc_get_rom2_region(size_t *bios_size); +uint64_t lpc_get_rom3_region(size_t *bios_size); + void lpc_disable_spi_rom_sharing(void); /** diff --git a/src/soc/amd/common/block/lpc/lpc_util.c b/src/soc/amd/common/block/lpc/lpc_util.c index 4097e6f734..b796f3faa4 100644 --- a/src/soc/amd/common/block/lpc/lpc_util.c +++ b/src/soc/amd/common/block/lpc/lpc_util.c @@ -286,6 +286,52 @@ void lpc_enable_rom(void) pci_write_config16(_LPCB_DEV, ROM_ADDRESS_RANGE2_END, 0xffff); } +/** + * Returns ROM2 MMIO SPI flash region in the lower MMIO space. + * The maximum window size is 16 MiB. It always resides in the 32-bit + * address space. + * + * @param bios_size Pointer where to store the ROM2 region size in bytes + * @return 32-bit base address of the ROM2 region. + */ +uint32_t lpc_get_rom2_region(size_t *bios_size) +{ + uint16_t start = pci_read_config16(_LPCB_DEV, ROM_ADDRESS_RANGE2_START); + uint16_t end = pci_read_config16(_LPCB_DEV, ROM_ADDRESS_RANGE2_END); + + uint32_t rom2_start = start << 16; + uint32_t rom2_end = (end << 16) | 0xffff; + + if (rom2_end <= rom2_start) { + *bios_size = 0; + return 0; + } + + *bios_size = rom2_end - rom2_start + 1; + + return rom2_start; +} + +/** + * Returns ROM3 MMIO SPI flash region in the high MMIO space. + * Default at 0xfd00000000. The maximum window size is 64 MiB. + * + * @param bios_size Pointer where to store the ROM3 region size in bytes + * @return 64-bit base address of the ROM3 region. + */ +uint64_t lpc_get_rom3_region(size_t *bios_size) +{ + uint32_t lower = pci_read_config32(_LPCB_DEV, ROM_ADDRESS_RANGE3_START); + uint32_t upper = pci_read_config32(_LPCB_DEV, ROM_ADDRESS_RANGE3_START + 4); + + if (lower || upper) + *bios_size = MIN(CONFIG_ROM_SIZE, 64 * MiB); + else + *bios_size = 0; + + return ((uint64_t)upper << 32) | lower; +} + void lpc_enable_spi_prefetch(void) { uint32_t dword;