pcihostbridge.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,244 行 · 第 1/3 页
C
1,244 行
/*++
Copyright (c) 2004 - 2006, 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:
PciHostBridge.c
Abstract:
Pci Host Bridge driver:
Adapted to work under the NT32 environment and will thunk to the appropriate
Kernel driver services if installed.
Revision History
--*/
#include "PciHostBridge.h"
#include "PciRootBridge.h"
#include "DeviceIo.h"
#include "Acpi.h"
#define RES_IO_BASE 0x1000
#define RES_MEM_BASE 0x80000000
//
// Support 64 K IO space
//
#define RES_IO_LIMIT 0xFFFF
//
// Supports 4G address space
//
#define RES_MEM_LIMIT 0xBFFFFFFF
//
// Hard code: Root Bridge Number within the host bridge
// Root Bridge's attribute
// Root Bridge's device path
// Root Bridge's resource appeture
//
static UINTN mRootBridgeNumber[1] = {
1
};
static UINT64 mRootBridgeAttribute[1][1] = {
EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM
};
static EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath[1][1] = {
{
ACPI_DEVICE_PATH,
ACPI_DP,
(UINT8) (sizeof (ACPI_HID_DEVICE_PATH)),
(UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8),
EISA_PNP_ID(0x0A03),
0,
END_DEVICE_PATH_TYPE,
END_ENTIRE_DEVICE_PATH_SUBTYPE,
END_DEVICE_PATH_LENGTH,
0
}
};
static PCI_ROOT_BRIDGE_RESOURCE_APPETURE mResAppeture[1][1] = {
{0, 255, 0, 0xffffffff, 0, 1 << 16}
};
static EFI_HANDLE mDriverImageHandle;
//
// Implementation
//
EFI_STATUS
InitializePciHostBridge (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
/*++
Routine Description:
Entry point of this driver
Arguments:
ImageHandle -
SystemTable -
Returns:
--*/
// TODO: EFI_DEVICE_ERROR - add return value to function comment
// TODO: EFI_DEVICE_ERROR - add return value to function comment
// TODO: EFI_SUCCESS - add return value to function comment
{
EFI_STATUS Status;
UINTN Loop1;
UINTN Loop2;
PCI_HOST_BRIDGE_INSTANCE *HostBridge;
PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
DxeInitializeDriverLib (ImageHandle, SystemTable);
mDriverImageHandle = ImageHandle;
//
// Support one Host Bridge (one Root Bridge in this Host Bridge)
//
//
// Create Host Bridge Device Handle
//
for (Loop1 = 0; Loop1 < HOST_BRIDGE_NUMBER; Loop1++) {
Status = gBS->AllocatePool (
EfiBootServicesData,
sizeof (PCI_HOST_BRIDGE_INSTANCE),
&HostBridge
);
ASSERT (!EFI_ERROR (Status));
HostBridge->Signature = PCI_HOST_BRIDGE_SIGNATURE;
HostBridge->RootBridgeNumber = mRootBridgeNumber[Loop1];
HostBridge->ResourceSubmited = FALSE;
HostBridge->CanRestarted = TRUE;
HostBridge->ResAlloc.NotifyPhase = NotifyPhase;
HostBridge->ResAlloc.GetNextRootBridge = GetNextRootBridge;
HostBridge->ResAlloc.GetAllocAttributes = GetAttributes;
HostBridge->ResAlloc.StartBusEnumeration = StartBusEnumeration;
HostBridge->ResAlloc.SetBusNumbers = SetBusNumbers;
HostBridge->ResAlloc.SubmitResources = SubmitResources;
HostBridge->ResAlloc.GetProposedResources = GetProposedResources;
HostBridge->ResAlloc.PreprocessController = PreprocessController;
HostBridge->HostBridgeHandle = NULL;
Status = gBS->InstallProtocolInterface (
&HostBridge->HostBridgeHandle,
&gEfiPciHostBridgeResourceAllocationProtocolGuid,
EFI_NATIVE_INTERFACE,
&HostBridge->ResAlloc
);
if (EFI_ERROR (Status)) {
gBS->FreePool (HostBridge);
return EFI_DEVICE_ERROR;
}
//
// Create Root Bridge Device Handle in this Host Bridge
//
InitializeListHead (&HostBridge->Head);
for (Loop2 = 0; Loop2 < HostBridge->RootBridgeNumber; Loop2++) {
Status = gBS->AllocatePool (
EfiBootServicesData,
sizeof (PCI_ROOT_BRIDGE_INSTANCE),
&PrivateData
);
ASSERT (!EFI_ERROR (Status));
PrivateData->Signature = PCI_ROOT_BRIDGE_SIGNATURE;
PrivateData->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) &mEfiPciRootBridgeDevicePath[Loop1][Loop2];
RootBridgeConstructor (
&PrivateData->Io,
HostBridge->HostBridgeHandle,
mRootBridgeAttribute[Loop1][Loop2],
mResAppeture[Loop1][Loop2]
);
PrivateData->Handle = NULL;
Status = gBS->InstallMultipleProtocolInterfaces (
&PrivateData->Handle,
&gEfiDevicePathProtocolGuid,
PrivateData->DevicePath,
&gEfiPciRootBridgeIoProtocolGuid,
&PrivateData->Io,
NULL
);
if (EFI_ERROR (Status)) {
gBS->FreePool (PrivateData);
return EFI_DEVICE_ERROR;
}
InsertTailList (&HostBridge->Head, &PrivateData->Link);
}
//
// end for
//
}
//
// end for
//
Status = gDS->AddIoSpace (
EfiGcdIoTypeIo,
RES_IO_BASE,
RES_IO_LIMIT - RES_IO_BASE + 1
);
Status = gDS->AddMemorySpace (
EfiGcdMemoryTypeMemoryMappedIo,
RES_MEM_BASE,
RES_MEM_LIMIT - RES_MEM_BASE + 1,
0
);
DeviceIoConstructor ();
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
NotifyPhase (
IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase
)
/*++
Routine Description:
Enter a certain phase of the PCI enumeration process
Arguments:
This -- The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance
Phase -- The phase during enumeration
Returns:
--*/
// TODO: EFI_NOT_READY - 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_NOT_READY - 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
{
PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;
PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;
PCI_RESOURCE_TYPE Index;
EFI_LIST_ENTRY *List;
EFI_PHYSICAL_ADDRESS BaseAddress;
UINT64 AddrLen;
UINTN BitsOfAlignment;
UINT64 Alignment;
EFI_STATUS Status;
EFI_STATUS ReturnStatus;
HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
switch (Phase) {
case EfiPciHostBridgeBeginEnumeration:
if (HostBridgeInstance->CanRestarted) {
//
// Reset the Each Root Bridge
//
List = HostBridgeInstance->Head.ForwardLink;
while (List != &HostBridgeInstance->Head) {
RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
for (Index = TypeIo; Index < TypeMax; Index++) {
RootBridgeInstance->ResAllocNode[Index].Type = Index;
RootBridgeInstance->ResAllocNode[Index].Base = 0;
RootBridgeInstance->ResAllocNode[Index].Length = 0;
RootBridgeInstance->ResAllocNode[Index].Status = ResNone;
}
List = List->ForwardLink;
}
HostBridgeInstance->ResourceSubmited = FALSE;
HostBridgeInstance->CanRestarted = TRUE;
} else {
//
// Can not restart
//
return EFI_NOT_READY;
}
break;
case EfiPciHostBridgeBeginBusAllocation:
//
// No specific action is required here, can perform any chipset specific programing
//
HostBridgeInstance->CanRestarted = FALSE;
return EFI_SUCCESS;
break;
case EfiPciHostBridgeEndBusAllocation:
//
// No specific action is required here, can perform any chipset specific programing
//
return EFI_SUCCESS;
break;
case EfiPciHostBridgeBeginResourceAllocation:
//
// No specific action is required here, can perform any chipset specific programing
//
return EFI_SUCCESS;
break;
case EfiPciHostBridgeAllocateResources:
ReturnStatus = EFI_SUCCESS;
if (HostBridgeInstance->ResourceSubmited) {
//
// Take care of the resource dependencies between the root bridges
//
List = HostBridgeInstance->Head.ForwardLink;
while (List != &HostBridgeInstance->Head) {
RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
for (Index = TypeIo; Index < TypeBus; Index++) {
if (RootBridgeInstance->ResAllocNode[Index].Status != ResNone) {
AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;
Alignment = RootBridgeInstance->ResAllocNode[Index].Alignment;
//
// Get the number of '1' in Alignment.
//
for (BitsOfAlignment = 0; Alignment != 0; BitsOfAlignment++) {
Alignment = RShiftU64 (Alignment, 1);
}
switch (Index) {
case TypeIo:
//
// It is impossible to align 0xFFFF for IO16
// So clear it
//
if (BitsOfAlignment >= 16) {
BitsOfAlignment = 0;
}
Status = gDS->AllocateIoSpace (
EfiGcdAllocateAnySearchBottomUp,
EfiGcdIoTypeIo,
BitsOfAlignment,
AddrLen,
&BaseAddress,
mDriverImageHandle,
NULL
);
if (!EFI_ERROR (Status)) {
RootBridgeInstance->ResAllocNode[Index].Base = (UINTN) BaseAddress;
RootBridgeInstance->ResAllocNode[Index].Status = ResAllocated;
} else {
ReturnStatus = Status;
if (Status != EFI_OUT_OF_RESOURCES) {
RootBridgeInstance->ResAllocNode[Index].Length = 0;
}
}
break;
case TypeMem32:
//
// It is impossible to align 0xFFFFFFFF for Mem32
// So clear it
//
if (BitsOfAlignment >= 32) {
BitsOfAlignment = 0;
}
Status = gDS->AllocateMemorySpace (
EfiGcdAllocateAnySearchBottomUp,
EfiGcdMemoryTypeMemoryMappedIo,
BitsOfAlignment,
AddrLen,
&BaseAddress,
mDriverImageHandle,
NULL
);
if (!EFI_ERROR (Status)) {
RootBridgeInstance->ResAllocNode[Index].Base = (UINTN) BaseAddress;
RootBridgeInstance->ResAllocNode[Index].Status = ResAllocated;
} else {
ReturnStatus = Status;
if (Status != EFI_OUT_OF_RESOURCES) {
RootBridgeInstance->ResAllocNode[Index].Length = 0;
}
}
break;
case TypePMem32:
case TypeMem64:
case TypePMem64:
ReturnStatus = EFI_ABORTED;
break;
}
//
// end switch
//
}
}
List = List->ForwardLink;
}
return ReturnStatus;
} else {
return EFI_NOT_READY;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?