]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/IScsiDxe/IScsiIbft.c
Clean up the private GUID definition in module Level.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / IScsiDxe / IScsiIbft.c
CommitLineData
12618416 1/** @file\r
2 Implementation for iSCSI Boot Firmware Table publication.\r
6a690e23 3\r
c8ad2d7a 4Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>\r
e5eed7d3 5This program and the accompanying materials\r
7a444476 6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
6a690e23 12\r
12618416 13**/\r
6a690e23 14\r
15#include "IScsiImpl.h"\r
16\r
85b990a8 17BOOLEAN mIbftInstalled = FALSE;\r
18UINTN mTableKey;\r
19\r
12618416 20/**\r
21 Initialize the header of the iSCSI Boot Firmware Table.\r
22 \r
f6b7393c 23 @param[out] Header The header of the iSCSI Boot Firmware Table.\r
24 @param[in] OemId The OEM ID.\r
25 @param[in] OemTableId The OEM table ID for the iBFT.\r
12618416 26**/\r
6a690e23 27VOID\r
28IScsiInitIbfTableHeader (\r
54fbbbd7 29 OUT EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Header,\r
30 IN UINT8 *OemId,\r
31 IN UINT64 *OemTableId\r
6a690e23 32 )\r
6a690e23 33{\r
e48e37fc 34 ZeroMem (Header, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER));\r
6a690e23 35\r
36 Header->Signature = EFI_ACPI_3_0_ISCSI_BOOT_FIRMWARE_TABLE_SIGNATURE;\r
37 Header->Length = IBFT_HEAP_OFFSET;\r
38 Header->Revision = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_REVISION;\r
39 Header->Checksum = 0;\r
40\r
41 Header->OemId[0] = 'I';\r
42 Header->OemId[1] = 'N';\r
43 Header->OemId[2] = 'T';\r
44 Header->OemId[3] = 'E';\r
45 Header->OemId[4] = 'L';\r
54fbbbd7 46 \r
47 CopyMem (Header->OemId, OemId, sizeof (Header->OemId));\r
7d6cdbc8 48 CopyMem (&Header->OemTableId, OemTableId, sizeof (UINT64));\r
6a690e23 49}\r
50\r
12618416 51/**\r
52 Initialize the control section of the iSCSI Boot Firmware Table.\r
53 \r
d8c04564 54 @param[in] Table The ACPI table.\r
55 @param[in] HandleCount The number of the handles associated with iSCSI sessions, it's\r
12618416 56 equal to the number of iSCSI sessions.\r
12618416 57**/\r
6a690e23 58VOID\r
59IScsiInitControlSection (\r
60 IN EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table,\r
61 IN UINTN HandleCount\r
62 )\r
6a690e23 63{\r
64 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *Control;\r
65 UINTN NumOffset;\r
66\r
67 Control = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *) (Table + 1);\r
68\r
e48e37fc 69 ZeroMem (Control, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE));\r
6a690e23 70\r
71 Control->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE_ID;\r
72 Control->Header.Version = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE_VERSION;\r
c9325700 73 Control->Header.Length = (UINT16) sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE);\r
6a690e23 74\r
75 //\r
76 // Each session occupies two offsets, one for the NIC section,\r
77 // the other for the Target section.\r
78 //\r
79 NumOffset = 2 * HandleCount;\r
80 if (NumOffset > 4) {\r
81 //\r
82 // Need expand the control section if more than 2 NIC/Target sections\r
83 // exist.\r
84 //\r
69b0882d 85 Control->Header.Length = (UINT16) (Control->Header.Length + (NumOffset - 4) * sizeof (UINT16));\r
6a690e23 86 }\r
87}\r
88\r
12618416 89/**\r
90 Add one item into the heap.\r
91\r
d8c04564 92 @param[in, out] Heap On input, the current address of the heap; On output, the address of\r
93 the heap after the item is added.\r
94 @param[in] Data The data to add into the heap.\r
95 @param[in] Len Length of the Data in byte.\r
12618416 96**/\r
6a690e23 97VOID\r
98IScsiAddHeapItem (\r
99 IN OUT UINT8 **Heap,\r
100 IN VOID *Data,\r
101 IN UINTN Len\r
102 )\r
6a690e23 103{\r
104 //\r
105 // Add one byte for the NULL delimiter.\r
106 //\r
107 *Heap -= Len + 1;\r
108\r
e48e37fc 109 CopyMem (*Heap, Data, Len);\r
6a690e23 110 *(*Heap + Len) = 0;\r
111}\r
112\r
12618416 113/**\r
114 Fill the Initiator section of the iSCSI Boot Firmware Table.\r
115\r
d8c04564 116 @param[in] Table The ACPI table.\r
117 @param[in, out] Heap The heap.\r
118 @param[in] Handle The handle associated with the iSCSI session.\r
12618416 119**/\r
6a690e23 120VOID\r
121IScsiFillInitiatorSection (\r
122 IN EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table,\r
123 IN OUT UINT8 **Heap,\r
124 IN EFI_HANDLE Handle\r
125 )\r
6a690e23 126{\r
127 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *Control;\r
128 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE *Initiator;\r
129 ISCSI_DRIVER_DATA *DriverData;\r
130 ISCSI_SESSION *Session;\r
131 ISCSI_PRIVATE_PROTOCOL *IScsiIdentifier;\r
132 EFI_STATUS Status;\r
133\r
134 Control = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *) (Table + 1);\r
135\r
136 //\r
137 // Initiator section immediately follows the control section.\r
138 //\r
139 Initiator = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE *) ((UINT8 *) Control + IBFT_ROUNDUP (Control->Header.Length));\r
140\r
141 Control->InitiatorOffset = (UINT16) ((UINTN) Initiator - (UINTN) Table);\r
142\r
e48e37fc 143 ZeroMem (Initiator, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE));\r
6a690e23 144\r
145 Initiator->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE_ID;\r
146 Initiator->Header.Version = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE_VERSION;\r
c9325700 147 Initiator->Header.Length = (UINT16) sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE);\r
6a690e23 148 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
149\r
150 //\r
151 // Get the identifier from the handle.\r
152 //\r
c8ad2d7a 153 Status = gBS->HandleProtocol (Handle, &gEfiCallerIdGuid, (VOID **) &IScsiIdentifier);\r
6a690e23 154 if (EFI_ERROR (Status)) {\r
155 ASSERT (FALSE);\r
156 return ;\r
157 }\r
158\r
159 DriverData = ISCSI_DRIVER_DATA_FROM_IDENTIFIER (IScsiIdentifier);\r
160 Session = &DriverData->Session;\r
161\r
162 //\r
163 // Fill the iSCSI Initiator Name into the heap.\r
164 //\r
165 IScsiAddHeapItem (Heap, Session->InitiatorName, Session->InitiatorNameLength - 1);\r
166\r
167 Initiator->IScsiNameLength = (UINT16) (Session->InitiatorNameLength - 1);\r
168 Initiator->IScsiNameOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);\r
169}\r
170\r
12618416 171/**\r
172 Map the v4 IP address into v6 IP address.\r
173\r
d8c04564 174 @param[in] V4 The v4 IP address.\r
175 @param[out] V6 The v6 IP address.\r
12618416 176**/\r
6a690e23 177VOID\r
178IScsiMapV4ToV6Addr (\r
179 IN EFI_IPv4_ADDRESS *V4,\r
180 OUT EFI_IPv6_ADDRESS *V6\r
181 )\r
6a690e23 182{\r
183 UINTN Index;\r
184\r
e48e37fc 185 ZeroMem (V6, sizeof (EFI_IPv6_ADDRESS));\r
6a690e23 186\r
187 V6->Addr[10] = 0xff;\r
188 V6->Addr[11] = 0xff;\r
189\r
190 for (Index = 0; Index < 4; Index++) {\r
191 V6->Addr[12 + Index] = V4->Addr[Index];\r
192 }\r
193}\r
194\r
12618416 195/**\r
6a690e23 196 Get the NIC's PCI location and return it accroding to the composited\r
197 format defined in iSCSI Boot Firmware Table.\r
6a690e23 198\r
d8c04564 199 @param[in] Controller The handle of the controller.\r
6a690e23 200\r
d8c04564 201 @return UINT16 The composited representation of the NIC PCI location.\r
963dbb30 202 @retval 0 Other errors as indicated.\r
12618416 203**/\r
12618416 204UINT16\r
205IScsiGetNICPciLocation (\r
206 IN EFI_HANDLE Controller\r
207 )\r
6a690e23 208{\r
209 EFI_STATUS Status;\r
210 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
211 EFI_HANDLE PciIoHandle;\r
212 EFI_PCI_IO_PROTOCOL *PciIo;\r
213 UINTN Segment;\r
214 UINTN Bus;\r
215 UINTN Device;\r
216 UINTN Function;\r
217\r
218 Status = gBS->HandleProtocol (\r
219 Controller,\r
220 &gEfiDevicePathProtocolGuid,\r
69b0882d 221 (VOID **)&DevicePath\r
6a690e23 222 );\r
223 if (EFI_ERROR (Status)) {\r
224 return 0;\r
225 }\r
226\r
227 Status = gBS->LocateDevicePath (\r
228 &gEfiPciIoProtocolGuid,\r
229 &DevicePath,\r
230 &PciIoHandle\r
231 );\r
232 if (EFI_ERROR (Status)) {\r
233 return 0;\r
234 }\r
235\r
69b0882d 236 Status = gBS->HandleProtocol (PciIoHandle, &gEfiPciIoProtocolGuid, (VOID **)&PciIo);\r
6a690e23 237 if (EFI_ERROR (Status)) {\r
238 return 0;\r
239 }\r
240\r
241 Status = PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);\r
242 if (EFI_ERROR (Status)) {\r
243 return 0;\r
244 }\r
245\r
246 return (UINT16) ((Bus << 8) | (Device << 3) | Function);\r
247}\r
248\r
12618416 249/**\r
250 Fill the NIC and target sections in iSCSI Boot Firmware Table.\r
251\r
d8c04564 252 @param[in] Table The buffer of the ACPI table.\r
253 @param[in, out] Heap The heap buffer used to store the variable length parameters such as iSCSI name.\r
254 @param[in] HandleCount Count The number of handles having iSCSI private protocol installed.\r
255 @param[in] Handles The handle buffer.\r
12618416 256**/\r
6a690e23 257VOID\r
258IScsiFillNICAndTargetSections (\r
259 IN EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table,\r
260 IN OUT UINT8 **Heap,\r
261 IN UINTN HandleCount,\r
262 IN EFI_HANDLE *Handles\r
263 )\r
6a690e23 264{\r
265 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *Control;\r
266 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE *Nic;\r
267 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE *Target;\r
268 ISCSI_DRIVER_DATA *DriverData;\r
269 ISCSI_SESSION_CONFIG_DATA *SessionConfigData;\r
270 ISCSI_CHAP_AUTH_CONFIG_NVDATA *AuthConfig;\r
271 UINT16 *SectionOffset;\r
272 UINTN Index;\r
273 UINT16 Length;\r
779ae357 274 EFI_MAC_ADDRESS MacAddress;\r
275 UINTN HwAddressSize;\r
6a690e23 276 ISCSI_PRIVATE_PROTOCOL *IScsiIdentifier;\r
277 EFI_STATUS Status;\r
278\r
279 //\r
280 // Get the offset of the first Nic and Target section.\r
281 //\r
282 Control = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *) (Table + 1);\r
283 Nic = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE *) ((UINTN) Table +\r
284 Control->InitiatorOffset + IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE)));\r
285 Target = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE *) ((UINTN) Nic +\r
286 IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE)));\r
287\r
288 SectionOffset = &Control->NIC0Offset;\r
289\r
290 for (Index = 0; Index < HandleCount; Index++) {\r
c8ad2d7a 291 Status = gBS->HandleProtocol (Handles[Index], &gEfiCallerIdGuid, (VOID **)&IScsiIdentifier);\r
6a690e23 292 if (EFI_ERROR (Status)) {\r
293 ASSERT (FALSE);\r
294 return ;\r
295 }\r
296\r
297 DriverData = ISCSI_DRIVER_DATA_FROM_IDENTIFIER (IScsiIdentifier);\r
298 SessionConfigData = &DriverData->Session.ConfigData;\r
299 AuthConfig = &DriverData->Session.AuthData.AuthConfig;\r
300\r
301 //\r
302 // Fill the Nic section.\r
303 //\r
e48e37fc 304 ZeroMem (Nic, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE));\r
6a690e23 305\r
306 Nic->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_ID;\r
307 Nic->Header.Version = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_VERSION;\r
c9325700 308 Nic->Header.Length = (UINT16) sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE);\r
6a690e23 309 Nic->Header.Index = (UINT8) Index;\r
310 Nic->Header.Flags = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_FLAG_BLOCK_VALID |\r
311 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_FLAG_BOOT_SELECTED |\r
312 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_FLAG_GLOBAL;\r
313\r
314 //\r
315 // Get the subnet mask prefix length.\r
316 //\r
317 Nic->SubnetMaskPrefixLength = IScsiGetSubnetMaskPrefixLength (&SessionConfigData->NvData.SubnetMask);\r
318\r
319 if (SessionConfigData->NvData.InitiatorInfoFromDhcp) {\r
320 Nic->Origin = IpPrefixOriginDhcp;\r
321 } else {\r
322 Nic->Origin = IpPrefixOriginManual;\r
323 }\r
324 //\r
325 // Map the various v4 addresses into v6 addresses.\r
326 //\r
327 IScsiMapV4ToV6Addr (&SessionConfigData->NvData.LocalIp, &Nic->Ip);\r
328 IScsiMapV4ToV6Addr (&SessionConfigData->NvData.Gateway, &Nic->Gateway);\r
329 IScsiMapV4ToV6Addr (&SessionConfigData->PrimaryDns, &Nic->PrimaryDns);\r
330 IScsiMapV4ToV6Addr (&SessionConfigData->SecondaryDns, &Nic->SecondaryDns);\r
331 IScsiMapV4ToV6Addr (&SessionConfigData->DhcpServer, &Nic->DhcpServer);\r
332\r
779ae357 333 Nic->VLanTag = NetLibGetVlanId (DriverData->Controller);\r
334\r
335 Status = NetLibGetMacAddress (DriverData->Controller, &MacAddress, &HwAddressSize);\r
336 ASSERT (Status == EFI_SUCCESS);\r
337 CopyMem (Nic->Mac, MacAddress.Addr, sizeof (Nic->Mac));\r
6a690e23 338\r
339 //\r
340 // Get the PCI location of the Nic.\r
341 //\r
342 Nic->PciLocation = IScsiGetNICPciLocation (DriverData->Controller);\r
343\r
344 *SectionOffset = (UINT16) ((UINTN) Nic - (UINTN) Table);\r
345 SectionOffset++;\r
346\r
347 //\r
348 // Fill the Target section.\r
349 //\r
e48e37fc 350 ZeroMem (Target, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE));\r
6a690e23 351\r
352 Target->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_ID;\r
353 Target->Header.Version = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_VERSION;\r
c9325700 354 Target->Header.Length = (UINT16) sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE);\r
6a690e23 355 Target->Header.Index = (UINT8) Index;\r
356 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
357 Target->Port = SessionConfigData->NvData.TargetPort;\r
358 Target->CHAPType = AuthConfig->CHAPType;\r
359 Target->NicIndex = (UINT8) Index;\r
360\r
361 IScsiMapV4ToV6Addr (&SessionConfigData->NvData.TargetIp, &Target->Ip);\r
e48e37fc 362 CopyMem (Target->BootLun, SessionConfigData->NvData.BootLun, sizeof (Target->BootLun));\r
6a690e23 363\r
364 //\r
365 // Target iSCSI Name, CHAP name/secret, reverse CHAP name/secret.\r
366 //\r
367 Length = (UINT16) AsciiStrLen (SessionConfigData->NvData.TargetName);\r
368 IScsiAddHeapItem (Heap, SessionConfigData->NvData.TargetName, Length);\r
369\r
370 Target->IScsiNameLength = Length;\r
371 Target->IScsiNameOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);\r
372\r
373 if (Target->CHAPType != ISCSI_CHAP_NONE) {\r
374 //\r
375 // CHAP Name\r
376 //\r
377 Length = (UINT16) AsciiStrLen (AuthConfig->CHAPName);\r
378 IScsiAddHeapItem (Heap, AuthConfig->CHAPName, Length);\r
379 Target->CHAPNameLength = Length;\r
380 Target->CHAPNameOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);\r
381\r
382 //\r
383 // CHAP Secret\r
384 //\r
385 Length = (UINT16) AsciiStrLen (AuthConfig->CHAPSecret);\r
386 IScsiAddHeapItem (Heap, AuthConfig->CHAPSecret, Length);\r
387 Target->CHAPSecretLength = Length;\r
388 Target->CHAPSecretOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);\r
389\r
390 if (Target->CHAPType == ISCSI_CHAP_MUTUAL) {\r
391 //\r
392 // Reverse CHAP Name\r
393 //\r
394 Length = (UINT16) AsciiStrLen (AuthConfig->ReverseCHAPName);\r
395 IScsiAddHeapItem (Heap, AuthConfig->ReverseCHAPName, Length);\r
396 Target->ReverseCHAPNameLength = Length;\r
397 Target->ReverseCHAPNameOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);\r
398\r
399 //\r
400 // Reverse CHAP Secret\r
401 //\r
402 Length = (UINT16) AsciiStrLen (AuthConfig->ReverseCHAPSecret);\r
403 IScsiAddHeapItem (Heap, AuthConfig->ReverseCHAPSecret, Length);\r
404 Target->ReverseCHAPSecretLength = Length;\r
405 Target->ReverseCHAPSecretOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);\r
406 }\r
407 }\r
408\r
409 *SectionOffset = (UINT16) ((UINTN) Target - (UINTN) Table);\r
410 SectionOffset++;\r
411\r
412 //\r
413 // Advance to the next NIC/Target pair\r
414 //\r
415 Nic = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE *) ((UINTN) Target +\r
416 IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE)));\r
417 Target = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE *) ((UINTN) Nic +\r
418 IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE)));\r
419 }\r
420}\r
421\r
12618416 422/**\r
6a690e23 423 Publish and remove the iSCSI Boot Firmware Table according to the iSCSI\r
424 session status.\r
12618416 425**/\r
426VOID\r
427IScsiPublishIbft (\r
55a64ae0 428 VOID\r
12618416 429 )\r
6a690e23 430{\r
431 EFI_STATUS Status;\r
85b990a8 432 EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;\r
6a690e23 433 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table;\r
434 UINTN HandleCount;\r
435 EFI_HANDLE *HandleBuffer;\r
436 UINT8 *Heap;\r
35c290c5 437 UINT8 Checksum;\r
54fbbbd7 438 UINTN Index;\r
439 EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp;\r
440 EFI_ACPI_DESCRIPTION_HEADER *Rsdt;\r
6a690e23 441\r
85b990a8 442 Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTableProtocol);\r
6a690e23 443 if (EFI_ERROR (Status)) {\r
444 return ;\r
445 }\r
6a690e23 446\r
54fbbbd7 447\r
448 //\r
449 // Find ACPI table RSD_PTR from system table\r
450 //\r
451 for (Index = 0, Rsdp = NULL; Index < gST->NumberOfTableEntries; Index++) {\r
452 if (CompareGuid (&(gST->ConfigurationTable[Index].VendorGuid), &gEfiAcpi20TableGuid) ||\r
453 CompareGuid (&(gST->ConfigurationTable[Index].VendorGuid), &gEfiAcpi10TableGuid) ||\r
454 CompareGuid (&(gST->ConfigurationTable[Index].VendorGuid), &gEfiAcpiTableGuid)\r
455 ) {\r
456 //\r
457 // A match was found.\r
458 //\r
459 Rsdp = (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *) gST->ConfigurationTable[Index].VendorTable;\r
460 break;\r
461 }\r
462 }\r
463\r
464 if (Rsdp == NULL) {\r
465 return ;\r
466 } else {\r
467 Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Rsdp->RsdtAddress;\r
468 }\r
469\r
470\r
85b990a8 471 if (mIbftInstalled) {\r
472 Status = AcpiTableProtocol->UninstallAcpiTable (\r
473 AcpiTableProtocol,\r
474 mTableKey\r
475 );\r
476 if (EFI_ERROR (Status)) {\r
477 return ;\r
6a690e23 478 }\r
85b990a8 479 mIbftInstalled = FALSE;\r
6a690e23 480 }\r
85b990a8 481\r
6a690e23 482 //\r
483 // Get all iSCSI private protocols.\r
484 //\r
485 Status = gBS->LocateHandleBuffer (\r
486 ByProtocol,\r
c8ad2d7a 487 &gEfiCallerIdGuid,\r
6a690e23 488 NULL,\r
489 &HandleCount,\r
490 &HandleBuffer\r
491 );\r
492 if (EFI_ERROR (Status)) {\r
493 return ;\r
494 }\r
495 //\r
496 // Allocate 4k bytes to hold the ACPI table.\r
497 //\r
35c290c5 498 Table = AllocateZeroPool (IBFT_MAX_SIZE);\r
6a690e23 499 if (Table == NULL) {\r
500 return ;\r
501 }\r
502\r
69b0882d 503 Heap = (UINT8 *) Table + IBFT_HEAP_OFFSET;\r
6a690e23 504\r
505 //\r
506 // Fill in the various section of the iSCSI Boot Firmware Table.\r
507 //\r
54fbbbd7 508 IScsiInitIbfTableHeader (Table, Rsdt->OemId, &Rsdt->OemTableId);\r
6a690e23 509 IScsiInitControlSection (Table, HandleCount);\r
510 IScsiFillInitiatorSection (Table, &Heap, HandleBuffer[0]);\r
511 IScsiFillNICAndTargetSections (Table, &Heap, HandleCount, HandleBuffer);\r
512\r
35c290c5 513 Checksum = CalculateCheckSum8((UINT8 *)Table, Table->Length);\r
514 Table->Checksum = Checksum;\r
515\r
85b990a8 516 FreePool (HandleBuffer);\r
6a690e23 517\r
518 //\r
519 // Install or update the iBFT table.\r
520 //\r
85b990a8 521 Status = AcpiTableProtocol->InstallAcpiTable (\r
522 AcpiTableProtocol,\r
523 Table,\r
524 Table->Length,\r
525 &mTableKey\r
526 );\r
527 if (EFI_ERROR(Status)) {\r
528 return;\r
6a690e23 529 }\r
530\r
85b990a8 531 mIbftInstalled = TRUE;\r
532 FreePool (Table);\r
6a690e23 533}\r