]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - DuetPkg/DxeIpl/LegacyTable.c
BaseTools: Fix parse OFFSET_OF get wrong offset
[mirror_edk2.git] / DuetPkg / DxeIpl / LegacyTable.c
... / ...
CommitLineData
1/** @file\r
2\r
3Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
4This 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
19**/\r
20\r
21#include "DxeIpl.h"\r
22#include "HobGeneration.h"\r
23#include "Debug.h"\r
24\r
25#define MPS_PTR SIGNATURE_32('_','M','P','_')\r
26#define SMBIOS_PTR 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) == EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE) {\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) == EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE) {\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
109\r
110typedef struct {\r
111 EFI_ACPI_DESCRIPTION_HEADER Header;\r
112 UINT32 Entry;\r
113} RSDT_TABLE;\r
114\r
115typedef struct {\r
116 EFI_ACPI_DESCRIPTION_HEADER Header;\r
117 UINT64 Entry;\r
118} XSDT_TABLE;\r
119\r
120#pragma pack()\r
121\r
122VOID\r
123ScanTableInRSDT (\r
124 RSDT_TABLE *Rsdt,\r
125 UINT32 Signature,\r
126 EFI_ACPI_DESCRIPTION_HEADER **FoundTable\r
127 )\r
128{\r
129 UINTN Index;\r
130 UINT32 EntryCount;\r
131 UINT32 *EntryPtr;\r
132 EFI_ACPI_DESCRIPTION_HEADER *Table;\r
133 \r
134 *FoundTable = NULL;\r
135 \r
136 EntryCount = (Rsdt->Header.Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof(UINT32);\r
137 \r
138 EntryPtr = &Rsdt->Entry;\r
139 for (Index = 0; Index < EntryCount; Index ++, EntryPtr ++) {\r
140 Table = (EFI_ACPI_DESCRIPTION_HEADER*)((UINTN)(*EntryPtr));\r
141 if (Table->Signature == Signature) {\r
142 *FoundTable = Table;\r
143 break;\r
144 }\r
145 }\r
146 \r
147 return;\r
148}\r
149\r
150VOID\r
151ScanTableInXSDT (\r
152 XSDT_TABLE *Xsdt,\r
153 UINT32 Signature,\r
154 EFI_ACPI_DESCRIPTION_HEADER **FoundTable\r
155 )\r
156{\r
157 UINTN Index;\r
158 UINT32 EntryCount;\r
159 UINT64 EntryPtr;\r
160 UINTN BasePtr;\r
161 EFI_ACPI_DESCRIPTION_HEADER *Table;\r
162 \r
163 *FoundTable = NULL;\r
164 \r
165 EntryCount = (Xsdt->Header.Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof(UINT64);\r
166 \r
167 BasePtr = (UINTN)(&(Xsdt->Entry));\r
168 for (Index = 0; Index < EntryCount; Index ++) {\r
169 CopyMem (&EntryPtr, (VOID *)(BasePtr + Index * sizeof(UINT64)), sizeof(UINT64));\r
170 Table = (EFI_ACPI_DESCRIPTION_HEADER*)((UINTN)(EntryPtr));\r
171 if (Table->Signature == Signature) {\r
172 *FoundTable = Table;\r
173 break;\r
174 }\r
175 }\r
176 \r
177 return;\r
178}\r
179\r
180VOID *\r
181FindAcpiPtr (\r
182 IN HOB_TEMPLATE *Hob,\r
183 UINT32 Signature\r
184 )\r
185{\r
186 EFI_ACPI_DESCRIPTION_HEADER *AcpiTable;\r
187 EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp;\r
188 RSDT_TABLE *Rsdt;\r
189 XSDT_TABLE *Xsdt;\r
190 \r
191 AcpiTable = NULL;\r
192\r
193 //\r
194 // Check ACPI2.0 table\r
195 //\r
196 if ((int)Hob->Acpi20.Table != -1) {\r
197 Rsdp = (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)(UINTN)Hob->Acpi20.Table;\r
198 Rsdt = (RSDT_TABLE *)(UINTN)Rsdp->RsdtAddress;\r
199 Xsdt = NULL;\r
200 if ((Rsdp->Revision >= 2) && (Rsdp->XsdtAddress < (UINT64)(UINTN)-1)) {\r
201 Xsdt = (XSDT_TABLE *)(UINTN)Rsdp->XsdtAddress;\r
202 }\r
203 //\r
204 // Check Xsdt\r
205 //\r
206 if (Xsdt != NULL) {\r
207 ScanTableInXSDT (Xsdt, Signature, &AcpiTable);\r
208 }\r
209 //\r
210 // Check Rsdt\r
211 //\r
212 if ((AcpiTable == NULL) && (Rsdt != NULL)) {\r
213 ScanTableInRSDT (Rsdt, Signature, &AcpiTable);\r
214 }\r
215 }\r
216 \r
217 //\r
218 // Check ACPI1.0 table\r
219 //\r
220 if ((AcpiTable == NULL) && ((int)Hob->Acpi.Table != -1)) {\r
221 Rsdp = (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)(UINTN)Hob->Acpi.Table;\r
222 Rsdt = (RSDT_TABLE *)(UINTN)Rsdp->RsdtAddress;\r
223 //\r
224 // Check Rsdt\r
225 //\r
226 if (Rsdt != NULL) {\r
227 ScanTableInRSDT (Rsdt, Signature, &AcpiTable);\r
228 }\r
229 }\r
230\r
231 return AcpiTable;\r
232}\r
233\r
234#pragma pack(1)\r
235typedef struct {\r
236 UINT64 BaseAddress;\r
237 UINT16 PciSegmentGroupNumber;\r
238 UINT8 StartBusNumber;\r
239 UINT8 EndBusNumber;\r
240 UINT32 Reserved;\r
241} MCFG_STRUCTURE;\r
242#pragma pack()\r
243\r
244VOID\r
245PrepareMcfgTable (\r
246 IN HOB_TEMPLATE *Hob\r
247 )\r
248{\r
249 EFI_ACPI_DESCRIPTION_HEADER *McfgTable;\r
250 MCFG_STRUCTURE *Mcfg;\r
251 UINTN McfgCount;\r
252 UINTN Index;\r
253\r
254 McfgTable = FindAcpiPtr (Hob, EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE);\r
255 if (McfgTable == NULL) {\r
256 return ;\r
257 }\r
258\r
259 Mcfg = (MCFG_STRUCTURE *)((UINTN)McfgTable + sizeof(EFI_ACPI_DESCRIPTION_HEADER) + sizeof(UINT64));\r
260 McfgCount = (McfgTable->Length - sizeof(EFI_ACPI_DESCRIPTION_HEADER) - sizeof(UINT64)) / sizeof(MCFG_STRUCTURE);\r
261\r
262 //\r
263 // Fill PciExpress info on Hob\r
264 // Note: Only for 1st segment\r
265 //\r
266 for (Index = 0; Index < McfgCount; Index++) {\r
267 if (Mcfg[Index].PciSegmentGroupNumber == 0) {\r
268 Hob->PciExpress.PciExpressBaseAddressInfo.PciExpressBaseAddress = Mcfg[Index].BaseAddress;\r
269 break;\r
270 }\r
271 }\r
272\r
273 return ;\r
274}\r
275\r
276VOID\r
277PrepareFadtTable (\r
278 IN HOB_TEMPLATE *Hob\r
279 )\r
280{\r
281 EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt;\r
282 EFI_ACPI_DESCRIPTION *AcpiDescription;\r
283\r
284 Fadt = FindAcpiPtr (Hob, EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE);\r
285 if (Fadt == NULL) {\r
286 return ;\r
287 }\r
288\r
289 AcpiDescription = &Hob->AcpiInfo.AcpiDescription;\r
290 //\r
291 // Fill AcpiDescription according to FADT\r
292 // Currently, only for PM_TMR\r
293 //\r
294 AcpiDescription->PM_TMR_LEN = Fadt->PmTmrLen;\r
295 AcpiDescription->TMR_VAL_EXT = (UINT8)((Fadt->Flags & 0x100) != 0);\r
296 \r
297 //\r
298 // For fields not included in ACPI 1.0 spec, we get the value based on table length\r
299 //\r
300 if (Fadt->Header.Length >= OFFSET_OF (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE, XPmTmrBlk) + sizeof (Fadt->XPmTmrBlk)) {\r
301 CopyMem (\r
302 &AcpiDescription->PM_TMR_BLK,\r
303 &Fadt->XPmTmrBlk,\r
304 sizeof(EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE)\r
305 );\r
306 }\r
307 if (Fadt->Header.Length >= OFFSET_OF (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE, ResetValue) + sizeof (Fadt->ResetValue)) {\r
308 CopyMem (\r
309 &AcpiDescription->RESET_REG,\r
310 &Fadt->ResetReg,\r
311 sizeof(EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE)\r
312 );\r
313 AcpiDescription->RESET_VALUE = Fadt->ResetValue;\r
314 }\r
315\r
316 if (AcpiDescription->PM_TMR_BLK.Address == 0) {\r
317 AcpiDescription->PM_TMR_BLK.Address = Fadt->PmTmrBlk;\r
318 AcpiDescription->PM_TMR_BLK.AddressSpaceId = EFI_ACPI_3_0_SYSTEM_IO;\r
319 }\r
320\r
321 //\r
322 // It's possible that the PM_TMR_BLK.RegisterBitWidth is always 32,\r
323 // we need to set the correct RegisterBitWidth value according to the TMR_VAL_EXT\r
324 // A zero indicates TMR_VAL is implemented as a 24-bit value. \r
325 // A one indicates TMR_VAL is implemented as a 32-bit value\r
326 //\r
327 AcpiDescription->PM_TMR_BLK.RegisterBitWidth = (UINT8) ((AcpiDescription->TMR_VAL_EXT == 0) ? 24 : 32);\r
328 \r
329\r
330 return ;\r
331}\r
332\r
333VOID\r
334PrepareHobLegacyTable (\r
335 IN HOB_TEMPLATE *Hob\r
336 )\r
337{\r
338 CHAR8 PrintBuffer[256];\r
339\r
340 Hob->Acpi.Table = (EFI_PHYSICAL_ADDRESS)(UINTN)FindAcpiRsdPtr ();\r
341 AsciiSPrint (PrintBuffer, 256, "\nAcpiTable=0x%x ", (UINT32)(UINTN)Hob->Acpi.Table);\r
342 PrintString (PrintBuffer);\r
343 Hob->Acpi20.Table = (EFI_PHYSICAL_ADDRESS)(UINTN)FindAcpiRsdPtr ();\r
344 Hob->Smbios.Table = (EFI_PHYSICAL_ADDRESS)(UINTN)FindSMBIOSPtr ();\r
345 AsciiSPrint (PrintBuffer, 256, "SMBIOS Table=0x%x ", (UINT32)(UINTN)Hob->Smbios.Table);\r
346 PrintString (PrintBuffer);\r
347 Hob->Mps.Table = (EFI_PHYSICAL_ADDRESS)(UINTN)FindMPSPtr ();\r
348 AsciiSPrint (PrintBuffer, 256, "MPS Table=0x%x\n", (UINT32)(UINTN)Hob->Mps.Table);\r
349 PrintString (PrintBuffer);\r
350\r
351 PrepareMcfgTable (Hob);\r
352\r
353 PrepareFadtTable (Hob);\r
354\r
355 return ;\r
356}\r
357\r