]> git.proxmox.com Git - mirror_edk2.git/blob - Vlv2TbltDevicePkg/PlatformPei/Platform.c
MdeModulePkg/CapsuleApp: Center bitmap at bottom of screen
[mirror_edk2.git] / Vlv2TbltDevicePkg / PlatformPei / Platform.c
1 /** @file
2
3 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
4
5 This program and the accompanying materials are licensed and made available under
6 the terms and conditions of the BSD License that accompanies this distribution.
7 The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php.
9
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.
12
13
14
15 Module Name:
16
17 **/
18
19 #include "CommonHeader.h"
20
21 #include "Platform.h"
22 #include <Library/PciCf8Lib.h>
23 #include "PlatformBaseAddresses.h"
24 #include "PchAccess.h"
25 #include <Guid/PlatformInfo.h>
26 #include "Platform.h"
27 #include "PchCommonDefinitions.h"
28 #include <Ppi/MfgMemoryTest.h>
29 #include <Guid/SetupVariable.h>
30 #include <Guid/Vlv2Variable.h>
31 #include <Ppi/fTPMPolicy.h>
32
33 //
34 // Start::Alpine Valley platform
35 //
36 enum {
37 SMBUS_READ_BYTE,
38 SMBUS_WRITE_BYTE,
39 SMBUS_READ_BLOCK,
40 SMBUS_WRITE_BLOCK
41 };
42
43 #define EC_BASE 0xE0000000
44
45 //
46 // DEVICE 0 (Memroy Controller Hub)
47 //
48 #define MC_BUS 0x00
49 #define MC_DEV 0x00
50 #define MC_FUN 0x00
51 #define MC_DEV_FUN (MC_DEV << 3)
52 #define MC_BUS_DEV_FUN ((MC_BUS << 8) + MC_DEV_FUN)
53
54 //
55 // SysCtl SMBus address and block size
56 //
57 #define AV_SC_SMBUS_ADDRESS 0x60
58 #define AV_SC_BYTE_LEN 1
59 #define AV_SC_BLOCK_LEN 4
60 #define AV_SC_SMBUS_WRCMD 1
61 #define AV_SC_SMBUS_RDCMD 0
62
63 //
64 // SysCtl registers offset
65 //
66 #define AV_SC_REG_PLATFORM_ID 24 // 0x18
67 #define AV_SC_REG_BOARD_ID 28 // 0x1C
68 #define AV_SC_REG_FAB_ID 32 // 0x20
69 #define AV_SC_REG_ECO_ID 68 // 0x44
70 #define AV_SC_REG_DDR_DAUGHTER_CARD_ID 144 // 0x90
71 #define AV_SC_REG_SODIMM_CONFIG 36
72
73 //
74 // ID values
75 //
76 #define AV_SC_PLATFORM_ID_TABLET 0
77 #define AV_SC_PLATFORM_ID_NETBOOK 2
78 #define AV_SC_PLATFORM_ID_INTERPOSER 3 // Configuration TBD
79 #define AV_SC_BOARD_ID_AV_SVP 1492
80
81 #define BUS_TRIES 3 // How many times to retry on Bus Errors
82
83 #define GTT_SIZE_1MB 1
84 #define GTT_SIZE_2MB 2
85
86 #define PciCfg16Read( PciExpressBase, Bus, Device, Function, Register ) \
87 MmioRead16(PciExpressBase + \
88 (UINTN)(Bus << 20) + \
89 (UINTN)(Device << 15) + \
90 (UINTN)(Function << 12) + \
91 (UINTN)(Register))
92 #define PciCfg16Write( PciExpressBase, Bus, Device, Function, Register, Data ) \
93 MmioWrite16(PciExpressBase + \
94 (UINTN)(Bus << 20) + \
95 (UINTN)(Device << 15) + \
96 (UINTN)(Function << 12) + \
97 (UINTN)(Register), \
98 (UINT16)Data)
99
100
101 //
102 //Memory Test Manufacturing mode
103 //
104 UINT32 DataPatternForMemoryTest[] = {
105 0x55555555, 0xAAAAAAAA, 0x55555510, 0x555555EF, 0x55555510, 0x555555EF, 0x55555510, 0x555555EF,
106 0x55555555, 0xAAAAAAAA, 0x55551055, 0x5555EF55, 0x55551055, 0x5555EF55, 0x55551055, 0x5555EF55,
107 0x55555555, 0xAAAAAAAA, 0x55105555, 0x55EF5555, 0x55105555, 0x55EF5555, 0x55105555, 0x55EF5555,
108 0x55555555, 0xAAAAAAAA, 0x10555555, 0xEF555555, 0x10555555, 0xEF555555, 0x10555555, 0xEF555555
109 };
110 #define DATA_PATTERN_ARRAY_SIZE (sizeof(DataPatternForMemoryTest) / sizeof(UINT32))
111
112 //
113 //Memory Test Manufacturing mode
114 //
115 //
116 // The global indicator, the FvFileLoader callback will modify it to TRUE after loading PEIM into memory
117 //
118 BOOLEAN ImageInMemory = FALSE;
119
120 EFI_STATUS
121 EFIAPI
122 Stall (
123 IN CONST EFI_PEI_SERVICES **PeiServices,
124 IN CONST EFI_PEI_STALL_PPI *This,
125 IN UINTN Microseconds
126 );
127
128 EFI_STATUS
129 EFIAPI
130 MfgMemoryTest (
131 IN CONST EFI_PEI_SERVICES **PeiServices,
132 IN PEI_MFG_MEMORY_TEST_PPI *This,
133 IN UINT32 BeginAddress,
134 IN UINT32 MemoryLength
135 );
136
137 static EFI_PEI_STALL_PPI mStallPpi = {
138 PEI_STALL_RESOLUTION,
139 Stall
140 };
141
142 static PEI_MFG_MEMORY_TEST_PPI mPeiMfgMemoryTestPpi = {
143 MfgMemoryTest
144 };
145
146 static EFI_PEI_PPI_DESCRIPTOR mInstallStallPpi[] = {
147 {
148 EFI_PEI_PPI_DESCRIPTOR_PPI,
149 &gEfiPeiStallPpiGuid,
150 &mStallPpi
151 },
152 {
153 EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
154 &gPeiMfgMemoryTestPpiGuid,
155 &mPeiMfgMemoryTestPpi
156 }
157 };
158
159 EFI_PEI_NOTIFY_DESCRIPTOR mMemoryDiscoveredNotifyList[1] = {
160 {
161 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
162 &gEfiPeiMemoryDiscoveredPpiGuid,
163 MemoryDiscoveredPpiNotifyCallback
164 }
165 };
166
167 EFI_STATUS
168 EFIAPI
169 InstallMonoStatusCode (
170 IN EFI_FFS_FILE_HEADER *FfsHeader,
171 IN CONST EFI_PEI_SERVICES **PeiServices
172 );
173
174
175 EFI_STATUS
176 ReadPlatformIds (
177 IN CONST EFI_PEI_SERVICES **PeiServices,
178 IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
179 );
180
181 //
182 // Start::Alpine Valley platform
183 //
184 EFI_STATUS
185 PeiSmbusExec (
186 UINT16 SmbusBase,
187 UINT8 SlvAddr,
188 UINT8 Operation,
189 UINT8 Offset,
190 UINT8 *Length,
191 UINT8 *Buffer
192 );
193
194
195 /**
196
197 Detemine Turbot board
198 @return 0: Not Turbot board
199 1: Turbot board
200
201 **/
202 UINT32
203 DetermineTurbotBoard (
204 void
205 )
206 {
207 UINTN PciD31F0RegBase = 0;
208 UINT32 GpioValue = 0;
209 UINT32 TmpVal = 0;
210 UINT32 MmioConf0 = 0;
211 UINT32 MmioPadval = 0;
212 UINT32 PConf0Offset = 0x200; //GPIO_S5_4 pad_conf0 register offset
213 UINT32 PValueOffset = 0x208; //GPIO_S5_4 pad_value register offset
214 UINT32 SSUSOffset = 0x2000;
215 UINT32 IoBase = 0;
216
217 DEBUG ((EFI_D_ERROR, "DetermineTurbotBoard() Entry\n"));
218 PciD31F0RegBase = MmPciAddress (0,
219 0,
220 PCI_DEVICE_NUMBER_PCH_LPC,
221 PCI_FUNCTION_NUMBER_PCH_LPC,
222 0
223 );
224 IoBase = MmioRead32 (PciD31F0RegBase + R_PCH_LPC_IO_BASE) & B_PCH_LPC_IO_BASE_BAR;
225
226 MmioConf0 = IoBase + SSUSOffset + PConf0Offset;
227 MmioPadval = IoBase + SSUSOffset + PValueOffset;
228 //0xFED0E200/0xFED0E208 is pad_Conf/pad_val register address of GPIO_S5_4
229 DEBUG ((EFI_D_ERROR, "MmioConf0[0x%x], MmioPadval[0x%x]\n", MmioConf0, MmioPadval));
230
231 MmioWrite32 (MmioConf0, 0x2003CC00);
232
233 TmpVal = MmioRead32 (MmioPadval);
234 TmpVal &= ~0x6; //Clear bit 1:2
235 TmpVal |= 0x2; // Set the pin as GPI
236 MmioWrite32 (MmioPadval, TmpVal);
237
238 GpioValue = MmioRead32 (MmioPadval);
239
240 DEBUG ((EFI_D_ERROR, "Gpio_S5_4 value is 0x%x\n", GpioValue));
241 return (GpioValue & 0x1);
242 }
243
244
245
246 EFI_STATUS
247 FtpmPolicyInit (
248 IN CONST EFI_PEI_SERVICES **PeiServices,
249 IN SYSTEM_CONFIGURATION *pSystemConfiguration
250 )
251 {
252 EFI_STATUS Status;
253 EFI_PEI_PPI_DESCRIPTOR *mFtpmPolicyPpiDesc;
254 SEC_FTPM_POLICY_PPI *mFtpmPolicyPpi;
255
256
257 DEBUG((EFI_D_INFO, "FtpmPolicyInit Entry \n"));
258
259 if (NULL == PeiServices || NULL == pSystemConfiguration) {
260 DEBUG((EFI_D_ERROR, "Input error. \n"));
261 return EFI_INVALID_PARAMETER;
262 }
263
264 Status = (*PeiServices)->AllocatePool(
265 PeiServices,
266 sizeof (EFI_PEI_PPI_DESCRIPTOR),
267 (void **)&mFtpmPolicyPpiDesc
268 );
269 ASSERT_EFI_ERROR (Status);
270
271 Status = (*PeiServices)->AllocatePool(
272 PeiServices,
273 sizeof (SEC_FTPM_POLICY_PPI),
274 (void **)&mFtpmPolicyPpi
275 );
276 ASSERT_EFI_ERROR (Status);
277
278 //
279 // Initialize PPI
280 //
281 (*PeiServices)->SetMem ((VOID *)mFtpmPolicyPpi, sizeof (SEC_FTPM_POLICY_PPI), 0);
282 mFtpmPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
283 mFtpmPolicyPpiDesc->Guid = &gSeCfTPMPolicyPpiGuid;
284 mFtpmPolicyPpiDesc->Ppi = mFtpmPolicyPpi;
285
286
287 DEBUG((EFI_D_INFO, "pSystemConfiguration->fTPM = 0x%x \n", pSystemConfiguration->fTPM));
288 if(pSystemConfiguration->fTPM == 1) {
289 mFtpmPolicyPpi->fTPMEnable = TRUE;
290 } else {
291 mFtpmPolicyPpi->fTPMEnable = FALSE;
292 }
293
294 Status = (*PeiServices)->InstallPpi(
295 PeiServices,
296 mFtpmPolicyPpiDesc
297 );
298 ASSERT_EFI_ERROR (Status);
299
300 DEBUG((EFI_D_INFO, "FtpmPolicyInit done \n"));
301
302 return EFI_SUCCESS;
303 }
304
305
306 /**
307 This routine attempts to acquire the SMBus
308
309 @retval FAILURE as failed
310 @retval SUCCESS as passed
311
312 **/
313 EFI_STATUS
314 AcquireBus (
315 UINT16 SmbusBase
316 )
317 {
318 UINT8 StsReg;
319
320 StsReg = 0;
321 StsReg = (UINT8)IoRead8(SmbusBase + R_PCH_SMBUS_HSTS);
322 if (StsReg & B_PCH_SMBUS_IUS) {
323 return EFI_DEVICE_ERROR;
324 } else if (StsReg & B_PCH_SMBUS_HBSY) {
325 //
326 // Clear Status Register and exit
327 //
328 // Wait for HSTS.HBSY to be clear
329 //
330 do { StsReg = (UINT8) IoRead8(SmbusBase+R_PCH_SMBUS_HSTS); } while ((StsReg & B_PCH_SMBUS_HBSY) != 0);
331
332 //
333 // Clear all status bits
334 //
335 IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, 0xFE);
336 return EFI_SUCCESS;
337 } else {
338 //
339 // Clear out any odd status information (Will Not Clear In Use)
340 //
341 IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, StsReg);
342 return EFI_SUCCESS;
343 }
344 }
345 //
346 // End::Alpine Valley platform
347 //
348
349 /**
350 This function checks the memory range in PEI.
351
352 @param PeiServices Pointer to PEI Services.
353 @param This Pei memory test PPI pointer.
354 @param BeginAddress Beginning of the memory address to be checked.
355 @param MemoryLength Bytes of memory range to be checked.
356 @param Operation Type of memory check operation to be performed.
357 @param ErrorAddress Return the address of the error memory address.
358
359 @retval EFI_SUCCESS The operation completed successfully.
360 @retval EFI_DEVICE_ERROR Memory test failed. It's not safe to use this range of memory.
361
362 **/
363 EFI_STATUS
364 EFIAPI
365 MfgMemoryTest (
366 IN CONST EFI_PEI_SERVICES **PeiServices,
367 IN PEI_MFG_MEMORY_TEST_PPI *This,
368 IN UINT32 BeginAddress,
369 IN UINT32 MemoryLength
370 )
371 {
372 UINT32 i;
373 UINT32 memAddr;
374 UINT32 readData;
375 UINT32 xorData;
376 UINT32 TestFlag = 0;
377 memAddr = BeginAddress;
378
379 //
380 //Output Message for MFG
381 //
382 DEBUG ((EFI_D_ERROR, "MFGMODE SET\n"));
383
384 //
385 //Writting the pattern in defined location.
386 //
387 while (memAddr < (BeginAddress+MemoryLength)) {
388 for (i = 0; i < DATA_PATTERN_ARRAY_SIZE; i++) {
389 if (memAddr > (BeginAddress+MemoryLength -4)) {
390 memAddr = memAddr + 4;
391 break;
392 }
393 *((volatile UINT32*) memAddr) = DataPatternForMemoryTest[i];
394 memAddr = memAddr + 4;
395 }
396 }
397
398 //
399 //Verify the pattern.
400 //
401 memAddr = BeginAddress;
402 while (memAddr < (BeginAddress+MemoryLength)) {
403 for (i = 0; i < DATA_PATTERN_ARRAY_SIZE; i++) {
404 if (memAddr > (BeginAddress+MemoryLength -4)) {
405 memAddr = memAddr + 4;
406 break;
407 }
408 readData = *((volatile UINT32*) memAddr);
409 xorData = readData ^ DataPatternForMemoryTest[i];
410
411 //
412 // If xorData is nonzero, this particular memAddr has a failure.
413 //
414 if (xorData != 0x00000000) {
415 DEBUG ((EFI_D_ERROR, "Expected value....: %x\n", DataPatternForMemoryTest[i]));
416 DEBUG ((EFI_D_ERROR, "ReadData value....: %x\n", readData));
417 DEBUG ((EFI_D_ERROR, "Pattern failure at....: %x\n", memAddr));
418 TestFlag = 1;
419 }
420 memAddr = memAddr + 4;
421 }
422 }
423 if (TestFlag) {
424 return EFI_DEVICE_ERROR;
425 }
426
427 //
428 //Output Message for MFG
429 //
430 DEBUG ((EFI_D_ERROR, "MFGMODE MEMORY TEST PASSED\n"));
431 return EFI_SUCCESS;
432 }
433
434 BOOLEAN
435 IsRtcUipAlwaysSet (
436 IN CONST EFI_PEI_SERVICES **PeiServices
437 )
438 {
439
440 EFI_PEI_STALL_PPI *StallPpi;
441 UINTN Count;
442
443 (**PeiServices).LocatePpi (PeiServices, &gEfiPeiStallPpiGuid, 0, NULL, (void **)&StallPpi);
444
445 for (Count = 0; Count < 500; Count++) { // Maximum waiting approximates to 1.5 seconds (= 3 msec * 500)
446 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERA);
447 if ((IoRead8 (R_PCH_RTC_TARGET2) & B_PCH_RTC_REGISTERA_UIP) == 0) {
448 return FALSE;
449 }
450
451 StallPpi->Stall (PeiServices, StallPpi, 3000);
452 }
453
454 return TRUE;
455 }
456
457 EFI_STATUS
458 RtcPowerFailureHandler (
459 IN CONST EFI_PEI_SERVICES **PeiServices
460 )
461 {
462
463 UINT16 DataUint16;
464 UINT8 DataUint8;
465 BOOLEAN RtcUipIsAlwaysSet;
466 DataUint16 = MmioRead16 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1);
467 RtcUipIsAlwaysSet = IsRtcUipAlwaysSet (PeiServices);
468 if ((DataUint16 & B_PCH_PMC_GEN_PMCON_RTC_PWR_STS) || (RtcUipIsAlwaysSet)) {
469 //
470 // Execute the sequence below. This will ensure that the RTC state machine has been initialized.
471 //
472 // Step 1.
473 // BIOS clears this bit by writing a '0' to it.
474 //
475 if (DataUint16 & B_PCH_PMC_GEN_PMCON_RTC_PWR_STS) {
476 //
477 // Set to invalid date in order to reset the time to
478 // BIOS build time later in the boot (SBRUN.c file).
479 //
480 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_YEAR);
481 IoWrite8 (R_PCH_RTC_TARGET2, 0x0FF);
482 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_MONTH);
483 IoWrite8 (R_PCH_RTC_TARGET2, 0x0FF);
484 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_DAYOFMONTH);
485 IoWrite8 (R_PCH_RTC_TARGET2, 0x0FF);
486 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_DAYOFWEEK);
487 IoWrite8 (R_PCH_RTC_TARGET2, 0x0FF);
488
489 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_SECONDSALARM);
490 IoWrite8 (R_PCH_RTC_TARGET2, 0x00);
491 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_MINUTESALARM);
492 IoWrite8 (R_PCH_RTC_TARGET2, 0x00);
493 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_HOURSALARM);
494 IoWrite8 (R_PCH_RTC_TARGET2, 0x00);
495 }
496
497 //
498 // Step 2.
499 // Set RTC Register 0Ah[6:4] to '110' or '111'.
500 //
501 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERA);
502 IoWrite8 (R_PCH_RTC_TARGET2, (V_PCH_RTC_REGISTERA_DV_DIV_RST1 | V_PCH_RTC_REGISTERA_RS_976P5US));
503
504 //
505 // Step 3.
506 // Set RTC Register 0Bh[7].
507 //
508 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERB);
509 DataUint8 = (IoRead8 (R_PCH_RTC_TARGET2) | B_PCH_RTC_REGISTERB_SET);
510 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERB);
511 IoWrite8 (R_PCH_RTC_TARGET2, DataUint8);
512
513 //
514 // Step 4.
515 // Set RTC Register 0Ah[6:4] to '010'.
516 //
517 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERA);
518 IoWrite8 (R_PCH_RTC_TARGET2, (V_PCH_RTC_REGISTERA_DV_NORM_OP | V_PCH_RTC_REGISTERA_RS_976P5US));
519
520 //
521 // Step 5.
522 // Clear RTC Register 0Bh[7].
523 //
524 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERB);
525 DataUint8 = (IoRead8 (R_PCH_RTC_TARGET2) & (UINT8)~B_PCH_RTC_REGISTERB_SET);
526 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERB);
527 IoWrite8 (R_PCH_RTC_TARGET2, DataUint8);
528 }
529
530 return EFI_SUCCESS;
531 }
532
533
534 VOID
535 PchBaseInit (
536 VOID
537 )
538 {
539 //
540 // Program ACPI Power Management I/O Space Base Address
541 //
542 MmioWrite16 (
543 MmPciAddress (0,
544 DEFAULT_PCI_BUS_NUMBER_PCH,
545 PCI_DEVICE_NUMBER_PCH_LPC,
546 PCI_FUNCTION_NUMBER_PCH_LPC,
547 R_PCH_LPC_ACPI_BASE
548 ),
549 (UINT16)((ACPI_BASE_ADDRESS & B_PCH_LPC_ACPI_BASE_BAR) | B_PCH_LPC_ACPI_BASE_EN)
550 );
551
552 //
553 // Program GPIO Base Address
554 //
555 MmioWrite16 (
556 MmPciAddress (0,
557 DEFAULT_PCI_BUS_NUMBER_PCH,
558 PCI_DEVICE_NUMBER_PCH_LPC,
559 PCI_FUNCTION_NUMBER_PCH_LPC,
560 R_PCH_LPC_GPIO_BASE
561 ),
562 (UINT16)((GPIO_BASE_ADDRESS & B_PCH_LPC_GPIO_BASE_BAR) | B_PCH_LPC_GPIO_BASE_EN)
563 );
564
565 //
566 // Set PMC Base Address
567 //
568 MmioWrite32 (
569 MmPciAddress (0,
570 DEFAULT_PCI_BUS_NUMBER_PCH,
571 PCI_DEVICE_NUMBER_PCH_LPC,
572 PCI_FUNCTION_NUMBER_PCH_LPC,
573 R_PCH_LPC_PMC_BASE
574 ),
575 (UINT32)((PMC_BASE_ADDRESS & B_PCH_LPC_PMC_BASE_BAR) | B_PCH_LPC_PMC_BASE_EN)
576 );
577
578 //
579 // Set IO Base Address
580 //
581 MmioWrite32 (
582 MmPciAddress (0,
583 DEFAULT_PCI_BUS_NUMBER_PCH,
584 PCI_DEVICE_NUMBER_PCH_LPC,
585 PCI_FUNCTION_NUMBER_PCH_LPC,
586 R_PCH_LPC_IO_BASE
587 ),
588 (UINT32)((IO_BASE_ADDRESS & B_PCH_LPC_IO_BASE_BAR) | B_PCH_LPC_IO_BASE_EN)
589 );
590
591 //
592 // Set ILB Base Address
593 //
594 MmioWrite32 (
595 MmPciAddress (0,
596 DEFAULT_PCI_BUS_NUMBER_PCH,
597 PCI_DEVICE_NUMBER_PCH_LPC,
598 PCI_FUNCTION_NUMBER_PCH_LPC,
599 R_PCH_LPC_ILB_BASE
600 ),
601 (UINT32)((ILB_BASE_ADDRESS & B_PCH_LPC_ILB_BASE_BAR) | B_PCH_LPC_ILB_BASE_EN)
602 );
603
604 //
605 // Set PUnit Base Address
606 //
607 MmioWrite32 (
608 MmPciAddress (0,
609 DEFAULT_PCI_BUS_NUMBER_PCH,
610 PCI_DEVICE_NUMBER_PCH_LPC,
611 PCI_FUNCTION_NUMBER_PCH_LPC,
612 R_PCH_LPC_PUNIT_BASE
613 ),
614 (UINT32)((PUNIT_BASE_ADDRESS & B_PCH_LPC_PUNIT_BASE_BAR) | B_PCH_LPC_PUNIT_BASE_EN)
615 );
616
617 //
618 // Set SPI Base Address
619 //
620 MmioWrite32 (
621 MmPciAddress (0,
622 DEFAULT_PCI_BUS_NUMBER_PCH,
623 PCI_DEVICE_NUMBER_PCH_LPC,
624 PCI_FUNCTION_NUMBER_PCH_LPC,
625 R_PCH_LPC_SPI_BASE
626 ),
627 (UINT32)((SPI_BASE_ADDRESS & B_PCH_LPC_SPI_BASE_BAR) | B_PCH_LPC_SPI_BASE_EN)
628 );
629
630 //
631 // Set Root Complex Base Address
632 //
633 MmioWrite32 (
634 MmPciAddress (0,
635 DEFAULT_PCI_BUS_NUMBER_PCH,
636 PCI_DEVICE_NUMBER_PCH_LPC,
637 PCI_FUNCTION_NUMBER_PCH_LPC,
638 R_PCH_LPC_RCBA
639 ),
640 (UINT32)((RCBA_BASE_ADDRESS & B_PCH_LPC_RCBA_BAR) | B_PCH_LPC_RCBA_EN)
641 );
642
643 //
644 // Set MPHY Base Address
645 //
646 MmioWrite32 (
647 MmPciAddress (0,
648 DEFAULT_PCI_BUS_NUMBER_PCH,
649 PCI_DEVICE_NUMBER_PCH_LPC,
650 PCI_FUNCTION_NUMBER_PCH_LPC,
651 R_PCH_LPC_MPHY_BASE
652 ),
653 (UINT32)((MPHY_BASE_ADDRESS & B_PCH_LPC_MPHY_BASE_BAR) | B_PCH_LPC_MPHY_BASE_EN)
654 );
655 MmioWrite16 (
656 MmPciAddress (0,
657 DEFAULT_PCI_BUS_NUMBER_PCH,
658 PCI_DEVICE_NUMBER_PCH_SMBUS,
659 PCI_FUNCTION_NUMBER_PCH_SMBUS,
660 R_PCH_SMBUS_BASE
661 ),
662 (UINT16)(SMBUS_BASE_ADDRESS & B_PCH_SMBUS_BASE_BAR)
663 );
664
665 MmioOr8 (
666 MmPciAddress (0,
667 DEFAULT_PCI_BUS_NUMBER_PCH,
668 PCI_DEVICE_NUMBER_PCH_SMBUS,
669 PCI_FUNCTION_NUMBER_PCH_SMBUS,
670 R_PCH_SMBUS_PCICMD
671 ),
672 B_PCH_SMBUS_PCICMD_IOSE
673 );
674
675 }
676
677 /**
678 This is the entrypoint of PEIM
679
680 @param FileHandle Handle of the file being invoked.
681 @param PeiServices Describes the list of possible PEI Services.
682
683 @retval EFI_SUCCESS if it completed successfully.
684 **/
685 EFI_STATUS
686 EFIAPI
687 PeiInitPlatform (
688 IN EFI_PEI_FILE_HANDLE FileHandle,
689 IN CONST EFI_PEI_SERVICES **PeiServices
690 )
691 {
692 UINTN SmbusRegBase;
693 EFI_PLATFORM_INFO_HOB PlatformInfo;
694 EFI_STATUS Status= EFI_SUCCESS;
695 EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable = NULL;
696 UINTN VariableSize;
697 SYSTEM_CONFIGURATION SystemConfiguration;
698 UINT32 GGC = 0;
699
700 EFI_PEI_PPI_DESCRIPTOR *mVlvMmioPolicyPpiDesc;
701 VLV_MMIO_POLICY_PPI *mVlvMmioPolicyPpi;
702
703 ZeroMem (&PlatformInfo, sizeof(PlatformInfo));
704
705 Status = InstallMonoStatusCode(FileHandle, PeiServices);
706 ASSERT_EFI_ERROR (Status);
707
708
709 //
710 // Initialize Stall PPIs
711 //
712 Status = (*PeiServices)->InstallPpi (PeiServices, &mInstallStallPpi[0]);
713 ASSERT_EFI_ERROR (Status);
714
715 Status = (*PeiServices)->NotifyPpi (PeiServices, &mMemoryDiscoveredNotifyList[0]);
716 ASSERT_EFI_ERROR (Status);
717 SmbusRegBase = PchPciDeviceMmBase (
718 DEFAULT_PCI_BUS_NUMBER_PCH,
719 PCI_DEVICE_NUMBER_PCH_SMBUS,
720 PCI_FUNCTION_NUMBER_PCH_SMBUS
721 );
722 //
723 // Since PEI has no PCI enumerator, set the BAR & I/O space enable ourselves
724 //
725 MmioAndThenOr32 (SmbusRegBase + R_PCH_SMBUS_BASE, B_PCH_SMBUS_BASE_BAR, SMBUS_BASE_ADDRESS);
726
727 MmioOr8 (SmbusRegBase + R_PCH_SMBUS_PCICMD, B_PCH_SMBUS_PCICMD_IOSE);
728
729 PchBaseInit();
730
731 //
732 //Todo: confirm if we need program 8254
733 //
734 // Setting 8254
735 // Program timer 1 as refresh timer
736 //
737 IoWrite8 (0x43, 0x54);
738 IoWrite8 (0x41, 0x12);
739
740 //
741 // RTC power failure handling
742 //
743 RtcPowerFailureHandler (PeiServices);
744
745
746 PchMmPci32( 0, 0, 2, 0, 0x50) = 0x210;
747
748 VariableSize = sizeof (SYSTEM_CONFIGURATION);
749 ZeroMem (&SystemConfiguration, VariableSize);
750
751 //
752 // Obtain variable services
753 //
754 Status = (*PeiServices)->LocatePpi(
755 PeiServices,
756 &gEfiPeiReadOnlyVariable2PpiGuid,
757 0,
758 NULL,
759 (void **)&Variable
760 );
761 ASSERT_EFI_ERROR(Status);
762 Status = Variable->GetVariable (
763 Variable,
764 L"Setup",
765 &gEfiSetupVariableGuid,
766 NULL,
767 &VariableSize,
768 &SystemConfiguration
769 );
770 if (EFI_ERROR (Status) || VariableSize != sizeof(SYSTEM_CONFIGURATION)) {
771 //The setup variable is corrupted
772 VariableSize = sizeof(SYSTEM_CONFIGURATION);
773 Status = Variable->GetVariable(
774 Variable,
775 L"SetupRecovery",
776 &gEfiSetupVariableGuid,
777 NULL,
778 &VariableSize,
779 &SystemConfiguration
780 );
781 ASSERT_EFI_ERROR (Status);
782 }
783
784 if (EFI_ERROR (Status)) {
785 GGC = ((2 << 3) | 0x200);
786 PciCfg16Write(EC_BASE, 0, 2, 0, 0x50, GGC);
787 GGC = PciCfg16Read(EC_BASE, 0, 2, 0, 0x50);
788 DEBUG((EFI_D_INFO , "GGC: 0x%08x GMSsize:0x%08x\n", GGC, (GGC & (BIT7|BIT6|BIT5|BIT4|BIT3))>>3));
789 } else {
790 if (SystemConfiguration.Igd == 1 && SystemConfiguration.PrimaryVideoAdaptor != 2) {
791 GGC = (SystemConfiguration.IgdDvmt50PreAlloc << 3) |
792 (SystemConfiguration.GTTSize == GTT_SIZE_1MB ? 0x100: 0x200);
793 PciCfg16Write(EC_BASE, 0, 2, 0, 0x50, GGC);
794 GGC = PciCfg16Read(EC_BASE, 0, 2, 0, 0x50);
795 DEBUG((EFI_D_INFO , "GGC: 0x%08x GMSsize:0x%08x\n", GGC, (GGC & (BIT7|BIT6|BIT5|BIT4|BIT3))>>3));
796 }
797 }
798
799 //
800 // Initialize PlatformInfo HOB
801 //
802 Status = ReadPlatformIds(PeiServices, &PlatformInfo);
803 ASSERT_EFI_ERROR (Status);
804
805 //
806 // 0 -> Disable , 1 -> Enable
807 //
808 if(SystemConfiguration.CfioPnpSettings == 1) {
809 DEBUG((EFI_D_INFO, "CheckCfioPnpSettings: CFIO Pnp Settings Enabled\n"));
810 PlatformInfo.CfioEnabled = 1;
811 } else {
812 DEBUG((EFI_D_INFO, "CheckCfioPnpSettings: CFIO Pnp Settings Disabled\n"));
813 PlatformInfo.CfioEnabled = 0;
814 }
815
816 //
817 // Build HOB for PlatformInfo
818 //
819 BuildGuidDataHob (
820 &gEfiPlatformInfoGuid,
821 &PlatformInfo,
822 sizeof (EFI_PLATFORM_INFO_HOB)
823 );
824
825
826 #ifdef FTPM_ENABLE
827 Status = FtpmPolicyInit(PeiServices, &SystemConfiguration);
828 if (EFI_ERROR (Status)) {
829 DEBUG((EFI_D_ERROR, "fTPM init failed.\n"));
830 }
831 #endif
832
833
834 //
835 // Set the new boot mode for MRC
836 //
837 #ifdef NOCS_S3_SUPPORT
838 Status = UpdateBootMode (PeiServices);
839 ASSERT_EFI_ERROR (Status);
840 #endif
841
842 DEBUG((EFI_D_INFO, "Setup MMIO size ... \n\n"));
843
844 //
845 // Setup MMIO size
846 //
847 Status = (*PeiServices)->AllocatePool(
848 PeiServices,
849 sizeof (EFI_PEI_PPI_DESCRIPTOR),
850 (void **)&mVlvMmioPolicyPpiDesc
851 );
852 ASSERT_EFI_ERROR (Status);
853 Status = (*PeiServices)->AllocatePool(
854 PeiServices,
855 sizeof (VLV_MMIO_POLICY_PPI),
856 (void **)&mVlvMmioPolicyPpi
857 );
858 ASSERT_EFI_ERROR (Status);
859 (*PeiServices)->SetMem (
860 (VOID *)mVlvMmioPolicyPpi,
861 sizeof (VLV_MMIO_POLICY_PPI),
862 0
863 );
864 mVlvMmioPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
865 mVlvMmioPolicyPpiDesc->Guid = &gVlvMmioPolicyPpiGuid;
866 mVlvMmioPolicyPpiDesc->Ppi = mVlvMmioPolicyPpi;
867 switch (SystemConfiguration.MmioSize) {
868 case 0: // 768MB
869 mVlvMmioPolicyPpi->MmioSize = 0x300;
870 break;
871 case 1: // 1GB
872 mVlvMmioPolicyPpi->MmioSize = 0x400;
873 break;
874 case 2: // 1.25GB
875 mVlvMmioPolicyPpi->MmioSize = 0x500;
876 break;
877 case 3: // 1.5GB
878 mVlvMmioPolicyPpi->MmioSize = 0x600;
879 break;
880 case 4: // 2GB
881 mVlvMmioPolicyPpi->MmioSize = 0x800;
882 break;
883 default:
884 mVlvMmioPolicyPpi->MmioSize = 0x800;
885 break;
886 }
887 Status = (*PeiServices)->InstallPpi(
888 PeiServices,
889 mVlvMmioPolicyPpiDesc
890 );
891 ASSERT_EFI_ERROR (Status);
892
893 return Status;
894 }
895
896 EFI_STATUS
897 ReadPlatformIds (
898 IN CONST EFI_PEI_SERVICES **PeiServices,
899 IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
900 )
901 {
902 {
903 EFI_STATUS Status = EFI_SUCCESS;
904 UINT8 FabId = 0;
905 UINTN DataSize;
906 EFI_PLATFORM_INFO_HOB TmpHob;
907 EFI_PEI_READ_ONLY_VARIABLE2_PPI *PeiVar;
908 UINT32 CompatibleBoard = 0;
909
910 Status = (**PeiServices).LocatePpi (
911 PeiServices,
912 &gEfiPeiReadOnlyVariable2PpiGuid,
913 0,
914 NULL,
915 (void **)&PeiVar
916 );
917 ASSERT_EFI_ERROR (Status);
918
919 DataSize = sizeof (EFI_PLATFORM_INFO_HOB);
920 Status = PeiVar->GetVariable (
921 PeiVar,
922 L"PlatformInfo",
923 &gEfiVlv2VariableGuid,
924 NULL,
925 &DataSize,
926 &TmpHob
927 );
928
929 if (Status == EFI_SUCCESS) {
930 PlatformInfoHob->BoardId = TmpHob.BoardId;
931 PlatformInfoHob->MemCfgID = TmpHob.MemCfgID;
932 PlatformInfoHob->BoardRev = TmpHob.BoardRev;
933 PlatformInfoHob->PlatformFlavor = TmpHob.PlatformFlavor;
934 return Status;
935 }
936
937 CompatibleBoard = DetermineTurbotBoard();
938 if (1 == CompatibleBoard) {
939 PlatformInfoHob->BoardId = BOARD_ID_MINNOW2_TURBOT;
940 DEBUG ((EFI_D_INFO, "I'm MinnowBoard Turbot!\n"));
941 } else {
942 PlatformInfoHob->BoardId = BOARD_ID_MINNOW2;
943 DEBUG ((EFI_D_INFO, "I'm MinnowBoard Max!\n"));
944 }
945
946
947 PlatformInfoHob->MemCfgID = 0;
948 PlatformInfoHob->BoardRev = FabId + 1; // FabId = 0 means FAB1 (BoardRev = 1), FabId = 1 means FAB2 (BoardRev = 2)...
949 PlatformInfoHob->PlatformFlavor = FlavorMobile;
950 }
951
952 return EFI_SUCCESS;
953 }
954
955 //
956 // Start::Alpine Valley platform
957 //
958 /**
959 This routine reads SysCtl registers
960
961 @param SmbusBase SMBUS Base Address
962 @param SlvAddr Targeted Smbus Slave device address
963 @param Operation Which SMBus protocol will be used
964 @param Offset Offset of the register
965 @param Length Number of bytes
966 @param Buffer Buffer contains values read from registers
967
968 @retval SUCCESS as passed
969 @retval Others as failed
970
971 **/
972 EFI_STATUS
973 PeiSmbusExec (
974 UINT16 SmbusBase,
975 UINT8 SlvAddr,
976 UINT8 Operation,
977 UINT8 Offset,
978 UINT8 *Length,
979 UINT8 *Buffer
980 )
981 {
982 EFI_STATUS Status=EFI_SUCCESS;
983 UINT8 AuxcReg;
984 UINT8 SmbusOperation = 0;
985 UINT8 StsReg;
986 UINT8 SlvAddrReg;
987 UINT8 HostCmdReg;
988 UINT8 BlockCount = 0;
989 BOOLEAN BufferTooSmall;
990 UINT8 Index;
991 UINT8 *CallBuffer;
992 UINT8 RetryCount = BUS_TRIES;
993
994 //
995 // MrcSmbusExec supports byte and block read.
996 // Only allow Byte or block access
997 //
998 if (!((*Length == AV_SC_BYTE_LEN) || (*Length == AV_SC_BLOCK_LEN))) {
999 return EFI_INVALID_PARAMETER;
1000 }
1001
1002 //
1003 // See if its ok to use the bus based upon INUSE_STS bit.
1004 //
1005 Status = AcquireBus (SmbusBase);
1006 ASSERT_EFI_ERROR(Status);
1007
1008 CallBuffer = Buffer;
1009
1010 //
1011 //SmbStatus Bits of interest
1012 //[6] = IUS (In Use Status)
1013 //[4] = FAIL
1014 //[3] = BERR (Bus Error = transaction collision)
1015 //[2] = DERR (Device Error = Illegal Command Field, Unclaimed Cycle, Host Device Timeout, CRC Error)
1016 //[1] = INTR (Successful completion of last command)
1017 //[0] = HOST BUSY
1018 //
1019 //
1020 // This is the main operation loop. If the operation results in a Smbus
1021 // collision with another master on the bus, it attempts the requested
1022 // transaction again at least BUS_TRIES attempts.
1023 //
1024 while (RetryCount--) {
1025 //
1026 // Operation Specifics (pre-execution)
1027 //
1028 Status = EFI_SUCCESS;
1029 SlvAddrReg = SlvAddr;
1030 HostCmdReg = Offset;
1031 AuxcReg = 0;
1032
1033 switch (Operation) {
1034
1035 case SMBUS_WRITE_BYTE:
1036 IoWrite8 (SmbusBase+R_PCH_SMBUS_HD0, CallBuffer[0]);
1037 SmbusOperation = V_PCH_SMBUS_SMB_CMD_BYTE_DATA;
1038 break;
1039
1040 case SMBUS_READ_BYTE:
1041 SmbusOperation = V_PCH_SMBUS_SMB_CMD_BYTE_DATA;
1042 SlvAddrReg |= B_PCH_SMBUS_RW_SEL_READ;
1043 if (*Length < 1) {
1044 Status = EFI_INVALID_PARAMETER;
1045 }
1046 *Length = 1;
1047 break;
1048
1049 case SMBUS_WRITE_BLOCK:
1050 SmbusOperation = V_PCH_SMBUS_SMB_CMD_BLOCK;
1051 IoWrite8 (SmbusBase+R_PCH_SMBUS_HD0, *(UINT8 *) Length);
1052 BlockCount = (UINT8) (*Length);
1053 if ((*Length < 1) || (*Length > 32)) {
1054 Status = EFI_INVALID_PARAMETER;
1055 break;
1056 }
1057 AuxcReg |= B_PCH_SMBUS_E32B;
1058 break;
1059
1060 case SMBUS_READ_BLOCK:
1061 SmbusOperation = V_PCH_SMBUS_SMB_CMD_BLOCK;
1062 SlvAddrReg |= B_PCH_SMBUS_RW_SEL_READ;
1063 if ((*Length < 1) || (*Length > 32)) {
1064 Status = EFI_INVALID_PARAMETER;
1065 break;
1066 }
1067 AuxcReg |= B_PCH_SMBUS_E32B;
1068 break;
1069
1070 default:
1071 Status = EFI_INVALID_PARAMETER;
1072 break;
1073 }
1074
1075 //
1076 // Set Auxiliary Control register
1077 //
1078 IoWrite8 (SmbusBase+R_PCH_SMBUS_AUXC, AuxcReg);
1079
1080 //
1081 // Reset the pointer of the internal buffer
1082 //
1083 IoRead8 (SmbusBase+R_PCH_SMBUS_HCTL);
1084
1085 //
1086 // Now that the 32 byte buffer is turned on, we can write th block data
1087 // into it
1088 //
1089 if (Operation == SMBUS_WRITE_BLOCK) {
1090 for (Index = 0; Index < BlockCount; Index++) {
1091 //
1092 // Write next byte
1093 //
1094 IoWrite8 (SmbusBase+R_PCH_SMBUS_HBD, CallBuffer[Index]);
1095 }
1096 }
1097
1098 //
1099 // Set SMBus slave address for the device to read
1100 //
1101 IoWrite8(SmbusBase+R_PCH_SMBUS_TSA, SlvAddrReg);
1102
1103 //
1104 //
1105 // Set Command register for the offset to read
1106 //
1107 IoWrite8(SmbusBase+R_PCH_SMBUS_HCMD, HostCmdReg );
1108
1109 //
1110 // Set Control Register to Set "operation command" protocol and start bit
1111 //
1112 IoWrite8(SmbusBase+R_PCH_SMBUS_HCTL, (UINT8) (SmbusOperation + B_PCH_SMBUS_START));
1113
1114 //
1115 // Wait for IO to complete
1116 //
1117 do { StsReg = (UINT8) IoRead8(SmbusBase+0); } while ((StsReg & (BIT4|BIT3|BIT2|BIT1)) == 0);
1118
1119 if (StsReg & B_PCH_SMBUS_DERR) {
1120 Status = EFI_DEVICE_ERROR;
1121 break;
1122 } else if (StsReg & B_PCH_SMBUS_BERR) {
1123 //
1124 // Clear the Bus Error for another try
1125 //
1126 Status = EFI_DEVICE_ERROR;
1127 IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, B_PCH_SMBUS_BERR);
1128
1129 //
1130 // Clear Status Registers
1131 //
1132 IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL);
1133 IoWrite8(SmbusBase+R_PCH_SMBUS_AUXS, B_PCH_SMBUS_CRCE);
1134
1135 continue;
1136 }
1137
1138 //
1139 // successfull completion
1140 // Operation Specifics (post-execution)
1141 //
1142 switch (Operation) {
1143
1144 case SMBUS_READ_BYTE:
1145 CallBuffer[0] = (UINT8)(IoRead8 (SmbusBase+R_PCH_SMBUS_HD0));
1146 break;
1147
1148 case SMBUS_WRITE_BLOCK:
1149 IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, B_PCH_SMBUS_BYTE_DONE_STS);
1150 break;
1151
1152 case SMBUS_READ_BLOCK:
1153 BufferTooSmall = FALSE;
1154
1155 //
1156 // Find out how many bytes will be in the block
1157 //
1158 BlockCount = (UINT8)(IoRead8 (SmbusBase+R_PCH_SMBUS_HD0));
1159 if (*Length < BlockCount) {
1160 BufferTooSmall = TRUE;
1161 } else {
1162 for (Index = 0; Index < BlockCount; Index++) {
1163 //
1164 // Read the byte
1165 //
1166 CallBuffer[Index] = (UINT8)IoRead8 (SmbusBase+R_PCH_SMBUS_HBD);
1167 }
1168 }
1169
1170 *Length = BlockCount;
1171 if (BufferTooSmall) {
1172 Status = EFI_BUFFER_TOO_SMALL;
1173 }
1174 break;
1175
1176 default:
1177 break;
1178 };
1179
1180 if ((StsReg & B_PCH_SMBUS_BERR) && (Status == EFI_SUCCESS)) {
1181 //
1182 // Clear the Bus Error for another try
1183 //
1184 Status = EFI_DEVICE_ERROR;
1185 IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, B_PCH_SMBUS_BERR);
1186
1187 continue;
1188 } else {
1189 break;
1190 }
1191 }
1192
1193 //
1194 // Clear Status Registers and exit
1195 //
1196 IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL);
1197 IoWrite8(SmbusBase+R_PCH_SMBUS_AUXS, B_PCH_SMBUS_CRCE);
1198 IoWrite8(SmbusBase+R_PCH_SMBUS_AUXC, 0);
1199 return Status;
1200 }
1201 //
1202 // End::Alpine Valley platform
1203 //
1204