118b84857507fc28b8fbfbcd434f9c48bbcaf4ac5klu/** @file
2ca162103dae16dd48474f8dfc7a8951c997c89bcklu
3b1f700a8593435e2bdc8f9b3dc21bced4774c80fhhtianCopyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
4b1f700a8593435e2bdc8f9b3dc21bced4774c80fhhtianThis program and the accompanying materials
5ca162103dae16dd48474f8dfc7a8951c997c89bckluare licensed and made available under the terms and conditions of the BSD License
6ca162103dae16dd48474f8dfc7a8951c997c89bckluwhich accompanies this distribution.  The full text of the license may be found at
7ca162103dae16dd48474f8dfc7a8951c997c89bckluhttp://opensource.org/licenses/bsd-license.php
8ca162103dae16dd48474f8dfc7a8951c997c89bcklu
9ca162103dae16dd48474f8dfc7a8951c997c89bckluTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10ca162103dae16dd48474f8dfc7a8951c997c89bckluWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11ca162103dae16dd48474f8dfc7a8951c997c89bcklu
12ca162103dae16dd48474f8dfc7a8951c997c89bckluModule Name:
13ca162103dae16dd48474f8dfc7a8951c997c89bcklu  LegacyTable.c
14ca162103dae16dd48474f8dfc7a8951c997c89bcklu
15ca162103dae16dd48474f8dfc7a8951c997c89bckluAbstract:
16ca162103dae16dd48474f8dfc7a8951c997c89bcklu
17ca162103dae16dd48474f8dfc7a8951c997c89bckluRevision History:
18ca162103dae16dd48474f8dfc7a8951c997c89bcklu
1918b84857507fc28b8fbfbcd434f9c48bbcaf4ac5klu**/
20ca162103dae16dd48474f8dfc7a8951c997c89bcklu
21ca162103dae16dd48474f8dfc7a8951c997c89bcklu#include "DxeIpl.h"
22ca162103dae16dd48474f8dfc7a8951c997c89bcklu#include "HobGeneration.h"
23df166ce57448db0df33b2ea77d1142610103677eklu#include "Debug.h"
24ca162103dae16dd48474f8dfc7a8951c997c89bcklu
25eea53ce14d49acddbb58418bb9055eed9d04648fqhuang#define MPS_PTR           SIGNATURE_32('_','M','P','_')
26eea53ce14d49acddbb58418bb9055eed9d04648fqhuang#define SMBIOS_PTR        SIGNATURE_32('_','S','M','_')
27ca162103dae16dd48474f8dfc7a8951c997c89bcklu
28ca162103dae16dd48474f8dfc7a8951c997c89bcklu#define EBDA_BASE_ADDRESS 0x40E
29ca162103dae16dd48474f8dfc7a8951c997c89bcklu
30ca162103dae16dd48474f8dfc7a8951c997c89bckluVOID *
31ca162103dae16dd48474f8dfc7a8951c997c89bckluFindAcpiRsdPtr (
32ca162103dae16dd48474f8dfc7a8951c997c89bcklu  VOID
33ca162103dae16dd48474f8dfc7a8951c997c89bcklu  )
34ca162103dae16dd48474f8dfc7a8951c997c89bcklu{
35ca162103dae16dd48474f8dfc7a8951c997c89bcklu  UINTN                           Address;
36ca162103dae16dd48474f8dfc7a8951c997c89bcklu  UINTN                           Index;
37ca162103dae16dd48474f8dfc7a8951c997c89bcklu
38ca162103dae16dd48474f8dfc7a8951c997c89bcklu  //
39ca162103dae16dd48474f8dfc7a8951c997c89bcklu  // First Seach 0x0e0000 - 0x0fffff for RSD Ptr
40ca162103dae16dd48474f8dfc7a8951c997c89bcklu  //
41ca162103dae16dd48474f8dfc7a8951c997c89bcklu  for (Address = 0xe0000; Address < 0xfffff; Address += 0x10) {
420e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu    if (*(UINT64 *)(Address) == EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE) {
43ca162103dae16dd48474f8dfc7a8951c997c89bcklu      return (VOID *)Address;
44ca162103dae16dd48474f8dfc7a8951c997c89bcklu    }
45ca162103dae16dd48474f8dfc7a8951c997c89bcklu  }
46ca162103dae16dd48474f8dfc7a8951c997c89bcklu
47ca162103dae16dd48474f8dfc7a8951c997c89bcklu  //
48ca162103dae16dd48474f8dfc7a8951c997c89bcklu  // Search EBDA
49ca162103dae16dd48474f8dfc7a8951c997c89bcklu  //
50ca162103dae16dd48474f8dfc7a8951c997c89bcklu
51ca162103dae16dd48474f8dfc7a8951c997c89bcklu  Address = (*(UINT16 *)(UINTN)(EBDA_BASE_ADDRESS)) << 4;
52ca162103dae16dd48474f8dfc7a8951c997c89bcklu  for (Index = 0; Index < 0x400 ; Index += 16) {
530e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu    if (*(UINT64 *)(Address + Index) == EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE) {
54ca162103dae16dd48474f8dfc7a8951c997c89bcklu      return (VOID *)Address;
55ca162103dae16dd48474f8dfc7a8951c997c89bcklu    }
56ca162103dae16dd48474f8dfc7a8951c997c89bcklu  }
57ca162103dae16dd48474f8dfc7a8951c997c89bcklu  return NULL;
58ca162103dae16dd48474f8dfc7a8951c997c89bcklu}
59ca162103dae16dd48474f8dfc7a8951c997c89bcklu
60ca162103dae16dd48474f8dfc7a8951c997c89bckluVOID *
61ca162103dae16dd48474f8dfc7a8951c997c89bckluFindSMBIOSPtr (
62ca162103dae16dd48474f8dfc7a8951c997c89bcklu  VOID
63ca162103dae16dd48474f8dfc7a8951c997c89bcklu  )
64ca162103dae16dd48474f8dfc7a8951c997c89bcklu{
65ca162103dae16dd48474f8dfc7a8951c997c89bcklu  UINTN                           Address;
66ca162103dae16dd48474f8dfc7a8951c997c89bcklu
67ca162103dae16dd48474f8dfc7a8951c997c89bcklu  //
68ca162103dae16dd48474f8dfc7a8951c997c89bcklu  // First Seach 0x0f0000 - 0x0fffff for SMBIOS Ptr
69ca162103dae16dd48474f8dfc7a8951c997c89bcklu  //
70ca162103dae16dd48474f8dfc7a8951c997c89bcklu  for (Address = 0xf0000; Address < 0xfffff; Address += 0x10) {
71ca162103dae16dd48474f8dfc7a8951c997c89bcklu    if (*(UINT32 *)(Address) == SMBIOS_PTR) {
72ca162103dae16dd48474f8dfc7a8951c997c89bcklu      return (VOID *)Address;
73ca162103dae16dd48474f8dfc7a8951c997c89bcklu    }
74ca162103dae16dd48474f8dfc7a8951c997c89bcklu  }
75ca162103dae16dd48474f8dfc7a8951c997c89bcklu  return NULL;
76ca162103dae16dd48474f8dfc7a8951c997c89bcklu}
77ca162103dae16dd48474f8dfc7a8951c997c89bcklu
78ca162103dae16dd48474f8dfc7a8951c997c89bckluVOID *
79ca162103dae16dd48474f8dfc7a8951c997c89bckluFindMPSPtr (
80ca162103dae16dd48474f8dfc7a8951c997c89bcklu  VOID
81ca162103dae16dd48474f8dfc7a8951c997c89bcklu  )
82ca162103dae16dd48474f8dfc7a8951c997c89bcklu{
83ca162103dae16dd48474f8dfc7a8951c997c89bcklu  UINTN                           Address;
84ca162103dae16dd48474f8dfc7a8951c997c89bcklu  UINTN                           Index;
85ca162103dae16dd48474f8dfc7a8951c997c89bcklu
86ca162103dae16dd48474f8dfc7a8951c997c89bcklu  //
87ca162103dae16dd48474f8dfc7a8951c997c89bcklu  // First Seach 0x0e0000 - 0x0fffff for MPS Ptr
88ca162103dae16dd48474f8dfc7a8951c997c89bcklu  //
89ca162103dae16dd48474f8dfc7a8951c997c89bcklu  for (Address = 0xe0000; Address < 0xfffff; Address += 0x10) {
90ca162103dae16dd48474f8dfc7a8951c997c89bcklu    if (*(UINT32 *)(Address) == MPS_PTR) {
91ca162103dae16dd48474f8dfc7a8951c997c89bcklu      return (VOID *)Address;
92ca162103dae16dd48474f8dfc7a8951c997c89bcklu    }
93ca162103dae16dd48474f8dfc7a8951c997c89bcklu  }
94ca162103dae16dd48474f8dfc7a8951c997c89bcklu
95ca162103dae16dd48474f8dfc7a8951c997c89bcklu  //
96ca162103dae16dd48474f8dfc7a8951c997c89bcklu  // Search EBDA
97ca162103dae16dd48474f8dfc7a8951c997c89bcklu  //
98ca162103dae16dd48474f8dfc7a8951c997c89bcklu
99ca162103dae16dd48474f8dfc7a8951c997c89bcklu  Address = (*(UINT16 *)(UINTN)(EBDA_BASE_ADDRESS)) << 4;
100ca162103dae16dd48474f8dfc7a8951c997c89bcklu  for (Index = 0; Index < 0x400 ; Index += 16) {
101ca162103dae16dd48474f8dfc7a8951c997c89bcklu    if (*(UINT32 *)(Address + Index) == MPS_PTR) {
102ca162103dae16dd48474f8dfc7a8951c997c89bcklu      return (VOID *)Address;
103ca162103dae16dd48474f8dfc7a8951c997c89bcklu    }
104ca162103dae16dd48474f8dfc7a8951c997c89bcklu  }
105ca162103dae16dd48474f8dfc7a8951c997c89bcklu  return NULL;
106ca162103dae16dd48474f8dfc7a8951c997c89bcklu}
107ca162103dae16dd48474f8dfc7a8951c997c89bcklu
108ca162103dae16dd48474f8dfc7a8951c997c89bcklu#pragma pack(1)
109ca162103dae16dd48474f8dfc7a8951c997c89bcklu
110ca162103dae16dd48474f8dfc7a8951c997c89bcklutypedef struct {
1110e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  EFI_ACPI_DESCRIPTION_HEADER  Header;
1120e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  UINT32                       Entry;
113ca162103dae16dd48474f8dfc7a8951c997c89bcklu} RSDT_TABLE;
114ca162103dae16dd48474f8dfc7a8951c997c89bcklu
115ca162103dae16dd48474f8dfc7a8951c997c89bcklutypedef struct {
1160e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  EFI_ACPI_DESCRIPTION_HEADER  Header;
1170e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  UINT64                       Entry;
118ca162103dae16dd48474f8dfc7a8951c997c89bcklu} XSDT_TABLE;
119ca162103dae16dd48474f8dfc7a8951c997c89bcklu
120ca162103dae16dd48474f8dfc7a8951c997c89bcklu#pragma pack()
121ca162103dae16dd48474f8dfc7a8951c997c89bcklu
122ca162103dae16dd48474f8dfc7a8951c997c89bckluVOID
123ca162103dae16dd48474f8dfc7a8951c997c89bckluScanTableInRSDT (
1240e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  RSDT_TABLE                   *Rsdt,
1250e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  UINT32                       Signature,
1260e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  EFI_ACPI_DESCRIPTION_HEADER  **FoundTable
127ca162103dae16dd48474f8dfc7a8951c997c89bcklu  )
128ca162103dae16dd48474f8dfc7a8951c997c89bcklu{
1290e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  UINTN                         Index;
1300e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  UINT32                        EntryCount;
1310e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  UINT32                        *EntryPtr;
1320e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  EFI_ACPI_DESCRIPTION_HEADER   *Table;
133ca162103dae16dd48474f8dfc7a8951c997c89bcklu
134ca162103dae16dd48474f8dfc7a8951c997c89bcklu  *FoundTable = NULL;
135ca162103dae16dd48474f8dfc7a8951c997c89bcklu
1360e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  EntryCount = (Rsdt->Header.Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof(UINT32);
137ca162103dae16dd48474f8dfc7a8951c997c89bcklu
138ca162103dae16dd48474f8dfc7a8951c997c89bcklu  EntryPtr = &Rsdt->Entry;
139ca162103dae16dd48474f8dfc7a8951c997c89bcklu  for (Index = 0; Index < EntryCount; Index ++, EntryPtr ++) {
1400e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu    Table = (EFI_ACPI_DESCRIPTION_HEADER*)((UINTN)(*EntryPtr));
141ca162103dae16dd48474f8dfc7a8951c997c89bcklu    if (Table->Signature == Signature) {
142ca162103dae16dd48474f8dfc7a8951c997c89bcklu      *FoundTable = Table;
143ca162103dae16dd48474f8dfc7a8951c997c89bcklu      break;
144ca162103dae16dd48474f8dfc7a8951c997c89bcklu    }
145ca162103dae16dd48474f8dfc7a8951c997c89bcklu  }
146ca162103dae16dd48474f8dfc7a8951c997c89bcklu
147ca162103dae16dd48474f8dfc7a8951c997c89bcklu  return;
148ca162103dae16dd48474f8dfc7a8951c997c89bcklu}
149ca162103dae16dd48474f8dfc7a8951c997c89bcklu
150ca162103dae16dd48474f8dfc7a8951c997c89bckluVOID
151ca162103dae16dd48474f8dfc7a8951c997c89bckluScanTableInXSDT (
1520e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  XSDT_TABLE                   *Xsdt,
1530e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  UINT32                       Signature,
1540e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  EFI_ACPI_DESCRIPTION_HEADER  **FoundTable
155ca162103dae16dd48474f8dfc7a8951c997c89bcklu  )
156ca162103dae16dd48474f8dfc7a8951c997c89bcklu{
1570e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  UINTN                        Index;
1580e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  UINT32                       EntryCount;
1590e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  UINT64                       EntryPtr;
1600e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  UINTN                        BasePtr;
1610e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  EFI_ACPI_DESCRIPTION_HEADER  *Table;
162ca162103dae16dd48474f8dfc7a8951c997c89bcklu
163ca162103dae16dd48474f8dfc7a8951c997c89bcklu  *FoundTable = NULL;
164ca162103dae16dd48474f8dfc7a8951c997c89bcklu
1650e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  EntryCount = (Xsdt->Header.Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof(UINT64);
166ca162103dae16dd48474f8dfc7a8951c997c89bcklu
167ca162103dae16dd48474f8dfc7a8951c997c89bcklu  BasePtr = (UINTN)(&(Xsdt->Entry));
168ca162103dae16dd48474f8dfc7a8951c997c89bcklu  for (Index = 0; Index < EntryCount; Index ++) {
169ca162103dae16dd48474f8dfc7a8951c997c89bcklu    CopyMem (&EntryPtr, (VOID *)(BasePtr + Index * sizeof(UINT64)), sizeof(UINT64));
1700e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu    Table = (EFI_ACPI_DESCRIPTION_HEADER*)((UINTN)(EntryPtr));
171ca162103dae16dd48474f8dfc7a8951c997c89bcklu    if (Table->Signature == Signature) {
172ca162103dae16dd48474f8dfc7a8951c997c89bcklu      *FoundTable = Table;
173ca162103dae16dd48474f8dfc7a8951c997c89bcklu      break;
174ca162103dae16dd48474f8dfc7a8951c997c89bcklu    }
175ca162103dae16dd48474f8dfc7a8951c997c89bcklu  }
176ca162103dae16dd48474f8dfc7a8951c997c89bcklu
177ca162103dae16dd48474f8dfc7a8951c997c89bcklu  return;
178ca162103dae16dd48474f8dfc7a8951c997c89bcklu}
179ca162103dae16dd48474f8dfc7a8951c997c89bcklu
180ca162103dae16dd48474f8dfc7a8951c997c89bckluVOID *
181ca162103dae16dd48474f8dfc7a8951c997c89bckluFindAcpiPtr (
182ca162103dae16dd48474f8dfc7a8951c997c89bcklu  IN HOB_TEMPLATE  *Hob,
183ca162103dae16dd48474f8dfc7a8951c997c89bcklu  UINT32           Signature
184ca162103dae16dd48474f8dfc7a8951c997c89bcklu  )
185ca162103dae16dd48474f8dfc7a8951c997c89bcklu{
1860e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  EFI_ACPI_DESCRIPTION_HEADER                    *AcpiTable;
1870e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER   *Rsdp;
1880e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  RSDT_TABLE                                     *Rsdt;
1890e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  XSDT_TABLE                                     *Xsdt;
190ca162103dae16dd48474f8dfc7a8951c997c89bcklu
191ca162103dae16dd48474f8dfc7a8951c997c89bcklu  AcpiTable = NULL;
192ca162103dae16dd48474f8dfc7a8951c997c89bcklu
193ca162103dae16dd48474f8dfc7a8951c997c89bcklu  //
194ca162103dae16dd48474f8dfc7a8951c997c89bcklu  // Check ACPI2.0 table
195ca162103dae16dd48474f8dfc7a8951c997c89bcklu  //
196df166ce57448db0df33b2ea77d1142610103677eklu  if ((int)Hob->Acpi20.Table != -1) {
1970e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu    Rsdp = (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)(UINTN)Hob->Acpi20.Table;
198ca162103dae16dd48474f8dfc7a8951c997c89bcklu    Rsdt = (RSDT_TABLE *)(UINTN)Rsdp->RsdtAddress;
199ca162103dae16dd48474f8dfc7a8951c997c89bcklu    Xsdt = NULL;
200ca162103dae16dd48474f8dfc7a8951c997c89bcklu    if ((Rsdp->Revision >= 2) && (Rsdp->XsdtAddress < (UINT64)(UINTN)-1)) {
201ca162103dae16dd48474f8dfc7a8951c997c89bcklu      Xsdt = (XSDT_TABLE *)(UINTN)Rsdp->XsdtAddress;
202ca162103dae16dd48474f8dfc7a8951c997c89bcklu    }
203ca162103dae16dd48474f8dfc7a8951c997c89bcklu    //
204ca162103dae16dd48474f8dfc7a8951c997c89bcklu    // Check Xsdt
205ca162103dae16dd48474f8dfc7a8951c997c89bcklu    //
206ca162103dae16dd48474f8dfc7a8951c997c89bcklu    if (Xsdt != NULL) {
207ca162103dae16dd48474f8dfc7a8951c997c89bcklu      ScanTableInXSDT (Xsdt, Signature, &AcpiTable);
208ca162103dae16dd48474f8dfc7a8951c997c89bcklu    }
209ca162103dae16dd48474f8dfc7a8951c997c89bcklu    //
210ca162103dae16dd48474f8dfc7a8951c997c89bcklu    // Check Rsdt
211ca162103dae16dd48474f8dfc7a8951c997c89bcklu    //
212ca162103dae16dd48474f8dfc7a8951c997c89bcklu    if ((AcpiTable == NULL) && (Rsdt != NULL)) {
213ca162103dae16dd48474f8dfc7a8951c997c89bcklu      ScanTableInRSDT (Rsdt, Signature, &AcpiTable);
214ca162103dae16dd48474f8dfc7a8951c997c89bcklu    }
215ca162103dae16dd48474f8dfc7a8951c997c89bcklu  }
216ca162103dae16dd48474f8dfc7a8951c997c89bcklu
217ca162103dae16dd48474f8dfc7a8951c997c89bcklu  //
218ca162103dae16dd48474f8dfc7a8951c997c89bcklu  // Check ACPI1.0 table
219ca162103dae16dd48474f8dfc7a8951c997c89bcklu  //
220df166ce57448db0df33b2ea77d1142610103677eklu  if ((AcpiTable == NULL) && ((int)Hob->Acpi.Table != -1)) {
2210e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu    Rsdp = (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)(UINTN)Hob->Acpi.Table;
222ca162103dae16dd48474f8dfc7a8951c997c89bcklu    Rsdt = (RSDT_TABLE *)(UINTN)Rsdp->RsdtAddress;
223ca162103dae16dd48474f8dfc7a8951c997c89bcklu    //
224ca162103dae16dd48474f8dfc7a8951c997c89bcklu    // Check Rsdt
225ca162103dae16dd48474f8dfc7a8951c997c89bcklu    //
226ca162103dae16dd48474f8dfc7a8951c997c89bcklu    if (Rsdt != NULL) {
227ca162103dae16dd48474f8dfc7a8951c997c89bcklu      ScanTableInRSDT (Rsdt, Signature, &AcpiTable);
228ca162103dae16dd48474f8dfc7a8951c997c89bcklu    }
229ca162103dae16dd48474f8dfc7a8951c997c89bcklu  }
230ca162103dae16dd48474f8dfc7a8951c997c89bcklu
231ca162103dae16dd48474f8dfc7a8951c997c89bcklu  return AcpiTable;
232ca162103dae16dd48474f8dfc7a8951c997c89bcklu}
233ca162103dae16dd48474f8dfc7a8951c997c89bcklu
234ca162103dae16dd48474f8dfc7a8951c997c89bcklu#pragma pack(1)
235ca162103dae16dd48474f8dfc7a8951c997c89bcklutypedef struct {
236ca162103dae16dd48474f8dfc7a8951c997c89bcklu  UINT64  BaseAddress;
237ca162103dae16dd48474f8dfc7a8951c997c89bcklu  UINT16  PciSegmentGroupNumber;
238ca162103dae16dd48474f8dfc7a8951c997c89bcklu  UINT8   StartBusNumber;
239ca162103dae16dd48474f8dfc7a8951c997c89bcklu  UINT8   EndBusNumber;
240ca162103dae16dd48474f8dfc7a8951c997c89bcklu  UINT32  Reserved;
241ca162103dae16dd48474f8dfc7a8951c997c89bcklu} MCFG_STRUCTURE;
242ca162103dae16dd48474f8dfc7a8951c997c89bcklu#pragma pack()
243ca162103dae16dd48474f8dfc7a8951c997c89bcklu
244ca162103dae16dd48474f8dfc7a8951c997c89bckluVOID
245ca162103dae16dd48474f8dfc7a8951c997c89bckluPrepareMcfgTable (
246ca162103dae16dd48474f8dfc7a8951c997c89bcklu  IN HOB_TEMPLATE  *Hob
247ca162103dae16dd48474f8dfc7a8951c997c89bcklu  )
248ca162103dae16dd48474f8dfc7a8951c997c89bcklu{
2490e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  EFI_ACPI_DESCRIPTION_HEADER  *McfgTable;
2500e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  MCFG_STRUCTURE               *Mcfg;
2510e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  UINTN                        McfgCount;
2520e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  UINTN                        Index;
253ca162103dae16dd48474f8dfc7a8951c997c89bcklu
2540e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  McfgTable = FindAcpiPtr (Hob, EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE);
255ca162103dae16dd48474f8dfc7a8951c997c89bcklu  if (McfgTable == NULL) {
256ca162103dae16dd48474f8dfc7a8951c997c89bcklu    return ;
257ca162103dae16dd48474f8dfc7a8951c997c89bcklu  }
258ca162103dae16dd48474f8dfc7a8951c997c89bcklu
2590e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  Mcfg = (MCFG_STRUCTURE *)((UINTN)McfgTable + sizeof(EFI_ACPI_DESCRIPTION_HEADER) + sizeof(UINT64));
2600e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  McfgCount = (McfgTable->Length - sizeof(EFI_ACPI_DESCRIPTION_HEADER) - sizeof(UINT64)) / sizeof(MCFG_STRUCTURE);
261ca162103dae16dd48474f8dfc7a8951c997c89bcklu
262ca162103dae16dd48474f8dfc7a8951c997c89bcklu  //
263ca162103dae16dd48474f8dfc7a8951c997c89bcklu  // Fill PciExpress info on Hob
264ca162103dae16dd48474f8dfc7a8951c997c89bcklu  // Note: Only for 1st segment
265ca162103dae16dd48474f8dfc7a8951c997c89bcklu  //
266ca162103dae16dd48474f8dfc7a8951c997c89bcklu  for (Index = 0; Index < McfgCount; Index++) {
267ca162103dae16dd48474f8dfc7a8951c997c89bcklu    if (Mcfg[Index].PciSegmentGroupNumber == 0) {
268ca162103dae16dd48474f8dfc7a8951c997c89bcklu      Hob->PciExpress.PciExpressBaseAddressInfo.PciExpressBaseAddress = Mcfg[Index].BaseAddress;
269ca162103dae16dd48474f8dfc7a8951c997c89bcklu      break;
270ca162103dae16dd48474f8dfc7a8951c997c89bcklu    }
271ca162103dae16dd48474f8dfc7a8951c997c89bcklu  }
272ca162103dae16dd48474f8dfc7a8951c997c89bcklu
273ca162103dae16dd48474f8dfc7a8951c997c89bcklu  return ;
274ca162103dae16dd48474f8dfc7a8951c997c89bcklu}
275ca162103dae16dd48474f8dfc7a8951c997c89bcklu
276ca162103dae16dd48474f8dfc7a8951c997c89bckluVOID
277ca162103dae16dd48474f8dfc7a8951c997c89bckluPrepareFadtTable (
278ca162103dae16dd48474f8dfc7a8951c997c89bcklu  IN HOB_TEMPLATE  *Hob
279ca162103dae16dd48474f8dfc7a8951c997c89bcklu  )
280ca162103dae16dd48474f8dfc7a8951c997c89bcklu{
2810e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE   *Fadt;
2820e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  EFI_ACPI_DESCRIPTION                        *AcpiDescription;
283ca162103dae16dd48474f8dfc7a8951c997c89bcklu
2840e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  Fadt = FindAcpiPtr (Hob, EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE);
285ca162103dae16dd48474f8dfc7a8951c997c89bcklu  if (Fadt == NULL) {
286ca162103dae16dd48474f8dfc7a8951c997c89bcklu    return ;
287ca162103dae16dd48474f8dfc7a8951c997c89bcklu  }
288ca162103dae16dd48474f8dfc7a8951c997c89bcklu
289ca162103dae16dd48474f8dfc7a8951c997c89bcklu  AcpiDescription = &Hob->AcpiInfo.AcpiDescription;
290ca162103dae16dd48474f8dfc7a8951c997c89bcklu  //
291ca162103dae16dd48474f8dfc7a8951c997c89bcklu  // Fill AcpiDescription according to FADT
292ca162103dae16dd48474f8dfc7a8951c997c89bcklu  // Currently, only for PM_TMR
293ca162103dae16dd48474f8dfc7a8951c997c89bcklu  //
2940e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  AcpiDescription->PM_TMR_LEN = Fadt->PmTmrLen;
295ca162103dae16dd48474f8dfc7a8951c997c89bcklu  AcpiDescription->TMR_VAL_EXT = (UINT8)((Fadt->Flags & 0x100) != 0);
2960e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu
2970e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  //
2980e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  // For fields not included in ACPI 1.0 spec, we get the value based on table length
2990e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  //
3000e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  if (Fadt->Header.Length >= OFFSET_OF (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE, XPmTmrBlk) + sizeof (Fadt->XPmTmrBlk)) {
301ca162103dae16dd48474f8dfc7a8951c997c89bcklu    CopyMem (
302ca162103dae16dd48474f8dfc7a8951c997c89bcklu      &AcpiDescription->PM_TMR_BLK,
3030e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu      &Fadt->XPmTmrBlk,
3040e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu      sizeof(EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE)
305ca162103dae16dd48474f8dfc7a8951c997c89bcklu      );
3060e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  }
3070e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu  if (Fadt->Header.Length >= OFFSET_OF (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE, ResetValue) + sizeof (Fadt->ResetValue)) {
308ca162103dae16dd48474f8dfc7a8951c997c89bcklu    CopyMem (
309ca162103dae16dd48474f8dfc7a8951c997c89bcklu      &AcpiDescription->RESET_REG,
3100e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu      &Fadt->ResetReg,
3110e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu      sizeof(EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE)
312ca162103dae16dd48474f8dfc7a8951c997c89bcklu      );
3130e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu    AcpiDescription->RESET_VALUE = Fadt->ResetValue;
314ca162103dae16dd48474f8dfc7a8951c997c89bcklu  }
3150e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu
316ca162103dae16dd48474f8dfc7a8951c997c89bcklu  if (AcpiDescription->PM_TMR_BLK.Address == 0) {
3170e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu    AcpiDescription->PM_TMR_BLK.Address          = Fadt->PmTmrBlk;
3180e047a2a83d3e4c04f73d26f3978a4efde0b2bc4niruiyu    AcpiDescription->PM_TMR_BLK.AddressSpaceId   = EFI_ACPI_3_0_SYSTEM_IO;
319ca162103dae16dd48474f8dfc7a8951c997c89bcklu  }
320ca162103dae16dd48474f8dfc7a8951c997c89bcklu
3214903c013bcdb61a487cbf72c0ad784ba3a1b18f9niruiyu  //
3224903c013bcdb61a487cbf72c0ad784ba3a1b18f9niruiyu  // It's possible that the PM_TMR_BLK.RegisterBitWidth is always 32,
3234903c013bcdb61a487cbf72c0ad784ba3a1b18f9niruiyu  //  we need to set the correct RegisterBitWidth value according to the TMR_VAL_EXT
3244903c013bcdb61a487cbf72c0ad784ba3a1b18f9niruiyu  //  A zero indicates TMR_VAL is implemented as a 24-bit value.
3254903c013bcdb61a487cbf72c0ad784ba3a1b18f9niruiyu  //  A one indicates TMR_VAL is implemented as a 32-bit value
3264903c013bcdb61a487cbf72c0ad784ba3a1b18f9niruiyu  //
3274903c013bcdb61a487cbf72c0ad784ba3a1b18f9niruiyu  AcpiDescription->PM_TMR_BLK.RegisterBitWidth = (UINT8) ((AcpiDescription->TMR_VAL_EXT == 0) ? 24 : 32);
3284903c013bcdb61a487cbf72c0ad784ba3a1b18f9niruiyu
3294903c013bcdb61a487cbf72c0ad784ba3a1b18f9niruiyu
330ca162103dae16dd48474f8dfc7a8951c997c89bcklu  return ;
331ca162103dae16dd48474f8dfc7a8951c997c89bcklu}
332ca162103dae16dd48474f8dfc7a8951c997c89bcklu
333ca162103dae16dd48474f8dfc7a8951c997c89bckluVOID
334ca162103dae16dd48474f8dfc7a8951c997c89bckluPrepareHobLegacyTable (
335ca162103dae16dd48474f8dfc7a8951c997c89bcklu  IN HOB_TEMPLATE  *Hob
336ca162103dae16dd48474f8dfc7a8951c997c89bcklu  )
337ca162103dae16dd48474f8dfc7a8951c997c89bcklu{
338df166ce57448db0df33b2ea77d1142610103677eklu  CHAR8    PrintBuffer[256];
339df166ce57448db0df33b2ea77d1142610103677eklu
340ca162103dae16dd48474f8dfc7a8951c997c89bcklu  Hob->Acpi.Table   = (EFI_PHYSICAL_ADDRESS)(UINTN)FindAcpiRsdPtr ();
341df166ce57448db0df33b2ea77d1142610103677eklu  AsciiSPrint (PrintBuffer, 256, "\nAcpiTable=0x%x ", (UINT32)(UINTN)Hob->Acpi.Table);
342df166ce57448db0df33b2ea77d1142610103677eklu  PrintString (PrintBuffer);
343ca162103dae16dd48474f8dfc7a8951c997c89bcklu  Hob->Acpi20.Table = (EFI_PHYSICAL_ADDRESS)(UINTN)FindAcpiRsdPtr ();
344ca162103dae16dd48474f8dfc7a8951c997c89bcklu  Hob->Smbios.Table = (EFI_PHYSICAL_ADDRESS)(UINTN)FindSMBIOSPtr ();
345df166ce57448db0df33b2ea77d1142610103677eklu  AsciiSPrint (PrintBuffer, 256, "SMBIOS Table=0x%x ", (UINT32)(UINTN)Hob->Smbios.Table);
346df166ce57448db0df33b2ea77d1142610103677eklu  PrintString (PrintBuffer);
347ca162103dae16dd48474f8dfc7a8951c997c89bcklu  Hob->Mps.Table    = (EFI_PHYSICAL_ADDRESS)(UINTN)FindMPSPtr ();
348df166ce57448db0df33b2ea77d1142610103677eklu  AsciiSPrint (PrintBuffer, 256, "MPS Table=0x%x\n", (UINT32)(UINTN)Hob->Mps.Table);
349df166ce57448db0df33b2ea77d1142610103677eklu  PrintString (PrintBuffer);
350ca162103dae16dd48474f8dfc7a8951c997c89bcklu
351ca162103dae16dd48474f8dfc7a8951c997c89bcklu  PrepareMcfgTable (Hob);
352ca162103dae16dd48474f8dfc7a8951c997c89bcklu
353ca162103dae16dd48474f8dfc7a8951c997c89bcklu  PrepareFadtTable (Hob);
354ca162103dae16dd48474f8dfc7a8951c997c89bcklu
355ca162103dae16dd48474f8dfc7a8951c997c89bcklu  return ;
356ca162103dae16dd48474f8dfc7a8951c997c89bcklu}
357ca162103dae16dd48474f8dfc7a8951c997c89bcklu
358