1 | /** @file
|
---|
2 | Implementation for iSCSI Boot Firmware Table publication.
|
---|
3 |
|
---|
4 | Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
|
---|
5 | This program and the accompanying materials
|
---|
6 | are licensed and made available under the terms and conditions of the BSD License
|
---|
7 | which accompanies this distribution. The full text of the license may be found at
|
---|
8 | http://opensource.org/licenses/bsd-license.php
|
---|
9 |
|
---|
10 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
---|
11 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
---|
12 |
|
---|
13 | **/
|
---|
14 |
|
---|
15 | #include "IScsiImpl.h"
|
---|
16 |
|
---|
17 | BOOLEAN mIbftInstalled = FALSE;
|
---|
18 | UINTN 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 | **/
|
---|
28 | VOID
|
---|
29 | IScsiInitIbfTableHeader (
|
---|
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 | **/
|
---|
51 | VOID
|
---|
52 | IScsiInitControlSection (
|
---|
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 | **/
|
---|
102 | VOID
|
---|
103 | IScsiAddHeapItem (
|
---|
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 | **/
|
---|
126 | VOID
|
---|
127 | IScsiFillInitiatorSection (
|
---|
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 | **/
|
---|
168 | VOID
|
---|
169 | IScsiMapV4ToV6Addr (
|
---|
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 | **/
|
---|
195 | VOID
|
---|
196 | IScsiFillNICAndTargetSections (
|
---|
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 | **/
|
---|
449 | VOID
|
---|
450 | IScsiPublishIbft (
|
---|
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 | }
|
---|