vc/amd/opensil: Add Phoenix OpenSIL POC directory as a copy of Genoa

Based on genoa_poc, this patch adds directory structure for Phoenix
OpenSIL as well as git submodule needed to build it.

Subsequent patches will begin adjusting this directory to Phoenix (Zen4)
silicon.

Change-Id: I04de276c1567c20d1e852efe220efa8131f53843
Signed-off-by: Alicja Michalska <alicja.michalska@9elements.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/91480
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-by: Matt DeVillier <matt.devillier@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Alicja Michalska 2026-03-01 00:40:09 +01:00 committed by Matt DeVillier
commit a616a589a2
17 changed files with 705 additions and 0 deletions

5
.gitmodules vendored
View file

@ -70,7 +70,12 @@
[submodule "3rdparty/open-power-signing-utils"]
path = 3rdparty/open-power-signing-utils
url = https://review.coreboot.org/open-power-signing-utils.git
[submodule "src/vendorcode/amd/opensil/phoenix_poc/opensil"]
path = src/vendorcode/amd/opensil/phoenix_poc/opensil
url = https://github.com/openSIL/openSIL.git
branch = phoenix_poc
[submodule "src/vendorcode/amd/opensil/turin_poc/opensil"]
path = src/vendorcode/amd/opensil/turin_poc/opensil
url = https://github.com/openSIL/openSIL.git
branch = turin_poc

View file

@ -15,6 +15,12 @@ config SOC_AMD_OPENSIL_GENOA_POC
Select this on SoCs that use the Genoa proof of concept version of
openSIL.
config SOC_AMD_OPENSIL_PHOENIX_POC
bool
help
Select this on SoCs that use the Phoenix proof of concept version of
openSIL.
config SOC_AMD_OPENSIL_TURIN_POC
bool
help
@ -25,6 +31,7 @@ config AMD_OPENSIL_PATH
string "Path to openSIL source"
depends on !SOC_AMD_OPENSIL_STUB
default "$(top)/src/vendorcode/amd/opensil/genoa_poc/opensil" if SOC_AMD_OPENSIL_GENOA_POC
default "$(top)/src/vendorcode/amd/opensil/phoenix_poc/opensil" if SOC_AMD_OPENSIL_PHOENIX_POC
default "$(top)/src/vendorcode/amd/opensil/turin_poc/opensil" if SOC_AMD_OPENSIL_TURIN_POC
help
Set to the path of the openSIL directory containing meson.build.
@ -33,6 +40,7 @@ config AMD_OPENSIL_PATH
config AMD_OPENSIL_MPIO_CHIP_H_FILE
string "Location of specific MPIO chip.h implementation"
default "$(top)/src/vendorcode/amd/opensil/genoa_poc/mpio/chip.h" if SOC_AMD_OPENSIL_GENOA_POC
default "$(top)/src/vendorcode/amd/opensil/phoenix_poc/mpio/chip.h" if SOC_AMD_OPENSIL_PHOENIX_POC
default "$(top)/src/vendorcode/amd/opensil/turin_poc/mpio/chip.h" if SOC_AMD_OPENSIL_TURIN_POC
default "$(top)/src/vendorcode/amd/opensil/stub/mpio/chip.h"
help

View file

@ -15,6 +15,7 @@ endif
opensil_dir := $(call strip_quotes,$(CONFIG_AMD_OPENSIL_PATH))
subdirs-$(CONFIG_SOC_AMD_OPENSIL_GENOA_POC) += genoa_poc
subdirs-$(CONFIG_SOC_AMD_OPENSIL_PHOENIX_POC) += phoenix_poc
subdirs-$(CONFIG_SOC_AMD_OPENSIL_TURIN_POC) += turin_poc
ifeq ($(CONFIG_ARCH_RAMSTAGE_X86_32),y)

View file

