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