snp.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,348 行 · 第 1/3 页
C
1,348 行
/*++
Copyright (c) 2004 - 2005, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module name:
snp.c
Abstract:
--*/
#include "snp.h"
EFI_STATUS
pxe_start (
SNP_DRIVER *snp
);
EFI_STATUS
pxe_stop (
SNP_DRIVER *snp
);
EFI_STATUS
pxe_init (
SNP_DRIVER *snp,
UINT16 OpFlags
);
EFI_STATUS
pxe_shutdown (
SNP_DRIVER *snp
);
EFI_STATUS
pxe_get_stn_addr (
SNP_DRIVER *snp
);
EFI_STATUS
EFIAPI
InitializeSnpNiiDriver (
IN EFI_HANDLE image_handle,
IN EFI_SYSTEM_TABLE *system_table
);
EFI_STATUS
EFIAPI
SimpleNetworkDriverSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
EFI_STATUS
EFIAPI
SimpleNetworkDriverStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
EFI_STATUS
EFIAPI
SimpleNetworkDriverStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
);
//
// Simple Network Protocol Driver Global Variables
//
EFI_DRIVER_BINDING_PROTOCOL mSimpleNetworkDriverBinding = {
SimpleNetworkDriverSupported,
SimpleNetworkDriverStart,
SimpleNetworkDriverStop,
0x10,
NULL,
NULL
};
//
// Module global variables needed to support undi 3.0 interface
//
EFI_PCI_IO_PROTOCOL *mPciIoFncs;
struct s_v2p *_v2p = NULL; // undi3.0 map_list head
// End Global variables
//
EFI_STATUS
add_v2p (
IN OUT struct s_v2p **v2p,
EFI_PCI_IO_PROTOCOL_OPERATION type,
VOID *vaddr,
UINTN bsize
)
/*++
Routine Description:
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.
Arguments:
v2p - pointer to return a map list node pointer.
type - the direction in which the data flows from the given virtual address
device->cpu or cpu->device or both ways.
vaddr - virtual address (or CPU address) to be mapped
bsize - size of the buffer to be mapped.
Returns:
EFI_SUCEESS - routine has completed the mapping
other - error as indicated.
--*/
{
EFI_STATUS Status;
if ((v2p == NULL) || (vaddr == NULL) || (bsize == 0)) {
return EFI_INVALID_PARAMETER;
}
Status = gBS->AllocatePool (
EfiBootServicesData,
sizeof (struct s_v2p),
(VOID **) v2p
);
if (Status != EFI_SUCCESS) {
return Status;
}
Status = mPciIoFncs->Map (
mPciIoFncs,
type,
vaddr,
&bsize,
&(*v2p)->paddr,
&(*v2p)->unmap
);
if (Status != EFI_SUCCESS) {
gBS->FreePool (*v2p);
return Status;
}
(*v2p)->vaddr = vaddr;
(*v2p)->bsize = bsize;
(*v2p)->next = _v2p;
_v2p = *v2p;
return EFI_SUCCESS;
}
EFI_STATUS
find_v2p (
struct s_v2p **v2p,
VOID *vaddr
)
/*++
Routine Description:
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.
Arguments:
v2p - pointer to return a map list node pointer.
vaddr - virtual address (or CPU address) to be searched in the map list
Returns:
EFI_SUCEESS - if a match found!
Other - match not found
--*/
{
struct s_v2p *v;
if (v2p == NULL || vaddr == NULL) {
return EFI_INVALID_PARAMETER;
}
for (v = _v2p; v != NULL; v = v->next) {
if (v->vaddr == vaddr) {
*v2p = v;
return EFI_SUCCESS;
}
}
return EFI_NOT_FOUND;
}
EFI_STATUS
del_v2p (
VOID *vaddr
)
/*++
Routine Description:
This routine unmaps the given virtual address and frees the memory allocated
for the map list node corresponding to that address.
Arguments:
vaddr - virtual address (or CPU address) to be unmapped
Returns:
EFI_SUCEESS - if successfully unmapped
Other - as indicated by the error
--*/
{
struct s_v2p *v;
struct s_v2p *t;
EFI_STATUS Status;
if (vaddr == NULL) {
return EFI_INVALID_PARAMETER;
}
if (_v2p == NULL) {
return EFI_NOT_FOUND;
}
//
// Is our node at the head of the list??
//
if ((v = _v2p)->vaddr == vaddr) {
_v2p = _v2p->next;
Status = mPciIoFncs->Unmap (mPciIoFncs, v->unmap);
gBS->FreePool (v);
#if SNP_DEBUG
if (Status) {
Print (L"Unmap failed with status = %x\n", Status);
}
#endif
return Status;
}
for (; v->next != NULL; v = t) {
if ((t = v->next)->vaddr == vaddr) {
v->next = t->next;
Status = mPciIoFncs->Unmap (mPciIoFncs, t->unmap);
gBS->FreePool (t);
#if SNP_DEBUG
if (Status) {
Print (L"Unmap failed with status = %x\n", Status);
}
#endif
return Status;
}
}
return EFI_NOT_FOUND;
}
#if SNP_DEBUG
VOID
snp_wait_for_key (
VOID
)
/*++
Routine Description:
Wait for a key stroke, used for debugging purposes
Arguments:
none
Returns:
none
--*/
{
EFI_INPUT_KEY key;
Aprint ("\nPress any key to continue\n");
while (gST->ConIn->ReadKeyStroke (gST->ConIn, &key) == EFI_NOT_READY) {
;
}
}
#endif
STATIC
EFI_STATUS
issue_hwundi_command (
UINT64 cdb
)
/*++
Routine Description:
Arguments:
Returns:
--*/
{
#if SNP_DEBUG
Aprint ("\nissue_hwundi_command() - This should not be called!");
snp_wait_for_key ();
#endif
if (cdb == 0) {
return EFI_INVALID_PARAMETER;
}
//
// %%TBD - For now, nothing is done.
//
return EFI_UNSUPPORTED;
}
STATIC
UINT8
calc_8bit_cksum (
VOID *ptr,
UINTN len
)
/*++
Routine Description:
Compute 8-bit checksum of a buffer.
Arguments:
ptr - Pointer to buffer.
len - Length of buffer in bytes.
Returns:
8-bit checksum of all bytes in buffer.
If ptr is NULL or len is zero, zero is returned.
--*/
{
UINT8 *bptr;
UINT8 cksum;
bptr = ptr;
cksum = 0;
if (ptr == NULL || len == 0) {
return 0;
}
while (len--) {
cksum = (UINT8) (cksum +*bptr++);
}
return cksum;
}
EFI_STATUS
EFIAPI
SimpleNetworkDriverSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
/*++
Routine Description:
Test to see if this driver supports Controller. Any Controller
that contains a Nii protocol can be supported.
Arguments:
This - Protocol instance pointer.
Controller - Handle of device to test.
RemainingDevicePath - Not used.
Returns:
EFI_SUCCESS - This driver supports this device.
EFI_ALREADY_STARTED - This driver is already running on this device.
other - This driver does not support this device.
--*/
{
EFI_STATUS Status;
EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *NiiProtocol;
PXE_UNDI *pxe;
BOOLEAN IsUndi31;
IsUndi31 = FALSE;
Status = gBS->OpenProtocol (
Controller,
&gEfiDevicePathProtocolGuid,
NULL,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = gBS->OpenProtocol (
Controller,
&gEfiNetworkInterfaceIdentifierProtocolGuid_31,
&NiiProtocol,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (Status == EFI_ALREADY_STARTED)
{
#if SNP_DEBUG
Aprint ("Support(): Already Started. on handle %x\n", Controller);
#endif
return EFI_ALREADY_STARTED;
}
if (!EFI_ERROR (Status))
{
#if SNP_DEBUG
Aprint ("Support(): UNDI3.1 found on handle %x\n", Controller);
snp_wait_for_key ();
#endif
IsUndi31 = TRUE;
} else {
//
// try the older 3.0 driver
//
Status = gBS->OpenProtocol (
Controller,
&gEfiNetworkInterfaceIdentifierProtocolGuid,
&NiiProtocol,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status)) {
return Status;
}
#if SNP_DEBUG
Aprint ("Support(): UNDI3.0 found on handle %x\n", Controller);
snp_wait_for_key ();
#endif
}
//
// check the version, we don't want to connect to the undi16
//
if (NiiProtocol->Type != EfiNetworkInterfaceUndi) {
Status = EFI_UNSUPPORTED;
goto Done;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?