1 /** @file
2 
3   Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
4 
5 
6   This program and the accompanying materials are licensed and made available under
7 
8   the terms and conditions of the BSD License that accompanies this distribution.
9 
10   The full text of the license may be found at
11 
12   http://opensource.org/licenses/bsd-license.php.
13 
14 
15 
16   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
17 
18   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 
20 
21 
22 
23 Module Name:
24 
25   MemoryCallback.c
26 
27 Abstract:
UpdateDefaultSetupValue(IN EFI_PLATFORM_INFO_HOB * PlatformInfo)28 
29   EFI 2.0 PEIM to provide the platform support functionality on the Bridgeport.
30 
31 --*/
32 
33 #include "PlatformEarlyInit.h"
34 
35 
36 VOID
37 UpdateDefaultSetupValue (
38   IN  EFI_PLATFORM_INFO_HOB       *PlatformInfo
39   )
40 {
41 return;
42 }
43 
44 /**
45   PEI termination callback.
46 
47   @param PeiServices         General purpose services available to every PEIM.
EndOfPeiPpiNotifyCallback(IN CONST EFI_PEI_SERVICES ** PeiServices,IN EFI_PEI_NOTIFY_DESCRIPTOR * NotifyDescriptor,IN VOID * Ppi)48   @param NotifyDescriptor    Not uesed.
49   @param Ppi                 Not uesed.
50 
51   @retval EFI_SUCCESS        If the interface could be successfully
52                              installed.
53 
54 **/
55 EFI_STATUS
56 EFIAPI
57 EndOfPeiPpiNotifyCallback (
58   IN CONST EFI_PEI_SERVICES           **PeiServices,
59   IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
60   IN VOID                       *Ppi
61   )
62 {
63   EFI_STATUS                  Status;
64   UINT64                      MemoryTop;
65   UINT64                      LowUncableBase;
66   EFI_PLATFORM_INFO_HOB       *PlatformInfo;
67   UINT32                      HecBaseHigh;
68   EFI_BOOT_MODE               BootMode;
69   EFI_PEI_HOB_POINTERS        Hob;
70 
71   Status = (*PeiServices)->GetBootMode(
72                              PeiServices,
73                              &BootMode
74                              );
75 
76   ASSERT_EFI_ERROR (Status);
77 
78   //
79   // Set the some PCI and chipset range as UC
80   // And align to 1M at leaset
81   //
82   Hob.Raw = GetFirstGuidHob (&gEfiPlatformInfoGuid);
83   ASSERT (Hob.Raw != NULL);
84   PlatformInfo = GET_GUID_HOB_DATA(Hob.Raw);
85 
86   UpdateDefaultSetupValue (PlatformInfo);
87 
88   DEBUG ((EFI_D_ERROR, "Memory TOLM: %X\n", PlatformInfo->MemData.MemTolm));
89   DEBUG ((EFI_D_ERROR, "PCIE OSBASE: %lX\n", PlatformInfo->PciData.PciExpressBase));
90   DEBUG (
91     (EFI_D_ERROR,
92     "PCIE   BASE: %lX     Size : %X\n",
93     PlatformInfo->PciData.PciExpressBase,
94     PlatformInfo->PciData.PciExpressSize)
95     );
96   DEBUG (
97     (EFI_D_ERROR,
98     "PCI32  BASE: %X     Limit: %X\n",
99     PlatformInfo->PciData.PciResourceMem32Base,
100     PlatformInfo->PciData.PciResourceMem32Limit)
101     );
102   DEBUG (
103     (EFI_D_ERROR,
104     "PCI64  BASE: %lX     Limit: %lX\n",
105     PlatformInfo->PciData.PciResourceMem64Base,
106     PlatformInfo->PciData.PciResourceMem64Limit)
107     );
108   DEBUG ((EFI_D_ERROR, "UC    START: %lX     End  : %lX\n", PlatformInfo->MemData.MemMir0, PlatformInfo->MemData.MemMir1));
109 
110   LowUncableBase = PlatformInfo->MemData.MemMaxTolm;
111   LowUncableBase &= (0x0FFF00000);
112   MemoryTop = (0x100000000);
113 
114   if (BootMode != BOOT_ON_S3_RESUME) {
115     //
116     // In BIOS, HECBASE will be always below 4GB
117     //
118     HecBaseHigh = (UINT32) RShiftU64 (PlatformInfo->PciData.PciExpressBase, 28);
119     ASSERT (HecBaseHigh < 16);
120   }
121 
122   return Status;
123 }
124 
125 /**
126   Install Firmware Volume Hob's once there is main memory
127 
MemoryDiscoveredPpiNotifyCallback(IN CONST EFI_PEI_SERVICES ** PeiServices,IN EFI_PEI_NOTIFY_DESCRIPTOR * NotifyDescriptor,IN VOID * Ppi)128   @param PeiServices       General purpose services available to every PEIM.
129   @param NotifyDescriptor  Notify that this module published.
130   @param Ppi               PPI that was installed.
131 
132   @retval EFI_SUCCESS     The function completed successfully.
133 
134 **/
135 EFI_STATUS
136 EFIAPI
137 MemoryDiscoveredPpiNotifyCallback (
138   IN CONST EFI_PEI_SERVICES           **PeiServices,
139   IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
140   IN VOID                       *Ppi
141   )
142 {
143   EFI_STATUS                  Status;
144   EFI_BOOT_MODE               BootMode;
145   EFI_CPUID_REGISTER          FeatureInfo;
146   UINT8                       CpuAddressWidth;
147   UINT16                      Pm1Cnt;
148   EFI_PEI_HOB_POINTERS        Hob;
149   EFI_PLATFORM_INFO_HOB       *PlatformInfo;
150   UINT32                      RootComplexBar;
151   UINT32                      PmcBase;
152   UINT32                      IoBase;
153   UINT32                      IlbBase;
154   UINT32                      SpiBase;
155   UINT32                      MphyBase;
156 
157   //
158   // Get Platform Info HOB
159   //
160   Hob.Raw = GetFirstGuidHob (&gEfiPlatformInfoGuid);
161   ASSERT (Hob.Raw != NULL);
162   PlatformInfo = GET_GUID_HOB_DATA(Hob.Raw);
163 
164   Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode);
165 
166   //
167   // Check if user wants to turn off in PEI phase
168   //
169   if ((BootMode != BOOT_ON_S3_RESUME) && (BootMode != BOOT_ON_FLASH_UPDATE)) {
170     CheckPowerOffNow();
171   } else {
172     Pm1Cnt  = IoRead16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT);
173     Pm1Cnt &= ~B_PCH_ACPI_PM1_CNT_SLP_TYP;
174     IoWrite16 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_CNT, Pm1Cnt);
175   }
176 
177   #ifndef MINNOW2_FSP_BUILD
178   //
179   // Set PEI cache mode here
180   //
181   SetPeiCacheMode (PeiServices);
182   #endif
183 
184   //
185   //  Pulish memory tyoe info
186   //
187   PublishMemoryTypeInfo ();
188 
189   //
190   // Work done if on a S3 resume
191   //
192   if (BootMode == BOOT_ON_S3_RESUME) {
193     //
194     //Program the side band packet register to send a sideband message to Punit
195     //To indicate that DRAM has been initialized and PUNIT FW base address in memory.
196     //
197     return EFI_SUCCESS;
198   }
199 
200   RootComplexBar = MmPci32( 0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_RCBA ) & B_PCH_LPC_RCBA_BAR;
201   BuildResourceDescriptorHob (
202     EFI_RESOURCE_MEMORY_MAPPED_IO,
203     (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
204     RootComplexBar,
205     0x1000
206     );
207   DEBUG ((EFI_D_INFO, "RootComplexBar     : 0x%x\n", RootComplexBar));
208 
209   PmcBase = MmPci32( 0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_PMC_BASE ) & B_PCH_LPC_PMC_BASE_BAR;
210   BuildResourceDescriptorHob (
211     EFI_RESOURCE_MEMORY_MAPPED_IO,
212     (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
213     PmcBase,
214     0x1000
215     );
216   DEBUG ((EFI_D_INFO, "PmcBase            : 0x%x\n", PmcBase));
217 
218   IoBase = MmPci32( 0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_IO_BASE ) & B_PCH_LPC_IO_BASE_BAR;
219   BuildResourceDescriptorHob (
220     EFI_RESOURCE_MEMORY_MAPPED_IO,
221     (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
222     IoBase,
223     0x4000
224     );
225   DEBUG ((EFI_D_INFO, "IoBase             : 0x%x\n", IoBase));
226 
227   IlbBase = MmPci32( 0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_ILB_BASE ) & B_PCH_LPC_ILB_BASE_BAR;
228   BuildResourceDescriptorHob (
229     EFI_RESOURCE_MEMORY_MAPPED_IO,
230     (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
231     IlbBase,
232     0x1000
233     );
234   DEBUG ((EFI_D_INFO, "IlbBase            : 0x%x\n", IlbBase));
235 
236   SpiBase = MmPci32( 0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_SPI_BASE ) & B_PCH_LPC_SPI_BASE_BAR;
237   BuildResourceDescriptorHob (
238     EFI_RESOURCE_MEMORY_MAPPED_IO,
239     (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
240     SpiBase,
241     0x1000
242     );
243   DEBUG ((EFI_D_INFO, "SpiBase            : 0x%x\n", SpiBase));
244 
245   MphyBase = MmPci32( 0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, R_PCH_LPC_MPHY_BASE ) & B_PCH_LPC_MPHY_BASE_BAR;
246   BuildResourceDescriptorHob (
247     EFI_RESOURCE_MEMORY_MAPPED_IO,
248     (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
249     MphyBase,
250     0x100000
251     );
252   DEBUG ((EFI_D_INFO, "MphyBase           : 0x%x\n", MphyBase));
253 
254   //
255   // Local APIC
256   //
257   BuildResourceDescriptorHob (
258     EFI_RESOURCE_MEMORY_MAPPED_IO,
259     (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
260     LOCAL_APIC_ADDRESS,
261     0x1000
262   );
263   DEBUG ((EFI_D_INFO, "LOCAL_APIC_ADDRESS : 0x%x\n", LOCAL_APIC_ADDRESS));
264 
265   //
266   // IO APIC
267   //
268   BuildResourceDescriptorHob (
269     EFI_RESOURCE_MEMORY_MAPPED_IO,
270     (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
271     IO_APIC_ADDRESS,
272     0x1000
273   );
274   DEBUG ((EFI_D_INFO, "IO_APIC_ADDRESS    : 0x%x\n", IO_APIC_ADDRESS));
275 
276   //
277   // Adding the PCIE Express area to the E820 memory table as type 2 memory.
278   //
279   BuildResourceDescriptorHob (
280     EFI_RESOURCE_MEMORY_MAPPED_IO,
281     (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
282     PlatformInfo->PciData.PciExpressBase,
283     PlatformInfo->PciData.PciExpressSize
284     );
285   DEBUG ((EFI_D_INFO, "PciExpressBase     : 0x%x\n", PlatformInfo->PciData.PciExpressBase));
286 
287   //
288   // Adding the Flashpart to the E820 memory table as type 2 memory.
289   //
290   BuildResourceDescriptorHob (
291     EFI_RESOURCE_FIRMWARE_DEVICE,
292     (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
293     FixedPcdGet32 (PcdFlashAreaBaseAddress),
294     FixedPcdGet32 (PcdFlashAreaSize)
295     );
296   DEBUG ((EFI_D_INFO, "FLASH_BASE_ADDRESS : 0x%x\n", FixedPcdGet32 (PcdFlashAreaBaseAddress)));
297 
298   //
299   // Create a CPU hand-off information
300   //
301   CpuAddressWidth = 32;
302   AsmCpuid (EFI_CPUID_EXTENDED_FUNCTION, &FeatureInfo.RegEax, &FeatureInfo.RegEbx, &FeatureInfo.RegEcx, &FeatureInfo.RegEdx);
303   if (FeatureInfo.RegEax >= EFI_CPUID_VIRT_PHYS_ADDRESS_SIZE) {
304     AsmCpuid (EFI_CPUID_VIRT_PHYS_ADDRESS_SIZE, &FeatureInfo.RegEax, &FeatureInfo.RegEbx, &FeatureInfo.RegEcx, &FeatureInfo.RegEdx);
305     CpuAddressWidth = (UINT8) (FeatureInfo.RegEax & 0xFF);
306   }
307 
308   BuildCpuHob(CpuAddressWidth, 16);
309   ASSERT_EFI_ERROR (Status);
310 
311   return Status;
312 
313 }
314 
315 
316 EFI_STATUS
317 ValidateFvHeader (
318   IN EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeader
319   )
320 {
321   UINT16  *Ptr;
322   UINT16  HeaderLength;
323   UINT16  Checksum;
324 
325   //
326   // Verify the header revision, header signature, length
327   // Length of FvBlock cannot be 2**64-1
328   // HeaderLength cannot be an odd number
329   //
330   if ((FwVolHeader->Revision != EFI_FVH_REVISION) ||
331       (FwVolHeader->Signature != EFI_FVH_SIGNATURE) ||
332       (FwVolHeader->FvLength == ((UINT64) -1)) ||
333       ((FwVolHeader->HeaderLength & 0x01) != 0)
334       ) {
335     return EFI_NOT_FOUND;
336   }
337 
338   //
339   // Verify the header checksum
340   //
341   HeaderLength  = (UINT16) (FwVolHeader->HeaderLength / 2);
342   Ptr           = (UINT16 *) FwVolHeader;
343   Checksum      = 0;
344   while (HeaderLength > 0) {
345     Checksum = *Ptr++;
346     HeaderLength--;
347   }
348 
349   if (Checksum != 0) {
350     return EFI_NOT_FOUND;
351   }
352 
353   return EFI_SUCCESS;
354 }
355