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