VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/NetworkPkg/IScsiDxe/IScsiIbft.c@ 69222

Last change on this file since 69222 was 58466, checked in by vboxsync, 9 years ago

EFI/Firmware: Merged in the svn:eol-style, svn:mime-type and trailing whitespace cleanup that was done after the initial UDK2014.SP1 import: svn merge /vendor/edk2/UDK2014.SP1 /vendor/edk2/current .

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette