/** @file | |
This PEIM will parse the hoblist from fsp and report them into pei core. | |
This file contains the main entrypoint of the PEIM. | |
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR> | |
This program and the accompanying materials | |
are licensed and made available under the terms and conditions of the BSD License | |
which accompanies this distribution. The full text of the license may be found at | |
http://opensource.org/licenses/bsd-license.php. | |
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
**/ | |
#include <PiPei.h> | |
#include <Library\IoLib.h> | |
#include <Library\SerialPortLib.h> | |
#define PCI_IDX 0xCF8 | |
#define PCI_DAT 0xCFC | |
#define PCI_LPC_BASE (0x8000F800) | |
#define PCI_LPC_REG(x) (PCI_LPC_BASE + (x)) | |
#define PMC_BASE_ADDRESS 0xFED03000 // PMC Memory Base Address | |
#define R_PCH_LPC_PMC_BASE 0x44 // PBASE, 32bit, 512 Bytes | |
#define B_PCH_LPC_PMC_BASE_EN BIT1 // Enable Bit | |
#define R_PCH_PMC_GEN_PMCON_1 0x20 // General PM Configuration 1 | |
#define B_PCH_PMC_GEN_PMCON_SUS_PWR_FLR BIT14 // SUS Well Power Failure | |
#define B_PCH_PMC_GEN_PMCON_PWROK_FLR BIT16 // PWROK Failure | |
#define R_PCH_LPC_UART_CTRL 0x80 // UART Control | |
#define B_PCH_LPC_UART_CTRL_COM1_EN BIT0 // COM1 Enable | |
#define ILB_BASE_ADDRESS 0xFED08000 // ILB Memory Base Address | |
#define R_PCH_ILB_IRQE 0x88 // IRQ Enable Control | |
#define IO_BASE_ADDRESS 0xFED0C000 // IO Memory Base Address | |
#define V_PCH_ILB_IRQE_UARTIRQEN_IRQ3 BIT3 // UART IRQ3 Enable | |
#define V_PCH_ILB_IRQE_UARTIRQEN_IRQ4 BIT4 // UART IRQ4 Enable | |
#define PCIEX_BASE_ADDRESS 0xE0000000 | |
#define PCI_EXPRESS_BASE_ADDRESS PCIEX_BASE_ADDRESS | |
#define PciD31F0RegBase PCIEX_BASE_ADDRESS + (UINT32) (31 << 15) | |
#define SB_RCBA 0xfed1c000 | |
typedef enum { | |
PchA0 = 0, | |
PchA1 = 1, | |
PchB0 = 2, | |
PchB1 = 3, | |
PchB2 = 4, | |
PchB3 = 5, | |
PchC0 = 6, | |
PchSteppingMax | |
} PCH_STEPPING; | |
#define MmPciAddress( Segment, Bus, Device, Function, Register ) \ | |
( (UINTN)PCI_EXPRESS_BASE_ADDRESS + \ | |
(UINTN)(Bus << 20) + \ | |
(UINTN)(Device << 15) + \ | |
(UINTN)(Function << 12) + \ | |
(UINTN)(Register) \ | |
) | |
#define DEFAULT_PCI_BUS_NUMBER_PCH 0 | |
#define PCI_DEVICE_NUMBER_PCH_LPC 31 | |
#define PCI_FUNCTION_NUMBER_PCH_LPC 0 | |
#define R_PCH_LPC_RID_CC 0x08 // Revision ID & Class Code | |
#define V_PCH_LPC_RID_0 0x01 // A0 Stepping (17 x 17) | |
#define V_PCH_LPC_RID_1 0x02 // A0 Stepping (25 x 27) | |
#define V_PCH_LPC_RID_2 0x03 // A1 Stepping (17 x 17) | |
#define V_PCH_LPC_RID_3 0x04 // A1 Stepping (25 x 27) | |
#define V_PCH_LPC_RID_4 0x05 // B0 Stepping (17 x 17) | |
#define V_PCH_LPC_RID_5 0x06 // B0 Stepping (25 x 27) | |
#define V_PCH_LPC_RID_6 0x07 // B1 Stepping (17 x 17) | |
#define V_PCH_LPC_RID_7 0x08 // B1 Stepping (25 x 27) | |
#define V_PCH_LPC_RID_8 0x09 // B2 Stepping (17 x 17) | |
#define V_PCH_LPC_RID_9 0x0A // B2 Stepping (25 x 27) | |
#define V_PCH_LPC_RID_A 0x0B // B3 Stepping (17 x 17) | |
#define V_PCH_LPC_RID_B 0x0C // B3 Stepping (25 x 27) | |
#define V_PCH_LPC_RID_C 0x0D // C0 Stepping (17 x 17) | |
#define V_PCH_LPC_RID_D 0x0E // C0 Stepping (25 x 27) | |
/** | |
Return Pch stepping type | |
@param[in] None | |
@retval PCH_STEPPING Pch stepping type | |
**/ | |
PCH_STEPPING | |
EFIAPI | |
PchStepping ( | |
VOID | |
) | |
{ | |
UINT8 RevId; | |
RevId = MmioRead8 ( | |
MmPciAddress (0, | |
DEFAULT_PCI_BUS_NUMBER_PCH, | |
PCI_DEVICE_NUMBER_PCH_LPC, | |
PCI_FUNCTION_NUMBER_PCH_LPC, | |
R_PCH_LPC_RID_CC) | |
); | |
switch (RevId) { | |
case V_PCH_LPC_RID_0: | |
case V_PCH_LPC_RID_1: | |
return PchA0; | |
break; | |
case V_PCH_LPC_RID_2: | |
case V_PCH_LPC_RID_3: | |
return PchA1; | |
break; | |
case V_PCH_LPC_RID_4: | |
case V_PCH_LPC_RID_5: | |
return PchB0; | |
break; | |
case V_PCH_LPC_RID_6: | |
case V_PCH_LPC_RID_7: | |
return PchB1; | |
break; | |
case V_PCH_LPC_RID_8: | |
case V_PCH_LPC_RID_9: | |
return PchB2; | |
break; | |
case V_PCH_LPC_RID_A: | |
case V_PCH_LPC_RID_B: | |
return PchB3; | |
break; | |
case V_PCH_LPC_RID_C: | |
case V_PCH_LPC_RID_D: | |
return PchC0; | |
break; | |
default: | |
return PchSteppingMax; | |
break; | |
} | |
} | |
/** | |
Enable legacy decoding on ICH6 | |
@param[in] none | |
@retval EFI_SUCCESS Always returns success. | |
**/ | |
VOID | |
EnableInternalUart( | |
VOID | |
) | |
{ | |
// | |
// Program and enable PMC Base. | |
// | |
IoWrite32 (PCI_IDX, PCI_LPC_REG(R_PCH_LPC_PMC_BASE)); | |
IoWrite32 (PCI_DAT, (PMC_BASE_ADDRESS | B_PCH_LPC_PMC_BASE_EN)); | |
// | |
// Enable COM1 for debug message output. | |
// | |
MmioAndThenOr32 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1, (UINT32) (~(B_PCH_PMC_GEN_PMCON_SUS_PWR_FLR + B_PCH_PMC_GEN_PMCON_PWROK_FLR)), BIT24); | |
// | |
// Silicon Steppings | |
// | |
if (PchStepping()>= PchB0) | |
MmioOr8 (ILB_BASE_ADDRESS + R_PCH_ILB_IRQE, (UINT8) V_PCH_ILB_IRQE_UARTIRQEN_IRQ4); | |
else | |
MmioOr8 (ILB_BASE_ADDRESS + R_PCH_ILB_IRQE, (UINT8) V_PCH_ILB_IRQE_UARTIRQEN_IRQ3); | |
MmioAnd32(IO_BASE_ADDRESS + 0x0520, (UINT32)~(0x00000187)); | |
MmioOr32 (IO_BASE_ADDRESS + 0x0520, (UINT32)0x81); // UART3_RXD-L | |
MmioAnd32(IO_BASE_ADDRESS + 0x0530, (UINT32)~(0x00000007)); | |
MmioOr32 (IO_BASE_ADDRESS + 0x0530, (UINT32)0x1); // UART3_RXD-L | |
MmioOr8 (PciD31F0RegBase + R_PCH_LPC_UART_CTRL, (UINT8) B_PCH_LPC_UART_CTRL_COM1_EN); | |
SerialPortInitialize (); | |
SerialPortWrite ("EnableInternalUart!\r\n", sizeof("EnableInternalUart!\r\n") - 1); | |
return ; | |
} |