@ -0,0 +1,18 @@
## SPDX-License-Identifier: GPL-2.0-only
subdirs-y += mpio
CPPFLAGS_common += -I$(opensil_dir)/Include -I$(opensil_dir)/xUSL -I$(opensil_dir)/xUSL/Include -I$(opensil_dir)/xUSL/FCH -I$(opensil_dir)/xUSL/FCH/Common -I$(opensil_dir)/xSIM -I$(opensil_dir)/xPRF
romstage-y += opensil_console.c
romstage-y += romstage.c
ramstage-y += acpi.c
ramstage-y += memmap.c
ramstage-y += opensil_console.c
ramstage-y += ramstage.c
$(obj)/romstage/vendorcode/amd/opensil/phoenix_poc/opensil_console.o: CFLAGS_romstage += -D_MSC_EXTENSIONS=0 -DHAS_STRING_H=1 -Wno-unknown-pragmas
$(obj)/romstage/vendorcode/amd/opensil/phoenix_poc/romstage.o: CFLAGS_romstage += -D_MSC_EXTENSIONS=0 -DHAS_STRING_H=1 -Wno-unknown-pragmas
$(obj)/ramstage/vendorcode/amd/opensil/phoenix_poc/opensil_console.o: CFLAGS_ramstage += -D_MSC_EXTENSIONS=0 -DHAS_STRING_H=1 -Wno-unknown-pragmas

View file

@ -0,0 +1,24 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <acpi/acpi.h>
#include <Sil-api.h>
#include <SilCommon.h>
#include <xSIM-api.h>
#include <FCH/Common/FchCommonCfg.h>
#include "../opensil.h"
void opensil_fill_fadt(acpi_fadt_t *fadt)
{
FCHHWACPI_INPUT_BLK *blk = SilFindStructure(SilId_FchHwAcpiP, 0);
fadt->pm1a_evt_blk = blk->AcpiPm1EvtBlkAddr;
fadt->pm1a_cnt_blk = blk->AcpiPm1CntBlkAddr;
fadt->pm_tmr_blk = blk->AcpiPmTmrBlkAddr;
fadt->gpe0_blk = blk->AcpiGpe0BlkAddr;
}
unsigned long add_opensil_acpi_table(unsigned long current, acpi_rsdp_t *rsdp)
{
return current;
}

View file

@ -0,0 +1,23 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Keep this in sync with openSIL SilCommon.h file */
#define DEBUG_FILTER_APOB 0x00000001UL
#define DEBUG_FILTER_NBIO 0x00000002UL
#define DEBUG_FILTER_CCX 0x00000004UL
#define DEBUG_FILTER_SMU 0x00000008UL
#define DEBUG_FILTER_DF 0x00000010UL
#define DEBUG_FILTER_MEM 0x00000040UL
#define DEBUG_FILTER_FCH 0x00000080UL
#define DEBUG_FILTER_RAS 0x00000100UL
#define SIL_DEBUG(topic) (CONFIG(OPENSIL_DEBUG_##topic) ? DEBUG_FILTER_##topic : 0)
#define SIL_DEBUG_MODULE_FILTER ( \
SIL_DEBUG(APOB) | \
SIL_DEBUG(NBIO) | \
SIL_DEBUG(CCX) | \
SIL_DEBUG(SMU) | \
SIL_DEBUG(DF) | \
SIL_DEBUG(MEM) | \
SIL_DEBUG(FCH) | \
SIL_DEBUG(RAS) )

View file

