decode.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,665 行 · 第 1/4 页

C
1,665
字号
  if (CdbPtr->CPBsize == PXE_CPBSIZE_NOT_USED) {
    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
    return ;
  }

  CdbPtr->StatCode = (PXE_STATCODE) E100bTransmit (AdapterInfo, CdbPtr->CPBaddr, CdbPtr->OpFlags);

  if (CdbPtr->StatCode != PXE_STATCODE_SUCCESS) {
    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
  }

  return ;
}

VOID
UNDI_Receive (
  IN  PXE_CDB           *CdbPtr,
  IN  NIC_DATA_INSTANCE *AdapterInfo
  )
/*++

Routine Description:
  When the network adapter has received a frame, this command is used to copy the frame
  into the driver/application storage location.  Once a frame has been copied, it is
  removed from the receive queue.

Arguments:
  CdbPtr            - Pointer to the command descriptor block.
  AdapterInfo       - Pointer to the NIC data structure information which the UNDI driver is layering on..

Returns:
  None

--*/
{
  PXE_CPB_RECEIVE *cpbptr;

  //
  // check if RU has started...
  //
  if (!AdapterInfo->Receive_Started) {
    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    CdbPtr->StatCode  = PXE_STATCODE_NOT_INITIALIZED;
    return ;
  }

  cpbptr            = (PXE_CPB_RECEIVE *) (UINTN) CdbPtr->CPBaddr;

  CdbPtr->StatCode  = (UINT16) E100bReceive (AdapterInfo, CdbPtr->CPBaddr, CdbPtr->DBaddr);
  if (CdbPtr->StatCode != PXE_STATCODE_SUCCESS) {
    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;

  }

  return ;
}

VOID
UNDI_APIEntry_old (
  IN  UINT64 cdb
  )
/*++

Routine Description:
  This is the main SW UNDI API entry using the older nii protocol.
  The parameter passed in is a 64 bit flat model virtual
  address of the cdb.  We then jump into the common routine for both old and
  new nii protocol entries.

Arguments:
  CdbPtr            - Pointer to the command descriptor block.
  AdapterInfo       - Pointer to the NIC data structure information which the UNDI driver is layering on..

Returns:
  None

--*/
// TODO:    cdb - add argument and description to function comment
{
  PXE_CDB           *CdbPtr;
  NIC_DATA_INSTANCE *AdapterInfo;

  if (cdb == (UINT64) 0) {
    return ;

  }

  CdbPtr = (PXE_CDB *) (UINTN) cdb;

  if (CdbPtr->IFnum >= pxe->IFcnt) {
    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
    return ;
  }

  AdapterInfo               = &(UNDI32DeviceList[CdbPtr->IFnum]->NicInfo);
  
  //
  // entering from older entry point
  //
  AdapterInfo->VersionFlag  = 0x30;
  UNDI_APIEntry_Common (cdb);
}

VOID
UNDI_APIEntry_new (
  IN  UINT64 cdb
  )
/*++

Routine Description:
  This is the main SW UNDI API entry using the newer nii protocol.
  The parameter passed in is a 64 bit flat model virtual
  address of the cdb.  We then jump into the common routine for both old and
  new nii protocol entries.

Arguments:
  CdbPtr            - Pointer to the command descriptor block.
  AdapterInfo       - Pointer to the NIC data structure information which the UNDI driver is layering on..

Returns:
  None

--*/
// TODO:    cdb - add argument and description to function comment
{
  PXE_CDB           *CdbPtr;
  NIC_DATA_INSTANCE *AdapterInfo;

  if (cdb == (UINT64) 0) {
    return ;

  }

  CdbPtr = (PXE_CDB *) (UINTN) cdb;

  if (CdbPtr->IFnum >= pxe_31->IFcnt) {
    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
    return ;
  }

  AdapterInfo               = &(UNDI32DeviceList[CdbPtr->IFnum]->NicInfo);
  //
  // entering from older entry point
  //
  AdapterInfo->VersionFlag  = 0x31;
  UNDI_APIEntry_Common (cdb);
}

VOID
UNDI_APIEntry_Common (
  IN  UINT64 cdb
  )
