1 /** @file 2 This PEIM will parse the hoblist from fsp and report them into pei core. 3 This file contains the main entrypoint of the PEIM. 4 5 Copyright (c) 2014, Intel Corporation. All rights reserved.<BR> 6 This program and the accompanying materials 7 are licensed and made available under the terms and conditions of the BSD License 8 which accompanies this distribution. The full text of the license may be found at 9 http://opensource.org/licenses/bsd-license.php. 10 11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13 14 **/ 15 16 17 #include <PiPei.h> 18 #include <Library\IoLib.h> 19 #include <Library\SerialPortLib.h> 20 21 #define PCI_IDX 0xCF8 22 #define PCI_DAT 0xCFC 23 24 #define PCI_LPC_BASE (0x8000F800) 25 #define PCI_LPC_REG(x) (PCI_LPC_BASE + (x)) 26 27 #define PMC_BASE_ADDRESS 0xFED03000 // PMC Memory Base Address 28 #define R_PCH_LPC_PMC_BASE 0x44 // PBASE, 32bit, 512 Bytes 29 #define B_PCH_LPC_PMC_BASE_EN BIT1 // Enable Bit 30 #define R_PCH_PMC_GEN_PMCON_1 0x20 // General PM Configuration 1 31 #define B_PCH_PMC_GEN_PMCON_SUS_PWR_FLR BIT14 // SUS Well Power Failure 32 #define B_PCH_PMC_GEN_PMCON_PWROK_FLR BIT16 // PWROK Failure 33 34 #define R_PCH_LPC_UART_CTRL 0x80 // UART Control 35 #define B_PCH_LPC_UART_CTRL_COM1_EN BIT0 // COM1 Enable 36 37 #define ILB_BASE_ADDRESS 0xFED08000 // ILB Memory Base Address 38 #define R_PCH_ILB_IRQE 0x88 // IRQ Enable Control 39 40 #define IO_BASE_ADDRESS 0xFED0C000 // IO Memory Base Address 41 42 #define V_PCH_ILB_IRQE_UARTIRQEN_IRQ3 BIT3 // UART IRQ3 Enable 43 #define V_PCH_ILB_IRQE_UARTIRQEN_IRQ4 BIT4 // UART IRQ4 Enable 44 #define PCIEX_BASE_ADDRESS 0xE0000000 45 #define PCI_EXPRESS_BASE_ADDRESS PCIEX_BASE_ADDRESS 46 #define PciD31F0RegBase PCIEX_BASE_ADDRESS + (UINT32) (31 << 15) 47 #define SB_RCBA 0xfed1c000 48 49 typedef enum { 50 PchA0 = 0, 51 PchA1 = 1, 52 PchB0 = 2, 53 PchB1 = 3, 54 PchB2 = 4, 55 PchB3 = 5, 56 PchC0 = 6, 57 PchSteppingMax 58 } PCH_STEPPING; 59 60 #define MmPciAddress( Segment, Bus, Device, Function, Register ) \ 61 ( (UINTN)PCI_EXPRESS_BASE_ADDRESS + \ 62 (UINTN)(Bus << 20) + \ 63 (UINTN)(Device << 15) + \ 64 (UINTN)(Function << 12) + \ 65 (UINTN)(Register) \ 66 ) 67 68 #define DEFAULT_PCI_BUS_NUMBER_PCH 0 69 #define PCI_DEVICE_NUMBER_PCH_LPC 31 70 #define PCI_FUNCTION_NUMBER_PCH_LPC 0 71 72 #define R_PCH_LPC_RID_CC 0x08 // Revision ID & Class Code 73 74 #define V_PCH_LPC_RID_0 0x01 // A0 Stepping (17 x 17) 75 #define V_PCH_LPC_RID_1 0x02 // A0 Stepping (25 x 27) 76 #define V_PCH_LPC_RID_2 0x03 // A1 Stepping (17 x 17) 77 #define V_PCH_LPC_RID_3 0x04 // A1 Stepping (25 x 27) 78 #define V_PCH_LPC_RID_4 0x05 // B0 Stepping (17 x 17) 79 #define V_PCH_LPC_RID_5 0x06 // B0 Stepping (25 x 27) 80 #define V_PCH_LPC_RID_6 0x07 // B1 Stepping (17 x 17) 81 #define V_PCH_LPC_RID_7 0x08 // B1 Stepping (25 x 27) 82 #define V_PCH_LPC_RID_8 0x09 // B2 Stepping (17 x 17) 83 #define V_PCH_LPC_RID_9 0x0A // B2 Stepping (25 x 27) 84 #define V_PCH_LPC_RID_A 0x0B // B3 Stepping (17 x 17) 85 #define V_PCH_LPC_RID_B 0x0C // B3 Stepping (25 x 27) 86 #define V_PCH_LPC_RID_C 0x0D // C0 Stepping (17 x 17) 87 #define V_PCH_LPC_RID_D 0x0E // C0 Stepping (25 x 27) 88 89 /** 90 Return Pch stepping type 91 92 @param[in] None 93 94 @retval PCH_STEPPING Pch stepping type 95 96 **/ 97 PCH_STEPPING 98 EFIAPI 99 PchStepping ( 100 VOID 101 ) 102 { 103 UINT8 RevId; 104 105 RevId = MmioRead8 ( 106 MmPciAddress (0, 107 DEFAULT_PCI_BUS_NUMBER_PCH, 108 PCI_DEVICE_NUMBER_PCH_LPC, 109 PCI_FUNCTION_NUMBER_PCH_LPC, 110 R_PCH_LPC_RID_CC) 111 ); 112 113 switch (RevId) { 114 case V_PCH_LPC_RID_0: 115 case V_PCH_LPC_RID_1: 116 return PchA0; 117 break; 118 119 case V_PCH_LPC_RID_2: 120 case V_PCH_LPC_RID_3: 121 return PchA1; 122 break; 123 124 case V_PCH_LPC_RID_4: 125 case V_PCH_LPC_RID_5: 126 return PchB0; 127 break; 128 129 case V_PCH_LPC_RID_6: 130 case V_PCH_LPC_RID_7: 131 return PchB1; 132 break; 133 134 case V_PCH_LPC_RID_8: 135 case V_PCH_LPC_RID_9: 136 return PchB2; 137 break; 138 139 case V_PCH_LPC_RID_A: 140 case V_PCH_LPC_RID_B: 141 return PchB3; 142 break; 143 144 case V_PCH_LPC_RID_C: 145 case V_PCH_LPC_RID_D: 146 return PchC0; 147 break; 148 149 default: 150 return PchSteppingMax; 151 break; 152 153 } 154 } 155 156 /** 157 Enable legacy decoding on ICH6 158 159 @param[in] none 160 161 @retval EFI_SUCCESS Always returns success. 162 163 **/ 164 VOID 165 EnableInternalUart( 166 VOID 167 ) 168 { 169 170 // 171 // Program and enable PMC Base. 172 // 173 IoWrite32 (PCI_IDX, PCI_LPC_REG(R_PCH_LPC_PMC_BASE)); 174 IoWrite32 (PCI_DAT, (PMC_BASE_ADDRESS | B_PCH_LPC_PMC_BASE_EN)); 175 176 // 177 // Enable COM1 for debug message output. 178 // 179 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); 180 181 // 182 // Silicon Steppings 183 // 184 if (PchStepping()>= PchB0) 185 MmioOr8 (ILB_BASE_ADDRESS + R_PCH_ILB_IRQE, (UINT8) V_PCH_ILB_IRQE_UARTIRQEN_IRQ4); 186 else 187 MmioOr8 (ILB_BASE_ADDRESS + R_PCH_ILB_IRQE, (UINT8) V_PCH_ILB_IRQE_UARTIRQEN_IRQ3); 188 MmioAnd32(IO_BASE_ADDRESS + 0x0520, (UINT32)~(0x00000187)); 189 MmioOr32 (IO_BASE_ADDRESS + 0x0520, (UINT32)0x81); // UART3_RXD-L 190 MmioAnd32(IO_BASE_ADDRESS + 0x0530, (UINT32)~(0x00000007)); 191 MmioOr32 (IO_BASE_ADDRESS + 0x0530, (UINT32)0x1); // UART3_RXD-L 192 MmioOr8 (PciD31F0RegBase + R_PCH_LPC_UART_CTRL, (UINT8) B_PCH_LPC_UART_CTRL_COM1_EN); 193 194 SerialPortInitialize (); 195 SerialPortWrite ("EnableInternalUart!\r\n", sizeof("EnableInternalUart!\r\n") - 1); 196 197 return ; 198 } 199