pcirootbridgeio.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,750 行 · 第 1/4 页
C
1,750 行
/*++
Copyright (c) 2004 - 2005, 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:
PciRootBridgeIo.c
Abstract:
PCI Root Bridge Io Protocol producer
--*/
#include "PciRootBridge.h"
#include "Pci22.h"
typedef struct {
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR SpaceDesp[TypeMax];
EFI_ACPI_END_TAG_DESCRIPTOR EndDesp;
} RESOURCE_CONFIGURATION;
RESOURCE_CONFIGURATION mConfiguration = {
{{0x8A, 0x2B, 1, 0, 0, 0, 0, 0, 0, 0},
{0x8A, 0x2B, 0, 0, 0, 32, 0, 0, 0, 0},
{0x8A, 0x2B, 0, 0, 6, 32, 0, 0, 0, 0},
{0x8A, 0x2B, 0, 0, 0, 64, 0, 0, 0, 0},
{0x8A, 0x2B, 0, 0, 6, 64, 0, 0, 0, 0},
{0x8A, 0x2B, 2, 0, 0, 0, 0, 0, 0, 0}},
{0x79, 0}
};
//
// Protocol Member Function Prototypes
//
EFI_STATUS
EFIAPI
RootBridgeIoPollMem (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
IN UINT64 Address,
IN UINT64 Mask,
IN UINT64 Value,
IN UINT64 Delay,
OUT UINT64 *Result
);
EFI_STATUS
EFIAPI
RootBridgeIoPollIo (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
IN UINT64 Address,
IN UINT64 Mask,
IN UINT64 Value,
IN UINT64 Delay,
OUT UINT64 *Result
);
EFI_STATUS
EFIAPI
RootBridgeIoMemRead (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
IN UINT64 Address,
IN UINTN Count,
IN OUT VOID *Buffer
);
EFI_STATUS
EFIAPI
RootBridgeIoMemWrite (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
IN UINT64 Address,
IN UINTN Count,
IN OUT VOID *Buffer
);
EFI_STATUS
EFIAPI
RootBridgeIoIoRead (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
IN UINT64 UserAddress,
IN UINTN Count,
IN OUT VOID *UserBuffer
);
EFI_STATUS
EFIAPI
RootBridgeIoIoWrite (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
IN UINT64 UserAddress,
IN UINTN Count,
IN OUT VOID *UserBuffer
);
EFI_STATUS
EFIAPI
RootBridgeIoCopyMem (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
IN UINT64 DestAddress,
IN UINT64 SrcAddress,
IN UINTN Count
);
EFI_STATUS
EFIAPI
RootBridgeIoPciRead (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
IN UINT64 Address,
IN UINTN Count,
IN OUT VOID *Buffer
);
EFI_STATUS
EFIAPI
RootBridgeIoPciWrite (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
IN UINT64 Address,
IN UINTN Count,
IN OUT VOID *Buffer
);
EFI_STATUS
EFIAPI
RootBridgeIoMap (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation,
IN VOID *HostAddress,
IN OUT UINTN *NumberOfBytes,
OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
OUT VOID **Mapping
);
EFI_STATUS
EFIAPI
RootBridgeIoUnmap (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN VOID *Mapping
);
EFI_STATUS
EFIAPI
RootBridgeIoAllocateBuffer (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN EFI_ALLOCATE_TYPE Type,
IN EFI_MEMORY_TYPE MemoryType,
IN UINTN Pages,
OUT VOID **HostAddress,
IN UINT64 Attributes
);
EFI_STATUS
EFIAPI
RootBridgeIoFreeBuffer (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN UINTN Pages,
OUT VOID *HostAddress
);
EFI_STATUS
EFIAPI
RootBridgeIoFlush (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This
);
EFI_STATUS
EFIAPI
RootBridgeIoGetAttributes (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
OUT UINT64 *Supported,
OUT UINT64 *Attributes
);
EFI_STATUS
EFIAPI
RootBridgeIoSetAttributes (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN UINT64 Attributes,
IN OUT UINT64 *ResourceBase,
IN OUT UINT64 *ResourceLength
);
EFI_STATUS
EFIAPI
RootBridgeIoConfiguration (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
OUT VOID **Resources
);
//
// Sub Function Prototypes
//
typedef union {
UINT8 VOLATILE *buf;
UINT8 VOLATILE *ui8;
UINT16 VOLATILE *ui16;
UINT32 VOLATILE *ui32;
UINT64 VOLATILE *ui64;
UINTN VOLATILE ui;
} PTR;
STATIC
EFI_STATUS
RootBridgeIoPciRW (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN BOOLEAN Write,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
IN UINT64 UserAddress,
IN UINTN Count,
IN OUT VOID *UserBuffer
);
//
// Pci Root Bridge Io Module Variables
//
EFI_METRONOME_ARCH_PROTOCOL *mMetronome;
EFI_CPU_IO_PROTOCOL *mCpuIo;
EFI_STATUS
RootBridgeConstructor (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *Protocol,
IN EFI_HANDLE HostBridgeHandle,
IN UINT64 Attri,
IN PCI_ROOT_BRIDGE_RESOURCE_APPETURE ResAppeture
)
/*++
Routine Description:
Construct the Pci Root Bridge Io protocol
Arguments:
Protocol - protocol to initialize
Returns:
None
--*/
// TODO: HostBridgeHandle - add argument and description to function comment
// TODO: Attri - add argument and description to function comment
// TODO: ResAppeture - add argument and description to function comment
// TODO: EFI_SUCCESS - add return value to function comment
{
EFI_STATUS Status;
PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
PCI_RESOURCE_TYPE Index;
PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (Protocol);
//
// The host to pci bridge, the host memory and io addresses are
// direct mapped to pci addresses, so no need translate, set bases to 0.
//
PrivateData->MemBase = ResAppeture.MemBase;
PrivateData->IoBase = ResAppeture.IoBase;
//
// The host bridge only supports 32bit addressing for memory
// and standard IA32 16bit io
//
PrivateData->MemLimit = ResAppeture.MemLimit;
PrivateData->IoLimit = ResAppeture.IoLimit;
//
// Bus Appeture for this Root Bridge (Possible Range)
//
PrivateData->BusBase = ResAppeture.BusBase;
PrivateData->BusLimit = ResAppeture.BusLimit;
//
// Specific for ea815 chipset
//
for (Index = TypeIo; Index < TypeMax; Index++) {
PrivateData->ResAllocNode[Index].Type = Index;
PrivateData->ResAllocNode[Index].Base = 0;
PrivateData->ResAllocNode[Index].Length = 0;
PrivateData->ResAllocNode[Index].Status = ResNone;
}
EfiInitializeLock (&PrivateData->PciLock, EFI_TPL_HIGH_LEVEL);
PrivateData->PciAddress = 0xCF8;
PrivateData->PciData = 0xCFC;
PrivateData->RootBridgeAttrib = Attri;
PrivateData->Attributes = 0;
PrivateData->Supports = EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO |
EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO |
EFI_PCI_ATTRIBUTE_ISA_IO |
EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO |
EFI_PCI_ATTRIBUTE_VGA_MEMORY |
EFI_PCI_ATTRIBUTE_VGA_IO;
Protocol->ParentHandle = HostBridgeHandle;
Protocol->PollMem = RootBridgeIoPollMem;
Protocol->PollIo = RootBridgeIoPollIo;
Protocol->Mem.Read = RootBridgeIoMemRead;
Protocol->Mem.Write = RootBridgeIoMemWrite;
Protocol->Io.Read = RootBridgeIoIoRead;
Protocol->Io.Write = RootBridgeIoIoWrite;
Protocol->CopyMem = RootBridgeIoCopyMem;
Protocol->Pci.Read = RootBridgeIoPciRead;
Protocol->Pci.Write = RootBridgeIoPciWrite;
Protocol->Map = RootBridgeIoMap;
Protocol->Unmap = RootBridgeIoUnmap;
Protocol->AllocateBuffer = RootBridgeIoAllocateBuffer;
Protocol->FreeBuffer = RootBridgeIoFreeBuffer;
Protocol->Flush = RootBridgeIoFlush;
Protocol->GetAttributes = RootBridgeIoGetAttributes;
Protocol->SetAttributes = RootBridgeIoSetAttributes;
Protocol->Configuration = RootBridgeIoConfiguration;
Protocol->SegmentNumber = 0;
Status = gBS->LocateProtocol (&gEfiMetronomeArchProtocolGuid, NULL, &mMetronome);
ASSERT_EFI_ERROR (Status);
Status = gBS->LocateProtocol (&gEfiCpuIoProtocolGuid, NULL, &mCpuIo);
ASSERT_EFI_ERROR (Status);
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
RootBridgeIoPollMem (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
IN UINT64 Address,
IN UINT64 Mask,
IN UINT64 Value,
IN UINT64 Delay,
OUT UINT64 *Result
)
/*++
Routine Description:
Memory Poll
Arguments:
Returns:
--*/
// TODO: This - add argument and description to function comment
// TODO: Width - add argument and description to function comment
// TODO: Address - add argument and description to function comment
// TODO: Mask - add argument and description to function comment
// TODO: Value - add argument and description to function comment
// TODO: Delay - add argument and description to function comment
// TODO: Result - add argument and description to function comment
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
// TODO: EFI_SUCCESS - add return value to function comment
// TODO: EFI_SUCCESS - add return value to function comment
// TODO: EFI_SUCCESS - add return value to function comment
// TODO: EFI_TIMEOUT - add return value to function comment
{
EFI_STATUS Status;
UINT64 NumberOfTicks;
UINTN Remainder;
if (Result == NULL) {
return EFI_INVALID_PARAMETER;
}
if (Width < 0 || Width > EfiPciWidthUint64) {
return EFI_INVALID_PARAMETER;
}
//
// No matter what, always do a single poll.
//
Status = This->Mem.Read (This, Width, Address, 1, Result);
if (EFI_ERROR (Status)) {
return Status;
}
if ((*Result & Mask) == Value) {
return EFI_SUCCESS;
}
if (Delay == 0) {
return EFI_SUCCESS;
} else {
//
// Determine the proper # of metronome ticks to wait for polling the
// location. The nuber of ticks is Roundup (Delay / mMetronome->TickPeriod)+1
// The "+1" to account for the possibility of the first tick being short
// because we started in the middle of a tick.
//
NumberOfTicks = DivU64x32 (Delay, mMetronome->TickPeriod, &Remainder);
if (Remainder != 0) {
NumberOfTicks += 1;
}
NumberOfTicks += 1;
while (NumberOfTicks) {
mMetronome->WaitForTick (mMetronome, 1);
Status = This->Mem.Read (This, Width, Address, 1, Result);
if (EFI_ERROR (Status)) {
return Status;
}
if ((*Result & Mask) == Value) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?