e100b.c

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

C
2,690
字号
/*++

Copyright (c) 2004, 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:
  
  
 E100B.C

Abstract:


Revision History

--*/

#include "undi32.h"

#if UNDI_DEBUG
extern VOID (*break_pt) ();
#endif
//
// How to wait for the command unit to accept a command.
// Typically this takes 0 ticks.
//
#define wait_for_cmd_done(cmd_ioaddr) \
{                      \
  INT16 wait = 2000;              \
  while ((InByte (AdapterInfo, cmd_ioaddr) != 0) && --wait >= 0)  \
    DelayIt (AdapterInfo, 10);  \
  if (wait == 0) \
    DelayIt (AdapterInfo, 50);    \
}

UINT8
InByte (
  IN NIC_DATA_INSTANCE *AdapterInfo,
  IN UINT32            Port
  )
/*++

Routine Description:
  This function calls the MemIo callback to read a byte from the device's
  address space
  Since UNDI3.0 uses the TmpMemIo function (instead of the callback routine)
  which also takes the UniqueId parameter (as in UNDI3.1 spec) we don't have 
  to make undi3.0 a special case
  
Arguments:
  Port              - Which port to read from.

Returns:
  Results           - The data read from the port.

--*/
// TODO:    AdapterInfo - add argument and description to function comment
{
  UINT8 Results;

  (*AdapterInfo->Mem_Io) (
    AdapterInfo->Unique_ID, 
    PXE_MEM_READ, 
    1, 
    (UINT64)Port,
    (UINT64)&Results
    );
  return Results;
}

UINT16
InWord (
  IN NIC_DATA_INSTANCE *AdapterInfo,
  IN UINT32            Port
  )
/*++

Routine Description:
  This function calls the MemIo callback to read a word from the device's
  address space
  Since UNDI3.0 uses the TmpMemIo function (instead of the callback routine)
  which also takes the UniqueId parameter (as in UNDI3.1 spec) we don't have 
  to make undi3.0 a special case

Arguments:
  Port              - Which port to read from.

Returns:
  Results           - The data read from the port.

--*/
// TODO:    AdapterInfo - add argument and description to function comment
{
  UINT16  Results;

  (*AdapterInfo->Mem_Io) (
    AdapterInfo->Unique_ID,
    PXE_MEM_READ,
    2,
    (UINT64)Port,
    (UINT64)&Results
    );
  return Results;
}

UINT32
InLong (
  IN NIC_DATA_INSTANCE *AdapterInfo,
  IN UINT32            Port
  )
/*++

Routine Description:
  This function calls the MemIo callback to read a dword from the device's
  address space
  Since UNDI3.0 uses the TmpMemIo function (instead of the callback routine)
  which also takes the UniqueId parameter (as in UNDI3.1 spec) we don't have 
  to make undi3.0 a special case

Arguments:
  Port              - Which port to read from.

Returns:
  Results           - The data read from the port.

--*/
// TODO:    AdapterInfo - add argument and description to function comment
{
  UINT32  Results;

  (*AdapterInfo->Mem_Io) (
    AdapterInfo->Unique_ID,
    PXE_MEM_READ,
    4,
    (UINT64)Port,
    (UINT64)&Results
    );
  return Results;
}

VOID
OutByte (
  IN NIC_DATA_INSTANCE *AdapterInfo,
  IN UINT8             Data,
  IN UINT32            Port
  )
/*++

Routine Description:
  This function calls the MemIo callback to write a byte from the device's
  address space
  Since UNDI3.0 uses the TmpMemIo function (instead of the callback routine)
  which also takes the UniqueId parameter (as in UNDI3.1 spec) we don't have 
  to make undi3.0 a special case

Arguments:
  Data              - Data to write to Port.
  Port              - Which port to write to.

Returns:
  none

--*/
// TODO:    AdapterInfo - add argument and description to function comment
{
  UINT8 Val;

  Val = Data;
  (*AdapterInfo->Mem_Io) (
     AdapterInfo->Unique_ID,
     PXE_MEM_WRITE,
     1,
     (UINT64)Port,
     (UINT64)&Val
     );
  return ;
}

VOID
OutWord (
  IN NIC_DATA_INSTANCE *AdapterInfo,
  IN UINT16            Data,
  IN UINT32            Port
  )
