blob: 5f52ca0904045b12bbefdd2f2fce0c7e3e194f23 [file] [log] [blame]
Angel Pons8a3453f2020-04-02 23:48:19 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Kyösti Mälkkic459f962014-05-04 17:07:45 +03002
Kyösti Mälkki36abdc42014-05-05 16:40:15 +03003#include <cbfs.h>
Elyes HAOUAS20eaef02019-03-29 17:45:28 +01004#include <console/console.h>
Patrick Georgi0e3c59e2017-01-28 15:59:25 +01005#include <spd_bin.h>
Kyösti Mälkkic7dcec62017-07-28 04:48:35 +03006#include <string.h>
Kyösti Mälkki36abdc42014-05-05 16:40:15 +03007
Elyes HAOUAS19f5ba82018-10-14 14:52:06 +02008#include <AGESA.h>
9#include <amdlib.h>
Kyösti Mälkkic459f962014-05-04 17:07:45 +030010#include "Ids.h"
Kyösti Mälkkic7dcec62017-07-28 04:48:35 +030011#include <northbridge/amd/agesa/state_machine.h>
Kyösti Mälkkid4955f02017-09-08 07:14:17 +030012#include <northbridge/amd/agesa/BiosCallOuts.h>
13#include <northbridge/amd/agesa/dimmSpd.h>
Kyösti Mälkkic459f962014-05-04 17:07:45 +030014
Kyösti Mälkkid8bf22a2020-06-08 06:05:03 +030015#if ENV_X86_64 && CONFIG(NORTHBRIDGE_AMD_PI)
Kyösti Mälkki9de82612017-04-13 16:56:07 +030016#error "FIXME: CALLOUT_ENTRY is UINT32 Data, not UINT Data"
17#endif
Kyösti Mälkki9de82612017-04-13 16:56:07 +030018
Stefan Reinauerdd132a52015-07-30 11:16:37 -070019AGESA_STATUS GetBiosCallout (UINT32 Func, UINTN Data, VOID *ConfigPtr)
Kyösti Mälkki6025efa2014-05-05 13:20:56 +030020{
Kyösti Mälkki82fbda72015-01-02 22:46:32 +020021 AGESA_STATUS status;
Kyösti Mälkki6025efa2014-05-05 13:20:56 +030022 UINTN i;
23
Kyösti Mälkki46f04cb2017-09-06 15:42:23 +030024 if (ENV_RAMSTAGE) {
Kyösti Mälkki3b4b0692017-09-08 07:37:06 +030025 /* One HeapManager serves them all. */
26 status = HeapManagerCallout(Func, Data, ConfigPtr);
27 if (status != AGESA_UNSUPPORTED)
28 return status;
29 }
Kyösti Mälkki82fbda72015-01-02 22:46:32 +020030
Kyösti Mälkkibf201d52017-03-30 17:26:25 +030031#if HAS_AGESA_FCH_OEM_CALLOUT
Kyösti Mälkki46f04cb2017-09-06 15:42:23 +030032 if (Func == AGESA_FCH_OEM_CALLOUT) {
Kyösti Mälkkibf201d52017-03-30 17:26:25 +030033 agesa_fch_oem_config(Data, ConfigPtr);
34 return AGESA_SUCCESS;
35 }
36#endif
37
Kyösti Mälkki6025efa2014-05-05 13:20:56 +030038 for (i = 0; i < BiosCalloutsLen; i++) {
39 if (BiosCallouts[i].CalloutName == Func)
40 break;
41 }
Elyes HAOUAS5a7e72f2016-08-23 21:36:02 +020042 if (i >= BiosCalloutsLen)
Kyösti Mälkki6025efa2014-05-05 13:20:56 +030043 return AGESA_UNSUPPORTED;
44
45 return BiosCallouts[i].CalloutPtr (Func, Data, ConfigPtr);
46}
47
Stefan Reinauerdd132a52015-07-30 11:16:37 -070048AGESA_STATUS agesa_NoopUnsupported (UINT32 Func, UINTN Data, VOID *ConfigPtr)
Kyösti Mälkkic459f962014-05-04 17:07:45 +030049{
50 return AGESA_UNSUPPORTED;
51}
52
Stefan Reinauerdd132a52015-07-30 11:16:37 -070053AGESA_STATUS agesa_NoopSuccess (UINT32 Func, UINTN Data, VOID *ConfigPtr)
Kyösti Mälkkic459f962014-05-04 17:07:45 +030054{
55 return AGESA_SUCCESS;
56}
57
Stefan Reinauerdd132a52015-07-30 11:16:37 -070058AGESA_STATUS agesa_EmptyIdsInitData (UINT32 Func, UINTN Data, VOID *ConfigPtr)
Kyösti Mälkkic459f962014-05-04 17:07:45 +030059{
60 IDS_NV_ITEM *IdsPtr = ((IDS_CALLOUT_STRUCT *) ConfigPtr)->IdsNvPtr;
61 if (Data == IDS_CALLOUT_INIT)
62 IdsPtr[0].IdsNvValue = IdsPtr[0].IdsNvId = 0xffff;
63 return AGESA_SUCCESS;
64}
Kyösti Mälkki5e19fa42014-05-04 23:13:54 +030065
Stefan Reinauerdd132a52015-07-30 11:16:37 -070066AGESA_STATUS agesa_Reset (UINT32 Func, UINTN Data, VOID *ConfigPtr)
Kyösti Mälkki5e19fa42014-05-04 23:13:54 +030067{
68 AGESA_STATUS Status;
69 UINT8 Value;
70 UINTN ResetType;
71 AMD_CONFIG_PARAMS *StdHeader;
72
73 ResetType = Data;
74 StdHeader = ConfigPtr;
75
76 //
77 // Perform the RESET based upon the ResetType. In case of
Elyes HAOUAS18958382018-08-07 12:23:16 +020078 // WARM_RESET_WHENEVER and COLD_RESET_WHENEVER, the request will go to
Kyösti Mälkki5e19fa42014-05-04 23:13:54 +030079 // AmdResetManager. During the critical condition, where reset is required
80 // immediately, the reset will be invoked directly by writing 0x04 to port
81 // 0xCF9 (Reset Port).
82 //
83 switch (ResetType) {
84 case WARM_RESET_WHENEVER:
85 case COLD_RESET_WHENEVER:
86 break;
87
88 case WARM_RESET_IMMEDIATELY:
89 case COLD_RESET_IMMEDIATELY:
90 Value = 0x06;
91 LibAmdIoWrite (AccessWidth8, 0xCf9, &Value, StdHeader);
92 break;
93
94 default:
95 break;
96 }
97
98 Status = 0;
99 return Status;
100}
Kyösti Mälkki6b4b1512014-05-05 12:05:53 +0300101
Stefan Reinauerdd132a52015-07-30 11:16:37 -0700102AGESA_STATUS agesa_RunFuncOnAp (UINT32 Func, UINTN Data, VOID *ConfigPtr)
Kyösti Mälkki6b4b1512014-05-05 12:05:53 +0300103{
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200104 AMD_CONFIG_PARAMS *StdHeader = ConfigPtr;
Kyösti Mälkkic7dcec62017-07-28 04:48:35 +0300105 AGESA_STATUS status;
106 AP_EXE_PARAMS ApExeParams;
Kyösti Mälkki6b4b1512014-05-05 12:05:53 +0300107
Kyösti Mälkkic7dcec62017-07-28 04:48:35 +0300108 memset(&ApExeParams, 0, sizeof(AP_EXE_PARAMS));
Kyösti Mälkki46f04cb2017-09-06 15:42:23 +0300109 memcpy(&ApExeParams.StdHeader, StdHeader, sizeof(*StdHeader));
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200110
Kyösti Mälkkic7dcec62017-07-28 04:48:35 +0300111 ApExeParams.FunctionNumber = Func;
112 ApExeParams.RelatedDataBlock = ConfigPtr;
113
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200114 status = module_dispatch(AMD_LATE_RUN_AP_TASK, &ApExeParams.StdHeader);
Kyösti Mälkkic7dcec62017-07-28 04:48:35 +0300115
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200116 ASSERT(status == AGESA_SUCCESS);
Kyösti Mälkkic7dcec62017-07-28 04:48:35 +0300117 return status;
Kyösti Mälkki6b4b1512014-05-05 12:05:53 +0300118}
119
Kyösti Mälkkia28bfad2017-04-13 17:01:18 +0300120#if defined(AGESA_GNB_GFX_GET_VBIOS_IMAGE)
Stefan Reinauerdd132a52015-07-30 11:16:37 -0700121AGESA_STATUS agesa_GfxGetVbiosImage(UINT32 Func, UINTN FchData, VOID *ConfigPrt)
Kyösti Mälkkicb989f22014-05-04 23:13:08 +0300122{
123 GFX_VBIOS_IMAGE_INFO *pVbiosImageInfo = (GFX_VBIOS_IMAGE_INFO *)ConfigPrt;
Julius Werner834b3ec2020-03-04 16:52:08 -0800124 pVbiosImageInfo->ImagePtr = cbfs_map("pci"CONFIG_VGA_BIOS_ID".rom", NULL);
Kyösti Mälkkicb989f22014-05-04 23:13:08 +0300125 /* printk(BIOS_DEBUG, "IMGptr=%x\n", pVbiosImageInfo->ImagePtr); */
126 return pVbiosImageInfo->ImagePtr == NULL ? AGESA_WARNING : AGESA_SUCCESS;
127}
Kyösti Mälkkia1ebbc42014-10-17 22:33:22 +0300128#endif
Kyösti Mälkkic5cc9f22014-10-17 22:33:22 +0300129
Stefan Reinauerdd132a52015-07-30 11:16:37 -0700130AGESA_STATUS agesa_ReadSpd (UINT32 Func, UINTN Data, VOID *ConfigPtr)
Kyösti Mälkkic5cc9f22014-10-17 22:33:22 +0300131{
Kyösti Mälkki5be75d52019-08-19 08:41:50 +0300132 if (!ENV_ROMSTAGE)
133 return AGESA_UNSUPPORTED;
134
135 return AmdMemoryReadSPD (Func, Data, ConfigPtr);
Kyösti Mälkkic5cc9f22014-10-17 22:33:22 +0300136}
Kyösti Mälkki36abdc42014-05-05 16:40:15 +0300137
Stefan Reinauerdd132a52015-07-30 11:16:37 -0700138AGESA_STATUS agesa_ReadSpd_from_cbfs(UINT32 Func, UINTN Data, VOID *ConfigPtr)
Kyösti Mälkki36abdc42014-05-05 16:40:15 +0300139{
Kyösti Mälkki36abdc42014-05-05 16:40:15 +0300140 AGESA_READ_SPD_PARAMS *info = ConfigPtr;
Kyösti Mälkki5be75d52019-08-19 08:41:50 +0300141
142 if (!ENV_ROMSTAGE)
143 return AGESA_UNSUPPORTED;
144
Kyösti Mälkki36abdc42014-05-05 16:40:15 +0300145 if (info->MemChannelId > 0)
146 return AGESA_UNSUPPORTED;
147 if (info->SocketId != 0)
148 return AGESA_UNSUPPORTED;
149 if (info->DimmId != 0)
150 return AGESA_UNSUPPORTED;
151
152 /* Read index 0, first SPD_SIZE bytes of spd.bin file. */
Patrick Georgi2e08b592017-01-28 15:26:43 +0100153 if (read_ddr3_spd_from_cbfs((u8*)info->Buffer, 0) < 0)
Kyösti Mälkki36abdc42014-05-05 16:40:15 +0300154 die("No SPD data\n");
155
Kyösti Mälkki5be75d52019-08-19 08:41:50 +0300156 return AGESA_SUCCESS;
Kyösti Mälkki36abdc42014-05-05 16:40:15 +0300157}
Kyösti Mälkkibf201d52017-03-30 17:26:25 +0300158
159#if HAS_AGESA_FCH_OEM_CALLOUT
160void agesa_fch_oem_config(uintptr_t Data, AMD_CONFIG_PARAMS *StdHeader)
161{
Kyösti Mälkkibf201d52017-03-30 17:26:25 +0300162 struct sysinfo *cb_NA = NULL;
163
164 if (StdHeader->Func == AMD_INIT_RESET) {
165 printk(BIOS_DEBUG, "Fch OEM config in INIT RESET\n");
166 board_FCH_InitReset(cb_NA, (FCH_RESET_DATA_BLOCK *)Data);
167 } else if (StdHeader->Func == AMD_INIT_ENV) {
168 printk(BIOS_DEBUG, "Fch OEM config in INIT ENV\n");
169 board_FCH_InitEnv(cb_NA, (FCH_DATA_BLOCK *)Data);
170 }
171}
172#endif