]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/iScsi/IScsiIbft.c
UEFI HII: Merge UEFI HII support changes from branch.
[mirror_edk2.git] / MdeModulePkg / Universal / iScsi / IScsiIbft.c
CommitLineData
6a690e23 1/*++\r
2\r
3Copyright (c) 2007 Intel Corporation. All rights reserved\r
4This software and associated documentation (if any) is furnished\r
5under a license and may only be used or copied in accordance\r
6with the terms of the license. Except as permitted by such\r
7license, no part of this software or documentation may be\r
8reproduced, stored in a retrieval system, or transmitted in any\r
9form or by any means without the express written consent of\r
10Intel Corporation.\r
11\r
12Module Name:\r
13\r
14 IScsiIbft.c\r
15\r
16Abstract:\r
17\r
18 Implementation for iSCSI Boot Firmware Table publication.\r
19\r
20--*/\r
21\r
22#include "IScsiImpl.h"\r
23\r
24STATIC\r
25VOID\r
26IScsiInitIbfTableHeader (\r
27 IN EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Header\r
28 )\r
29/*++\r
30\r
31Routine Description:\r
32\r
33 Initialize the header of the iSCSI Boot Firmware Table.\r
34 \r
35Arguments:\r
36\r
37 Header - The header of the iSCSI Boot Firmware Table.\r
38\r
39Returns:\r
40\r
41 None.\r
42\r
43--*/\r
44{\r
45 NetZeroMem (Header, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER));\r
46\r
47 Header->Signature = EFI_ACPI_3_0_ISCSI_BOOT_FIRMWARE_TABLE_SIGNATURE;\r
48 Header->Length = IBFT_HEAP_OFFSET;\r
49 Header->Revision = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_REVISION;\r
50 Header->Checksum = 0;\r
51\r
52 Header->OemId[0] = 'I';\r
53 Header->OemId[1] = 'N';\r
54 Header->OemId[2] = 'T';\r
55 Header->OemId[3] = 'E';\r
56 Header->OemId[4] = 'L';\r
57}\r
58\r
59STATIC\r
60VOID\r
61IScsiInitControlSection (\r
62 IN EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table,\r
63 IN UINTN HandleCount\r
64 )\r
65/*++\r
66\r
67Routine Description:\r
68\r
69 Initialize the control section of the iSCSI Boot Firmware Table.\r
70 \r
71Arguments:\r
72\r
73 Table - The ACPI table.\r
74 HandleCount - The number of the handles associated with iSCSI sessions, it's\r
75 equal to the number of iSCSI sessions.\r
76\r
77Returns:\r
78\r
79 None.\r
80\r
81--*/\r
82{\r
83 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *Control;\r
84 UINTN NumOffset;\r
85\r
86 Control = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *) (Table + 1);\r
87\r
88 NetZeroMem (Control, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE));\r
89\r
90 Control->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE_ID;\r
91 Control->Header.Version = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE_VERSION;\r
92 Control->Header.Length = sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE);\r
93\r
94 //\r
95 // Each session occupies two offsets, one for the NIC section,\r
96 // the other for the Target section.\r
97 //\r
98 NumOffset = 2 * HandleCount;\r
99 if (NumOffset > 4) {\r
100 //\r
101 // Need expand the control section if more than 2 NIC/Target sections\r
102 // exist.\r
103 //\r
93e3992d 104 Control->Header.Length += (UINT16) (NumOffset - 4) * sizeof (UINT16);\r
6a690e23 105 }\r
106}\r
107\r
108STATIC\r
109VOID\r
110IScsiAddHeapItem (\r
111 IN OUT UINT8 **Heap,\r
112 IN VOID *Data,\r
113 IN UINTN Len\r
114 )\r
115/*++\r
116\r
117Routine Description:\r
118\r
119 Add one item into the heap.\r
120 \r
121Arguments:\r
122\r
123 Heap - On input, the current address of the heap; On output, the address of\r
124 the heap after the item is added.\r
125 Data - The data to add into the heap.\r
126 Len - Length of the Data in byte.\r
127\r
128Returns:\r
129\r
130 None.\r
131\r
132--*/\r
133{\r
134 //\r
135 // Add one byte for the NULL delimiter.\r
136 //\r
137 *Heap -= Len + 1;\r
138\r
139 NetCopyMem (*Heap, Data, Len);\r
140 *(*Heap + Len) = 0;\r
141}\r
142\r
143STATIC\r
144VOID\r
145IScsiFillInitiatorSection (\r
146 IN EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table,\r
147 IN OUT UINT8 **Heap,\r
148 IN EFI_HANDLE Handle\r
149 )\r
150/*++\r
151\r
152Routine Description:\r
153\r
154 Fill the Initiator section of the iSCSI Boot Firmware Table.\r
155 \r
156Arguments:\r
157\r
158 Table - The ACPI table.\r
159 Heap - The heap.\r
160 Handle - The handle associated with the iSCSI session.\r
161\r
162Returns:\r
163\r
164 None.\r
165\r
166--*/\r
167{\r
168 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *Control;\r
169 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE *Initiator;\r
170 ISCSI_DRIVER_DATA *DriverData;\r
171 ISCSI_SESSION *Session;\r
172 ISCSI_PRIVATE_PROTOCOL *IScsiIdentifier;\r
173 EFI_STATUS Status;\r
174\r
175 Control = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *) (Table + 1);\r
176\r
177 //\r
178 // Initiator section immediately follows the control section.\r
179 //\r
180 Initiator = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE *) ((UINT8 *) Control + IBFT_ROUNDUP (Control->Header.Length));\r
181\r
182 Control->InitiatorOffset = (UINT16) ((UINTN) Initiator - (UINTN) Table);\r
183\r
184 NetZeroMem (Initiator, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE));\r
185\r
186 Initiator->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE_ID;\r
187 Initiator->Header.Version = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE_VERSION;\r
188 Initiator->Header.Length = sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE);\r
189 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
190\r
191 //\r
192 // Get the identifier from the handle.\r
193 //\r
93e3992d 194 Status = gBS->HandleProtocol (Handle, &mIScsiPrivateGuid, &IScsiIdentifier);\r
6a690e23 195 if (EFI_ERROR (Status)) {\r
196 ASSERT (FALSE);\r
197 return ;\r
198 }\r
199\r
200 DriverData = ISCSI_DRIVER_DATA_FROM_IDENTIFIER (IScsiIdentifier);\r
201 Session = &DriverData->Session;\r
202\r
203 //\r
204 // Fill the iSCSI Initiator Name into the heap.\r
205 //\r
206 IScsiAddHeapItem (Heap, Session->InitiatorName, Session->InitiatorNameLength - 1);\r
207\r
208 Initiator->IScsiNameLength = (UINT16) (Session->InitiatorNameLength - 1);\r
209 Initiator->IScsiNameOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);\r
210}\r
211\r
212STATIC\r
213VOID\r
214IScsiMapV4ToV6Addr (\r
215 IN EFI_IPv4_ADDRESS *V4,\r
216 OUT EFI_IPv6_ADDRESS *V6\r
217 )\r
218/*++\r
219\r
220Routine Description:\r
221\r
222 Map the v4 IP address into v6 IP address.\r
223 \r
224Arguments:\r
225\r
226 V4 - The v4 IP address.\r
227 V6 - The v6 IP address.\r
228\r
229Returns:\r
230\r
231 None.\r
232\r
233--*/\r
234{\r
235 UINTN Index;\r
236\r
237 NetZeroMem (V6, sizeof (EFI_IPv6_ADDRESS));\r
238\r
239 V6->Addr[10] = 0xff;\r
240 V6->Addr[11] = 0xff;\r
241\r
242 for (Index = 0; Index < 4; Index++) {\r
243 V6->Addr[12 + Index] = V4->Addr[Index];\r
244 }\r
245}\r
246\r
247STATIC\r
248UINT16\r
249IScsiGetNICPciLocation (\r
250 IN EFI_HANDLE Controller\r
251 )\r
252/*++\r
253\r
254Routine Description:\r
255\r
256 Get the NIC's PCI location and return it accroding to the composited\r
257 format defined in iSCSI Boot Firmware Table.\r
258 \r
259Arguments:\r
260\r
261 Controller - The handle of the controller.\r
262\r
263Returns:\r
264\r
265 UINT16 - The composited representation of the NIC PCI location.\r
266\r
267--*/\r
268{\r
269 EFI_STATUS Status;\r
270 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
271 EFI_HANDLE PciIoHandle;\r
272 EFI_PCI_IO_PROTOCOL *PciIo;\r
273 UINTN Segment;\r
274 UINTN Bus;\r
275 UINTN Device;\r
276 UINTN Function;\r
277\r
278 Status = gBS->HandleProtocol (\r
279 Controller,\r
280 &gEfiDevicePathProtocolGuid,\r
93e3992d 281 &DevicePath\r
6a690e23 282 );\r
283 if (EFI_ERROR (Status)) {\r
284 return 0;\r
285 }\r
286\r
287 Status = gBS->LocateDevicePath (\r
288 &gEfiPciIoProtocolGuid,\r
289 &DevicePath,\r
290 &PciIoHandle\r
291 );\r
292 if (EFI_ERROR (Status)) {\r
293 return 0;\r
294 }\r
295\r
93e3992d 296 Status = gBS->HandleProtocol (PciIoHandle, &gEfiPciIoProtocolGuid, &PciIo);\r
6a690e23 297 if (EFI_ERROR (Status)) {\r
298 return 0;\r
299 }\r
300\r
301 Status = PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);\r
302 if (EFI_ERROR (Status)) {\r
303 return 0;\r
304 }\r
305\r
306 return (UINT16) ((Bus << 8) | (Device << 3) | Function);\r
307}\r
308\r
309STATIC\r
310EFI_MAC_ADDRESS *\r
311IScsiGetMacAddress (\r
312 IN EFI_HANDLE Controller\r
313 )\r
314/*++\r
315\r
316Routine Description:\r
317\r
318 Get the MAC address of the controller.\r
319 \r
320Arguments:\r
321\r
322 Controller - The handle of the controller.\r
323\r
324Returns:\r
325\r
326 EFI_MAC_ADDRESS * - The mac address.\r
327\r
328--*/\r
329{\r
330 EFI_STATUS Status;\r
331 EFI_SIMPLE_NETWORK_PROTOCOL *Snp;\r
332\r
333 Status = gBS->HandleProtocol (\r
334 Controller,\r
335 &gEfiSimpleNetworkProtocolGuid,\r
93e3992d 336 &Snp\r
6a690e23 337 );\r
338 ASSERT_EFI_ERROR (Status);\r
339\r
340 return &Snp->Mode->PermanentAddress;\r
341}\r
342\r
343STATIC\r
344VOID\r
345IScsiFillNICAndTargetSections (\r
346 IN EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table,\r
347 IN OUT UINT8 **Heap,\r
348 IN UINTN HandleCount,\r
349 IN EFI_HANDLE *Handles\r
350 )\r
351/*++\r
352\r
353Routine Description:\r
354\r
355 Fill the NIC and target sections in iSCSI Boot Firmware Table.\r
356\r
357Arguments:\r
358\r
359 Table - The buffer of the ACPI table.\r
360 Heap - The heap buffer used to store the variable length parameters such as iSCSI name.\r
361 HandleCount - The number of handles having iSCSI private protocol installed.\r
362 Handles - The handle buffer.\r
363\r
364Returns:\r
365\r
366 None.\r
367\r
368--*/\r
369{\r
370 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *Control;\r
371 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE *Nic;\r
372 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE *Target;\r
373 ISCSI_DRIVER_DATA *DriverData;\r
374 ISCSI_SESSION_CONFIG_DATA *SessionConfigData;\r
375 ISCSI_CHAP_AUTH_CONFIG_NVDATA *AuthConfig;\r
376 UINT16 *SectionOffset;\r
377 UINTN Index;\r
378 UINT16 Length;\r
379 EFI_MAC_ADDRESS *Mac;\r
380 ISCSI_PRIVATE_PROTOCOL *IScsiIdentifier;\r
381 EFI_STATUS Status;\r
382\r
383 //\r
384 // Get the offset of the first Nic and Target section.\r
385 //\r
386 Control = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *) (Table + 1);\r
387 Nic = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE *) ((UINTN) Table +\r
388 Control->InitiatorOffset + IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE)));\r
389 Target = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE *) ((UINTN) Nic +\r
390 IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE)));\r
391\r
392 SectionOffset = &Control->NIC0Offset;\r
393\r
394 for (Index = 0; Index < HandleCount; Index++) {\r
93e3992d 395 Status = gBS->HandleProtocol (Handles[Index], &mIScsiPrivateGuid, &IScsiIdentifier);\r
6a690e23 396 if (EFI_ERROR (Status)) {\r
397 ASSERT (FALSE);\r
398 return ;\r
399 }\r
400\r
401 DriverData = ISCSI_DRIVER_DATA_FROM_IDENTIFIER (IScsiIdentifier);\r
402 SessionConfigData = &DriverData->Session.ConfigData;\r
403 AuthConfig = &DriverData->Session.AuthData.AuthConfig;\r
404\r
405 //\r
406 // Fill the Nic section.\r
407 //\r
408 NetZeroMem (Nic, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE));\r
409\r
410 Nic->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_ID;\r
411 Nic->Header.Version = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_VERSION;\r
412 Nic->Header.Length = sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE);\r
413 Nic->Header.Index = (UINT8) Index;\r
414 Nic->Header.Flags = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_FLAG_BLOCK_VALID |\r
415 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_FLAG_BOOT_SELECTED |\r
416 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_FLAG_GLOBAL;\r
417\r
418 //\r
419 // Get the subnet mask prefix length.\r
420 //\r
421 Nic->SubnetMaskPrefixLength = IScsiGetSubnetMaskPrefixLength (&SessionConfigData->NvData.SubnetMask);\r
422\r
423 if (SessionConfigData->NvData.InitiatorInfoFromDhcp) {\r
424 Nic->Origin = IpPrefixOriginDhcp;\r
425 } else {\r
426 Nic->Origin = IpPrefixOriginManual;\r
427 }\r
428 //\r
429 // Map the various v4 addresses into v6 addresses.\r
430 //\r
431 IScsiMapV4ToV6Addr (&SessionConfigData->NvData.LocalIp, &Nic->Ip);\r
432 IScsiMapV4ToV6Addr (&SessionConfigData->NvData.Gateway, &Nic->Gateway);\r
433 IScsiMapV4ToV6Addr (&SessionConfigData->PrimaryDns, &Nic->PrimaryDns);\r
434 IScsiMapV4ToV6Addr (&SessionConfigData->SecondaryDns, &Nic->SecondaryDns);\r
435 IScsiMapV4ToV6Addr (&SessionConfigData->DhcpServer, &Nic->DhcpServer);\r
436\r
437 Mac = IScsiGetMacAddress (DriverData->Controller);\r
438 NetCopyMem (Nic->Mac, Mac, sizeof (Nic->Mac));\r
439\r
440 //\r
441 // Get the PCI location of the Nic.\r
442 //\r
443 Nic->PciLocation = IScsiGetNICPciLocation (DriverData->Controller);\r
444\r
445 *SectionOffset = (UINT16) ((UINTN) Nic - (UINTN) Table);\r
446 SectionOffset++;\r
447\r
448 //\r
449 // Fill the Target section.\r
450 //\r
451 NetZeroMem (Target, sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE));\r
452\r
453 Target->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_ID;\r
454 Target->Header.Version = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_VERSION;\r
455 Target->Header.Length = sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE);\r
456 Target->Header.Index = (UINT8) Index;\r
457 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
458 Target->Port = SessionConfigData->NvData.TargetPort;\r
459 Target->CHAPType = AuthConfig->CHAPType;\r
460 Target->NicIndex = (UINT8) Index;\r
461\r
462 IScsiMapV4ToV6Addr (&SessionConfigData->NvData.TargetIp, &Target->Ip);\r
463 NetCopyMem (Target->BootLun, SessionConfigData->NvData.BootLun, sizeof (Target->BootLun));\r
464\r
465 //\r
466 // Target iSCSI Name, CHAP name/secret, reverse CHAP name/secret.\r
467 //\r
468 Length = (UINT16) AsciiStrLen (SessionConfigData->NvData.TargetName);\r
469 IScsiAddHeapItem (Heap, SessionConfigData->NvData.TargetName, Length);\r
470\r
471 Target->IScsiNameLength = Length;\r
472 Target->IScsiNameOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);\r
473\r
474 if (Target->CHAPType != ISCSI_CHAP_NONE) {\r
475 //\r
476 // CHAP Name\r
477 //\r
478 Length = (UINT16) AsciiStrLen (AuthConfig->CHAPName);\r
479 IScsiAddHeapItem (Heap, AuthConfig->CHAPName, Length);\r
480 Target->CHAPNameLength = Length;\r
481 Target->CHAPNameOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);\r
482\r
483 //\r
484 // CHAP Secret\r
485 //\r
486 Length = (UINT16) AsciiStrLen (AuthConfig->CHAPSecret);\r
487 IScsiAddHeapItem (Heap, AuthConfig->CHAPSecret, Length);\r
488 Target->CHAPSecretLength = Length;\r
489 Target->CHAPSecretOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);\r
490\r
491 if (Target->CHAPType == ISCSI_CHAP_MUTUAL) {\r
492 //\r
493 // Reverse CHAP Name\r
494 //\r
495 Length = (UINT16) AsciiStrLen (AuthConfig->ReverseCHAPName);\r
496 IScsiAddHeapItem (Heap, AuthConfig->ReverseCHAPName, Length);\r
497 Target->ReverseCHAPNameLength = Length;\r
498 Target->ReverseCHAPNameOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);\r
499\r
500 //\r
501 // Reverse CHAP Secret\r
502 //\r
503 Length = (UINT16) AsciiStrLen (AuthConfig->ReverseCHAPSecret);\r
504 IScsiAddHeapItem (Heap, AuthConfig->ReverseCHAPSecret, Length);\r
505 Target->ReverseCHAPSecretLength = Length;\r
506 Target->ReverseCHAPSecretOffset = (UINT16) ((UINTN) *Heap - (UINTN) Table);\r
507 }\r
508 }\r
509\r
510 *SectionOffset = (UINT16) ((UINTN) Target - (UINTN) Table);\r
511 SectionOffset++;\r
512\r
513 //\r
514 // Advance to the next NIC/Target pair\r
515 //\r
516 Nic = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE *) ((UINTN) Target +\r
517 IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE)));\r
518 Target = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE *) ((UINTN) Nic +\r
519 IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE)));\r
520 }\r
521}\r
522\r
523VOID\r
524IScsiPublishIbft (\r
525 IN VOID\r
526 )\r
527/*++\r
528\r
529Routine Description:\r
530\r
531 Publish and remove the iSCSI Boot Firmware Table according to the iSCSI\r
532 session status.\r
533\r
534Arguments:\r
535\r
536 None.\r
537\r
538Returns:\r
539\r
540 None.\r
541\r
542--*/\r
543{\r
544 EFI_STATUS Status;\r
545 UINTN TableHandle;\r
546 EFI_ACPI_SUPPORT_PROTOCOL *AcpiSupport;\r
547 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table;\r
548 UINTN HandleCount;\r
549 EFI_HANDLE *HandleBuffer;\r
550 UINT8 *Heap;\r
551 INTN Index;\r
552 EFI_ACPI_TABLE_VERSION Version;\r
553 UINT32 Signature;\r
554\r
93e3992d 555 Status = gBS->LocateProtocol (&gEfiAcpiSupportProtocolGuid, NULL, &AcpiSupport);\r
6a690e23 556 if (EFI_ERROR (Status)) {\r
557 return ;\r
558 }\r
559 //\r
560 // Try to remove the old iSCSI Boot Firmware Table.\r
561 //\r
562 for (Index = 0;; Index++) {\r
563 Status = AcpiSupport->GetAcpiTable (\r
564 AcpiSupport,\r
565 Index,\r
93e3992d 566 &Table,\r
6a690e23 567 &Version,\r
568 &TableHandle\r
569 );\r
570 if (EFI_ERROR (Status)) {\r
571 break;\r
572 }\r
573\r
574 Signature = Table->Signature;\r
575 NetFreePool (Table);\r
576\r
577 if (Signature == EFI_ACPI_3_0_ISCSI_BOOT_FIRMWARE_TABLE_SIGNATURE) {\r
578 //\r
579 // Remove the table.\r
580 //\r
581 Status = AcpiSupport->SetAcpiTable (\r
582 AcpiSupport,\r
583 NULL,\r
584 FALSE,\r
585 Version,\r
586 &TableHandle\r
587 );\r
588 if (EFI_ERROR (Status)) {\r
589 return ;\r
590 }\r
591\r
592 break;\r
593 }\r
594 }\r
595 //\r
596 // Get all iSCSI private protocols.\r
597 //\r
598 Status = gBS->LocateHandleBuffer (\r
599 ByProtocol,\r
600 &mIScsiPrivateGuid,\r
601 NULL,\r
602 &HandleCount,\r
603 &HandleBuffer\r
604 );\r
605 if (EFI_ERROR (Status)) {\r
606 return ;\r
607 }\r
608 //\r
609 // Allocate 4k bytes to hold the ACPI table.\r
610 //\r
611 Table = NetAllocatePool (IBFT_MAX_SIZE);\r
612 if (Table == NULL) {\r
613 return ;\r
614 }\r
615\r
93e3992d 616 Heap = (CHAR8 *) Table + IBFT_HEAP_OFFSET;\r
6a690e23 617\r
618 //\r
619 // Fill in the various section of the iSCSI Boot Firmware Table.\r
620 //\r
621 IScsiInitIbfTableHeader (Table);\r
622 IScsiInitControlSection (Table, HandleCount);\r
623 IScsiFillInitiatorSection (Table, &Heap, HandleBuffer[0]);\r
624 IScsiFillNICAndTargetSections (Table, &Heap, HandleCount, HandleBuffer);\r
625\r
626 NetFreePool (HandleBuffer);\r
627\r
628 TableHandle = 0;\r
629\r
630 //\r
631 // Install or update the iBFT table.\r
632 //\r
633 Status = AcpiSupport->SetAcpiTable (\r
634 AcpiSupport,\r
635 Table,\r
636 TRUE,\r
637 EFI_ACPI_TABLE_VERSION_3_0,\r
638 &TableHandle\r
639 );\r
640 if (!EFI_ERROR (Status)) {\r
641 AcpiSupport->PublishTables (AcpiSupport, EFI_ACPI_TABLE_VERSION_3_0);\r
642 }\r
643\r
644 NetFreePool (Table);\r
645}\r