]> git.proxmox.com Git - mirror_edk2.git/blob - NetworkPkg/IScsiDxe/IScsiIbft.c
NetworkPkg: Apply uncrustify changes
[mirror_edk2.git] / NetworkPkg / IScsiDxe / IScsiIbft.c
1 /** @file
2 Implementation for iSCSI Boot Firmware Table publication.
3
4 Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include "IScsiImpl.h"
10
11 BOOLEAN mIbftInstalled = FALSE;
12 UINTN mTableKey;
13
14 /**
15 Initialize the header of the iSCSI Boot Firmware Table.
16
17 @param[out] Header The header of the iSCSI Boot Firmware Table.
18 @param[in] OemId The OEM ID.
19 @param[in] OemTableId The OEM table ID for the iBFT.
20
21 **/
22 VOID
23 IScsiInitIbfTableHeader (
24 OUT EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Header,
25 IN UINT8 *OemId,
26 IN UINT64 *OemTableId
27 )
28 {
29 Header->Signature = EFI_ACPI_3_0_ISCSI_BOOT_FIRMWARE_TABLE_SIGNATURE;
30 Header->Length = IBFT_HEAP_OFFSET;
31 Header->Revision = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_REVISION;
32 Header->Checksum = 0;
33
34 CopyMem (Header->OemId, OemId, sizeof (Header->OemId));
35 CopyMem (&Header->OemTableId, OemTableId, sizeof (UINT64));
36 }
37
38 /**
39 Initialize the control section of the iSCSI Boot Firmware Table.
40
41 @param[in] Table The ACPI table.
42
43 **/
44 VOID
45 IScsiInitControlSection (
46 IN EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table
47 )
48 {
49 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *Control;
50 UINTN NumOffset;
51
52 Control = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *)(Table + 1);
53
54 Control->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE_ID;
55 Control->Header.Version = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE_VERSION;
56 Control->Header.Length = (UINT16)sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE);
57
58 //
59 // If in multipathing mode, enable the Boot Failover Flag.
60 // If in single path mode, disable it. Mix-model is not allowed.
61 //
62 // BUGBUG: if Boot Failover Flag is set to 1, the OS installer cannot
63 // find the iSCSI mapped disk. So still keep not set for single path mode.
64 //
65 if (mPrivate->EnableMpio) {
66 Control->Header.Flags = 0;
67 NumOffset = 2 * (mPrivate->MpioCount - mPrivate->Krb5MpioCount);
68 } else {
69 NumOffset = 2 * mPrivate->ValidSinglePathCount;
70 }
71
72 //
73 // Each attempt occupies two offsets: one for the NIC section;
74 // the other for the Target section.
75 //
76 if (NumOffset > 4) {
77 //
78 // Need expand the control section if more than 2 NIC/Target attempts
79 // exist.
80 //
81 Control->Header.Length = (UINT16)(Control->Header.Length + (NumOffset - 4) * sizeof (UINT16));
82 }
83 }
84
85 /**
86 Add one item into the heap.
87
88 @param[in, out] Heap On input, the current address of the heap. On output, the address of
89 the heap after the item is added.
90 @param[in] Data The data to add into the heap.
91 @param[in] Len Length of the Data in byte.
92
93 **/
94 VOID
95 IScsiAddHeapItem (
96 IN OUT UINT8 **Heap,
97 IN VOID *Data,
98 IN UINTN Len
99 )
100 {
101 //
102 // Add one byte for the NULL delimiter.
103 //
104 *Heap -= Len + 1;
105
106 CopyMem (*Heap, Data, Len);
107 *(*Heap + Len) = 0;
108 }
109
110 /**
111 Fill the Initiator section of the iSCSI Boot Firmware Table.
112
113 @param[in] Table The ACPI table.
114 @param[in, out] Heap The heap.
115
116 **/
117 VOID
118 IScsiFillInitiatorSection (
119 IN EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table,
120 IN OUT UINT8 **Heap
121 )
122 {
123 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *Control;
124 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE *Initiator;
125
126 Control = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *)(Table + 1);
127
128 //
129 // Initiator section immediately follows the control section.
130 //
131 Initiator = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE *)
132 ((UINT8 *)Control + IBFT_ROUNDUP (Control->Header.Length));
133
134 Control->InitiatorOffset = (UINT16)((UINTN)Initiator - (UINTN)Table);
135
136 Initiator->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE_ID;
137 Initiator->Header.Version = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE_VERSION;
138 Initiator->Header.Length = (UINT16)sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE);
139 Initiator->Header.Flags = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE_FLAG_BLOCK_VALID |
140 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE_FLAG_BOOT_SELECTED;
141
142 //
143 // Fill the iSCSI Initiator Name into the heap.
144 //
145 IScsiAddHeapItem (Heap, mPrivate->InitiatorName, mPrivate->InitiatorNameLength - 1);
146
147 Initiator->IScsiNameLength = (UINT16)(mPrivate->InitiatorNameLength - 1);
148 Initiator->IScsiNameOffset = (UINT16)((UINTN)*Heap - (UINTN)Table);
149 }
150
151 /**
152 Map the v4 IP address into v6 IP address.
153
154 @param[in] V4 The v4 IP address.
155 @param[out] V6 The v6 IP address.
156
157 **/
158 VOID
159 IScsiMapV4ToV6Addr (
160 IN EFI_IPv4_ADDRESS *V4,
161 OUT EFI_IPv6_ADDRESS *V6
162 )
163 {
164 UINTN Index;
165
166 ZeroMem (V6, sizeof (EFI_IPv6_ADDRESS));
167
168 V6->Addr[10] = 0xff;
169 V6->Addr[11] = 0xff;
170
171 for (Index = 0; Index < 4; Index++) {
172 V6->Addr[12 + Index] = V4->Addr[Index];
173 }
174 }
175
176 /**
177 Fill the NIC and target sections in iSCSI Boot Firmware Table.
178
179 @param[in] Table The buffer of the ACPI table.
180 @param[in, out] Heap The heap buffer used to store the variable length
181 parameters such as iSCSI name.
182
183 **/
184 VOID
185 IScsiFillNICAndTargetSections (
186 IN EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table,
187 IN OUT UINT8 **Heap
188 )
189 {
190 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *Control;
191 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE *Nic;
192 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE *Target;
193 ISCSI_SESSION_CONFIG_NVDATA *NvData;
194 ISCSI_CHAP_AUTH_CONFIG_NVDATA *AuthConfig;
195 UINT16 *SectionOffset;
196 UINTN Index;
197 UINT16 Length;
198 LIST_ENTRY *Entry;
199 ISCSI_ATTEMPT_CONFIG_NVDATA *Attempt;
200 ISCSI_NIC_INFO *NicInfo;
201 BOOLEAN Flag;
202
203 //
204 // Get the offset of the first Nic and Target section.
205 //
206 Control = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_CONTROL_STRUCTURE *)(Table + 1);
207 Nic = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE *)((UINTN)Table +
208 Control->InitiatorOffset + IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_INITIATOR_STRUCTURE)));
209 Target = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE *)((UINTN)Nic +
210 IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE)));
211
212 SectionOffset = &Control->NIC0Offset;
213
214 Index = 0;
215 Flag = TRUE;
216
217 NET_LIST_FOR_EACH (Entry, &mPrivate->AttemptConfigs) {
218 if (Index == 0) {
219 //
220 // First entry should be boot selected entry.
221 //
222 Attempt = IScsiConfigGetAttemptByConfigIndex (mPrivate->BootSelectedIndex);
223 if (Attempt == NULL) {
224 //
225 // First boot selected entry can not be found.
226 //
227 break;
228 }
229
230 ASSERT (Attempt->SessionConfigData.Enabled != ISCSI_DISABLED);
231 } else {
232 if ((Index == 1) && Flag) {
233 Entry = mPrivate->AttemptConfigs.ForwardLink;
234 Flag = FALSE;
235 }
236
237 Attempt = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);
238 if (Attempt->AttemptConfigIndex == mPrivate->BootSelectedIndex) {
239 continue;
240 }
241 }
242
243 if (Attempt->SessionConfigData.Enabled == ISCSI_DISABLED) {
244 continue;
245 }
246
247 //
248 // Krb5 attempt will not be recorded in iBFT.
249 //
250 if (Attempt->AuthenticationType == ISCSI_AUTH_TYPE_KRB) {
251 continue;
252 }
253
254 //
255 // If multipath mode is enabled, only the attempts in MPIO will be recorded in iBFT.
256 //
257 if (mPrivate->EnableMpio && (Attempt->SessionConfigData.Enabled != ISCSI_ENABLED_FOR_MPIO)) {
258 continue;
259 }
260
261 //
262 // Only the valid attempts will be recorded.
263 //
264 if (!Attempt->ValidiBFTPath) {
265 continue;
266 }
267
268 NvData = &Attempt->SessionConfigData;
269 AuthConfig = &Attempt->AuthConfigData.CHAP;
270
271 //
272 // Fill the Nic section.
273 //
274
275 Nic->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_ID;
276 Nic->Header.Version = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_VERSION;
277 Nic->Header.Length = (UINT16)sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE);
278 Nic->Header.Index = (UINT8)Index;
279 Nic->Header.Flags = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_FLAG_BLOCK_VALID |
280 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_FLAG_GLOBAL;
281
282 if (Index == 0) {
283 Nic->Header.Flags |= EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE_FLAG_BOOT_SELECTED;
284 }
285
286 if (NvData->InitiatorInfoFromDhcp) {
287 Nic->Origin = IpPrefixOriginDhcp;
288 } else {
289 Nic->Origin = IpPrefixOriginManual;
290 }
291
292 if ((NvData->IpMode == IP_MODE_IP4) || (NvData->IpMode == IP_MODE_AUTOCONFIG)) {
293 //
294 // Get the subnet mask prefix length.
295 //
296 Nic->SubnetMaskPrefixLength = IScsiGetSubnetMaskPrefixLength (&NvData->SubnetMask);
297
298 //
299 // Map the various v4 addresses into v6 addresses.
300 //
301 IScsiMapV4ToV6Addr (&NvData->LocalIp.v4, &Nic->Ip);
302 IScsiMapV4ToV6Addr (&NvData->Gateway.v4, &Nic->Gateway);
303 IScsiMapV4ToV6Addr (&Attempt->PrimaryDns.v4, &Nic->PrimaryDns);
304 IScsiMapV4ToV6Addr (&Attempt->SecondaryDns.v4, &Nic->SecondaryDns);
305 IScsiMapV4ToV6Addr (&Attempt->DhcpServer.v4, &Nic->DhcpServer);
306 } else if ((NvData->IpMode == IP_MODE_IP6) || (NvData->IpMode == IP_MODE_AUTOCONFIG)) {
307 Nic->SubnetMaskPrefixLength = NvData->PrefixLength;
308 CopyMem (&Nic->Ip, &NvData->LocalIp, sizeof (EFI_IPv6_ADDRESS));
309 CopyMem (&Nic->Gateway, &NvData->Gateway, sizeof (EFI_IPv6_ADDRESS));
310 CopyMem (&Nic->PrimaryDns, &Attempt->PrimaryDns, sizeof (EFI_IPv6_ADDRESS));
311 CopyMem (&Nic->SecondaryDns, &Attempt->SecondaryDns, sizeof (EFI_IPv6_ADDRESS));
312 CopyMem (&Nic->DhcpServer, &Attempt->DhcpServer, sizeof (EFI_IPv6_ADDRESS));
313 } else {
314 ASSERT (FALSE);
315 }
316
317 //
318 // Get Nic Info: VLAN tag, Mac address, PCI location.
319 //
320 NicInfo = IScsiGetNicInfoByIndex (Attempt->NicIndex);
321 ASSERT (NicInfo != NULL);
322
323 Nic->VLanTag = NicInfo->VlanId;
324 CopyMem (Nic->Mac, &NicInfo->PermanentAddress, sizeof (Nic->Mac));
325 Nic->PciLocation = (UINT16)((NicInfo->BusNumber << 8) |
326 (NicInfo->DeviceNumber << 3) | NicInfo->FunctionNumber);
327 *SectionOffset = (UINT16)((UINTN)Nic - (UINTN)Table);
328 SectionOffset++;
329
330 //
331 // Fill the Target section.
332 //
333
334 Target->Header.StructureId = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_ID;
335 Target->Header.Version = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_VERSION;
336 Target->Header.Length = (UINT16)sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE);
337 Target->Header.Index = (UINT8)Index;
338 Target->Header.Flags = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_FLAG_BLOCK_VALID;
339
340 if (Index == 0) {
341 Target->Header.Flags |= EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_FLAG_BOOT_SELECTED;
342 }
343
344 Target->Port = NvData->TargetPort;
345
346 if (Attempt->AuthenticationType == ISCSI_AUTH_TYPE_CHAP) {
347 if (AuthConfig->CHAPType == ISCSI_CHAP_UNI) {
348 Target->CHAPType = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_CHAP_TYPE_CHAP;
349 } else if (AuthConfig->CHAPType == ISCSI_CHAP_MUTUAL) {
350 Target->CHAPType = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_CHAP_TYPE_MUTUAL_CHAP;
351 }
352 } else if (Attempt->AuthenticationType == ISCSI_AUTH_TYPE_NONE) {
353 Target->CHAPType = EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_CHAP_TYPE_NO_CHAP;
354 }
355
356 Target->NicIndex = (UINT8)Index;
357
358 if ((NvData->IpMode == IP_MODE_IP4) || (NvData->IpMode == IP_MODE_AUTOCONFIG)) {
359 IScsiMapV4ToV6Addr (&NvData->TargetIp.v4, &Target->Ip);
360 } else if ((NvData->IpMode == IP_MODE_IP6) || (NvData->IpMode == IP_MODE_AUTOCONFIG)) {
361 CopyMem (&Target->Ip, &NvData->TargetIp, sizeof (EFI_IPv6_ADDRESS));
362 } else {
363 ASSERT (FALSE);
364 }
365
366 CopyMem (Target->BootLun, NvData->BootLun, sizeof (Target->BootLun));
367
368 //
369 // Target iSCSI Name, CHAP name/secret, reverse CHAP name/secret.
370 //
371 Length = (UINT16)AsciiStrLen (NvData->TargetName);
372 IScsiAddHeapItem (Heap, NvData->TargetName, Length);
373
374 Target->IScsiNameLength = Length;
375 Target->IScsiNameOffset = (UINT16)((UINTN)*Heap - (UINTN)Table);
376
377 if (Attempt->AuthenticationType == ISCSI_AUTH_TYPE_CHAP) {
378 //
379 // CHAP Name
380 //
381 Length = (UINT16)AsciiStrLen (AuthConfig->CHAPName);
382 IScsiAddHeapItem (Heap, AuthConfig->CHAPName, Length);
383 Target->CHAPNameLength = Length;
384 Target->CHAPNameOffset = (UINT16)((UINTN)*Heap - (UINTN)Table);
385
386 //
387 // CHAP Secret
388 //
389 Length = (UINT16)AsciiStrLen (AuthConfig->CHAPSecret);
390 IScsiAddHeapItem (Heap, AuthConfig->CHAPSecret, Length);
391 Target->CHAPSecretLength = Length;
392 Target->CHAPSecretOffset = (UINT16)((UINTN)*Heap - (UINTN)Table);
393
394 if (Target->CHAPType == EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE_CHAP_TYPE_MUTUAL_CHAP) {
395 //
396 // Reverse CHAP Name.
397 //
398 Length = (UINT16)AsciiStrLen (AuthConfig->ReverseCHAPName);
399 IScsiAddHeapItem (Heap, AuthConfig->ReverseCHAPName, Length);
400 Target->ReverseCHAPNameLength = Length;
401 Target->ReverseCHAPNameOffset = (UINT16)((UINTN)*Heap - (UINTN)Table);
402
403 //
404 // Reverse CHAP Secret.
405 //
406 Length = (UINT16)AsciiStrLen (AuthConfig->ReverseCHAPSecret);
407 IScsiAddHeapItem (Heap, AuthConfig->ReverseCHAPSecret, Length);
408 Target->ReverseCHAPSecretLength = Length;
409 Target->ReverseCHAPSecretOffset = (UINT16)((UINTN)*Heap - (UINTN)Table);
410 }
411 }
412
413 *SectionOffset = (UINT16)((UINTN)Target - (UINTN)Table);
414 SectionOffset++;
415
416 //
417 // Advance to the next NIC/Target pair.
418 //
419 Nic = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE *)((UINTN)Target +
420 IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE)));
421 Target = (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_TARGET_STRUCTURE *)((UINTN)Nic +
422 IBFT_ROUNDUP (sizeof (EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_NIC_STRUCTURE)));
423
424 Index++;
425 }
426 }
427
428 /**
429 Publish and remove the iSCSI Boot Firmware Table according to the iSCSI
430 session status.
431
432 **/
433 VOID
434 IScsiPublishIbft (
435 IN VOID
436 )
437 {
438 EFI_STATUS Status;
439 EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;
440 EFI_ACPI_ISCSI_BOOT_FIRMWARE_TABLE_HEADER *Table;
441 EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp;
442 EFI_ACPI_DESCRIPTION_HEADER *Rsdt;
443 EFI_ACPI_DESCRIPTION_HEADER *Xsdt;
444 UINT8 *Heap;
445 UINT8 Checksum;
446
447 Rsdt = NULL;
448 Xsdt = NULL;
449
450 Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTableProtocol);
451 if (EFI_ERROR (Status)) {
452 return;
453 }
454
455 //
456 // Find ACPI table RSD_PTR from the system table.
457 //
458 Status = EfiGetSystemConfigurationTable (&gEfiAcpiTableGuid, (VOID **)&Rsdp);
459 if (EFI_ERROR (Status)) {
460 Status = EfiGetSystemConfigurationTable (&gEfiAcpi10TableGuid, (VOID **)&Rsdp);
461 }
462
463 if (EFI_ERROR (Status) || (Rsdp == NULL)) {
464 return;
465 } else if ((Rsdp->Revision >= EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION) && (Rsdp->XsdtAddress != 0)) {
466 Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Rsdp->XsdtAddress;
467 } else if (Rsdp->RsdtAddress != 0) {
468 Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Rsdp->RsdtAddress;
469 }
470
471 if ((Xsdt == NULL) && (Rsdt == NULL)) {
472 return;
473 }
474
475 if (mIbftInstalled) {
476 Status = AcpiTableProtocol->UninstallAcpiTable (
477 AcpiTableProtocol,
478 mTableKey
479 );
480 if (EFI_ERROR (Status)) {
481 return;
482 }
483
484 mIbftInstalled = FALSE;
485 }
486
487 //
488 // If there is no valid attempt configuration, just return.
489 //
490 if ((!mPrivate->EnableMpio && (mPrivate->ValidSinglePathCount == 0)) ||
491 (mPrivate->EnableMpio && (mPrivate->MpioCount <= mPrivate->Krb5MpioCount)))
492 {
493 return;
494 }
495
496 //
497 // Allocate 4k bytes to hold the ACPI table.
498 //
499 Table = AllocateZeroPool (IBFT_MAX_SIZE);
500 if (Table == NULL) {
501 return;
502 }
503
504 Heap = (UINT8 *)Table + IBFT_HEAP_OFFSET;
505
506 //
507 // Fill in the various section of the iSCSI Boot Firmware Table.
508 //
509 if (Rsdp->Revision >= EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION) {
510 IScsiInitIbfTableHeader (Table, Xsdt->OemId, &Xsdt->OemTableId);
511 } else {
512 IScsiInitIbfTableHeader (Table, Rsdt->OemId, &Rsdt->OemTableId);
513 }
514
515 IScsiInitControlSection (Table);
516 IScsiFillInitiatorSection (Table, &Heap);
517 IScsiFillNICAndTargetSections (Table, &Heap);
518
519 Checksum = CalculateCheckSum8 ((UINT8 *)Table, Table->Length);
520 Table->Checksum = Checksum;
521
522 //
523 // Install or update the iBFT table.
524 //
525 Status = AcpiTableProtocol->InstallAcpiTable (
526 AcpiTableProtocol,
527 Table,
528 Table->Length,
529 &mTableKey
530 );
531 if (EFI_ERROR (Status)) {
532 return;
533 }
534
535 mIbftInstalled = TRUE;
536 FreePool (Table);
537 }