]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiVariableThunkPlatform.c
IntelFrameworkModulePkg: Add AcpiS3SaveDxe driver
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / Acpi / AcpiS3SaveDxe / AcpiVariableThunkPlatform.c
1 /** @file
2 This is an implementation of the AcpiVariable platform field for ECP platform.
3
4 Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
5
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions
8 of the BSD License which accompanies this distribution. The
9 full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
11
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14
15 ==
16
17 typedef struct {
18 EFI_PHYSICAL_ADDRESS AcpiReservedMemoryBase; <<===
19 UINT32 AcpiReservedMemorySize; <<===
20 EFI_PHYSICAL_ADDRESS S3ReservedLowMemoryBase;
21 EFI_PHYSICAL_ADDRESS AcpiBootScriptTable;
22 EFI_PHYSICAL_ADDRESS RuntimeScriptTableBase;
23 EFI_PHYSICAL_ADDRESS AcpiFacsTable;
24 UINT64 SystemMemoryLength; <<===
25 ACPI_CPU_DATA_COMPATIBILITY AcpiCpuData;
26 EFI_PHYSICAL_ADDRESS VideoOpromAddress;
27 UINT32 VideoOpromSize;
28 EFI_PHYSICAL_ADDRESS S3DebugBufferAddress;
29 EFI_PHYSICAL_ADDRESS S3ResumeNvsEntryPoint;
30 } ACPI_VARIABLE_SET_COMPATIBILITY;
31
32 **/
33
34 #include <FrameworkDxe.h>
35 #include <Library/BaseLib.h>
36 #include <Library/BaseMemoryLib.h>
37 #include <Library/UefiBootServicesTableLib.h>
38 #include <Library/UefiRuntimeServicesTableLib.h>
39 #include <Library/HobLib.h>
40 #include <Library/PcdLib.h>
41 #include <Library/DebugLib.h>
42 #include <Protocol/FrameworkMpService.h>
43 #include <Guid/AcpiVariableCompatibility.h>
44 #include <Guid/AcpiS3Context.h>
45
46 GLOBAL_REMOVE_IF_UNREFERENCED
47 ACPI_VARIABLE_SET_COMPATIBILITY *mAcpiVariableSetCompatibility = NULL;
48
49 /**
50 Allocate EfiACPIMemoryNVS below 4G memory address.
51
52 This function allocates EfiACPIMemoryNVS below 4G memory address.
53
54 @param Size Size of memory to allocate.
55
56 @return Allocated address for output.
57
58 **/
59 VOID*
60 AllocateAcpiNvsMemoryBelow4G (
61 IN UINTN Size
62 );
63
64 /**
65 Hook point for AcpiVariableThunkPlatform for S3Ready.
66
67 @param AcpiS3Context ACPI s3 context
68 **/
69 VOID
70 S3ReadyThunkPlatform (
71 IN ACPI_S3_CONTEXT *AcpiS3Context
72 )
73 {
74 EFI_PHYSICAL_ADDRESS AcpiMemoryBase;
75 UINT32 AcpiMemorySize;
76 EFI_PEI_HOB_POINTERS Hob;
77 UINT64 MemoryLength;
78
79 DEBUG ((EFI_D_INFO, "S3ReadyThunkPlatform\n"));
80
81 //
82 // Allocate ACPI reserved memory under 4G
83 //
84 AcpiMemoryBase = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateAcpiNvsMemoryBelow4G (PcdGet32 (PcdS3AcpiReservedMemorySize));
85 ASSERT (AcpiMemoryBase != 0);
86 AcpiMemorySize = PcdGet32 (PcdS3AcpiReservedMemorySize);
87
88 //
89 // Calculate the system memory length by memory hobs
90 //
91 MemoryLength = 0x100000;
92 Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
93 ASSERT (Hob.Raw != NULL);
94 while ((Hob.Raw != NULL) && (!END_OF_HOB_LIST (Hob))) {
95 if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
96 //
97 // Skip the memory region below 1MB
98 //
99 if (Hob.ResourceDescriptor->PhysicalStart >= 0x100000) {
100 MemoryLength += Hob.ResourceDescriptor->ResourceLength;
101 }
102 }
103 Hob.Raw = GET_NEXT_HOB (Hob);
104 Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw);
105 }
106
107 mAcpiVariableSetCompatibility->AcpiReservedMemoryBase = AcpiMemoryBase;
108 mAcpiVariableSetCompatibility->AcpiReservedMemorySize = AcpiMemorySize;
109 mAcpiVariableSetCompatibility->SystemMemoryLength = MemoryLength;
110
111 DEBUG((EFI_D_INFO, "AcpiVariableThunkPlatform: AcpiMemoryBase is 0x%8x\n", mAcpiVariableSetCompatibility->AcpiReservedMemoryBase));
112 DEBUG((EFI_D_INFO, "AcpiVariableThunkPlatform: AcpiMemorySize is 0x%8x\n", mAcpiVariableSetCompatibility->AcpiReservedMemorySize));
113 DEBUG((EFI_D_INFO, "AcpiVariableThunkPlatform: SystemMemoryLength is 0x%8x\n", mAcpiVariableSetCompatibility->SystemMemoryLength));
114
115 return ;
116 }
117
118 /**
119 Hook point for AcpiVariableThunkPlatform for InstallAcpiS3Save.
120 **/
121 VOID
122 InstallAcpiS3SaveThunk (
123 VOID
124 )
125 {
126 EFI_STATUS Status;
127 FRAMEWORK_EFI_MP_SERVICES_PROTOCOL *FrameworkMpService;
128 UINTN VarSize;
129
130 Status = gBS->LocateProtocol (
131 &gFrameworkEfiMpServiceProtocolGuid,
132 NULL,
133 (VOID**) &FrameworkMpService
134 );
135 if (!EFI_ERROR (Status)) {
136 //
137 // On ECP platform, if framework CPU drivers are in use, The compatible version of ACPI variable set
138 // should be produced by CPU driver.
139 //
140 VarSize = sizeof (mAcpiVariableSetCompatibility);
141 Status = gRT->GetVariable (
142 ACPI_GLOBAL_VARIABLE,
143 &gEfiAcpiVariableCompatiblityGuid,
144 NULL,
145 &VarSize,
146 &mAcpiVariableSetCompatibility
147 );
148 ASSERT_EFI_ERROR (Status);
149 } else {
150 //
151 // Allocate/initialize the compatible version of Acpi Variable Set since Framework chipset/platform
152 // driver need this variable
153 //
154 mAcpiVariableSetCompatibility = AllocateAcpiNvsMemoryBelow4G (sizeof(ACPI_VARIABLE_SET_COMPATIBILITY));
155 Status = gRT->SetVariable (
156 ACPI_GLOBAL_VARIABLE,
157 &gEfiAcpiVariableCompatiblityGuid,
158 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
159 sizeof(mAcpiVariableSetCompatibility),
160 &mAcpiVariableSetCompatibility
161 );
162 ASSERT_EFI_ERROR (Status);
163 }
164
165 DEBUG((EFI_D_INFO, "AcpiVariableSetCompatibility is 0x%8x\n", mAcpiVariableSetCompatibility));
166 }