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