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