soc/intel/xeon_sp: Scan and allocate resources on all stacks
The code can now deal with stacks that have no resources so just hook them all up. Intel XEON-SP FSP reports all report the state of its stacks, which comprise of PCI root bridges and their respective resources, like PCI busses, IO and MEM resources, via HOB. Parsing all of those into native coreboot structures makes it possible to handle those in a more native fashion like use PCI drivers, native helper functions, ... As opposed parsing those structures again out of the HOB each time. This makes code reuse across the tree more feasible. An additional advantage is that Linux does not need to redo resource allocation since the one done by coreboot will be valid, which potentially decreases boot time. TEST=intel/archercity CRB Signed-off-by: Arthur Heymans <arthur@aheymans.xyz> Signed-off-by: Shuo Liu <shuo.liu@intel.com> Change-Id: Id72c6e4499e99df3b7ca821ab2893cbcc869dbcd Reviewed-on: https://review.coreboot.org/c/coreboot/+/78332 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Patrick Rudolph <patrick.rudolph@9elements.com> Reviewed-by: Lean Sheng Tan <sheng.tan@9elements.com>
This commit is contained in:
committed by
Lean Sheng Tan
parent
f40e59c838
commit
470f1d3885
@@ -104,9 +104,9 @@ size_t soc_get_ioapic_info(const uintptr_t *ioapic_bases[])
|
|||||||
for (int stack = 0; stack < MAX_IIO_STACK; ++stack) {
|
for (int stack = 0; stack < MAX_IIO_STACK; ++stack) {
|
||||||
const STACK_RES *ri =
|
const STACK_RES *ri =
|
||||||
&hob->PlatformData.IIO_resource[socket].StackRes[stack];
|
&hob->PlatformData.IIO_resource[socket].StackRes[stack];
|
||||||
if (!stack_needs_resource_alloc(ri))
|
|
||||||
continue;
|
|
||||||
uint32_t ioapic_base = ri->IoApicBase;
|
uint32_t ioapic_base = ri->IoApicBase;
|
||||||
|
if (ioapic_base == 0 || ioapic_base == 0xFFFFFFFF)
|
||||||
|
continue;
|
||||||
assert(index < ARRAY_SIZE(xeonsp_ioapic_bases));
|
assert(index < ARRAY_SIZE(xeonsp_ioapic_bases));
|
||||||
xeonsp_ioapic_bases[index++] = ioapic_base;
|
xeonsp_ioapic_bases[index++] = ioapic_base;
|
||||||
if (!CONFIG(XEON_SP_HAVE_IIO_IOAPIC))
|
if (!CONFIG(XEON_SP_HAVE_IIO_IOAPIC))
|
||||||
|
@@ -110,7 +110,7 @@ void attach_iio_stacks(struct device *dev)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
const STACK_RES *ri = &hob->PlatformData.IIO_resource[s].StackRes[x];
|
const STACK_RES *ri = &hob->PlatformData.IIO_resource[s].StackRes[x];
|
||||||
if (!stack_needs_resource_alloc(ri))
|
if (ri->BusBase > ri->BusLimit)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!is_pcie_iio_stack_res(ri)) {
|
if (!is_pcie_iio_stack_res(ri)) {
|
||||||
|
@@ -25,14 +25,9 @@ const struct SystemMemoryMapHob *get_system_memory_map(void)
|
|||||||
return *memmap_addr;
|
return *memmap_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool stack_needs_resource_alloc(const STACK_RES *res)
|
|
||||||
{
|
|
||||||
return res->Personality == TYPE_UBOX_IIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_pcie_iio_stack_res(const STACK_RES *res)
|
bool is_pcie_iio_stack_res(const STACK_RES *res)
|
||||||
{
|
{
|
||||||
return stack_needs_resource_alloc(res);
|
return res->Personality == TYPE_UBOX_IIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t get_stack_busno(const uint8_t stack)
|
uint8_t get_stack_busno(const uint8_t stack)
|
||||||
@@ -116,3 +111,24 @@ void soc_set_mrc_cold_boot_flag(bool cold_boot_required)
|
|||||||
cmos_write(new_mrc_status, CMOS_OFFSET_MRC_STATUS);
|
cmos_write(new_mrc_status, CMOS_OFFSET_MRC_STATUS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void get_iiostack_info(struct iiostack_resource *info)
|
||||||
|
{
|
||||||
|
const IIO_UDS *hob = get_iio_uds();
|
||||||
|
|
||||||
|
// copy IIO Stack info from FSP HOB
|
||||||
|
info->no_of_stacks = 0;
|
||||||
|
for (int socket = 0, iio = 0; iio < hob->PlatformData.numofIIO; ++socket) {
|
||||||
|
if (!soc_cpu_is_enabled(socket))
|
||||||
|
continue;
|
||||||
|
iio++;
|
||||||
|
for (int x = 0; x < MAX_IIO_STACK; ++x) {
|
||||||
|
const STACK_RES *ri;
|
||||||
|
ri = &hob->PlatformData.IIO_resource[socket].StackRes[x];
|
||||||
|
if (!is_pcie_iio_stack_res(ri))
|
||||||
|
continue;
|
||||||
|
assert(info->no_of_stacks < (CONFIG_MAX_SOCKET * MAX_IIO_STACK));
|
||||||
|
memcpy(&info->res[info->no_of_stacks++], ri, sizeof(STACK_RES));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -23,7 +23,6 @@ struct iiostack_resource {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void get_iiostack_info(struct iiostack_resource *info);
|
void get_iiostack_info(struct iiostack_resource *info);
|
||||||
bool stack_needs_resource_alloc(const STACK_RES *res);
|
|
||||||
bool is_pcie_iio_stack_res(const STACK_RES *res);
|
bool is_pcie_iio_stack_res(const STACK_RES *res);
|
||||||
void bios_done_msr(void *unused);
|
void bios_done_msr(void *unused);
|
||||||
|
|
||||||
|
@@ -74,7 +74,7 @@ union dpr_register txt_get_chipset_dpr(void)
|
|||||||
for (int stack = 0; stack < MAX_IIO_STACK; ++stack) {
|
for (int stack = 0; stack < MAX_IIO_STACK; ++stack) {
|
||||||
const STACK_RES *ri =
|
const STACK_RES *ri =
|
||||||
&hob->PlatformData.IIO_resource[socket].StackRes[stack];
|
&hob->PlatformData.IIO_resource[socket].StackRes[stack];
|
||||||
if (!stack_needs_resource_alloc(ri))
|
if (ri->VtdBarAddress == 0)
|
||||||
continue;
|
continue;
|
||||||
uint8_t bus = ri->BusBase;
|
uint8_t bus = ri->BusBase;
|
||||||
dev = VTD_DEV(bus);
|
dev = VTD_DEV(bus);
|
||||||
|
@@ -54,15 +54,9 @@ const struct SystemMemoryMapHob *get_system_memory_map(void)
|
|||||||
return memmap_addr;
|
return memmap_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool stack_needs_resource_alloc(const STACK_RES *res)
|
|
||||||
{
|
|
||||||
// TODO: do we have situation with only bux 0 and one stack?
|
|
||||||
return res->BusBase < res->BusLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_pcie_iio_stack_res(const STACK_RES *res)
|
bool is_pcie_iio_stack_res(const STACK_RES *res)
|
||||||
{
|
{
|
||||||
return stack_needs_resource_alloc(res);
|
return res->BusBase < res->BusLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t get_stack_busno(const uint8_t stack)
|
uint8_t get_stack_busno(const uint8_t stack)
|
||||||
|
@@ -68,11 +68,6 @@ const struct SystemMemoryMapElement *get_system_memory_map_elment(uint8_t *num)
|
|||||||
return hob->Element;
|
return hob->Element;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool stack_needs_resource_alloc(const STACK_RES *res)
|
|
||||||
{
|
|
||||||
return res->Personality == TYPE_UBOX_IIO || res->Personality == TYPE_DINO;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_pcie_iio_stack_res(const STACK_RES *res)
|
bool is_pcie_iio_stack_res(const STACK_RES *res)
|
||||||
{
|
{
|
||||||
return res->Personality == TYPE_UBOX_IIO;
|
return res->Personality == TYPE_UBOX_IIO;
|
||||||
|
@@ -101,27 +101,6 @@ const IIO_UDS *get_iio_uds(void)
|
|||||||
return hob;
|
return hob;
|
||||||
}
|
}
|
||||||
|
|
||||||
void get_iiostack_info(struct iiostack_resource *info)
|
|
||||||
{
|
|
||||||
const IIO_UDS *hob = get_iio_uds();
|
|
||||||
|
|
||||||
// copy IIO Stack info from FSP HOB
|
|
||||||
info->no_of_stacks = 0;
|
|
||||||
for (int socket = 0, iio = 0; iio < hob->PlatformData.numofIIO; ++socket) {
|
|
||||||
if (!soc_cpu_is_enabled(socket))
|
|
||||||
continue;
|
|
||||||
iio++;
|
|
||||||
for (int x = 0; x < MAX_IIO_STACK; ++x) {
|
|
||||||
const STACK_RES *ri;
|
|
||||||
ri = &hob->PlatformData.IIO_resource[socket].StackRes[x];
|
|
||||||
if (!stack_needs_resource_alloc(ri))
|
|
||||||
continue;
|
|
||||||
assert(info->no_of_stacks < (CONFIG_MAX_SOCKET * MAX_IIO_STACK));
|
|
||||||
memcpy(&info->res[info->no_of_stacks++], ri, sizeof(STACK_RES));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns true if the CPU in the specified socket was found
|
* Returns true if the CPU in the specified socket was found
|
||||||
* during QPI init, false otherwise.
|
* during QPI init, false otherwise.
|
||||||
|
Reference in New Issue
Block a user