]> git.proxmox.com Git - mirror_edk2.git/blame - DuetPkg/DxeIpl/LegacyTable.c
Apply david's patch.
[mirror_edk2.git] / DuetPkg / DxeIpl / LegacyTable.c
CommitLineData
18b84857 1/** @file\r
ca162103 2\r
3Copyright (c) 2006, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13 LegacyTable.c\r
14\r
15Abstract:\r
16\r
17Revision History:\r
18\r
18b84857 19**/\r
ca162103 20\r
21#include "DxeIpl.h"\r
22#include "HobGeneration.h"\r
23\r
f40bbc08 24#define ACPI_RSD_PTR 0x2052545020445352LL\r
ca162103 25#define MPS_PTR EFI_SIGNATURE_32('_','M','P','_')\r
26#define SMBIOS_PTR EFI_SIGNATURE_32('_','S','M','_')\r
27\r
28#define EBDA_BASE_ADDRESS 0x40E\r
29\r
30VOID *\r
31FindAcpiRsdPtr (\r
32 VOID\r
33 )\r
34{\r
35 UINTN Address;\r
36 UINTN Index;\r
37\r
38 //\r
39 // First Seach 0x0e0000 - 0x0fffff for RSD Ptr\r
40 //\r
41 for (Address = 0xe0000; Address < 0xfffff; Address += 0x10) {\r
42 if (*(UINT64 *)(Address) == ACPI_RSD_PTR) {\r
43 return (VOID *)Address;\r
44 }\r
45 }\r
46\r
47 //\r
48 // Search EBDA\r
49 //\r
50\r
51 Address = (*(UINT16 *)(UINTN)(EBDA_BASE_ADDRESS)) << 4;\r
52 for (Index = 0; Index < 0x400 ; Index += 16) {\r
53 if (*(UINT64 *)(Address + Index) == ACPI_RSD_PTR) {\r
54 return (VOID *)Address;\r
55 }\r
56 }\r
57 return NULL;\r
58}\r
59\r
60VOID *\r
61FindSMBIOSPtr (\r
62 VOID\r
63 )\r
64{\r
65 UINTN Address;\r
66\r
67 //\r
68 // First Seach 0x0f0000 - 0x0fffff for SMBIOS Ptr\r
69 //\r
70 for (Address = 0xf0000; Address < 0xfffff; Address += 0x10) {\r
71 if (*(UINT32 *)(Address) == SMBIOS_PTR) {\r
72 return (VOID *)Address;\r
73 }\r
74 }\r
75 return NULL;\r
76}\r
77\r
78VOID *\r
79FindMPSPtr (\r
80 VOID\r
81 )\r
82{\r
83 UINTN Address;\r
84 UINTN Index;\r
85\r
86 //\r
87 // First Seach 0x0e0000 - 0x0fffff for MPS Ptr\r
88 //\r
89 for (Address = 0xe0000; Address < 0xfffff; Address += 0x10) {\r
90 if (*(UINT32 *)(Address) == MPS_PTR) {\r
91 return (VOID *)Address;\r
92 }\r
93 }\r
94\r
95 //\r
96 // Search EBDA\r
97 //\r
98\r
99 Address = (*(UINT16 *)(UINTN)(EBDA_BASE_ADDRESS)) << 4;\r
100 for (Index = 0; Index < 0x400 ; Index += 16) {\r
101 if (*(UINT32 *)(Address + Index) == MPS_PTR) {\r
102 return (VOID *)Address;\r
103 }\r
104 }\r
105 return NULL;\r
106}\r
107\r
108#pragma pack(1)\r
109typedef struct {\r
110 UINT8 Signature[8];\r
111 UINT8 Checksum;\r
112 UINT8 OemId[6];\r
113 UINT8 Revision;\r
114 UINT32 RsdtAddress;\r
115 UINT32 Length;\r
116 UINT64 XsdtAddress;\r
117 UINT8 ExtendedChecksum;\r
118 UINT8 Reserved[3];\r
119} RSDP_TABLE;\r
120\r
121typedef struct {\r
122 UINT32 Signature;\r
123 UINT32 Length;\r
124 UINT8 Revision;\r
125 UINT8 Checksum;\r
126 UINT8 OemId[6];\r
127 UINT8 OemTableId[8];\r
128 UINT32 OemRevision;\r
129 UINT8 CreatorId[4];\r
130 UINT32 CreatorRevision;\r
131} DESCRIPTION_HEADER;\r
132\r
133typedef struct {\r
134 DESCRIPTION_HEADER Header;\r
135 UINT32 Entry;\r
136} RSDT_TABLE;\r
137\r
138typedef struct {\r
139 DESCRIPTION_HEADER Header;\r
140 UINT64 Entry;\r
141} XSDT_TABLE;\r
142\r
143typedef struct {\r
144 UINT8 Address_Space_ID;\r
145 UINT8 Register_Bit_Width;\r
146 UINT8 Register_Bit_Offset;\r
147 UINT8 Access_Size;\r
148 UINT64 Address;\r
149} GADDRESS_STRUCTURE;\r
150\r
151#pragma pack()\r
152\r
153VOID\r
154ScanTableInRSDT (\r
155 RSDT_TABLE *Rsdt,\r
156 UINT32 Signature,\r
157 DESCRIPTION_HEADER **FoundTable\r
158 )\r
159{\r
160 UINTN Index;\r
161 UINT32 EntryCount;\r
162 UINT32 *EntryPtr;\r
163 DESCRIPTION_HEADER *Table;\r
164 \r
165 *FoundTable = NULL;\r
166 \r
167 EntryCount = (Rsdt->Header.Length - sizeof (DESCRIPTION_HEADER)) / sizeof(UINT32);\r
168 \r
169 EntryPtr = &Rsdt->Entry;\r
170 for (Index = 0; Index < EntryCount; Index ++, EntryPtr ++) {\r
171 Table = (DESCRIPTION_HEADER*)((UINTN)(*EntryPtr));\r
172 if (Table->Signature == Signature) {\r
173 *FoundTable = Table;\r
174 break;\r
175 }\r
176 }\r
177 \r
178 return;\r
179}\r
180\r
181VOID\r
182ScanTableInXSDT (\r
183 XSDT_TABLE *Xsdt,\r
184 UINT32 Signature,\r
185 DESCRIPTION_HEADER **FoundTable\r
186 )\r
187{\r
188 UINTN Index;\r
189 UINT32 EntryCount;\r
190 UINT64 EntryPtr;\r
191 UINTN BasePtr;\r
192 \r
193 DESCRIPTION_HEADER *Table;\r
194 \r
195 *FoundTable = NULL;\r
196 \r
197 EntryCount = (Xsdt->Header.Length - sizeof (DESCRIPTION_HEADER)) / sizeof(UINT64);\r
198 \r
199 BasePtr = (UINTN)(&(Xsdt->Entry));\r
200 for (Index = 0; Index < EntryCount; Index ++) {\r
201 CopyMem (&EntryPtr, (VOID *)(BasePtr + Index * sizeof(UINT64)), sizeof(UINT64));\r
202 Table = (DESCRIPTION_HEADER*)((UINTN)(EntryPtr));\r
203 if (Table->Signature == Signature) {\r
204 *FoundTable = Table;\r
205 break;\r
206 }\r
207 }\r
208 \r
209 return;\r
210}\r
211\r
212VOID *\r
213FindAcpiPtr (\r
214 IN HOB_TEMPLATE *Hob,\r
215 UINT32 Signature\r
216 )\r
217{\r
218 DESCRIPTION_HEADER *AcpiTable;\r
219 RSDP_TABLE *Rsdp;\r
220 RSDT_TABLE *Rsdt;\r
221 XSDT_TABLE *Xsdt;\r
222 \r
223 AcpiTable = NULL;\r
224\r
225 //\r
226 // Check ACPI2.0 table\r
227 //\r
228 if (Hob->Acpi20.Table > 0) {\r
229 Rsdp = (RSDP_TABLE *)(UINTN)Hob->Acpi20.Table;\r
230 Rsdt = (RSDT_TABLE *)(UINTN)Rsdp->RsdtAddress;\r
231 Xsdt = NULL;\r
232 if ((Rsdp->Revision >= 2) && (Rsdp->XsdtAddress < (UINT64)(UINTN)-1)) {\r
233 Xsdt = (XSDT_TABLE *)(UINTN)Rsdp->XsdtAddress;\r
234 }\r
235 //\r
236 // Check Xsdt\r
237 //\r
238 if (Xsdt != NULL) {\r
239 ScanTableInXSDT (Xsdt, Signature, &AcpiTable);\r
240 }\r
241 //\r
242 // Check Rsdt\r
243 //\r
244 if ((AcpiTable == NULL) && (Rsdt != NULL)) {\r
245 ScanTableInRSDT (Rsdt, Signature, &AcpiTable);\r
246 }\r
247 }\r
248 \r
249 //\r
250 // Check ACPI1.0 table\r
251 //\r
252 if ((AcpiTable == NULL) && (Hob->Acpi.Table > 0)) {\r
253 Rsdp = (RSDP_TABLE *)(UINTN)Hob->Acpi.Table;\r
254 Rsdt = (RSDT_TABLE *)(UINTN)Rsdp->RsdtAddress;\r
255 //\r
256 // Check Rsdt\r
257 //\r
258 if (Rsdt != NULL) {\r
259 ScanTableInRSDT (Rsdt, Signature, &AcpiTable);\r
260 }\r
261 }\r
262\r
263 return AcpiTable;\r
264}\r
265\r
266#pragma pack(1)\r
267//#define MCFG_SIGNATURE 0x4746434D\r
268#define MCFG_SIGNATURE EFI_SIGNATURE_32 ('M', 'C', 'F', 'G')\r
269typedef struct {\r
270 UINT64 BaseAddress;\r
271 UINT16 PciSegmentGroupNumber;\r
272 UINT8 StartBusNumber;\r
273 UINT8 EndBusNumber;\r
274 UINT32 Reserved;\r
275} MCFG_STRUCTURE;\r
276\r
277#define FADT_SIGNATURE EFI_SIGNATURE_32 ('F', 'A', 'C', 'P')\r
278typedef struct {\r
279 DESCRIPTION_HEADER Header;\r
280 UINT32 FIRMWARE_CTRL;\r
281 UINT32 DSDT;\r
282 UINT8 INT_MODEL;\r
283 UINT8 Preferred_PM_Profile;\r
284 UINT16 SCI_INIT;\r
285 UINT32 SMI_CMD;\r
286 UINT8 ACPI_ENABLE;\r
287 UINT8 ACPI_DISABLE;\r
288 UINT8 S4BIOS_REQ;\r
289 UINT8 PSTATE_CNT;\r
290 UINT32 PM1a_EVT_BLK;\r
291 UINT32 PM1b_EVT_BLK;\r
292 UINT32 PM1a_CNT_BLK;\r
293 UINT32 PM1b_CNT_BLK;\r
294 UINT32 PM2_CNT_BLK;\r
295 UINT32 PM_TMR_BLK;\r
296 UINT32 GPE0_BLK;\r
297 UINT32 GPE1_BLK;\r
298 UINT8 PM1_EVT_LEN;\r
299 UINT8 PM1_CNT_LEN;\r
300 UINT8 PM2_CNT_LEN;\r
301 UINT8 PM_TMR_LEN;\r
302 UINT8 GPE0_BLK_LEN;\r
303 UINT8 GPE1_BLK_LEN;\r
304 UINT8 GPE1_BASE;\r
305 UINT8 CST_CNT;\r
306 UINT16 P_LVL2_LAT;\r
307 UINT16 P_LVL3_LAT;\r
308 UINT16 FLUSH_SIZE;\r
309 UINT16 FLUSH_STRIDE;\r
310 UINT8 DUTY_OFFSET;\r
311 UINT8 DUTY_WIDTH;\r
312 UINT8 DAY_ALARM;\r
313 UINT8 MON_ALARM;\r
314 UINT8 CENTRY;\r
315 UINT16 IAPC_BOOT_ARCH;\r
316 UINT8 Reserved_111;\r
317 UINT32 Flags;\r
318 GADDRESS_STRUCTURE RESET_REG;\r
319 UINT8 RESET_VALUE;\r
320 UINT8 Reserved_129[3];\r
321 UINT64 X_FIRMWARE_CTRL;\r
322 UINT64 X_DSDT;\r
323 GADDRESS_STRUCTURE X_PM1a_EVT_BLK;\r
324 GADDRESS_STRUCTURE X_PM1b_EVT_BLK;\r
325 GADDRESS_STRUCTURE X_PM1a_CNT_BLK;\r
326 GADDRESS_STRUCTURE X_PM1b_CNT_BLK;\r
327 GADDRESS_STRUCTURE X_PM2_CNT_BLK;\r
328 GADDRESS_STRUCTURE X_PM_TMR_BLK;\r
329 GADDRESS_STRUCTURE X_GPE0_BLK;\r
330 GADDRESS_STRUCTURE X_GPE1_BLK;\r
331} FADT_TABLE;\r
332\r
333#pragma pack()\r
334\r
335VOID\r
336PrepareMcfgTable (\r
337 IN HOB_TEMPLATE *Hob\r
338 )\r
339{\r
340 DESCRIPTION_HEADER *McfgTable;\r
341 MCFG_STRUCTURE *Mcfg;\r
342 UINTN McfgCount;\r
343 UINTN Index;\r
344\r
345 McfgTable = FindAcpiPtr (Hob, MCFG_SIGNATURE);\r
346 if (McfgTable == NULL) {\r
347 return ;\r
348 }\r
349\r
350 Mcfg = (MCFG_STRUCTURE *)((UINTN)McfgTable + sizeof(DESCRIPTION_HEADER) + sizeof(UINT64));\r
351 McfgCount = (McfgTable->Length - sizeof(DESCRIPTION_HEADER) - sizeof(UINT64)) / sizeof(MCFG_STRUCTURE);\r
352\r
353 //\r
354 // Fill PciExpress info on Hob\r
355 // Note: Only for 1st segment\r
356 //\r
357 for (Index = 0; Index < McfgCount; Index++) {\r
358 if (Mcfg[Index].PciSegmentGroupNumber == 0) {\r
359 Hob->PciExpress.PciExpressBaseAddressInfo.PciExpressBaseAddress = Mcfg[Index].BaseAddress;\r
360 break;\r
361 }\r
362 }\r
363\r
364 return ;\r
365}\r
366\r
367VOID\r
368PrepareFadtTable (\r
369 IN HOB_TEMPLATE *Hob\r
370 )\r
371{\r
372 FADT_TABLE *Fadt;\r
373 EFI_ACPI_DESCRIPTION *AcpiDescription;\r
374\r
375 Fadt = FindAcpiPtr (Hob, FADT_SIGNATURE);\r
376 if (Fadt == NULL) {\r
377 return ;\r
378 }\r
379\r
380 AcpiDescription = &Hob->AcpiInfo.AcpiDescription;\r
381 //\r
382 // Fill AcpiDescription according to FADT\r
383 // Currently, only for PM_TMR\r
384 //\r
385 AcpiDescription->PM_TMR_LEN = Fadt->PM_TMR_LEN;\r
386 AcpiDescription->TMR_VAL_EXT = (UINT8)((Fadt->Flags & 0x100) != 0);\r
387 if ((Fadt->Header.Revision >= 3) && (Fadt->Header.Length >= sizeof(FADT_TABLE))) {\r
388 CopyMem (\r
389 &AcpiDescription->PM_TMR_BLK,\r
390 &Fadt->X_PM_TMR_BLK,\r
391 sizeof(GADDRESS_STRUCTURE)\r
392 );\r
393 CopyMem (\r
394 &AcpiDescription->RESET_REG,\r
395 &Fadt->RESET_REG,\r
396 sizeof(GADDRESS_STRUCTURE)\r
397 );\r
398 AcpiDescription->RESET_VALUE = Fadt->RESET_VALUE;\r
399 }\r
400 if (AcpiDescription->PM_TMR_BLK.Address == 0) {\r
401 AcpiDescription->PM_TMR_BLK.Address = Fadt->PM_TMR_BLK;\r
402 AcpiDescription->PM_TMR_BLK.AddressSpaceId = ACPI_ADDRESS_ID_IO;\r
403 AcpiDescription->PM_TMR_BLK.RegisterBitWidth = (AcpiDescription->TMR_VAL_EXT == 0) ? 24 : 32;\r
404 }\r
405\r
406 return ;\r
407}\r
408\r
409VOID\r
410PrepareHobLegacyTable (\r
411 IN HOB_TEMPLATE *Hob\r
412 )\r
413{\r
414 Hob->Acpi.Table = (EFI_PHYSICAL_ADDRESS)(UINTN)FindAcpiRsdPtr ();\r
415 Hob->Acpi20.Table = (EFI_PHYSICAL_ADDRESS)(UINTN)FindAcpiRsdPtr ();\r
416 Hob->Smbios.Table = (EFI_PHYSICAL_ADDRESS)(UINTN)FindSMBIOSPtr ();\r
417 Hob->Mps.Table = (EFI_PHYSICAL_ADDRESS)(UINTN)FindMPSPtr ();\r
418\r
419 PrepareMcfgTable (Hob);\r
420\r
421 PrepareFadtTable (Hob);\r
422\r
423 return ;\r
424}\r
425\r