mirror of https://github.com/acidanthera/audk.git
385 lines
8.9 KiB
C
385 lines
8.9 KiB
C
/*++
|
|
|
|
Copyright (c) 2004, Intel Corporation
|
|
All rights reserved. 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.
|
|
|
|
Module Name:
|
|
|
|
misc.c
|
|
|
|
Abstract:
|
|
|
|
--*/
|
|
|
|
#include "Tiano.h"
|
|
#include "pei.h"
|
|
#include "cpuio.h"
|
|
#include "pcicfg.h"
|
|
#include "pcicfg2.h"
|
|
#include EFI_PROTOCOL_CONSUMER (PciRootBridgeIo)
|
|
|
|
//
|
|
// Modular variable used by common libiary in PEI phase
|
|
//
|
|
EFI_GUID mPeiCpuIoPpiGuid = PEI_CPU_IO_PPI_GUID;
|
|
#if (PI_SPECIFICATION_VERSION < 0x00010000)
|
|
EFI_GUID mPeiPciCfgPpiGuid = PEI_PCI_CFG_PPI_GUID;
|
|
PEI_PCI_CFG_PPI *PciCfgPpi = NULL;
|
|
#else
|
|
EFI_GUID mPeiPciCfgPpiGuid = EFI_PEI_PCI_CFG2_PPI_GUID;
|
|
EFI_PEI_PCI_CFG2_PPI *PciCfgPpi = NULL;
|
|
#endif
|
|
EFI_PEI_SERVICES **mPeiServices = NULL;
|
|
PEI_CPU_IO_PPI *CpuIoPpi = NULL;
|
|
|
|
//
|
|
// Modular variable used by common libiary in DXE phase
|
|
//
|
|
EFI_SYSTEM_TABLE *mST = NULL;
|
|
EFI_BOOT_SERVICES *mBS = NULL;
|
|
EFI_RUNTIME_SERVICES *mRT = NULL;
|
|
|
|
EFI_STATUS
|
|
EfiInitializeCommonDriverLib (
|
|
IN EFI_HANDLE ImageHandle,
|
|
IN VOID *SystemTable
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Initialize lib function calling phase: PEI or DXE
|
|
|
|
Arguments:
|
|
|
|
ImageHandle - The firmware allocated handle for the EFI image.
|
|
|
|
SystemTable - A pointer to the EFI System Table.
|
|
|
|
Returns:
|
|
|
|
EFI_STATUS always returns EFI_SUCCESS
|
|
|
|
--*/
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
mPeiServices = NULL;
|
|
CpuIoPpi = NULL;
|
|
PciCfgPpi = NULL;
|
|
|
|
if (ImageHandle == NULL) {
|
|
//
|
|
// The function is called in PEI phase, use PEI interfaces
|
|
//
|
|
mPeiServices = (EFI_PEI_SERVICES **) SystemTable;
|
|
ASSERT (mPeiServices == NULL);
|
|
|
|
CpuIoPpi = (**mPeiServices).CpuIo;
|
|
PciCfgPpi = (**mPeiServices).PciCfg;
|
|
|
|
} else {
|
|
//
|
|
// ImageHandle is not NULL. The function is called in DXE phase
|
|
//
|
|
mST = SystemTable;
|
|
ASSERT (mST != NULL);
|
|
|
|
mBS = mST->BootServices;
|
|
mRT = mST->RuntimeServices;
|
|
ASSERT (mBS != NULL);
|
|
ASSERT (mRT != NULL);
|
|
|
|
//
|
|
// Should be at EFI_D_INFO, but lets us know things are running
|
|
//
|
|
DEBUG ((EFI_D_INFO, "EfiInitializeCommonDriverLib: Started in DXE\n"));
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
|
|
EFI_STATUS
|
|
EfiCommonIoWrite (
|
|
IN UINT8 Width,
|
|
IN UINTN Address,
|
|
IN UINTN Count,
|
|
IN OUT VOID *Buffer
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Io write operation.
|
|
|
|
Arguments:
|
|
|
|
Width - Width of write operation
|
|
Address - Start IO address to write
|
|
Count - Write count
|
|
Buffer - Buffer to write to the address
|
|
|
|
Returns:
|
|
|
|
Status code
|
|
|
|
--*/
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RootBridgeIo;
|
|
|
|
if (mPeiServices == NULL) {
|
|
//
|
|
// The function is called in PEI phase, use PEI interfaces
|
|
//
|
|
Status = CpuIoPpi->Io.Write (
|
|
mPeiServices,
|
|
CpuIoPpi,
|
|
Width,
|
|
Address,
|
|
Count,
|
|
Buffer
|
|
);
|
|
} else {
|
|
//
|
|
// The function is called in DXE phase
|
|
//
|
|
Status = mBS->LocateProtocol (
|
|
&gEfiPciRootBridgeIoProtocolGuid,
|
|
NULL,
|
|
(VOID **) &RootBridgeIo
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Status = RootBridgeIo->Io.Write (RootBridgeIo, Width, Address, Count, Buffer);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
EFI_STATUS
|
|
EfiCommonIoRead (
|
|
IN UINT8 Width,
|
|
IN UINTN Address,
|
|
IN UINTN Count,
|
|
IN OUT VOID *Buffer
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Io read operation.
|
|
|
|
Arguments:
|
|
|
|
Width - Width of read operation
|
|
Address - Start IO address to read
|
|
Count - Read count
|
|
Buffer - Buffer to store result
|
|
|
|
Returns:
|
|
|
|
Status code
|
|
|
|
--*/
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RootBridgeIo;
|
|
|
|
if (mPeiServices == NULL) {
|
|
//
|
|
// The function is called in PEI phase, use PEI interfaces
|
|
//
|
|
Status = CpuIoPpi->Io.Read (
|
|
mPeiServices,
|
|
CpuIoPpi,
|
|
Width,
|
|
Address,
|
|
Count,
|
|
Buffer
|
|
);
|
|
} else {
|
|
//
|
|
// The function is called in DXE phase
|
|
//
|
|
Status = mBS->LocateProtocol (
|
|
&gEfiPciRootBridgeIoProtocolGuid,
|
|
NULL,
|
|
(VOID **) &RootBridgeIo
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Status = RootBridgeIo->Io.Read (RootBridgeIo, Width, Address, Count, Buffer);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
EFI_STATUS
|
|
EfiCommonPciWrite (
|
|
IN UINT8 Width,
|
|
IN UINT64 Address,
|
|
IN UINTN Count,
|
|
IN OUT VOID *Buffer
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Pci write operation
|
|
|
|
Arguments:
|
|
|
|
Width - Width of PCI write
|
|
Address - PCI address to write
|
|
Count - Write count
|
|
Buffer - Buffer to write to the address
|
|
|
|
Returns:
|
|
|
|
Status code
|
|
|
|
--*/
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN Index;
|
|
UINT8 *Buffer8;
|
|
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RootBridgeIo;
|
|
|
|
if (mPeiServices == NULL) {
|
|
//
|
|
// The function is called in PEI phase, use PEI interfaces
|
|
//
|
|
Buffer8 = Buffer;
|
|
for (Index = 0; Index < Count; Index++) {
|
|
Status = PciCfgPpi->Write (
|
|
mPeiServices,
|
|
PciCfgPpi,
|
|
Width,
|
|
Address,
|
|
Buffer8
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Buffer8 += Width;
|
|
}
|
|
|
|
} else {
|
|
//
|
|
// The function is called in DXE phase
|
|
//
|
|
Status = mBS->LocateProtocol (
|
|
&gEfiPciRootBridgeIoProtocolGuid,
|
|
NULL,
|
|
(VOID **) &RootBridgeIo
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Status = RootBridgeIo->Pci.Write (
|
|
RootBridgeIo,
|
|
Width,
|
|
Address,
|
|
Count,
|
|
Buffer
|
|
);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EfiCommonPciRead (
|
|
IN UINT8 Width,
|
|
IN UINT64 Address,
|
|
IN UINTN Count,
|
|
IN OUT VOID *Buffer
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Pci read operation
|
|
|
|
Arguments:
|
|
|
|
Width - Width of PCI read
|
|
Address - PCI address to read
|
|
Count - Read count
|
|
Buffer - Output buffer for the read
|
|
|
|
Returns:
|
|
|
|
Status code
|
|
|
|
--*/
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN Index;
|
|
UINT8 *Buffer8;
|
|
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RootBridgeIo;
|
|
|
|
if (mPeiServices == NULL) {
|
|
//
|
|
// The function is called in PEI phase, use PEI interfaces
|
|
//
|
|
Buffer8 = Buffer;
|
|
for (Index = 0; Index < Count; Index++) {
|
|
Status = PciCfgPpi->Read (
|
|
mPeiServices,
|
|
PciCfgPpi,
|
|
Width,
|
|
Address,
|
|
Buffer8
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Buffer8 += Width;
|
|
}
|
|
|
|
} else {
|
|
//
|
|
// The function is called in DXE phase
|
|
//
|
|
Status = mBS->LocateProtocol (
|
|
&gEfiPciRootBridgeIoProtocolGuid,
|
|
NULL,
|
|
(VOID **) &RootBridgeIo
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Status = RootBridgeIo->Pci.Read (
|
|
RootBridgeIo,
|
|
Width,
|
|
Address,
|
|
Count,
|
|
Buffer
|
|
);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|