1 /*++ 2 3 Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR> 4 This program and the accompanying materials 5 are licensed and made available under the terms and conditions of the BSD License 6 which accompanies this distribution. The full text of the license may be found at 7 http://opensource.org/licenses/bsd-license.php 8 9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 12 Module Name: 13 14 misc.c 15 16 Abstract: 17 18 --*/ 19 20 #include "Tiano.h" 21 #include "pei.h" 22 #include "cpuio.h" 23 #include EFI_PPI_CONSUMER (PciCfg) 24 #include EFI_PPI_CONSUMER (PciCfg2) 25 #include EFI_PROTOCOL_CONSUMER (PciRootBridgeIo) 26 27 // 28 // Modular variable used by common libiary in PEI phase 29 // 30 EFI_GUID mPeiCpuIoPpiGuid = PEI_CPU_IO_PPI_GUID; 31 #if (PI_SPECIFICATION_VERSION < 0x00010000) 32 EFI_GUID mPeiPciCfgPpiGuid = PEI_PCI_CFG_PPI_GUID; 33 PEI_PCI_CFG_PPI *PciCfgPpi = NULL; 34 #else 35 EFI_GUID mPeiPciCfgPpiGuid = EFI_PEI_PCI_CFG2_PPI_GUID; 36 EFI_PEI_PCI_CFG2_PPI *PciCfgPpi = NULL; 37 #endif 38 EFI_PEI_SERVICES **mPeiServices = NULL; 39 PEI_CPU_IO_PPI *CpuIoPpi = NULL; 40 41 // 42 // Modular variable used by common libiary in DXE phase 43 // 44 EFI_SYSTEM_TABLE *mST = NULL; 45 EFI_BOOT_SERVICES *mBS = NULL; 46 EFI_RUNTIME_SERVICES *mRT = NULL; 47 48 EFI_STATUS 49 EfiInitializeCommonDriverLib ( 50 IN EFI_HANDLE ImageHandle, 51 IN VOID *SystemTable 52 ) 53 /*++ 54 55 Routine Description: 56 57 Initialize lib function calling phase: PEI or DXE 58 59 Arguments: 60 61 ImageHandle - The firmware allocated handle for the EFI image. 62 63 SystemTable - A pointer to the EFI System Table. 64 65 Returns: 66 67 EFI_STATUS always returns EFI_SUCCESS 68 69 --*/ 70 { 71 mPeiServices = NULL; 72 CpuIoPpi = NULL; 73 PciCfgPpi = NULL; 74 75 if (ImageHandle == NULL) { 76 // 77 // The function is called in PEI phase, use PEI interfaces 78 // 79 mPeiServices = (EFI_PEI_SERVICES **) SystemTable; 80 ASSERT (mPeiServices == NULL); 81 82 CpuIoPpi = (**mPeiServices).CpuIo; 83 PciCfgPpi = (**mPeiServices).PciCfg; 84 85 } else { 86 // 87 // ImageHandle is not NULL. The function is called in DXE phase 88 // 89 mST = SystemTable; 90 ASSERT (mST != NULL); 91 92 mBS = mST->BootServices; 93 mRT = mST->RuntimeServices; 94 ASSERT (mBS != NULL); 95 ASSERT (mRT != NULL); 96 97 // 98 // Should be at EFI_D_INFO, but lets us know things are running 99 // 100 DEBUG ((EFI_D_INFO, "EfiInitializeCommonDriverLib: Started in DXE\n")); 101 return EFI_SUCCESS; 102 } 103 104 return EFI_SUCCESS; 105 } 106 107 108 EFI_STATUS 109 EfiCommonIoWrite ( 110 IN UINT8 Width, 111 IN UINTN Address, 112 IN UINTN Count, 113 IN OUT VOID *Buffer 114 ) 115 /*++ 116 117 Routine Description: 118 119 Io write operation. 120 121 Arguments: 122 123 Width - Width of write operation 124 Address - Start IO address to write 125 Count - Write count 126 Buffer - Buffer to write to the address 127 128 Returns: 129 130 Status code 131 132 --*/ 133 { 134 EFI_STATUS Status; 135 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RootBridgeIo; 136 137 if (mPeiServices != NULL) { 138 // 139 // The function is called in PEI phase, use PEI interfaces 140 // 141 Status = CpuIoPpi->Io.Write ( 142 mPeiServices, 143 CpuIoPpi, 144 Width, 145 Address, 146 Count, 147 Buffer 148 ); 149 } else { 150 // 151 // The function is called in DXE phase 152 // 153 Status = mBS->LocateProtocol ( 154 &gEfiPciRootBridgeIoProtocolGuid, 155 NULL, 156 (VOID **) &RootBridgeIo 157 ); 158 if (EFI_ERROR (Status)) { 159 return Status; 160 } 161 162 Status = RootBridgeIo->Io.Write (RootBridgeIo, Width, Address, Count, Buffer); 163 } 164 165 return Status; 166 } 167 168 169 EFI_STATUS 170 EfiCommonIoRead ( 171 IN UINT8 Width, 172 IN UINTN Address, 173 IN UINTN Count, 174 IN OUT VOID *Buffer 175 ) 176 /*++ 177 178 Routine Description: 179 180 Io read operation. 181 182 Arguments: 183 184 Width - Width of read operation 185 Address - Start IO address to read 186 Count - Read count 187 Buffer - Buffer to store result 188 189 Returns: 190 191 Status code 192 193 --*/ 194 { 195 EFI_STATUS Status; 196 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RootBridgeIo; 197 198 if (mPeiServices != NULL) { 199 // 200 // The function is called in PEI phase, use PEI interfaces 201 // 202 Status = CpuIoPpi->Io.Read ( 203 mPeiServices, 204 CpuIoPpi, 205 Width, 206 Address, 207 Count, 208 Buffer 209 ); 210 } else { 211 // 212 // The function is called in DXE phase 213 // 214 Status = mBS->LocateProtocol ( 215 &gEfiPciRootBridgeIoProtocolGuid, 216 NULL, 217 (VOID **) &RootBridgeIo 218 ); 219 if (EFI_ERROR (Status)) { 220 return Status; 221 } 222 223 Status = RootBridgeIo->Io.Read (RootBridgeIo, Width, Address, Count, Buffer); 224 } 225 226 return Status; 227 } 228 229 230 EFI_STATUS 231 EfiCommonPciWrite ( 232 IN UINT8 Width, 233 IN UINT64 Address, 234 IN UINTN Count, 235 IN OUT VOID *Buffer 236 ) 237 /*++ 238 239 Routine Description: 240 241 Pci write operation 242 243 Arguments: 244 245 Width - Width of PCI write 246 Address - PCI address to write 247 Count - Write count 248 Buffer - Buffer to write to the address 249 250 Returns: 251 252 Status code 253 254 --*/ 255 { 256 EFI_STATUS Status; 257 UINTN Index; 258 UINT8 *Buffer8; 259 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RootBridgeIo; 260 261 if (mPeiServices != NULL) { 262 // 263 // The function is called in PEI phase, use PEI interfaces 264 // 265 Buffer8 = Buffer; 266 for (Index = 0; Index < Count; Index++) { 267 Status = PciCfgPpi->Write ( 268 mPeiServices, 269 PciCfgPpi, 270 Width, 271 Address, 272 Buffer8 273 ); 274 275 if (EFI_ERROR (Status)) { 276 return Status; 277 } 278 279 Buffer8 += Width; 280 } 281 282 } else { 283 // 284 // The function is called in DXE phase 285 // 286 Status = mBS->LocateProtocol ( 287 &gEfiPciRootBridgeIoProtocolGuid, 288 NULL, 289 (VOID **) &RootBridgeIo 290 ); 291 if (EFI_ERROR (Status)) { 292 return Status; 293 } 294 295 Status = RootBridgeIo->Pci.Write ( 296 RootBridgeIo, 297 Width, 298 Address, 299 Count, 300 Buffer 301 ); 302 } 303 304 return EFI_SUCCESS; 305 } 306 307 EFI_STATUS 308 EfiCommonPciRead ( 309 IN UINT8 Width, 310 IN UINT64 Address, 311 IN UINTN Count, 312 IN OUT VOID *Buffer 313 ) 314 /*++ 315 316 Routine Description: 317 318 Pci read operation 319 320 Arguments: 321 322 Width - Width of PCI read 323 Address - PCI address to read 324 Count - Read count 325 Buffer - Output buffer for the read 326 327 Returns: 328 329 Status code 330 331 --*/ 332 { 333 EFI_STATUS Status; 334 UINTN Index; 335 UINT8 *Buffer8; 336 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RootBridgeIo; 337 338 if (mPeiServices != NULL) { 339 // 340 // The function is called in PEI phase, use PEI interfaces 341 // 342 Buffer8 = Buffer; 343 for (Index = 0; Index < Count; Index++) { 344 Status = PciCfgPpi->Read ( 345 mPeiServices, 346 PciCfgPpi, 347 Width, 348 Address, 349 Buffer8 350 ); 351 352 if (EFI_ERROR (Status)) { 353 return Status; 354 } 355 356 Buffer8 += Width; 357 } 358 359 } else { 360 // 361 // The function is called in DXE phase 362 // 363 Status = mBS->LocateProtocol ( 364 &gEfiPciRootBridgeIoProtocolGuid, 365 NULL, 366 (VOID **) &RootBridgeIo 367 ); 368 if (EFI_ERROR (Status)) { 369 return Status; 370 } 371 372 Status = RootBridgeIo->Pci.Read ( 373 RootBridgeIo, 374 Width, 375 Address, 376 Count, 377 Buffer 378 ); 379 } 380 381 return EFI_SUCCESS; 382 } 383