This makes sure that the resource allocator won't use this address range for anything else. In the systems I looked at, this was between the end of the above 4GB memory and the beginning of the above 4GB PCI BAR MMIO region, but better reserve it here so nothing else will get allocated there if this expectation isn't met. TEST=Reserved region is printed in the console logs: update_constraints: PCI: 00:00.0 09 base fd00000000 limit fdffffffff mem (fixed) Signed-off-by: Felix Held <felix-coreboot@felixheld.de> Change-Id: I5a8150873cb019ca1d903ed269e18d6f9fabb871 Reviewed-on: https://review.coreboot.org/c/coreboot/+/75611 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Eric Lai <eric_lai@quanta.corp-partner.google.com> Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
222 lines
8.4 KiB
C
222 lines
8.4 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
|
|
#include <acpi/acpigen.h>
|
|
#include <amdblocks/acpi.h>
|
|
#include <amdblocks/alib.h>
|
|
#include <amdblocks/data_fabric.h>
|
|
#include <amdblocks/memmap.h>
|
|
#include <amdblocks/ioapic.h>
|
|
#include <amdblocks/iomap.h>
|
|
#include <arch/ioapic.h>
|
|
#include <arch/vga.h>
|
|
#include <assert.h>
|
|
#include <cbmem.h>
|
|
#include <console/console.h>
|
|
#include <device/device.h>
|
|
#include <device/pci.h>
|
|
#include <fsp/util.h>
|
|
#include <stdint.h>
|
|
#include <soc/iomap.h>
|
|
#include "chip.h"
|
|
|
|
#define DPTC_TOTAL_UPDATE_PARAMS 4
|
|
|
|
struct dptc_input {
|
|
uint16_t size;
|
|
struct alib_dptc_param params[DPTC_TOTAL_UPDATE_PARAMS];
|
|
} __packed;
|
|
|
|
#define DPTC_INPUTS(_thermctllmit, _sustained, _fast, _slow) \
|
|
{ \
|
|
.size = sizeof(struct dptc_input), \
|
|
.params = { \
|
|
{ \
|
|
.id = ALIB_DPTC_THERMAL_CONTROL_LIMIT_ID, \
|
|
.value = _thermctllmit, \
|
|
}, \
|
|
{ \
|
|
.id = ALIB_DPTC_SUSTAINED_POWER_LIMIT_ID, \
|
|
.value = _sustained, \
|
|
}, \
|
|
{ \
|
|
.id = ALIB_DPTC_FAST_PPT_LIMIT_ID, \
|
|
.value = _fast, \
|
|
}, \
|
|
{ \
|
|
.id = ALIB_DPTC_SLOW_PPT_LIMIT_ID, \
|
|
.value = _slow, \
|
|
}, \
|
|
}, \
|
|
}
|
|
/*
|
|
*
|
|
* +--------------------------------+
|
|
* | |
|
|
* | |
|
|
* | |
|
|
* | |
|
|
* | |
|
|
* | |
|
|
* | |
|
|
* reserved_dram_end +--------------------------------+
|
|
* | |
|
|
* | verstage (if reqd) |
|
|
* | (VERSTAGE_SIZE) |
|
|
* +--------------------------------+ VERSTAGE_ADDR
|
|
* | |
|
|
* | FSP-M |
|
|
* | (FSP_M_SIZE) |
|
|
* +--------------------------------+ FSP_M_ADDR
|
|
* | romstage |
|
|
* | (ROMSTAGE_SIZE) |
|
|
* +--------------------------------+ ROMSTAGE_ADDR = BOOTBLOCK_END
|
|
* | | X86_RESET_VECTOR = BOOTBLOCK_END - 0x10
|
|
* | bootblock |
|
|
* | (C_ENV_BOOTBLOCK_SIZE) |
|
|
* +--------------------------------+ BOOTBLOCK_ADDR = BOOTBLOCK_END - C_ENV_BOOTBLOCK_SIZE
|
|
* | 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)
|
|
{
|
|
uint32_t mem_usable = (uintptr_t)cbmem_top();
|
|
unsigned int idx = 0;
|
|
const struct hob_header *hob_iterator;
|
|
const struct hob_resource *res;
|
|
struct resource *gnb_apic;
|
|
|
|
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;
|
|
|
|
/* The root complex has no PCI BARs implemented, so there's no need to call
|
|
pci_dev_read_resources for it */
|
|
|
|
fixed_io_range_reserved(dev, idx++, PCI_IO_CONFIG_INDEX, PCI_IO_CONFIG_PORT_COUNT);
|
|
|
|
/* 0x0 - 0x9ffff */
|
|
ram_resource_kb(dev, idx++, 0, 0xa0000 / KiB);
|
|
|
|
/* 0xa0000 - 0xbffff: legacy VGA */
|
|
mmio_resource_kb(dev, idx++, VGA_MMIO_BASE / KiB, VGA_MMIO_SIZE / KiB);
|
|
|
|
/* 0xc0000 - 0xfffff: Option ROM */
|
|
reserved_ram_resource_kb(dev, idx++, 0xc0000 / KiB, 0x40000 / KiB);
|
|
|
|
/* 1MB - bottom of DRAM reserved for early coreboot usage */
|
|
ram_resource_kb(dev, idx++, (1 * MiB) / KiB,
|
|
(early_reserved_dram_start - (1 * MiB)) / KiB);
|
|
|
|
/* DRAM reserved for early coreboot usage */
|
|
reserved_ram_resource_kb(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_kb(dev, idx++, early_reserved_dram_end / KiB,
|
|
(mem_usable - early_reserved_dram_end) / KiB);
|
|
|
|
mmconf_resource(dev, idx++);
|
|
|
|
/* GNB IOAPIC resource */
|
|
gnb_apic = new_resource(dev, IOMMU_IOAPIC_IDX);
|
|
gnb_apic->base = GNB_IO_APIC_ADDR;
|
|
gnb_apic->size = 0x00001000;
|
|
gnb_apic->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
|
|
|
|
/* Reserve fixed IOMMU MMIO region */
|
|
mmio_range(dev, idx++, IOMMU_RESERVED_MMIO_BASE, IOMMU_RESERVED_MMIO_SIZE);
|
|
|
|
if (fsp_hob_iterator_init(&hob_iterator) != CB_SUCCESS) {
|
|
printk(BIOS_ERR, "%s incomplete because no HOB list was found\n", __func__);
|
|
return;
|
|
}
|
|
|
|
while (fsp_hob_iterator_get_next_resource(&hob_iterator, &res) == CB_SUCCESS) {
|
|
if (res->type == EFI_RESOURCE_SYSTEM_MEMORY && res->addr < mem_usable)
|
|
continue; /* 0 through low usable was set above */
|
|
if (res->type == EFI_RESOURCE_MEMORY_MAPPED_IO)
|
|
continue; /* Done separately */
|
|
|
|
if (res->type == EFI_RESOURCE_SYSTEM_MEMORY)
|
|
ram_resource_kb(dev, idx++, res->addr / KiB, res->length / KiB);
|
|
else if (res->type == EFI_RESOURCE_MEMORY_RESERVED)
|
|
reserved_ram_resource_kb(dev, idx++, res->addr / KiB, res->length / KiB);
|
|
else
|
|
printk(BIOS_ERR, "failed to set resources for type %d\n",
|
|
res->type);
|
|
}
|
|
}
|
|
|
|
static void root_complex_init(struct device *dev)
|
|
{
|
|
register_new_ioapic((u8 *)GNB_IO_APIC_ADDR);
|
|
}
|
|
|
|
static void acipgen_dptci(void)
|
|
{
|
|
const struct soc_amd_picasso_config *config = config_of_soc();
|
|
|
|
/* Normal mode DPTC values. */
|
|
struct dptc_input default_input = DPTC_INPUTS(config->thermctl_limit_degreeC,
|
|
config->sustained_power_limit_mW,
|
|
config->fast_ppt_limit_mW,
|
|
config->slow_ppt_limit_mW);
|
|
acpigen_write_alib_dptc_default((uint8_t *)&default_input, sizeof(default_input));
|
|
|
|
/* Tablet Mode */
|
|
struct dptc_input tablet_mode_input = DPTC_INPUTS(
|
|
config->thermctl_limit_tablet_mode_degreeC,
|
|
config->sustained_power_limit_tablet_mode_mW,
|
|
config->fast_ppt_limit_tablet_mode_mW,
|
|
config->slow_ppt_limit_tablet_mode_mW);
|
|
acpigen_write_alib_dptc_tablet((uint8_t *)&tablet_mode_input,
|
|
sizeof(tablet_mode_input));
|
|
}
|
|
|
|
static void root_complex_fill_ssdt(const struct device *device)
|
|
{
|
|
if (CONFIG(SOC_AMD_COMMON_BLOCK_ACPI_DPTC))
|
|
acipgen_dptci();
|
|
}
|
|
|
|
static const char *gnb_acpi_name(const struct device *dev)
|
|
{
|
|
return "GNB";
|
|
}
|
|
|
|
struct device_operations picasso_root_complex_operations = {
|
|
.read_resources = read_resources,
|
|
.set_resources = noop_set_resources,
|
|
.enable_resources = pci_dev_enable_resources,
|
|
.init = root_complex_init,
|
|
.acpi_name = gnb_acpi_name,
|
|
.acpi_fill_ssdt = root_complex_fill_ssdt,
|
|
};
|