/*++

Routine Description:
  This is the common routine for both old and new entry point procedures.
  The parameter passed in is a 64 bit flat model virtual
  address of the cdb.  We then jump into the service routine pointed to by the
  Api_Table[OpCode].

Arguments:
  CdbPtr            - Pointer to the command descriptor block.
  AdapterInfo       - Pointer to the NIC data structure information which the UNDI driver is layering on..

Returns:
  None

--*/
// TODO:    cdb - add argument and description to function comment
{
  PXE_CDB           *CdbPtr;
  NIC_DATA_INSTANCE *AdapterInfo;
  UNDI_CALL_TABLE   *tab_ptr;

  CdbPtr = (PXE_CDB *) (UINTN) cdb;

  //
  // check the OPCODE range
  //
  if ((CdbPtr->OpCode > PXE_OPCODE_LAST_VALID) ||
      (CdbPtr->StatCode != PXE_STATCODE_INITIALIZE) ||
      (CdbPtr->StatFlags != PXE_STATFLAGS_INITIALIZE) ||
      (CdbPtr->IFnum >= pxe_31->IFcnt) ) {
    goto badcdb;

  }

  if (CdbPtr->CPBsize == PXE_CPBSIZE_NOT_USED) {
    if (CdbPtr->CPBaddr != PXE_CPBADDR_NOT_USED) {
      goto badcdb;
    }
  } else if (CdbPtr->CPBaddr == PXE_CPBADDR_NOT_USED) {
    goto badcdb;
  }

  if (CdbPtr->DBsize == PXE_DBSIZE_NOT_USED) {
    if (CdbPtr->DBaddr != PXE_DBADDR_NOT_USED) {
      goto badcdb;
    }
  } else if (CdbPtr->DBaddr == PXE_DBADDR_NOT_USED) {
    goto badcdb;
  }

  //
  // check if cpbsize and dbsize are as needed
  // check if opflags are as expected
  //
  tab_ptr = &api_table[CdbPtr->OpCode];

  if (tab_ptr->cpbsize != (UINT16) (DONT_CHECK) && tab_ptr->cpbsize != CdbPtr->CPBsize) {
    goto badcdb;
  }

  if (tab_ptr->dbsize != (UINT16) (DONT_CHECK) && tab_ptr->dbsize != CdbPtr->DBsize) {
    goto badcdb;
  }

  if (tab_ptr->opflags != (UINT16) (DONT_CHECK) && tab_ptr->opflags != CdbPtr->OpFlags) {
    goto badcdb;

  }

  AdapterInfo = &(UNDI32DeviceList[CdbPtr->IFnum]->NicInfo);

  //
  // check if UNDI_State is valid for this call
  //
  if (tab_ptr->state != (UINT16) (-1)) {
    //
    // should atleast be started
    //
    if (AdapterInfo->State == PXE_STATFLAGS_GET_STATE_STOPPED) {
      CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
      CdbPtr->StatCode  = PXE_STATCODE_NOT_STARTED;
      return ;
    }
    //
    // check if it should be initialized
    //
    if (tab_ptr->state == 2) {
      if (AdapterInfo->State != PXE_STATFLAGS_GET_STATE_INITIALIZED) {
        CdbPtr->StatCode  = PXE_STATCODE_NOT_INITIALIZED;
        CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
        return ;
      }
    }
  }
  //
  // set the return variable for success case here
  //
  CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_COMPLETE;
  CdbPtr->StatCode  = PXE_STATCODE_SUCCESS;

  tab_ptr->api_ptr (CdbPtr, AdapterInfo);
  return ;
  //
  // %% AVL - check for command linking
  //
badcdb:
  CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
  CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
  return ;
}

UINT8
ChkSum (
  IN  VOID   *Buffer,
  IN  UINT16 Len
  )
/*++

Routine Description:
  This does an 8 bit check sum of the passed in buffer for Len bytes.
  This is primarily used to update the check sum in the SW UNDI header.

Arguments:
  Buffer            - Pointer to the passed in buffer to check sum
  Len               - Length of buffer to be check summed in bytes.

Returns:
  None

--*/
{
  UINT8 Chksum;
  INT8  *Bp;

  Chksum = 0;
  if ((Bp = Buffer) != NULL) {
    while (Len--) {
      Chksum = (UINT8) (Chksum +*Bp++);

    }

  }

  return Chksum;
}

