Misc.c revision 4fd606d1f5abe38e1f42c38de1d2e895166bd0f4
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock/** @file
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Helper Routines that use a PXE-enabled NIC option ROM.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockCopyright (c) 1999 - 2010, Intel Corporation. All rights reserved.<BR>
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockThis program and the accompanying materials
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockare licensed and made available under the terms and conditions
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockof the BSD License which accompanies this distribution. The
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockfull text of the license may be found at
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockhttp://opensource.org/licenses/bsd-license.php
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock**/
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock#include "BiosSnp16.h"
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock#define TO_SEGMENT(x) ((UINT16) (RShiftU64 ((UINT32)(UINTN) (x), 4) & 0xF000))
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock#define TO_OFFSET(x) ((UINT16) ((UINT32)(UINTN) (x) & 0xFFFF))
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock#define PARAGRAPH_SIZE 0x10
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock#define IVT_BASE 0x00000000
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock#pragma pack(1)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrocktypedef struct {
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UINT16 Signature; ///< 0xaa55
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UINT8 ROMlength; ///< size of this ROM in 512 byte blocks
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UINT8 InitEntryPoint[4]; ///< a jump to the initialization routine
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UINT8 Reserved[0xf]; ///< various
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UINT16 PxeRomIdOffset; ///< offset of UNDI, $BC$, or BUSD ROM ID structure
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UINT16 PcirHeaderOffset; ///< offset of PCI Expansion Header
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UINT16 PnpHeaderOffset; ///< offset of Plug and Play Expansion Header
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock} OPTION_ROM_HEADER;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock#pragma pack()
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockUINT32 CachedVectorAddress[0x100];
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock/**
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Cache Interrupt verctor address converted from IVT number.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock @param VectorNumber IVT number
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock @retval EFI_SUCCESS Success to operation.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock**/
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockEFI_STATUS
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockCacheVectorAddress (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UINT8 VectorNumber
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock{
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UINT32 *Address;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Address = (UINT32 *)(UINTN) (IVT_BASE + VectorNumber * 4);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock CachedVectorAddress[VectorNumber] = *Address;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock return EFI_SUCCESS;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock}
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock/**
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Get interrupt vector address according to IVT number.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock @param VectorNumber Given IVT number
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock @return cached interrupt vector address.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock**/
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockEFI_STATUS
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockRestoreCachedVectorAddress (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UINT8 VectorNumber
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock{
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UINT32 *Address;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Address = (UINT32 *)(UINTN) (IVT_BASE + VectorNumber * 4);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock *Address = CachedVectorAddress[VectorNumber];
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock return EFI_SUCCESS;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock}
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock/**
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Print Undi loader table.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock @param UndiLoaderStructure Point to Undi Loader table structure.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock**/
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockVOID
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockPrint_Undi_Loader_Table (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock VOID *UndiLoaderStructure
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock{
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UNDI_LOADER_T *DisplayPointer;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer = (UNDI_LOADER_T *) UndiLoaderStructure;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "Before Parsing the table contents, the table itself lives\n"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "\tat the address 0x%X\n\r", (UINT32)(UINTN) UndiLoaderStructure));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "\n\rStatus = 0x%X\n\r", DisplayPointer->Status));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "\t_AX_= 0x%X\n\r", DisplayPointer->Ax));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "\t_BX_= 0x%X\n\r", DisplayPointer->Bx));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "\t_DX_= 0x%X\n\r", DisplayPointer->Dx));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "\t_DI_= 0x%X\n\r", DisplayPointer->Di));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "\t_ES_= 0x%X\n\r", DisplayPointer->Es));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "\tUNDI_DS= 0x%X\n\r", DisplayPointer->Undi_Ds));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "\tUNDI_CS= 0x%X\n\r", DisplayPointer->Undi_Cs));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "\tPXEptr:SEG= 0x%X\n\r", (UINT16) DisplayPointer->PXEptr.Segment));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "\tPXEptr:OFF= 0x%X\n\r", (UINT16) DisplayPointer->PXEptr.Offset));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "\tPXENVptr:SEG= 0x%X\n\r", (UINT16) DisplayPointer->PXENVptr.Segment));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "\tPXENVptr:OFF= 0x%X\n\r", (UINT16) DisplayPointer->PXENVptr.Offset));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock}
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock/**
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Simple table dumper. The ROMID table is necessary in order to effect
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock the "Early UNDI" trick. Herein, the UNDI layer can be loaded in the
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock pre-boot phase without having to download a Network Boot Program
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock across the wire. It is required in the implementation in that we
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock are not using PXE.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock @param RomIDStructure Point to RomID structure.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock**/
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockVOID
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockPrint_ROMID_Table (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock IN VOID *RomIDStructure
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock{
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UNDI_ROMID_T *DisplayPointer;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer = (UNDI_ROMID_T *) RomIDStructure;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "Before Parsing the table contents, the table itself lives\n"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "\tat the address 0x%X\n\r", (UINT32)(UINTN) RomIDStructure));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "\n\rROMID %c%c%c%c\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->Signature[0],
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->Signature[1],
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->Signature[2],
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->Signature[3])
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "Length of this structure in bytes = 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->StructLength)
9af3851a3a831b4de34b42482c22351e14f33f16eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
9af3851a3a831b4de34b42482c22351e14f33f16eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "Use to make byte checksum of this structure == zero is = 0x%X\n\r",
9af3851a3a831b4de34b42482c22351e14f33f16eschrock DisplayPointer->StructCksum)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
9af3851a3a831b4de34b42482c22351e14f33f16eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "Structure format revision number= 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->StructRev)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "API Revision number = 0x%X 0x%X 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->UNDI_Rev[0],
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->UNDI_Rev[1],
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->UNDI_Rev[2])
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "Offset of UNDI loader routine in the option ROM image= 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->UNDI_Loader)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "From the data above, the absolute entry point of the UNDI loader is\n\r"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "\tat address 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (UINT32) (DisplayPointer->UNDI_Loader + ((UINT32) (UINTN)(DisplayPointer - 0x20) & 0xFFFF0)))
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "Minimum stack segment size, in bytes,\n\r"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "needed to load and run the UNDI= 0x%X \n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->StackSize)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "UNDI runtime code and data = 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->DataSize)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "Segment size = 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->CodeSize)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "\n\rBus Type = %c%c%c%c\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->BusType[0],
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->BusType[1],
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->BusType[2],
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->BusType[3])
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock}
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock/**
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Print PXE table.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock @param PxeTable Point to PXE table structure
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock**/
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockVOID
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockPrint_PXE_Table (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock IN VOID* PxeTable
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock{
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock PXE_T *DisplayPointer;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UINTN Index;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UINT8 *Dptr;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer = (PXE_T *) PxeTable;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Dptr = (UINT8 *) PxeTable;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "This is the PXE table at address 0x%X\n\r", PxeTable));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "A dump of the 0x%X bytes is:\n\r", sizeof (PXE_T)));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock for (Index = 0; Index < sizeof (PXE_T); Index++) {
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock if ((Index % 0x10) == 0) {
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "\t\n\r"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock }
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, " 0x%X ", *Dptr++));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock }
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "\n\r"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "\n\rPXE %c%c%c%c%c%c\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->Signature[0],
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->Signature[1],
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->Signature[2],
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->Signature[3])
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "Length of this structure in bytes = 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->StructLength)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "Use to make byte checksum of this structure == zero is = 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->StructCksum)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "Structure format revision number = 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->StructRev)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "Must be zero, is equal to 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->Reserved1)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "Far pointer to UNDI ROMID = 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (UINT32) (DisplayPointer->Undi.Segment << 0x4 | DisplayPointer->Undi.Offset))
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "Far pointer to base-code ROMID = 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (UINT32) ((DisplayPointer->Base.Segment << 0x04) | DisplayPointer->Base.Offset))
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "16bit stack segment API entry point. This will be seg:off in \n\r"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "real mode and sel:off in 16:16 protected mode = 0x%X:0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->EntryPointSP.Segment,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->EntryPointSP.Offset)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "\n\tNOTE to the implementer\n\tThis is the entry to use for call-ins\n\r"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "32bit stack Segment API entry point. This will be sel:off. \n\r"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "In real mode, sel == 0 = 0x%X:0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->EntryPointESP.Segment,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->EntryPointESP.Offset)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "Reserved2 value, must be zero, is equal to 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->Reserved2)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "Number of segment descriptors in this structur = 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (UINT8) DisplayPointer->SegDescCnt)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "First segment descriptor in GDT assigned to PXE = 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (UINT16) DisplayPointer->FirstSelector)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "The Stack is \n\r\tSegment Addr = 0x%X\n\r\tPhysical Addr = 0x%X\n\r\tSeg Size = 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (UINT16) DisplayPointer->Stack.Seg_Addr,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (UINT32) DisplayPointer->Stack.Phy_Addr,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (UINT16) DisplayPointer->Stack.Seg_Size)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "The UNDIData is \n\r\tSegment Addr = 0x%X\n\r\tPhysical Addr = 0x%X\n\r\tSeg Size = 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (UINT16) DisplayPointer->UNDIData.Seg_Addr,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (UINT32) DisplayPointer->UNDIData.Phy_Addr,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (UINT16) DisplayPointer->UNDIData.Seg_Size)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "The UNDICodeWrite is \n\r\tSegment Addr = 0x%X\n\r\tPhysical Addr = 0x%X\n\r\tSeg Size = 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (UINT16) DisplayPointer->UNDICode.Seg_Addr,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (UINT32) DisplayPointer->UNDICode.Phy_Addr,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (UINT16) DisplayPointer->UNDICode.Seg_Size)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "The Stack is \n\r\tSegment Addr = 0x%X\n\r\tPhysical Addr = 0x%X\n\r\tSeg Size = 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (UINT16) DisplayPointer->UNDICodeWrite.Seg_Addr,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (UINT32) DisplayPointer->UNDICodeWrite.Phy_Addr,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (UINT16) DisplayPointer->UNDICodeWrite.Seg_Size)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "The BC_Data is \n\r\tSegment Addr = 0x%X\n\r\tPhysical Addr = 0x%X\n\r\tSeg Size = 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (UINT16) DisplayPointer->BC_Data.Seg_Addr,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (UINT32) DisplayPointer->BC_Data.Phy_Addr,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (UINT16) DisplayPointer->BC_Data.Seg_Size)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "The BC_Code is \n\r\tSegment Addr = 0x%X\n\r\tPhysical Addr = 0x%X\n\r\tSeg Size = 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (UINT16) DisplayPointer->BC_Code.Seg_Addr,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (UINT32) DisplayPointer->BC_Code.Phy_Addr,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (UINT16) DisplayPointer->BC_Code.Seg_Size)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "The BC_CodeWrite is \n\r\tSegment Addr = 0x%X\n\r\tPhysical Addr = 0x%X\n\r\tSeg Size = 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (UINT16) DisplayPointer->BC_CodeWrite.Seg_Addr,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (UINT32) DisplayPointer->BC_CodeWrite.Phy_Addr,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (UINT16) DisplayPointer->BC_CodeWrite.Seg_Size)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock}
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock/**
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Print PXENV table.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock @param PxenvTable Point to PXENV
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock**/
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockVOID
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockPrint_PXENV_Table (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock IN VOID *PxenvTable
9af3851a3a831b4de34b42482c22351e14f33f16eschrock )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock{
9af3851a3a831b4de34b42482c22351e14f33f16eschrock PXENV_T *DisplayPointer;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
9af3851a3a831b4de34b42482c22351e14f33f16eschrock DisplayPointer = (PXENV_T *) PxenvTable;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
9af3851a3a831b4de34b42482c22351e14f33f16eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "\n\rPXENV+ %c%c%c%c%c%c\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->Signature[0],
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->Signature[1],
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->Signature[2],
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->Signature[3],
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->Signature[4],
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->Signature[5])
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "PXE version number. \n\r\tLSB is minor version. \n\r\tMSB is major version = 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->Version)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
9af3851a3a831b4de34b42482c22351e14f33f16eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
9af3851a3a831b4de34b42482c22351e14f33f16eschrock "Length of PXE-2.0 Entry Point structure in bytes = 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->StructLength)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "Used to make structure checksum equal zero is now = 0x%X\n\r", DisplayPointer->StructCksum));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "Real mode API entry point segment:Offset. = 0x%X\n\r", DisplayPointer->RMEntry));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "Protected mode API entry point = 0x%X\n\r", DisplayPointer->PMEntryOff));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, " segment:Offset. This will always be zero. \n\r"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "Protected mode API calls = 0x%X\n\r", DisplayPointer->PMEntrySeg));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "Real mode stack segment = 0x%X\n\r", DisplayPointer->StackSeg));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "Stack segment size in bytes = 0x%X\n\r", DisplayPointer->StackSize));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "Real mode base-code code segment = 0x%X\n\r", DisplayPointer->BaseCodeSeg));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "Base-code code segment size = 0x%X\n\r", DisplayPointer->BaseCodeSize));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "Real mode base-code data segment = 0x%X\n\r", DisplayPointer->BaseDataSeg));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "Base-code data segment size = 0x%X\n\r", DisplayPointer->BaseDataSize));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "UNDI code segment size in bytes = 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->UNDICodeSize)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "Real mode segment:Offset pointer \n\r\tto PXE Runtime ID structure, address = 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DisplayPointer->RuntimePtr)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "From above, we have a linear address of 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (UINT32)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock ((UINT32)(UINTN)(DisplayPointer->RuntimePtr) & 0xFFFF) +
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (((UINT32)(UINTN)(DisplayPointer->RuntimePtr) & 0xFFFF0000) >> 12)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock}
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock#define OPTION_ROM_PTR ((OPTION_ROM_HEADER *) RomAddress)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock/**
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock If available, launch the BaseCode from a NIC option ROM.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock This should install the !PXE and PXENV+ structures in memory for
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock subsequent use.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock @param SimpleNetworkDevice Simple network device instance
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock @param RomAddress The ROM base address for NIC rom.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock @retval EFI_NOT_FOUND The check sum does not match
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock @retval EFI_NOT_FOUND Rom ID offset is wrong
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock @retval EFI_NOT_FOUND No Rom ID structure is found
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock**/
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockEFI_STATUS
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockLaunchBaseCode (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UINTN RomAddress
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock{
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock EFI_STATUS Status;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock EFI_IA32_REGISTER_SET InOutRegs;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UNDI_ROMID_T *RomIdTableAddress;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UNDI_LOADER_T *UndiLoaderTable;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UINT16 Segment;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UINT16 *StackPointer;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock VOID *Buffer;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UINTN Size;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock PXE_T *Pxe;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UINT32 RomLength;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UINTN PciSegment;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UINTN Bus;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UINTN Device;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UINTN Function;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock BOOLEAN ThunkFailed;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "\n\r\n\rCheck for the UNDI ROMID Signature\n\r"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // paranoia - check structures for validity
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock RomLength = OPTION_ROM_PTR->ROMlength << 9;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock if (CalculateSum8 ((UINT8 *) RomAddress, RomLength) != 0) {
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_ERROR, "ROM Header Checksum Error\n\r"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock return EFI_NOT_FOUND;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock }
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock RomIdTableAddress = (UNDI_ROMID_T *) (RomAddress + OPTION_ROM_PTR->PxeRomIdOffset);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock if ((UINTN) (OPTION_ROM_PTR->PxeRomIdOffset + RomIdTableAddress->StructLength) > RomLength) {
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_ERROR, "ROM ID Offset Error\n\r"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock return EFI_NOT_FOUND;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock }
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // see if this is a header for an UNDI ROM ID structure (vs. a $BC$ or BUSD type)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock if (CompareMem (RomIdTableAddress->Signature, UNDI_ROMID_SIG, sizeof RomIdTableAddress->Signature) != 0) {
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_ERROR, "No ROM ID Structure found....\n\r"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock return EFI_NOT_FOUND;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // its not - keep looking
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock }
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock if (CalculateSum8 ((UINT8 *) RomIdTableAddress, RomIdTableAddress->StructLength) != 0) {
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_ERROR, "ROM ID Checksum Error\n\r"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock return EFI_NOT_FOUND;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock }
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Print_ROMID_Table (RomIdTableAddress);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "The ROM ID is located at 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock RomIdTableAddress)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "With an UNDI Loader located at 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock RomAddress + RomIdTableAddress->UNDI_Loader)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // found an UNDI ROM ID structure
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock SimpleNetworkDevice->Nii.ImageAddr = RomAddress;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock SimpleNetworkDevice->Nii.ImageSize = RomLength;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock SimpleNetworkDevice->Nii.MajorVer = RomIdTableAddress->UNDI_Rev[2];
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock SimpleNetworkDevice->Nii.MinorVer = RomIdTableAddress->UNDI_Rev[1];
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "Allocate area for the UNDI_LOADER_T structure\n\r"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // Allocate 1 page below 1MB to put real mode thunk code in
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // Undi Loader Table is a PXE Specification prescribed data structure
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // that is used to transfer information into and out of the Undi layer.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // Note how it must be located below 1 MB.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock SimpleNetworkDevice->UndiLoaderTablePages = EFI_SIZE_TO_PAGES (PARAGRAPH_SIZE + sizeof (UNDI_LOADER_T));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Status = BiosSnp16AllocatePagesBelowOneMb (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock SimpleNetworkDevice->UndiLoaderTablePages,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock &SimpleNetworkDevice->UndiLoaderTable
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock if (EFI_ERROR (Status)) {
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_ERROR, "We had a failure in AllocatePages, status code = 0x%X\n", Status));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock return EFI_OUT_OF_RESOURCES;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock }
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UndiLoaderTable = SimpleNetworkDevice->UndiLoaderTable;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "Allocate area for the real-mode stack whose sole purpose\n\r"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "in life right now is to store a SEG:OFFSET combo pair that\n\r"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "points to an Undi_Loader_t table structure\n\r"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Size = 0x100;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Status = gBS->AllocatePool (EfiLoaderData, Size, &Buffer);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock if (EFI_ERROR (Status)) {
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock return Status;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock }
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // Now we want to put a pointer to the Under Loader Table in our MemPage
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // Buffer. This will be the argument stack for the call into the Undi Loader
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock StackPointer = (UINT16 *) Buffer;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock *StackPointer++ = TO_OFFSET (UndiLoaderTable);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // push the OFFSET
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock *StackPointer++ = TO_SEGMENT (UndiLoaderTable);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // push the SEGMENT
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock StackPointer = (UINT16 *) Buffer;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // reset the stack pointer
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "After the fixups, the stack pointer is 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (UINT64)(UINTN) StackPointer)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // Allocate memory for the Deployed UNDI.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // The UNDI is essentially telling us how much space it needs, and
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // it is up to the EFI driver to allocate sufficient, boot-time
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // persistent resources for the call
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock SimpleNetworkDevice->DestinationDataSegmentPages = EFI_SIZE_TO_PAGES (RomIdTableAddress->DataSize);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Status = BiosSnp16AllocatePagesBelowOneMb (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock SimpleNetworkDevice->DestinationDataSegmentPages,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock &SimpleNetworkDevice->DestinationDataSegment
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock if (EFI_ERROR (Status)) {
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_ERROR, "We had a failure in AllocatePages, status code = 0x%X\n", Status));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock return Status;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock }
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UndiLoaderTable->Undi_Ds = (UINT16) ((UINTN) SimpleNetworkDevice->DestinationDataSegment >> 4);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // Allocate memory for the Deployed UNDI stack
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // The UNDI is essentially telling us how much space it needs, and
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // it is up to the EFI driver to allocate sufficient, boot-time
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // persistent resources for the call
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock SimpleNetworkDevice->DestinationStackSegmentPages = EFI_SIZE_TO_PAGES (RomIdTableAddress->StackSize);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Status = BiosSnp16AllocatePagesBelowOneMb (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock SimpleNetworkDevice->DestinationStackSegmentPages,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock &SimpleNetworkDevice->DestinationStackSegment
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock if (EFI_ERROR (Status)) {
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_ERROR, "We had a failure in AllocatePages, status code = 0x%X\n", Status));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock return Status;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock }
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // Allocate memory for the Deployed UNDI.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // The UNDI is essentially telling us how much space it needs, and
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // it is up to the EFI driver to allocate sufficient, boot-time
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // persistent resources for the call
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock SimpleNetworkDevice->DestinationCodeSegmentPages = EFI_SIZE_TO_PAGES (RomIdTableAddress->CodeSize);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Status = BiosSnp16AllocatePagesBelowOneMb (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock SimpleNetworkDevice->DestinationCodeSegmentPages,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock &SimpleNetworkDevice->DestinationCodeSegment
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock if (EFI_ERROR (Status)) {
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_ERROR, "We had a failure in AllocatePages, status code = 0x%X\n", Status));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock return Status;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock }
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UndiLoaderTable->Undi_Cs = (UINT16) ((UINTN) SimpleNetworkDevice->DestinationCodeSegment >> 4);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // these are in the Input and Output Parameter to be sent to the UNDI Loader code
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UndiLoaderTable->Status = 0xAA55;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // -------------------- Changed by Michael_Huang@3Com.com -----------------
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // UndiLoaderTable->_AX is AX value when UNDI ROM is initialized by BIOS, it is the PCI bus device
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // function of the NIC. Please refer to PXE Spec for detail info.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // old code is:
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // UndiLoaderTable->Ax = 0x0;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // -----------------------------------------------------------------------
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock SimpleNetworkDevice->PciIo->GetLocation (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock SimpleNetworkDevice->PciIo,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock &PciSegment,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock &Bus,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock &Device,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock &Function
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UndiLoaderTable->Ax = (UINT16) ((Bus << 0x8) | (Device << 0x3) | (Function));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UndiLoaderTable->Bx = 0x0;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UndiLoaderTable->Dx = 0x0;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UndiLoaderTable->Di = 0x0;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UndiLoaderTable->Es = 0x0;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // set these OUT values to zero in order to ensure that
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // uninitialized memory is not mistaken for display data
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UndiLoaderTable->PXEptr.Offset = 0;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UndiLoaderTable->PXEptr.Segment = 0;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UndiLoaderTable->PXENVptr.Segment = 0;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UndiLoaderTable->PXENVptr.Offset = 0;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_INIT,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "The NIC is located at Bus 0x%X, Device 0x%X, Function 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Bus,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Device,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Function)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // These are the values that set up the ACTUAL IA32 machine state, whether in
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // Real16 in EFI32 or the IVE for IA64
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // register values are unused except for CS:IP and SS:SP
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock InOutRegs.X.AX = 0;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock InOutRegs.X.BX = 0;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock InOutRegs.X.CX = 0;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock InOutRegs.X.DX = 0;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock InOutRegs.X.SI = 0;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock InOutRegs.X.DI = 0;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock InOutRegs.X.BP = 0;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock InOutRegs.X.DS = 0;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock InOutRegs.X.ES = 0;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // just to be clean
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "The way this game works is that the SS:SP +4 should point\n\r"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "to the contents of the UndiLoaderTable\n\r"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "The Undi Loader Table is at address = 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (UINT32)(UINTN) UndiLoaderTable)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "The segment and offsets are 0x%X and 0x%X, resp\n",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock TO_SEGMENT (UndiLoaderTable),
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock TO_OFFSET (UndiLoaderTable))
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "The Linear Address of the UNDI Loader entry is 0x%X\n",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock RomAddress + RomIdTableAddress->UNDI_Loader)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "The Address offset of the UNDI Loader entry is 0x%X\n",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock RomIdTableAddress->UNDI_Loader)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "Before the call, we have...\n\r"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Print_Undi_Loader_Table (UndiLoaderTable);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Segment = ((UINT16) (RShiftU64 (RomAddress, 4) & 0xFFFF));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "The Segment of the call is 0x%X\n\r", Segment));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // make the call into the UNDI Code
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_INIT, "Make the call into the UNDI code now\n\r"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "\nThe 20-BIt address of the Call, and the location \n\r"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "\twhere we should be able to set a breakpoint is \n\r"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "\t\t0x%X, from SEG:OFF 0x%X:0x%X\n\r\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Segment * 0x10 + RomIdTableAddress->UNDI_Loader,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Segment,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock RomIdTableAddress->UNDI_Loader)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock ThunkFailed = SimpleNetworkDevice->LegacyBios->FarCall86 (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock SimpleNetworkDevice->LegacyBios,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Segment, // Input segment
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (UINT16) RomIdTableAddress->UNDI_Loader, // Offset
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock &InOutRegs, // Ptr to Regs
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Buffer, // Reference to Stack
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Size // Size of the Stack
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock if (ThunkFailed) {
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock return EFI_ABORTED;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock }
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "The return code UndiLoaderTable->Status is = 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UndiLoaderTable->Status)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (DEBUG_NET,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock "This error code should match eax, which is = 0x%X\n\r",
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock InOutRegs.X.AX)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "Now returned from the UNDI code\n\r"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "After the call, we have...\n\r"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Print_Undi_Loader_Table (UndiLoaderTable);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "Display the PXENV+ and !PXE tables exported by NIC\n\r"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Print_PXENV_Table ((VOID *)(UINTN)((UndiLoaderTable->PXENVptr.Segment << 4) | UndiLoaderTable->PXENVptr.Offset));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Print_PXE_Table ((VOID *)(UINTN)((UndiLoaderTable->PXEptr.Segment << 4) + UndiLoaderTable->PXEptr.Offset));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Pxe = (PXE_T *)(UINTN)((UndiLoaderTable->PXEptr.Segment << 4) + UndiLoaderTable->PXEptr.Offset);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock SimpleNetworkDevice->Nii.Id = (UINT64)(UINTN) Pxe;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // FreePool (Buffer);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // paranoia - make sure a valid !PXE structure
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock if (CompareMem (Pxe->Signature, PXE_SIG, sizeof Pxe->Signature) != 0) {
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_ERROR, "!PXE Structure not found....\n\r"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock return EFI_NOT_FOUND;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // its not - keep looking
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock }
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock if (CalculateSum8 ((UINT8 *) Pxe, Pxe->StructLength) != 0) {
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_ERROR, "!PXE Checksum Error\n\r"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock return EFI_NOT_FOUND;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock }
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock if (Pxe->StructLength < (UINT8 *) &Pxe->FirstSelector - (UINT8 *) Pxe->Signature) {
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_ERROR, "!PXE Length Error\n\r"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock return EFI_NOT_FOUND;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock }
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock if ((((UINTN) Pxe->Undi.Segment) << 4) + Pxe->Undi.Offset != (UINTN) RomIdTableAddress) {
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_ERROR, "!PXE RomId Address Error\n\r"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock return EFI_NOT_FOUND;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock }
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // This is the magic to bind the global PXE interface
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // This dirtiness is for non-protocol shrouded access
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock SimpleNetworkDevice->PxeEntrySegment = Pxe->EntryPointSP.Segment;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock if (SimpleNetworkDevice->PxeEntrySegment == 0) {
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_ERROR, "!PXE EntryPointSP segment Error\n\r"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock return EFI_NOT_FOUND;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock }
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock SimpleNetworkDevice->PxeEntryOffset = Pxe->EntryPointSP.Offset;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG_NET, "The entry point is 0x%X:0x%X\n\r", SimpleNetworkDevice->PxeEntrySegment, SimpleNetworkDevice->
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock PxeEntryOffset
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock return EFI_SUCCESS;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock}
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock/**
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Effect the Far Call into the PXE Layer
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Note: When using a 32-bit stack segment do not push 32-bit words onto the stack. The PXE API
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock services will not work, unless there are three 16-bit parameters pushed onto the stack.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock push DS ;Far pointer to parameter structure
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock push offset pxe_data_call_struct ;is pushed onto stack.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock push Index ;UINT16 is pushed onto stack.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock call dword ptr (s_PXE ptr es:[di]).EntryPointSP
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock add sp, 6 ;Caller cleans up stack.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock @param SimpleNetworkDevice Device instance for simple network
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock @param Table Point to parameter/retun value table for legacy far call
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock @param TableSize The size of paramter/return value table
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock @param CallIndex The index of legacy call.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock @return EFI_STATUS
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock**/
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockEFI_STATUS
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrockMakePxeCall (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock IN OUT VOID *Table,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock IN UINTN TableSize,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock IN UINT16 CallIndex
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock )
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock{
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock EFI_STATUS Status;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock EFI_IA32_REGISTER_SET InOutRegs;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UINT16 *BPtr;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock VOID *Buffer;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UINTN Size;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock VOID *MemPageAddress;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock UINTN Index;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock BOOLEAN ThunkFailed;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "MakePxeCall(CallIndex = %02x, Table = %X, TableSize = %d)\n", CallIndex, Table, TableSize));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock if (SimpleNetworkDevice->PxeEntrySegment == 0 && SimpleNetworkDevice->PxeEntryOffset == 0) {
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock return EFI_DEVICE_ERROR;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock }
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Status = EFI_SUCCESS;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // Allocate a transient data structure for the argument table
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // This table needs to have the input XXX_t structure copied into here.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // The PXE UNDI can only grab this table when it's below one-MB, and
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // this implementation will not try to push this table on the stack
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // (although this is a possible optimization path since EFI always allocates
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // 4K as a minimum page size...............)
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Status = BiosSnp16AllocatePagesBelowOneMb (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock TableSize / EFI_PAGE_SIZE + 1,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock &MemPageAddress
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock if (EFI_ERROR (Status)) {
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_ERROR, "We had a failure in AllocatePages, status code = 0x%X\n", Status));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock return Status;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock }
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // Copy the > 1MB pool table to a sub-1MB buffer
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock CopyMem (MemPageAddress, Table, TableSize);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // Allocate space for IA-32 register context
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock ZeroMem (&InOutRegs, sizeof (InOutRegs));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock InOutRegs.X.ES = SimpleNetworkDevice->PxeEntrySegment;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock InOutRegs.X.DI = SimpleNetworkDevice->PxeEntryOffset;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // The game here is to build the stack which will subsequently
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // get copied down below 1 MB by the FarCall primitive.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // This is now our working stack
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Size = 6;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Status = gBS->AllocatePool (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock EfiRuntimeServicesData,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Size,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock &Buffer
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock if (EFI_ERROR (Status)) {
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock return Status;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock }
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock BPtr = (UINT16 *) Buffer;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock *BPtr++ = CallIndex;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // SP + 2
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock *BPtr++ = TO_OFFSET (MemPageAddress);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock *BPtr++ = TO_SEGMENT (MemPageAddress);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "State before FarCall86\n"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "The Buffer is at 0x%X\n\r", Buffer));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock BPtr = (UINT16 *) Buffer;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, " Buffer = %04X %04X %04X", *BPtr, *(BPtr + 1), *(BPtr + 2)));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, " MemPage = "));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock for (Index = 0; Index < TableSize; Index++) {
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, " %02x", *((UINT8 *) MemPageAddress + Index)));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock }
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "\n"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock ThunkFailed = SimpleNetworkDevice->LegacyBios->FarCall86 (
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock SimpleNetworkDevice->LegacyBios,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock SimpleNetworkDevice->PxeEntrySegment, // Input segment
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock SimpleNetworkDevice->PxeEntryOffset,
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock &InOutRegs, // Ptr to Regs
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Buffer, // Reference to Stack
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock 6 // Size of the Stack
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock );
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock if (ThunkFailed) {
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock return EFI_ABORTED;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock }
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "State after FarCall86\n"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "The Buffer is at 0x%X\n\r", Buffer));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock BPtr = (UINT16 *) Buffer;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, " Buffer = %04X %04X %04X", *BPtr, *(BPtr + 1), *(BPtr + 2)));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, " MemPage = "));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock for (Index = 0; Index < TableSize; Index++) {
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, " %02x", *((UINT8 *) MemPageAddress + Index)));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock }
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock DEBUG ((DEBUG_NET, "\n"));
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // Copy the sub 1MB table to > 1MB table
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock CopyMem (Table, MemPageAddress, TableSize);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // For PXE UNDI call, AX contains the return status.
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // Convert the PXE UNDI Status to EFI_STATUS type
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock if (InOutRegs.X.AX == PXENV_EXIT_SUCCESS) {
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Status = EFI_SUCCESS;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock } else {
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock Status = EFI_DEVICE_ERROR;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock }
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock // Clean up house
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock //
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock gBS->FreePool (Buffer);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) MemPageAddress, TableSize / EFI_PAGE_SIZE + 1);
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock return Status;
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock}
275c9da86e89f8abf71135cf63d9fc23671b2e60eschrock