soc/amd/picasso: Place early stages and data buffers at the bottom of DRAM

This change updates memlayout.ld for Picasso to place all early
stages (bootblock, romstage, FSP-M, verstage) and data buffers (vboot
workbuf, APOB, preram-cbmem console, timestamp, early BSP stack) at
the bottom of DRAM starting at 32MiB. This uses static allocation for
most components by defining Kconfig variables for base and size. It
relies on the linker to complain if any of the assumptions are broken.

This also allows romstage to use linker symbols for
_early_reserved_dram and _eearly_reserved_dram to store information in
CBMEM about the early DRAM usage by coreboot before ramstage starts
execution. This allows ramstage to reserve this memory region in BIOS
tables so that S3 resume can reuse the same space without corrupting
OS memory.

BUG=b:155322763
TEST=Verified memory reported by coreboot:
Writing coreboot table at 0xcc656000
 0. 0000000000000000-0000000000000fff: CONFIGURATION TABLES
 1. 0000000000001000-000000000009ffff: RAM
 2. 00000000000a0000-00000000000fffff: RESERVED
 3. 0000000000100000-0000000001ffffff: RAM
 4. 0000000002000000-000000000223ffff: RESERVED
 5. 0000000002240000-00000000cc512fff: RAM
 6. 00000000cc513000-00000000cc6bffff: CONFIGURATION TABLES
 7. 00000000cc6c0000-00000000cc7c7fff: RAMSTAGE
 8. 00000000cc7c8000-00000000cd7fffff: CONFIGURATION TABLES
 9. 00000000cd800000-00000000cfffffff: RESERVED
10. 00000000f8000000-00000000fbffffff: RESERVED
11. 0000000100000000-000000042f33ffff: RAM
12. 000000042f340000-000000042fffffff: RESERVED

Signed-off-by: Furquan Shaikh <furquan@google.com>
Change-Id: I009e1ea71b5b5a8e65eba16911897b2586ccfdb6
Reviewed-on: https://review.coreboot.org/c/coreboot/+/42264
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
This commit is contained in:
Furquan Shaikh 2020-06-10 16:37:23 -07:00
parent c3bb6923bd
commit bc45650b5f
6 changed files with 309 additions and 47 deletions

View File

