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
|
/** @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
|
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.
|
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
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
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"
|
#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
|
Acquire or release a lock of the exclusive access to a critical section of the
|
||||||
code/data.
|
code/data.
|
||||||
|
|
|
@ -14,14 +14,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
|
||||||
#include "Snp.h"
|
#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.
|
One notified function to stop UNDI device when gBS->ExitBootServices() called.
|
||||||
|
|
||||||
|
@ -277,11 +269,10 @@ SimpleNetworkDriverStart (
|
||||||
SNP_DRIVER *Snp;
|
SNP_DRIVER *Snp;
|
||||||
VOID *Address;
|
VOID *Address;
|
||||||
EFI_HANDLE Handle;
|
EFI_HANDLE Handle;
|
||||||
PXE_PCI_CONFIG_INFO ConfigInfo;
|
|
||||||
PCI_TYPE00 *ConfigHeader;
|
|
||||||
UINT32 *TempBar;
|
|
||||||
UINT8 BarIndex;
|
UINT8 BarIndex;
|
||||||
PXE_STATFLAGS InitStatFlags;
|
PXE_STATFLAGS InitStatFlags;
|
||||||
|
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||||
|
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *BarDesc;
|
||||||
|
|
||||||
DEBUG ((EFI_D_NET, "\nSnpNotifyNetworkInterfaceIdentifier() "));
|
DEBUG ((EFI_D_NET, "\nSnpNotifyNetworkInterfaceIdentifier() "));
|
||||||
|
|
||||||
|
@ -311,7 +302,7 @@ SimpleNetworkDriverStart (
|
||||||
Status = gBS->OpenProtocol (
|
Status = gBS->OpenProtocol (
|
||||||
Handle,
|
Handle,
|
||||||
&gEfiPciIoProtocolGuid,
|
&gEfiPciIoProtocolGuid,
|
||||||
(VOID **) &mPciIo,
|
(VOID **) &PciIo,
|
||||||
This->DriverBindingHandle,
|
This->DriverBindingHandle,
|
||||||
Controller,
|
Controller,
|
||||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
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
|
// 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.
|
// Allocate and initialize a new simple network protocol structure.
|
||||||
//
|
//
|
||||||
Status = mPciIo->AllocateBuffer (
|
Status = PciIo->AllocateBuffer (
|
||||||
mPciIo,
|
PciIo,
|
||||||
AllocateAnyPages,
|
AllocateAnyPages,
|
||||||
EfiBootServicesData,
|
EfiBootServicesData,
|
||||||
SNP_MEM_PAGES (sizeof (SNP_DRIVER)),
|
SNP_MEM_PAGES (sizeof (SNP_DRIVER)),
|
||||||
&Address,
|
&Address,
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
|
||||||
if (Status != EFI_SUCCESS) {
|
if (Status != EFI_SUCCESS) {
|
||||||
DEBUG ((EFI_D_NET, "\nCould not allocate SNP_DRIVER structure.\n"));
|
DEBUG ((EFI_D_NET, "\nCould not allocate SNP_DRIVER structure.\n"));
|
||||||
|
@ -385,7 +376,7 @@ SimpleNetworkDriverStart (
|
||||||
|
|
||||||
ZeroMem (Snp, sizeof (SNP_DRIVER));
|
ZeroMem (Snp, sizeof (SNP_DRIVER));
|
||||||
|
|
||||||
Snp->PciIo = mPciIo;
|
Snp->PciIo = PciIo;
|
||||||
Snp->Signature = SNP_DRIVER_SIGNATURE;
|
Snp->Signature = SNP_DRIVER_SIGNATURE;
|
||||||
|
|
||||||
EfiInitializeLock (&Snp->Lock, TPL_NOTIFY);
|
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
|
// -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!
|
// interface as EFI does not multi-task and so SNP will not be re-entered!
|
||||||
//
|
//
|
||||||
Status = mPciIo->AllocateBuffer (
|
Status = PciIo->AllocateBuffer (
|
||||||
mPciIo,
|
PciIo,
|
||||||
AllocateAnyPages,
|
AllocateAnyPages,
|
||||||
EfiBootServicesData,
|
EfiBootServicesData,
|
||||||
SNP_MEM_PAGES (4096),
|
SNP_MEM_PAGES (4096),
|
||||||
&Address,
|
&Address,
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
|
||||||
if (Status != EFI_SUCCESS) {
|
if (Status != EFI_SUCCESS) {
|
||||||
DEBUG ((EFI_D_NET, "\nCould not allocate CPB and DB structures.\n"));
|
DEBUG ((EFI_D_NET, "\nCould not allocate CPB and DB structures.\n"));
|
||||||
|
@ -464,19 +455,35 @@ SimpleNetworkDriverStart (
|
||||||
Snp->Db = (VOID *) ((UINTN) Address + 2048);
|
Snp->Db = (VOID *) ((UINTN) Address + 2048);
|
||||||
|
|
||||||
//
|
//
|
||||||
// PxeStart call is going to give the callback functions to UNDI, these callback
|
// Find the correct memory and io bar.
|
||||||
// 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
|
|
||||||
//
|
//
|
||||||
Snp->MemoryBarIndex = 0;
|
Snp->MemoryBarIndex = PCI_MAX_BAR;
|
||||||
Snp->IoBarIndex = 1;
|
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);
|
Status = PxeStart (Snp);
|
||||||
|
|
||||||
if (Status != EFI_SUCCESS) {
|
if (Status != EFI_SUCCESS) {
|
||||||
|
@ -513,57 +520,6 @@ SimpleNetworkDriverStart (
|
||||||
goto Error_DeleteSNP;
|
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
|
// Initialize simple network protocol mode structure
|
||||||
//
|
//
|
||||||
|
@ -703,19 +659,19 @@ SimpleNetworkDriverStart (
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
mPciIo->FreeBuffer (
|
PciIo->FreeBuffer (
|
||||||
mPciIo,
|
PciIo,
|
||||||
SNP_MEM_PAGES (4096),
|
SNP_MEM_PAGES (4096),
|
||||||
Snp->Cpb
|
Snp->Cpb
|
||||||
);
|
);
|
||||||
|
|
||||||
Error_DeleteSNP:
|
Error_DeleteSNP:
|
||||||
|
|
||||||
mPciIo->FreeBuffer (
|
PciIo->FreeBuffer (
|
||||||
mPciIo,
|
PciIo,
|
||||||
SNP_MEM_PAGES (sizeof (SNP_DRIVER)),
|
SNP_MEM_PAGES (sizeof (SNP_DRIVER)),
|
||||||
Snp
|
Snp
|
||||||
);
|
);
|
||||||
NiiError:
|
NiiError:
|
||||||
gBS->CloseProtocol (
|
gBS->CloseProtocol (
|
||||||
Controller,
|
Controller,
|
||||||
|
@ -771,6 +727,7 @@ SimpleNetworkDriverStop (
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
EFI_SIMPLE_NETWORK_PROTOCOL *SnpProtocol;
|
EFI_SIMPLE_NETWORK_PROTOCOL *SnpProtocol;
|
||||||
SNP_DRIVER *Snp;
|
SNP_DRIVER *Snp;
|
||||||
|
EFI_PCI_IO_PROTOCOL *PciIo;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Get our context back.
|
// Get our context back.
|
||||||
|
@ -822,17 +779,18 @@ SimpleNetworkDriverStop (
|
||||||
PxeShutdown (Snp);
|
PxeShutdown (Snp);
|
||||||
PxeStop (Snp);
|
PxeStop (Snp);
|
||||||
|
|
||||||
mPciIo->FreeBuffer (
|
PciIo = Snp->PciIo;
|
||||||
mPciIo,
|
PciIo->FreeBuffer (
|
||||||
SNP_MEM_PAGES (4096),
|
PciIo,
|
||||||
Snp->Cpb
|
SNP_MEM_PAGES (4096),
|
||||||
);
|
Snp->Cpb
|
||||||
|
);
|
||||||
|
|
||||||
mPciIo->FreeBuffer (
|
PciIo->FreeBuffer (
|
||||||
mPciIo,
|
PciIo,
|
||||||
SNP_MEM_PAGES (sizeof (SNP_DRIVER)),
|
SNP_MEM_PAGES (sizeof (SNP_DRIVER)),
|
||||||
Snp
|
Snp
|
||||||
);
|
);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -849,159 +807,6 @@ EFI_DRIVER_BINDING_PROTOCOL gSimpleNetworkDriverBinding = {
|
||||||
NULL
|
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.
|
The SNP driver entry point.
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/** @file
|
/** @file
|
||||||
Declaration of strctures and functions for SnpDxe driver.
|
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
|
This program and the accompanying materials are licensed
|
||||||
and made available under the terms and conditions of the BSD License which
|
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
|
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 <Library/PrintLib.h>
|
||||||
|
|
||||||
#include <IndustryStandard/Pci.h>
|
#include <IndustryStandard/Pci.h>
|
||||||
|
#include <IndustryStandard/Acpi.h>
|
||||||
|
|
||||||
#define FOUR_GIGABYTES (UINT64) 0x100000000ULL
|
#define FOUR_GIGABYTES (UINT64) 0x100000000ULL
|
||||||
|
|
||||||
|
@ -140,62 +141,6 @@ extern EFI_DRIVER_BINDING_PROTOCOL gSimpleNetworkDriverBinding;
|
||||||
extern EFI_COMPONENT_NAME_PROTOCOL gSimpleNetworkComponentName;
|
extern EFI_COMPONENT_NAME_PROTOCOL gSimpleNetworkComponentName;
|
||||||
extern EFI_COMPONENT_NAME2_PROTOCOL gSimpleNetworkComponentName2;
|
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.
|
this routine calls undi to start the interface and changes the snp state.
|
||||||
|
|
||||||
|
@ -272,100 +217,6 @@ PxeGetStnAddr (
|
||||||
SNP_DRIVER *Snp
|
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.
|
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
|
UNDI call this routine when it wants to have exclusive access to a critical
|
||||||
|
|
Loading…
Reference in New Issue