mirror of https://github.com/acidanthera/audk.git
1. Use the PciIo->GetBarAttributes to find the logical bar index of the memory mapped bar and IO mapped bar.
2. Remove unused code for undi 3.0. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Fu, Siyuan <siyuan.fu@intel.com> Reviewed-By: Ye, Ting (ting.ye@intel.com) Reviewed-By: Ni, Ruiyu <ruiyu.ni@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16104 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
6c22c0a35d
commit
c4a7d20890
|
@ -1,9 +1,9 @@
|
|||
/** @file
|
||||
This file contains two sets of callback routines for undi3.0 and undi3.1.
|
||||
This file contains the callback routines for undi3.1.
|
||||
the callback routines for Undi3.1 have an extra parameter UniqueId which
|
||||
stores the interface context for the NIC that snp is trying to talk.
|
||||
|
||||
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
|
||||
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
|
||||
|
@ -16,218 +16,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||
|
||||
#include "Snp.h"
|
||||
|
||||
//
|
||||
// Global variables
|
||||
// these 2 global variables are used only for 3.0 undi. we could not place
|
||||
// them in the snp structure because we will not know which snp structure
|
||||
// in the callback context!
|
||||
//
|
||||
BOOLEAN mInitializeLock = TRUE;
|
||||
EFI_LOCK mLock;
|
||||
|
||||
//
|
||||
// End Global variables
|
||||
//
|
||||
extern EFI_PCI_IO_PROTOCOL *mPciIo;
|
||||
|
||||
/**
|
||||
Convert a virtual or CPU address provided by SNP to a physical or device
|
||||
address.
|
||||
|
||||
This is a callback routine supplied to UNDI at undi_start time. Since EFI uses
|
||||
the identical mapping, this routine returns the physical address same as the
|
||||
virtual address for most of the addresses. an address above 4GB cannot
|
||||
generally be used as a device address, it needs to be mapped to a lower
|
||||
physical address. This routine does not call the map routine itself, but it
|
||||
assumes that the mapping was done at the time of providing the address to
|
||||
UNDI. This routine just looks up the address in a map table (which is the v2p
|
||||
structure chain).
|
||||
|
||||
@param CpuAddr Virtual address.
|
||||
@param DeviceAddrPtr Pointer to the physical address, or 0 in case of any
|
||||
error.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
SnpUndi32CallbackV2p30 (
|
||||
IN UINT64 CpuAddr,
|
||||
IN OUT UINT64 DeviceAddrPtr
|
||||
)
|
||||
{
|
||||
V2P *V2p;
|
||||
//
|
||||
// Do nothing if virtual address is zero or physical pointer is NULL.
|
||||
// No need to map if the virtual address is within 4GB limit since
|
||||
// EFI uses identical mapping
|
||||
//
|
||||
if ((CpuAddr == 0) || (DeviceAddrPtr == 0)) {
|
||||
DEBUG ((EFI_D_NET, "\nv2p: Null virtual address or physical pointer.\n"));
|
||||
return ;
|
||||
}
|
||||
|
||||
if (CpuAddr < FOUR_GIGABYTES) {
|
||||
*(UINT64 *) (UINTN) DeviceAddrPtr = CpuAddr;
|
||||
return ;
|
||||
}
|
||||
//
|
||||
// SNP creates a vaddr tp paddr mapping at the time of calling undi with any
|
||||
// big address, this callback routine just looks up in the v2p list and
|
||||
// returns the physical address for any given virtual address.
|
||||
//
|
||||
if (FindV2p (&V2p, (VOID *) (UINTN) CpuAddr) != EFI_SUCCESS) {
|
||||
*(UINT64 *) (UINTN) DeviceAddrPtr = CpuAddr;
|
||||
} else {
|
||||
*(UINT64 *) (UINTN) DeviceAddrPtr = V2p->PhysicalAddress;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Acquire or release a lock of an exclusive access to a critical section of the
|
||||
code/data.
|
||||
|
||||
This is a callback routine supplied to UNDI at undi_start time.
|
||||
|
||||
@param Enable Non-zero indicates acquire; Zero indicates release.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
SnpUndi32CallbackBlock30 (
|
||||
IN UINT32 Enable
|
||||
)
|
||||
{
|
||||
//
|
||||
// tcpip was calling snp at tpl_notify and if we acquire a lock that was
|
||||
// created at a lower level (TPL_CALLBACK) it gives an assert!
|
||||
//
|
||||
if (mInitializeLock) {
|
||||
EfiInitializeLock (&mLock, TPL_NOTIFY);
|
||||
mInitializeLock = FALSE;
|
||||
}
|
||||
|
||||
if (Enable != 0) {
|
||||
EfiAcquireLock (&mLock);
|
||||
} else {
|
||||
EfiReleaseLock (&mLock);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Delay MicroSeconds of micro seconds.
|
||||
|
||||
This is a callback routine supplied to UNDI at undi_start time.
|
||||
|
||||
@param MicroSeconds Number of micro seconds to pause, ususlly multiple of 10.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
SnpUndi32CallbackDelay30 (
|
||||
IN UINT64 MicroSeconds
|
||||
)
|
||||
{
|
||||
if (MicroSeconds != 0) {
|
||||
gBS->Stall ((UINTN) MicroSeconds);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
IO routine for UNDI.
|
||||
|
||||
This is a callback routine supplied to UNDI at undi_start time. This is not
|
||||
currently being used by UNDI3.0 because Undi3.0 uses io/mem offsets relative
|
||||
to the beginning of the device io/mem address and so it needs to use the
|
||||
PCI_IO_FUNCTION that abstracts the start of the device's io/mem addresses.
|
||||
Since SNP cannot retrive the context of the undi3.0 interface it cannot use
|
||||
the PCI_IO_FUNCTION that specific for that NIC and uses one global IO
|
||||
functions structure, this does not work. This however works fine for EFI1.0
|
||||
Undis because they use absolute addresses for io/mem access.
|
||||
|
||||
@param ReadOrWrite Indicates read or write, IO or Memory.
|
||||
@param NumBytes Number of bytes to read or write.
|
||||
@param Address IO or memory address to read from or write to.
|
||||
@param BufferAddr Memory location to read into or that contains the bytes to
|
||||
write.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
SnpUndi32CallbackMemio30 (
|
||||
IN UINT8 ReadOrWrite,
|
||||
IN UINT8 NumBytes,
|
||||
IN UINT64 Address,
|
||||
IN OUT UINT64 BufferAddr
|
||||
)
|
||||
{
|
||||
EFI_PCI_IO_PROTOCOL_WIDTH Width;
|
||||
|
||||
switch (NumBytes) {
|
||||
case 2:
|
||||
Width = (EFI_PCI_IO_PROTOCOL_WIDTH) 1;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
Width = (EFI_PCI_IO_PROTOCOL_WIDTH) 2;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
Width = (EFI_PCI_IO_PROTOCOL_WIDTH) 3;
|
||||
break;
|
||||
|
||||
default:
|
||||
Width = (EFI_PCI_IO_PROTOCOL_WIDTH) 0;
|
||||
}
|
||||
|
||||
switch (ReadOrWrite) {
|
||||
case PXE_IO_READ:
|
||||
mPciIo->Io.Read (
|
||||
mPciIo,
|
||||
Width,
|
||||
1, // BAR 1, IO base address
|
||||
Address,
|
||||
1, // count
|
||||
(VOID *) (UINTN) BufferAddr
|
||||
);
|
||||
break;
|
||||
|
||||
case PXE_IO_WRITE:
|
||||
mPciIo->Io.Write (
|
||||
mPciIo,
|
||||
Width,
|
||||
1, // BAR 1, IO base address
|
||||
Address,
|
||||
1, // count
|
||||
(VOID *) (UINTN) BufferAddr
|
||||
);
|
||||
break;
|
||||
|
||||
case PXE_MEM_READ:
|
||||
mPciIo->Mem.Read (
|
||||
mPciIo,
|
||||
Width,
|
||||
0, // BAR 0, Memory base address
|
||||
Address,
|
||||
1, // count
|
||||
(VOID *) (UINTN) BufferAddr
|
||||
);
|
||||
break;
|
||||
|
||||
case PXE_MEM_WRITE:
|
||||
mPciIo->Mem.Write (
|
||||
mPciIo,
|
||||
Width,
|
||||
0, // BAR 0, Memory base address
|
||||
Address,
|
||||
1, // count
|
||||
(VOID *) (UINTN) BufferAddr
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
/**
|
||||
Acquire or release a lock of the exclusive access to a critical section of the
|
||||
code/data.
|
||||
|
|
|
@ -14,14 +14,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||
|
||||
#include "Snp.h"
|
||||
|
||||
//
|
||||
// Module global variables needed to support undi 3.0 interface
|
||||
//
|
||||
EFI_PCI_IO_PROTOCOL *mPciIo;
|
||||
V2P *mV2p = NULL; // undi3.0 map_list head
|
||||
// End Global variables
|
||||
//
|
||||
|
||||
/**
|
||||
One notified function to stop UNDI device when gBS->ExitBootServices() called.
|
||||
|
||||
|
@ -277,12 +269,11 @@ SimpleNetworkDriverStart (
|
|||
SNP_DRIVER *Snp;
|
||||
VOID *Address;
|
||||
EFI_HANDLE Handle;
|
||||
PXE_PCI_CONFIG_INFO ConfigInfo;
|
||||
PCI_TYPE00 *ConfigHeader;
|
||||
UINT32 *TempBar;
|
||||
UINT8 BarIndex;
|
||||
PXE_STATFLAGS InitStatFlags;
|
||||
|
||||
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *BarDesc;
|
||||
|
||||
DEBUG ((EFI_D_NET, "\nSnpNotifyNetworkInterfaceIdentifier() "));
|
||||
|
||||
Status = gBS->OpenProtocol (
|
||||
|
@ -311,7 +302,7 @@ SimpleNetworkDriverStart (
|
|||
Status = gBS->OpenProtocol (
|
||||
Handle,
|
||||
&gEfiPciIoProtocolGuid,
|
||||
(VOID **) &mPciIo,
|
||||
(VOID **) &PciIo,
|
||||
This->DriverBindingHandle,
|
||||
Controller,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
|
@ -367,14 +358,14 @@ SimpleNetworkDriverStart (
|
|||
// OK, we like this UNDI, and we know snp is not already there on this handle
|
||||
// Allocate and initialize a new simple network protocol structure.
|
||||
//
|
||||
Status = mPciIo->AllocateBuffer (
|
||||
mPciIo,
|
||||
AllocateAnyPages,
|
||||
EfiBootServicesData,
|
||||
SNP_MEM_PAGES (sizeof (SNP_DRIVER)),
|
||||
&Address,
|
||||
0
|
||||
);
|
||||
Status = PciIo->AllocateBuffer (
|
||||
PciIo,
|
||||
AllocateAnyPages,
|
||||
EfiBootServicesData,
|
||||
SNP_MEM_PAGES (sizeof (SNP_DRIVER)),
|
||||
&Address,
|
||||
0
|
||||
);
|
||||
|
||||
if (Status != EFI_SUCCESS) {
|
||||
DEBUG ((EFI_D_NET, "\nCould not allocate SNP_DRIVER structure.\n"));
|
||||
|
@ -385,7 +376,7 @@ SimpleNetworkDriverStart (
|
|||
|
||||
ZeroMem (Snp, sizeof (SNP_DRIVER));
|
||||
|
||||
Snp->PciIo = mPciIo;
|
||||
Snp->PciIo = PciIo;
|
||||
Snp->Signature = SNP_DRIVER_SIGNATURE;
|
||||
|
||||
EfiInitializeLock (&Snp->Lock, TPL_NOTIFY);
|
||||
|
@ -446,14 +437,14 @@ SimpleNetworkDriverStart (
|
|||
// -it is OK to allocate one global set of CPB, DB pair for each UNDI
|
||||
// interface as EFI does not multi-task and so SNP will not be re-entered!
|
||||
//
|
||||
Status = mPciIo->AllocateBuffer (
|
||||
mPciIo,
|
||||
AllocateAnyPages,
|
||||
EfiBootServicesData,
|
||||
SNP_MEM_PAGES (4096),
|
||||
&Address,
|
||||
0
|
||||
);
|
||||
Status = PciIo->AllocateBuffer (
|
||||
PciIo,
|
||||
AllocateAnyPages,
|
||||
EfiBootServicesData,
|
||||
SNP_MEM_PAGES (4096),
|
||||
&Address,
|
||||
0
|
||||
);
|
||||
|
||||
if (Status != EFI_SUCCESS) {
|
||||
DEBUG ((EFI_D_NET, "\nCould not allocate CPB and DB structures.\n"));
|
||||
|
@ -464,19 +455,35 @@ SimpleNetworkDriverStart (
|
|||
Snp->Db = (VOID *) ((UINTN) Address + 2048);
|
||||
|
||||
//
|
||||
// PxeStart call is going to give the callback functions to UNDI, these callback
|
||||
// functions use the BarIndex values from the snp structure, so these must be initialized
|
||||
// with default values before doing a PxeStart. The correct values can be obtained after
|
||||
// getting the config information from UNDI
|
||||
// Find the correct memory and io bar.
|
||||
//
|
||||
Snp->MemoryBarIndex = 0;
|
||||
Snp->IoBarIndex = 1;
|
||||
Snp->MemoryBarIndex = PCI_MAX_BAR;
|
||||
Snp->IoBarIndex = PCI_MAX_BAR;
|
||||
for (BarIndex = 0; BarIndex < PCI_MAX_BAR; BarIndex++) {
|
||||
Status = PciIo->GetBarAttributes (
|
||||
PciIo,
|
||||
BarIndex,
|
||||
NULL,
|
||||
(VOID**) &BarDesc
|
||||
);
|
||||
if (Status == EFI_UNSUPPORTED) {
|
||||
continue;
|
||||
} else if (EFI_ERROR (Status)) {
|
||||
goto Error_DeleteSNP;
|
||||
}
|
||||
|
||||
if (BarDesc->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {
|
||||
Snp->MemoryBarIndex = BarIndex;
|
||||
} else if (BarDesc->ResType == ACPI_ADDRESS_SPACE_TYPE_IO) {
|
||||
Snp->IoBarIndex = BarIndex;
|
||||
}
|
||||
|
||||
FreePool (BarDesc);
|
||||
}
|
||||
if ((Snp->MemoryBarIndex == PCI_MAX_BAR) || (Snp->IoBarIndex == PCI_MAX_BAR)) {
|
||||
goto Error_DeleteSNP;
|
||||
}
|
||||
|
||||
//
|
||||
// we need the undi init information many times in this snp code, just get it
|
||||
// once here and store it in the snp driver structure. to get Init Info
|
||||
// from UNDI we have to start undi first.
|
||||
//
|
||||
Status = PxeStart (Snp);
|
||||
|
||||
if (Status != EFI_SUCCESS) {
|
||||
|
@ -513,57 +520,6 @@ SimpleNetworkDriverStart (
|
|||
goto Error_DeleteSNP;
|
||||
}
|
||||
|
||||
Snp->Cdb.OpCode = PXE_OPCODE_GET_CONFIG_INFO;
|
||||
Snp->Cdb.OpFlags = PXE_OPFLAGS_NOT_USED;
|
||||
|
||||
Snp->Cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
|
||||
Snp->Cdb.CPBaddr = PXE_DBADDR_NOT_USED;
|
||||
|
||||
Snp->Cdb.DBsize = (UINT16) sizeof (ConfigInfo);
|
||||
Snp->Cdb.DBaddr = (UINT64)(UINTN) &ConfigInfo;
|
||||
|
||||
Snp->Cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
Snp->Cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
|
||||
Snp->Cdb.IFnum = Snp->IfNum;
|
||||
Snp->Cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
DEBUG ((EFI_D_NET, "\nSnp->undi.get_config_info() "));
|
||||
|
||||
(*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb);
|
||||
|
||||
if (Snp->Cdb.StatCode != PXE_STATCODE_SUCCESS) {
|
||||
DEBUG ((EFI_D_NET, "\nSnp->undi.config_info() %xh:%xh\n", Snp->Cdb.StatFlags, Snp->Cdb.StatCode));
|
||||
PxeStop (Snp);
|
||||
goto Error_DeleteSNP;
|
||||
}
|
||||
//
|
||||
// Find the correct BAR to do IO.
|
||||
//
|
||||
//
|
||||
// Enumerate through the PCI BARs for the device to determine which one is
|
||||
// the IO BAR. Save the index of the BAR into the adapter info structure.
|
||||
// for regular 32bit BARs, 0 is memory mapped, 1 is io mapped
|
||||
//
|
||||
ConfigHeader = (PCI_TYPE00 *) ConfigInfo.Config.Byte;
|
||||
TempBar = (UINT32 *) ConfigHeader->Device.Bar;
|
||||
for (BarIndex = 0; BarIndex <= 5; BarIndex++) {
|
||||
if ((*TempBar & PCI_BAR_MEM_MASK) == PCI_BAR_MEM_64BIT) {
|
||||
//
|
||||
// This is a 64-bit memory bar, skip this and the
|
||||
// next bar as well.
|
||||
//
|
||||
TempBar++;
|
||||
}
|
||||
|
||||
if ((*TempBar & PCI_BAR_IO_MASK) == PCI_BAR_IO_MODE) {
|
||||
Snp->IoBarIndex = BarIndex;
|
||||
break;
|
||||
}
|
||||
|
||||
TempBar++;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize simple network protocol mode structure
|
||||
//
|
||||
|
@ -703,19 +659,19 @@ SimpleNetworkDriverStart (
|
|||
return Status;
|
||||
}
|
||||
|
||||
mPciIo->FreeBuffer (
|
||||
mPciIo,
|
||||
SNP_MEM_PAGES (4096),
|
||||
Snp->Cpb
|
||||
);
|
||||
PciIo->FreeBuffer (
|
||||
PciIo,
|
||||
SNP_MEM_PAGES (4096),
|
||||
Snp->Cpb
|
||||
);
|
||||
|
||||
Error_DeleteSNP:
|
||||
|
||||
mPciIo->FreeBuffer (
|
||||
mPciIo,
|
||||
SNP_MEM_PAGES (sizeof (SNP_DRIVER)),
|
||||
Snp
|
||||
);
|
||||
PciIo->FreeBuffer (
|
||||
PciIo,
|
||||
SNP_MEM_PAGES (sizeof (SNP_DRIVER)),
|
||||
Snp
|
||||
);
|
||||
NiiError:
|
||||
gBS->CloseProtocol (
|
||||
Controller,
|
||||
|
@ -771,6 +727,7 @@ SimpleNetworkDriverStop (
|
|||
EFI_STATUS Status;
|
||||
EFI_SIMPLE_NETWORK_PROTOCOL *SnpProtocol;
|
||||
SNP_DRIVER *Snp;
|
||||
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||
|
||||
//
|
||||
// Get our context back.
|
||||
|
@ -822,17 +779,18 @@ SimpleNetworkDriverStop (
|
|||
PxeShutdown (Snp);
|
||||
PxeStop (Snp);
|
||||
|
||||
mPciIo->FreeBuffer (
|
||||
mPciIo,
|
||||
SNP_MEM_PAGES (4096),
|
||||
Snp->Cpb
|
||||
);
|
||||
PciIo = Snp->PciIo;
|
||||
PciIo->FreeBuffer (
|
||||
PciIo,
|
||||
SNP_MEM_PAGES (4096),
|
||||
Snp->Cpb
|
||||
);
|
||||
|
||||
mPciIo->FreeBuffer (
|
||||
mPciIo,
|
||||
SNP_MEM_PAGES (sizeof (SNP_DRIVER)),
|
||||
Snp
|
||||
);
|
||||
PciIo->FreeBuffer (
|
||||
PciIo,
|
||||
SNP_MEM_PAGES (sizeof (SNP_DRIVER)),
|
||||
Snp
|
||||
);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
@ -849,159 +807,6 @@ EFI_DRIVER_BINDING_PROTOCOL gSimpleNetworkDriverBinding = {
|
|||
NULL
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
This routine maps the given CPU address to a Device address. It creates a
|
||||
an entry in the map list with the virtual and physical addresses and the
|
||||
un map cookie.
|
||||
|
||||
@param V2p pointer to return a map list node pointer.
|
||||
@param Type the direction in which the data flows from the given
|
||||
virtual address device->cpu or cpu->device or both
|
||||
ways.
|
||||
@param VirtualAddress virtual address (or CPU address) to be mapped.
|
||||
@param BufferSize size of the buffer to be mapped.
|
||||
|
||||
@retval EFI_SUCEESS routine has completed the mapping.
|
||||
@retval EFI_INVALID_PARAMETER invalid parameter.
|
||||
@retval EFI_OUT_OF_RESOURCES out of resource.
|
||||
@retval other error as indicated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
AddV2P (
|
||||
IN OUT V2P **V2p,
|
||||
EFI_PCI_IO_PROTOCOL_OPERATION Type,
|
||||
VOID *VirtualAddress,
|
||||
UINTN BufferSize
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
if ((V2p == NULL) || (VirtualAddress == NULL) || (BufferSize == 0)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
*V2p = AllocatePool (sizeof (V2P));
|
||||
if (*V2p == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
Status = mPciIo->Map (
|
||||
mPciIo,
|
||||
Type,
|
||||
VirtualAddress,
|
||||
&BufferSize,
|
||||
&(*V2p)->PhysicalAddress,
|
||||
&(*V2p)->Unmap
|
||||
);
|
||||
if (Status != EFI_SUCCESS) {
|
||||
FreePool (*V2p);
|
||||
return Status;
|
||||
}
|
||||
(*V2p)->VirtualAddress = VirtualAddress;
|
||||
(*V2p)->BufferSize = BufferSize;
|
||||
(*V2p)->Next = mV2p;
|
||||
mV2p = *V2p;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This routine searches the linked list of mapped address nodes (for undi3.0
|
||||
interface) to find the node that corresponds to the given virtual address and
|
||||
returns a pointer to that node.
|
||||
|
||||
@param V2p pointer to return a map list node pointer.
|
||||
@param VirtualAddr virtual address (or CPU address) to be searched in
|
||||
the map list
|
||||
|
||||
@retval EFI_SUCEESS A match was found.
|
||||
@retval Other A match cannot be found.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
FindV2p (
|
||||
V2P **V2p,
|
||||
VOID *VirtualAddr
|
||||
)
|
||||
{
|
||||
V2P *Ptr;
|
||||
|
||||
if (V2p == NULL || VirtualAddr == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
for (Ptr = mV2p; Ptr != NULL; Ptr = Ptr->Next) {
|
||||
if (Ptr->VirtualAddress == VirtualAddr) {
|
||||
*V2p = Ptr;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Unmap the given virtual address and free the memory allocated for the map list
|
||||
node corresponding to that address.
|
||||
|
||||
@param VirtualAddress virtual address (or CPU address) to be unmapped.
|
||||
|
||||
@retval EFI_SUCEESS Successfully unmapped.
|
||||
@retval Other Other errors as indicated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
DelV2p (
|
||||
VOID *VirtualAddress
|
||||
)
|
||||
{
|
||||
V2P *Current;
|
||||
V2P *Next;
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (VirtualAddress == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (mV2p == NULL) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
//
|
||||
// Is our node at the head of the list??
|
||||
//
|
||||
if ((Current = mV2p)->VirtualAddress == VirtualAddress) {
|
||||
mV2p = mV2p->Next;
|
||||
|
||||
Status = mPciIo->Unmap (mPciIo, Current->Unmap);
|
||||
|
||||
FreePool (Current);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((EFI_D_ERROR, "Unmap failed with status = %r\n", Status));
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
for (; Current->Next != NULL; Current = Next) {
|
||||
if ((Next = Current->Next)->VirtualAddress == VirtualAddress) {
|
||||
Current->Next = Next->Next;
|
||||
Status = mPciIo->Unmap (mPciIo, Next->Unmap);
|
||||
FreePool (Next);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((EFI_D_ERROR, "Unmap failed with status = %r\n", Status));
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
The SNP driver entry point.
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
Declaration of strctures and functions for SnpDxe driver.
|
||||
|
||||
Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2004 - 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
|
||||
|
@ -34,6 +34,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||
#include <Library/PrintLib.h>
|
||||
|
||||
#include <IndustryStandard/Pci.h>
|
||||
#include <IndustryStandard/Acpi.h>
|
||||
|
||||
#define FOUR_GIGABYTES (UINT64) 0x100000000ULL
|
||||
|
||||
|
@ -140,62 +141,6 @@ extern EFI_DRIVER_BINDING_PROTOCOL gSimpleNetworkDriverBinding;
|
|||
extern EFI_COMPONENT_NAME_PROTOCOL gSimpleNetworkComponentName;
|
||||
extern EFI_COMPONENT_NAME2_PROTOCOL gSimpleNetworkComponentName2;
|
||||
|
||||
//
|
||||
// Virtual to physical mapping for all UNDI 3.0s.
|
||||
//
|
||||
typedef struct _V2P V2P;
|
||||
|
||||
struct _V2P {
|
||||
V2P *Next;
|
||||
VOID *VirtualAddress;
|
||||
UINTN BufferSize;
|
||||
EFI_PHYSICAL_ADDRESS PhysicalAddress;
|
||||
VOID *Unmap;
|
||||
};
|
||||
|
||||
/**
|
||||
This routine maps the given CPU address to a Device address. It creates a
|
||||
an entry in the map list with the virtual and physical addresses and the
|
||||
un map cookie.
|
||||
|
||||
@param V2p pointer to return a map list node pointer.
|
||||
@param Type the direction in which the data flows from the given
|
||||
virtual address device->cpu or cpu->device or both
|
||||
ways.
|
||||
@param VirtualAddress virtual address (or CPU address) to be mapped.
|
||||
@param BufferSize size of the buffer to be mapped.
|
||||
|
||||
@retval EFI_SUCEESS routine has completed the mapping.
|
||||
@retval other error as indicated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
AddV2p (
|
||||
V2P **V2p,
|
||||
EFI_PCI_IO_PROTOCOL_OPERATION Type,
|
||||
VOID *VirtualAddress,
|
||||
UINTN BufferSize
|
||||
);
|
||||
|
||||
/**
|
||||
This routine searches the linked list of mapped address nodes (for undi3.0
|
||||
interface) to find the node that corresponds to the given virtual address and
|
||||
returns a pointer to that node.
|
||||
|
||||
@param V2p pointer to return a map list node pointer.
|
||||
@param VirtualAddress virtual address (or CPU address) to be searched in
|
||||
the map list
|
||||
|
||||
@retval EFI_SUCEESS if a match found!
|
||||
@retval Other match not found
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
FindV2p (
|
||||
V2P **V2p,
|
||||
VOID *VirtualAddress
|
||||
);
|
||||
|
||||
/**
|
||||
this routine calls undi to start the interface and changes the snp state.
|
||||
|
||||
|
@ -272,100 +217,6 @@ PxeGetStnAddr (
|
|||
SNP_DRIVER *Snp
|
||||
);
|
||||
|
||||
/**
|
||||
This routine unmaps the given virtual address and frees the memory allocated
|
||||
for the map list node corresponding to that address.
|
||||
|
||||
@param VirtualAddress virtual address (or CPU address) to be unmapped
|
||||
|
||||
@retval EFI_SUCEESS if successfully unmapped
|
||||
@retval Other as indicated by the error
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
DelV2p (
|
||||
VOID *VirtualAddress
|
||||
);
|
||||
|
||||
/**
|
||||
This is a callback routine supplied to UNDI at undi_start time.
|
||||
UNDI call this routine when it wants to have exclusive access to a critical
|
||||
section of the code/data.
|
||||
|
||||
@param Enable non-zero indicates acquire
|
||||
zero indicates release
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
SnpUndi32CallbackBlock30 (
|
||||
IN UINT32 Enable
|
||||
);
|
||||
|
||||
/**
|
||||
This is a callback routine supplied to UNDI at undi_start time.
|
||||
UNDI call this routine with the number of micro seconds when it wants to
|
||||
pause.
|
||||
|
||||
@param MicroSeconds number of micro seconds to pause, ususlly multiple of 10.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
SnpUndi32CallbackDelay30 (
|
||||
IN UINT64 MicroSeconds
|
||||
);
|
||||
|
||||
/**
|
||||
This is a callback routine supplied to UNDI at undi_start time.
|
||||
This is the IO routine for UNDI. This is not currently being used by UNDI3.0
|
||||
because Undi3.0 uses io/mem offsets relative to the beginning of the device
|
||||
io/mem address and so it needs to use the PCI_IO_FUNCTION that abstracts the
|
||||
start of the device's io/mem addresses. Since SNP cannot retrive the context
|
||||
of the undi3.0 interface it cannot use the PCI_IO_FUNCTION that specific for
|
||||
that NIC and uses one global IO functions structure, this does not work.
|
||||
This however works fine for EFI1.0 Undis because they use absolute addresses
|
||||
for io/mem access.
|
||||
|
||||
@param ReadOrWrite indicates read or write, IO or Memory
|
||||
@param NumBytes number of bytes to read or write
|
||||
@param Address IO or memory address to read from or write to
|
||||
@param BufferAddr memory location to read into or that contains the bytes to
|
||||
write
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
SnpUndi32CallbackMemio30 (
|
||||
IN UINT8 ReadOrWrite,
|
||||
IN UINT8 NumBytes,
|
||||
IN UINT64 Address,
|
||||
IN OUT UINT64 BufferAddr
|
||||
);
|
||||
|
||||
/**
|
||||
This is a callback routine supplied to UNDI at undi_start time.
|
||||
UNDI call this routine with a virtual or CPU address that SNP provided to
|
||||
convert it to a physical or device address. Since EFI uses the identical
|
||||
mapping, this routine returns the physical address same as the virtual address
|
||||
for most of the addresses. an address above 4GB cannot generally be used as a
|
||||
device address, it needs to be mapped to a lower physical address. This
|
||||
routine does not call the map routine itself, but it assumes that the mapping
|
||||
was done at the time of providing the address to UNDI. This routine just
|
||||
looks up the address in a map table (which is the v2p structure chain).
|
||||
|
||||
@param CpuAddr virtual address of a buffer.
|
||||
@param DeviceAddrPtr pointer to the physical address.
|
||||
The DeviceAddrPtr will contain 0 in case of any error.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
SnpUndi32CallbackV2p30 (
|
||||
IN UINT64 CpuAddr,
|
||||
IN OUT UINT64 DeviceAddrPtr
|
||||
);
|
||||
|
||||
/**
|
||||
This is a callback routine supplied to UNDI3.1 at undi_start time.
|
||||
UNDI call this routine when it wants to have exclusive access to a critical
|
||||
|
|
Loading…
Reference in New Issue