@ -0,0 +1,57 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <SilCommon.h>
#include <Sil-api.h> // needed above ApobCmn.h
#include <ApobCmn.h>
#include <xPRF-api.h>
#include "../opensil.h"
_Static_assert(sizeof(uint32_t) == sizeof(((MEMORY_HOLE_DESCRIPTOR){0}).Type),
"Unexpected size of MEMORY_HOLE_TYPES in the MEMORY_HOLE_DESCRIPTOR "
"struct which doesn't match the code in drivers/amd/opensil/memmap.c");
const char *opensil_get_hole_info_type(uint32_t type)
{
const struct hole_type {
MEMORY_HOLE_TYPES type;
const char *string;
} types[] = {
{UMA, "UMA"},
{MMIO, "MMIO"},
{PrivilegedDRAM, "PrivilegedDRAM"},
{Reserved1TbRemap, "Reserved1TbRemap"},
{ReservedSLink, "ReservedSLink"},
{ReservedSLinkAlignment, "ReservedSLinkAlignment"},
{ReservedDrtm, "ReservedDrtm"},
{ReservedCvip, "ReservedCvip"},
{ReservedSmuFeatures, "ReservedSmuFeatures"},
{ReservedFwtpm, "ReservedFwtpm"},
{ReservedMpioC20, "ReservedMpioC20"},
{ReservedNbif, "ReservedNbif"},
{ReservedCxl, "ReservedCxl"},
{ReservedCxlAlignment, "ReservedCxlAlignment"},
{ReservedCpuTmr, "ReservedCpuTmr"},
{ReservedRasEinj, "ReservedRasEinj"},
{MaxMemoryHoleTypes, "MaxMemoryHoleTypes"},
};
int i;
MEMORY_HOLE_TYPES enum_type = (MEMORY_HOLE_TYPES)type; // Cast int to enum
for (i = 0; i < ARRAY_SIZE(types); i++)
if (enum_type == types[i].type)
return types[i].string;
return "Unknown type";
}
void opensil_get_hole_info(uint32_t *n_holes, uint64_t *top_of_mem, void **hole_info)
{
SIL_STATUS status = xPrfGetSystemMemoryMap(n_holes, top_of_mem, hole_info);
SIL_STATUS_report("xPrfGetSystemMemoryMap", status);
// Make sure hole_info does not get initialized to something odd by xPRF on failure
if (status != SilPass) {
*hole_info = NULL;
*n_holes = 0;
*top_of_mem = 0;
}
}

View file

@ -0,0 +1,35 @@
[binaries]
c = '##COMPILER##'
ar = '##AR##'
nasm = '##NASM##'
[built-in options]
c_args = ['-nostdinc',
'-I##OBJPATH##',
'-I##COREBOOT_DIR##/src/include',
'-I##COREBOOT_DIR##/src/arch/x86/include',
'-I##COREBOOT_DIR##/src/commonlib/include',
'-I##COREBOOT_DIR##/src/commonlib/bsd/include',
'-include', '##COREBOOT_DIR##/src/include/kconfig.h',
'-include', '##OBJPATH##/config.h',
'-include', '##COREBOOT_DIR##/src/commonlib/bsd/include/commonlib/bsd/compiler.h',
'-include', '##OPENSIL_DIR##/../filter.h',
'-DHAS_STRING_H=1',
# openSIL isn't compatible with coreboot's assert implementation, so use special case
'-D_PORTING_H_=1',
'-DSIL_DEBUG_ENABLE=##SIL_DEBUG_ENABLE##',
# openSIL uses coreboot assert which uses printk which warns about unused-param
'-Wno-unused-parameter',
# ubiquitous problem in openSIL
'-Wno-missing-field-initializers',
##CLANG_ARGS##
]
[host_machine]
system = 'linux'
cpu_family = '##CPU_FAMILY##'
cpu = '##CPU##'
endian = 'little'
[properties]
is32bit = ##IS32BIT##

View file

@ -0,0 +1,5 @@
## SPDX-License-Identifier: GPL-2.0-only
ramstage-y += chip.c
$(obj)/ramstage/vendorcode/amd/opensil/phoenix_poc/mpio/chip.o: CFLAGS_ramstage += -D_MSC_EXTENSIONS=0 -DHAS_STRING_H=1 -Wno-unknown-pragmas

View file

