mirror of https://github.com/acidanthera/audk.git
Merge branch 'master' of github.com:tianocore/edk2
This commit is contained in:
commit
070827be5a
|
@ -93,7 +93,7 @@ DmaMap (
|
|||
*Mapping = Map;
|
||||
|
||||
if ((((UINTN)HostAddress & (gCacheAlignment - 1)) != 0) ||
|
||||
((*NumberOfBytes % gCacheAlignment) != 0)) {
|
||||
((*NumberOfBytes & (gCacheAlignment - 1)) != 0)) {
|
||||
|
||||
// Get the cacheability of the region
|
||||
Status = gDS->GetMemorySpaceDescriptor (*DeviceAddress, &GcdDescriptor);
|
||||
|
@ -102,9 +102,19 @@ DmaMap (
|
|||
}
|
||||
|
||||
// If the mapped buffer is not an uncached buffer
|
||||
if ( (GcdDescriptor.Attributes != EFI_MEMORY_WC) &&
|
||||
(GcdDescriptor.Attributes != EFI_MEMORY_UC) )
|
||||
{
|
||||
if ((GcdDescriptor.Attributes & (EFI_MEMORY_WB | EFI_MEMORY_WT)) != 0) {
|
||||
//
|
||||
// Operations of type MapOperationBusMasterCommonBuffer are only allowed
|
||||
// on uncached buffers.
|
||||
//
|
||||
if (Operation == MapOperationBusMasterCommonBuffer) {
|
||||
DEBUG ((EFI_D_ERROR,
|
||||
"%a: Operation type 'MapOperationBusMasterCommonBuffer' is only supported\n"
|
||||
"on memory regions that were allocated using DmaAllocateBuffer ()\n",
|
||||
__FUNCTION__));
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
//
|
||||
// If the buffer does not fill entire cache lines we must double buffer into
|
||||
// uncached memory. Device (PCI) address becomes uncached page.
|
||||
|
@ -115,7 +125,7 @@ DmaMap (
|
|||
return Status;
|
||||
}
|
||||
|
||||
if ((Operation == MapOperationBusMasterRead) || (Operation == MapOperationBusMasterCommonBuffer)) {
|
||||
if (Operation == MapOperationBusMasterRead) {
|
||||
CopyMem (Buffer, HostAddress, *NumberOfBytes);
|
||||
}
|
||||
|
||||
|
@ -126,14 +136,25 @@ DmaMap (
|
|||
} else {
|
||||
Map->DoubleBuffer = FALSE;
|
||||
|
||||
DEBUG_CODE_BEGIN ();
|
||||
|
||||
//
|
||||
// The operation type check above only executes if the buffer happens to be
|
||||
// misaligned with respect to CWG, but even if it is aligned, we should not
|
||||
// allow arbitrary buffers to be used for creating consistent mappings.
|
||||
// So duplicate the check here when running in DEBUG mode, just to assert
|
||||
// that we are not trying to create a consistent mapping for cached memory.
|
||||
//
|
||||
Status = gDS->GetMemorySpaceDescriptor (*DeviceAddress, &GcdDescriptor);
|
||||
ASSERT_EFI_ERROR(Status);
|
||||
|
||||
ASSERT (Operation != MapOperationBusMasterCommonBuffer ||
|
||||
(GcdDescriptor.Attributes & (EFI_MEMORY_WB | EFI_MEMORY_WT)) == 0);
|
||||
|
||||
DEBUG_CODE_END ();
|
||||
|
||||
// Flush the Data Cache (should not have any effect if the memory region is uncached)
|
||||
gCpu->FlushDataCache (gCpu, *DeviceAddress, *NumberOfBytes, EfiCpuFlushTypeWriteBackInvalidate);
|
||||
|
||||
if ((Operation == MapOperationBusMasterRead) || (Operation == MapOperationBusMasterCommonBuffer)) {
|
||||
// In case the buffer is used for instance to send command to a PCI controller, we must ensure the memory is uncached
|
||||
Status = gDS->SetMemorySpaceAttributes (*DeviceAddress & ~(BASE_4KB - 1), ALIGN_VALUE (*NumberOfBytes, BASE_4KB), EFI_MEMORY_WC);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
}
|
||||
|
||||
Map->HostAddress = (UINTN)HostAddress;
|
||||
|
@ -153,6 +174,8 @@ DmaMap (
|
|||
|
||||
@retval EFI_SUCCESS The range was unmapped.
|
||||
@retval EFI_DEVICE_ERROR The data was not committed to the target system memory.
|
||||
@retval EFI_INVALID_PARAMETER An inconsistency was detected between the mapping type
|
||||
and the DoubleBuffer field
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
|
@ -162,6 +185,7 @@ DmaUnmap (
|
|||
)
|
||||
{
|
||||
MAP_INFO_INSTANCE *Map;
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (Mapping == NULL) {
|
||||
ASSERT (FALSE);
|
||||
|
@ -170,8 +194,13 @@ DmaUnmap (
|
|||
|
||||
Map = (MAP_INFO_INSTANCE *)Mapping;
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
if (Map->DoubleBuffer) {
|
||||
if ((Map->Operation == MapOperationBusMasterWrite) || (Map->Operation == MapOperationBusMasterCommonBuffer)) {
|
||||
ASSERT (Map->Operation != MapOperationBusMasterCommonBuffer);
|
||||
|
||||
if (Map->Operation == MapOperationBusMasterCommonBuffer) {
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
} else if (Map->Operation == MapOperationBusMasterWrite) {
|
||||
CopyMem ((VOID *)(UINTN)Map->HostAddress, (VOID *)(UINTN)Map->DeviceAddress, Map->NumberOfBytes);
|
||||
}
|
||||
|
||||
|
@ -188,7 +217,7 @@ DmaUnmap (
|
|||
|
||||
FreePool (Map);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -216,6 +245,8 @@ DmaAllocateBuffer (
|
|||
OUT VOID **HostAddress
|
||||
)
|
||||
{
|
||||
VOID *Allocation;
|
||||
|
||||
if (HostAddress == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
@ -226,13 +257,19 @@ DmaAllocateBuffer (
|
|||
// We used uncached memory to keep coherency
|
||||
//
|
||||
if (MemoryType == EfiBootServicesData) {
|
||||
*HostAddress = UncachedAllocatePages (Pages);
|
||||
Allocation = UncachedAllocatePages (Pages);
|
||||
} else if (MemoryType == EfiRuntimeServicesData) {
|
||||
*HostAddress = UncachedAllocateRuntimePages (Pages);
|
||||
Allocation = UncachedAllocateRuntimePages (Pages);
|
||||
} else {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (Allocation == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
*HostAddress = Allocation;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -306,13 +306,6 @@ GetBlockEntryListFromAddress (
|
|||
|
||||
// Convert the block entry attributes into Table descriptor attributes
|
||||
TableAttributes = TT_TABLE_AP_NO_PERMISSION;
|
||||
if (Attributes & TT_PXN_MASK) {
|
||||
TableAttributes = TT_TABLE_PXN;
|
||||
}
|
||||
// XN maps to UXN in the EL1&0 translation regime
|
||||
if (Attributes & TT_XN_MASK) {
|
||||
TableAttributes = TT_TABLE_XN;
|
||||
}
|
||||
if (Attributes & TT_NS) {
|
||||
TableAttributes = TT_TABLE_NS;
|
||||
}
|
||||
|
|
|
@ -111,6 +111,8 @@
|
|||
|
||||
gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0x4007c000
|
||||
gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0x4000
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800
|
||||
|
||||
# Size of the region used by UEFI in permanent memory (Reserved 64MB)
|
||||
gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize|0x04000000
|
||||
|
|
|
@ -100,6 +100,8 @@
|
|||
|
||||
gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0x4007c000
|
||||
gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0x4000
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800
|
||||
|
||||
# Size of the region used by UEFI in permanent memory (Reserved 64MB)
|
||||
gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize|0x04000000
|
||||
|
|
|
@ -80,7 +80,7 @@ struct imd_root {
|
|||
UINT32 max_entries;
|
||||
UINT32 num_entries;
|
||||
UINT32 flags;
|
||||
UINT32 entry_align;
|
||||
UINT32 entry_align;
|
||||
UINT32 max_offset;
|
||||
struct imd_entry entries[0];
|
||||
};
|
||||
|
@ -165,6 +165,21 @@ struct cb_serial {
|
|||
UINT32 type;
|
||||
UINT32 baseaddr;
|
||||
UINT32 baud;
|
||||
UINT32 regwidth;
|
||||
|
||||
// Crystal or input frequency to the chip containing the UART.
|
||||
// Provide the board specific details to allow the payload to
|
||||
// initialize the chip containing the UART and make independent
|
||||
// decisions as to which dividers to select and their values
|
||||
// to eventually arrive at the desired console baud-rate.
|
||||
UINT32 input_hertz;
|
||||
|
||||
// UART PCI address: bus, device, function
|
||||
// 1 << 31 - Valid bit, PCI UART in use
|
||||
// Bus << 20
|
||||
// Device << 15
|
||||
// Function << 12
|
||||
UINT32 uart_pci_addr;
|
||||
};
|
||||
|
||||
#define CB_TAG_CONSOLE 0x00010
|
||||
|
|
|
@ -30,7 +30,7 @@ CbParseMemoryInfo (
|
|||
IN UINT64* pLowMemorySize,
|
||||
IN UINT64* pHighMemorySize
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
Acquire the coreboot memory table with the given table id
|
||||
|
||||
|
@ -45,11 +45,11 @@ CbParseMemoryInfo (
|
|||
**/
|
||||
RETURN_STATUS
|
||||
CbParseCbMemTable (
|
||||
IN UINT32 TableId,
|
||||
IN UINT32 TableId,
|
||||
IN VOID** pMemTable,
|
||||
IN UINT32* pMemTableSize
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
Acquire the acpi table from coreboot
|
||||
|
||||
|
@ -66,7 +66,7 @@ CbParseAcpiTable (
|
|||
IN VOID** pMemTable,
|
||||
IN UINT32* pMemTableSize
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
Acquire the smbios table from coreboot
|
||||
|
||||
|
@ -83,7 +83,7 @@ CbParseSmbiosTable (
|
|||
IN VOID** pMemTable,
|
||||
IN UINT32* pMemTableSize
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
Find the required fadt information
|
||||
|
||||
|
@ -107,13 +107,16 @@ CbParseFadtInfo (
|
|||
IN UINTN* pPmEvtReg,
|
||||
IN UINTN* pPmGpeEnReg
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
Find the serial port information
|
||||
|
||||
@param pRegBase Pointer to the base address of serial port registers
|
||||
@param pRegAccessType Pointer to the access type of serial port registers
|
||||
@param pRegWidth Pointer to the register width in bytes
|
||||
@param pBaudrate Pointer to the serial port baudrate
|
||||
@param pInputHertz Pointer to the input clock frequency
|
||||
@param pUartPciAddr Pointer to the UART PCI bus, dev and func address
|
||||
|
||||
@retval RETURN_SUCCESS Successfully find the serial port information.
|
||||
@retval RETURN_NOT_FOUND Failed to find the serial port information .
|
||||
|
@ -121,9 +124,12 @@ CbParseFadtInfo (
|
|||
**/
|
||||
RETURN_STATUS
|
||||
CbParseSerialInfo (
|
||||
IN UINT32* pRegBase,
|
||||
IN UINT32* pRegAccessType,
|
||||
IN UINT32* pBaudrate
|
||||
OUT UINT32 *pRegBase,
|
||||
OUT UINT32 *pRegAccessType,
|
||||
OUT UINT32 *pRegWidth,
|
||||
OUT UINT32 *pBaudrate,
|
||||
OUT UINT32 *pInputHertz,
|
||||
OUT UINT32 *pUartPciAddr
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -141,7 +147,7 @@ CbParseGetCbHeader (
|
|||
IN UINTN Level,
|
||||
IN VOID** HeaderPtr
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
Find the video frame buffer information
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,48 @@
|
|||
## @file
|
||||
# SerialPortLib instance for 16550 UART.
|
||||
#
|
||||
# Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
|
||||
# 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.
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = BaseSerialPortLib16550
|
||||
MODULE_UNI_FILE = BaseSerialPortLib16550.uni
|
||||
FILE_GUID = 9E7C00CF-355A-4d4e-BF60-0428CFF95540
|
||||
MODULE_TYPE = BASE
|
||||
VERSION_STRING = 1.1
|
||||
LIBRARY_CLASS = SerialPortLib
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
PcdLib
|
||||
IoLib
|
||||
PlatformHookLib
|
||||
PciLib
|
||||
|
||||
[Sources]
|
||||
BaseSerialPortLib16550.c
|
||||
|
||||
[Pcd]
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio ## CONSUMES
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl ## CONSUMES
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialDetectCable ## SOMETIMES_CONSUMES
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase ## CONSUMES
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate ## CONSUMES
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialLineControl ## CONSUMES
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialFifoControl ## CONSUMES
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate ## CONSUMES
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialPciDeviceInfo ## CONSUMES
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialExtendedTxFifoSize ## CONSUMES
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride ## CONSUMES
|
|
@ -0,0 +1,22 @@
|
|||
// /** @file
|
||||
// SerialPortLib instance for 16550 UART.
|
||||
//
|
||||
// SerialPortLib instance for 16550 UART.
|
||||
//
|
||||
// Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// **/
|
||||
|
||||
|
||||
#string STR_MODULE_ABSTRACT #language en-US "SerialPortLib instance for 16550 UART"
|
||||
|
||||
#string STR_MODULE_DESCRIPTION #language en-US "SerialPortLib instance for 16550 UART."
|
||||
|
|
@ -33,7 +33,7 @@
|
|||
@return the UNIT64 value after convertion.
|
||||
|
||||
**/
|
||||
UINT64
|
||||
UINT64
|
||||
cb_unpack64 (
|
||||
IN struct cbuint64 val
|
||||
)
|
||||
|
@ -469,12 +469,12 @@ CbParseFadtInfo (
|
|||
}
|
||||
DEBUG ((EFI_D_INFO, "Reset Value 0x%x\n", Fadt->ResetValue));
|
||||
|
||||
if (pPmEvtReg != NULL) {
|
||||
if (pPmEvtReg != NULL) {
|
||||
*pPmEvtReg = Fadt->Pm1aEvtBlk;
|
||||
DEBUG ((EFI_D_INFO, "PmEvt Reg 0x%x\n", Fadt->Pm1aEvtBlk));
|
||||
}
|
||||
|
||||
if (pPmGpeEnReg != NULL) {
|
||||
if (pPmGpeEnReg != NULL) {
|
||||
*pPmGpeEnReg = Fadt->Gpe0Blk + Fadt->Gpe0BlkLen / 2;
|
||||
DEBUG ((EFI_D_INFO, "PmGpeEn Reg 0x%x\n", *pPmGpeEnReg));
|
||||
}
|
||||
|
@ -519,15 +519,15 @@ CbParseFadtInfo (
|
|||
*pResetValue = Fadt->ResetValue;
|
||||
DEBUG ((EFI_D_ERROR, "Reset Value 0x%x\n", Fadt->ResetValue));
|
||||
|
||||
if (pPmEvtReg != NULL) {
|
||||
if (pPmEvtReg != NULL) {
|
||||
*pPmEvtReg = Fadt->Pm1aEvtBlk;
|
||||
DEBUG ((EFI_D_INFO, "PmEvt Reg 0x%x\n", Fadt->Pm1aEvtBlk));
|
||||
}
|
||||
|
||||
if (pPmGpeEnReg != NULL) {
|
||||
if (pPmGpeEnReg != NULL) {
|
||||
*pPmGpeEnReg = Fadt->Gpe0Blk + Fadt->Gpe0BlkLen / 2;
|
||||
DEBUG ((EFI_D_INFO, "PmGpeEn Reg 0x%x\n", *pPmGpeEnReg));
|
||||
}
|
||||
}
|
||||
return RETURN_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
@ -541,7 +541,10 @@ CbParseFadtInfo (
|
|||
|
||||
@param pRegBase Pointer to the base address of serial port registers
|
||||
@param pRegAccessType Pointer to the access type of serial port registers
|
||||
@param pRegWidth Pointer to the register width in bytes
|
||||
@param pBaudrate Pointer to the serial port baudrate
|
||||
@param pInputHertz Pointer to the input clock frequency
|
||||
@param pUartPciAddr Pointer to the UART PCI bus, dev and func address
|
||||
|
||||
@retval RETURN_SUCCESS Successfully find the serial port information.
|
||||
@retval RETURN_NOT_FOUND Failed to find the serial port information .
|
||||
|
@ -551,7 +554,10 @@ RETURN_STATUS
|
|||
CbParseSerialInfo (
|
||||
OUT UINT32 *pRegBase,
|
||||
OUT UINT32 *pRegAccessType,
|
||||
OUT UINT32 *pBaudrate
|
||||
OUT UINT32 *pRegWidth,
|
||||
OUT UINT32 *pBaudrate,
|
||||
OUT UINT32 *pInputHertz,
|
||||
OUT UINT32 *pUartPciAddr
|
||||
)
|
||||
{
|
||||
struct cb_serial *CbSerial;
|
||||
|
@ -569,6 +575,10 @@ CbParseSerialInfo (
|
|||
*pRegBase = CbSerial->baseaddr;
|
||||
}
|
||||
|
||||
if (pRegWidth != NULL) {
|
||||
*pRegWidth = CbSerial->regwidth;
|
||||
}
|
||||
|
||||
if (pRegAccessType != NULL) {
|
||||
*pRegAccessType = CbSerial->type;
|
||||
}
|
||||
|
@ -577,6 +587,14 @@ CbParseSerialInfo (
|
|||
*pBaudrate = CbSerial->baud;
|
||||
}
|
||||
|
||||
if (pInputHertz != NULL) {
|
||||
*pInputHertz = CbSerial->input_hertz;
|
||||
}
|
||||
|
||||
if (pUartPciAddr != NULL) {
|
||||
*pUartPciAddr = CbSerial->uart_pci_addr;
|
||||
}
|
||||
|
||||
return RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,18 +2,18 @@
|
|||
|
||||
Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||
(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
|
||||
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.
|
||||
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:
|
||||
|
||||
PciEnumeratorSupport.c
|
||||
|
||||
|
||||
Abstract:
|
||||
|
||||
PCI Bus Driver
|
||||
|
@ -24,17 +24,17 @@ Revision History
|
|||
|
||||
#include "PciBus.h"
|
||||
|
||||
EFI_STATUS
|
||||
EFI_STATUS
|
||||
InitializePPB (
|
||||
IN PCI_IO_DEVICE *PciIoDevice
|
||||
IN PCI_IO_DEVICE *PciIoDevice
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFI_STATUS
|
||||
InitializeP2C (
|
||||
IN PCI_IO_DEVICE *PciIoDevice
|
||||
IN PCI_IO_DEVICE *PciIoDevice
|
||||
);
|
||||
|
||||
PCI_IO_DEVICE*
|
||||
PCI_IO_DEVICE*
|
||||
CreatePciIoDevice (
|
||||
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,
|
||||
IN PCI_TYPE00 *Pci,
|
||||
|
@ -72,12 +72,12 @@ PciSearchDevice (
|
|||
);
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFI_STATUS
|
||||
DetermineDeviceAttribute (
|
||||
IN PCI_IO_DEVICE *PciIoDevice
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFI_STATUS
|
||||
BarExisted (
|
||||
IN PCI_IO_DEVICE *PciIoDevice,
|
||||
IN UINTN Offset,
|
||||
|
@ -90,10 +90,10 @@ BarExisted (
|
|||
EFI_DEVICE_PATH_PROTOCOL*
|
||||
CreatePciDevicePath(
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,
|
||||
IN PCI_IO_DEVICE *PciIoDevice
|
||||
IN PCI_IO_DEVICE *PciIoDevice
|
||||
);
|
||||
|
||||
PCI_IO_DEVICE*
|
||||
PCI_IO_DEVICE*
|
||||
GatherDeviceInfo (
|
||||
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,
|
||||
IN PCI_TYPE00 *Pci,
|
||||
|
@ -102,7 +102,7 @@ GatherDeviceInfo (
|
|||
UINT8 Func
|
||||
);
|
||||
|
||||
PCI_IO_DEVICE*
|
||||
PCI_IO_DEVICE*
|
||||
GatherPPBInfo (
|
||||
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,
|
||||
IN PCI_TYPE00 *Pci,
|
||||
|
@ -226,6 +226,15 @@ Returns:
|
|||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
|
||||
//
|
||||
// Skip non-bridge devices which are not enabled
|
||||
//
|
||||
if (((Pci.Hdr.Command & (EFI_PCI_COMMAND_IO_SPACE
|
||||
| EFI_PCI_COMMAND_MEMORY_SPACE)) == 0)
|
||||
&& (!(IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci)))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Collect all the information about the PCI device discovered
|
||||
//
|
||||
|
@ -255,7 +264,7 @@ Returns:
|
|||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// If the PCI bridge is initialized then enumerate the next level bus
|
||||
//
|
||||
|
@ -368,15 +377,15 @@ Returns:
|
|||
if (!PciIoDevice) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Create a device path for this PCI device and store it into its private data
|
||||
//
|
||||
CreatePciDevicePath(
|
||||
Bridge->DevicePath,
|
||||
PciIoDevice
|
||||
PciIoDevice
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// Detect this function has option rom
|
||||
//
|
||||
|
@ -389,8 +398,8 @@ Returns:
|
|||
}
|
||||
|
||||
ResetPowerManagementFeature (PciIoDevice);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
PciRomGetRomResourceFromPciOptionRomTable (
|
||||
&gPciBusDriverBinding,
|
||||
|
@ -399,7 +408,7 @@ Returns:
|
|||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Insert it into a global tree for future reference
|
||||
//
|
||||
|
@ -509,7 +518,7 @@ Returns:
|
|||
if (!PciIoDevice) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
if (gFullEnumeration) {
|
||||
PciDisableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED);
|
||||
|
||||
|
@ -593,7 +602,7 @@ Returns:
|
|||
--*/
|
||||
{
|
||||
PCI_IO_DEVICE *PciIoDevice;
|
||||
|
||||
|
||||
PciIoDevice = CreatePciIoDevice (
|
||||
PciRootBridgeIo,
|
||||
Pci,
|
||||
|
@ -619,7 +628,7 @@ Returns:
|
|||
// P2C only has one bar that is in 0x10
|
||||
//
|
||||
PciParseBar(PciIoDevice, 0x10, 0);
|
||||
|
||||
|
||||
PciIoDevice->Decodes = EFI_BRIDGE_MEM32_DECODE_SUPPORTED |
|
||||
EFI_BRIDGE_PMEM32_DECODE_SUPPORTED |
|
||||
EFI_BRIDGE_IO32_DECODE_SUPPORTED;
|
||||
|
@ -742,7 +751,7 @@ DetermineDeviceAttribute (
|
|||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
|
||||
Determine the related attributes of all devices under a Root Bridge
|
||||
|
||||
Arguments:
|
||||
|
@ -799,7 +808,7 @@ Returns:
|
|||
|
||||
PciReadCommandRegister(PciIoDevice, &Command);
|
||||
|
||||
|
||||
|
||||
if (Command & EFI_PCI_COMMAND_IO_SPACE) {
|
||||
PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_IO;
|
||||
}
|
||||
|
@ -812,7 +821,7 @@ Returns:
|
|||
PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_BUS_MASTER;
|
||||
}
|
||||
|
||||
if (IS_PCI_BRIDGE (&(PciIoDevice->Pci)) ||
|
||||
if (IS_PCI_BRIDGE (&(PciIoDevice->Pci)) ||
|
||||
IS_CARDBUS_BRIDGE (&(PciIoDevice->Pci))){
|
||||
|
||||
//
|
||||
|
@ -825,12 +834,12 @@ Returns:
|
|||
//
|
||||
// Determine whether the ISA bit is set
|
||||
// If ISA Enable on Bridge is set, the PPB
|
||||
// will block forwarding 0x100-0x3ff for each 1KB in the
|
||||
// will block forwarding 0x100-0x3ff for each 1KB in the
|
||||
// first 64KB I/O range.
|
||||
//
|
||||
if ((BridgeControl & EFI_PCI_BRIDGE_CONTROL_ISA) != 0) {
|
||||
PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_IO;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Determine whether the VGA bit is set
|
||||
|
@ -844,13 +853,13 @@ Returns:
|
|||
}
|
||||
|
||||
//
|
||||
// if the palette snoop bit is set, then the brige is set to
|
||||
// if the palette snoop bit is set, then the brige is set to
|
||||
// decode palette IO write
|
||||
//
|
||||
if (Command & EFI_PCI_COMMAND_VGA_PALETTE_SNOOP) {
|
||||
PciIoDevice->Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
@ -997,7 +1006,7 @@ Returns:
|
|||
//
|
||||
// Fix the length to support some spefic 64 bit BAR
|
||||
//
|
||||
Value |= ((UINT32)(-1) << HighBitSet32 (Value));
|
||||
Value |= ((UINT32)(-1) << HighBitSet32 (Value));
|
||||
|
||||
//
|
||||
// Calculate the size of 64bit bar
|
||||
|
@ -1021,7 +1030,7 @@ Returns:
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Check the length again so as to keep compatible with some special bars
|
||||
//
|
||||
|
@ -1030,7 +1039,7 @@ Returns:
|
|||
PciIoDevice->PciBar[BarIndex].BaseAddress = 0;
|
||||
PciIoDevice->PciBar[BarIndex].Alignment = 0;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Increment number of bar
|
||||
//
|
||||
|
@ -1220,7 +1229,7 @@ PciEnumeratorLight (
|
|||
|
||||
Routine Description:
|
||||
|
||||
This routine is used to enumerate entire pci bus system
|
||||
This routine is used to enumerate entire pci bus system
|
||||
in a given platform
|
||||
|
||||
Arguments:
|
||||
|
@ -1255,11 +1264,11 @@ Returns:
|
|||
// Open the IO Abstraction(s) needed to perform the supported test
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
Controller ,
|
||||
&gEfiDevicePathProtocolGuid,
|
||||
Controller ,
|
||||
&gEfiDevicePathProtocolGuid,
|
||||
(VOID **)&ParentDevicePath,
|
||||
gPciBusDriverBinding.DriverBindingHandle,
|
||||
Controller,
|
||||
gPciBusDriverBinding.DriverBindingHandle,
|
||||
Controller,
|
||||
EFI_OPEN_PROTOCOL_BY_DRIVER
|
||||
);
|
||||
if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
|
||||
|
@ -1282,7 +1291,7 @@ Returns:
|
|||
}
|
||||
|
||||
//
|
||||
// Load all EFI Drivers from all PCI Option ROMs behind the PCI Root Bridge
|
||||
// Load all EFI Drivers from all PCI Option ROMs behind the PCI Root Bridge
|
||||
//
|
||||
Status = PciRomLoadEfiDriversFromOptionRomTable (&gPciBusDriverBinding, PciRootBridgeIo);
|
||||
|
||||
|
@ -1353,9 +1362,9 @@ Arguments:
|
|||
MinBus - The min bus.
|
||||
MaxBus - The max bus.
|
||||
BusRange - The bus range.
|
||||
|
||||
|
||||
Returns:
|
||||
|
||||
|
||||
Status Code.
|
||||
|
||||
--*/
|
||||
|
|
|
@ -78,6 +78,10 @@ PlatformBdsInit (
|
|||
VOID
|
||||
)
|
||||
{
|
||||
gUartDeviceNode.BaudRate = PcdGet64 (PcdUartDefaultBaudRate);
|
||||
gUartDeviceNode.DataBits = PcdGet8 (PcdUartDefaultDataBits);
|
||||
gUartDeviceNode.Parity = PcdGet8 (PcdUartDefaultParity);
|
||||
gUartDeviceNode.StopBits = PcdGet8 (PcdUartDefaultStopBits);
|
||||
}
|
||||
|
||||
|
||||
|
@ -786,6 +790,7 @@ PlatformBdsPolicyBehavior (
|
|||
|
||||
DEBUG ((EFI_D_INFO, "PlatformBdsPolicyBehavior\n"));
|
||||
|
||||
PlatformBdsInit();
|
||||
ConnectRootBridge ();
|
||||
|
||||
//
|
||||
|
|
|
@ -45,6 +45,12 @@
|
|||
DebugLib
|
||||
PcdLib
|
||||
GenericBdsLib
|
||||
PlatformHookLib
|
||||
|
||||
[Pcd]
|
||||
gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
|
||||
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLogoFile
|
||||
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate
|
||||
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits
|
||||
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity
|
||||
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits
|
||||
|
|
|
@ -14,10 +14,23 @@
|
|||
|
||||
#include <Base.h>
|
||||
#include <Uefi/UefiBaseType.h>
|
||||
#include <Library/PciLib.h>
|
||||
#include <Library/PlatformHookLib.h>
|
||||
#include <Library/CbParseLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
|
||||
typedef struct {
|
||||
UINT16 VendorId; ///< Vendor ID to match the PCI device. The value 0xFFFF terminates the list of entries.
|
||||
UINT16 DeviceId; ///< Device ID to match the PCI device
|
||||
UINT32 ClockRate; ///< UART clock rate. Set to 0 for default clock rate of 1843200 Hz
|
||||
UINT64 Offset; ///< The byte offset into to the BAR
|
||||
UINT8 BarIndex; ///< Which BAR to get the UART base address
|
||||
UINT8 RegisterStride; ///< UART register stride in bytes. Set to 0 for default register stride of 1 byte.
|
||||
UINT16 ReceiveFifoDepth; ///< UART receive FIFO depth in bytes. Set to 0 for a default FIFO depth of 16 bytes.
|
||||
UINT16 TransmitFifoDepth; ///< UART transmit FIFO depth in bytes. Set to 0 for a default FIFO depth of 16 bytes.
|
||||
UINT8 Reserved[2];
|
||||
} PCI_SERIAL_PARAMETER;
|
||||
|
||||
/**
|
||||
Performs platform specific initialization required for the CPU to access
|
||||
the hardware associated with a SerialPortLib instance. This function does
|
||||
|
@ -38,8 +51,16 @@ PlatformHookSerialPortInitialize (
|
|||
RETURN_STATUS Status;
|
||||
UINT32 SerialRegBase;
|
||||
UINT32 SerialRegAccessType;
|
||||
UINT32 BaudRate;
|
||||
UINT32 RegWidth;
|
||||
UINT32 InputHertz;
|
||||
UINT32 PayloadParam;
|
||||
UINT32 DeviceVendor;
|
||||
PCI_SERIAL_PARAMETER *SerialParam;
|
||||
|
||||
Status = CbParseSerialInfo (&SerialRegBase, &SerialRegAccessType, NULL);
|
||||
Status = CbParseSerialInfo (&SerialRegBase, &SerialRegAccessType,
|
||||
&RegWidth, &BaudRate, &InputHertz,
|
||||
&PayloadParam);
|
||||
if (RETURN_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
@ -57,6 +78,34 @@ PlatformHookSerialPortInitialize (
|
|||
return Status;
|
||||
}
|
||||
|
||||
Status = PcdSet32S (PcdSerialRegisterStride, RegWidth);
|
||||
if (RETURN_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = PcdSet32S (PcdSerialBaudRate, BaudRate);
|
||||
if (RETURN_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = PcdSet64S (PcdUartDefaultBaudRate, BaudRate);
|
||||
if (RETURN_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = PcdSet32S (PcdSerialClockRate, InputHertz);
|
||||
if (RETURN_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (PayloadParam >= 0x80000000) {
|
||||
DeviceVendor = PciRead32 (PayloadParam & 0x0ffff000);
|
||||
SerialParam = PcdGetPtr(PcdPciSerialParameters);
|
||||
SerialParam->VendorId = (UINT16)DeviceVendor;
|
||||
SerialParam->DeviceId = DeviceVendor >> 16;
|
||||
SerialParam->ClockRate = InputHertz;
|
||||
SerialParam->RegisterStride = (UINT8)RegWidth;
|
||||
}
|
||||
|
||||
return RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
MODULE_TYPE = BASE
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = PlatformHookLib
|
||||
CONSTRUCTOR = PlatformHookSerialPortInitialize
|
||||
|
||||
[Sources]
|
||||
PlatformHookLib.c
|
||||
|
@ -26,6 +27,7 @@
|
|||
[LibraryClasses]
|
||||
CbParseLib
|
||||
PcdLib
|
||||
PciLib
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
|
@ -33,6 +35,10 @@
|
|||
CorebootModulePkg/CorebootModulePkg.dec
|
||||
|
||||
[Pcd]
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio ## PRODUCES
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase ## PRODUCES
|
||||
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio ## PRODUCES
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase ## PRODUCES
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate ## PRODUCES
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride ## PRODUCES
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate ## PRODUCES
|
||||
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate ## PRODUCES
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdPciSerialParameters ## PRODUCES
|
||||
|
|
|
@ -297,7 +297,7 @@ SnpInitialize (
|
|||
}
|
||||
|
||||
// Read the PM register
|
||||
PmConf = MmioRead32 (LAN9118_PMT_CTRL);
|
||||
PmConf = Lan9118MmioRead32 (LAN9118_PMT_CTRL);
|
||||
|
||||
// MPTCTRL_WOL_EN: Allow Wake-On-Lan to detect wake up frames or magic packets
|
||||
// MPTCTRL_ED_EN: Allow energy detection to allow lowest power consumption mode
|
||||
|
@ -306,8 +306,7 @@ SnpInitialize (
|
|||
PmConf |= (MPTCTRL_WOL_EN | MPTCTRL_ED_EN | MPTCTRL_PME_EN);
|
||||
|
||||
// Write the current configuration to the register
|
||||
MmioWrite32 (LAN9118_PMT_CTRL, PmConf);
|
||||
MemoryFence();
|
||||
Lan9118MmioWrite32 (LAN9118_PMT_CTRL, PmConf);
|
||||
|
||||
// Configure GPIO and HW
|
||||
Status = ConfigureHardware (HW_CONF_USE_LEDS, Snp);
|
||||
|
@ -358,7 +357,7 @@ SnpInitialize (
|
|||
}
|
||||
|
||||
// Now acknowledge all interrupts
|
||||
MmioWrite32 (LAN9118_INT_STS, ~0);
|
||||
Lan9118MmioWrite32 (LAN9118_INT_STS, ~0);
|
||||
|
||||
// Declare the driver as initialized
|
||||
Snp->Mode->State = EfiSimpleNetworkInitialized;
|
||||
|
@ -421,7 +420,7 @@ SnpReset (
|
|||
}
|
||||
|
||||
// Read the PM register
|
||||
PmConf = MmioRead32 (LAN9118_PMT_CTRL);
|
||||
PmConf = Lan9118MmioRead32 (LAN9118_PMT_CTRL);
|
||||
|
||||
// MPTCTRL_WOL_EN: Allow Wake-On-Lan to detect wake up frames or magic packets
|
||||
// MPTCTRL_ED_EN: Allow energy detection to allow lowest power consumption mode
|
||||
|
@ -429,8 +428,7 @@ SnpReset (
|
|||
PmConf |= (MPTCTRL_WOL_EN | MPTCTRL_ED_EN | MPTCTRL_PME_EN);
|
||||
|
||||
// Write the current configuration to the register
|
||||
MmioWrite32 (LAN9118_PMT_CTRL, PmConf);
|
||||
MemoryFence();
|
||||
Lan9118MmioWrite32 (LAN9118_PMT_CTRL, PmConf);
|
||||
|
||||
// Reactivate the LEDs
|
||||
Status = ConfigureHardware (HW_CONF_USE_LEDS, Snp);
|
||||
|
@ -440,12 +438,11 @@ SnpReset (
|
|||
|
||||
// Check that a buffer size was specified in SnpInitialize
|
||||
if (gTxBuffer != 0) {
|
||||
HwConf = MmioRead32 (LAN9118_HW_CFG); // Read the HW register
|
||||
HwConf = Lan9118MmioRead32 (LAN9118_HW_CFG); // Read the HW register
|
||||
HwConf &= ~HW_CFG_TX_FIFO_SIZE_MASK; // Clear buffer bits first
|
||||
HwConf |= HW_CFG_TX_FIFO_SIZE(gTxBuffer); // assign size chosen in SnpInitialize
|
||||
|
||||
MmioWrite32 (LAN9118_HW_CFG, HwConf); // Write the conf
|
||||
MemoryFence();
|
||||
Lan9118MmioWrite32 (LAN9118_HW_CFG, HwConf); // Write the conf
|
||||
}
|
||||
|
||||
// Enable the receiver and transmitter and clear their contents
|
||||
|
@ -453,7 +450,7 @@ SnpReset (
|
|||
StartTx (START_TX_MAC | START_TX_CFG | START_TX_CLEAR, Snp);
|
||||
|
||||
// Now acknowledge all interrupts
|
||||
MmioWrite32 (LAN9118_INT_STS, ~0);
|
||||
Lan9118MmioWrite32 (LAN9118_INT_STS, ~0);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
@ -700,7 +697,6 @@ SnpReceiveFilters (
|
|||
// Write the options to the MAC_CSR
|
||||
//
|
||||
IndirectMACWrite32 (INDIRECT_MAC_INDEX_CR, MacCSRValue);
|
||||
MemoryFence();
|
||||
|
||||
//
|
||||
// If we have to retrieve something, start packet reception.
|
||||
|
@ -995,12 +991,12 @@ SnpGetStatus (
|
|||
// consumer of SNP does not call GetStatus.)
|
||||
// TODO will we lose TxStatuses if this happens? Maybe in SnpTransmit we
|
||||
// should check for it and dump the TX Status FIFO.
|
||||
FifoInt = MmioRead32 (LAN9118_FIFO_INT);
|
||||
FifoInt = Lan9118MmioRead32 (LAN9118_FIFO_INT);
|
||||
|
||||
// Clear the TX Status FIFO Overflow
|
||||
if ((FifoInt & INSTS_TXSO) == 0) {
|
||||
FifoInt |= INSTS_TXSO;
|
||||
MmioWrite32 (LAN9118_FIFO_INT, FifoInt);
|
||||
Lan9118MmioWrite32 (LAN9118_FIFO_INT, FifoInt);
|
||||
}
|
||||
|
||||
// Read interrupt status if IrqStat is not NULL
|
||||
|
@ -1008,30 +1004,30 @@ SnpGetStatus (
|
|||
*IrqStat = 0;
|
||||
|
||||
// Check for receive interrupt
|
||||
if (MmioRead32 (LAN9118_INT_STS) & INSTS_RSFL) { // Data moved from rx FIFO
|
||||
if (Lan9118MmioRead32 (LAN9118_INT_STS) & INSTS_RSFL) { // Data moved from rx FIFO
|
||||
*IrqStat |= EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT;
|
||||
MmioWrite32 (LAN9118_INT_STS,INSTS_RSFL);
|
||||
Lan9118MmioWrite32 (LAN9118_INT_STS,INSTS_RSFL);
|
||||
}
|
||||
|
||||
// Check for transmit interrupt
|
||||
if (MmioRead32 (LAN9118_INT_STS) & INSTS_TSFL) {
|
||||
if (Lan9118MmioRead32 (LAN9118_INT_STS) & INSTS_TSFL) {
|
||||
*IrqStat |= EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;
|
||||
MmioWrite32 (LAN9118_INT_STS,INSTS_TSFL);
|
||||
Lan9118MmioWrite32 (LAN9118_INT_STS,INSTS_TSFL);
|
||||
}
|
||||
|
||||
// Check for software interrupt
|
||||
if (MmioRead32 (LAN9118_INT_STS) & INSTS_SW_INT) {
|
||||
if (Lan9118MmioRead32 (LAN9118_INT_STS) & INSTS_SW_INT) {
|
||||
*IrqStat |= EFI_SIMPLE_NETWORK_SOFTWARE_INTERRUPT;
|
||||
MmioWrite32 (LAN9118_INT_STS,INSTS_SW_INT);
|
||||
Lan9118MmioWrite32 (LAN9118_INT_STS,INSTS_SW_INT);
|
||||
}
|
||||
}
|
||||
|
||||
// Check Status of transmitted packets
|
||||
// (We ignore TXSTATUS_NO_CA has it might happen in Full Duplex)
|
||||
|
||||
NumTxStatusEntries = MmioRead32(LAN9118_TX_FIFO_INF) & TXFIFOINF_TXSUSED_MASK;
|
||||
NumTxStatusEntries = Lan9118MmioRead32(LAN9118_TX_FIFO_INF) & TXFIFOINF_TXSUSED_MASK;
|
||||
if (NumTxStatusEntries > 0) {
|
||||
TxStatus = MmioRead32 (LAN9118_TX_STATUS);
|
||||
TxStatus = Lan9118MmioRead32 (LAN9118_TX_STATUS);
|
||||
PacketTag = TxStatus >> 16;
|
||||
TxStatus = TxStatus & 0xFFFF;
|
||||
if ((TxStatus & TXSTATUS_ES) && (TxStatus != (TXSTATUS_ES | TXSTATUS_NO_CA))) {
|
||||
|
@ -1062,7 +1058,7 @@ SnpGetStatus (
|
|||
}
|
||||
|
||||
// Check for a TX Error interrupt
|
||||
Interrupts = MmioRead32 (LAN9118_INT_STS);
|
||||
Interrupts = Lan9118MmioRead32 (LAN9118_INT_STS);
|
||||
if (Interrupts & INSTS_TXE) {
|
||||
DEBUG ((EFI_D_ERROR, "LAN9118: Transmitter error. Restarting..."));
|
||||
|
||||
|
@ -1220,25 +1216,25 @@ SnpTransmit (
|
|||
CommandB = TX_CMD_B_PACKET_TAG (PacketTag) | TX_CMD_B_PACKET_LENGTH (BuffSize);
|
||||
|
||||
// Write the commands first
|
||||
MmioWrite32 (LAN9118_TX_DATA, CommandA);
|
||||
MmioWrite32 (LAN9118_TX_DATA, CommandB);
|
||||
Lan9118MmioWrite32 (LAN9118_TX_DATA, CommandA);
|
||||
Lan9118MmioWrite32 (LAN9118_TX_DATA, CommandB);
|
||||
|
||||
// Write the destination address
|
||||
MmioWrite32 (LAN9118_TX_DATA,
|
||||
Lan9118MmioWrite32 (LAN9118_TX_DATA,
|
||||
(DstAddr->Addr[0]) |
|
||||
(DstAddr->Addr[1] << 8) |
|
||||
(DstAddr->Addr[2] << 16) |
|
||||
(DstAddr->Addr[3] << 24)
|
||||
);
|
||||
|
||||
MmioWrite32 (LAN9118_TX_DATA,
|
||||
Lan9118MmioWrite32 (LAN9118_TX_DATA,
|
||||
(DstAddr->Addr[4]) |
|
||||
(DstAddr->Addr[5] << 8) |
|
||||
(SrcAddr->Addr[0] << 16) | // Write the Source Address
|
||||
(SrcAddr->Addr[1] << 24)
|
||||
);
|
||||
|
||||
MmioWrite32 (LAN9118_TX_DATA,
|
||||
Lan9118MmioWrite32 (LAN9118_TX_DATA,
|
||||
(SrcAddr->Addr[2]) |
|
||||
(SrcAddr->Addr[3] << 8) |
|
||||
(SrcAddr->Addr[4] << 16) |
|
||||
|
@ -1246,18 +1242,18 @@ SnpTransmit (
|
|||
);
|
||||
|
||||
// Write the Protocol
|
||||
MmioWrite32 (LAN9118_TX_DATA, (UINT32)(HTONS (LocalProtocol)));
|
||||
Lan9118MmioWrite32 (LAN9118_TX_DATA, (UINT32)(HTONS (LocalProtocol)));
|
||||
|
||||
// Next buffer is the payload
|
||||
CommandA = TX_CMD_A_LAST_SEGMENT | TX_CMD_A_BUFF_SIZE (BuffSize - HdrSize) | TX_CMD_A_COMPLETION_INT | TX_CMD_A_DATA_START_OFFSET (2); // 2 bytes beginning offset
|
||||
|
||||
// Write the commands
|
||||
MmioWrite32 (LAN9118_TX_DATA, CommandA);
|
||||
MmioWrite32 (LAN9118_TX_DATA, CommandB);
|
||||
Lan9118MmioWrite32 (LAN9118_TX_DATA, CommandA);
|
||||
Lan9118MmioWrite32 (LAN9118_TX_DATA, CommandB);
|
||||
|
||||
// Write the payload
|
||||
for (Count = 0; Count < ((BuffSize + 3) >> 2) - 3; Count++) {
|
||||
MmioWrite32 (LAN9118_TX_DATA, LocalData[Count + 3]);
|
||||
Lan9118MmioWrite32 (LAN9118_TX_DATA, LocalData[Count + 3]);
|
||||
}
|
||||
} else {
|
||||
// Format pointer
|
||||
|
@ -1268,12 +1264,12 @@ SnpTransmit (
|
|||
CommandB = TX_CMD_B_PACKET_TAG (PacketTag) | TX_CMD_B_PACKET_LENGTH (BuffSize);
|
||||
|
||||
// Write the commands first
|
||||
MmioWrite32 (LAN9118_TX_DATA, CommandA);
|
||||
MmioWrite32 (LAN9118_TX_DATA, CommandB);
|
||||
Lan9118MmioWrite32 (LAN9118_TX_DATA, CommandA);
|
||||
Lan9118MmioWrite32 (LAN9118_TX_DATA, CommandB);
|
||||
|
||||
// Write all the data
|
||||
for (Count = 0; Count < ((BuffSize + 3) >> 2); Count++) {
|
||||
MmioWrite32 (LAN9118_TX_DATA, LocalData[Count]);
|
||||
Lan9118MmioWrite32 (LAN9118_TX_DATA, LocalData[Count]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1361,13 +1357,13 @@ SnpReceive (
|
|||
// explain those errors has been found so far and everything seems to
|
||||
// work perfectly when they are just ignored.
|
||||
//
|
||||
IntSts = MmioRead32 (LAN9118_INT_STS);
|
||||
IntSts = Lan9118MmioRead32 (LAN9118_INT_STS);
|
||||
if ((IntSts & INSTS_RXE) && (!(IntSts & INSTS_RSFF))) {
|
||||
MmioWrite32 (LAN9118_INT_STS, INSTS_RXE);
|
||||
Lan9118MmioWrite32 (LAN9118_INT_STS, INSTS_RXE);
|
||||
}
|
||||
|
||||
// Count dropped frames
|
||||
DroppedFrames = MmioRead32 (LAN9118_RX_DROP);
|
||||
DroppedFrames = Lan9118MmioRead32 (LAN9118_RX_DROP);
|
||||
LanDriver->Stats.RxDroppedFrames += DroppedFrames;
|
||||
|
||||
NumPackets = RxStatusUsedSpace (0, Snp) / 4;
|
||||
|
@ -1376,7 +1372,7 @@ SnpReceive (
|
|||
}
|
||||
|
||||
// Read Rx Status (only if not empty)
|
||||
RxFifoStatus = MmioRead32 (LAN9118_RX_STATUS);
|
||||
RxFifoStatus = Lan9118MmioRead32 (LAN9118_RX_STATUS);
|
||||
LanDriver->Stats.RxTotalFrames += 1;
|
||||
|
||||
// First check for errors
|
||||
|
@ -1449,13 +1445,13 @@ SnpReceive (
|
|||
|
||||
// Set the amount of data to be transfered out of FIFO for THIS packet
|
||||
// This can be used to trigger an interrupt, and status can be checked
|
||||
RxCfgValue = MmioRead32 (LAN9118_RX_CFG);
|
||||
RxCfgValue = Lan9118MmioRead32 (LAN9118_RX_CFG);
|
||||
RxCfgValue &= ~(RXCFG_RX_DMA_CNT_MASK);
|
||||
RxCfgValue |= RXCFG_RX_DMA_CNT (ReadLimit);
|
||||
|
||||
// Set end alignment to 4-bytes
|
||||
RxCfgValue &= ~(RXCFG_RX_END_ALIGN_MASK);
|
||||
MmioWrite32 (LAN9118_RX_CFG, RxCfgValue);
|
||||
Lan9118MmioWrite32 (LAN9118_RX_CFG, RxCfgValue);
|
||||
|
||||
// Update buffer size
|
||||
*BuffSize = PLength; // -4 bytes may be needed: Received in buffer as
|
||||
|
@ -1470,7 +1466,7 @@ SnpReceive (
|
|||
|
||||
// Read Rx Packet
|
||||
for (Count = 0; Count < ReadLimit; Count++) {
|
||||
RawData[Count] = MmioRead32 (LAN9118_RX_DATA);
|
||||
RawData[Count] = Lan9118MmioRead32 (LAN9118_RX_DATA);
|
||||
}
|
||||
|
||||
// Get the destination address
|
||||
|
@ -1501,7 +1497,7 @@ SnpReceive (
|
|||
}
|
||||
|
||||
// Check for Rx errors (worst possible error)
|
||||
if (MmioRead32 (LAN9118_INT_STS) & INSTS_RXE) {
|
||||
if (Lan9118MmioRead32 (LAN9118_INT_STS) & INSTS_RXE) {
|
||||
DEBUG ((EFI_D_WARN, "Warning: Receiver Error. Restarting...\n"));
|
||||
|
||||
// Software reset, the RXE interrupt is cleared by the reset.
|
||||
|
|
|
@ -57,6 +57,77 @@
|
|||
#define LAN9118_E2P_CMD (0x000000B0 + LAN9118_BA) // EEPROM Command
|
||||
#define LAN9118_E2P_DATA (0x000000B4 + LAN9118_BA) // EEPROM Data
|
||||
|
||||
/*
|
||||
* Required delays following write cycles (number of BYTE_TEST reads)
|
||||
* Taken from Table 6.1 in Revision 1.5 (07-11-08) of the LAN9118 datasheet.
|
||||
* Where no delay listed, 0 has been assumed.
|
||||
*/
|
||||
#define LAN9118_RX_DATA_WR_DELAY 0
|
||||
#define LAN9118_RX_STATUS_WR_DELAY 0
|
||||
#define LAN9118_RX_STATUS_PEEK_WR_DELAY 0
|
||||
#define LAN9118_TX_DATA_WR_DELAY 0
|
||||
#define LAN9118_TX_STATUS_WR_DELAY 0
|
||||
#define LAN9118_TX_STATUS_PEEK_WR_DELAY 0
|
||||
#define LAN9118_ID_REV_WR_DELAY 0
|
||||
#define LAN9118_IRQ_CFG_WR_DELAY 3
|
||||
#define LAN9118_INT_STS_WR_DELAY 2
|
||||
#define LAN9118_INT_EN_WR_DELAY 1
|
||||
#define LAN9118_BYTE_TEST_WR_DELAY 0
|
||||
#define LAN9118_FIFO_INT_WR_DELAY 1
|
||||
#define LAN9118_RX_CFG_WR_DELAY 1
|
||||
#define LAN9118_TX_CFG_WR_DELAY 1
|
||||
#define LAN9118_HW_CFG_WR_DELAY 1
|
||||
#define LAN9118_RX_DP_CTL_WR_DELAY 1
|
||||
#define LAN9118_RX_FIFO_INF_WR_DELAY 0
|
||||
#define LAN9118_TX_FIFO_INF_WR_DELAY 3
|
||||
#define LAN9118_PMT_CTRL_WR_DELAY 7
|
||||
#define LAN9118_GPIO_CFG_WR_DELAY 1
|
||||
#define LAN9118_GPT_CFG_WR_DELAY 1
|
||||
#define LAN9118_GPT_CNT_WR_DELAY 3
|
||||
#define LAN9118_WORD_SWAP_WR_DELAY 1
|
||||
#define LAN9118_FREE_RUN_WR_DELAY 4
|
||||
#define LAN9118_RX_DROP_WR_DELAY 0
|
||||
#define LAN9118_MAC_CSR_CMD_WR_DELAY 1
|
||||
#define LAN9118_MAC_CSR_DATA_WR_DELAY 1
|
||||
#define LAN9118_AFC_CFG_WR_DELAY 1
|
||||
#define LAN9118_E2P_CMD_WR_DELAY 1
|
||||
#define LAN9118_E2P_DATA_WR_DELAY 1
|
||||
|
||||
/*
|
||||
* Required delays following read cycles (number of BYTE_TEST reads)
|
||||
* Taken from Table 6.2 in Revision 1.5 (07-11-08) of the LAN9118 datasheet.
|
||||
* Where no delay listed, 0 has been assumed.
|
||||
*/
|
||||
#define LAN9118_RX_DATA_RD_DELAY 3
|
||||
#define LAN9118_RX_STATUS_RD_DELAY 3
|
||||
#define LAN9118_RX_STATUS_PEEK_RD_DELAY 0
|
||||
#define LAN9118_TX_DATA_RD_DELAY 0
|
||||
#define LAN9118_TX_STATUS_RD_DELAY 3
|
||||
#define LAN9118_TX_STATUS_PEEK_RD_DELAY 0
|
||||
#define LAN9118_ID_REV_RD_DELAY 0
|
||||
#define LAN9118_IRQ_CFG_RD_DELAY 0
|
||||
#define LAN9118_INT_STS_RD_DELAY 0
|
||||
#define LAN9118_INT_EN_RD_DELAY 0
|
||||
#define LAN9118_BYTE_TEST_RD_DELAY 0
|
||||
#define LAN9118_FIFO_INT_RD_DELAY 0
|
||||
#define LAN9118_RX_CFG_RD_DELAY 0
|
||||
#define LAN9118_TX_CFG_RD_DELAY 0
|
||||
#define LAN9118_HW_CFG_RD_DELAY 0
|
||||
#define LAN9118_RX_DP_CTL_RD_DELAY 0
|
||||
#define LAN9118_RX_FIFO_INF_RD_DELAY 0
|
||||
#define LAN9118_TX_FIFO_INF_RD_DELAY 0
|
||||
#define LAN9118_PMT_CTRL_RD_DELAY 0
|
||||
#define LAN9118_GPIO_CFG_RD_DELAY 0
|
||||
#define LAN9118_GPT_CFG_RD_DELAY 0
|
||||
#define LAN9118_GPT_CNT_RD_DELAY 0
|
||||
#define LAN9118_WORD_SWAP_RD_DELAY 0
|
||||
#define LAN9118_FREE_RUN_RD_DELAY 0
|
||||
#define LAN9118_RX_DROP_RD_DELAY 4
|
||||
#define LAN9118_MAC_CSR_CMD_RD_DELAY 0
|
||||
#define LAN9118_MAC_CSR_DATA_RD_DELAY 0
|
||||
#define LAN9118_AFC_CFG_RD_DELAY 0
|
||||
#define LAN9118_E2P_CMD_RD_DELAY 0
|
||||
#define LAN9118_E2P_DATA_RD_DELAY 0
|
||||
|
||||
// Receiver Status bits
|
||||
#define RXSTATUS_CRC_ERROR BIT1 // Cyclic Redundancy Check Error
|
||||
|
@ -87,8 +158,8 @@
|
|||
#define TXSTATUS_PTAG_MASK (0xFFFF0000) // Mask for Unique ID of packets (So we know who the packets are for)
|
||||
|
||||
// ID_REV register bits
|
||||
#define IDREV_ID ((MmioRead32(LAN9118_ID_REV) & 0xFFFF0000) >> 16)
|
||||
#define IDREV_REV (MmioRead32(LAN9118_ID_REV) & 0x0000FFFF)
|
||||
#define IDREV_ID ((Lan9118MmioRead32(LAN9118_ID_REV) & 0xFFFF0000) >> 16)
|
||||
#define IDREV_REV (Lan9118MmioRead32(LAN9118_ID_REV) & 0x0000FFFF)
|
||||
|
||||
// Interrupt Config Register bits
|
||||
#define IRQCFG_IRQ_TYPE BIT0 // IRQ Buffer type
|
||||
|
|
|
@ -98,7 +98,7 @@ IndirectMACRead32 (
|
|||
ASSERT(Index <= 12);
|
||||
|
||||
// Wait until CSR busy bit is cleared
|
||||
while ((MmioRead32 (LAN9118_MAC_CSR_CMD) & MAC_CSR_BUSY) == MAC_CSR_BUSY);
|
||||
while ((Lan9118MmioRead32 (LAN9118_MAC_CSR_CMD) & MAC_CSR_BUSY) == MAC_CSR_BUSY);
|
||||
|
||||
// Set CSR busy bit to ensure read will occur
|
||||
// Set the R/W bit to indicate we are reading
|
||||
|
@ -106,13 +106,61 @@ IndirectMACRead32 (
|
|||
MacCSR = MAC_CSR_BUSY | MAC_CSR_READ | MAC_CSR_ADDR(Index);
|
||||
|
||||
// Write to the register
|
||||
MmioWrite32 (LAN9118_MAC_CSR_CMD, MacCSR);
|
||||
Lan9118MmioWrite32 (LAN9118_MAC_CSR_CMD, MacCSR);
|
||||
|
||||
// Wait until CSR busy bit is cleared
|
||||
while ((MmioRead32 (LAN9118_MAC_CSR_CMD) & MAC_CSR_BUSY) == MAC_CSR_BUSY);
|
||||
while ((Lan9118MmioRead32 (LAN9118_MAC_CSR_CMD) & MAC_CSR_BUSY) == MAC_CSR_BUSY);
|
||||
|
||||
// Now read from data register to get read value
|
||||
return MmioRead32 (LAN9118_MAC_CSR_DATA);
|
||||
return Lan9118MmioRead32 (LAN9118_MAC_CSR_DATA);
|
||||
}
|
||||
|
||||
/*
|
||||
* LAN9118 chips have special restrictions on some back-to-back Write/Read or
|
||||
* Read/Read pairs of accesses. After a read or write that changes the state of
|
||||
* the device, there is a period in which stale values may be returned in
|
||||
* response to a read. This period is dependent on the registers accessed.
|
||||
*
|
||||
* We must delay prior reads by this period. This can either be achieved by
|
||||
* timer-based delays, or by performing dummy reads of the BYTE_TEST register,
|
||||
* for which the recommended number of reads is described in the LAN9118 data
|
||||
* sheet. This is required in addition to any memory barriers.
|
||||
*
|
||||
* This function performs a number of dummy reads of the BYTE_TEST register, as
|
||||
* a building block for the above.
|
||||
*/
|
||||
VOID
|
||||
WaitDummyReads (
|
||||
UINTN Count
|
||||
)
|
||||
{
|
||||
while (Count--)
|
||||
MmioRead32(LAN9118_BYTE_TEST);
|
||||
}
|
||||
|
||||
UINT32
|
||||
Lan9118RawMmioRead32(
|
||||
UINTN Address,
|
||||
UINTN Delay
|
||||
)
|
||||
{
|
||||
UINT32 Value;
|
||||
|
||||
Value = MmioRead32(Address);
|
||||
WaitDummyReads(Delay);
|
||||
return Value;
|
||||
}
|
||||
|
||||
UINT32
|
||||
Lan9118RawMmioWrite32(
|
||||
UINTN Address,
|
||||
UINT32 Value,
|
||||
UINTN Delay
|
||||
)
|
||||
{
|
||||
MmioWrite32(Address, Value);
|
||||
WaitDummyReads(Delay);
|
||||
return Value;
|
||||
}
|
||||
|
||||
// Function to write to MAC indirect registers
|
||||
|
@ -129,7 +177,7 @@ IndirectMACWrite32 (
|
|||
ASSERT(Index <= 12);
|
||||
|
||||
// Wait until CSR busy bit is cleared
|
||||
while ((MmioRead32 (LAN9118_MAC_CSR_CMD) & MAC_CSR_BUSY) == MAC_CSR_BUSY);
|
||||
while ((Lan9118MmioRead32 (LAN9118_MAC_CSR_CMD) & MAC_CSR_BUSY) == MAC_CSR_BUSY);
|
||||
|
||||
// Set CSR busy bit to ensure read will occur
|
||||
// Set the R/W bit to indicate we are writing
|
||||
|
@ -137,13 +185,13 @@ IndirectMACWrite32 (
|
|||
MacCSR = MAC_CSR_BUSY | MAC_CSR_WRITE | MAC_CSR_ADDR(Index);
|
||||
|
||||
// Now write the value to the register before issuing the write command
|
||||
ValueWritten = MmioWrite32 (LAN9118_MAC_CSR_DATA, Value);
|
||||
ValueWritten = Lan9118MmioWrite32 (LAN9118_MAC_CSR_DATA, Value);
|
||||
|
||||
// Write the config to the register
|
||||
MmioWrite32 (LAN9118_MAC_CSR_CMD, MacCSR);
|
||||
Lan9118MmioWrite32 (LAN9118_MAC_CSR_CMD, MacCSR);
|
||||
|
||||
// Wait until CSR busy bit is cleared
|
||||
while ((MmioRead32 (LAN9118_MAC_CSR_CMD) & MAC_CSR_BUSY) == MAC_CSR_BUSY);
|
||||
while ((Lan9118MmioRead32 (LAN9118_MAC_CSR_CMD) & MAC_CSR_BUSY) == MAC_CSR_BUSY);
|
||||
|
||||
return ValueWritten;
|
||||
}
|
||||
|
@ -235,23 +283,22 @@ IndirectEEPROMRead32 (
|
|||
EepromCmd |= E2P_EPC_ADDRESS(Index);
|
||||
|
||||
// Write to Eeprom command register
|
||||
MmioWrite32 (LAN9118_E2P_CMD, EepromCmd);
|
||||
MemoryFence();
|
||||
Lan9118MmioWrite32 (LAN9118_E2P_CMD, EepromCmd);
|
||||
|
||||
// Wait until operation has completed
|
||||
while (MmioRead32 (LAN9118_E2P_CMD) & E2P_EPC_BUSY);
|
||||
while (Lan9118MmioRead32 (LAN9118_E2P_CMD) & E2P_EPC_BUSY);
|
||||
|
||||
// Check that operation didn't time out
|
||||
if (MmioRead32 (LAN9118_E2P_CMD) & E2P_EPC_TIMEOUT) {
|
||||
if (Lan9118MmioRead32 (LAN9118_E2P_CMD) & E2P_EPC_TIMEOUT) {
|
||||
DEBUG ((EFI_D_ERROR, "EEPROM Operation Timed out: Read command on index %x\n",Index));
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Wait until operation has completed
|
||||
while (MmioRead32 (LAN9118_E2P_CMD) & E2P_EPC_BUSY);
|
||||
while (Lan9118MmioRead32 (LAN9118_E2P_CMD) & E2P_EPC_BUSY);
|
||||
|
||||
// Finally read the value
|
||||
return MmioRead32 (LAN9118_E2P_DATA);
|
||||
return Lan9118MmioRead32 (LAN9118_E2P_DATA);
|
||||
}
|
||||
|
||||
// Function to write to EEPROM memory
|
||||
|
@ -267,7 +314,7 @@ IndirectEEPROMWrite32 (
|
|||
ValueWritten = 0;
|
||||
|
||||
// Read the EEPROM Command register
|
||||
EepromCmd = MmioRead32 (LAN9118_E2P_CMD);
|
||||
EepromCmd = Lan9118MmioRead32 (LAN9118_E2P_CMD);
|
||||
|
||||
// Set the busy bit to ensure read will occur
|
||||
EepromCmd |= ((UINT32)1 << 31);
|
||||
|
@ -280,23 +327,22 @@ IndirectEEPROMWrite32 (
|
|||
EepromCmd |= (Index & 0xF);
|
||||
|
||||
// Write the value to the data register first
|
||||
ValueWritten = MmioWrite32 (LAN9118_E2P_DATA, Value);
|
||||
ValueWritten = Lan9118MmioWrite32 (LAN9118_E2P_DATA, Value);
|
||||
|
||||
// Write to Eeprom command register
|
||||
MmioWrite32 (LAN9118_E2P_CMD, EepromCmd);
|
||||
MemoryFence();
|
||||
Lan9118MmioWrite32 (LAN9118_E2P_CMD, EepromCmd);
|
||||
|
||||
// Wait until operation has completed
|
||||
while (MmioRead32 (LAN9118_E2P_CMD) & E2P_EPC_BUSY);
|
||||
while (Lan9118MmioRead32 (LAN9118_E2P_CMD) & E2P_EPC_BUSY);
|
||||
|
||||
// Check that operation didn't time out
|
||||
if (MmioRead32 (LAN9118_E2P_CMD) & E2P_EPC_TIMEOUT) {
|
||||
if (Lan9118MmioRead32 (LAN9118_E2P_CMD) & E2P_EPC_TIMEOUT) {
|
||||
DEBUG ((EFI_D_ERROR, "EEPROM Operation Timed out: Write command at memloc 0x%x, with value 0x%x\n",Index, Value));
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Wait until operation has completed
|
||||
while (MmioRead32 (LAN9118_E2P_CMD) & E2P_EPC_BUSY);
|
||||
while (Lan9118MmioRead32 (LAN9118_E2P_CMD) & E2P_EPC_BUSY);
|
||||
|
||||
return ValueWritten;
|
||||
}
|
||||
|
@ -359,17 +405,15 @@ Lan9118Initialize (
|
|||
UINT64 DefaultMacAddress;
|
||||
|
||||
// Attempt to wake-up the device if it is in a lower power state
|
||||
if (((MmioRead32 (LAN9118_PMT_CTRL) & MPTCTRL_PM_MODE_MASK) >> 12) != 0) {
|
||||
if (((Lan9118MmioRead32 (LAN9118_PMT_CTRL) & MPTCTRL_PM_MODE_MASK) >> 12) != 0) {
|
||||
DEBUG ((DEBUG_NET, "Waking from reduced power state.\n"));
|
||||
MmioWrite32 (LAN9118_BYTE_TEST, 0xFFFFFFFF);
|
||||
MemoryFence();
|
||||
Lan9118MmioWrite32 (LAN9118_BYTE_TEST, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
// Check that device is active
|
||||
Retries = 20;
|
||||
while ((MmioRead32 (LAN9118_PMT_CTRL) & MPTCTRL_READY) == 0 && --Retries) {
|
||||
while ((Lan9118MmioRead32 (LAN9118_PMT_CTRL) & MPTCTRL_READY) == 0 && --Retries) {
|
||||
gBS->Stall (LAN9118_STALL);
|
||||
MemoryFence();
|
||||
}
|
||||
if (!Retries) {
|
||||
return EFI_TIMEOUT;
|
||||
|
@ -377,9 +421,8 @@ Lan9118Initialize (
|
|||
|
||||
// Check that EEPROM isn't active
|
||||
Retries = 20;
|
||||
while ((MmioRead32 (LAN9118_E2P_CMD) & E2P_EPC_BUSY) && --Retries){
|
||||
while ((Lan9118MmioRead32 (LAN9118_E2P_CMD) & E2P_EPC_BUSY) && --Retries){
|
||||
gBS->Stall (LAN9118_STALL);
|
||||
MemoryFence();
|
||||
}
|
||||
if (!Retries) {
|
||||
return EFI_TIMEOUT;
|
||||
|
@ -387,7 +430,7 @@ Lan9118Initialize (
|
|||
|
||||
// Check if a MAC address was loaded from EEPROM, and if it was, set it as the
|
||||
// current address.
|
||||
if ((MmioRead32 (LAN9118_E2P_CMD) & E2P_EPC_MAC_ADDRESS_LOADED) == 0) {
|
||||
if ((Lan9118MmioRead32 (LAN9118_E2P_CMD) & E2P_EPC_MAC_ADDRESS_LOADED) == 0) {
|
||||
DEBUG ((EFI_D_ERROR, "Warning: There was an error detecting EEPROM or loading the MAC Address.\n"));
|
||||
|
||||
// If we had an address before (set by StationAddess), continue to use it
|
||||
|
@ -407,9 +450,9 @@ Lan9118Initialize (
|
|||
}
|
||||
|
||||
// Clear and acknowledge interrupts
|
||||
MmioWrite32 (LAN9118_INT_EN, 0);
|
||||
MmioWrite32 (LAN9118_IRQ_CFG, 0);
|
||||
MmioWrite32 (LAN9118_INT_STS, 0xFFFFFFFF);
|
||||
Lan9118MmioWrite32 (LAN9118_INT_EN, 0);
|
||||
Lan9118MmioWrite32 (LAN9118_IRQ_CFG, 0);
|
||||
Lan9118MmioWrite32 (LAN9118_INT_STS, 0xFFFFFFFF);
|
||||
|
||||
// Do self tests here?
|
||||
|
||||
|
@ -436,7 +479,7 @@ SoftReset (
|
|||
StopRx (STOP_RX_CLEAR, Snp); // Clear receiver FIFO
|
||||
|
||||
// Issue the reset
|
||||
HwConf = MmioRead32 (LAN9118_HW_CFG);
|
||||
HwConf = Lan9118MmioRead32 (LAN9118_HW_CFG);
|
||||
HwConf |= 1;
|
||||
|
||||
// Set the Must Be One (MBO) bit
|
||||
|
@ -445,16 +488,14 @@ SoftReset (
|
|||
}
|
||||
|
||||
// Check that EEPROM isn't active
|
||||
while (MmioRead32 (LAN9118_E2P_CMD) & E2P_EPC_BUSY);
|
||||
while (Lan9118MmioRead32 (LAN9118_E2P_CMD) & E2P_EPC_BUSY);
|
||||
|
||||
// Write the configuration
|
||||
MmioWrite32 (LAN9118_HW_CFG, HwConf);
|
||||
MemoryFence();
|
||||
Lan9118MmioWrite32 (LAN9118_HW_CFG, HwConf);
|
||||
|
||||
// Wait for reset to complete
|
||||
while (MmioRead32 (LAN9118_HW_CFG) & HWCFG_SRST) {
|
||||
while (Lan9118MmioRead32 (LAN9118_HW_CFG) & HWCFG_SRST) {
|
||||
|
||||
MemoryFence();
|
||||
gBS->Stall (LAN9118_STALL);
|
||||
ResetTime += 1;
|
||||
|
||||
|
@ -466,15 +507,15 @@ SoftReset (
|
|||
}
|
||||
|
||||
// Check that EEPROM isn't active
|
||||
while (MmioRead32 (LAN9118_E2P_CMD) & E2P_EPC_BUSY);
|
||||
while (Lan9118MmioRead32 (LAN9118_E2P_CMD) & E2P_EPC_BUSY);
|
||||
|
||||
// TODO we probably need to re-set the mac address here.
|
||||
|
||||
// Clear and acknowledge all interrupts
|
||||
if (Flags & SOFT_RESET_CLEAR_INT) {
|
||||
MmioWrite32 (LAN9118_INT_EN, 0);
|
||||
MmioWrite32 (LAN9118_IRQ_CFG, 0);
|
||||
MmioWrite32 (LAN9118_INT_STS, 0xFFFFFFFF);
|
||||
Lan9118MmioWrite32 (LAN9118_INT_EN, 0);
|
||||
Lan9118MmioWrite32 (LAN9118_IRQ_CFG, 0);
|
||||
Lan9118MmioWrite32 (LAN9118_INT_STS, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
// Do self tests here?
|
||||
|
@ -497,13 +538,13 @@ PhySoftReset (
|
|||
|
||||
// PMT PHY reset takes precedence over BCR
|
||||
if (Flags & PHY_RESET_PMT) {
|
||||
PmtCtrl = MmioRead32 (LAN9118_PMT_CTRL);
|
||||
PmtCtrl = Lan9118MmioRead32 (LAN9118_PMT_CTRL);
|
||||
PmtCtrl |= MPTCTRL_PHY_RST;
|
||||
MmioWrite32 (LAN9118_PMT_CTRL,PmtCtrl);
|
||||
Lan9118MmioWrite32 (LAN9118_PMT_CTRL,PmtCtrl);
|
||||
|
||||
// Wait for completion
|
||||
while (MmioRead32 (LAN9118_PMT_CTRL) & MPTCTRL_PHY_RST) {
|
||||
MemoryFence();
|
||||
while (Lan9118MmioRead32 (LAN9118_PMT_CTRL) & MPTCTRL_PHY_RST) {
|
||||
gBS->Stall (LAN9118_STALL);
|
||||
}
|
||||
// PHY Basic Control Register reset
|
||||
} else if (Flags & PHY_RESET_BCR) {
|
||||
|
@ -511,15 +552,15 @@ PhySoftReset (
|
|||
|
||||
// Wait for completion
|
||||
while (IndirectPHYRead32 (PHY_INDEX_BASIC_CTRL) & PHYCR_RESET) {
|
||||
MemoryFence();
|
||||
gBS->Stall (LAN9118_STALL);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear and acknowledge all interrupts
|
||||
if (Flags & PHY_SOFT_RESET_CLEAR_INT) {
|
||||
MmioWrite32 (LAN9118_INT_EN, 0);
|
||||
MmioWrite32 (LAN9118_IRQ_CFG, 0);
|
||||
MmioWrite32 (LAN9118_INT_STS, 0xFFFFFFFF);
|
||||
Lan9118MmioWrite32 (LAN9118_INT_EN, 0);
|
||||
Lan9118MmioWrite32 (LAN9118_IRQ_CFG, 0);
|
||||
Lan9118MmioWrite32 (LAN9118_INT_STS, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
@ -537,15 +578,14 @@ ConfigureHardware (
|
|||
|
||||
// Check if we want to use LEDs on GPIO
|
||||
if (Flags & HW_CONF_USE_LEDS) {
|
||||
GpioConf = MmioRead32 (LAN9118_GPIO_CFG);
|
||||
GpioConf = Lan9118MmioRead32 (LAN9118_GPIO_CFG);
|
||||
|
||||
// Enable GPIO as LEDs and Config as Push-Pull driver
|
||||
GpioConf |= GPIO_GPIO0_PUSH_PULL | GPIO_GPIO1_PUSH_PULL | GPIO_GPIO2_PUSH_PULL |
|
||||
GPIO_LED1_ENABLE | GPIO_LED2_ENABLE | GPIO_LED3_ENABLE;
|
||||
|
||||
// Write the configuration
|
||||
MmioWrite32 (LAN9118_GPIO_CFG, GpioConf);
|
||||
MemoryFence();
|
||||
Lan9118MmioWrite32 (LAN9118_GPIO_CFG, GpioConf);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
@ -588,7 +628,6 @@ AutoNegotiate (
|
|||
// Wait until it is up or until Time Out
|
||||
Retries = FixedPcdGet32 (PcdLan9118DefaultNegotiationTimeout) / LAN9118_STALL;
|
||||
while ((IndirectPHYRead32 (PHY_INDEX_BASIC_STATUS) & PHYSTS_LINK_STS) == 0) {
|
||||
MemoryFence();
|
||||
gBS->Stall (LAN9118_STALL);
|
||||
Retries--;
|
||||
if (!Retries) {
|
||||
|
@ -672,10 +711,9 @@ StopTx (
|
|||
|
||||
// Check if we want to clear tx
|
||||
if (Flags & STOP_TX_CLEAR) {
|
||||
TxCfg = MmioRead32 (LAN9118_TX_CFG);
|
||||
TxCfg = Lan9118MmioRead32 (LAN9118_TX_CFG);
|
||||
TxCfg |= TXCFG_TXS_DUMP | TXCFG_TXD_DUMP;
|
||||
MmioWrite32 (LAN9118_TX_CFG, TxCfg);
|
||||
MemoryFence();
|
||||
Lan9118MmioWrite32 (LAN9118_TX_CFG, TxCfg);
|
||||
}
|
||||
|
||||
// Check if already stopped
|
||||
|
@ -689,15 +727,14 @@ StopTx (
|
|||
}
|
||||
|
||||
if (Flags & STOP_TX_CFG) {
|
||||
TxCfg = MmioRead32 (LAN9118_TX_CFG);
|
||||
TxCfg = Lan9118MmioRead32 (LAN9118_TX_CFG);
|
||||
|
||||
if (TxCfg & TXCFG_TX_ON) {
|
||||
TxCfg |= TXCFG_STOP_TX;
|
||||
MmioWrite32 (LAN9118_TX_CFG, TxCfg);
|
||||
MemoryFence();
|
||||
Lan9118MmioWrite32 (LAN9118_TX_CFG, TxCfg);
|
||||
|
||||
// Wait for Tx to finish transmitting
|
||||
while (MmioRead32 (LAN9118_TX_CFG) & TXCFG_STOP_TX);
|
||||
while (Lan9118MmioRead32 (LAN9118_TX_CFG) & TXCFG_STOP_TX);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -726,12 +763,11 @@ StopRx (
|
|||
|
||||
// Check if we want to clear receiver FIFOs
|
||||
if (Flags & STOP_RX_CLEAR) {
|
||||
RxCfg = MmioRead32 (LAN9118_RX_CFG);
|
||||
RxCfg = Lan9118MmioRead32 (LAN9118_RX_CFG);
|
||||
RxCfg |= RXCFG_RX_DUMP;
|
||||
MmioWrite32 (LAN9118_RX_CFG, RxCfg);
|
||||
MemoryFence();
|
||||
Lan9118MmioWrite32 (LAN9118_RX_CFG, RxCfg);
|
||||
|
||||
while (MmioRead32 (LAN9118_RX_CFG) & RXCFG_RX_DUMP);
|
||||
while (Lan9118MmioRead32 (LAN9118_RX_CFG) & RXCFG_RX_DUMP);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
@ -752,31 +788,26 @@ StartTx (
|
|||
|
||||
// Check if we want to clear tx
|
||||
if (Flags & START_TX_CLEAR) {
|
||||
TxCfg = MmioRead32 (LAN9118_TX_CFG);
|
||||
TxCfg = Lan9118MmioRead32 (LAN9118_TX_CFG);
|
||||
TxCfg |= TXCFG_TXS_DUMP | TXCFG_TXD_DUMP;
|
||||
MmioWrite32 (LAN9118_TX_CFG, TxCfg);
|
||||
MemoryFence();
|
||||
Lan9118MmioWrite32 (LAN9118_TX_CFG, TxCfg);
|
||||
}
|
||||
|
||||
// Check if tx was started from MAC and enable if not
|
||||
if (Flags & START_TX_MAC) {
|
||||
MacCsr = IndirectMACRead32 (INDIRECT_MAC_INDEX_CR);
|
||||
MemoryFence();
|
||||
if ((MacCsr & MACCR_TX_EN) == 0) {
|
||||
MacCsr |= MACCR_TX_EN;
|
||||
IndirectMACWrite32 (INDIRECT_MAC_INDEX_CR, MacCsr);
|
||||
MemoryFence();
|
||||
}
|
||||
}
|
||||
|
||||
// Check if tx was started from TX_CFG and enable if not
|
||||
if (Flags & START_TX_CFG) {
|
||||
TxCfg = MmioRead32 (LAN9118_TX_CFG);
|
||||
MemoryFence();
|
||||
TxCfg = Lan9118MmioRead32 (LAN9118_TX_CFG);
|
||||
if ((TxCfg & TXCFG_TX_ON) == 0) {
|
||||
TxCfg |= TXCFG_TX_ON;
|
||||
MmioWrite32 (LAN9118_TX_CFG, TxCfg);
|
||||
MemoryFence();
|
||||
Lan9118MmioWrite32 (LAN9118_TX_CFG, TxCfg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -803,17 +834,15 @@ StartRx (
|
|||
if ((MacCsr & MACCR_RX_EN) == 0) {
|
||||
// Check if we want to clear receiver FIFOs before starting
|
||||
if (Flags & START_RX_CLEAR) {
|
||||
RxCfg = MmioRead32 (LAN9118_RX_CFG);
|
||||
RxCfg = Lan9118MmioRead32 (LAN9118_RX_CFG);
|
||||
RxCfg |= RXCFG_RX_DUMP;
|
||||
MmioWrite32 (LAN9118_RX_CFG, RxCfg);
|
||||
MemoryFence();
|
||||
Lan9118MmioWrite32 (LAN9118_RX_CFG, RxCfg);
|
||||
|
||||
while (MmioRead32 (LAN9118_RX_CFG) & RXCFG_RX_DUMP);
|
||||
while (Lan9118MmioRead32 (LAN9118_RX_CFG) & RXCFG_RX_DUMP);
|
||||
}
|
||||
|
||||
MacCsr |= MACCR_RX_EN;
|
||||
IndirectMACWrite32 (INDIRECT_MAC_INDEX_CR, MacCsr);
|
||||
MemoryFence();
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
@ -830,7 +859,7 @@ TxDataFreeSpace (
|
|||
UINT32 FreeSpace;
|
||||
|
||||
// Get the amount of free space from information register
|
||||
TxInf = MmioRead32 (LAN9118_TX_FIFO_INF);
|
||||
TxInf = Lan9118MmioRead32 (LAN9118_TX_FIFO_INF);
|
||||
FreeSpace = (TxInf & TXFIFOINF_TDFREE_MASK);
|
||||
|
||||
return FreeSpace; // Value in bytes
|
||||
|
@ -847,7 +876,7 @@ TxStatusUsedSpace (
|
|||
UINT32 UsedSpace;
|
||||
|
||||
// Get the amount of used space from information register
|
||||
TxInf = MmioRead32 (LAN9118_TX_FIFO_INF);
|
||||
TxInf = Lan9118MmioRead32 (LAN9118_TX_FIFO_INF);
|
||||
UsedSpace = (TxInf & TXFIFOINF_TXSUSED_MASK) >> 16;
|
||||
|
||||
return UsedSpace << 2; // Value in bytes
|
||||
|
@ -864,7 +893,7 @@ RxDataUsedSpace (
|
|||
UINT32 UsedSpace;
|
||||
|
||||
// Get the amount of used space from information register
|
||||
RxInf = MmioRead32 (LAN9118_RX_FIFO_INF);
|
||||
RxInf = Lan9118MmioRead32 (LAN9118_RX_FIFO_INF);
|
||||
UsedSpace = (RxInf & RXFIFOINF_RXDUSED_MASK);
|
||||
|
||||
return UsedSpace; // Value in bytes (rounded up to nearest DWORD)
|
||||
|
@ -881,7 +910,7 @@ RxStatusUsedSpace (
|
|||
UINT32 UsedSpace;
|
||||
|
||||
// Get the amount of used space from information register
|
||||
RxInf = MmioRead32 (LAN9118_RX_FIFO_INF);
|
||||
RxInf = Lan9118MmioRead32 (LAN9118_RX_FIFO_INF);
|
||||
UsedSpace = (RxInf & RXFIFOINF_RXSUSED_MASK) >> 16;
|
||||
|
||||
return UsedSpace << 2; // Value in bytes
|
||||
|
@ -919,7 +948,7 @@ ChangeFifoAllocation (
|
|||
// If we use the FIFOs (always use this first)
|
||||
if (Flags & ALLOC_USE_FIFOS) {
|
||||
// Read the current value of allocation
|
||||
HwConf = MmioRead32 (LAN9118_HW_CFG);
|
||||
HwConf = Lan9118MmioRead32 (LAN9118_HW_CFG);
|
||||
TxFifoOption = (HwConf >> 16) & 0xF;
|
||||
|
||||
// Choose the correct size (always use larger than requested if possible)
|
||||
|
@ -1002,8 +1031,7 @@ ChangeFifoAllocation (
|
|||
// Clear and assign the new size option
|
||||
HwConf &= ~(0xF0000);
|
||||
HwConf |= ((TxFifoOption & 0xF) << 16);
|
||||
MmioWrite32 (LAN9118_HW_CFG, HwConf);
|
||||
MemoryFence();
|
||||
Lan9118MmioWrite32 (LAN9118_HW_CFG, HwConf);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -38,6 +38,23 @@ GenEtherCrc32 (
|
|||
IN UINT32 AddrLen
|
||||
);
|
||||
|
||||
UINT32
|
||||
Lan9118RawMmioRead32(
|
||||
UINTN Address,
|
||||
UINTN Delay
|
||||
);
|
||||
#define Lan9118MmioRead32(a) \
|
||||
Lan9118RawMmioRead32(a, a ## _RD_DELAY)
|
||||
|
||||
UINT32
|
||||
Lan9118RawMmioWrite32(
|
||||
UINTN Address,
|
||||
UINT32 Value,
|
||||
UINTN Delay
|
||||
);
|
||||
#define Lan9118MmioWrite32(a, v) \
|
||||
Lan9118RawMmioWrite32(a, v, a ## _WR_DELAY)
|
||||
|
||||
/* ------------------ MAC CSR Access ------------------- */
|
||||
|
||||
// Read from MAC indirect registers
|
||||
|
|
|
@ -338,6 +338,8 @@ InitializePciHostBridge (
|
|||
UINTN Index;
|
||||
PCI_ROOT_BRIDGE_APERTURE *MemApertures[4];
|
||||
UINTN MemApertureIndex;
|
||||
BOOLEAN ResourceAssigned;
|
||||
LIST_ENTRY *Link;
|
||||
|
||||
RootBridges = PciHostBridgeGetRootBridges (&RootBridgeCount);
|
||||
if ((RootBridges == NULL) || (RootBridgeCount == 0)) {
|
||||
|
@ -358,27 +360,7 @@ InitializePciHostBridge (
|
|||
HostBridge->Signature = PCI_HOST_BRIDGE_SIGNATURE;
|
||||
HostBridge->CanRestarted = TRUE;
|
||||
InitializeListHead (&HostBridge->RootBridges);
|
||||
|
||||
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;
|
||||
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&HostBridge->Handle,
|
||||
&gEfiPciHostBridgeResourceAllocationProtocolGuid, &HostBridge->ResAlloc,
|
||||
NULL
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
if (EFI_ERROR (Status)) {
|
||||
FreePool (HostBridge);
|
||||
PciHostBridgeFreeRootBridges (RootBridges, RootBridgeCount);
|
||||
return Status;
|
||||
}
|
||||
ResourceAssigned = FALSE;
|
||||
|
||||
//
|
||||
// Create Root Bridge Device Handle in this Host Bridge
|
||||
|
@ -387,18 +369,39 @@ InitializePciHostBridge (
|
|||
//
|
||||
// Create Root Bridge Handle Instance
|
||||
//
|
||||
RootBridge = CreateRootBridge (&RootBridges[Index], HostBridge->Handle);
|
||||
RootBridge = CreateRootBridge (&RootBridges[Index]);
|
||||
ASSERT (RootBridge != NULL);
|
||||
if (RootBridge == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (RootBridges[Index].Io.Limit > RootBridges[Index].Io.Base) {
|
||||
//
|
||||
// Make sure all root bridges share the same ResourceAssigned value.
|
||||
//
|
||||
if (Index == 0) {
|
||||
ResourceAssigned = RootBridges[Index].ResourceAssigned;
|
||||
} else {
|
||||
ASSERT (ResourceAssigned == RootBridges[Index].ResourceAssigned);
|
||||
}
|
||||
|
||||
if (RootBridges[Index].Io.Base <= RootBridges[Index].Io.Limit) {
|
||||
Status = AddIoSpace (
|
||||
RootBridges[Index].Io.Base,
|
||||
RootBridges[Index].Io.Limit - RootBridges[Index].Io.Base + 1
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
if (ResourceAssigned) {
|
||||
Status = gDS->AllocateIoSpace (
|
||||
EfiGcdAllocateAddress,
|
||||
EfiGcdIoTypeIo,
|
||||
0,
|
||||
RootBridges[Index].Io.Limit - RootBridges[Index].Io.Base + 1,
|
||||
&RootBridges[Index].Io.Base,
|
||||
gImageHandle,
|
||||
NULL
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -413,7 +416,7 @@ InitializePciHostBridge (
|
|||
MemApertures[3] = &RootBridges[Index].PMemAbove4G;
|
||||
|
||||
for (MemApertureIndex = 0; MemApertureIndex < sizeof (MemApertures) / sizeof (MemApertures[0]); MemApertureIndex++) {
|
||||
if (MemApertures[MemApertureIndex]->Limit > MemApertures[MemApertureIndex]->Base) {
|
||||
if (MemApertures[MemApertureIndex]->Base <= MemApertures[MemApertureIndex]->Limit) {
|
||||
Status = AddMemoryMappedIoSpace (
|
||||
MemApertures[MemApertureIndex]->Base,
|
||||
MemApertures[MemApertureIndex]->Limit - MemApertures[MemApertureIndex]->Base + 1,
|
||||
|
@ -428,11 +431,55 @@ InitializePciHostBridge (
|
|||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_WARN, "PciHostBridge driver failed to set EFI_MEMORY_UC to MMIO aperture - %r.\n", Status));
|
||||
}
|
||||
if (ResourceAssigned) {
|
||||
Status = gDS->AllocateMemorySpace (
|
||||
EfiGcdAllocateAddress,
|
||||
EfiGcdMemoryTypeMemoryMappedIo,
|
||||
0,
|
||||
MemApertures[MemApertureIndex]->Limit - MemApertures[MemApertureIndex]->Base + 1,
|
||||
&MemApertures[MemApertureIndex]->Base,
|
||||
gImageHandle,
|
||||
NULL
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// Insert Root Bridge Handle Instance
|
||||
//
|
||||
InsertTailList (&HostBridge->RootBridges, &RootBridge->Link);
|
||||
}
|
||||
|
||||
//
|
||||
// When resources were assigned, it's not needed to expose
|
||||
// PciHostBridgeResourceAllocation protocol.
|
||||
//
|
||||
if (!ResourceAssigned) {
|
||||
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;
|
||||
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&HostBridge->Handle,
|
||||
&gEfiPciHostBridgeResourceAllocationProtocolGuid, &HostBridge->ResAlloc,
|
||||
NULL
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
|
||||
for (Link = GetFirstNode (&HostBridge->RootBridges)
|
||||
; !IsNull (&HostBridge->RootBridges, Link)
|
||||
; Link = GetNextNode (&HostBridge->RootBridges, Link)
|
||||
) {
|
||||
RootBridge = ROOT_BRIDGE_FROM_LINK (Link);
|
||||
RootBridge->RootBridgeIo.ParentHandle = HostBridge->Handle;
|
||||
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&RootBridge->Handle,
|
||||
&gEfiDevicePathProtocolGuid, RootBridge->DevicePath,
|
||||
|
@ -440,7 +487,6 @@ InitializePciHostBridge (
|
|||
NULL
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
InsertTailList (&HostBridge->RootBridges, &RootBridge->Link);
|
||||
}
|
||||
PciHostBridgeFreeRootBridges (RootBridges, RootBridgeCount);
|
||||
return Status;
|
||||
|
|
|
@ -90,15 +90,13 @@ typedef struct {
|
|||
Construct the Pci Root Bridge instance.
|
||||
|
||||
@param Bridge The root bridge instance.
|
||||
@param HostBridgeHandle Handle to the HostBridge.
|
||||
|
||||
@return The pointer to PCI_ROOT_BRIDGE_INSTANCE just created
|
||||
or NULL if creation fails.
|
||||
**/
|
||||
PCI_ROOT_BRIDGE_INSTANCE *
|
||||
CreateRootBridge (
|
||||
IN PCI_ROOT_BRIDGE *Bridge,
|
||||
IN EFI_HANDLE HostBridgeHandle
|
||||
IN PCI_ROOT_BRIDGE *Bridge
|
||||
);
|
||||
|
||||
//
|
||||
|
|
|
@ -59,20 +59,19 @@ UINT8 mOutStride[] = {
|
|||
Construct the Pci Root Bridge instance.
|
||||
|
||||
@param Bridge The root bridge instance.
|
||||
@param HostBridgeHandle Handle to the HostBridge.
|
||||
|
||||
@return The pointer to PCI_ROOT_BRIDGE_INSTANCE just created
|
||||
or NULL if creation fails.
|
||||
**/
|
||||
PCI_ROOT_BRIDGE_INSTANCE *
|
||||
CreateRootBridge (
|
||||
IN PCI_ROOT_BRIDGE *Bridge,
|
||||
IN EFI_HANDLE HostBridgeHandle
|
||||
IN PCI_ROOT_BRIDGE *Bridge
|
||||
)
|
||||
{
|
||||
PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
|
||||
PCI_RESOURCE_TYPE Index;
|
||||
CHAR16 *DevicePathStr;
|
||||
PCI_ROOT_BRIDGE_APERTURE *Aperture;
|
||||
|
||||
DevicePathStr = NULL;
|
||||
|
||||
|
@ -95,57 +94,62 @@ CreateRootBridge (
|
|||
//
|
||||
// Make sure Mem and MemAbove4G apertures are valid
|
||||
//
|
||||
if (Bridge->Mem.Base < Bridge->Mem.Limit) {
|
||||
if (Bridge->Mem.Base <= Bridge->Mem.Limit) {
|
||||
ASSERT (Bridge->Mem.Limit < SIZE_4GB);
|
||||
if (Bridge->Mem.Limit >= SIZE_4GB) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (Bridge->MemAbove4G.Base < Bridge->MemAbove4G.Limit) {
|
||||
if (Bridge->MemAbove4G.Base <= Bridge->MemAbove4G.Limit) {
|
||||
ASSERT (Bridge->MemAbove4G.Base >= SIZE_4GB);
|
||||
if (Bridge->MemAbove4G.Base < SIZE_4GB) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (Bridge->PMem.Base < Bridge->PMem.Limit) {
|
||||
if (Bridge->PMem.Base <= Bridge->PMem.Limit) {
|
||||
ASSERT (Bridge->PMem.Limit < SIZE_4GB);
|
||||
if (Bridge->PMem.Limit >= SIZE_4GB) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (Bridge->PMemAbove4G.Base < Bridge->PMemAbove4G.Limit) {
|
||||
if (Bridge->PMemAbove4G.Base <= Bridge->PMemAbove4G.Limit) {
|
||||
ASSERT (Bridge->PMemAbove4G.Base >= SIZE_4GB);
|
||||
if (Bridge->PMemAbove4G.Base < SIZE_4GB) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ((Bridge->AllocationAttributes & EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM) != 0) {
|
||||
//
|
||||
// If this bit is set, then the PCI Root Bridge does not
|
||||
// support separate windows for Non-prefetchable and Prefetchable
|
||||
// memory.
|
||||
//
|
||||
ASSERT (Bridge->PMem.Base >= Bridge->PMem.Limit);
|
||||
ASSERT (Bridge->PMemAbove4G.Base >= Bridge->PMemAbove4G.Limit);
|
||||
if ((Bridge->PMem.Base < Bridge->PMem.Limit) ||
|
||||
(Bridge->PMemAbove4G.Base < Bridge->PMemAbove4G.Limit)
|
||||
) {
|
||||
return NULL;
|
||||
//
|
||||
// Ignore AllocationAttributes when resources were already assigned.
|
||||
//
|
||||
if (!Bridge->ResourceAssigned) {
|
||||
if ((Bridge->AllocationAttributes & EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM) != 0) {
|
||||
//
|
||||
// If this bit is set, then the PCI Root Bridge does not
|
||||
// support separate windows for Non-prefetchable and Prefetchable
|
||||
// memory.
|
||||
//
|
||||
ASSERT (Bridge->PMem.Base > Bridge->PMem.Limit);
|
||||
ASSERT (Bridge->PMemAbove4G.Base > Bridge->PMemAbove4G.Limit);
|
||||
if ((Bridge->PMem.Base <= Bridge->PMem.Limit) ||
|
||||
(Bridge->PMemAbove4G.Base <= Bridge->PMemAbove4G.Limit)
|
||||
) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((Bridge->AllocationAttributes & EFI_PCI_HOST_BRIDGE_MEM64_DECODE) == 0) {
|
||||
//
|
||||
// If this bit is not set, then the PCI Root Bridge does not support
|
||||
// 64 bit memory windows.
|
||||
//
|
||||
ASSERT (Bridge->MemAbove4G.Base >= Bridge->MemAbove4G.Limit);
|
||||
ASSERT (Bridge->PMemAbove4G.Base >= Bridge->PMemAbove4G.Limit);
|
||||
if ((Bridge->MemAbove4G.Base < Bridge->MemAbove4G.Limit) ||
|
||||
(Bridge->PMemAbove4G.Base < Bridge->PMemAbove4G.Limit)
|
||||
) {
|
||||
return NULL;
|
||||
if ((Bridge->AllocationAttributes & EFI_PCI_HOST_BRIDGE_MEM64_DECODE) == 0) {
|
||||
//
|
||||
// If this bit is not set, then the PCI Root Bridge does not support
|
||||
// 64 bit memory windows.
|
||||
//
|
||||
ASSERT (Bridge->MemAbove4G.Base > Bridge->MemAbove4G.Limit);
|
||||
ASSERT (Bridge->PMemAbove4G.Base > Bridge->PMemAbove4G.Limit);
|
||||
if ((Bridge->MemAbove4G.Base <= Bridge->MemAbove4G.Limit) ||
|
||||
(Bridge->PMemAbove4G.Base <= Bridge->PMemAbove4G.Limit)
|
||||
) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,17 +174,46 @@ CreateRootBridge (
|
|||
CopyMem (&RootBridge->Io, &Bridge->Io, sizeof (PCI_ROOT_BRIDGE_APERTURE));
|
||||
CopyMem (&RootBridge->Mem, &Bridge->Mem, sizeof (PCI_ROOT_BRIDGE_APERTURE));
|
||||
CopyMem (&RootBridge->MemAbove4G, &Bridge->MemAbove4G, sizeof (PCI_ROOT_BRIDGE_APERTURE));
|
||||
|
||||
CopyMem (&RootBridge->PMem, &Bridge->PMem, sizeof (PCI_ROOT_BRIDGE_APERTURE));
|
||||
CopyMem (&RootBridge->PMemAbove4G, &Bridge->PMemAbove4G, sizeof (PCI_ROOT_BRIDGE_APERTURE));
|
||||
|
||||
for (Index = TypeIo; Index < TypeMax; Index++) {
|
||||
RootBridge->ResAllocNode[Index].Type = Index;
|
||||
RootBridge->ResAllocNode[Index].Base = 0;
|
||||
RootBridge->ResAllocNode[Index].Length = 0;
|
||||
RootBridge->ResAllocNode[Index].Status = ResNone;
|
||||
switch (Index) {
|
||||
case TypeBus:
|
||||
Aperture = &RootBridge->Bus;
|
||||
break;
|
||||
case TypeIo:
|
||||
Aperture = &RootBridge->Io;
|
||||
break;
|
||||
case TypeMem32:
|
||||
Aperture = &RootBridge->Mem;
|
||||
break;
|
||||
case TypeMem64:
|
||||
Aperture = &RootBridge->MemAbove4G;
|
||||
break;
|
||||
case TypePMem32:
|
||||
Aperture = &RootBridge->PMem;
|
||||
break;
|
||||
case TypePMem64:
|
||||
Aperture = &RootBridge->PMemAbove4G;
|
||||
break;
|
||||
default:
|
||||
ASSERT (FALSE);
|
||||
break;
|
||||
}
|
||||
RootBridge->ResAllocNode[Index].Type = Index;
|
||||
if (Bridge->ResourceAssigned && (Aperture->Limit >= Aperture->Base)) {
|
||||
RootBridge->ResAllocNode[Index].Base = Aperture->Base;
|
||||
RootBridge->ResAllocNode[Index].Length = Aperture->Limit - Aperture->Base + 1;
|
||||
RootBridge->ResAllocNode[Index].Status = ResAllocated;
|
||||
} else {
|
||||
RootBridge->ResAllocNode[Index].Base = 0;
|
||||
RootBridge->ResAllocNode[Index].Length = 0;
|
||||
RootBridge->ResAllocNode[Index].Status = ResNone;
|
||||
}
|
||||
}
|
||||
|
||||
RootBridge->RootBridgeIo.SegmentNumber = Bridge->Segment;
|
||||
RootBridge->RootBridgeIo.ParentHandle = HostBridgeHandle;
|
||||
RootBridge->RootBridgeIo.PollMem = RootBridgeIoPollMem;
|
||||
RootBridge->RootBridgeIo.PollIo = RootBridgeIoPollIo;
|
||||
RootBridge->RootBridgeIo.Mem.Read = RootBridgeIoMemRead;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
SerialIo implementation for PCI or SIO UARTs.
|
||||
|
||||
Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||
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
|
||||
|
@ -442,27 +442,6 @@ SerialReceiveTransmit (
|
|||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Flush the serial hardware transmit FIFO and shift register.
|
||||
|
||||
@param SerialDevice The device to flush.
|
||||
**/
|
||||
VOID
|
||||
SerialFlushTransmitFifo (
|
||||
SERIAL_DEV *SerialDevice
|
||||
)
|
||||
{
|
||||
SERIAL_PORT_LSR Lsr;
|
||||
|
||||
//
|
||||
// Wait for the serial port to be ready, to make sure both the transmit FIFO
|
||||
// and shift register empty.
|
||||
//
|
||||
do {
|
||||
Lsr.Data = READ_LSR (SerialDevice);
|
||||
} while (Lsr.Bits.Temt == 0);
|
||||
}
|
||||
|
||||
//
|
||||
// Interface Functions
|
||||
//
|
||||
|
@ -503,8 +482,6 @@ SerialReset (
|
|||
|
||||
Tpl = gBS->RaiseTPL (TPL_NOTIFY);
|
||||
|
||||
SerialFlushTransmitFifo (SerialDevice);
|
||||
|
||||
//
|
||||
// Make sure DLAB is 0.
|
||||
//
|
||||
|
@ -683,8 +660,6 @@ SerialSetAttributes (
|
|||
|
||||
Tpl = gBS->RaiseTPL (TPL_NOTIFY);
|
||||
|
||||
SerialFlushTransmitFifo (SerialDevice);
|
||||
|
||||
//
|
||||
// Put serial port on Divisor Latch Mode
|
||||
//
|
||||
|
|
|
@ -38,6 +38,8 @@ typedef struct {
|
|||
///< Extended (4096-byte) Configuration Space.
|
||||
///< When TRUE, the root bridge supports
|
||||
///< 256-byte Configuration Space only.
|
||||
BOOLEAN ResourceAssigned; ///< Resource assignment status of the root bridge.
|
||||
///< Set to TRUE if Bus/IO/MMIO resources for root bridge have been assigned.
|
||||
UINT64 AllocationAttributes; ///< Allocation attributes.
|
||||
///< Refer to EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM and
|
||||
///< EFI_PCI_HOST_BRIDGE_MEM64_DECODE used by GetAllocAttributes()
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
/** @file
|
||||
Header file of OVMF instance of PciHostBridgeLib.
|
||||
|
||||
Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
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.
|
||||
|
||||
**/
|
||||
|
||||
PCI_ROOT_BRIDGE *
|
||||
ScanForRootBridges (
|
||||
UINTN *NumberOfRootBridges
|
||||
);
|
||||
|
||||
/**
|
||||
Initialize a PCI_ROOT_BRIDGE structure.
|
||||
|
||||
@param[in] Supports Supported attributes.
|
||||
|
||||
@param[in] Attributes Initial attributes.
|
||||
|
||||
@param[in] AllocAttributes Allocation attributes.
|
||||
|
||||
@param[in] RootBusNumber The bus number to store in RootBus.
|
||||
|
||||
@param[in] MaxSubBusNumber The inclusive maximum bus number that can be
|
||||
assigned to any subordinate bus found behind any
|
||||
PCI bridge hanging off this root bus.
|
||||
|
||||
The caller is repsonsible for ensuring that
|
||||
RootBusNumber <= MaxSubBusNumber. If
|
||||
RootBusNumber equals MaxSubBusNumber, then the
|
||||
root bus has no room for subordinate buses.
|
||||
|
||||
@param[in] Io IO aperture.
|
||||
|
||||
@param[in] Mem MMIO aperture.
|
||||
|
||||
@param[in] MemAbove4G MMIO aperture above 4G.
|
||||
|
||||
@param[in] PMem Prefetchable MMIO aperture.
|
||||
|
||||
@param[in] PMemAbove4G Prefetchable MMIO aperture above 4G.
|
||||
|
||||
@param[out] RootBus The PCI_ROOT_BRIDGE structure (allocated by the
|
||||
caller) that should be filled in by this
|
||||
function.
|
||||
|
||||
@retval EFI_SUCCESS Initialization successful. A device path
|
||||
consisting of an ACPI device path node, with
|
||||
UID = RootBusNumber, has been allocated and
|
||||
linked into RootBus.
|
||||
|
||||
@retval EFI_OUT_OF_RESOURCES Memory allocation failed.
|
||||
**/
|
||||
EFI_STATUS
|
||||
InitRootBridge (
|
||||
IN UINT64 Supports,
|
||||
IN UINT64 Attributes,
|
||||
IN UINT64 AllocAttributes,
|
||||
IN UINT8 RootBusNumber,
|
||||
IN UINT8 MaxSubBusNumber,
|
||||
IN PCI_ROOT_BRIDGE_APERTURE *Io,
|
||||
IN PCI_ROOT_BRIDGE_APERTURE *Mem,
|
||||
IN PCI_ROOT_BRIDGE_APERTURE *MemAbove4G,
|
||||
IN PCI_ROOT_BRIDGE_APERTURE *PMem,
|
||||
IN PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G,
|
||||
OUT PCI_ROOT_BRIDGE *RootBus
|
||||
);
|
|
@ -28,6 +28,7 @@
|
|||
#include <Library/PciHostBridgeLib.h>
|
||||
#include <Library/PciLib.h>
|
||||
#include <Library/QemuFwCfgLib.h>
|
||||
#include "PciHostBridge.h"
|
||||
|
||||
|
||||
#pragma pack(1)
|
||||
|
@ -70,13 +71,20 @@ OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH mRootBridgeDevicePathTemplate = {
|
|||
}
|
||||
};
|
||||
|
||||
STATIC PCI_ROOT_BRIDGE_APERTURE mNonExistAperture = { MAX_UINT64, 0 };
|
||||
|
||||
/**
|
||||
Initialize a PCI_ROOT_BRIDGE structure.
|
||||
|
||||
param[in] RootBusNumber The bus number to store in RootBus.
|
||||
@param[in] Supports Supported attributes.
|
||||
|
||||
param[in] MaxSubBusNumber The inclusive maximum bus number that can be
|
||||
@param[in] Attributes Initial attributes.
|
||||
|
||||
@param[in] AllocAttributes Allocation attributes.
|
||||
|
||||
@param[in] RootBusNumber The bus number to store in RootBus.
|
||||
|
||||
@param[in] MaxSubBusNumber The inclusive maximum bus number that can be
|
||||
assigned to any subordinate bus found behind any
|
||||
PCI bridge hanging off this root bus.
|
||||
|
||||
|
@ -85,7 +93,17 @@ OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH mRootBridgeDevicePathTemplate = {
|
|||
RootBusNumber equals MaxSubBusNumber, then the
|
||||
root bus has no room for subordinate buses.
|
||||
|
||||
param[out] RootBus The PCI_ROOT_BRIDGE structure (allocated by the
|
||||
@param[in] Io IO aperture.
|
||||
|
||||
@param[in] Mem MMIO aperture.
|
||||
|
||||
@param[in] MemAbove4G MMIO aperture above 4G.
|
||||
|
||||
@param[in] PMem Prefetchable MMIO aperture.
|
||||
|
||||
@param[in] PMemAbove4G Prefetchable MMIO aperture above 4G.
|
||||
|
||||
@param[out] RootBus The PCI_ROOT_BRIDGE structure (allocated by the
|
||||
caller) that should be filled in by this
|
||||
function.
|
||||
|
||||
|
@ -96,12 +114,19 @@ OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH mRootBridgeDevicePathTemplate = {
|
|||
|
||||
@retval EFI_OUT_OF_RESOURCES Memory allocation failed.
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
InitRootBridge (
|
||||
IN UINT8 RootBusNumber,
|
||||
IN UINT8 MaxSubBusNumber,
|
||||
OUT PCI_ROOT_BRIDGE *RootBus
|
||||
IN UINT64 Supports,
|
||||
IN UINT64 Attributes,
|
||||
IN UINT64 AllocAttributes,
|
||||
IN UINT8 RootBusNumber,
|
||||
IN UINT8 MaxSubBusNumber,
|
||||
IN PCI_ROOT_BRIDGE_APERTURE *Io,
|
||||
IN PCI_ROOT_BRIDGE_APERTURE *Mem,
|
||||
IN PCI_ROOT_BRIDGE_APERTURE *MemAbove4G,
|
||||
IN PCI_ROOT_BRIDGE_APERTURE *PMem,
|
||||
IN PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G,
|
||||
OUT PCI_ROOT_BRIDGE *RootBus
|
||||
)
|
||||
{
|
||||
OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH *DevicePath;
|
||||
|
@ -113,39 +138,19 @@ InitRootBridge (
|
|||
|
||||
RootBus->Segment = 0;
|
||||
|
||||
RootBus->Supports = EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO |
|
||||
EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO |
|
||||
EFI_PCI_ATTRIBUTE_ISA_IO_16 |
|
||||
EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO |
|
||||
EFI_PCI_ATTRIBUTE_VGA_MEMORY |
|
||||
EFI_PCI_ATTRIBUTE_VGA_IO_16 |
|
||||
EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;
|
||||
RootBus->Attributes = RootBus->Supports;
|
||||
RootBus->Supports = Supports;
|
||||
RootBus->Attributes = Attributes;
|
||||
|
||||
RootBus->DmaAbove4G = FALSE;
|
||||
|
||||
RootBus->AllocationAttributes = EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM;
|
||||
RootBus->PMem.Base = 0;
|
||||
RootBus->PMem.Limit = 0;
|
||||
RootBus->PMemAbove4G.Base = 0;
|
||||
RootBus->PMemAbove4G.Limit = 0;
|
||||
RootBus->MemAbove4G.Base = 0;
|
||||
RootBus->MemAbove4G.Limit = 0;
|
||||
|
||||
if (PcdGet64 (PcdPciMmio64Size) > 0) {
|
||||
RootBus->AllocationAttributes |= EFI_PCI_HOST_BRIDGE_MEM64_DECODE;
|
||||
RootBus->MemAbove4G.Base = PcdGet64 (PcdPciMmio64Base);
|
||||
RootBus->MemAbove4G.Limit = PcdGet64 (PcdPciMmio64Base) +
|
||||
(PcdGet64 (PcdPciMmio64Size) - 1);
|
||||
}
|
||||
|
||||
RootBus->AllocationAttributes = AllocAttributes;
|
||||
RootBus->Bus.Base = RootBusNumber;
|
||||
RootBus->Bus.Limit = MaxSubBusNumber;
|
||||
RootBus->Io.Base = PcdGet64 (PcdPciIoBase);
|
||||
RootBus->Io.Limit = PcdGet64 (PcdPciIoBase) + (PcdGet64 (PcdPciIoSize) - 1);
|
||||
RootBus->Mem.Base = PcdGet64 (PcdPciMmio32Base);
|
||||
RootBus->Mem.Limit = PcdGet64 (PcdPciMmio32Base) +
|
||||
(PcdGet64 (PcdPciMmio32Size) - 1);
|
||||
CopyMem (&RootBus->Io, Io, sizeof (*Io));
|
||||
CopyMem (&RootBus->Mem, Mem, sizeof (*Mem));
|
||||
CopyMem (&RootBus->MemAbove4G, MemAbove4G, sizeof (*MemAbove4G));
|
||||
CopyMem (&RootBus->PMem, PMem, sizeof (*PMem));
|
||||
CopyMem (&RootBus->PMemAbove4G, PMemAbove4G, sizeof (*PMemAbove4G));
|
||||
|
||||
RootBus->NoExtendedConfigSpace = (PcdGet16 (PcdOvmfHostBridgePciDevId) !=
|
||||
INTEL_Q35_MCH_DEVICE_ID);
|
||||
|
@ -206,6 +211,38 @@ PciHostBridgeGetRootBridges (
|
|||
UINTN Initialized;
|
||||
UINTN LastRootBridgeNumber;
|
||||
UINTN RootBridgeNumber;
|
||||
UINT64 Attributes;
|
||||
UINT64 AllocationAttributes;
|
||||
PCI_ROOT_BRIDGE_APERTURE Io;
|
||||
PCI_ROOT_BRIDGE_APERTURE Mem;
|
||||
PCI_ROOT_BRIDGE_APERTURE MemAbove4G;
|
||||
|
||||
if (PcdGetBool (PcdPciDisableBusEnumeration)) {
|
||||
return ScanForRootBridges (Count);
|
||||
}
|
||||
|
||||
Attributes = EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO |
|
||||
EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO |
|
||||
EFI_PCI_ATTRIBUTE_ISA_IO_16 |
|
||||
EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO |
|
||||
EFI_PCI_ATTRIBUTE_VGA_MEMORY |
|
||||
EFI_PCI_ATTRIBUTE_VGA_IO_16 |
|
||||
EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;
|
||||
|
||||
AllocationAttributes = EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM;
|
||||
if (PcdGet64 (PcdPciMmio64Size) > 0) {
|
||||
AllocationAttributes |= EFI_PCI_HOST_BRIDGE_MEM64_DECODE;
|
||||
MemAbove4G.Base = PcdGet64 (PcdPciMmio64Base);
|
||||
MemAbove4G.Limit = PcdGet64 (PcdPciMmio64Base) +
|
||||
PcdGet64 (PcdPciMmio64Size) - 1;
|
||||
} else {
|
||||
CopyMem (&MemAbove4G, &mNonExistAperture, sizeof (mNonExistAperture));
|
||||
}
|
||||
|
||||
Io.Base = PcdGet64 (PcdPciIoBase);
|
||||
Io.Limit = PcdGet64 (PcdPciIoBase) + (PcdGet64 (PcdPciIoSize) - 1);
|
||||
Mem.Base = PcdGet64 (PcdPciMmio32Base);
|
||||
Mem.Limit = PcdGet64 (PcdPciMmio32Base) + (PcdGet64 (PcdPciMmio32Size) - 1);
|
||||
|
||||
*Count = 0;
|
||||
|
||||
|
@ -266,8 +303,19 @@ PciHostBridgeGetRootBridges (
|
|||
// because now we know how big a bus number range *that* one has, for any
|
||||
// subordinate buses that might exist behind PCI bridges hanging off it.
|
||||
//
|
||||
Status = InitRootBridge ((UINT8)LastRootBridgeNumber,
|
||||
(UINT8)(RootBridgeNumber - 1), &Bridges[Initialized]);
|
||||
Status = InitRootBridge (
|
||||
Attributes,
|
||||
Attributes,
|
||||
AllocationAttributes,
|
||||
(UINT8) LastRootBridgeNumber,
|
||||
(UINT8) (RootBridgeNumber - 1),
|
||||
&Io,
|
||||
&Mem,
|
||||
&MemAbove4G,
|
||||
&mNonExistAperture,
|
||||
&mNonExistAperture,
|
||||
&Bridges[Initialized]
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto FreeBridges;
|
||||
}
|
||||
|
@ -280,8 +328,19 @@ PciHostBridgeGetRootBridges (
|
|||
// Install the last root bus (which might be the only, ie. main, root bus, if
|
||||
// we've found no extra root buses).
|
||||
//
|
||||
Status = InitRootBridge ((UINT8)LastRootBridgeNumber, PCI_MAX_BUS,
|
||||
&Bridges[Initialized]);
|
||||
Status = InitRootBridge (
|
||||
Attributes,
|
||||
Attributes,
|
||||
AllocationAttributes,
|
||||
(UINT8) LastRootBridgeNumber,
|
||||
PCI_MAX_BUS,
|
||||
&Io,
|
||||
&Mem,
|
||||
&MemAbove4G,
|
||||
&mNonExistAperture,
|
||||
&mNonExistAperture,
|
||||
&Bridges[Initialized]
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto FreeBridges;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
|
||||
[Sources]
|
||||
PciHostBridgeLib.c
|
||||
XenSupport.c
|
||||
PciHostBridge.h
|
||||
|
||||
[Packages]
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
|
@ -54,3 +56,4 @@
|
|||
gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Base
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Size
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration
|
||||
|
|
|
@ -0,0 +1,456 @@
|
|||
/** @file
|
||||
Scan the entire PCI bus for root bridges to support OVMF above Xen.
|
||||
|
||||
Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
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.
|
||||
|
||||
**/
|
||||
#include <PiDxe.h>
|
||||
|
||||
#include <IndustryStandard/Pci.h>
|
||||
#include <IndustryStandard/Q35MchIch9.h>
|
||||
|
||||
#include <Protocol/PciHostBridgeResourceAllocation.h>
|
||||
#include <Protocol/PciRootBridgeIo.h>
|
||||
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/PciHostBridgeLib.h>
|
||||
#include <Library/PciLib.h>
|
||||
#include "PciHostBridge.h"
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
PcatPciRootBridgeBarExisted (
|
||||
IN UINT64 Address,
|
||||
OUT UINT32 *OriginalValue,
|
||||
OUT UINT32 *Value
|
||||
)
|
||||
{
|
||||
//
|
||||
// Preserve the original value
|
||||
//
|
||||
*OriginalValue = PciRead32 (Address);
|
||||
|
||||
//
|
||||
// Disable timer interrupt while the BAR is probed
|
||||
//
|
||||
DisableInterrupts ();
|
||||
|
||||
PciWrite32 (Address, 0xFFFFFFFF);
|
||||
*Value = PciRead32 (Address);
|
||||
PciWrite32 (Address, *OriginalValue);
|
||||
|
||||
//
|
||||
// Enable interrupt
|
||||
//
|
||||
EnableInterrupts ();
|
||||
}
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
PcatPciRootBridgeParseBars (
|
||||
IN UINT16 Command,
|
||||
IN UINTN Bus,
|
||||
IN UINTN Device,
|
||||
IN UINTN Function,
|
||||
IN UINTN BarOffsetBase,
|
||||
IN UINTN BarOffsetEnd,
|
||||
IN PCI_ROOT_BRIDGE_APERTURE *Io,
|
||||
IN PCI_ROOT_BRIDGE_APERTURE *Mem,
|
||||
IN PCI_ROOT_BRIDGE_APERTURE *MemAbove4G,
|
||||
IN PCI_ROOT_BRIDGE_APERTURE *PMem,
|
||||
IN PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G
|
||||
|
||||
)
|
||||
{
|
||||
UINT32 OriginalValue;
|
||||
UINT32 Value;
|
||||
UINT32 OriginalUpperValue;
|
||||
UINT32 UpperValue;
|
||||
UINT64 Mask;
|
||||
UINTN Offset;
|
||||
UINT64 Base;
|
||||
UINT64 Length;
|
||||
UINT64 Limit;
|
||||
PCI_ROOT_BRIDGE_APERTURE *MemAperture;
|
||||
|
||||
for (Offset = BarOffsetBase; Offset < BarOffsetEnd; Offset += sizeof (UINT32)) {
|
||||
PcatPciRootBridgeBarExisted (
|
||||
PCI_LIB_ADDRESS (Bus, Device, Function, Offset),
|
||||
&OriginalValue, &Value
|
||||
);
|
||||
if (Value == 0) {
|
||||
continue;
|
||||
}
|
||||
if ((Value & BIT0) == BIT0) {
|
||||
//
|
||||
// IO Bar
|
||||
//
|
||||
if (Command & EFI_PCI_COMMAND_IO_SPACE) {
|
||||
Mask = 0xfffffffc;
|
||||
Base = OriginalValue & Mask;
|
||||
Length = ((~(Value & Mask)) & Mask) + 0x04;
|
||||
if (!(Value & 0xFFFF0000)) {
|
||||
Length &= 0x0000FFFF;
|
||||
}
|
||||
Limit = Base + Length - 1;
|
||||
|
||||
if (Base < Limit) {
|
||||
if (Io->Base > Base) {
|
||||
Io->Base = Base;
|
||||
}
|
||||
if (Io->Limit < Limit) {
|
||||
Io->Limit = Limit;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//
|
||||
// Mem Bar
|
||||
//
|
||||
if (Command & EFI_PCI_COMMAND_MEMORY_SPACE) {
|
||||
|
||||
Mask = 0xfffffff0;
|
||||
Base = OriginalValue & Mask;
|
||||
Length = Value & Mask;
|
||||
|
||||
if ((Value & (BIT1 | BIT2)) == 0) {
|
||||
//
|
||||
// 32bit
|
||||
//
|
||||
Length = ((~Length) + 1) & 0xffffffff;
|
||||
|
||||
if ((Value & BIT3) == BIT3) {
|
||||
MemAperture = PMem;
|
||||
} else {
|
||||
MemAperture = Mem;
|
||||
}
|
||||
} else {
|
||||
//
|
||||
// 64bit
|
||||
//
|
||||
Offset += 4;
|
||||
PcatPciRootBridgeBarExisted (
|
||||
PCI_LIB_ADDRESS (Bus, Device, Function, Offset),
|
||||
&OriginalUpperValue,
|
||||
&UpperValue
|
||||
);
|
||||
|
||||
Base = Base | LShiftU64 ((UINT64) OriginalUpperValue, 32);
|
||||
Length = Length | LShiftU64 ((UINT64) UpperValue, 32);
|
||||
Length = (~Length) + 1;
|
||||
|
||||
if ((Value & BIT3) == BIT3) {
|
||||
MemAperture = PMemAbove4G;
|
||||
} else {
|
||||
MemAperture = MemAbove4G;
|
||||
}
|
||||
}
|
||||
|
||||
Limit = Base + Length - 1;
|
||||
if (Base < Limit) {
|
||||
if (MemAperture->Base > Base) {
|
||||
MemAperture->Base = Base;
|
||||
}
|
||||
if (MemAperture->Limit < Limit) {
|
||||
MemAperture->Limit = Limit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PCI_ROOT_BRIDGE *
|
||||
ScanForRootBridges (
|
||||
UINTN *NumberOfRootBridges
|
||||
)
|
||||
{
|
||||
UINTN PrimaryBus;
|
||||
UINTN SubBus;
|
||||
UINT8 Device;
|
||||
UINT8 Function;
|
||||
UINTN NumberOfDevices;
|
||||
UINT64 Address;
|
||||
PCI_TYPE01 Pci;
|
||||
UINT64 Attributes;
|
||||
UINT64 Base;
|
||||
UINT64 Limit;
|
||||
UINT64 Value;
|
||||
PCI_ROOT_BRIDGE_APERTURE Io, Mem, MemAbove4G, PMem, PMemAbove4G, *MemAperture;
|
||||
PCI_ROOT_BRIDGE *RootBridges;
|
||||
UINTN BarOffsetEnd;
|
||||
|
||||
|
||||
*NumberOfRootBridges = 0;
|
||||
RootBridges = NULL;
|
||||
|
||||
//
|
||||
// After scanning all the PCI devices on the PCI root bridge's primary bus,
|
||||
// update the Primary Bus Number for the next PCI root bridge to be this PCI
|
||||
// root bridge's subordinate bus number + 1.
|
||||
//
|
||||
for (PrimaryBus = 0; PrimaryBus <= PCI_MAX_BUS; PrimaryBus = SubBus + 1) {
|
||||
SubBus = PrimaryBus;
|
||||
Attributes = 0;
|
||||
Io.Base = Mem.Base = MemAbove4G.Base = PMem.Base = PMemAbove4G.Base = MAX_UINT64;
|
||||
Io.Limit = Mem.Limit = MemAbove4G.Limit = PMem.Limit = PMemAbove4G.Limit = 0;
|
||||
//
|
||||
// Scan all the PCI devices on the primary bus of the PCI root bridge
|
||||
//
|
||||
for (Device = 0, NumberOfDevices = 0; Device <= PCI_MAX_DEVICE; Device++) {
|
||||
|
||||
for (Function = 0; Function <= PCI_MAX_FUNC; Function++) {
|
||||
|
||||
//
|
||||
// Compute the PCI configuration address of the PCI device to probe
|
||||
//
|
||||
Address = PCI_LIB_ADDRESS (PrimaryBus, Device, Function, 0);
|
||||
|
||||
//
|
||||
// Read the Vendor ID from the PCI Configuration Header
|
||||
//
|
||||
if (PciRead16 (Address) == MAX_UINT16) {
|
||||
if (Function == 0) {
|
||||
//
|
||||
// If the PCI Configuration Read fails, or a PCI device does not
|
||||
// exist, then skip this entire PCI device
|
||||
//
|
||||
break;
|
||||
} else {
|
||||
//
|
||||
// If PCI function != 0, VendorId == 0xFFFF, we continue to search
|
||||
// PCI function.
|
||||
//
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Read the entire PCI Configuration Header
|
||||
//
|
||||
PciReadBuffer (Address, sizeof (Pci), &Pci);
|
||||
|
||||
//
|
||||
// Increment the number of PCI device found on the primary bus of the
|
||||
// PCI root bridge
|
||||
//
|
||||
NumberOfDevices++;
|
||||
|
||||
//
|
||||
// Look for devices with the VGA Palette Snoop enabled in the COMMAND
|
||||
// register of the PCI Config Header
|
||||
//
|
||||
if ((Pci.Hdr.Command & EFI_PCI_COMMAND_VGA_PALETTE_SNOOP) != 0) {
|
||||
Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO;
|
||||
Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;
|
||||
}
|
||||
|
||||
BarOffsetEnd = 0;
|
||||
|
||||
//
|
||||
// PCI-PCI Bridge
|
||||
//
|
||||
if (IS_PCI_BRIDGE (&Pci)) {
|
||||
//
|
||||
// Get the Bus range that the PPB is decoding
|
||||
//
|
||||
if (Pci.Bridge.SubordinateBus > SubBus) {
|
||||
//
|
||||
// If the suborinate bus number of the PCI-PCI bridge is greater
|
||||
// than the PCI root bridge's current subordinate bus number,
|
||||
// then update the PCI root bridge's subordinate bus number
|
||||
//
|
||||
SubBus = Pci.Bridge.SubordinateBus;
|
||||
}
|
||||
|
||||
//
|
||||
// Get the I/O range that the PPB is decoding
|
||||
//
|
||||
Value = Pci.Bridge.IoBase & 0x0f;
|
||||
Base = ((UINT32) Pci.Bridge.IoBase & 0xf0) << 8;
|
||||
Limit = (((UINT32) Pci.Bridge.IoLimit & 0xf0) << 8) | 0x0fff;
|
||||
if (Value == BIT0) {
|
||||
Base |= ((UINT32) Pci.Bridge.IoBaseUpper16 << 16);
|
||||
Limit |= ((UINT32) Pci.Bridge.IoLimitUpper16 << 16);
|
||||
}
|
||||
if (Base < Limit) {
|
||||
if (Io.Base > Base) {
|
||||
Io.Base = Base;
|
||||
}
|
||||
if (Io.Limit < Limit) {
|
||||
Io.Limit = Limit;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Get the Memory range that the PPB is decoding
|
||||
//
|
||||
Base = ((UINT32) Pci.Bridge.MemoryBase & 0xfff0) << 16;
|
||||
Limit = (((UINT32) Pci.Bridge.MemoryLimit & 0xfff0) << 16) | 0xfffff;
|
||||
if (Base < Limit) {
|
||||
if (Mem.Base > Base) {
|
||||
Mem.Base = Base;
|
||||
}
|
||||
if (Mem.Limit < Limit) {
|
||||
Mem.Limit = Limit;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Get the Prefetchable Memory range that the PPB is decoding
|
||||
//
|
||||
Value = Pci.Bridge.PrefetchableMemoryBase & 0x0f;
|
||||
Base = ((UINT32) Pci.Bridge.PrefetchableMemoryBase & 0xfff0) << 16;
|
||||
Limit = (((UINT32) Pci.Bridge.PrefetchableMemoryLimit & 0xfff0)
|
||||
<< 16) | 0xfffff;
|
||||
MemAperture = &PMem;
|
||||
if (Value == BIT0) {
|
||||
Base |= LShiftU64 (Pci.Bridge.PrefetchableBaseUpper32, 32);
|
||||
Limit |= LShiftU64 (Pci.Bridge.PrefetchableLimitUpper32, 32);
|
||||
MemAperture = &PMemAbove4G;
|
||||
}
|
||||
if (Base < Limit) {
|
||||
if (MemAperture->Base > Base) {
|
||||
MemAperture->Base = Base;
|
||||
}
|
||||
if (MemAperture->Limit < Limit) {
|
||||
MemAperture->Limit = Limit;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Look at the PPB Configuration for legacy decoding attributes
|
||||
//
|
||||
if ((Pci.Bridge.BridgeControl & EFI_PCI_BRIDGE_CONTROL_ISA)
|
||||
== EFI_PCI_BRIDGE_CONTROL_ISA) {
|
||||
Attributes |= EFI_PCI_ATTRIBUTE_ISA_IO;
|
||||
Attributes |= EFI_PCI_ATTRIBUTE_ISA_IO_16;
|
||||
Attributes |= EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO;
|
||||
}
|
||||
if ((Pci.Bridge.BridgeControl & EFI_PCI_BRIDGE_CONTROL_VGA)
|
||||
== EFI_PCI_BRIDGE_CONTROL_VGA) {
|
||||
Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO;
|
||||
Attributes |= EFI_PCI_ATTRIBUTE_VGA_MEMORY;
|
||||
Attributes |= EFI_PCI_ATTRIBUTE_VGA_IO;
|
||||
if ((Pci.Bridge.BridgeControl & EFI_PCI_BRIDGE_CONTROL_VGA_16)
|
||||
!= 0) {
|
||||
Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;
|
||||
Attributes |= EFI_PCI_ATTRIBUTE_VGA_IO_16;
|
||||
}
|
||||
}
|
||||
|
||||
BarOffsetEnd = OFFSET_OF (PCI_TYPE01, Bridge.Bar[2]);
|
||||
} else {
|
||||
//
|
||||
// Parse the BARs of the PCI device to get what I/O Ranges, Memory
|
||||
// Ranges, and Prefetchable Memory Ranges the device is decoding
|
||||
//
|
||||
if ((Pci.Hdr.HeaderType & HEADER_LAYOUT_CODE) == HEADER_TYPE_DEVICE) {
|
||||
BarOffsetEnd = OFFSET_OF (PCI_TYPE00, Device.Bar[6]);
|
||||
}
|
||||
}
|
||||
|
||||
PcatPciRootBridgeParseBars (
|
||||
Pci.Hdr.Command,
|
||||
PrimaryBus,
|
||||
Device,
|
||||
Function,
|
||||
OFFSET_OF (PCI_TYPE00, Device.Bar),
|
||||
BarOffsetEnd,
|
||||
&Io,
|
||||
&Mem, &MemAbove4G,
|
||||
&PMem, &PMemAbove4G
|
||||
);
|
||||
|
||||
//
|
||||
// See if the PCI device is an IDE controller
|
||||
//
|
||||
if (IS_CLASS2 (&Pci, PCI_CLASS_MASS_STORAGE,
|
||||
PCI_CLASS_MASS_STORAGE_IDE)) {
|
||||
if (Pci.Hdr.ClassCode[0] & 0x80) {
|
||||
Attributes |= EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO;
|
||||
Attributes |= EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO;
|
||||
}
|
||||
if (Pci.Hdr.ClassCode[0] & 0x01) {
|
||||
Attributes |= EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO;
|
||||
}
|
||||
if (Pci.Hdr.ClassCode[0] & 0x04) {
|
||||
Attributes |= EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// See if the PCI device is a legacy VGA controller or
|
||||
// a standard VGA controller
|
||||
//
|
||||
if (IS_CLASS2 (&Pci, PCI_CLASS_OLD, PCI_CLASS_OLD_VGA) ||
|
||||
IS_CLASS2 (&Pci, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_VGA)
|
||||
) {
|
||||
Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO;
|
||||
Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;
|
||||
Attributes |= EFI_PCI_ATTRIBUTE_VGA_MEMORY;
|
||||
Attributes |= EFI_PCI_ATTRIBUTE_VGA_IO;
|
||||
Attributes |= EFI_PCI_ATTRIBUTE_VGA_IO_16;
|
||||
}
|
||||
|
||||
//
|
||||
// See if the PCI Device is a PCI - ISA or PCI - EISA
|
||||
// or ISA_POSITIVIE_DECODE Bridge device
|
||||
//
|
||||
if (Pci.Hdr.ClassCode[2] == PCI_CLASS_BRIDGE) {
|
||||
if (Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA ||
|
||||
Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_EISA ||
|
||||
Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA_PDECODE) {
|
||||
Attributes |= EFI_PCI_ATTRIBUTE_ISA_IO;
|
||||
Attributes |= EFI_PCI_ATTRIBUTE_ISA_IO_16;
|
||||
Attributes |= EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// If this device is not a multi function device, then skip the rest
|
||||
// of this PCI device
|
||||
//
|
||||
if (Function == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// If at least one PCI device was found on the primary bus of this PCI
|
||||
// root bridge, then the PCI root bridge exists.
|
||||
//
|
||||
if (NumberOfDevices > 0) {
|
||||
RootBridges = ReallocatePool (
|
||||
(*NumberOfRootBridges) * sizeof (PCI_ROOT_BRIDGE),
|
||||
(*NumberOfRootBridges + 1) * sizeof (PCI_ROOT_BRIDGE),
|
||||
RootBridges
|
||||
);
|
||||
ASSERT (RootBridges != NULL);
|
||||
InitRootBridge (
|
||||
Attributes, Attributes, 0,
|
||||
(UINT8) PrimaryBus, (UINT8) SubBus,
|
||||
&Io, &Mem, &MemAbove4G, &PMem, &PMemAbove4G,
|
||||
&RootBridges[*NumberOfRootBridges]
|
||||
);
|
||||
RootBridges[*NumberOfRootBridges].ResourceAssigned = TRUE;
|
||||
//
|
||||
// Increment the index for the next PCI Root Bridge
|
||||
//
|
||||
(*NumberOfRootBridges)++;
|
||||
}
|
||||
}
|
||||
|
||||
return RootBridges;
|
||||
}
|
Loading…
Reference in New Issue