/* * This file is part of the coreboot project. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #include <console/console.h> #include <stdint.h> #include <string.h> #include <northbridge/amd/agesa/state_machine.h> #include <northbridge/amd/agesa/BiosCallOuts.h> #include "amdlib.h" #include "AGESA.h" #include "AMD.h" #include <heapManager.h> static const char undefined[] = "undefined"; /* Match order of enum AGESA_STRUCT_NAME. */ static const char *AgesaFunctionNameStr[] = { "AmdInitRecovery", "AmdCreateStruct", "AmdInitEarly", "AmdInitEnv", "AmdInitLate", "AmdInitMid", "AmdInitPost", "AmdInitReset", "AmdInitResume", "AmdReleaseStruct", "AmdS3LateRestore","AmdS3Save", "AmdGetApicId", "AmdGetPciAddress", "AmdIdentifyCore", "AmdReadEventLog", "AmdGetAvailableExeCacheSize", "AmdLateRunApTask", "AmdIdentifyDimm", }; /* heapManager.h */ static const char *HeapStatusStr[] = { "DoNotExistYet", "LocalCache", "TempMem", "SystemMem", "DoNotExistAnymore","S3Resume" }; /* This function has to match with enumeration of AGESA_STRUCT_NAME defined * inside AMD.h header file. Unfortunately those are different across * different vendorcode subtrees. * * TBD: Fix said header or move this function together with the strings above * under vendorcode/ tree. */ const char *agesa_struct_name(int state) { #if IS_ENABLED(CONFIG_CPU_AMD_AGESA_OPENSOURCE) if ((state < AMD_INIT_RECOVERY) || (state > AMD_IDENTIFY_DIMMS)) return undefined; int index = state - AMD_INIT_RECOVERY; #else state >>= 12; if ((state < AMD_INIT_RECOVERY >> 12) || (state > AMD_IDENTIFY_DIMMS >> 12)) return undefined; int index = state - (AMD_INIT_RECOVERY >> 12); #endif return AgesaFunctionNameStr[index]; } const char *heap_status_name(int status) { if ((status < HEAP_DO_NOT_EXIST_YET) || (status > HEAP_S3_RESUME)) return undefined; int index = status - HEAP_DO_NOT_EXIST_YET; return HeapStatusStr[index]; } /* * Possible AGESA_STATUS values: * * 0x0 = AGESA_SUCCESS * 0x1 = AGESA_UNSUPPORTED * 0x2 = AGESA_BOUNDS_CHK * 0x3 = AGESA_ALERT * 0x4 = AGESA_WARNING * 0x5 = AGESA_ERROR * 0x6 = AGESA_CRITICAL * 0x7 = AGESA_FATAL */ static const char * decodeAGESA_STATUS(AGESA_STATUS sret) { const char* statusStrings[] = { "AGESA_SUCCESS", "AGESA_UNSUPPORTED", "AGESA_BOUNDS_CHK", "AGESA_ALERT", "AGESA_WARNING", "AGESA_ERROR", "AGESA_CRITICAL", "AGESA_FATAL" }; if (sret > 7) return "unknown"; /* Non-AGESA error code */ return statusStrings[sret]; } static void show_event(EVENT_PARAMS *Event) { printk(BIOS_DEBUG,"\nEventLog: EventClass = %x, EventInfo = %x.\n", (unsigned int)Event->EventClass, (unsigned int)Event->EventInfo); printk(BIOS_DEBUG," Param1 = %x, Param2 = %x.\n", (unsigned int)Event->DataParam1, (unsigned int)Event->DataParam2); printk(BIOS_DEBUG," Param3 = %x, Param4 = %x.\n", (unsigned int)Event->DataParam3, (unsigned int)Event->DataParam4); } #define MAX_LOG_ENTRIES 100 static void amd_flush_eventlog(EVENT_PARAMS *Event) { int i = 0; do { AGESA_STATUS status; #if HAS_LEGACY_WRAPPER status = AmdReadEventLog(Event); #else status = module_dispatch(AMD_READ_EVENT_LOG, &Event->StdHeader); #endif if (status != AGESA_SUCCESS) return; if (Event->EventClass == 0) return; show_event(Event); } while (++i < MAX_LOG_ENTRIES); } void agesawrapper_trace(AGESA_STATUS ret, AMD_CONFIG_PARAMS *StdHeader, const char *func) { EVENT_PARAMS AmdEventParams; printk(BIOS_DEBUG, "%s() returned %s\n", func, decodeAGESA_STATUS(ret)); if (ret == AGESA_SUCCESS) return; memset(&AmdEventParams, 0, sizeof(EVENT_PARAMS)); if (HAS_LEGACY_WRAPPER) { AmdEventParams.StdHeader.AltImageBasePtr = 0; AmdEventParams.StdHeader.CalloutPtr = &GetBiosCallout; AmdEventParams.StdHeader.Func = 0; AmdEventParams.StdHeader.ImageBasePtr = 0; AmdEventParams.StdHeader.HeapStatus = StdHeader->HeapStatus; } else { memcpy(&AmdEventParams.StdHeader, StdHeader, sizeof(*StdHeader)); } amd_flush_eventlog(&AmdEventParams); } AGESA_STATUS agesawrapper_amdreadeventlog (UINT8 HeapStatus) { EVENT_PARAMS AmdEventParams; memset(&AmdEventParams, 0, sizeof(EVENT_PARAMS)); AmdEventParams.StdHeader.AltImageBasePtr = 0; AmdEventParams.StdHeader.CalloutPtr = &GetBiosCallout; AmdEventParams.StdHeader.Func = 0; AmdEventParams.StdHeader.ImageBasePtr = 0; AmdEventParams.StdHeader.HeapStatus = HeapStatus; amd_flush_eventlog(&AmdEventParams); return AGESA_SUCCESS; }