@ -0,0 +1,202 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <device/device.h>
#include <device/pci_def.h>
#include <Mpio/Common/MpioStructs.h>
#include <Mpio/MpioClass-api.h>
#include <NBIO/NbioClass-api.h>
#include <RcMgr/DfX/RcManager4-api.h>
#include <vendorcode/amd/opensil/opensil.h>
#include <xSIM-api.h>
#include "chip.h"
static void mpio_params_config(void)
{
MPIOCLASS_INPUT_BLK *mpio_data = SilFindStructure(SilId_MpioClass, 0);
mpio_data->CfgDxioClockGating = 1;
mpio_data->PcieDxioTimingControlEnable = 0;
mpio_data->PCIELinkReceiverDetectionPolling = 0;
mpio_data->PCIELinkResetToTrainingTime = 0;
mpio_data->PCIELinkL0Polling = 0;
mpio_data->PCIeExactMatchEnable = 0;
mpio_data->DxioPhyValid = 1;
mpio_data->DxioPhyProgramming = 1;
mpio_data->CfgSkipPspMessage = 1;
mpio_data->DxioSaveRestoreModes = 0xff;
mpio_data->AmdAllowCompliance = 0;
mpio_data->AmdAllowCompliance = 0xff;
mpio_data->SrisEnableMode = 0xff;
mpio_data->SrisSkipInterval = 0;
mpio_data->SrisSkpIntervalSel = 1;
mpio_data->SrisCfgType = 0;
mpio_data->SrisAutoDetectMode = 0xff;
mpio_data->SrisAutodetectFactor = 0;
mpio_data->SrisLowerSkpOsGenSup = 0;
mpio_data->SrisLowerSkpOsRcvSup = 0;
mpio_data->AmdCxlOnAllPorts = 1;
mpio_data->CxlCorrectableErrorLogging = 1;
mpio_data->CxlUnCorrectableErrorLogging = 1;
// This is also available in Nbio. How to handle duplicate entries?
mpio_data->CfgAEREnable = 1;
mpio_data->CfgMcCapEnable = 0;
mpio_data->CfgRcvErrEnable = 0;
mpio_data->EarlyBmcLinkTraining = 1;
mpio_data->SurpriseDownFeature = 1;
mpio_data->LcMultAutoSpdChgOnLastRateEnable = 0;
mpio_data->AmdRxMarginEnabled = 1;
mpio_data->CfgPcieCVTestWA = 1;
mpio_data->CfgPcieAriSupport = 1;
mpio_data->CfgNbioCTOtoSC = 0;
mpio_data->CfgNbioCTOIgnoreError = 1;
mpio_data->CfgNbioSsid = 0;
mpio_data->CfgIommuSsid = 0;
mpio_data->CfgPspccpSsid = 0;
mpio_data->CfgNtbccpSsid = 0;
mpio_data->CfgNbifF0Ssid = 0;
mpio_data->CfgNtbSsid = 0;
mpio_data->AmdPcieSubsystemDeviceID = 0x1453;
mpio_data->AmdPcieSubsystemVendorID = 0x1022;
mpio_data->GppAtomicOps = 1;
mpio_data->GfxAtomicOps = 1;
mpio_data->AmdNbioReportEdbErrors = 0;
mpio_data->OpnSpare = 0;
mpio_data->AmdPreSilCtrl0 = 0;
mpio_data->MPIOAncDataSupport = 1;
mpio_data->AfterResetDelay = 0;
mpio_data->CfgEarlyLink = 0;
mpio_data->AmdCfgExposeUnusedPciePorts = 1; // Show all ports
mpio_data->CfgForcePcieGenSpeed = 0;
mpio_data->CfgSataPhyTuning = 0;
mpio_data->PcieLinkComplianceModeAllPorts = 0;
mpio_data->AmdMCTPEnable = 0;
mpio_data->SbrBrokenLaneAvoidanceSup = 1;
mpio_data->AutoFullMarginSup = 1;
// A getter and setter, both are needed for this PCD.
mpio_data->AmdPciePresetMask8GtAllPort = 0xffffffff;
// A getter and setter, both are needed for this PCD.
mpio_data->AmdPciePresetMask16GtAllPort = 0xffffffff;
// A getter and setter, both are needed for this PCD.
mpio_data->AmdPciePresetMask32GtAllPort = 0xffffffff;
mpio_data->PcieLinkAspmAllPort = 0xff;
mpio_data->SyncHeaderByPass = 1;
mpio_data->CxlTempGen5AdvertAltPtcl = 0;
/* TODO handle this differently on multisocket */
mpio_data->PcieTopologyData.PlatformData[0].Flags = DESCRIPTOR_TERMINATE_LIST;
mpio_data->PcieTopologyData.PlatformData[0].PciePortList = mpio_data->PcieTopologyData.PortList;
}
static void nbio_params_config(void)
{
NBIOCLASS_DATA_BLOCK *nbio_data = SilFindStructure(SilId_NbioClass, 0);
NBIOCLASS_INPUT_BLK *input = &nbio_data->NbioInputBlk;
input->CfgHdAudioEnable = false;
input->EsmEnableAllRootPorts = false;
input->EsmTargetSpeed = 16;
input->CfgRxMarginPersistenceMode = 1;
input->CfgDxioFrequencyVetting = false;
input->CfgSkipPspMessage = 1;
input->CfgEarlyTrainTwoPcieLinks = false;
input->EarlyBmcLinkTraining = true;
input->EdpcEnable = 0;
input->PcieAerReportMechanism = 2;
input->SevSnpSupport = false;
}
static void setup_bmc_lanes(uint8_t lane, uint8_t socket)
{
DFX_RCMGR_INPUT_BLK *rc_mgr_input_block = SilFindStructure(SilId_RcManager, 0);
rc_mgr_input_block->BmcSocket = socket;
rc_mgr_input_block->EarlyBmcLinkLaneNum = lane;
NBIOCLASS_DATA_BLOCK *nbio_data = SilFindStructure(SilId_NbioClass, 0);
NBIOCLASS_INPUT_BLK *nbio_input = &nbio_data->NbioInputBlk;
nbio_input->EarlyBmcLinkSocket = socket;
nbio_input->EarlyBmcLinkLaneNum = lane;
nbio_input->EarlyBmcLinkDie = 0;
MPIOCLASS_INPUT_BLK *mpio_data = SilFindStructure(SilId_MpioClass, 0);
mpio_data->EarlyBmcLinkSocket = socket;
mpio_data->EarlyBmcLinkLaneNum = lane;
mpio_data->EarlyBmcLinkDie = 0;
}
void opensil_mpio_per_device_config(struct device *dev)
{
/* Cache *mpio_data from SilFindStructure */
static MPIOCLASS_INPUT_BLK *mpio_data = NULL;
if (mpio_data == NULL) {
mpio_data = SilFindStructure(SilId_MpioClass, 0);
}
static uint32_t slot_num;
const uint32_t domain = dev_get_domain_id(dev);
const uint32_t devfn = dev->path.pci.devfn;
const struct drivers_amd_opensil_mpio_config *const config = dev->chip_info;
printk(BIOS_DEBUG, "Setting MPIO port for domain 0x%x, PCI %d:%d\n",
domain, PCI_SLOT(devfn), PCI_FUNC(devfn));
if (config->type == IFTYPE_UNUSED) {
if (is_dev_enabled(dev)) {
printk(BIOS_WARNING, "Unused MPIO chip, disabling PCI device.\n");
dev->enabled = false;
} else {
printk(BIOS_DEBUG, "Unused MPIO chip, skipping.\n");
}
return;
}
if (config->bmc) {
setup_bmc_lanes(config->start_lane, 0); // TODO support multiple sockets
return;
}
static int mpio_port = 0;
MPIO_PORT_DESCRIPTOR port = { .Flags = DESCRIPTOR_TERMINATE_LIST };
if (config->type == IFTYPE_PCIE) {
const MPIO_ENGINE_DATA engine_data =
MPIO_ENGINE_DATA_INITIALIZER(MpioPcieEngine,
config->start_lane, config->end_lane,
config->hotplug == HotplugDisabled ? 0 : 1,
config->gpio_group);
port.EngineData = engine_data;
const MPIO_PORT_DATA port_data =
MPIO_PORT_DATA_INITIALIZER_PCIE(is_dev_enabled(dev) ?
MpioPortEnabled : MpioPortDisabled,
PCI_SLOT(devfn),
PCI_FUNC(devfn),
config->hotplug,
config->speed,
0, // No backup PCIe speed
config->aspm,
config->aspm_l1_1,
config->aspm_l1_2,
config->clock_pm);
port.Port = port_data;
} else if (config->type == IFTYPE_SATA) {
const MPIO_ENGINE_DATA engine_data =
MPIO_ENGINE_DATA_INITIALIZER(MpioSATAEngine,
config->start_lane, config->end_lane,
0, // meaningless field
config->gpio_group);
port.EngineData = engine_data;
const MPIO_PORT_DATA port_data = { .PortPresent = 1 };
port.Port = port_data;
}
port.Port.AlwaysExpose = 1;
port.Port.SlotNum = ++slot_num;
mpio_data->PcieTopologyData.PortList[mpio_port] = port;
/* Update TERMINATE list */
if (mpio_port > 0)
mpio_data->PcieTopologyData.PortList[mpio_port - 1].Flags = 0;
mpio_port++;
}
void opensil_mpio_global_config(void)
{
mpio_params_config();
nbio_params_config();
}

