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>
26 if (!QemuFwCfgIsAvailable ()) {
37 QemuInstallAcpiMadtTable (
38 IN EFI_ACPI_TABLE_PROTOCOL
*AcpiProtocol
,
39 IN VOID
*AcpiTableBuffer
,
40 IN UINTN AcpiTableBufferSize
,
47 EFI_ACPI_DESCRIPTION_HEADER
*Hdr
;
49 EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC_STRUCTURE
*LocalApic
;
51 QemuFwCfgSelectItem (QemuFwCfgItemSmpCpuCount
);
52 Count
= (UINTN
) QemuFwCfgRead16 ();
57 // The pre-built MADT table covers the single CPU case
59 return InstallAcpiTable (
68 // We need to add additional Local APIC entries to the MADT
70 NewBufferSize
= AcpiTableBufferSize
+ ((Count
- 1) * sizeof (*LocalApic
));
71 Hdr
= (EFI_ACPI_DESCRIPTION_HEADER
*) AllocatePool (NewBufferSize
);
74 CopyMem (Hdr
, AcpiTableBuffer
, AcpiTableBufferSize
);
76 LocalApic
= (EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC_STRUCTURE
*)
77 (((UINT8
*) Hdr
) + AcpiTableBufferSize
);
80 // Add Local APIC entries for the APs to the MADT
82 for (Loop
= 1; Loop
< Count
; Loop
++) {
83 LocalApic
->Type
= EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC
;
84 LocalApic
->Length
= sizeof (*LocalApic
);
85 LocalApic
->AcpiProcessorId
= (UINT8
) Loop
;
86 LocalApic
->ApicId
= (UINT8
) Loop
;
91 Hdr
->Length
= (UINT32
) NewBufferSize
;
93 Status
= InstallAcpiTable (AcpiProtocol
, Hdr
, NewBufferSize
, TableKey
);
110 PCI_WINDOW PciWindow32
;
111 PCI_WINDOW PciWindow64
;
121 OUT FIRMWARE_DATA
*FwData
131 QemuInstallAcpiSsdtTable (
132 IN EFI_ACPI_TABLE_PROTOCOL
*AcpiProtocol
,
133 IN VOID
*AcpiTableBuffer
,
134 IN UINTN AcpiTableBufferSize
,
139 FIRMWARE_DATA
*FwData
;
141 Status
= EFI_OUT_OF_RESOURCES
;
143 FwData
= AllocateReservedPool (sizeof (*FwData
));
144 if (FwData
!= NULL
) {
148 SsdtSize
= AcpiTableBufferSize
+ 17;
149 Ssdt
= AllocatePool (SsdtSize
);
152 Status
= PopulateFwData (FwData
);
154 if (Status
== EFI_SUCCESS
) {
159 CopyMem (SsdtPtr
, AcpiTableBuffer
, AcpiTableBufferSize
);
160 SsdtPtr
+= AcpiTableBufferSize
;
163 // build "OperationRegion(FWDT, SystemMemory, 0x12345678, 0x87654321)"
165 *(SsdtPtr
++) = 0x5B; // ExtOpPrefix
166 *(SsdtPtr
++) = 0x80; // OpRegionOp
171 *(SsdtPtr
++) = 0x00; // SystemMemory
172 *(SsdtPtr
++) = 0x0C; // DWordPrefix
175 // no virtual addressing yet, take the four least significant bytes
177 CopyMem(SsdtPtr
, &FwData
, 4);
180 *(SsdtPtr
++) = 0x0C; // DWordPrefix
182 *(UINT32
*) SsdtPtr
= sizeof (*FwData
);
185 ASSERT(SsdtPtr
- Ssdt
== SsdtSize
);
186 ((EFI_ACPI_DESCRIPTION_HEADER
*) Ssdt
)->Length
= SsdtSize
;
187 Status
= InstallAcpiTable (AcpiProtocol
, Ssdt
, SsdtSize
, TableKey
);
193 if (Status
!= EFI_SUCCESS
) {
204 QemuInstallAcpiTable (
205 IN EFI_ACPI_TABLE_PROTOCOL
*AcpiProtocol
,
206 IN VOID
*AcpiTableBuffer
,
207 IN UINTN AcpiTableBufferSize
,
211 EFI_ACPI_DESCRIPTION_HEADER
*Hdr
;
212 EFI_ACPI_TABLE_INSTALL_ACPI_TABLE TableInstallFunction
;
214 Hdr
= (EFI_ACPI_DESCRIPTION_HEADER
*) AcpiTableBuffer
;
215 switch (Hdr
->Signature
) {
216 case EFI_ACPI_1_0_APIC_SIGNATURE
:
217 TableInstallFunction
= QemuInstallAcpiMadtTable
;
219 case EFI_ACPI_1_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
:
220 TableInstallFunction
= QemuInstallAcpiSsdtTable
;
223 TableInstallFunction
= InstallAcpiTable
;
226 return TableInstallFunction (