/* SPDX-License-Identifier: GPL-2.0-only */ #include #include #include #include #include #include #include #include #include #include #include #if ENV_BOOTBLOCK const BIOS_CALLOUT_STRUCT BiosCallouts[] = { { AGESA_DO_RESET, agesa_Reset }, { AGESA_FCH_OEM_CALLOUT, agesa_fch_initreset }, { AGESA_HALT_THIS_AP, agesa_HaltThisAp }, { AGESA_HEAP_REBASE, agesa_HeapRebase }, { AGESA_GNB_PCIE_SLOT_RESET, agesa_PcieSlotResetControl } }; #else const BIOS_CALLOUT_STRUCT BiosCallouts[] = { /* Required callouts */ #if ENV_ROMSTAGE { AGESA_HALT_THIS_AP, agesa_HaltThisAp }, #endif { AGESA_ALLOCATE_BUFFER, agesa_AllocateBuffer }, { AGESA_DEALLOCATE_BUFFER, agesa_DeallocateBuffer }, { AGESA_DO_RESET, agesa_Reset }, { AGESA_LOCATE_BUFFER, agesa_LocateBuffer }, { AGESA_READ_SPD, agesa_ReadSpd }, { AGESA_GNB_PCIE_SLOT_RESET, agesa_PcieSlotResetControl }, { AGESA_GET_TEMP_HEAP_BASE, agesa_GetTempHeapBase }, { AGESA_HEAP_REBASE, agesa_HeapRebase }, #if ENV_RAMSTAGE { AGESA_RUNFUNC_ONAP, agesa_RunFuncOnAp }, { AGESA_RUNFUNC_ON_ALL_APS, agesa_RunFcnOnAllAps }, { AGESA_WAIT_FOR_ALL_APS, agesa_WaitForAllApsFinished }, { AGESA_IDLE_AN_AP, agesa_IdleAnAp }, #endif /* ENV_RAMSTAGE */ /* Optional callouts */ { AGESA_GET_IDS_INIT_DATA, agesa_EmptyIdsInitData }, //AgesaHeapRebase - Hook ID? { AGESA_HOOKBEFORE_DRAM_INIT, agesa_NoopUnsupported }, { AGESA_HOOKBEFORE_DQS_TRAINING, agesa_NoopUnsupported }, { AGESA_EXTERNAL_2D_TRAIN_VREF_CHANGE, agesa_NoopUnsupported }, { AGESA_HOOKBEFORE_EXIT_SELF_REF, agesa_NoopUnsupported }, { AGESA_GNB_GFX_GET_VBIOS_IMAGE, agesa_GfxGetVbiosImage }, { AGESA_FCH_OEM_CALLOUT, agesa_fch_initenv }, { AGESA_EXTERNAL_VOLTAGE_ADJUST, agesa_NoopUnsupported }, { AGESA_GNB_PCIE_CLK_REQ, agesa_NoopUnsupported }, /* Deprecated */ { AGESA_HOOKBEFORE_DRAM_INIT_RECOVERY, agesa_NoopUnsupported}, { AGESA_READ_SPD_RECOVERY, agesa_NoopUnsupported }, }; #endif const int BiosCalloutsLen = ARRAY_SIZE(BiosCallouts); AGESA_STATUS GetBiosCallout(uint32_t Func, uintptr_t Data, void *ConfigPtr) { uintptr_t i; for (i = 0 ; i < BiosCalloutsLen ; i++) { if (BiosCallouts[i].CalloutName == Func) break; } if (i >= BiosCalloutsLen) { printk(BIOS_ERR, "ERROR: AGESA Callout Not Supported: 0x%x\n", (u32)Func); return AGESA_UNSUPPORTED; } return BiosCallouts[i].CalloutPtr(Func, Data, ConfigPtr); } AGESA_STATUS agesa_NoopUnsupported(uint32_t Func, uintptr_t Data, void *ConfigPtr) { return AGESA_UNSUPPORTED; } AGESA_STATUS agesa_NoopSuccess(uint32_t Func, uintptr_t Data, void *ConfigPtr) { return AGESA_SUCCESS; } AGESA_STATUS agesa_EmptyIdsInitData(uint32_t Func, uintptr_t Data, void *ConfigPtr) { IDS_NV_ITEM *IdsPtr = ((IDS_CALLOUT_STRUCT *) ConfigPtr)->IdsNvPtr; if (Data == IDS_CALLOUT_INIT) IdsPtr[0].IdsNvValue = IdsPtr[0].IdsNvId = 0xffff; return AGESA_SUCCESS; } AGESA_STATUS agesa_Reset(uint32_t Func, uintptr_t Data, void *ConfigPtr) { AGESA_STATUS Status; uintptr_t ResetType; ResetType = Data; /* * This should perform the RESET based upon the ResetType, but coreboot * doesn't have a reset manager to handle a WHENEVER case. Do all * resets immediately. */ switch (ResetType) { case WARM_RESET_WHENEVER: case WARM_RESET_IMMEDIATELY: warm_reset(); break; case COLD_RESET_WHENEVER: case COLD_RESET_IMMEDIATELY: cold_reset(); break; default: break; } Status = 0; return Status; } AGESA_STATUS agesa_GfxGetVbiosImage(uint32_t Func, uintptr_t FchData, void *ConfigPrt) { GFX_VBIOS_IMAGE_INFO *pVbiosImageInfo; pVbiosImageInfo = (GFX_VBIOS_IMAGE_INFO *)ConfigPrt; pVbiosImageInfo->ImagePtr = cbfs_map( "pci"CONFIG_VGA_BIOS_ID".rom", NULL); printk(BIOS_DEBUG, "%s: IMGptr=%p\n", __func__, pVbiosImageInfo->ImagePtr); return pVbiosImageInfo->ImagePtr ? AGESA_SUCCESS : AGESA_WARNING; } AGESA_STATUS __weak platform_PcieSlotResetControl(uint32_t Func, uintptr_t Data, void *ConfigPtr) { printk(BIOS_WARNING, "Warning - AGESA callout: %s not supported\n", __func__); return AGESA_UNSUPPORTED; } AGESA_STATUS agesa_PcieSlotResetControl(uint32_t Func, uintptr_t Data, void *ConfigPtr) { return platform_PcieSlotResetControl(Func, Data, ConfigPtr); } /* * Application Processor callouts: * agesa_RunFuncOnAp() and agesa_RunFcnOnAllAps() are called after main memory * has been initialized and coreboot has taken control of AP task dispatching. * These functions execute callout_ap_entry() on each AP, which calls the * AmdLateRunApTask() entry point if it is a targeted AP. */ /* * Global data for APs. * Passed from the AGESA_Callout for the agesawrapper_amdlaterunaptask. */ static struct agesa_data { uint32_t Func; uintptr_t Data; AP_EXE_PARAMS *ConfigPtr; } agesadata; /* * BSP deploys APs to callout_ap_entry(), which calls * agesawrapper_amdlaterunaptask with the agesadata. */ static void callout_ap_entry(void *unused) { AGESA_STATUS Status = AGESA_UNSUPPORTED; printk(BIOS_DEBUG, "%s Func: 0x%x, Data: 0x%lx, Ptr: %p\n", __func__, agesadata.Func, agesadata.Data, agesadata.ConfigPtr); /* Check if this AP should run the function */ if (!((agesadata.Func == AGESA_RUNFUNC_ONAP) && (agesadata.Data == lapicid()))) return; Status = amd_late_run_ap_task(agesadata.ConfigPtr); if (Status) printk(BIOS_DEBUG, "There was a problem with %x returned %s\n", lapicid(), decodeAGESA_STATUS(Status)); } AGESA_STATUS agesa_RunFuncOnAp(uint32_t Func, uintptr_t Data, void *ConfigPtr) { printk(BIOS_DEBUG, "%s\n", __func__); agesadata.Func = Func; agesadata.Data = Data; agesadata.ConfigPtr = ConfigPtr; if (mp_run_on_aps(callout_ap_entry, NULL, MP_RUN_ON_ALL_CPUS, 100 * USECS_PER_MSEC) != CB_SUCCESS) return AGESA_ERROR; return AGESA_SUCCESS; } AGESA_STATUS agesa_RunFcnOnAllAps(uint32_t Func, uintptr_t Data, void *ConfigPtr) { printk(BIOS_DEBUG, "%s\n", __func__); agesadata.Func = Func; agesadata.Data = Data; agesadata.ConfigPtr = ConfigPtr; if (mp_run_on_aps(callout_ap_entry, NULL, MP_RUN_ON_ALL_CPUS, 100 * USECS_PER_MSEC) != CB_SUCCESS) return AGESA_ERROR; return AGESA_SUCCESS; } AGESA_STATUS agesa_WaitForAllApsFinished(uint32_t Func, uintptr_t Data, void *ConfigPtr) { printk(BIOS_WARNING, "Warning - AGESA callout: %s not supported\n", __func__); AGESA_STATUS Status = AGESA_UNSUPPORTED; return Status; } AGESA_STATUS agesa_IdleAnAp(uint32_t Func, uintptr_t Data, void *ConfigPtr) { printk(BIOS_WARNING, "Warning - AGESA callout: %s no supported\n", __func__); AGESA_STATUS Status = AGESA_UNSUPPORTED; return Status; }