View file

@ -0,0 +1,71 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef OPENSIL_PHOENIX_POC_MPIO_CHIP_H
#define OPENSIL_PHOENIX_POC_MPIO_CHIP_H
#include <stdint.h>
/*
* PHOENIX MPIO mapping
* P0 -> [0-15]
* G0 -> [16-31]
* P1 -> [32-47]
* G1 -> [48-63]
* P2 -> [64-79]
* G2 -> [80-95]
* P3 -> [96-111]
* G3 -> [112-127]
* P4 -> [128-131]
* P5 -> [132-136]
*/
enum mpio_type {
IFTYPE_UNUSED,
IFTYPE_PCIE,
IFTYPE_SATA,
};
/* Sync with PCIE_HOTPLUG_TYPE */
enum mpio_hotplug {
HotplugDisabled, ///< Hotplug disable
Basic, ///< Basic Hotplug
ServerExpress, ///< Server Hotplug Express Module
Enhanced, ///< Enhanced
Inboard, ///< Inboard
ServerEntSSD, ///< Server Hotplug Enterprise SSD
UBM, ///< UBM Backplane
OCP, ///< OCP NIC 3.0
};
enum pcie_link_speed {
MaxSupported,
Gen1,
Gen2,
Gen3,
Gen4,
Gen5,
};
/* Sync with PCIE_ASPM_TYPE */
enum pcie_aspm {
aspm_disabled,
L0s,
L1,
L0sL1,
};
struct drivers_amd_opensil_mpio_config {
enum mpio_type type;
uint8_t start_lane;
uint8_t end_lane;
uint8_t gpio_group;
enum mpio_hotplug hotplug;
enum pcie_link_speed speed;
enum pcie_aspm aspm;
uint8_t aspm_l1_1 : 1;
uint8_t aspm_l1_2 : 1;
uint8_t clock_pm : 1;
uint8_t bmc : 1;
};
#endif /* OPENSIL_PHOENIX_POC_MPIO_CHIP_H */

