diff options
Diffstat (limited to 'src/drivers/amd/agesa/eventlog.c')
-rw-r--r-- | src/drivers/amd/agesa/eventlog.c | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/src/drivers/amd/agesa/eventlog.c b/src/drivers/amd/agesa/eventlog.c new file mode 100644 index 0000000000..33e5590530 --- /dev/null +++ b/src/drivers/amd/agesa/eventlog.c @@ -0,0 +1,171 @@ +/* + * 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; +} |