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