/*++

Routine Description:
  This function calls the MemIo callback to write a word from the device's
  address space
  Since UNDI3.0 uses the TmpMemIo function (instead of the callback routine)
  which also takes the UniqueId parameter (as in UNDI3.1 spec) we don't have 
  to make undi3.0 a special case

Arguments:
  Data              - Data to write to Port.
  Port              - Which port to write to.

Returns:
  none

--*/
// TODO:    AdapterInfo - add argument and description to function comment
{
  UINT16  Val;

  Val = Data;
  (*AdapterInfo->Mem_Io) (
     AdapterInfo->Unique_ID,
     PXE_MEM_WRITE,
     2,
     (UINT64)Port,
     (UINT64)&Val
     );
  return ;
}

VOID
OutLong (
  IN NIC_DATA_INSTANCE *AdapterInfo,
  IN UINT32            Data,
  IN UINT32            Port
  )
/*++

Routine Description:
  This function calls the MemIo callback to write a dword from the device's
  address space
  Since UNDI3.0 uses the TmpMemIo function (instead of the callback routine)
  which also takes the UniqueId parameter (as in UNDI3.1 spec) we don't have 
  to make undi3.0 a special case

Arguments:
  Data              - Data to write to Port.
  Port              - Which port to write to.

Returns:
  none

--*/
// TODO:    AdapterInfo - add argument and description to function comment
{
  UINT32  Val;

  Val = Data;
  (*AdapterInfo->Mem_Io) (
     AdapterInfo->Unique_ID,
     PXE_MEM_WRITE,
     4,
     (UINT64)Port,
     (UINT64)&Val
     );
  return ;
}

UINTN
MapIt (
  IN NIC_DATA_INSTANCE *AdapterInfo,
  IN UINT64            MemAddr,
  IN UINT32            Size,
  IN UINT32            Direction,
  OUT UINT64           MappedAddr
  )
/*++

Routine Description:

  TODO: Add function description

Arguments:

  AdapterInfo - TODO: add argument description
  MemAddr     - TODO: add argument description
  Size        - TODO: add argument description
  Direction   - TODO: add argument description
  MappedAddr  - TODO: add argument description

Returns:

  TODO: add return values

--*/
{
  UINT64  *PhyAddr;

  PhyAddr = (UINT64 *) (UINTN) MappedAddr;
  //
  // mapping is different for theold and new NII protocols
  //
  if (AdapterInfo->VersionFlag == 0x30) {
    if (AdapterInfo->Virt2Phys_30 == (VOID *) NULL) {
      *PhyAddr = (UINT64) AdapterInfo->MemoryPtr;
    } else {
      (*AdapterInfo->Virt2Phys_30) (MemAddr, (UINT64) PhyAddr);
    }

    if (*PhyAddr > FOUR_GIGABYTE) {
      return PXE_STATCODE_INVALID_PARAMETER;
    }
  } else {
    if (AdapterInfo->Map_Mem == (VOID *) NULL) {
      //
      // this UNDI cannot handle addresses beyond 4 GB without a map routine
      //
      if (MemAddr > FOUR_GIGABYTE) {
        return PXE_STATCODE_INVALID_PARAMETER;
      } else {
        *PhyAddr = MemAddr;
      }
    } else {
      (*AdapterInfo->Map_Mem) (
        AdapterInfo->Unique_ID,
        MemAddr,
        Size,
        Direction,
        MappedAddr
        );
    }
  }

  return PXE_STATCODE_SUCCESS;
}

VOID
UnMapIt (
  IN NIC_DATA_INSTANCE *AdapterInfo,
  IN UINT64            MemAddr,
  IN UINT32            Size,
  IN UINT32            Direction,
  IN UINT64            MappedAddr
  )
/*++

Routine Description:

  TODO: Add function description

Arguments:

  AdapterInfo - TODO: add argument description
  MemAddr     - TODO: add argument description
  Size        - TODO: add argument description
  Direction   - TODO: add argument description
  MappedAddr  - TODO: add argument description

Returns:

  TODO: add return values

--*/
{
  if (AdapterInfo->VersionFlag > 0x30) {
    //
    // no mapping service
    //
    if (AdapterInfo->UnMap_Mem != (VOID *) NULL) {
      (*AdapterInfo->UnMap_Mem) (
        AdapterInfo->Unique_ID,
        MemAddr,
        Size,
        Direction,
        MappedAddr
        );

    }
  }

  return ;
}

