4 Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "AcpiPlatform.h"
16 #include <Library/BaseMemoryLib.h>
17 #include <Library/MemoryAllocationLib.h>
18 #include <Library/QemuFwCfgLib.h>
19 #include <Library/DxeServicesTableLib.h>
27 if (!QemuFwCfgIsAvailable ()) {
38 QemuInstallAcpiMadtTable (
39 IN EFI_ACPI_TABLE_PROTOCOL
*AcpiProtocol
,
40 IN VOID
*AcpiTableBuffer
,
41 IN UINTN AcpiTableBufferSize
,
48 EFI_ACPI_DESCRIPTION_HEADER
*Hdr
;
50 EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC_STRUCTURE
*LocalApic
;
52 QemuFwCfgSelectItem (QemuFwCfgItemSmpCpuCount
);
53 Count
= (UINTN
) QemuFwCfgRead16 ();
58 // The pre-built MADT table covers the single CPU case
60 return InstallAcpiTable (
69 // We need to add additional Local APIC entries to the MADT
71 NewBufferSize
= AcpiTableBufferSize
+ ((Count
- 1) * sizeof (*LocalApic
));
72 Hdr
= (EFI_ACPI_DESCRIPTION_HEADER
*) AllocatePool (NewBufferSize
);
75 CopyMem (Hdr
, AcpiTableBuffer
, AcpiTableBufferSize
);
77 LocalApic
= (EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC_STRUCTURE
*)
78 (((UINT8
*) Hdr
) + AcpiTableBufferSize
);
81 // Add Local APIC entries for the APs to the MADT
83 for (Loop
= 1; Loop
< Count
; Loop
++) {
84 LocalApic
->Type
= EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC
;
85 LocalApic
->Length
= sizeof (*LocalApic
);
86 LocalApic
->AcpiProcessorId
= (UINT8
) Loop
;
87 LocalApic
->ApicId
= (UINT8
) Loop
;
92 Hdr
->Length
= (UINT32
) NewBufferSize
;
94 Status
= InstallAcpiTable (AcpiProtocol
, Hdr
, NewBufferSize
, TableKey
);
111 PCI_WINDOW PciWindow32
;
112 PCI_WINDOW PciWindow64
;
122 OUT FIRMWARE_DATA
*FwData
127 EFI_GCD_MEMORY_SPACE_DESCRIPTOR
*AllDesc
;
129 Status
= gDS
->GetMemorySpaceMap (&NumDesc
, &AllDesc
);
130 if (Status
== EFI_SUCCESS
) {
131 UINT64 NonMmio32MaxExclTop
;
132 UINT64 Mmio32MinBase
;
133 UINT64 Mmio32MaxExclTop
;
136 Status
= EFI_UNSUPPORTED
;
138 NonMmio32MaxExclTop
= 0;
139 Mmio32MinBase
= BASE_4GB
;
140 Mmio32MaxExclTop
= 0;
142 for (CurDesc
= 0; CurDesc
< NumDesc
; ++CurDesc
) {
143 CONST EFI_GCD_MEMORY_SPACE_DESCRIPTOR
*Desc
;
146 Desc
= &AllDesc
[CurDesc
];
147 ExclTop
= Desc
->BaseAddress
+ Desc
->Length
;
149 if (ExclTop
<= BASE_4GB
) {
150 switch (Desc
->GcdMemoryType
) {
151 case EfiGcdMemoryTypeNonExistent
:
154 case EfiGcdMemoryTypeReserved
:
155 case EfiGcdMemoryTypeSystemMemory
:
156 if (NonMmio32MaxExclTop
< ExclTop
) {
157 NonMmio32MaxExclTop
= ExclTop
;
161 case EfiGcdMemoryTypeMemoryMappedIo
:
162 if (Mmio32MinBase
> Desc
->BaseAddress
) {
163 Mmio32MinBase
= Desc
->BaseAddress
;
165 if (Mmio32MaxExclTop
< ExclTop
) {
166 Mmio32MaxExclTop
= ExclTop
;
176 if (Mmio32MinBase
< NonMmio32MaxExclTop
) {
177 Mmio32MinBase
= NonMmio32MaxExclTop
;
180 if (Mmio32MinBase
< Mmio32MaxExclTop
) {
181 FwData
->PciWindow32
.Base
= Mmio32MinBase
;
182 FwData
->PciWindow32
.End
= Mmio32MaxExclTop
- 1;
183 FwData
->PciWindow32
.Length
= Mmio32MaxExclTop
- Mmio32MinBase
;
185 FwData
->PciWindow64
.Base
= 0;
186 FwData
->PciWindow64
.End
= 0;
187 FwData
->PciWindow64
.Length
= 0;
189 Status
= EFI_SUCCESS
;
197 "ACPI PciWindow32: Base=0x%08lx End=0x%08lx Length=0x%08lx\n",
198 FwData
->PciWindow32
.Base
,
199 FwData
->PciWindow32
.End
,
200 FwData
->PciWindow32
.Length
204 "ACPI PciWindow64: Base=0x%08lx End=0x%08lx Length=0x%08lx\n",
205 FwData
->PciWindow64
.Base
,
206 FwData
->PciWindow64
.End
,
207 FwData
->PciWindow64
.Length
217 QemuInstallAcpiSsdtTable (
218 IN EFI_ACPI_TABLE_PROTOCOL
*AcpiProtocol
,
219 IN VOID
*AcpiTableBuffer
,
220 IN UINTN AcpiTableBufferSize
,
225 FIRMWARE_DATA
*FwData
;
227 Status
= EFI_OUT_OF_RESOURCES
;
229 FwData
= AllocateReservedPool (sizeof (*FwData
));
230 if (FwData
!= NULL
) {
234 SsdtSize
= AcpiTableBufferSize
+ 17;
235 Ssdt
= AllocatePool (SsdtSize
);
238 Status
= PopulateFwData (FwData
);
240 if (Status
== EFI_SUCCESS
) {
245 CopyMem (SsdtPtr
, AcpiTableBuffer
, AcpiTableBufferSize
);
246 SsdtPtr
+= AcpiTableBufferSize
;
249 // build "OperationRegion(FWDT, SystemMemory, 0x12345678, 0x87654321)"
251 *(SsdtPtr
++) = 0x5B; // ExtOpPrefix
252 *(SsdtPtr
++) = 0x80; // OpRegionOp
257 *(SsdtPtr
++) = 0x00; // SystemMemory
258 *(SsdtPtr
++) = 0x0C; // DWordPrefix
261 // no virtual addressing yet, take the four least significant bytes
263 CopyMem(SsdtPtr
, &FwData
, 4);
266 *(SsdtPtr
++) = 0x0C; // DWordPrefix
268 *(UINT32
*) SsdtPtr
= sizeof (*FwData
);
271 ASSERT(SsdtPtr
- Ssdt
== SsdtSize
);
272 ((EFI_ACPI_DESCRIPTION_HEADER
*) Ssdt
)->Length
= SsdtSize
;
273 Status
= InstallAcpiTable (AcpiProtocol
, Ssdt
, SsdtSize
, TableKey
);
279 if (Status
!= EFI_SUCCESS
) {
290 QemuInstallAcpiTable (
291 IN EFI_ACPI_TABLE_PROTOCOL
*AcpiProtocol
,
292 IN VOID
*AcpiTableBuffer
,
293 IN UINTN AcpiTableBufferSize
,
297 EFI_ACPI_DESCRIPTION_HEADER
*Hdr
;
298 EFI_ACPI_TABLE_INSTALL_ACPI_TABLE TableInstallFunction
;
300 Hdr
= (EFI_ACPI_DESCRIPTION_HEADER
*) AcpiTableBuffer
;
301 switch (Hdr
->Signature
) {
302 case EFI_ACPI_1_0_APIC_SIGNATURE
:
303 TableInstallFunction
= QemuInstallAcpiMadtTable
;
305 case EFI_ACPI_1_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
:
306 TableInstallFunction
= QemuInstallAcpiSsdtTable
;
309 TableInstallFunction
= InstallAcpiTable
;
312 return TableInstallFunction (