/** * Application Processor perform a function as directed by the BSC. * * This is needed for an AP task that must run after AGESA has relinquished control * of the APs to the IBV. * * @param[in] AmdApExeParams The interface struct for any required routine. * * @return The most severe AGESA_STATUS returned by any called service. Note * that this will be the return value passed back to the BSC as the * return value for the call out. * */ AGESA_STATUS AmdLateRunApTask ( IN AP_EXE_PARAMS *AmdApExeParams ) { AGESA_STATUS CalledAgesaStatus; AGESA_STATUS ApLateTaskStatus; DISPATCH_TABLE *Entry; AGESA_TESTPOINT (TpIfAmdLateRunApTaskEntry, &AmdApExeParams->StdHeader); ASSERT (AmdApExeParams != NULL); ApLateTaskStatus = AGESA_SUCCESS; CalledAgesaStatus = AGESA_UNSUPPORTED; // Dispatch, if valid Entry = (DISPATCH_TABLE *) ApDispatchTable; while (Entry->FunctionId != 0) { if (AmdApExeParams->FunctionNumber == Entry->FunctionId) { CalledAgesaStatus = Entry->EntryPoint (AmdApExeParams); break; } Entry++; } if (CalledAgesaStatus > ApLateTaskStatus) { ApLateTaskStatus = CalledAgesaStatus; } AGESA_TESTPOINT (TpIfAmdLateRunApTaskExit, &AmdApExeParams->StdHeader); return ApLateTaskStatus; }
/** * The Dispatcher is the entry point into the AGESA software. It takes a function * number as entry parameter in order to invoke the published function * * @param[in,out] ConfigPtr * * @return AGESA Status. * */ AGESA_STATUS CALLCONV AmdAgesaDispatcher ( IN OUT VOID *ConfigPtr ) { AGESA_STATUS Status; MODULE_ENTRY ModuleEntry; DISPATCH_TABLE *Entry; Status = AGESA_UNSUPPORTED; ModuleEntry = NULL; Entry = (DISPATCH_TABLE *) DispatchTable; while (Entry->FunctionId != 0) { if ((((AMD_CONFIG_PARAMS *) ConfigPtr)->Func) == Entry->FunctionId) { Status = Entry->EntryPoint (ConfigPtr); break; } Entry++; } // 2. Try next dispatcher if possible, and we have not already got status back if ((mCpuModuleID.NextBlock != NULL) && (Status == AGESA_UNSUPPORTED)) { ModuleEntry = (MODULE_ENTRY) /* (UINT64) */ mCpuModuleID.NextBlock->ModuleDispatcher; if (ModuleEntry != NULL) { Status = (*ModuleEntry) (ConfigPtr); } } return (Status); }
/** * The Dispatcher is the entry point into the AGESA software. It takes a function * number as entry parameter in order to invoke the published function * * @param[in,out] ConfigPtr * * @return AGESA Status. * */ AGESA_STATUS CALLCONV AmdAgesaDispatcher ( IN OUT VOID *ConfigPtrParm ) { AGESA_STATUS Status = AGESA_UNSUPPORTED; AMD_CONFIG_PARAMS *ConfigPtr = ConfigPtrParm; { DISPATCH_TABLE *Entry; Entry = (DISPATCH_TABLE *) DispatchTable; while (Entry->FunctionId != 0) { if (ConfigPtr->Func == Entry->FunctionId) { Status = Entry->EntryPoint (ConfigPtr); break; } Entry++; } } // 2. Try next dispatcher if possible, and we have not already got status back if ((mCpuModuleID.NextBlock != NULL) && (Status == AGESA_UNSUPPORTED)) { MODULE_ENTRY ModuleEntry = NULL; ModuleEntry = (MODULE_ENTRY) (UINT64) mCpuModuleID.NextBlock->ModuleDispatcher; if (ModuleEntry != NULL) { Status = (*ModuleEntry) (ConfigPtr); } } // 3. If not this image specific function, see if we can find alternative image instead if (Status == AGESA_UNSUPPORTED) { IMAGE_ENTRY ImageEntry = NULL; UINT32 ImageStart = 0xFFE80000; UINT32 ImageEnd = 0xFFFC0000; AMD_IMAGE_HEADER* AltImagePtr = NULL; if ((((AMD_CONFIG_PARAMS *)ConfigPtr)->AltImageBasePtr != 0xFFFFFFFF ) || (((AMD_CONFIG_PARAMS *)ConfigPtr)->AltImageBasePtr != 0)) { ImageStart = ((AMD_CONFIG_PARAMS *)ConfigPtr)->AltImageBasePtr; ImageEnd = ImageStart + 4; // Locate/test image base that matches this component AltImagePtr = LibAmdLocateImage ( (VOID *)ImageStart, (VOID *)ImageEnd, 4096, (CHAR8 *)AGESA_ID ); if (AltImagePtr != NULL) { //Invoke alternative Image ImageEntry = (IMAGE_ENTRY) ((UINT64) AltImagePtr + AltImagePtr->EntryPointAddress); Status = (*ImageEntry) (ConfigPtr); } } } return (Status); }