• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2 
3 Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
4 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 *
FindAcpiRsdPtr(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 *
FindSMBIOSPtr(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 *
FindMPSPtr(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
ScanTableInRSDT(RSDT_TABLE * Rsdt,UINT32 Signature,EFI_ACPI_DESCRIPTION_HEADER ** FoundTable)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
ScanTableInXSDT(XSDT_TABLE * Xsdt,UINT32 Signature,EFI_ACPI_DESCRIPTION_HEADER ** FoundTable)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 *
FindAcpiPtr(IN HOB_TEMPLATE * Hob,UINT32 Signature)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
PrepareMcfgTable(IN HOB_TEMPLATE * Hob)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
PrepareFadtTable(IN HOB_TEMPLATE * Hob)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
PrepareHobLegacyTable(IN HOB_TEMPLATE * Hob)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 
358