bc.c

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

C
2,547
字号
  if (MakeCallbackPtr != NULL) {
    if (*MakeCallbackPtr) {
      if (!SetMakeCallback (Private)) {
        return EFI_INVALID_PARAMETER;
      }
    }

    PxebcMode->MakeCallbacks = *MakeCallbackPtr;
  }

  if (AutoArpPtr != NULL) {
    PxebcMode->AutoArp = *AutoArpPtr;
  }

  if (SendGuidPtr != NULL) {
    PxebcMode->SendGUID = *SendGuidPtr;
  }

  if (TimeToLivePtr != NULL) {
    PxebcMode->TTL = *TimeToLivePtr;
  }

  if (TypeOfServicePtr != NULL) {
    PxebcMode->ToS = *TypeOfServicePtr;
  }
  //
  // Unlock the instance data
  //
  DEBUG ((EFI_D_INFO, "\nSetparameters()  Exit = %xh  ", StatCode));

  EfiReleaseLock (&Private->Lock);
  return StatCode;
}
//
// //////////////////////////////////////////////////////////
//
//  BC Set Station IP Routine
//
EFI_STATUS
EFIAPI
BcSetStationIP (
  IN EFI_PXE_BASE_CODE_PROTOCOL *This,
  IN EFI_IP_ADDRESS             *StationIpPtr,
  IN EFI_IP_ADDRESS             *SubnetMaskPtr
  )
/*++

  Routine Description:
    Set the station IP address

  Arguments:
    This                 - Pointer to Pxe BaseCode Protocol
    StationIpPtr         - Pointer to the requested IP address to set in base code
    SubnetMaskPtr        - Pointer to the requested subnet mask for the base code

  Returns:

    EFI_SUCCESS          - Successfully set the parameters
    EFI_NOT_STARTED      - BC has not started
--*/
{
  EFI_PXE_BASE_CODE_MODE  *PxebcMode;
  EFI_STATUS              StatCode;
  PXE_BASECODE_DEVICE     *Private;

  //
  // Lock the instance data and make sure started
  //
  StatCode = EFI_SUCCESS;

  if (This == NULL) {
    DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL"));
    return EFI_INVALID_PARAMETER;
  }

  Private = CR (This, PXE_BASECODE_DEVICE, EfiBc, PXE_BASECODE_DEVICE_SIGNATURE);

  if (Private == NULL) {
    DEBUG ((EFI_D_ERROR, "PXE_BASECODE_DEVICE poiner == NULL"));
    return EFI_INVALID_PARAMETER;
  }

  EfiAcquireLock (&Private->Lock);

  if (This->Mode == NULL || !This->Mode->Started) {
    DEBUG ((EFI_D_ERROR, "BC was not started."));
    EfiReleaseLock (&Private->Lock);
    return EFI_NOT_STARTED;
  }

  PxebcMode = Private->EfiBc.Mode;

  if (StationIpPtr != NULL) {
    EfiCopyMem (&PxebcMode->StationIp, StationIpPtr, sizeof (EFI_IP_ADDRESS));
    Private->GoodStationIp = TRUE;
  }

  if (SubnetMaskPtr != NULL) {
    EfiCopyMem (&PxebcMode->SubnetMask, SubnetMaskPtr, sizeof (EFI_IP_ADDRESS));
  }
  //
  // Unlock the instance data
  //
  EfiReleaseLock (&Private->Lock);

  return EFI_SUCCESS;
}

EFI_DRIVER_BINDING_PROTOCOL mPxeBcDriverBinding = {
  PxeBcDriverSupported,
  PxeBcDriverStart,
  PxeBcDriverStop,
  0x10,
  NULL,
  NULL
};

EFI_STATUS
EFIAPI
PxeBcDriverSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN EFI_HANDLE                     Controller,
  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
  )
/*++

  Routine Description:
    Test to see if this driver supports Controller. Any Controller
    than contains a Snp protocol can be supported.

  Arguments:
    This                - Protocol instance pointer.
    Controller          - Handle of device to test.
    RemainingDevicePath - Not used.

  Returns:
    EFI_SUCCESS         - This driver supports this device.
    EFI_ALREADY_STARTED - This driver is already running on this device.
    other               - This driver does not support this device.

--*/
{
  EFI_STATUS                  Status;
  EFI_SIMPLE_NETWORK_PROTOCOL *SnpPtr;

  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiDevicePathProtocolGuid,
                  NULL,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                  );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiSimpleNetworkProtocolGuid,
                  &SnpPtr,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  gBS->CloseProtocol (
        Controller,
        &gEfiSimpleNetworkProtocolGuid,
        This->DriverBindingHandle,
        Controller
        );

  return Status;
}