VOID
PxeUpdate (
  IN  NIC_DATA_INSTANCE *NicPtr,
  IN PXE_SW_UNDI        *PxePtr
  )
/*++

Routine Description:
  When called with a null NicPtr, this routine decrements the number of NICs
  this UNDI is supporting and removes the NIC_DATA_POINTER from the array.
  Otherwise, it increments the number of NICs this UNDI is supported and
  updates the pxe.Fudge to ensure a proper check sum results.

Arguments:
  NicPtr            - Pointer to the NIC data structure.

Returns:
  None

--*/
// TODO:    PxePtr - add argument and description to function comment
{
  if (NicPtr == NULL) {
    if (PxePtr->IFcnt > 0) {
      //
      // number of NICs this undi supports
      //
      PxePtr->IFcnt--;
    }

    PxePtr->Fudge = (UINT8) (PxePtr->Fudge - ChkSum ((VOID *) PxePtr, PxePtr->Len));
    return ;
  }

  //
  // number of NICs this undi supports
  //
  PxePtr->IFcnt++;
  PxePtr->Fudge = (UINT8) (PxePtr->Fudge - ChkSum ((VOID *) PxePtr, PxePtr->Len));

  return ;
}

VOID
PxeStructInit (
  IN PXE_SW_UNDI *PxePtr,
  IN UINTN       VersionFlag
  )
/*++

Routine Description:
  Initialize the !PXE structure

Arguments:
  RemainingDevicePath - Not used, always produce all possible children.

Returns:
  EFI_SUCCESS         - This driver is added to Controller.
  other               - This driver does not support this device.

--*/
// TODO:    PxePtr - add argument and description to function comment
// TODO:    VersionFlag - add argument and description to function comment
{
  //
  // Initialize the !PXE structure
  //
  PxePtr->Signature = PXE_ROMID_SIGNATURE;
  PxePtr->Len       = sizeof (PXE_SW_UNDI);
  //
  // cksum
  //
  PxePtr->Fudge     = 0;
  //
  // number of NICs this undi supports
  //
  PxePtr->IFcnt = 0;
  PxePtr->Rev       = PXE_ROMID_REV;
  PxePtr->MajorVer  = PXE_ROMID_MAJORVER;
  PxePtr->MinorVer  = PXE_ROMID_MINORVER;
  PxePtr->reserved1 = 0;

  PxePtr->Implementation = PXE_ROMID_IMP_SW_VIRT_ADDR |
    PXE_ROMID_IMP_FRAG_SUPPORTED |
    PXE_ROMID_IMP_CMD_LINK_SUPPORTED |
    PXE_ROMID_IMP_NVDATA_READ_ONLY |
    PXE_ROMID_IMP_STATION_ADDR_SETTABLE |
    PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED |
    PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED |
    PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED |
    PXE_ROMID_IMP_FILTERED_MULTICAST_RX_SUPPORTED |
    PXE_ROMID_IMP_SOFTWARE_INT_SUPPORTED |
    PXE_ROMID_IMP_PACKET_RX_INT_SUPPORTED;

  if (VersionFlag == 0x30) {
    PxePtr->EntryPoint = (UINT64) UNDI_APIEntry_old;
  } else {
    PxePtr->EntryPoint  = (UINT64) UNDI_APIEntry_new;
    PxePtr->MinorVer    = PXE_ROMID_MINORVER_31;
  }

  PxePtr->reserved2[0]  = 0;
  PxePtr->reserved2[1]  = 0;
  PxePtr->reserved2[2]  = 0;
  PxePtr->BusCnt        = 1;
  PxePtr->BusType[0]    = PXE_BUSTYPE_PCI;

  PxePtr->Fudge         = (UINT8) (PxePtr->Fudge - ChkSum ((VOID *) PxePtr, PxePtr->Len));
}

#pragma data_seg()

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?