VOID
DelayIt (
  IN NIC_DATA_INSTANCE *AdapterInfo,
  UINT16               MicroSeconds
  )
/*++

Routine Description:

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

Returns:

--*/
// TODO:    MicroSeconds - add argument and description to function comment
{
  if (AdapterInfo->VersionFlag == 0x30) {
    (*AdapterInfo->Delay_30) (MicroSeconds);
  } else {
    (*AdapterInfo->Delay) (AdapterInfo->Unique_ID, MicroSeconds);
  }
}

VOID
BlockIt (
  IN NIC_DATA_INSTANCE *AdapterInfo,
  UINT32               flag
  )
/*++

Routine Description:

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

Returns:

--*/
// TODO:    flag - add argument and description to function comment
{
  if (AdapterInfo->VersionFlag == 0x30) {
    (*AdapterInfo->Block_30) (flag);
  } else {
    (*AdapterInfo->Block) (AdapterInfo->Unique_ID, flag);
  }
}

UINT8
Load_Base_Regs (
  NIC_DATA_INSTANCE *AdapterInfo
  )
/*++

Routine Description:

  TODO: Add function description

Arguments:

  AdapterInfo - TODO: add argument description

Returns:

  TODO: add return values

--*/
{
  //
  // we will use the linear (flat) memory model and fill our base registers
  // with 0's so that the entire physical address is our offset
  //
  //
  // we reset the statistics totals here because this is where we are loading stats addr
  //
  AdapterInfo->RxTotals = 0;
  AdapterInfo->TxTotals = 0;

  //
  // Load the statistics block address.
  //
  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
  OutLong (AdapterInfo, (UINT32) AdapterInfo->stat_phy_addr, AdapterInfo->ioaddr + SCBPointer);
  OutByte (AdapterInfo, CU_STATSADDR, AdapterInfo->ioaddr + SCBCmd);
  AdapterInfo->statistics->done_marker = 0;

  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
  OutLong (AdapterInfo, 0, AdapterInfo->ioaddr + SCBPointer);
  OutByte (AdapterInfo, RX_ADDR_LOAD, AdapterInfo->ioaddr + SCBCmd);

  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
  OutLong (AdapterInfo, 0, AdapterInfo->ioaddr + SCBPointer);
  OutByte (AdapterInfo, CU_CMD_BASE, AdapterInfo->ioaddr + SCBCmd);

  return 0;
}

UINT8
IssueCB (
  NIC_DATA_INSTANCE *AdapterInfo,
  TxCB              *cmd_ptr
  )
/*++

Routine Description:

  TODO: Add function description

Arguments:

  AdapterInfo - TODO: add argument description
  cmd_ptr     - TODO: add argument description

Returns:

  TODO: add return values

--*/
{
  UINT16  status;

  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);

  //
  // read the CU status, if it is idle, write the address of cb_ptr
  // in the scbpointer and issue a cu_start,
  // if it is suspended, remove the suspend bit in the previous command
  // block and issue a resume
  //
  // Ensure that the CU Active Status bit is not on from previous CBs.
  //
  status = InWord (AdapterInfo, AdapterInfo->ioaddr + SCBStatus);

  //
  // Skip acknowledging the interrupt if it is not already set
  //

  //
  // ack only the cna the integer
  //
  if ((status & SCB_STATUS_CNA) != 0) {
    OutWord (AdapterInfo, SCB_STATUS_CNA, AdapterInfo->ioaddr + SCBStatus);

  }

  if ((status & SCB_STATUS_CU_MASK) == SCB_STATUS_CU_IDLE) {
    //
    // give a cu_start
    //
    OutLong (AdapterInfo, cmd_ptr->PhysTCBAddress, AdapterInfo->ioaddr + SCBPointer);
    OutByte (AdapterInfo, CU_START, AdapterInfo->ioaddr + SCBCmd);
  } else {
    //
    // either active or suspended, give a resume
    //

    cmd_ptr->PrevTCBVirtualLinkPtr->cb_header.command &= ~(CmdSuspend | CmdIntr);
    OutByte (AdapterInfo, CU_RESUME, AdapterInfo->ioaddr + SCBCmd);
  }

  return 0;

⌨️ 快捷键说明

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