EFI_STATUS
EFIAPI
PxeBcDriverStart (
  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN EFI_HANDLE                     Controller,
  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
  )
/*++

  Routine Description:
    Start the Base code driver.

  Arguments:
    This                - Protocol instance pointer.
    Controller          - Handle of device to test.
    RemainingDevicePath - Not used.

  Returns:
    EFI_SUCCESS         - This driver supports this device.
    EFI_ALREADY_STARTED - This driver is already running on this device.
    other               - This driver does not support this device.

--*/
{
  EFI_STATUS          Status;
  PXE_BASECODE_DEVICE *Private;
  LOADFILE_DEVICE     *pLF;

  //
  // Allocate structures needed by BaseCode and LoadFile protocols.
  //
  Status = gBS->AllocatePool (
                  EfiBootServicesData,
                  sizeof (PXE_BASECODE_DEVICE),
                  &Private
                  );

  if (!EFI_ERROR (Status)) {
    EfiZeroMem (Private, sizeof (PXE_BASECODE_DEVICE));
  } else {
    DEBUG ((EFI_D_NET, "\nBcNotifySnp()  Could not alloc PXE_BASECODE_DEVICE structure.\n"));
    return Status;
  }

  Status = gBS->AllocatePool (
                  EfiBootServicesData,
                  sizeof (LOADFILE_DEVICE),
                  &pLF
                  );

  if (!EFI_ERROR (Status)) {
    EfiZeroMem (pLF, sizeof (LOADFILE_DEVICE));
  } else {
    DEBUG ((EFI_D_NET, "\nBcNotifySnp()  Could not alloc LOADFILE_DEVICE structure.\n"));
    gBS->FreePool (Private);
    return Status;
  }

  Status = gBS->AllocatePool (
                  EfiBootServicesData,
                  sizeof (EFI_PXE_BASE_CODE_MODE),
                  &Private->EfiBc.Mode
                  );

  if (!EFI_ERROR (Status)) {
    EfiZeroMem (Private->EfiBc.Mode, sizeof (EFI_PXE_BASE_CODE_MODE));
  } else {
    DEBUG ((EFI_D_NET, "\nBcNotifySnp()  Could not alloc Mode structure.\n"));
    gBS->FreePool (Private);
    gBS->FreePool (pLF);
    return Status;
  }
  //
  // Lock access, just in case
  //
  EfiInitializeLock (&Private->Lock, EFI_TPL_CALLBACK);
  EfiAcquireLock (&Private->Lock);

  EfiInitializeLock (&pLF->Lock, EFI_TPL_CALLBACK);
  EfiAcquireLock (&pLF->Lock);

  //
  // Initialize PXE structure
  //
  //
  // First initialize the internal 'private' data that the application
  // does not see.
  //
  Private->Signature  = PXE_BASECODE_DEVICE_SIGNATURE;
  Private->Handle     = Controller;

  //
  // Get the NII interface
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
                  &Private->NiiPtr,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );

  if (EFI_ERROR (Status)) {
    Status = gBS->OpenProtocol (
                    Controller,
                    &gEfiNetworkInterfaceIdentifierProtocolGuid,
                    &Private->NiiPtr,
                    This->DriverBindingHandle,
                    Controller,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );

    if (EFI_ERROR (Status)) {
      goto PxeBcError;
    }
  }
  //
  // Get the Snp interface
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiSimpleNetworkProtocolGuid,
                  &Private->SimpleNetwork,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );

  if (EFI_ERROR (Status)) {
    goto PxeBcError;
  }
  //
  // Adding TCP support
  //
  Private->Tcp.TcpWrite = BcTcpWrite;
  Private->Tcp.TcpRead  = BcTcpRead;

  //
  // Next, initialize the external 'public' data that
  // the application does see.
  //
  Private->EfiBc.Revision       = EFI_PXE_BASE_CODE_INTERFACE_REVISION;
  Private->EfiBc.Start          = BcStart;
  Private->EfiBc.Stop           = BcStop;
  Private->EfiBc.Dhcp           = BcDhcp;
  Private->EfiBc.Discover       = BcDiscover;
  Private->EfiBc.Mtftp          = BcMtftp;
  Private->EfiBc.UdpWrite       = BcUdpWrite;
  Private->EfiBc.UdpRead        = BcUdpRead;
  Private->EfiBc.Arp            = BcArp;
  Private->EfiBc.SetIpFilter    = BcIpFilter;
  Private->EfiBc.SetParameters  = BcSetParameters;
  Private->EfiBc.SetStationIp   = BcSetStationIP;
  Private->EfiBc.SetPackets     = BcSetPackets;

  //
  // Initialize BaseCode Mode structure
  //
  Private->EfiBc.Mode->Started    = FALSE;
  Private->EfiBc.Mode->TTL        = DEFAULT_TTL;
  Private->EfiBc.Mode->ToS        = DEFAULT_ToS;
  Private->EfiBc.Mode->UsingIpv6  = FALSE;
  Private->EfiBc.Mode->AutoArp    = TRUE;

  //
  // Set to PXE_TRUE by the BC constructor if this BC
  // implementation supports IPv6.
  //
  Private->EfiBc.Mode->Ipv6Supported = SUPPORT_IPV6;

