cpu/x86/smm/smm_module_loader: Install bigger page tables
In order to give SMM access to more than 4GiB on x86_64, update the page table generation in the SMM loader. Honor CONFIG_CPU_PT_ROM_MAP_GB and map the same amount of the address space as done in other stages. This is required for SMM trying to access the SPI BAR in high MMIO on AMD platforms. TEST=Could access ROM3 BAR at 0xfd00000000 in SMM on AMD/birman+ Change-Id: Iae3dac8d39d3f5e55cc08aa96c8924f6364c5140 Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/87573 Reviewed-by: Maximilian Brune <maximilian.brune@9elements.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Shuo Liu <shuo.liu@intel.com>
This commit is contained in:
parent
aa121a9bbe
commit
011baca89d
1 changed files with 23 additions and 12 deletions
|
|
@ -418,28 +418,39 @@ static int append_and_check_region(const struct region smram,
|
|||
#define _PS (1ULL << 7)
|
||||
#define _GEN_DIR(a) (_PRES + _RW + _US + _A + (a))
|
||||
#define _GEN_PAGE(a) (_PRES + _RW + _US + _PS + _A + _D + (a))
|
||||
#define PAGE_SIZE 8
|
||||
#define PTE_SIZE 8
|
||||
|
||||
/* Return the PML4E */
|
||||
static uintptr_t install_page_table(const uintptr_t handler_base)
|
||||
{
|
||||
const bool one_g_pages = !!(cpuid_edx(0x80000001) & (1 << 26));
|
||||
/* 4 1G pages or 4 PDPE entries with 512 * 2M pages */
|
||||
const size_t pages_needed = one_g_pages ? 4 : 2048 + 4;
|
||||
const uintptr_t pages_base = ALIGN_DOWN(handler_base - pages_needed * PAGE_SIZE, 4096);
|
||||
|
||||
/*
|
||||
* CONFIG_CPU_PT_ROM_MAP_GB 1G pages or
|
||||
* CONFIG_CPU_PT_ROM_MAP_GB PDPE entries with 512 * 2M pages
|
||||
*/
|
||||
const size_t ptes_needed = CONFIG_CPU_PT_ROM_MAP_GB + (one_g_pages ? 0 :
|
||||
512 * CONFIG_CPU_PT_ROM_MAP_GB);
|
||||
const uintptr_t pages_base = ALIGN_DOWN(handler_base - ptes_needed * PTE_SIZE, 4096);
|
||||
const uintptr_t pml4e = ALIGN_DOWN(pages_base - 8, 4096);
|
||||
uintptr_t pdpt;
|
||||
|
||||
if (one_g_pages) {
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
write64p(pages_base + i * PAGE_SIZE, _GEN_PAGE(1ull * GiB * i));
|
||||
write64p(pml4e, _GEN_DIR(pages_base));
|
||||
for (size_t i = 0; i < CONFIG_CPU_PT_ROM_MAP_GB; i++)
|
||||
write64p(pages_base + i * PTE_SIZE, _GEN_PAGE(1ull * GiB * i));
|
||||
pdpt = pages_base;
|
||||
} else {
|
||||
for (size_t i = 0; i < 2048; i++)
|
||||
write64p(pages_base + i * PAGE_SIZE, _GEN_PAGE(2ull * MiB * i));
|
||||
write64p(pml4e, _GEN_DIR(pages_base + 2048 * PAGE_SIZE));
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
write64p(pages_base + (2048 + i) * PAGE_SIZE, _GEN_DIR(pages_base + 4096 * i));
|
||||
for (size_t i = 0; i < 512 * CONFIG_CPU_PT_ROM_MAP_GB; i++)
|
||||
write64p(pages_base + i * PTE_SIZE, _GEN_PAGE(2ull * MiB * i));
|
||||
|
||||
pdpt = pages_base + 4096 * CONFIG_CPU_PT_ROM_MAP_GB;
|
||||
for (size_t i = 0; i < CONFIG_CPU_PT_ROM_MAP_GB; i++)
|
||||
write64p(pdpt + i * PTE_SIZE, _GEN_DIR(pages_base + 4096 * i));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < DIV_ROUND_UP(CONFIG_CPU_PT_ROM_MAP_GB, 512); i++)
|
||||
write64p(pml4e + i * PTE_SIZE, _GEN_DIR(pdpt + i * 4096));
|
||||
|
||||
return pml4e;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue