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