pcirootbridgeio.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,750 行 · 第 1/4 页
C
1,750 行
return EFI_SUCCESS;
}
NumberOfTicks -= 1;
}
}
return EFI_TIMEOUT;
}
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
)
/*++
Routine Description:
Io 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;
//
// No matter what, always do a single poll.
//
if (Result == NULL) {
return EFI_INVALID_PARAMETER;
}
if (Width < 0 || Width > EfiPciWidthUint64) {
return EFI_INVALID_PARAMETER;
}
Status = This->Io.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 number 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, (UINT32) mMetronome->TickPeriod, &Remainder);
if (Remainder != 0) {
NumberOfTicks += 1;
}
NumberOfTicks += 1;
while (NumberOfTicks) {
mMetronome->WaitForTick (mMetronome, 1);
Status = This->Io.Read (This, Width, Address, 1, Result);
if (EFI_ERROR (Status)) {
return Status;
}
if ((*Result & Mask) == Value) {
return EFI_SUCCESS;
}
NumberOfTicks -= 1;
}
}
return EFI_TIMEOUT;
}
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
)
/*++
Routine Description:
Memory read
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: Count - add argument and description to function comment
// TODO: Buffer - 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_INVALID_PARAMETER - add return value to function comment
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
{
PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH OldWidth;
UINTN OldCount;
UINTN AlignMask;
VOID *Buf;
VOID *ptr;
EFI_STATUS Status;
if (Buffer == NULL) {
return EFI_INVALID_PARAMETER;
}
if (Width < 0 || Width >= EfiPciWidthMaximum) {
return EFI_INVALID_PARAMETER;
}
PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
//
// Check memory access limit
//
if (Address < PrivateData->MemBase) {
return EFI_INVALID_PARAMETER;
}
OldWidth = Width;
OldCount = Count;
if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {
Count = 1;
}
Width &= 0x03;
if (Address + (1 << Width) * Count - 1 > PrivateData->MemLimit) {
return EFI_INVALID_PARAMETER;
}
AlignMask = (1 << Width) - 1;
if ((UINTN) Buffer & AlignMask) {
Status = gBS->AllocatePool (
EfiBootServicesData,
(1 << Width) * (OldCount + 1),
&Buf
);
ptr = (VOID *) (((UINTN) (((UINTN) Buf) &~(AlignMask))) + (1 << Width));
Status = mCpuIo->Mem.Read (
mCpuIo,
(EFI_CPU_IO_PROTOCOL_WIDTH) OldWidth,
Address,
OldCount,
ptr
);
EfiCopyMem (Buffer, ptr, (1 << Width) * OldCount);
gBS->FreePool (Buf);
} else {
Status = mCpuIo->Mem.Read (
mCpuIo,
(EFI_CPU_IO_PROTOCOL_WIDTH) OldWidth,
Address,
OldCount,
Buffer
);
}
return Status;
}
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
)
/*++
Routine Description:
Memory write
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: Count - add argument and description to function comment
// TODO: Buffer - 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_INVALID_PARAMETER - add return value to function comment
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
{
PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH OldWidth;
UINTN OldCount;
UINTN AlignMask;
VOID *Buf;
VOID *ptr;
EFI_STATUS Status;
if (Buffer == NULL) {
return EFI_INVALID_PARAMETER;
}
if (Width < 0 || Width >= EfiPciWidthMaximum) {
return EFI_INVALID_PARAMETER;
}
PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
//
// Check memory access limit
//
if (Address < PrivateData->MemBase) {
return EFI_INVALID_PARAMETER;
}
OldWidth = Width;
OldCount = Count;
if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {
Count = 1;
}
Width &= 0x03;
if (Address + (1 << Width) * Count - 1 > PrivateData->MemLimit) {
return EFI_INVALID_PARAMETER;
}
AlignMask = (1 << Width) - 1;
if ((UINTN) Buffer & AlignMask) {
Status = gBS->AllocatePool (
EfiBootServicesData,
(1 << Width) * (OldCount + 1),
&Buf
);
ptr = (VOID *) (((UINTN) (((UINTN) Buf) &~(AlignMask))) + (1 << Width));
EfiCopyMem (ptr, Buffer, (1 << Width) * OldCount);
Status = mCpuIo->Mem.Write (
mCpuIo,
(EFI_CPU_IO_PROTOCOL_WIDTH) OldWidth,
Address,
OldCount,
ptr
);
gBS->FreePool (Buf);
} else {
Status = mCpuIo->Mem.Write (
mCpuIo,
(EFI_CPU_IO_PROTOCOL_WIDTH) OldWidth,
Address,
OldCount,
Buffer
);
}
return Status;
}
EFI_STATUS
EFIAPI
RootBridgeIoIoRead (
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
)
/*++
Routine Description:
Io read
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: Count - add argument and description to function comment
// TODO: Buffer - 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_INVALID_PARAMETER - add return value to function comment
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
{
UINTN AlignMask;
PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH OldWidth;
UINTN OldCount;
UINTN Counter;
UINTN InStride;
UINTN OutStride;
CHAR8 Buf[16];
CHAR8 *Ptr;
CHAR8 *TempBuf;
EFI_STATUS Status;
if (Buffer == NULL) {
return EFI_INVALID_PARAMETER;
}
if (Width < 0 || Width >= EfiPciWidthMaximum) {
return EFI_INVALID_PARAMETER;
}
PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
AlignMask = (1 << (Width & 0x03)) - 1;
//
// check Io access limit
//
if (Address < PrivateData->IoBase) {
return EFI_INVALID_PARAMETER;
}
OldWidth = Width;
OldCount = Count;
if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {
Count = 1;
}
Width &= 0x03;
if (Address + (1 << Width) * Count - 1 >= PrivateData->IoLimit) {
return EFI_INVALID_PARAMETER;
}
if (Address & AlignMask) {
return EFI_INVALID_PARAMETER;
}
Counter = OldCount;
TempBuf = (CHAR8 *) Buffer;
Status = EFI_SUCCESS;
if ((UINTN) Buffer & AlignMask) {
Ptr = (CHAR8 *) (((UINTN) (((UINTN) Buf) &~(AlignMask))) + (1 << Width));
while (Counter > 0) {
InStride = (OldCount - Counter) << Width;
OutStride = (OldCount - Counter) << Width;
if (Width >= EfiCpuIoWidthFifoUint8 && Width <= EfiCpuIoWidthFifoUint64) {
InStride = 0;
}
if (Width >= EfiCpuIoWidthFillUint8 && Width <= EfiCpuIoWidthFillUint64) {
OutStride = 0;
}
Status = mCpuIo->Io.Read (
mCpuIo,
(EFI_CPU_IO_PROTOCOL_WIDTH) OldWidth,
Address + InStride,
1,
(VOID *) Ptr
);
if (EFI_ERROR (Status)) {
return Status;
}
EfiCopyMem (TempBuf + OutStride, Ptr, (1 << Width));
Counter--;
};
} else {
Status = mCpuIo->Io.Read (
mCpuIo,
(EFI_CPU_IO_PROTOCOL_WIDTH) OldWidth,
Address,
OldCount,
Buffer
);
}
return Status;
}
EFI_STATUS
EFIAPI
RootBridgeIoIoWrite (
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
)
/*++
Routine Description:
Io write
Arguments:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?