#if SUPPORT_IPV6
  Private->EfiBc.Mode->Ipv6Available = Private->NiiPtr->Ipv6Supported;
#else
  Private->EfiBc.Mode->Ipv6Available = FALSE;
#endif
  //
  // Set to TRUE by the BC constructor if this BC
  // implementation supports BIS.
  //
  Private->EfiBc.Mode->BisSupported = TRUE;
  Private->EfiBc.Mode->BisDetected  = PxebcBisDetect (Private);

  //
  // Initialize LoadFile structure.
  //
  pLF->Signature          = LOADFILE_DEVICE_SIGNATURE;
  pLF->LoadFile.LoadFile  = LoadFile;
  pLF->Private            = Private;

  //
  // Install protocol interfaces.
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Controller,
                  &gEfiTcpProtocolGuid,
                  &Private->Tcp,
                  &gEfiPxeBaseCodeProtocolGuid,
                  &Private->EfiBc,
                  &gEfiLoadFileProtocolGuid,
                  &pLF->LoadFile,
                  NULL
                  );

  if (EFI_ERROR (Status)) {
    gBS->CloseProtocol (
          Controller,
          &gEfiSimpleNetworkProtocolGuid,
          This->DriverBindingHandle,
          Controller
          );

    goto PxeBcError;
  }
  //
  // Release locks.
  //
  EfiReleaseLock (&pLF->Lock);
  EfiReleaseLock (&Private->Lock);
  return Status;

PxeBcError: ;
  gBS->FreePool (Private->EfiBc.Mode);
  gBS->FreePool (Private);
  gBS->FreePool (pLF);
  return Status;
}

EFI_STATUS
EFIAPI
PxeBcDriverStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN  EFI_HANDLE                     Controller,
  IN  UINTN                          NumberOfChildren,
  IN  EFI_HANDLE                     *ChildHandleBuffer
  )
/*++

  Routine Description:
    Stop the Base code driver.

  Arguments:
    This                - Protocol instance pointer.
    Controller          - Handle of device to test.
    NumberOfChildren    - Not used
    ChildHandleBuffer   - Not used

  Returns:
    EFI_SUCCESS         - This driver supports this device.
    EFI_ALREADY_STARTED - This driver is already running on this device.
    other               - This driver does not support this device.

--*/
{
  EFI_STATUS              Status;
  EFI_LOAD_FILE_PROTOCOL  *LfProtocol;
  LOADFILE_DEVICE         *LoadDevice;

  //
  // Get our context back.
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiLoadFileProtocolGuid,
                  &LfProtocol,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );

  if (EFI_ERROR (Status)) {
    return EFI_UNSUPPORTED;
  }

  LoadDevice = EFI_LOAD_FILE_DEV_FROM_THIS (LfProtocol);

  Status = gBS->UninstallMultipleProtocolInterfaces (
                  Controller,
                  &gEfiLoadFileProtocolGuid,
                  &LoadDevice->LoadFile,
                  &gEfiPxeBaseCodeProtocolGuid,
                  &LoadDevice->Private->EfiBc,
                  &gEfiTcpProtocolGuid,
                  &LoadDevice->Private->Tcp,
                  NULL
                  );

  if (!EFI_ERROR (Status)) {

    Status = gBS->CloseProtocol (
                    Controller,
                    &gEfiSimpleNetworkProtocolGuid,
                    This->DriverBindingHandle,
                    Controller
                    );

    gBS->FreePool (LoadDevice->Private->EfiBc.Mode);
    gBS->FreePool (LoadDevice->Private);
    gBS->FreePool (LoadDevice);
  }

  return Status;
}

EFI_STATUS
EFIAPI
InitializeBCDriver (
  IN EFI_HANDLE       ImageHandle,
  IN EFI_SYSTEM_TABLE *SystemTable
  )
/*++

  Routine Description:
    Initialize the base code drivers and install the driver binding

  Arguments:
    Standard EFI Image Entry

  Returns:
    EFI_SUCCESS         - This driver was successfully bound

--*/
{
  EFI_STATUS  Status;

  //
  // Initialize EFI li

⌨️ 快捷键说明

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