]> git.proxmox.com Git - mirror_edk2.git/blob - Vlv2TbltDevicePkg/PlatformPei/Platform.c
Sync the branch changes to trunk.
[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 EFI_STATUS
196 FtpmPolicyInit (
197 IN CONST EFI_PEI_SERVICES **PeiServices,
198 IN SYSTEM_CONFIGURATION *pSystemConfiguration
199 )
200 {
201 EFI_STATUS Status;
202 EFI_PEI_PPI_DESCRIPTOR *mFtpmPolicyPpiDesc;
203 SEC_FTPM_POLICY_PPI *mFtpmPolicyPpi;
204
205
206 DEBUG((EFI_D_INFO, "FtpmPolicyInit Entry \n"));
207
208 if (NULL == PeiServices || NULL == pSystemConfiguration) {
209 DEBUG((EFI_D_ERROR, "Input error. \n"));
210 return EFI_INVALID_PARAMETER;
211 }
212
213 Status = (*PeiServices)->AllocatePool(
214 PeiServices,
215 sizeof (EFI_PEI_PPI_DESCRIPTOR),
216 (void **)&mFtpmPolicyPpiDesc
217 );
218 ASSERT_EFI_ERROR (Status);
219
220 Status = (*PeiServices)->AllocatePool(
221 PeiServices,
222 sizeof (SEC_FTPM_POLICY_PPI),
223 (void **)&mFtpmPolicyPpi
224 );
225 ASSERT_EFI_ERROR (Status);
226
227 //
228 // Initialize PPI
229 //
230 (*PeiServices)->SetMem ((VOID *)mFtpmPolicyPpi, sizeof (SEC_FTPM_POLICY_PPI), 0);
231 mFtpmPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
232 mFtpmPolicyPpiDesc->Guid = &gSeCfTPMPolicyPpiGuid;
233 mFtpmPolicyPpiDesc->Ppi = mFtpmPolicyPpi;
234
235
236 DEBUG((EFI_D_INFO, "pSystemConfiguration->fTPM = 0x%x \n", pSystemConfiguration->fTPM));
237 if(pSystemConfiguration->fTPM == 1) {
238 mFtpmPolicyPpi->fTPMEnable = TRUE;
239 } else {
240 mFtpmPolicyPpi->fTPMEnable = FALSE;
241 }
242
243 Status = (*PeiServices)->InstallPpi(
244 PeiServices,
245 mFtpmPolicyPpiDesc
246 );
247 ASSERT_EFI_ERROR (Status);
248
249 DEBUG((EFI_D_INFO, "FtpmPolicyInit done \n"));
250
251 return EFI_SUCCESS;
252 }
253
254
255 /**
256 This routine attempts to acquire the SMBus
257
258 @retval FAILURE as failed
259 @retval SUCCESS as passed
260
261 **/
262 EFI_STATUS
263 AcquireBus (
264 UINT16 SmbusBase
265 )
266 {
267 UINT8 StsReg;
268
269 StsReg = 0;
270 StsReg = (UINT8)IoRead8(SmbusBase + R_PCH_SMBUS_HSTS);
271 if (StsReg & B_PCH_SMBUS_IUS) {
272 return EFI_DEVICE_ERROR;
273 } else if (StsReg & B_PCH_SMBUS_HBSY) {
274 //
275 // Clear Status Register and exit
276 //
277 // Wait for HSTS.HBSY to be clear
278 //
279 do { StsReg = (UINT8) IoRead8(SmbusBase+R_PCH_SMBUS_HSTS); } while ((StsReg & B_PCH_SMBUS_HBSY) != 0);
280
281 //
282 // Clear all status bits
283 //
284 IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, 0xFE);
285 return EFI_SUCCESS;
286 } else {
287 //
288 // Clear out any odd status information (Will Not Clear In Use)
289 //
290 IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, StsReg);
291 return EFI_SUCCESS;
292 }
293 }
294 //
295 // End::Alpine Valley platform
296 //
297
298 /**
299 This function checks the memory range in PEI.
300
301 @param PeiServices Pointer to PEI Services.
302 @param This Pei memory test PPI pointer.
303 @param BeginAddress Beginning of the memory address to be checked.
304 @param MemoryLength Bytes of memory range to be checked.
305 @param Operation Type of memory check operation to be performed.
306 @param ErrorAddress Return the address of the error memory address.
307
308 @retval EFI_SUCCESS The operation completed successfully.
309 @retval EFI_DEVICE_ERROR Memory test failed. It's not safe to use this range of memory.
310
311 **/
312 EFI_STATUS
313 EFIAPI
314 MfgMemoryTest (
315 IN CONST EFI_PEI_SERVICES **PeiServices,
316 IN PEI_MFG_MEMORY_TEST_PPI *This,
317 IN UINT32 BeginAddress,
318 IN UINT32 MemoryLength
319 )
320 {
321 UINT32 i;
322 UINT32 memAddr;
323 UINT32 readData;
324 UINT32 xorData;
325 UINT32 TestFlag = 0;
326 memAddr = BeginAddress;
327
328 //
329 //Output Message for MFG
330 //
331 DEBUG ((EFI_D_ERROR, "MFGMODE SET\n"));
332
333 //
334 //Writting the pattern in defined location.
335 //
336 while (memAddr < (BeginAddress+MemoryLength)) {
337 for (i = 0; i < DATA_PATTERN_ARRAY_SIZE; i++) {
338 if (memAddr > (BeginAddress+MemoryLength -4)) {
339 memAddr = memAddr + 4;
340 break;
341 }
342 *((volatile UINT32*) memAddr) = DataPatternForMemoryTest[i];
343 memAddr = memAddr + 4;
344 }
345 }
346
347 //
348 //Verify the pattern.
349 //
350 memAddr = BeginAddress;
351 while (memAddr < (BeginAddress+MemoryLength)) {
352 for (i = 0; i < DATA_PATTERN_ARRAY_SIZE; i++) {
353 if (memAddr > (BeginAddress+MemoryLength -4)) {
354 memAddr = memAddr + 4;
355 break;
356 }
357 readData = *((volatile UINT32*) memAddr);
358 xorData = readData ^ DataPatternForMemoryTest[i];
359
360 //
361 // If xorData is nonzero, this particular memAddr has a failure.
362 //
363 if (xorData != 0x00000000) {
364 DEBUG ((EFI_D_ERROR, "Expected value....: %x\n", DataPatternForMemoryTest[i]));
365 DEBUG ((EFI_D_ERROR, "ReadData value....: %x\n", readData));
366 DEBUG ((EFI_D_ERROR, "Pattern failure at....: %x\n", memAddr));
367 TestFlag = 1;
368 }
369 memAddr = memAddr + 4;
370 }
371 }
372 if (TestFlag) {
373 return EFI_DEVICE_ERROR;
374 }
375
376 //
377 //Output Message for MFG
378 //
379 DEBUG ((EFI_D_ERROR, "MFGMODE MEMORY TEST PASSED\n"));
380 return EFI_SUCCESS;
381 }
382
383 BOOLEAN
384 IsRtcUipAlwaysSet (
385 IN CONST EFI_PEI_SERVICES **PeiServices
386 )
387 {
388
389 EFI_PEI_STALL_PPI *StallPpi;
390 UINTN Count;
391
392 (**PeiServices).LocatePpi (PeiServices, &gEfiPeiStallPpiGuid, 0, NULL, (void **)&StallPpi);
393
394 for (Count = 0; Count < 500; Count++) { // Maximum waiting approximates to 1.5 seconds (= 3 msec * 500)
395 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERA);
396 if ((IoRead8 (R_PCH_RTC_TARGET2) & B_PCH_RTC_REGISTERA_UIP) == 0) {
397 return FALSE;
398 }
399
400 StallPpi->Stall (PeiServices, StallPpi, 3000);
401 }
402
403 return TRUE;
404 }
405
406 EFI_STATUS
407 RtcPowerFailureHandler (
408 IN CONST EFI_PEI_SERVICES **PeiServices
409 )
410 {
411
412 UINT16 DataUint16;
413 UINT8 DataUint8;
414 BOOLEAN RtcUipIsAlwaysSet;
415 DataUint16 = MmioRead16 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1);
416 RtcUipIsAlwaysSet = IsRtcUipAlwaysSet (PeiServices);
417 if ((DataUint16 & B_PCH_PMC_GEN_PMCON_RTC_PWR_STS) || (RtcUipIsAlwaysSet)) {
418 //
419 // Execute the sequence below. This will ensure that the RTC state machine has been initialized.
420 //
421 // Step 1.
422 // BIOS clears this bit by writing a '0' to it.
423 //
424 if (DataUint16 & B_PCH_PMC_GEN_PMCON_RTC_PWR_STS) {
425 //
426 // Set to invalid date in order to reset the time to
427 // BIOS build time later in the boot (SBRUN.c file).
428 //
429 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_YEAR);
430 IoWrite8 (R_PCH_RTC_TARGET2, 0x0FF);
431 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_MONTH);
432 IoWrite8 (R_PCH_RTC_TARGET2, 0x0FF);
433 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_DAYOFMONTH);
434 IoWrite8 (R_PCH_RTC_TARGET2, 0x0FF);
435 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_DAYOFWEEK);
436 IoWrite8 (R_PCH_RTC_TARGET2, 0x0FF);
437
438 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_SECONDSALARM);
439 IoWrite8 (R_PCH_RTC_TARGET2, 0x00);
440 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_MINUTESALARM);
441 IoWrite8 (R_PCH_RTC_TARGET2, 0x00);
442 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_HOURSALARM);
443 IoWrite8 (R_PCH_RTC_TARGET2, 0x00);
444 }
445
446 //
447 // Step 2.
448 // Set RTC Register 0Ah[6:4] to '110' or '111'.
449 //
450 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERA);
451 IoWrite8 (R_PCH_RTC_TARGET2, (V_PCH_RTC_REGISTERA_DV_DIV_RST1 | V_PCH_RTC_REGISTERA_RS_976P5US));
452
453 //
454 // Step 3.
455 // Set RTC Register 0Bh[7].
456 //
457 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERB);
458 DataUint8 = (IoRead8 (R_PCH_RTC_TARGET2) | B_PCH_RTC_REGISTERB_SET);
459 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERB);
460 IoWrite8 (R_PCH_RTC_TARGET2, DataUint8);
461
462 //
463 // Step 4.
464 // Set RTC Register 0Ah[6:4] to '010'.
465 //
466 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERA);
467 IoWrite8 (R_PCH_RTC_TARGET2, (V_PCH_RTC_REGISTERA_DV_NORM_OP | V_PCH_RTC_REGISTERA_RS_976P5US));
468
469 //
470 // Step 5.
471 // Clear RTC Register 0Bh[7].
472 //
473 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERB);
474 DataUint8 = (IoRead8 (R_PCH_RTC_TARGET2) & (UINT8)~B_PCH_RTC_REGISTERB_SET);
475 IoWrite8 (R_PCH_RTC_INDEX2, R_PCH_RTC_REGISTERB);
476 IoWrite8 (R_PCH_RTC_TARGET2, DataUint8);
477 }
478
479 return EFI_SUCCESS;
480 }
481
482
483 VOID
484 PchBaseInit (
485 VOID
486 )
487 {
488 //
489 // Program ACPI Power Management I/O Space Base Address
490 //
491 MmioWrite16 (
492 MmPciAddress (0,
493 DEFAULT_PCI_BUS_NUMBER_PCH,
494 PCI_DEVICE_NUMBER_PCH_LPC,
495 PCI_FUNCTION_NUMBER_PCH_LPC,
496 R_PCH_LPC_ACPI_BASE
497 ),
498 (UINT16)((ACPI_BASE_ADDRESS & B_PCH_LPC_ACPI_BASE_BAR) | B_PCH_LPC_ACPI_BASE_EN)
499 );
500
501 //
502 // Program GPIO Base Address
503 //
504 MmioWrite16 (
505 MmPciAddress (0,
506 DEFAULT_PCI_BUS_NUMBER_PCH,
507 PCI_DEVICE_NUMBER_PCH_LPC,
508 PCI_FUNCTION_NUMBER_PCH_LPC,
509 R_PCH_LPC_GPIO_BASE
510 ),
511 (UINT16)((GPIO_BASE_ADDRESS & B_PCH_LPC_GPIO_BASE_BAR) | B_PCH_LPC_GPIO_BASE_EN)
512 );
513
514 //
515 // Set PMC Base Address
516 //
517 MmioWrite32 (
518 MmPciAddress (0,
519 DEFAULT_PCI_BUS_NUMBER_PCH,
520 PCI_DEVICE_NUMBER_PCH_LPC,
521 PCI_FUNCTION_NUMBER_PCH_LPC,
522 R_PCH_LPC_PMC_BASE
523 ),
524 (UINT32)((PMC_BASE_ADDRESS & B_PCH_LPC_PMC_BASE_BAR) | B_PCH_LPC_PMC_BASE_EN)
525 );
526
527 //
528 // Set IO Base Address
529 //
530 MmioWrite32 (
531 MmPciAddress (0,
532 DEFAULT_PCI_BUS_NUMBER_PCH,
533 PCI_DEVICE_NUMBER_PCH_LPC,
534 PCI_FUNCTION_NUMBER_PCH_LPC,
535 R_PCH_LPC_IO_BASE
536 ),
537 (UINT32)((IO_BASE_ADDRESS & B_PCH_LPC_IO_BASE_BAR) | B_PCH_LPC_IO_BASE_EN)
538 );
539
540 //
541 // Set ILB Base Address
542 //
543 MmioWrite32 (
544 MmPciAddress (0,
545 DEFAULT_PCI_BUS_NUMBER_PCH,
546 PCI_DEVICE_NUMBER_PCH_LPC,
547 PCI_FUNCTION_NUMBER_PCH_LPC,
548 R_PCH_LPC_ILB_BASE
549 ),
550 (UINT32)((ILB_BASE_ADDRESS & B_PCH_LPC_ILB_BASE_BAR) | B_PCH_LPC_ILB_BASE_EN)
551 );
552
553 //
554 // Set PUnit Base Address
555 //
556 MmioWrite32 (
557 MmPciAddress (0,
558 DEFAULT_PCI_BUS_NUMBER_PCH,
559 PCI_DEVICE_NUMBER_PCH_LPC,
560 PCI_FUNCTION_NUMBER_PCH_LPC,
561 R_PCH_LPC_PUNIT_BASE
562 ),
563 (UINT32)((PUNIT_BASE_ADDRESS & B_PCH_LPC_PUNIT_BASE_BAR) | B_PCH_LPC_PUNIT_BASE_EN)
564 );
565
566 //
567 // Set SPI Base Address
568 //
569 MmioWrite32 (
570 MmPciAddress (0,
571 DEFAULT_PCI_BUS_NUMBER_PCH,
572 PCI_DEVICE_NUMBER_PCH_LPC,
573 PCI_FUNCTION_NUMBER_PCH_LPC,
574 R_PCH_LPC_SPI_BASE
575 ),
576 (UINT32)((SPI_BASE_ADDRESS & B_PCH_LPC_SPI_BASE_BAR) | B_PCH_LPC_SPI_BASE_EN)
577 );
578
579 //
580 // Set Root Complex Base Address
581 //
582 MmioWrite32 (
583 MmPciAddress (0,
584 DEFAULT_PCI_BUS_NUMBER_PCH,
585 PCI_DEVICE_NUMBER_PCH_LPC,
586 PCI_FUNCTION_NUMBER_PCH_LPC,
587 R_PCH_LPC_RCBA
588 ),
589 (UINT32)((RCBA_BASE_ADDRESS & B_PCH_LPC_RCBA_BAR) | B_PCH_LPC_RCBA_EN)
590 );
591
592 //
593 // Set MPHY Base Address
594 //
595 MmioWrite32 (
596 MmPciAddress (0,
597 DEFAULT_PCI_BUS_NUMBER_PCH,
598 PCI_DEVICE_NUMBER_PCH_LPC,
599 PCI_FUNCTION_NUMBER_PCH_LPC,
600 R_PCH_LPC_MPHY_BASE
601 ),
602 (UINT32)((MPHY_BASE_ADDRESS & B_PCH_LPC_MPHY_BASE_BAR) | B_PCH_LPC_MPHY_BASE_EN)
603 );
604 MmioWrite16 (
605 MmPciAddress (0,
606 DEFAULT_PCI_BUS_NUMBER_PCH,
607 PCI_DEVICE_NUMBER_PCH_SMBUS,
608 PCI_FUNCTION_NUMBER_PCH_SMBUS,
609 R_PCH_SMBUS_BASE
610 ),
611 (UINT16)(SMBUS_BASE_ADDRESS & B_PCH_SMBUS_BASE_BAR)
612 );
613
614 MmioOr8 (
615 MmPciAddress (0,
616 DEFAULT_PCI_BUS_NUMBER_PCH,
617 PCI_DEVICE_NUMBER_PCH_SMBUS,
618 PCI_FUNCTION_NUMBER_PCH_SMBUS,
619 R_PCH_SMBUS_PCICMD
620 ),
621 B_PCH_SMBUS_PCICMD_IOSE
622 );
623
624 }
625
626 /**
627 This is the entrypoint of PEIM
628
629 @param FileHandle Handle of the file being invoked.
630 @param PeiServices Describes the list of possible PEI Services.
631
632 @retval EFI_SUCCESS if it completed successfully.
633 **/
634 EFI_STATUS
635 EFIAPI
636 PeiInitPlatform (
637 IN EFI_PEI_FILE_HANDLE FileHandle,
638 IN CONST EFI_PEI_SERVICES **PeiServices
639 )
640 {
641 UINTN SmbusRegBase;
642 EFI_PLATFORM_INFO_HOB PlatformInfo;
643 EFI_STATUS Status= EFI_SUCCESS;
644 EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable = NULL;
645 UINTN VariableSize;
646 SYSTEM_CONFIGURATION SystemConfiguration;
647 UINT32 GGC = 0;
648
649 EFI_PEI_PPI_DESCRIPTOR *mVlvMmioPolicyPpiDesc;
650 VLV_MMIO_POLICY_PPI *mVlvMmioPolicyPpi;
651
652 ZeroMem (&PlatformInfo, sizeof(PlatformInfo));
653
654 Status = InstallMonoStatusCode(FileHandle, PeiServices);
655 ASSERT_EFI_ERROR (Status);
656
657
658 //
659 // Initialize Stall PPIs
660 //
661 Status = (*PeiServices)->InstallPpi (PeiServices, &mInstallStallPpi[0]);
662 ASSERT_EFI_ERROR (Status);
663
664 Status = (*PeiServices)->NotifyPpi (PeiServices, &mMemoryDiscoveredNotifyList[0]);
665 ASSERT_EFI_ERROR (Status);
666 SmbusRegBase = PchPciDeviceMmBase (
667 DEFAULT_PCI_BUS_NUMBER_PCH,
668 PCI_DEVICE_NUMBER_PCH_SMBUS,
669 PCI_FUNCTION_NUMBER_PCH_SMBUS
670 );
671 //
672 // Since PEI has no PCI enumerator, set the BAR & I/O space enable ourselves
673 //
674 MmioAndThenOr32 (SmbusRegBase + R_PCH_SMBUS_BASE, B_PCH_SMBUS_BASE_BAR, SMBUS_BASE_ADDRESS);
675
676 MmioOr8 (SmbusRegBase + R_PCH_SMBUS_PCICMD, B_PCH_SMBUS_PCICMD_IOSE);
677
678 PchBaseInit();
679
680 //
681 //Todo: confirm if we need program 8254
682 //
683 // Setting 8254
684 // Program timer 1 as refresh timer
685 //
686 IoWrite8 (0x43, 0x54);
687 IoWrite8 (0x41, 0x12);
688
689 //
690 // RTC power failure handling
691 //
692 RtcPowerFailureHandler (PeiServices);
693
694
695 PchMmPci32( 0, 0, 2, 0, 0x50) = 0x210;
696
697 VariableSize = sizeof (SYSTEM_CONFIGURATION);
698 ZeroMem (&SystemConfiguration, VariableSize);
699
700 //
701 // Obtain variable services
702 //
703 Status = (*PeiServices)->LocatePpi(
704 PeiServices,
705 &gEfiPeiReadOnlyVariable2PpiGuid,
706 0,
707 NULL,
708 (void **)&Variable
709 );
710 ASSERT_EFI_ERROR(Status);
711 Status = Variable->GetVariable (
712 Variable,
713 L"Setup",
714 &gEfiSetupVariableGuid,
715 NULL,
716 &VariableSize,
717 &SystemConfiguration
718 );
719 if (EFI_ERROR (Status) || VariableSize != sizeof(SYSTEM_CONFIGURATION)) {
720 //The setup variable is corrupted
721 VariableSize = sizeof(SYSTEM_CONFIGURATION);
722 Status = Variable->GetVariable(
723 Variable,
724 L"SetupRecovery",
725 &gEfiSetupVariableGuid,
726 NULL,
727 &VariableSize,
728 &SystemConfiguration
729 );
730 ASSERT_EFI_ERROR (Status);
731 }
732
733 if (EFI_ERROR (Status)) {
734 GGC = ((2 << 3) | 0x200);
735 PciCfg16Write(EC_BASE, 0, 2, 0, 0x50, GGC);
736 GGC = PciCfg16Read(EC_BASE, 0, 2, 0, 0x50);
737 DEBUG((EFI_D_INFO , "GGC: 0x%08x GMSsize:0x%08x\n", GGC, (GGC & (BIT7|BIT6|BIT5|BIT4|BIT3))>>3));
738 } else {
739 if (SystemConfiguration.Igd == 1 && SystemConfiguration.PrimaryVideoAdaptor != 2) {
740 GGC = (SystemConfiguration.IgdDvmt50PreAlloc << 3) |
741 (SystemConfiguration.GTTSize == GTT_SIZE_1MB ? 0x100: 0x200);
742 PciCfg16Write(EC_BASE, 0, 2, 0, 0x50, GGC);
743 GGC = PciCfg16Read(EC_BASE, 0, 2, 0, 0x50);
744 DEBUG((EFI_D_INFO , "GGC: 0x%08x GMSsize:0x%08x\n", GGC, (GGC & (BIT7|BIT6|BIT5|BIT4|BIT3))>>3));
745 }
746 }
747
748 //
749 // Initialize PlatformInfo HOB
750 //
751 Status = ReadPlatformIds(PeiServices, &PlatformInfo);
752 ASSERT_EFI_ERROR (Status);
753
754 //
755 // 0 -> Disable , 1 -> Enable
756 //
757 if(SystemConfiguration.CfioPnpSettings == 1) {
758 DEBUG((EFI_D_INFO, "CheckCfioPnpSettings: CFIO Pnp Settings Enabled\n"));
759 PlatformInfo.CfioEnabled = 1;
760 } else {
761 DEBUG((EFI_D_INFO, "CheckCfioPnpSettings: CFIO Pnp Settings Disabled\n"));
762 PlatformInfo.CfioEnabled = 0;
763 }
764
765 //
766 // Build HOB for PlatformInfo
767 //
768 BuildGuidDataHob (
769 &gEfiPlatformInfoGuid,
770 &PlatformInfo,
771 sizeof (EFI_PLATFORM_INFO_HOB)
772 );
773
774
775 #ifdef FTPM_ENABLE
776 Status = FtpmPolicyInit(PeiServices, &SystemConfiguration);
777 if (EFI_ERROR (Status)) {
778 DEBUG((EFI_D_ERROR, "fTPM init failed.\n"));
779 }
780 #endif
781
782
783 //
784 // Set the new boot mode for MRC
785 //
786 #ifdef NOCS_S3_SUPPORT
787 Status = UpdateBootMode (PeiServices);
788 ASSERT_EFI_ERROR (Status);
789 #endif
790
791 DEBUG((EFI_D_INFO, "Setup MMIO size ... \n\n"));
792
793 //
794 // Setup MMIO size
795 //
796 Status = (*PeiServices)->AllocatePool(
797 PeiServices,
798 sizeof (EFI_PEI_PPI_DESCRIPTOR),
799 (void **)&mVlvMmioPolicyPpiDesc
800 );
801 ASSERT_EFI_ERROR (Status);
802 Status = (*PeiServices)->AllocatePool(
803 PeiServices,
804 sizeof (VLV_MMIO_POLICY_PPI),
805 (void **)&mVlvMmioPolicyPpi
806 );
807 ASSERT_EFI_ERROR (Status);
808 (*PeiServices)->SetMem (
809 (VOID *)mVlvMmioPolicyPpi,
810 sizeof (VLV_MMIO_POLICY_PPI),
811 0
812 );
813 mVlvMmioPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
814 mVlvMmioPolicyPpiDesc->Guid = &gVlvMmioPolicyPpiGuid;
815 mVlvMmioPolicyPpiDesc->Ppi = mVlvMmioPolicyPpi;
816 switch (SystemConfiguration.MmioSize) {
817 case 0: // 768MB
818 mVlvMmioPolicyPpi->MmioSize = 0x300;
819 break;
820 case 1: // 1GB
821 mVlvMmioPolicyPpi->MmioSize = 0x400;
822 break;
823 case 2: // 1.25GB
824 mVlvMmioPolicyPpi->MmioSize = 0x500;
825 break;
826 case 3: // 1.5GB
827 mVlvMmioPolicyPpi->MmioSize = 0x600;
828 break;
829 case 4: // 2GB
830 mVlvMmioPolicyPpi->MmioSize = 0x800;
831 break;
832 default:
833 mVlvMmioPolicyPpi->MmioSize = 0x800;
834 break;
835 }
836 Status = (*PeiServices)->InstallPpi(
837 PeiServices,
838 mVlvMmioPolicyPpiDesc
839 );
840 ASSERT_EFI_ERROR (Status);
841
842 return Status;
843 }
844
845 EFI_STATUS
846 ReadPlatformIds (
847 IN CONST EFI_PEI_SERVICES **PeiServices,
848 IN OUT EFI_PLATFORM_INFO_HOB *PlatformInfoHob
849 )
850 {
851 {
852 EFI_STATUS Status = EFI_SUCCESS;
853 UINT8 FabId = 0;
854 UINTN DataSize;
855 EFI_PLATFORM_INFO_HOB TmpHob;
856 EFI_PEI_READ_ONLY_VARIABLE2_PPI *PeiVar;
857
858 Status = (**PeiServices).LocatePpi (
859 PeiServices,
860 &gEfiPeiReadOnlyVariable2PpiGuid,
861 0,
862 NULL,
863 (void **)&PeiVar
864 );
865 ASSERT_EFI_ERROR (Status);
866
867 DataSize = sizeof (EFI_PLATFORM_INFO_HOB);
868 Status = PeiVar->GetVariable (
869 PeiVar,
870 L"PlatformInfo",
871 &gEfiVlv2VariableGuid,
872 NULL,
873 &DataSize,
874 &TmpHob
875 );
876
877 if (Status == EFI_SUCCESS) {
878 PlatformInfoHob->BoardId = TmpHob.BoardId;
879 PlatformInfoHob->MemCfgID = TmpHob.MemCfgID;
880 PlatformInfoHob->BoardRev = TmpHob.BoardRev;
881 PlatformInfoHob->PlatformFlavor = TmpHob.PlatformFlavor;
882 return Status;
883 }
884
885
886 PlatformInfoHob->BoardId = BOARD_ID_MINNOW2;
887 DEBUG ((EFI_D_INFO, "I'm Minnow2!\n"));
888
889 PlatformInfoHob->MemCfgID = 0;
890 PlatformInfoHob->BoardRev = FabId + 1; // FabId = 0 means FAB1 (BoardRev = 1), FabId = 1 means FAB2 (BoardRev = 2)...
891 PlatformInfoHob->PlatformFlavor = FlavorMobile;
892 }
893
894 return EFI_SUCCESS;
895 }
896
897 //
898 // Start::Alpine Valley platform
899 //
900 /**
901 This routine reads SysCtl registers
902
903 @param SmbusBase SMBUS Base Address
904 @param SlvAddr Targeted Smbus Slave device address
905 @param Operation Which SMBus protocol will be used
906 @param Offset Offset of the register
907 @param Length Number of bytes
908 @param Buffer Buffer contains values read from registers
909
910 @retval SUCCESS as passed
911 @retval Others as failed
912
913 **/
914 EFI_STATUS
915 PeiSmbusExec (
916 UINT16 SmbusBase,
917 UINT8 SlvAddr,
918 UINT8 Operation,
919 UINT8 Offset,
920 UINT8 *Length,
921 UINT8 *Buffer
922 )
923 {
924 EFI_STATUS Status=EFI_SUCCESS;
925 UINT8 AuxcReg;
926 UINT8 SmbusOperation = 0;
927 UINT8 StsReg;
928 UINT8 SlvAddrReg;
929 UINT8 HostCmdReg;
930 UINT8 BlockCount = 0;
931 BOOLEAN BufferTooSmall;
932 UINT8 Index;
933 UINT8 *CallBuffer;
934 UINT8 RetryCount = BUS_TRIES;
935
936 //
937 // MrcSmbusExec supports byte and block read.
938 // Only allow Byte or block access
939 //
940 if (!((*Length == AV_SC_BYTE_LEN) || (*Length == AV_SC_BLOCK_LEN))) {
941 return EFI_INVALID_PARAMETER;
942 }
943
944 //
945 // See if its ok to use the bus based upon INUSE_STS bit.
946 //
947 Status = AcquireBus (SmbusBase);
948 ASSERT_EFI_ERROR(Status);
949
950 CallBuffer = Buffer;
951
952 //
953 //SmbStatus Bits of interest
954 //[6] = IUS (In Use Status)
955 //[4] = FAIL
956 //[3] = BERR (Bus Error = transaction collision)
957 //[2] = DERR (Device Error = Illegal Command Field, Unclaimed Cycle, Host Device Timeout, CRC Error)
958 //[1] = INTR (Successful completion of last command)
959 //[0] = HOST BUSY
960 //
961 //
962 // This is the main operation loop. If the operation results in a Smbus
963 // collision with another master on the bus, it attempts the requested
964 // transaction again at least BUS_TRIES attempts.
965 //
966 while (RetryCount--) {
967 //
968 // Operation Specifics (pre-execution)
969 //
970 Status = EFI_SUCCESS;
971 SlvAddrReg = SlvAddr;
972 HostCmdReg = Offset;
973 AuxcReg = 0;
974
975 switch (Operation) {
976
977 case SMBUS_WRITE_BYTE:
978 IoWrite8 (SmbusBase+R_PCH_SMBUS_HD0, CallBuffer[0]);
979 SmbusOperation = V_PCH_SMBUS_SMB_CMD_BYTE_DATA;
980 break;
981
982 case SMBUS_READ_BYTE:
983 SmbusOperation = V_PCH_SMBUS_SMB_CMD_BYTE_DATA;
984 SlvAddrReg |= B_PCH_SMBUS_RW_SEL_READ;
985 if (*Length < 1) {
986 Status = EFI_INVALID_PARAMETER;
987 }
988 *Length = 1;
989 break;
990
991 case SMBUS_WRITE_BLOCK:
992 SmbusOperation = V_PCH_SMBUS_SMB_CMD_BLOCK;
993 IoWrite8 (SmbusBase+R_PCH_SMBUS_HD0, *(UINT8 *) Length);
994 BlockCount = (UINT8) (*Length);
995 if ((*Length < 1) || (*Length > 32)) {
996 Status = EFI_INVALID_PARAMETER;
997 break;
998 }
999 AuxcReg |= B_PCH_SMBUS_E32B;
1000 break;
1001
1002 case SMBUS_READ_BLOCK:
1003 SmbusOperation = V_PCH_SMBUS_SMB_CMD_BLOCK;
1004 SlvAddrReg |= B_PCH_SMBUS_RW_SEL_READ;
1005 if ((*Length < 1) || (*Length > 32)) {
1006 Status = EFI_INVALID_PARAMETER;
1007 break;
1008 }
1009 AuxcReg |= B_PCH_SMBUS_E32B;
1010 break;
1011
1012 default:
1013 Status = EFI_INVALID_PARAMETER;
1014 break;
1015 }
1016
1017 //
1018 // Set Auxiliary Control register
1019 //
1020 IoWrite8 (SmbusBase+R_PCH_SMBUS_AUXC, AuxcReg);
1021
1022 //
1023 // Reset the pointer of the internal buffer
1024 //
1025 IoRead8 (SmbusBase+R_PCH_SMBUS_HCTL);
1026
1027 //
1028 // Now that the 32 byte buffer is turned on, we can write th block data
1029 // into it
1030 //
1031 if (Operation == SMBUS_WRITE_BLOCK) {
1032 for (Index = 0; Index < BlockCount; Index++) {
1033 //
1034 // Write next byte
1035 //
1036 IoWrite8 (SmbusBase+R_PCH_SMBUS_HBD, CallBuffer[Index]);
1037 }
1038 }
1039
1040 //
1041 // Set SMBus slave address for the device to read
1042 //
1043 IoWrite8(SmbusBase+R_PCH_SMBUS_TSA, SlvAddrReg);
1044
1045 //
1046 //
1047 // Set Command register for the offset to read
1048 //
1049 IoWrite8(SmbusBase+R_PCH_SMBUS_HCMD, HostCmdReg );
1050
1051 //
1052 // Set Control Register to Set "operation command" protocol and start bit
1053 //
1054 IoWrite8(SmbusBase+R_PCH_SMBUS_HCTL, (UINT8) (SmbusOperation + B_PCH_SMBUS_START));
1055
1056 //
1057 // Wait for IO to complete
1058 //
1059 do { StsReg = (UINT8) IoRead8(SmbusBase+0); } while ((StsReg & (BIT4|BIT3|BIT2|BIT1)) == 0);
1060
1061 if (StsReg & B_PCH_SMBUS_DERR) {
1062 Status = EFI_DEVICE_ERROR;
1063 break;
1064 } else if (StsReg & B_PCH_SMBUS_BERR) {
1065 //
1066 // Clear the Bus Error for another try
1067 //
1068 Status = EFI_DEVICE_ERROR;
1069 IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, B_PCH_SMBUS_BERR);
1070
1071 //
1072 // Clear Status Registers
1073 //
1074 IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL);
1075 IoWrite8(SmbusBase+R_PCH_SMBUS_AUXS, B_PCH_SMBUS_CRCE);
1076
1077 continue;
1078 }
1079
1080 //
1081 // successfull completion
1082 // Operation Specifics (post-execution)
1083 //
1084 switch (Operation) {
1085
1086 case SMBUS_READ_BYTE:
1087 CallBuffer[0] = (UINT8)(IoRead8 (SmbusBase+R_PCH_SMBUS_HD0));
1088 break;
1089
1090 case SMBUS_WRITE_BLOCK:
1091 IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, B_PCH_SMBUS_BYTE_DONE_STS);
1092 break;
1093
1094 case SMBUS_READ_BLOCK:
1095 BufferTooSmall = FALSE;
1096
1097 //
1098 // Find out how many bytes will be in the block
1099 //
1100 BlockCount = (UINT8)(IoRead8 (SmbusBase+R_PCH_SMBUS_HD0));
1101 if (*Length < BlockCount) {
1102 BufferTooSmall = TRUE;
1103 } else {
1104 for (Index = 0; Index < BlockCount; Index++) {
1105 //
1106 // Read the byte
1107 //
1108 CallBuffer[Index] = (UINT8)IoRead8 (SmbusBase+R_PCH_SMBUS_HBD);
1109 }
1110 }
1111
1112 *Length = BlockCount;
1113 if (BufferTooSmall) {
1114 Status = EFI_BUFFER_TOO_SMALL;
1115 }
1116 break;
1117
1118 default:
1119 break;
1120 };
1121
1122 if ((StsReg & B_PCH_SMBUS_BERR) && (Status == EFI_SUCCESS)) {
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 continue;
1130 } else {
1131 break;
1132 }
1133 }
1134
1135 //
1136 // Clear Status Registers and exit
1137 //
1138 IoWrite8(SmbusBase+R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL);
1139 IoWrite8(SmbusBase+R_PCH_SMBUS_AUXS, B_PCH_SMBUS_CRCE);
1140 IoWrite8(SmbusBase+R_PCH_SMBUS_AUXC, 0);
1141 return Status;
1142 }
1143 //
1144 // End::Alpine Valley platform
1145 //
1146