@ -60,12 +60,122 @@ config MEMLAYOUT_LD_FILE
string string
default "src/soc/amd/picasso/memlayout.ld" default "src/soc/amd/picasso/memlayout.ld"
config EARLY_RESERVED_DRAM_BASE
hex
default 0x2000000
help
This variable defines the base address of the DRAM which is reserved
for usage by coreboot in early stages (i.e. before ramstage is up).
This memory gets reserved in BIOS tables to ensure that the OS does
not use it, thus preventing corruption of OS memory in case of S3
resume.
config EARLYRAM_BSP_STACK_SIZE
hex
default 0x1000
config PSP_APOB_DRAM_ADDRESS
hex
default 0x2001000
help
Location in DRAM where the PSP will copy the AGESA PSP Output
Block.
config PSP_SHAREDMEM_BASE
hex
default 0x2011000 if VBOOT
default 0x0
help
This variable defines the base address in DRAM memory where PSP copies
vboot workbuf to. This is used in linker script to have a static
allocation for the buffer as well as for adding relevant entries in
BIOS directory table for the PSP.
config PSP_SHAREDMEM_SIZE
hex
default 0x8000 if VBOOT
default 0x0
help
Sets the maximum size for the PSP to pass the vboot workbuf and
any logs or timestamps back to coreboot. This will be copied
into main memory by the PSP and will be available when the x86 is
started. The workbuf's base depends on the address of the reset
vector.
config PRERAM_CBMEM_CONSOLE_SIZE config PRERAM_CBMEM_CONSOLE_SIZE
hex hex
default 0x1600 default 0x1600
help help
Increase this value if preram cbmem console is getting truncated Increase this value if preram cbmem console is getting truncated
config BOOTBLOCK_ADDR
hex
default 0x2030000
help
Sets the address in DRAM where bootblock should be loaded.
config C_ENV_BOOTBLOCK_SIZE
hex
default 0x10000
help
Sets the size of the bootblock stage that should be loaded in DRAM.
This variable controls the DRAM allocation size in linker script
for bootblock stage.
config X86_RESET_VECTOR
hex
depends on ARCH_X86
default 0x203fff0
help
Sets the reset vector within bootblock where x86 starts execution.
Reset vector is supposed to live at offset -0x10 from end of
bootblock i.e. BOOTBLOCK_ADDR + C_ENV_BOOTBLOCK_SIZE - 0x10.
config ROMSTAGE_ADDR
hex
default 0x2040000
help
Sets the address in DRAM where romstage should be loaded.
config ROMSTAGE_SIZE
hex
default 0x80000
help
Sets the size of DRAM allocation for romstage in linker script.
config FSP_M_ADDR
hex
default 0x20C0000
help
Sets the address in DRAM where FSP-M should be loaded. cbfstool
performs relocation of FSP-M to this address.
config FSP_M_SIZE
hex
default 0x80000
help
Sets the size of DRAM allocation for FSP-M in linker script.
config VERSTAGE_ADDR
hex
depends on VBOOT_SEPARATE_VERSTAGE
default 0x2140000
help
Sets the address in DRAM where verstage should be loaded if running
as a separate stage on x86.
config VERSTAGE_SIZE
hex
depends on VBOOT_SEPARATE_VERSTAGE
default 0x80000
help
Sets the size of DRAM allocation for verstage in linker script if
running as a separate stage on x86.
config RAMBASE
hex
default 0x10000000
config CPU_ADDR_BITS config CPU_ADDR_BITS
int int
default 48 default 48
@ -234,18 +344,6 @@ config MAINBOARD_POWER_RESTORE
return to S0. Otherwise the system will remain in S5 once power return to S0. Otherwise the system will remain in S5 once power
is restored. is restored.
config FSP_M_ADDR
hex
default 0x90000000
config X86_RESET_VECTOR
hex
default 0x807fff0
config EARLYRAM_BSP_STACK_SIZE
hex
default 0x800
config FSP_TEMP_RAM_SIZE config FSP_TEMP_RAM_SIZE
hex hex
depends on FSP_USES_CB_STACK depends on FSP_USES_CB_STACK
@ -300,13 +398,6 @@ config AMD_PUBKEY_FILE
string string
default "3rdparty/amd_blobs/picasso/PSP/AmdPubKeyRV.bin" default "3rdparty/amd_blobs/picasso/PSP/AmdPubKeyRV.bin"
config PSP_APOB_DRAM_ADDRESS
hex
default 0x9f00000
help
Location in DRAM where the PSP will copy the AGESA PSP Output
Block.
config USE_PSPSCUREOS config USE_PSPSCUREOS
bool bool
default y default y

View File

@ -0,0 +1,18 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef __SOC_AMD_PICASSO_MEMMAP_H__
#define __SOC_AMD_PICASSO_MEMMAP_H__
#include <symbols.h>
DECLARE_REGION(early_reserved_dram)
struct memmap_early_dram {
uint32_t base;
uint32_t size;
};
void memmap_stash_early_dram_usage(void);
const struct memmap_early_dram *memmap_get_early_dram_usage(void);
#endif /* __SOC_AMD_PICASSO_MEMMAP_H__ */

View File