@ -0,0 +1 @@
Subproject commit 52b83c56a3a653c287f5839a5986eda22677f304

View file

@ -0,0 +1,5 @@
CONFIG_PLAT_APOB_ADDRESS=##APOB_BASE##
CONFIG_PSP_BIOS_BIN_BASE=##BIOS_ENTRY_BASE##
CONFIG_PSP_BIOS_BIN_SIZE=##BIOS_ENTRY_SIZE##
CONFIG_PLAT_NUMBER_SOCKETS=1
CONFIG_SOC_F19M10=y

View file

@ -0,0 +1,44 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <console/console.h>
#include "opensil_console.h"
#include <SilCommon.h>
static int translate_opensil_debug_level(size_t MsgLevel)
{
switch (MsgLevel) {
case SIL_TRACE_ERROR:
return BIOS_ERR;
case SIL_TRACE_WARNING:
return BIOS_WARNING;
case SIL_TRACE_ENTRY:
case SIL_TRACE_EXIT:
return BIOS_SPEW;
case SIL_TRACE_INFO:
return BIOS_DEBUG;
default:
return BIOS_NEVER;
}
}
void HostDebugService(size_t MsgLevel, const char *SilPrefix, const char *Message,
const char *Function, size_t Line, ...)
{
if (!CONFIG(OPENSIL_DEBUG_OUTPUT))
return;
const int loglevel = translate_opensil_debug_level(MsgLevel);
/* print fomatted prefix */
if (CONFIG(OPENSIL_DEBUG_PREFIX))
printk(loglevel, "%s%s:%zu:", SilPrefix, Function, Line);
/* print formatted message */
va_list args;
va_start(args, Line);
vprintk(loglevel, Message, args);
va_end(args);
}

View file

@ -0,0 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef _VENDORCODE_AND_OPENSIL_CONSOLE
#define _VENDORCODE_AND_OPENSIL_CONSOLE
void HostDebugService(size_t MsgLevel, const char *SilPrefix, const char *Message,
const char *Function, size_t Line, ...);
#endif

View file

