]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Universal/Network/IScsiDxe/IScsiIbft.c
Libraries and utilities for instrumenting regions of code and measuring their perform...
[mirror_edk2.git] / MdeModulePkg / Universal / Network / IScsiDxe / IScsiIbft.c
... / ...
CommitLineData
1/** @file\r
2 Implementation for iSCSI Boot Firmware Table publication.\r
3\r
4Copyright (c) 2004 - 2010, Intel Corporation.<BR>\r
5All rights reserved. This program and the accompanying materials\r
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
12\r
13**/\r
14\r
15#include "IScsiImpl.h"\r
16\r
17BOOLEAN mIbftInstalled = FALSE;\r
18UINTN mTableKey;\r
19\r
20/**\r
21 Initialize the header of the iSCSI Boot Firmware Table.\r
22 \r
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
26**/\r
27VOID\r
28IScsiInitIbfTableHeader (\r
29 OUT EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Header,\r
30 IN UINT8 *OemId,\r
31 IN UINT64 *OemTableId\r
32 )\r
33{\r
34 ZeroMem (Header, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER));\r
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
46 \r
47 CopyMem (Header->OemId, OemId, sizeof (Header->OemId));\r
48 CopyMem (&Header->OemTableId, OemTableId, sizeof (UINT64));\r
49}\r
50\r
51/**\r
52 Initialize the control section of the iSCSI Boot Firmware Table.\r
53 \r
54 @param[in] Table The ACPI table.\r
55 @param[in] HandleCount The number of the handles associated with iSCSI sessions, it's\r
56 equal to the number of iSCSI sessions.\r
57**/\r
58VOID\r
59IScsiInitControlSection (\r
60 IN EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table,\r
61 IN UINTN HandleCount\r
62 )\r
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
69 ZeroMem (Control, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE));\r
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
73 Control->Header.Length = sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE);\r
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
85 Control->Header.Length = (UINT16) (Control->Header.Length + (NumOffset - 4) * sizeof (UINT16));\r
86 }\r
87}\r
88\r
89/**\r
90 Add one item into the heap.\r
91\r
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
96**/\r
97VOID\r
98IScsiAddHeapItem (\r
99 IN OUT UINT8 **Heap,\r
100 IN VOID *Data,\r
101 IN UINTN Len\r
102 )\r
103{\r
104 //\r
105 // Add one byte for the NULL delimiter.\r
106 //\r
107 *Heap -= Len + 1;\r
108\r
109 CopyMem (*Heap, Data, Len);\r
110 *(*Heap + Len) = 0;\r
111}\r
112\r
113/**\r
114 Fill the Initiator section of the iSCSI Boot Firmware Table.\r
115\r
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
119**/\r
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
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
143 ZeroMem (Initiator, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE));\r
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
147 Initiator->Header.Length = sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE);\r
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
153 Status = gBS->HandleProtocol (Handle, &gIScsiPrivateGuid, (VOID **) &IScsiIdentifier);\r
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
171/**\r
172 Map the v4 IP address into v6 IP address.\r
173\r
174 @param[in] V4 The v4 IP address.\r
175 @param[out] V6 The v6 IP address.\r
176**/\r
177VOID\r
178IScsiMapV4ToV6Addr (\r
179 IN EFI_IPv4_ADDRESS *V4,\r
180 OUT EFI_IPv6_ADDRESS *V6\r
181 )\r
182{\r
183 UINTN Index;\r
184\r
185 ZeroMem (V6, sizeof (EFI_IPv6_ADDRESS));\r
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
195/**\r
196 Get the NIC's PCI location and return it accroding to the composited\r
197 format defined in iSCSI Boot Firmware Table.\r
198\r
199 @param[in] Controller The handle of the controller.\r
200\r
201 @return UINT16 The composited representation of the NIC PCI location.\r
202 @retval 0 Other errors as indicated.\r
203**/\r
204UINT16\r
205IScsiGetNICPciLocation (\r
206 IN EFI_HANDLE Controller\r
207 )\r
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
221 (VOID **)&DevicePath\r
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
236 Status = gBS->HandleProtocol (PciIoHandle, &gEfiPciIoProtocolGuid, (VOID **)&PciIo);\r
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
249/**\r
250 Fill the NIC and target sections in iSCSI Boot Firmware Table.\r
251\r
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
256**/\r
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
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
274 EFI_MAC_ADDRESS MacAddress;\r
275 UINTN HwAddressSize;\r
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
291 Status = gBS->HandleProtocol (Handles[Index], &gIScsiPrivateGuid, (VOID **)&IScsiIdentifier);\r
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
304 ZeroMem (Nic, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE));\r
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
308 Nic->Header.Length = sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE);\r
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
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
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
350 ZeroMem (Target, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE));\r
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
354 Target->Header.Length = sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE);\r
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
362 CopyMem (Target->BootLun, SessionConfigData->NvData.BootLun, sizeof (Target->BootLun));\r
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
422/**\r
423 Publish and remove the iSCSI Boot Firmware Table according to the iSCSI\r
424 session status.\r
425**/\r
426VOID\r
427IScsiPublishIbft (\r
428 VOID\r
429 )\r
430{\r
431 EFI_STATUS Status;\r
432 EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;\r
433 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table;\r
434 UINTN HandleCount;\r
435 EFI_HANDLE *HandleBuffer;\r
436 UINT8 *Heap;\r
437 UINT8 Checksum;\r
438 UINTN Index;\r
439 EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp;\r
440 EFI_ACPI_DESCRIPTION_HEADER *Rsdt;\r
441\r
442 Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTableProtocol);\r
443 if (EFI_ERROR (Status)) {\r
444 return ;\r
445 }\r
446\r
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
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
478 }\r
479 mIbftInstalled = FALSE;\r
480 }\r
481\r
482 //\r
483 // Get all iSCSI private protocols.\r
484 //\r
485 Status = gBS->LocateHandleBuffer (\r
486 ByProtocol,\r
487 &gIScsiPrivateGuid,\r
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
498 Table = AllocateZeroPool (IBFT_MAX_SIZE);\r
499 if (Table == NULL) {\r
500 return ;\r
501 }\r
502\r
503 Heap = (UINT8 *) Table + IBFT_HEAP_OFFSET;\r
504\r
505 //\r
506 // Fill in the various section of the iSCSI Boot Firmware Table.\r
507 //\r
508 IScsiInitIbfTableHeader (Table, Rsdt->OemId, &Rsdt->OemTableId);\r
509 IScsiInitControlSection (Table, HandleCount);\r
510 IScsiFillInitiatorSection (Table, &Heap, HandleBuffer[0]);\r
511 IScsiFillNICAndTargetSections (Table, &Heap, HandleCount, HandleBuffer);\r
512\r
513 Checksum = CalculateCheckSum8((UINT8 *)Table, Table->Length);\r
514 Table->Checksum = Checksum;\r
515\r
516 FreePool (HandleBuffer);\r
517\r
518 //\r
519 // Install or update the iBFT table.\r
520 //\r
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
529 }\r
530\r
531 mIbftInstalled = TRUE;\r
532 FreePool (Table);\r
533}\r