@ -3,39 +3,94 @@
#include <memlayout.h> #include <memlayout.h>
#include <arch/header.ld> #include <arch/header.ld>
#define EARLY_MEMLAYOUT "src/arch/x86/early_ram.ld" #define EARLY_RESERVED_DRAM_START(addr) SYMBOL(early_reserved_dram, addr)
#define EARLY_RESERVED_DRAM_END(addr) SYMBOL(eearly_reserved_dram, addr)
#define PSP_SHAREDMEM_DRAM_START(addr) SYMBOL(psp_sharedmem_dram, addr)
#define PSP_SHAREDMEM_DRAM_END(addr) SYMBOL(epsp_sharedmem_dram, addr)
/*
*
* +--------------------------------+
* | |
* | |
* | |
* | |
* | |
* | |
* | |
* reserved_dram_end +--------------------------------+
* | |
* | verstage (if reqd) |
* | (VERSTAGE_SIZE) |
* +--------------------------------+ VERSTAGE_ADDR
* | |
* | FSP-M |
* | (FSP_M_SIZE) |
* +--------------------------------+ FSP_M_ADDR
* | |X86_RESET_VECTOR = ROMSTAGE_ADDR + ROMSTAGE_SIZE - 0x10
* | romstage |
* | (ROMSTAGE_SIZE) |
* +--------------------------------+ ROMSTAGE_ADDR
* | bootblock |
* | (C_ENV_BOOTBLOCK_SIZE) |
* +--------------------------------+ BOOTBLOCK_ADDR
* | Unused hole |
* +--------------------------------+
* | FMAP cache (FMAP_SIZE) |
* +--------------------------------+ PSP_SHAREDMEM_BASE + PSP_SHAREDMEM_SIZE + PRERAM_CBMEM_CONSOLE_SIZE + 0x200
* | Early Timestamp region (512B) |
* +--------------------------------+ PSP_SHAREDMEM_BASE + PSP_SHAREDMEM_SIZE + PRERAM_CBMEM_CONSOLE_SIZE
* | Preram CBMEM console |
* | (PRERAM_CBMEM_CONSOLE_SIZE) |
* +--------------------------------+ PSP_SHAREDMEM_BASE + PSP_SHAREDMEM_SIZE
* | PSP shared (vboot workbuf) |
* | (PSP_SHAREDMEM_SIZE) |
* +--------------------------------+ PSP_SHAREDMEM_BASE
* | APOB (64KiB) |
* +--------------------------------+ PSP_APOB_DRAM_ADDRESS
* | Early BSP stack |
* | (EARLYRAM_BSP_STACK_SIZE) |
* reserved_dram_start +--------------------------------+ EARLY_RESERVED_DRAM_BASE
* | DRAM |
* +--------------------------------+ 0x100000
* | Option ROM |
* +--------------------------------+ 0xc0000
* | Legacy VGA |
* +--------------------------------+ 0xa0000
* | DRAM |
* +--------------------------------+ 0x0
*/
SECTIONS SECTIONS
{ {
/* DRAM_START(0x0)
* It would be good to lay down RAMSTAGE, ROMSTAGE, etc consecutively
* like other architectures/chipsets it's not possible because of
* the linking games played during romstage creation by trying
* to find the final landing place in CBFS for XIP. Therefore,
* conditionalize with macros.
*/
#if ENV_RAMSTAGE
RAMSTAGE(CONFIG_RAMBASE, (CONFIG(RELOCATABLE_RAMSTAGE) ? 8M :
CONFIG_RAMTOP - CONFIG_RAMBASE))
#elif ENV_ROMSTAGE EARLY_RESERVED_DRAM_START(CONFIG_EARLY_RESERVED_DRAM_BASE)
/* The 1M size is not allocated. It's just for basic size checking.
* Link at 32MiB address and rely on cbfstool to relocate to XIP. */
ROMSTAGE(CONFIG_ROMSTAGE_ADDR, 1M)
#include EARLY_MEMLAYOUT EARLYRAM_STACK(., CONFIG_EARLYRAM_BSP_STACK_SIZE)
#elif ENV_SEPARATE_VERSTAGE REGION(apob, CONFIG_PSP_APOB_DRAM_ADDRESS, 64K, 1)
/* The 1M size is not allocated. It's just for basic size checking.
* Link at 32MiB address and rely on cbfstool to relocate to XIP. */
VERSTAGE(CONFIG_VERSTAGE_ADDR, 1M)
#include EARLY_MEMLAYOUT #if CONFIG(VBOOT)
#elif ENV_BOOTBLOCK PSP_SHAREDMEM_DRAM_START(CONFIG_PSP_SHAREDMEM_BASE)
BOOTBLOCK(CONFIG_X86_RESET_VECTOR - CONFIG_C_ENV_BOOTBLOCK_SIZE + 0x10, VBOOT2_WORK(., VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE)
CONFIG_C_ENV_BOOTBLOCK_SIZE) PSP_SHAREDMEM_DRAM_END(CONFIG_PSP_SHAREDMEM_BASE + CONFIG_PSP_SHAREDMEM_SIZE)
#include EARLY_MEMLAYOUT
#endif #endif
PRERAM_CBMEM_CONSOLE(., CONFIG_PRERAM_CBMEM_CONSOLE_SIZE)
TIMESTAMP(., 0x200)
FMAP_CACHE(., FMAP_SIZE)
_ = ASSERT((CONFIG_BOOTBLOCK_ADDR + CONFIG_C_ENV_BOOTBLOCK_SIZE - 0x10) == CONFIG_X86_RESET_VECTOR, "Reset vector should be -0x10 from end of bootblock");
BOOTBLOCK(CONFIG_BOOTBLOCK_ADDR, CONFIG_C_ENV_BOOTBLOCK_SIZE)
ROMSTAGE(CONFIG_ROMSTAGE_ADDR, CONFIG_ROMSTAGE_SIZE)
REGION(fspm, CONFIG_FSP_M_ADDR, CONFIG_FSP_M_SIZE, 1)
#if CONFIG(VBOOT_SEPARATE_VERSTAGE)
VERSTAGE(CONFIG_VERSTAGE_ADDR, CONFIG_VERSTAGE_SIZE)
#endif
EARLY_RESERVED_DRAM_END(.)
RAMSTAGE(CONFIG_RAMBASE, 8M)
} }
#if ENV_BOOTBLOCK #if ENV_BOOTBLOCK