@ -0,0 +1,180 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <FCH/Common/FchCommonCfg.h>
#include <FCH/Common/FchCore/FchSata/FchSata.h>
#include <RcMgr/DfX/RcManager4-api.h>
#include <amdblocks/reset.h>
#include <bootstate.h>
#include <cbmem.h>
#include <cpu/cpu.h>
#include <device/device.h>
#include <soc/soc_chip.h>
#include <static.h>
#include <stdio.h>
#include <xSIM-api.h>
#include "opensil_console.h"
#include "../opensil.h"
void SIL_STATUS_report(const char *function, const int status)
{
const int log_level = status == SilPass ? BIOS_DEBUG : BIOS_ERR;
const char *error_string = "Unknown error";
const struct error_string_entry {
SIL_STATUS status;
const char *string;
} errors[] = {
{SilPass, "SilPass"},
{SilUnsupportedHardware, "SilUnsupportedHardware"},
{SilUnsupported, "SilUnsupported"},
{SilInvalidParameter, "SilInvalidParameter"},
{SilAborted, "SilAborted"},
{SilOutOfResources, "SilOutOfResources"},
{SilNotFound, "SilNotFound"},
{SilOutOfBounds, "SilOutOfBounds"},
{SilDeviceError, "SilDeviceError"},
{SilResetRequestColdImm, "SilResetRequestColdImm"},
{SilResetRequestColdDef, "SilResetRequestColdDef"},
{SilResetRequestWarmImm, "SilResetRequestWarmImm"},
{SilResetRequestWarmDef, "SilResetRequestWarmDef"},
};
int i;
for (i = 0; i < ARRAY_SIZE(errors); i++) {
if (errors[i].status == status)
error_string = errors[i].string;
}
printk(log_level, "%s returned %d (%s)\n", function, status, error_string);
}
static void setup_rc_manager_default(void)
{
DFX_RCMGR_INPUT_BLK *rc_mgr_input_block = SilFindStructure(SilId_RcManager, 0);
/* Let openSIL distribute the resources to the different PCI roots */
rc_mgr_input_block->SetRcBasedOnNv = false;
/* Currently 1P is the only supported configuration */
rc_mgr_input_block->SocketNumber = 1;
rc_mgr_input_block->RbsPerSocket = 4; /* PCI root bridges per socket */
rc_mgr_input_block->McptEnable = true;
rc_mgr_input_block->PciExpressBaseAddress = CONFIG_ECAM_MMCONF_BASE_ADDRESS;
rc_mgr_input_block->BottomMmioReservedForPrimaryRb = 4ull * GiB - 32 * MiB;
rc_mgr_input_block->MmioSizePerRbForNonPciDevice = 16 * MiB;
/* MmioAbove4GLimit will be adjusted down in openSIL */
rc_mgr_input_block->MmioAbove4GLimit = POWER_OF_2(cpu_phys_address_size());
rc_mgr_input_block->Above4GMmioSizePerRbForNonPciDevice = 0;
}
#define NUM_XHCI_CONTROLLERS 2
static void configure_usb(void)
{
const struct soc_amd_phoenix_poc_config *soc_config = config_of_soc();
const struct soc_usb_config *usb = &soc_config->usb;
FCHUSB_INPUT_BLK *fch_usb_data = SilFindStructure(SilId_FchUsb, 0);
fch_usb_data->Xhci0Enable = usb->xhci0_enable;
fch_usb_data->Xhci1Enable = usb->xhci1_enable;
fch_usb_data->Xhci2Enable = false; /* there's no XHCI2 on this SoC */
for (int i = 0; i < NUM_XHCI_CONTROLLERS; i++) {
memcpy(&fch_usb_data->XhciOCpinSelect[i].Usb20OcPin, &usb->usb2_oc_pins[i],
sizeof(fch_usb_data->XhciOCpinSelect[i].Usb20OcPin));
memcpy(&fch_usb_data->XhciOCpinSelect[i].Usb31OcPin, &usb->usb3_oc_pins[i],
sizeof(fch_usb_data->XhciOCpinSelect[i].Usb31OcPin));
}
fch_usb_data->XhciOcPolarityCfgLow = usb->polarity_cfg_low;
fch_usb_data->Usb3PortForceGen1 = usb->usb3_force_gen1.raw;
/* Instead of overwriting the whole OemUsbConfigurationTable, only copy the relevant
fields to the pre-populated data structure */
fch_usb_data->OemUsbConfigurationTable.Usb31PhyEnable = usb->usb31_phy_enable;
if (usb->usb31_phy_enable)
memcpy(&fch_usb_data->OemUsbConfigurationTable.Usb31PhyPort, usb->usb31_phy,
sizeof(fch_usb_data->OemUsbConfigurationTable.Usb31PhyPort));
fch_usb_data->OemUsbConfigurationTable.Usb31PhyEnable = usb->s1_usb31_phy_enable;
if (usb->s1_usb31_phy_enable)
memcpy(&fch_usb_data->OemUsbConfigurationTable.S1Usb31PhyPort, usb->s1_usb31_phy,
sizeof(fch_usb_data->OemUsbConfigurationTable.S1Usb31PhyPort));
}
#define NUM_SATA_CONTROLLERS 4
static void configure_sata(void)
{
FCHSATA_INPUT_BLK *fch_sata_data = SilFindStructure(SilId_FchSata, 0);
FCH_SATA2 *fch_sata_defaults = GetFchSataData();
for (int i = 0; i < NUM_SATA_CONTROLLERS; i++) {
fch_sata_data[i] = fch_sata_defaults[i];
fch_sata_data[i].SataSetMaxGen2 = false;
fch_sata_data[i].SataMsiEnable = true;
fch_sata_data[i].SataEspPort = 0xFF;
fch_sata_data[i].SataRasSupport = true;
fch_sata_data[i].SataDevSlpPort1Num = 1;
fch_sata_data[i].SataMsiEnable = true;
fch_sata_data[i].SataControllerAutoShutdown = true;
fch_sata_data[i].SataRxPolarity = 0xFF;
}
}
void setup_opensil(void)
{
const SIL_STATUS debug_ret = SilDebugSetup(HostDebugService);
SIL_STATUS_report("SilDebugSetup", debug_ret);
const size_t mem_req = xSimQueryMemoryRequirements();
void *buf = cbmem_add(CBMEM_ID_AMD_OPENSIL, mem_req);
assert(buf);
/* We run all openSIL timepoints in the same stage so using TP1 as argument is fine. */
const SIL_STATUS assign_mem_ret = xSimAssignMemoryTp1(buf, mem_req);
SIL_STATUS_report("xSimAssignMemory", assign_mem_ret);
setup_rc_manager_default();
configure_usb();
configure_sata();
}
static void opensil_entry(SIL_TIMEPOINT timepoint)
{
SIL_STATUS ret;
SIL_TIMEPOINT tp = (uintptr_t)timepoint;
switch (tp) {
case SIL_TP1:
ret = InitializeSiTp1();
break;
case SIL_TP2:
ret = InitializeSiTp2();
break;
case SIL_TP3:
ret = InitializeSiTp3();
break;
default:
printk(BIOS_ERR, "Unknown openSIL timepoint\n");
return;
}
char opensil_function[16];
snprintf(opensil_function, sizeof(opensil_function), "InitializeSiTp%d", tp + 1);
SIL_STATUS_report(opensil_function, ret);
if (ret == SilResetRequestColdImm || ret == SilResetRequestColdDef) {
printk(BIOS_INFO, "openSIL requested a cold reset");
do_cold_reset();
} else if (ret == SilResetRequestWarmImm || ret == SilResetRequestWarmDef) {
printk(BIOS_INFO, "openSIL requested a warm reset");
do_warm_reset();
}
}
void opensil_xSIM_timepoint_1(void)
{
opensil_entry(SIL_TP1);
}
void opensil_xSIM_timepoint_2(void)
{
opensil_entry(SIL_TP2);
}
void opensil_xSIM_timepoint_3(void)
{
opensil_entry(SIL_TP3);
}
/* TODO: also call timepoints 2 and 3 from coreboot. Are they NOOP? */

View file

@ -0,0 +1,17 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <console/console.h>
#include "opensil_console.h"
#include <xSIM-api.h>
#include <xPRF-api.h>
#include "../opensil.h"
uintptr_t opensil_get_low_usable_dram_address(void)
{
SilDebugSetup(HostDebugService);
uintptr_t low_usable_dram_addr = xPrfGetLowUsableDramAddress(0);
printk(BIOS_DEBUG, "xPrfGetLowUsableDramAddress: 0x%lx\n", low_usable_dram_addr);
return low_usable_dram_addr;
}