blob: 0b56ac82b9780f1d1fab6a77b1b7165fa96d490a [file] [log] [blame]
Angel Pons8a3453f2020-04-02 23:48:19 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Kyösti Mälkkie68f4ff2014-10-22 15:53:34 +03002
Arthur Heymans78ab06a2021-05-29 06:58:38 +02003#include <cpu/x86/lapic.h>
Kyösti Mälkkie68f4ff2014-10-22 15:53:34 +03004#include <console/console.h>
Kyösti Mälkki1aa35c62014-10-21 14:19:04 +03005#include <stdint.h>
6#include <string.h>
Kyösti Mälkki43f6d9d2019-03-14 14:59:31 +02007#include <timestamp.h>
Kyösti Mälkkie68f4ff2014-10-22 15:53:34 +03008
Kyösti Mälkkiacc599b2016-11-24 14:31:07 +02009#include <northbridge/amd/agesa/state_machine.h>
Kyösti Mälkkie68f4ff2014-10-22 15:53:34 +030010#include <northbridge/amd/agesa/BiosCallOuts.h>
Elyes HAOUAS19f5ba82018-10-14 14:52:06 +020011#include <amdlib.h>
Kyösti Mälkkid1d4f932017-09-24 08:21:00 +030012#include <debug_util.h>
Elyes HAOUAS19f5ba82018-10-14 14:52:06 +020013#include <AGESA.h>
14#include <AMD.h>
Kyösti Mälkki1aa35c62014-10-21 14:19:04 +030015
Kyösti Mälkkiacc599b2016-11-24 14:31:07 +020016static const char undefined[] = "undefined";
17
Kyösti Mälkkie20d6092018-06-10 08:20:56 +030018struct agesa_mapping
19{
20 AGESA_STRUCT_NAME func;
21 const char *name;
Kyösti Mälkki43f6d9d2019-03-14 14:59:31 +020022 uint32_t entry_id;
23 uint32_t exit_id;
Kyösti Mälkkiacc599b2016-11-24 14:31:07 +020024};
25
Kyösti Mälkkie20d6092018-06-10 08:20:56 +030026static const struct agesa_mapping entrypoint[] = {
27 {
28 .func = AMD_INIT_RESET,
29 .name = "AmdInitReset",
Kyösti Mälkki43f6d9d2019-03-14 14:59:31 +020030 .entry_id = TS_AGESA_INIT_RESET_START,
Jakub Czapigaad6157e2022-02-15 11:50:31 +010031 .exit_id = TS_AGESA_INIT_RESET_END,
Kyösti Mälkkie20d6092018-06-10 08:20:56 +030032 },
33 {
34 .func = AMD_INIT_EARLY,
35 .name = "AmdInitEarly",
Kyösti Mälkki43f6d9d2019-03-14 14:59:31 +020036 .entry_id = TS_AGESA_INIT_EARLY_START,
Jakub Czapigaad6157e2022-02-15 11:50:31 +010037 .exit_id = TS_AGESA_INIT_EARLY_END,
Kyösti Mälkkie20d6092018-06-10 08:20:56 +030038 },
39 {
40 .func = AMD_INIT_POST,
41 .name = "AmdInitPost",
Kyösti Mälkki43f6d9d2019-03-14 14:59:31 +020042 .entry_id = TS_AGESA_INIT_POST_START,
Jakub Czapigaad6157e2022-02-15 11:50:31 +010043 .exit_id = TS_AGESA_INIT_POST_END,
Kyösti Mälkkie20d6092018-06-10 08:20:56 +030044 },
45 {
46 .func = AMD_INIT_RESUME,
47 .name = "AmdInitResume",
Kyösti Mälkki43f6d9d2019-03-14 14:59:31 +020048 .entry_id = TS_AGESA_INIT_RESUME_START,
Jakub Czapigaad6157e2022-02-15 11:50:31 +010049 .exit_id = TS_AGESA_INIT_RESUME_END,
Kyösti Mälkkie20d6092018-06-10 08:20:56 +030050 },
51 {
52 .func = AMD_INIT_ENV,
53 .name = "AmdInitEnv",
Kyösti Mälkki43f6d9d2019-03-14 14:59:31 +020054 .entry_id = TS_AGESA_INIT_ENV_START,
Jakub Czapigaad6157e2022-02-15 11:50:31 +010055 .exit_id = TS_AGESA_INIT_ENV_END,
Kyösti Mälkkie20d6092018-06-10 08:20:56 +030056 },
57 {
58 .func = AMD_INIT_MID,
59 .name = "AmdInitMid",
Kyösti Mälkki43f6d9d2019-03-14 14:59:31 +020060 .entry_id = TS_AGESA_INIT_MID_START,
Jakub Czapigaad6157e2022-02-15 11:50:31 +010061 .exit_id = TS_AGESA_INIT_MID_END,
Kyösti Mälkkie20d6092018-06-10 08:20:56 +030062 },
63 {
64 .func = AMD_INIT_LATE,
65 .name = "AmdInitLate",
Kyösti Mälkki43f6d9d2019-03-14 14:59:31 +020066 .entry_id = TS_AGESA_INIT_LATE_START,
Jakub Czapigaad6157e2022-02-15 11:50:31 +010067 .exit_id = TS_AGESA_INIT_LATE_END,
Kyösti Mälkkie20d6092018-06-10 08:20:56 +030068 },
69 {
70 .func = AMD_S3LATE_RESTORE,
71 .name = "AmdS3LateRestore",
Kyösti Mälkki43f6d9d2019-03-14 14:59:31 +020072 .entry_id = TS_AGESA_S3_LATE_START,
Jakub Czapigaad6157e2022-02-15 11:50:31 +010073 .exit_id = TS_AGESA_S3_LATE_END,
Kyösti Mälkkie20d6092018-06-10 08:20:56 +030074 },
75#if !defined(AMD_S3_SAVE_REMOVED)
76 {
77 .func = AMD_S3_SAVE,
78 .name = "AmdS3Save",
Kyösti Mälkki43f6d9d2019-03-14 14:59:31 +020079 .entry_id = TS_AGESA_INIT_RTB_START,
Jakub Czapigaad6157e2022-02-15 11:50:31 +010080 .exit_id = TS_AGESA_INIT_RTB_END,
Kyösti Mälkkie20d6092018-06-10 08:20:56 +030081 },
Kyösti Mälkki903ce252016-11-25 11:21:02 +020082#endif
Kyösti Mälkkie20d6092018-06-10 08:20:56 +030083 {
84 .func = AMD_S3FINAL_RESTORE,
85 .name = "AmdS3FinalRestore",
Kyösti Mälkki43f6d9d2019-03-14 14:59:31 +020086 .entry_id = TS_AGESA_S3_FINAL_START,
Jakub Czapigaad6157e2022-02-15 11:50:31 +010087 .exit_id = TS_AGESA_S3_FINAL_END,
Kyösti Mälkkie20d6092018-06-10 08:20:56 +030088 },
89 {
90 .func = AMD_INIT_RTB,
91 .name = "AmdInitRtb",
Kyösti Mälkki43f6d9d2019-03-14 14:59:31 +020092 .entry_id = TS_AGESA_INIT_RTB_START,
Jakub Czapigaad6157e2022-02-15 11:50:31 +010093 .exit_id = TS_AGESA_INIT_RTB_END,
Kyösti Mälkkie20d6092018-06-10 08:20:56 +030094 },
95};
Kyösti Mälkkiacc599b2016-11-24 14:31:07 +020096
Kyösti Mälkkid1d4f932017-09-24 08:21:00 +030097void agesa_state_on_entry(struct agesa_state *task, AGESA_STRUCT_NAME func)
98{
Kyösti Mälkkie20d6092018-06-10 08:20:56 +030099 int i;
100
Arthur Heymans78ab06a2021-05-29 06:58:38 +0200101 task->apic_id = (u8)initial_lapicid();
Kyösti Mälkkid1d4f932017-09-24 08:21:00 +0300102 task->func = func;
Kyösti Mälkkie20d6092018-06-10 08:20:56 +0300103 task->function_name = undefined;
104
105 for (i = 0; i < ARRAY_SIZE(entrypoint); i++) {
106 if (task->func == entrypoint[i].func) {
107 task->function_name = entrypoint[i].name;
Kyösti Mälkki43f6d9d2019-03-14 14:59:31 +0200108 task->ts_entry_id = entrypoint[i].entry_id;
109 task->ts_exit_id = entrypoint[i].exit_id;
Kyösti Mälkkie20d6092018-06-10 08:20:56 +0300110 break;
111 }
112 }
Kyösti Mälkkid1d4f932017-09-24 08:21:00 +0300113
114 printk(BIOS_DEBUG, "\nAPIC %02d: ** Enter %s [%08x]\n",
115 task->apic_id, task->function_name, task->func);
116}
117
118void agesa_state_on_exit(struct agesa_state *task,
119 AMD_CONFIG_PARAMS *StdHeader)
120{
121 printk(BIOS_DEBUG, "APIC %02d: Heap in %s (%d) at 0x%08x\n",
122 task->apic_id, heap_status_name(StdHeader->HeapStatus),
123 StdHeader->HeapStatus, (u32)StdHeader->HeapBasePtr);
124
125 printk(BIOS_DEBUG, "APIC %02d: ** Exit %s [%08x]\n",
126 task->apic_id, task->function_name, task->func);
127}
128
Kyösti Mälkki1aa35c62014-10-21 14:19:04 +0300129/*
130 * Possible AGESA_STATUS values:
131 *
132 * 0x0 = AGESA_SUCCESS
133 * 0x1 = AGESA_UNSUPPORTED
134 * 0x2 = AGESA_BOUNDS_CHK
135 * 0x3 = AGESA_ALERT
136 * 0x4 = AGESA_WARNING
137 * 0x5 = AGESA_ERROR
138 * 0x6 = AGESA_CRITICAL
139 * 0x7 = AGESA_FATAL
140 */
Elyes HAOUAS448d9fb2018-05-22 12:51:27 +0200141static const char *decodeAGESA_STATUS(AGESA_STATUS sret)
Kyösti Mälkki1aa35c62014-10-21 14:19:04 +0300142{
Elyes HAOUAS448d9fb2018-05-22 12:51:27 +0200143 const char *statusStrings[] = { "AGESA_SUCCESS", "AGESA_UNSUPPORTED",
Kyösti Mälkki1aa35c62014-10-21 14:19:04 +0300144 "AGESA_BOUNDS_CHK", "AGESA_ALERT",
145 "AGESA_WARNING", "AGESA_ERROR",
146 "AGESA_CRITICAL", "AGESA_FATAL"
147 };
148 if (sret > 7) return "unknown"; /* Non-AGESA error code */
149 return statusStrings[sret];
150}
Kyösti Mälkkie68f4ff2014-10-22 15:53:34 +0300151
Kyösti Mälkki0a7cab82017-07-29 08:11:52 +0300152static void show_event(EVENT_PARAMS *Event)
Kyösti Mälkkie68f4ff2014-10-22 15:53:34 +0300153{
Elyes Haouas76c63232022-07-16 09:47:00 +0200154 printk(BIOS_DEBUG, "\nEventLog: EventClass = %x, EventInfo = %x.\n",
Kyösti Mälkki0a7cab82017-07-29 08:11:52 +0300155 (unsigned int)Event->EventClass,
156 (unsigned int)Event->EventInfo);
Elyes Haouas76c63232022-07-16 09:47:00 +0200157 printk(BIOS_DEBUG, " Param1 = %x, Param2 = %x.\n",
Kyösti Mälkki0a7cab82017-07-29 08:11:52 +0300158 (unsigned int)Event->DataParam1,
159 (unsigned int)Event->DataParam2);
Elyes Haouas76c63232022-07-16 09:47:00 +0200160 printk(BIOS_DEBUG, " Param3 = %x, Param4 = %x.\n",
Kyösti Mälkki0a7cab82017-07-29 08:11:52 +0300161 (unsigned int)Event->DataParam3,
162 (unsigned int)Event->DataParam4);
163}
164
165#define MAX_LOG_ENTRIES 100
166
167static void amd_flush_eventlog(EVENT_PARAMS *Event)
168{
169 int i = 0;
170
171 do {
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200172 AGESA_STATUS status;
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200173 status = module_dispatch(AMD_READ_EVENT_LOG, &Event->StdHeader);
Kyösti Mälkki0a7cab82017-07-29 08:11:52 +0300174 if (status != AGESA_SUCCESS)
175 return;
176 if (Event->EventClass == 0)
177 return;
178 show_event(Event);
179 } while (++i < MAX_LOG_ENTRIES);
180}
181
182void agesawrapper_trace(AGESA_STATUS ret, AMD_CONFIG_PARAMS *StdHeader,
183 const char *func)
184{
Kyösti Mälkkie68f4ff2014-10-22 15:53:34 +0300185 EVENT_PARAMS AmdEventParams;
186
Kyösti Mälkki0a7cab82017-07-29 08:11:52 +0300187 printk(BIOS_DEBUG, "%s() returned %s\n", func, decodeAGESA_STATUS(ret));
188 if (ret == AGESA_SUCCESS)
189 return;
190
Kyösti Mälkki1aa35c62014-10-21 14:19:04 +0300191 memset(&AmdEventParams, 0, sizeof(EVENT_PARAMS));
Kyösti Mälkki46f04cb2017-09-06 15:42:23 +0300192 memcpy(&AmdEventParams.StdHeader, StdHeader, sizeof(*StdHeader));
Kyösti Mälkki1aa35c62014-10-21 14:19:04 +0300193
Kyösti Mälkki0a7cab82017-07-29 08:11:52 +0300194 amd_flush_eventlog(&AmdEventParams);
Kyösti Mälkki1aa35c62014-10-21 14:19:04 +0300195}
Kyösti Mälkkie68f4ff2014-10-22 15:53:34 +0300196
Elyes Haouas76c63232022-07-16 09:47:00 +0200197AGESA_STATUS agesawrapper_amdreadeventlog(UINT8 HeapStatus)
Kyösti Mälkki1aa35c62014-10-21 14:19:04 +0300198{
Kyösti Mälkki0a7cab82017-07-29 08:11:52 +0300199 EVENT_PARAMS AmdEventParams;
200
201 memset(&AmdEventParams, 0, sizeof(EVENT_PARAMS));
202
203 AmdEventParams.StdHeader.AltImageBasePtr = 0;
204 AmdEventParams.StdHeader.CalloutPtr = &GetBiosCallout;
205 AmdEventParams.StdHeader.Func = 0;
206 AmdEventParams.StdHeader.ImageBasePtr = 0;
207 AmdEventParams.StdHeader.HeapStatus = HeapStatus;
208
209 amd_flush_eventlog(&AmdEventParams);
210
211 return AGESA_SUCCESS;
Kyösti Mälkkie68f4ff2014-10-22 15:53:34 +0300212}