View File

@ -4,12 +4,14 @@
#include <assert.h> #include <assert.h>
#include <stdint.h> #include <stdint.h>
#include <cbmem.h>
#include <console/console.h> #include <console/console.h>
#include <cpu/x86/smm.h> #include <cpu/x86/smm.h>
#include <cpu/amd/msr.h> #include <cpu/amd/msr.h>
#include <memrange.h> #include <memrange.h>
#include <fsp/util.h> #include <fsp/util.h>
#include <FspGuids.h> #include <FspGuids.h>
#include <soc/memmap.h>
/* /*
* For data stored in TSEG, ensure TValid is clear so R/W access can reach * For data stored in TSEG, ensure TValid is clear so R/W access can reach
@ -57,3 +59,26 @@ void smm_region(uintptr_t *start, size_t *size)
once = 1; once = 1;
} }
} }
void memmap_stash_early_dram_usage(void)
{
struct memmap_early_dram *e;
e = cbmem_add(CBMEM_ID_CB_EARLY_DRAM, sizeof(*e));
if (!e)
die("ERROR: Failed to stash early dram usage!\n");
e->base = (uint32_t)(uintptr_t)_early_reserved_dram;
e->size = REGION_SIZE(early_reserved_dram);
}
const struct memmap_early_dram *memmap_get_early_dram_usage(void)
{
struct memmap_early_dram *e = cbmem_find(CBMEM_ID_CB_EARLY_DRAM);
if (!e)
die("ERROR: Failed to read early dram usage!\n");
return e;
}

View File

@ -12,6 +12,7 @@
#include <program_loading.h> #include <program_loading.h>
#include <elog.h> #include <elog.h>
#include <soc/romstage.h> #include <soc/romstage.h>
#include <soc/memmap.h>
#include <soc/mrc_cache.h> #include <soc/mrc_cache.h>
#include <types.h> #include <types.h>
#include "chip.h" #include "chip.h"
@ -90,6 +91,8 @@ asmlinkage void car_stage_entry(void)
fsp_memory_init(s3_resume); fsp_memory_init(s3_resume);
soc_update_mrc_cache(); soc_update_mrc_cache();
memmap_stash_early_dram_usage();
post_code(0x44); post_code(0x44);
run_ramstage(); run_ramstage();

View File

@ -10,7 +10,61 @@
#include <device/pci_ids.h> #include <device/pci_ids.h>
#include <fsp/util.h> #include <fsp/util.h>
#include <stdint.h> #include <stdint.h>
#include <soc/memmap.h>
/*
*
* +--------------------------------+
* | |
* | |
* | |
* | |
* | |
* | |
* | |
* reserved_dram_end +--------------------------------+
* | |
* | verstage (if reqd) |
* | (VERSTAGE_SIZE) |
* +--------------------------------+ VERSTAGE_ADDR
* | |
* | FSP-M |
* | (FSP_M_SIZE) |
* +--------------------------------+ FSP_M_ADDR
* | |X86_RESET_VECTOR = ROMSTAGE_ADDR + ROMSTAGE_SIZE - 0x10
* | romstage |
* | (ROMSTAGE_SIZE) |
* +--------------------------------+ ROMSTAGE_ADDR
* | bootblock |
* | (C_ENV_BOOTBLOCK_SIZE) |
* +--------------------------------+ BOOTBLOCK_ADDR
* | Unused hole |
* | (86KiB) |
* +--------------------------------+
* | FMAP cache (FMAP_SIZE) |
* +--------------------------------+ PSP_SHAREDMEM_BASE + PSP_SHAREDMEM_SIZE + PRERAM_CBMEM_CONSOLE_SIZE + 0x200
* | Early Timestamp region (512B) |
* +--------------------------------+ PSP_SHAREDMEM_BASE + PSP_SHAREDMEM_SIZE + PRERAM_CBMEM_CONSOLE_SIZE
* | Preram CBMEM console |
* | (PRERAM_CBMEM_CONSOLE_SIZE) |
* +--------------------------------+ PSP_SHAREDMEM_BASE + PSP_SHAREDMEM_SIZE
* | PSP shared (vboot workbuf) |
* | (PSP_SHAREDMEM_SIZE) |
* +--------------------------------+ PSP_SHAREDMEM_BASE
* | APOB (64KiB) |
* +--------------------------------+ PSP_APOB_DRAM_ADDRESS
* | Early BSP stack |
* | (EARLYRAM_BSP_STACK_SIZE) |
* reserved_dram_start +--------------------------------+ EARLY_RESERVED_DRAM_BASE
* | DRAM |
* +--------------------------------+ 0x100000
* | Option ROM |
* +--------------------------------+ 0xc0000
* | Legacy VGA |
* +--------------------------------+ 0xa0000
* | DRAM |
* +--------------------------------+ 0x0
*/
static void read_resources(struct device *dev) static void read_resources(struct device *dev)
{ {
uint32_t mem_usable = (uintptr_t)cbmem_top(); uint32_t mem_usable = (uintptr_t)cbmem_top();
@ -18,6 +72,12 @@ static void read_resources(struct device *dev)
const struct hob_header *hob = fsp_get_hob_list(); const struct hob_header *hob = fsp_get_hob_list();
const struct hob_resource *res; const struct hob_resource *res;
uintptr_t early_reserved_dram_start, early_reserved_dram_end;
const struct memmap_early_dram *e = memmap_get_early_dram_usage();
early_reserved_dram_start = e->base;
early_reserved_dram_end = e->base + e->size;
/* 0x0 - 0x9ffff */ /* 0x0 - 0x9ffff */
ram_resource(dev, idx++, 0, 0xa0000 / KiB); ram_resource(dev, idx++, 0, 0xa0000 / KiB);
@ -27,8 +87,18 @@ static void read_resources(struct device *dev)
/* 0xc0000 - 0xfffff: Option ROM */ /* 0xc0000 - 0xfffff: Option ROM */
reserved_ram_resource(dev, idx++, 0xc0000 / KiB, 0x40000 / KiB); reserved_ram_resource(dev, idx++, 0xc0000 / KiB, 0x40000 / KiB);
/* 1MB to top of low usable RAM */ /* 1MB - bottom of DRAM reserved for early coreboot usage */
ram_resource(dev, idx++, 1 * MiB / KiB, (mem_usable - 1 * MiB) / KiB); ram_resource(dev, idx++, (1 * MiB) / KiB,
(early_reserved_dram_start - (1 * MiB)) / KiB);
/* DRAM reserved for early coreboot usage */
reserved_ram_resource(dev, idx++, early_reserved_dram_start / KiB,
(early_reserved_dram_end - early_reserved_dram_start) / KiB);
/* top of DRAM consumed early - low top usable RAM
* cbmem_top() accounts for low UMA and TSEG if they are used. */
ram_resource(dev, idx++, early_reserved_dram_end / KiB,
(mem_usable - early_reserved_dram_end) / KiB);
mmconf_resource(dev, MMIO_CONF_BASE); mmconf_resource(dev, MMIO_CONF_BASE);