]>
Commit | Line | Data |
---|---|---|
cc5a6726 GD |
1 | /** @file\r |
2 | \r | |
3 | \r | |
4 | Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>\r | |
5 | \r | |
6 | SPDX-License-Identifier: BSD-2-Clause-Patent\r | |
7 | \r | |
8 | **/\r | |
9 | \r | |
10 | #include "UefiPayloadEntry.h"\r | |
11 | \r | |
cc5a6726 GD |
12 | /**\r |
13 | Find the board related info from ACPI table\r | |
14 | \r | |
15 | @param AcpiTableBase ACPI table start address in memory\r | |
16 | @param AcpiBoardInfo Pointer to the acpi board info strucutre\r | |
17 | \r | |
18 | @retval RETURN_SUCCESS Successfully find out all the required information.\r | |
19 | @retval RETURN_NOT_FOUND Failed to find the required info.\r | |
20 | \r | |
21 | **/\r | |
22 | RETURN_STATUS\r | |
23 | ParseAcpiInfo (\r | |
e5efcf8b MK |
24 | IN UINT64 AcpiTableBase,\r |
25 | OUT ACPI_BOARD_INFO *AcpiBoardInfo\r | |
cc5a6726 GD |
26 | )\r |
27 | {\r | |
e5efcf8b MK |
28 | EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp;\r |
29 | EFI_ACPI_DESCRIPTION_HEADER *Rsdt;\r | |
30 | UINT32 *Entry32;\r | |
31 | UINTN Entry32Num;\r | |
32 | EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt;\r | |
33 | EFI_ACPI_DESCRIPTION_HEADER *Xsdt;\r | |
34 | UINT64 *Entry64;\r | |
35 | UINTN Entry64Num;\r | |
36 | UINTN Idx;\r | |
37 | UINT32 *Signature;\r | |
38 | EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER *MmCfgHdr;\r | |
39 | EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE *MmCfgBase;\r | |
cc5a6726 GD |
40 | \r |
41 | Rsdp = (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)(UINTN)AcpiTableBase;\r | |
42 | DEBUG ((DEBUG_INFO, "Rsdp at 0x%p\n", Rsdp));\r | |
43 | DEBUG ((DEBUG_INFO, "Rsdt at 0x%x, Xsdt at 0x%lx\n", Rsdp->RsdtAddress, Rsdp->XsdtAddress));\r | |
44 | \r | |
45 | //\r | |
46 | // Search Rsdt First\r | |
47 | //\r | |
48 | Fadt = NULL;\r | |
49 | MmCfgHdr = NULL;\r | |
50 | Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)(Rsdp->RsdtAddress);\r | |
51 | if (Rsdt != NULL) {\r | |
e5efcf8b MK |
52 | Entry32 = (UINT32 *)(Rsdt + 1);\r |
53 | Entry32Num = (Rsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) >> 2;\r | |
cc5a6726 GD |
54 | for (Idx = 0; Idx < Entry32Num; Idx++) {\r |
55 | Signature = (UINT32 *)(UINTN)Entry32[Idx];\r | |
56 | if (*Signature == EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {\r | |
57 | Fadt = (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)Signature;\r | |
58 | DEBUG ((DEBUG_INFO, "Found Fadt in Rsdt\n"));\r | |
59 | }\r | |
60 | \r | |
61 | if (*Signature == EFI_ACPI_5_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE) {\r | |
62 | MmCfgHdr = (EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER *)Signature;\r | |
63 | DEBUG ((DEBUG_INFO, "Found MM config address in Rsdt\n"));\r | |
64 | }\r | |
65 | \r | |
66 | if ((Fadt != NULL) && (MmCfgHdr != NULL)) {\r | |
67 | goto Done;\r | |
68 | }\r | |
69 | }\r | |
70 | }\r | |
71 | \r | |
72 | //\r | |
73 | // Search Xsdt Second\r | |
74 | //\r | |
e5efcf8b | 75 | Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)(Rsdp->XsdtAddress);\r |
cc5a6726 | 76 | if (Xsdt != NULL) {\r |
e5efcf8b MK |
77 | Entry64 = (UINT64 *)(Xsdt + 1);\r |
78 | Entry64Num = (Xsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) >> 3;\r | |
cc5a6726 GD |
79 | for (Idx = 0; Idx < Entry64Num; Idx++) {\r |
80 | Signature = (UINT32 *)(UINTN)Entry64[Idx];\r | |
81 | if (*Signature == EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {\r | |
82 | Fadt = (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)Signature;\r | |
83 | DEBUG ((DEBUG_INFO, "Found Fadt in Xsdt\n"));\r | |
84 | }\r | |
85 | \r | |
86 | if (*Signature == EFI_ACPI_5_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE) {\r | |
87 | MmCfgHdr = (EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER *)Signature;\r | |
88 | DEBUG ((DEBUG_INFO, "Found MM config address in Xsdt\n"));\r | |
89 | }\r | |
90 | \r | |
91 | if ((Fadt != NULL) && (MmCfgHdr != NULL)) {\r | |
92 | goto Done;\r | |
93 | }\r | |
94 | }\r | |
95 | }\r | |
96 | \r | |
97 | if (Fadt == NULL) {\r | |
98 | return RETURN_NOT_FOUND;\r | |
99 | }\r | |
100 | \r | |
101 | Done:\r | |
102 | \r | |
103 | AcpiBoardInfo->PmCtrlRegBase = Fadt->Pm1aCntBlk;\r | |
104 | AcpiBoardInfo->PmTimerRegBase = Fadt->PmTmrBlk;\r | |
105 | AcpiBoardInfo->ResetRegAddress = Fadt->ResetReg.Address;\r | |
106 | AcpiBoardInfo->ResetValue = Fadt->ResetValue;\r | |
107 | AcpiBoardInfo->PmEvtBase = Fadt->Pm1aEvtBlk;\r | |
108 | AcpiBoardInfo->PmGpeEnBase = Fadt->Gpe0Blk + Fadt->Gpe0BlkLen / 2;\r | |
109 | \r | |
110 | if (MmCfgHdr != NULL) {\r | |
e5efcf8b | 111 | MmCfgBase = (EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE *)((UINT8 *)MmCfgHdr + sizeof (*MmCfgHdr));\r |
cc5a6726 | 112 | AcpiBoardInfo->PcieBaseAddress = MmCfgBase->BaseAddress;\r |
e5efcf8b | 113 | AcpiBoardInfo->PcieBaseSize = (MmCfgBase->EndBusNumber + 1 - MmCfgBase->StartBusNumber) * 4096 * 32 * 8;\r |
cc5a6726 GD |
114 | } else {\r |
115 | AcpiBoardInfo->PcieBaseAddress = 0;\r | |
e5efcf8b | 116 | AcpiBoardInfo->PcieBaseSize = 0;\r |
cc5a6726 | 117 | }\r |
e5efcf8b MK |
118 | \r |
119 | DEBUG ((DEBUG_INFO, "PmCtrl Reg 0x%lx\n", AcpiBoardInfo->PmCtrlRegBase));\r | |
120 | DEBUG ((DEBUG_INFO, "PmTimer Reg 0x%lx\n", AcpiBoardInfo->PmTimerRegBase));\r | |
121 | DEBUG ((DEBUG_INFO, "Reset Reg 0x%lx\n", AcpiBoardInfo->ResetRegAddress));\r | |
cc5a6726 | 122 | DEBUG ((DEBUG_INFO, "Reset Value 0x%x\n", AcpiBoardInfo->ResetValue));\r |
e5efcf8b MK |
123 | DEBUG ((DEBUG_INFO, "PmEvt Reg 0x%lx\n", AcpiBoardInfo->PmEvtBase));\r |
124 | DEBUG ((DEBUG_INFO, "PmGpeEn Reg 0x%lx\n", AcpiBoardInfo->PmGpeEnBase));\r | |
cc5a6726 GD |
125 | DEBUG ((DEBUG_INFO, "PcieBaseAddr 0x%lx\n", AcpiBoardInfo->PcieBaseAddress));\r |
126 | DEBUG ((DEBUG_INFO, "PcieBaseSize 0x%lx\n", AcpiBoardInfo->PcieBaseSize));\r | |
127 | \r | |
128 | //\r | |
129 | // Verify values for proper operation\r | |
130 | //\r | |
e5efcf8b MK |
131 | ASSERT (Fadt->Pm1aCntBlk != 0);\r |
132 | ASSERT (Fadt->PmTmrBlk != 0);\r | |
133 | ASSERT (Fadt->ResetReg.Address != 0);\r | |
134 | ASSERT (Fadt->Pm1aEvtBlk != 0);\r | |
135 | ASSERT (Fadt->Gpe0Blk != 0);\r | |
cc5a6726 GD |
136 | \r |
137 | DEBUG_CODE_BEGIN ();\r | |
e5efcf8b MK |
138 | BOOLEAN SciEnabled;\r |
139 | \r | |
140 | //\r | |
141 | // Check the consistency of SCI enabling\r | |
142 | //\r | |
cc5a6726 | 143 | \r |
e5efcf8b MK |
144 | //\r |
145 | // Get SCI_EN value\r | |
146 | //\r | |
147 | if (Fadt->Pm1CntLen == 4) {\r | |
148 | SciEnabled = (IoRead32 (Fadt->Pm1aCntBlk) & BIT0) ? TRUE : FALSE;\r | |
149 | } else {\r | |
cc5a6726 | 150 | //\r |
e5efcf8b MK |
151 | // if (Pm1CntLen == 2), use 16 bit IO read;\r |
152 | // if (Pm1CntLen != 2 && Pm1CntLen != 4), use 16 bit IO read as a fallback\r | |
cc5a6726 | 153 | //\r |
e5efcf8b MK |
154 | SciEnabled = (IoRead16 (Fadt->Pm1aCntBlk) & BIT0) ? TRUE : FALSE;\r |
155 | }\r | |
cc5a6726 | 156 | \r |
e5efcf8b MK |
157 | if (!(Fadt->Flags & EFI_ACPI_5_0_HW_REDUCED_ACPI) &&\r |
158 | (Fadt->SmiCmd == 0) &&\r | |
159 | !SciEnabled)\r | |
160 | {\r | |
cc5a6726 | 161 | //\r |
e5efcf8b MK |
162 | // The ACPI enabling status is inconsistent: SCI is not enabled but ACPI\r |
163 | // table does not provide a means to enable it through FADT->SmiCmd\r | |
cc5a6726 | 164 | //\r |
e5efcf8b MK |
165 | DEBUG ((\r |
166 | DEBUG_ERROR,\r | |
167 | "ERROR: The ACPI enabling status is inconsistent: SCI is not"\r | |
168 | " enabled but the ACPI table does not provide a means to enable it through FADT->SmiCmd."\r | |
169 | " This may cause issues in OS.\n"\r | |
170 | ));\r | |
171 | }\r | |
cc5a6726 | 172 | \r |
cc5a6726 GD |
173 | DEBUG_CODE_END ();\r |
174 | \r | |
175 | return RETURN_SUCCESS;\r | |
176 | }\r | |
177 | \r | |
cc5a6726 GD |
178 | /**\r |
179 | Build ACPI board info HOB using infomation from ACPI table\r | |
180 | \r | |
181 | @param AcpiTableBase ACPI table start address in memory\r | |
182 | \r | |
183 | @retval A pointer to ACPI board HOB ACPI_BOARD_INFO. Null if build HOB failure.\r | |
184 | **/\r | |
185 | ACPI_BOARD_INFO *\r | |
186 | BuildHobFromAcpi (\r | |
e5efcf8b | 187 | IN UINT64 AcpiTableBase\r |
cc5a6726 GD |
188 | )\r |
189 | {\r | |
e5efcf8b MK |
190 | EFI_STATUS Status;\r |
191 | ACPI_BOARD_INFO AcpiBoardInfo;\r | |
192 | ACPI_BOARD_INFO *NewAcpiBoardInfo;\r | |
cc5a6726 GD |
193 | \r |
194 | NewAcpiBoardInfo = NULL;\r | |
e5efcf8b | 195 | Status = ParseAcpiInfo (AcpiTableBase, &AcpiBoardInfo);\r |
cc5a6726 GD |
196 | ASSERT_EFI_ERROR (Status);\r |
197 | if (!EFI_ERROR (Status)) {\r | |
198 | NewAcpiBoardInfo = BuildGuidHob (&gUefiAcpiBoardInfoGuid, sizeof (ACPI_BOARD_INFO));\r | |
199 | ASSERT (NewAcpiBoardInfo != NULL);\r | |
200 | CopyMem (NewAcpiBoardInfo, &AcpiBoardInfo, sizeof (ACPI_BOARD_INFO));\r | |
201 | DEBUG ((DEBUG_INFO, "Create acpi board info guid hob\n"));\r | |
202 | }\r | |
e5efcf8b | 203 | \r |
cc5a6726 GD |
204 | return NewAcpiBoardInfo;\r |
205 | }\r |