+++ /dev/null
-/** @file\r
- Implementation for iSCSI Boot Firmware Table publication.\r
-\r
-Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include "IScsiImpl.h"\r
-\r
-BOOLEAN mIbftInstalled = FALSE;\r
-UINTN mTableKey;\r
-\r
-/**\r
- Initialize the header of the iSCSI Boot Firmware Table.\r
-\r
- @param[out] Header The header of the iSCSI Boot Firmware Table.\r
- @param[in] OemId The OEM ID.\r
- @param[in] OemTableId The OEM table ID for the iBFT.\r
-**/\r
-VOID\r
-IScsiInitIbfTableHeader (\r
- OUT EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Header,\r
- IN UINT8 *OemId,\r
- IN UINT64 *OemTableId\r
- )\r
-{\r
- ZeroMem (Header, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER));\r
-\r
- Header->Signature = EFI_ACPI_3_0_ISCSI_BOOT_FIRMWARE_TABLE_SIGNATURE;\r
- Header->Length = IBFT_HEAP_OFFSET;\r
- Header->Revision = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_REVISION;\r
- Header->Checksum = 0;\r
-\r
- CopyMem (Header->OemId, OemId, sizeof (Header->OemId));\r
- CopyMem (&Header->OemTableId, OemTableId, sizeof (UINT64));\r
-}\r
-\r
-/**\r
- Initialize the control section of the iSCSI Boot Firmware Table.\r
-\r
- @param[in] Table The ACPI table.\r
- @param[in] HandleCount The number of the handles associated with iSCSI sessions, it's\r
- equal to the number of iSCSI sessions.\r
-**/\r
-VOID\r
-IScsiInitControlSection (\r
- IN EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table,\r
- IN UINTN HandleCount\r
- )\r
-{\r
- EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *Control;\r
- UINTN NumOffset;\r
-\r
- Control = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *) (Table + 1);\r
-\r
- ZeroMem (Control, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE));\r
-\r
- Control->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE_ID;\r
- Control->Header.Version = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE_VERSION;\r
- Control->Header.Length = (UINT16) sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE);\r
-\r
- //\r
- // Each session occupies two offsets, one for the NIC section,\r
- // the other for the Target section.\r
- //\r
- NumOffset = 2 * HandleCount;\r
- if (NumOffset > 4) {\r
- //\r
- // Need expand the control section if more than 2 NIC/Target sections\r
- // exist.\r
- //\r
- Control->Header.Length = (UINT16) (Control->Header.Length + (NumOffset - 4) * sizeof (UINT16));\r
- }\r
-}\r
-\r
-/**\r
- Add one item into the heap.\r
-\r
- @param[in, out] Heap On input, the current address of the heap; On output, the address of\r
- the heap after the item is added.\r
- @param[in] Data The data to add into the heap.\r
- @param[in] Len Length of the Data in byte.\r
-**/\r
-VOID\r
-IScsiAddHeapItem (\r
- IN OUT UINT8 **Heap,\r
- IN VOID *Data,\r
- IN UINTN Len\r
- )\r
-{\r
- //\r
- // Add one byte for the NULL delimiter.\r
- //\r
- *Heap -= Len + 1;\r
-\r
- CopyMem (*Heap, Data, Len);\r
- *(*Heap + Len) = 0;\r
-}\r
-\r
-/**\r
- Fill the Initiator section of the iSCSI Boot Firmware Table.\r
-\r
- @param[in] Table The ACPI table.\r
- @param[in, out] Heap The heap.\r
- @param[in] Handle The handle associated with the iSCSI session.\r
-**/\r
-VOID\r
-IScsiFillInitiatorSection (\r
- IN EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table,\r
- IN OUT UINT8 **Heap,\r
- IN EFI_HANDLE Handle\r
- )\r
-{\r
- EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *Control;\r
- EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE *Initiator;\r
- ISCSI_DRIVER_DATA *DriverData;\r
- ISCSI_SESSION *Session;\r
- ISCSI_PRIVATE_PROTOCOL *IScsiIdentifier;\r
- EFI_STATUS Status;\r
-\r
- Control = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *) (Table + 1);\r
-\r
- //\r
- // Initiator section immediately follows the control section.\r
- //\r
- Initiator = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE *) ((UINT8 *) Control + IBFT_ROUNDUP (Control->Header.Length));\r
-\r
- Control->InitiatorOffset = (UINT16) ((UINTN) Initiator - (UINTN) Table);\r
-\r
- ZeroMem (Initiator, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE));\r
-\r
- Initiator->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE_ID;\r
- Initiator->Header.Version = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE_VERSION;\r
- Initiator->Header.Length = (UINT16) sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE);\r
- Initiator->Header.Flags = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE_FLAG_BLOCK_VALID | EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE_FLAG_BOOT_SELECTED;\r
-\r
- //\r
- // Get the identifier from the handle.\r
- //\r
- Status = gBS->HandleProtocol (Handle, &gEfiCallerIdGuid, (VOID **) &IScsiIdentifier);\r
- if (EFI_ERROR (Status)) {\r
- ASSERT (FALSE);\r
- return ;\r
- }\r
-\r
- DriverData = ISCSI_DRIVER_DATA_FROM_IDENTIFIER (IScsiIdentifier);\r
- Session = &DriverData->Session;\r
-\r
- //\r
- // Fill the iSCSI Initiator Name into the heap.\r
- //\r
- IScsiAddHeapItem (Heap, Session->InitiatorName, Session->InitiatorNameLength - 1);\r
-\r
- Initiator->IScsiNameLength = (UINT16) (Session->InitiatorNameLength - 1);\r
- Initiator->IScsiNameOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);\r
-}\r
-\r
-/**\r
- Map the v4 IP address into v6 IP address.\r
-\r
- @param[in] V4 The v4 IP address.\r
- @param[out] V6 The v6 IP address.\r
-**/\r
-VOID\r
-IScsiMapV4ToV6Addr (\r
- IN EFI_IPv4_ADDRESS *V4,\r
- OUT EFI_IPv6_ADDRESS *V6\r
- )\r
-{\r
- UINTN Index;\r
-\r
- ZeroMem (V6, sizeof (EFI_IPv6_ADDRESS));\r
-\r
- V6->Addr[10] = 0xff;\r
- V6->Addr[11] = 0xff;\r
-\r
- for (Index = 0; Index < 4; Index++) {\r
- V6->Addr[12 + Index] = V4->Addr[Index];\r
- }\r
-}\r
-\r
-/**\r
- Get the NIC's PCI location and return it according to the composited\r
- format defined in iSCSI Boot Firmware Table.\r
-\r
- @param[in] Controller The handle of the controller.\r
-\r
- @return UINT16 The composited representation of the NIC PCI location.\r
- @retval 0 Other errors as indicated.\r
-**/\r
-UINT16\r
-IScsiGetNICPciLocation (\r
- IN EFI_HANDLE Controller\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
- EFI_HANDLE PciIoHandle;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- UINTN Segment;\r
- UINTN Bus;\r
- UINTN Device;\r
- UINTN Function;\r
-\r
- Status = gBS->HandleProtocol (\r
- Controller,\r
- &gEfiDevicePathProtocolGuid,\r
- (VOID **)&DevicePath\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return 0;\r
- }\r
-\r
- Status = gBS->LocateDevicePath (\r
- &gEfiPciIoProtocolGuid,\r
- &DevicePath,\r
- &PciIoHandle\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return 0;\r
- }\r
-\r
- Status = gBS->HandleProtocol (PciIoHandle, &gEfiPciIoProtocolGuid, (VOID **)&PciIo);\r
- if (EFI_ERROR (Status)) {\r
- return 0;\r
- }\r
-\r
- Status = PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);\r
- if (EFI_ERROR (Status)) {\r
- return 0;\r
- }\r
-\r
- return (UINT16) ((Bus << 8) | (Device << 3) | Function);\r
-}\r
-\r
-/**\r
- Fill the NIC and target sections in iSCSI Boot Firmware Table.\r
-\r
- @param[in] Table The buffer of the ACPI table.\r
- @param[in, out] Heap The heap buffer used to store the variable length parameters such as iSCSI name.\r
- @param[in] HandleCount Count The number of handles having iSCSI private protocol installed.\r
- @param[in] Handles The handle buffer.\r
-**/\r
-VOID\r
-IScsiFillNICAndTargetSections (\r
- IN EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table,\r
- IN OUT UINT8 **Heap,\r
- IN UINTN HandleCount,\r
- IN EFI_HANDLE *Handles\r
- )\r
-{\r
- EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *Control;\r
- EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE *Nic;\r
- EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE *Target;\r
- ISCSI_DRIVER_DATA *DriverData;\r
- ISCSI_SESSION_CONFIG_DATA *SessionConfigData;\r
- ISCSI_CHAP_AUTH_CONFIG_NVDATA *AuthConfig;\r
- UINT16 *SectionOffset;\r
- UINTN Index;\r
- UINT16 Length;\r
- EFI_MAC_ADDRESS MacAddress;\r
- UINTN HwAddressSize;\r
- ISCSI_PRIVATE_PROTOCOL *IScsiIdentifier;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Get the offset of the first Nic and Target section.\r
- //\r
- Control = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *) (Table + 1);\r
- Nic = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE *) ((UINTN) Table +\r
- Control->InitiatorOffset + IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE)));\r
- Target = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE *) ((UINTN) Nic +\r
- IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE)));\r
-\r
- SectionOffset = &Control->NIC0Offset;\r
-\r
- for (Index = 0; Index < HandleCount; Index++) {\r
- Status = gBS->HandleProtocol (Handles[Index], &gEfiCallerIdGuid, (VOID **)&IScsiIdentifier);\r
- if (EFI_ERROR (Status)) {\r
- ASSERT (FALSE);\r
- return ;\r
- }\r
-\r
- DriverData = ISCSI_DRIVER_DATA_FROM_IDENTIFIER (IScsiIdentifier);\r
- SessionConfigData = &DriverData->Session.ConfigData;\r
- AuthConfig = &DriverData->Session.AuthData.AuthConfig;\r
-\r
- //\r
- // Fill the Nic section.\r
- //\r
- ZeroMem (Nic, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE));\r
-\r
- Nic->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_ID;\r
- Nic->Header.Version = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_VERSION;\r
- Nic->Header.Length = (UINT16) sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE);\r
- Nic->Header.Index = (UINT8) Index;\r
- Nic->Header.Flags = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_FLAG_BLOCK_VALID |\r
- EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_FLAG_BOOT_SELECTED |\r
- EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_FLAG_GLOBAL;\r
-\r
- //\r
- // Get the subnet mask prefix length.\r
- //\r
- Nic->SubnetMaskPrefixLength = IScsiGetSubnetMaskPrefixLength (&SessionConfigData->NvData.SubnetMask);\r
-\r
- if (SessionConfigData->NvData.InitiatorInfoFromDhcp) {\r
- Nic->Origin = IpPrefixOriginDhcp;\r
- } else {\r
- Nic->Origin = IpPrefixOriginManual;\r
- }\r
- //\r
- // Map the various v4 addresses into v6 addresses.\r
- //\r
- IScsiMapV4ToV6Addr (&SessionConfigData->NvData.LocalIp, &Nic->Ip);\r
- IScsiMapV4ToV6Addr (&SessionConfigData->NvData.Gateway, &Nic->Gateway);\r
- IScsiMapV4ToV6Addr (&SessionConfigData->PrimaryDns, &Nic->PrimaryDns);\r
- IScsiMapV4ToV6Addr (&SessionConfigData->SecondaryDns, &Nic->SecondaryDns);\r
- IScsiMapV4ToV6Addr (&SessionConfigData->DhcpServer, &Nic->DhcpServer);\r
-\r
- Nic->VLanTag = NetLibGetVlanId (DriverData->Controller);\r
-\r
- Status = NetLibGetMacAddress (DriverData->Controller, &MacAddress, &HwAddressSize);\r
- ASSERT (Status == EFI_SUCCESS);\r
- CopyMem (Nic->Mac, MacAddress.Addr, sizeof (Nic->Mac));\r
-\r
- //\r
- // Get the PCI location of the Nic.\r
- //\r
- Nic->PciLocation = IScsiGetNICPciLocation (DriverData->Controller);\r
-\r
- *SectionOffset = (UINT16) ((UINTN) Nic - (UINTN) Table);\r
- SectionOffset++;\r
-\r
- //\r
- // Fill the Target section.\r
- //\r
- ZeroMem (Target, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE));\r
-\r
- Target->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_ID;\r
- Target->Header.Version = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_VERSION;\r
- Target->Header.Length = (UINT16) sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE);\r
- Target->Header.Index = (UINT8) Index;\r
- Target->Header.Flags = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_FLAG_BLOCK_VALID | EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_FLAG_BOOT_SELECTED;\r
- Target->Port = SessionConfigData->NvData.TargetPort;\r
- Target->NicIndex = (UINT8) Index;\r
-\r
- if (AuthConfig->CHAPType == ISCSI_CHAP_NONE) {\r
- Target->CHAPType = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_CHAP_TYPE_NO_CHAP;\r
- } if (AuthConfig->CHAPType == ISCSI_CHAP_UNI) {\r
- Target->CHAPType = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_CHAP_TYPE_CHAP;\r
- } else if (AuthConfig->CHAPType == ISCSI_CHAP_MUTUAL) {\r
- Target->CHAPType = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_CHAP_TYPE_MUTUAL_CHAP;\r
- }\r
-\r
- IScsiMapV4ToV6Addr (&SessionConfigData->NvData.TargetIp, &Target->Ip);\r
- CopyMem (Target->BootLun, SessionConfigData->NvData.BootLun, sizeof (Target->BootLun));\r
-\r
- //\r
- // Target iSCSI Name, CHAP name/secret, reverse CHAP name/secret.\r
- //\r
- Length = (UINT16) AsciiStrLen (SessionConfigData->NvData.TargetName);\r
- IScsiAddHeapItem (Heap, SessionConfigData->NvData.TargetName, Length);\r
-\r
- Target->IScsiNameLength = Length;\r
- Target->IScsiNameOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);\r
-\r
- if (Target->CHAPType != EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_CHAP_TYPE_NO_CHAP) {\r
- //\r
- // CHAP Name\r
- //\r
- Length = (UINT16) AsciiStrLen (AuthConfig->CHAPName);\r
- IScsiAddHeapItem (Heap, AuthConfig->CHAPName, Length);\r
- Target->CHAPNameLength = Length;\r
- Target->CHAPNameOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);\r
-\r
- //\r
- // CHAP Secret\r
- //\r
- Length = (UINT16) AsciiStrLen (AuthConfig->CHAPSecret);\r
- IScsiAddHeapItem (Heap, AuthConfig->CHAPSecret, Length);\r
- Target->CHAPSecretLength = Length;\r
- Target->CHAPSecretOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);\r
-\r
- if (Target->CHAPType == EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_CHAP_TYPE_MUTUAL_CHAP) {\r
- //\r
- // Reverse CHAP Name\r
- //\r
- Length = (UINT16) AsciiStrLen (AuthConfig->ReverseCHAPName);\r
- IScsiAddHeapItem (Heap, AuthConfig->ReverseCHAPName, Length);\r
- Target->ReverseCHAPNameLength = Length;\r
- Target->ReverseCHAPNameOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);\r
-\r
- //\r
- // Reverse CHAP Secret\r
- //\r
- Length = (UINT16) AsciiStrLen (AuthConfig->ReverseCHAPSecret);\r
- IScsiAddHeapItem (Heap, AuthConfig->ReverseCHAPSecret, Length);\r
- Target->ReverseCHAPSecretLength = Length;\r
- Target->ReverseCHAPSecretOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);\r
- }\r
- }\r
-\r
- *SectionOffset = (UINT16) ((UINTN) Target - (UINTN) Table);\r
- SectionOffset++;\r
-\r
- //\r
- // Advance to the next NIC/Target pair\r
- //\r
- Nic = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE *) ((UINTN) Target +\r
- IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE)));\r
- Target = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE *) ((UINTN) Nic +\r
- IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE)));\r
- }\r
-}\r
-\r
-/**\r
- Publish and remove the iSCSI Boot Firmware Table according to the iSCSI\r
- session status.\r
-**/\r
-VOID\r
-IScsiPublishIbft (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;\r
- EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table;\r
- UINTN HandleCount;\r
- EFI_HANDLE *HandleBuffer;\r
- UINT8 *Heap;\r
- UINT8 Checksum;\r
- EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp;\r
- EFI_ACPI_DESCRIPTION_HEADER *Rsdt;\r
- EFI_ACPI_DESCRIPTION_HEADER *Xsdt;\r
-\r
- Rsdt = NULL;\r
- Xsdt = NULL;\r
-\r
- Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTableProtocol);\r
- if (EFI_ERROR (Status)) {\r
- return ;\r
- }\r
-\r
-\r
- //\r
- // Find ACPI table RSD_PTR from system table\r
- //\r
- Status = EfiGetSystemConfigurationTable (&gEfiAcpiTableGuid, (VOID **) &Rsdp);\r
- if (EFI_ERROR (Status)) {\r
- Status = EfiGetSystemConfigurationTable (&gEfiAcpi10TableGuid, (VOID **) &Rsdp);\r
- }\r
-\r
- if (EFI_ERROR (Status) || (Rsdp == NULL)) {\r
- return ;\r
- } else if (Rsdp->Revision >= EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION && Rsdp->XsdtAddress != 0) {\r
- Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Rsdp->XsdtAddress;\r
- } else if (Rsdp->RsdtAddress != 0) {\r
- Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Rsdp->RsdtAddress;\r
- }\r
-\r
- if ((Xsdt == NULL) && (Rsdt == NULL)) {\r
- return ;\r
- }\r
-\r
- if (mIbftInstalled) {\r
- Status = AcpiTableProtocol->UninstallAcpiTable (\r
- AcpiTableProtocol,\r
- mTableKey\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return ;\r
- }\r
- mIbftInstalled = FALSE;\r
- }\r
-\r
- //\r
- // Get all iSCSI private protocols.\r
- //\r
- Status = gBS->LocateHandleBuffer (\r
- ByProtocol,\r
- &gEfiCallerIdGuid,\r
- NULL,\r
- &HandleCount,\r
- &HandleBuffer\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return ;\r
- }\r
- //\r
- // Allocate 4k bytes to hold the ACPI table.\r
- //\r
- Table = AllocateZeroPool (IBFT_MAX_SIZE);\r
- if (Table == NULL) {\r
- return ;\r
- }\r
-\r
- Heap = (UINT8 *) Table + IBFT_HEAP_OFFSET;\r
-\r
- //\r
- // Fill in the various section of the iSCSI Boot Firmware Table.\r
- //\r
- if (Rsdp->Revision >= EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION) {\r
- IScsiInitIbfTableHeader (Table, Xsdt->OemId, &Xsdt->OemTableId);\r
- } else {\r
- IScsiInitIbfTableHeader (Table, Rsdt->OemId, &Rsdt->OemTableId);\r
- }\r
-\r
- IScsiInitControlSection (Table, HandleCount);\r
- IScsiFillInitiatorSection (Table, &Heap, HandleBuffer[0]);\r
- IScsiFillNICAndTargetSections (Table, &Heap, HandleCount, HandleBuffer);\r
-\r
- Checksum = CalculateCheckSum8((UINT8 *)Table, Table->Length);\r
- Table->Checksum = Checksum;\r
-\r
- FreePool (HandleBuffer);\r
-\r
- //\r
- // Install or update the iBFT table.\r
- //\r
- Status = AcpiTableProtocol->InstallAcpiTable (\r
- AcpiTableProtocol,\r
- Table,\r
- Table->Length,\r
- &mTableKey\r
- );\r
- if (EFI_ERROR(Status)) {\r
- return;\r
- }\r
-\r
- mIbftInstalled = TRUE;\r
- FreePool (Table);\r
-}\r