Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2726 | vana | 1 | /*++ |
2 | |||
3 | Copyright (c) 1998 Intel Corporation |
||
4 | |||
5 | Module Name: |
||
6 | |||
7 | dpath.c |
||
8 | |||
9 | Abstract: |
||
10 | MBR & Device Path functions |
||
11 | |||
12 | |||
13 | |||
14 | Revision History |
||
15 | |||
16 | --*/ |
||
17 | |||
18 | #include "lib.h" |
||
19 | |||
20 | #define ALIGN_SIZE(a) ((a % MIN_ALIGNMENT_SIZE) ? MIN_ALIGNMENT_SIZE - (a % MIN_ALIGNMENT_SIZE) : 0) |
||
21 | |||
22 | |||
23 | |||
24 | EFI_DEVICE_PATH * |
||
25 | DevicePathFromHandle ( |
||
26 | IN EFI_HANDLE Handle |
||
27 | ) |
||
28 | { |
||
29 | EFI_STATUS Status; |
||
30 | EFI_DEVICE_PATH *DevicePath; |
||
31 | |||
32 | Status = BS->HandleProtocol (Handle, &DevicePathProtocol, (VOID*)&DevicePath); |
||
33 | if (EFI_ERROR(Status)) { |
||
34 | DevicePath = NULL; |
||
35 | } |
||
36 | |||
37 | return DevicePath; |
||
38 | } |
||
39 | |||
40 | |||
41 | EFI_DEVICE_PATH * |
||
42 | DevicePathInstance ( |
||
43 | IN OUT EFI_DEVICE_PATH **DevicePath, |
||
44 | OUT UINTN *Size |
||
45 | ) |
||
46 | { |
||
47 | EFI_DEVICE_PATH *Start, *Next, *DevPath; |
||
48 | UINTN Count; |
||
49 | |||
50 | DevPath = *DevicePath; |
||
51 | Start = DevPath; |
||
52 | |||
53 | if (!DevPath) { |
||
54 | return NULL; |
||
55 | } |
||
56 | |||
57 | // |
||
58 | // Check for end of device path type |
||
59 | // |
||
60 | |||
61 | for (Count = 0; ; Count++) { |
||
62 | Next = NextDevicePathNode(DevPath); |
||
63 | |||
64 | if (IsDevicePathEndType(DevPath)) { |
||
65 | break; |
||
66 | } |
||
67 | |||
68 | if (Count > 01000) { |
||
69 | // |
||
70 | // BugBug: Debug code to catch bogus device paths |
||
71 | // |
||
72 | DEBUG((D_ERROR, "DevicePathInstance: DevicePath %x Size %d", *DevicePath, ((UINT8 *) DevPath) - ((UINT8 *) Start) )); |
||
73 | DumpHex (0, 0, ((UINT8 *) DevPath) - ((UINT8 *) Start), Start); |
||
74 | break; |
||
75 | } |
||
76 | |||
77 | DevPath = Next; |
||
78 | } |
||
79 | |||
80 | ASSERT (DevicePathSubType(DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE || |
||
81 | DevicePathSubType(DevPath) == END_INSTANCE_DEVICE_PATH_SUBTYPE); |
||
82 | |||
83 | // |
||
84 | // Set next position |
||
85 | // |
||
86 | |||
87 | if (DevicePathSubType(DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE) { |
||
88 | Next = NULL; |
||
89 | } |
||
90 | |||
91 | *DevicePath = Next; |
||
92 | |||
93 | // |
||
94 | // Return size and start of device path instance |
||
95 | // |
||
96 | |||
97 | *Size = ((UINT8 *) DevPath) - ((UINT8 *) Start); |
||
98 | return Start; |
||
99 | } |
||
100 | |||
101 | UINTN |
||
102 | DevicePathInstanceCount ( |
||
103 | IN EFI_DEVICE_PATH *DevicePath |
||
104 | ) |
||
105 | { |
||
106 | UINTN Count, Size; |
||
107 | |||
108 | Count = 0; |
||
109 | while (DevicePathInstance(&DevicePath, &Size)) { |
||
110 | Count += 1; |
||
111 | } |
||
112 | |||
113 | return Count; |
||
114 | } |
||
115 | |||
116 | |||
117 | EFI_DEVICE_PATH * |
||
118 | AppendDevicePath ( |
||
119 | IN EFI_DEVICE_PATH *Src1, |
||
120 | IN EFI_DEVICE_PATH *Src2 |
||
121 | ) |
||
122 | // Src1 may have multiple "instances" and each instance is appended |
||
123 | // Src2 is appended to each instance is Src1. (E.g., it's possible |
||
124 | // to append a new instance to the complete device path by passing |
||
125 | // it in Src2) |
||
126 | { |
||
127 | UINTN Src1Size, Src1Inst, Src2Size, Size; |
||
128 | EFI_DEVICE_PATH *Dst, *Inst; |
||
129 | UINT8 *DstPos; |
||
130 | |||
131 | // |
||
132 | // If there's only 1 path, just duplicate it |
||
133 | // |
||
134 | |||
135 | if (!Src1) { |
||
136 | ASSERT (!IsDevicePathUnpacked (Src2)); |
||
137 | return DuplicateDevicePath (Src2); |
||
138 | } |
||
139 | |||
140 | if (!Src2) { |
||
141 | ASSERT (!IsDevicePathUnpacked (Src1)); |
||
142 | return DuplicateDevicePath (Src1); |
||
143 | } |
||
144 | |||
145 | // |
||
146 | // Verify we're not working with unpacked paths |
||
147 | // |
||
148 | |||
149 | // ASSERT (!IsDevicePathUnpacked (Src1)); |
||
150 | // ASSERT (!IsDevicePathUnpacked (Src2)); |
||
151 | |||
152 | // |
||
153 | // Append Src2 to every instance in Src1 |
||
154 | // |
||
155 | |||
156 | Src1Size = DevicePathSize(Src1); |
||
157 | Src1Inst = DevicePathInstanceCount(Src1); |
||
158 | Src2Size = DevicePathSize(Src2); |
||
159 | Size = Src1Size * Src1Inst + Src2Size; |
||
160 | |||
161 | Dst = AllocatePool (Size); |
||
162 | if (Dst) { |
||
163 | DstPos = (UINT8 *) Dst; |
||
164 | |||
165 | // |
||
166 | // Copy all device path instances |
||
167 | // |
||
168 | |||
169 | while ((Inst = DevicePathInstance (&Src1, &Size))) { |
||
170 | |||
171 | CopyMem(DstPos, Inst, Size); |
||
172 | DstPos += Size; |
||
173 | |||
174 | CopyMem(DstPos, Src2, Src2Size); |
||
175 | DstPos += Src2Size; |
||
176 | |||
177 | CopyMem(DstPos, EndInstanceDevicePath, sizeof(EFI_DEVICE_PATH)); |
||
178 | DstPos += sizeof(EFI_DEVICE_PATH); |
||
179 | } |
||
180 | |||
181 | // Change last end marker |
||
182 | DstPos -= sizeof(EFI_DEVICE_PATH); |
||
183 | CopyMem(DstPos, EndDevicePath, sizeof(EFI_DEVICE_PATH)); |
||
184 | } |
||
185 | |||
186 | return Dst; |
||
187 | } |
||
188 | |||
189 | |||
190 | EFI_DEVICE_PATH * |
||
191 | AppendDevicePathNode ( |
||
192 | IN EFI_DEVICE_PATH *Src1, |
||
193 | IN EFI_DEVICE_PATH *Src2 |
||
194 | ) |
||
195 | // Src1 may have multiple "instances" and each instance is appended |
||
196 | // Src2 is a signal device path node (without a terminator) that is |
||
197 | // appended to each instance is Src1. |
||
198 | { |
||
199 | EFI_DEVICE_PATH *Temp, *Eop; |
||
200 | UINTN Length; |
||
201 | |||
202 | // |
||
203 | // Build a Src2 that has a terminator on it |
||
204 | // |
||
205 | |||
206 | Length = DevicePathNodeLength(Src2); |
||
207 | Temp = AllocatePool (Length + sizeof(EFI_DEVICE_PATH)); |
||
208 | if (!Temp) { |
||
209 | return NULL; |
||
210 | } |
||
211 | |||
212 | CopyMem (Temp, Src2, Length); |
||
213 | Eop = NextDevicePathNode(Temp); |
||
214 | SetDevicePathEndNode(Eop); |
||
215 | |||
216 | // |
||
217 | // Append device paths |
||
218 | // |
||
219 | |||
220 | Src1 = AppendDevicePath (Src1, Temp); |
||
221 | FreePool (Temp); |
||
222 | return Src1; |
||
223 | } |
||
224 | |||
225 | |||
226 | EFI_DEVICE_PATH * |
||
227 | FileDevicePath ( |
||
228 | IN EFI_HANDLE Device OPTIONAL, |
||
229 | IN CHAR16 *FileName |
||
230 | ) |
||
231 | /*++ |
||
232 | |||
233 | N.B. Results are allocated from pool. The caller must FreePool |
||
234 | the resulting device path structure |
||
235 | |||
236 | --*/ |
||
237 | { |
||
238 | UINTN Size; |
||
239 | FILEPATH_DEVICE_PATH *FilePath; |
||
240 | EFI_DEVICE_PATH *Eop, *DevicePath; |
||
241 | |||
242 | Size = StrSize(FileName); |
||
243 | FilePath = AllocateZeroPool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + sizeof(EFI_DEVICE_PATH)); |
||
244 | DevicePath = NULL; |
||
245 | |||
246 | if (FilePath) { |
||
247 | |||
248 | // |
||
249 | // Build a file path |
||
250 | // |
||
251 | |||
252 | FilePath->Header.Type = MEDIA_DEVICE_PATH; |
||
253 | FilePath->Header.SubType = MEDIA_FILEPATH_DP; |
||
254 | SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH); |
||
255 | CopyMem (FilePath->PathName, FileName, Size); |
||
256 | Eop = NextDevicePathNode(&FilePath->Header); |
||
257 | SetDevicePathEndNode(Eop); |
||
258 | |||
259 | // |
||
260 | // Append file path to device's device path |
||
261 | // |
||
262 | |||
263 | DevicePath = (EFI_DEVICE_PATH *) FilePath; |
||
264 | if (Device) { |
||
265 | DevicePath = AppendDevicePath ( |
||
266 | DevicePathFromHandle(Device), |
||
267 | DevicePath |
||
268 | ); |
||
269 | |||
270 | FreePool(FilePath); |
||
271 | } |
||
272 | } |
||
273 | |||
274 | return DevicePath; |
||
275 | } |
||
276 | |||
277 | |||
278 | |||
279 | UINTN |
||
280 | DevicePathSize ( |
||
281 | IN EFI_DEVICE_PATH *DevPath |
||
282 | ) |
||
283 | { |
||
284 | EFI_DEVICE_PATH *Start; |
||
285 | |||
286 | // |
||
287 | // Search for the end of the device path structure |
||
288 | // |
||
289 | |||
290 | Start = DevPath; |
||
291 | while (!IsDevicePathEnd(DevPath)) { |
||
292 | DevPath = NextDevicePathNode(DevPath); |
||
293 | } |
||
294 | |||
295 | // |
||
296 | // Compute the size |
||
297 | // |
||
298 | |||
299 | return ((UINTN) DevPath - (UINTN) Start) + sizeof(EFI_DEVICE_PATH); |
||
300 | } |
||
301 | |||
302 | EFI_DEVICE_PATH * |
||
303 | DuplicateDevicePath ( |
||
304 | IN EFI_DEVICE_PATH *DevPath |
||
305 | ) |
||
306 | { |
||
307 | EFI_DEVICE_PATH *NewDevPath; |
||
308 | UINTN Size; |
||
309 | |||
310 | |||
311 | // |
||
312 | // Compute the size |
||
313 | // |
||
314 | |||
315 | Size = DevicePathSize (DevPath); |
||
316 | |||
317 | // |
||
318 | // Make a copy |
||
319 | // |
||
320 | |||
321 | NewDevPath = AllocatePool (Size); |
||
322 | if (NewDevPath) { |
||
323 | CopyMem (NewDevPath, DevPath, Size); |
||
324 | } |
||
325 | |||
326 | return NewDevPath; |
||
327 | } |
||
328 | |||
329 | EFI_DEVICE_PATH * |
||
330 | UnpackDevicePath ( |
||
331 | IN EFI_DEVICE_PATH *DevPath |
||
332 | ) |
||
333 | { |
||
334 | EFI_DEVICE_PATH *Src, *Dest, *NewPath; |
||
335 | UINTN Size; |
||
336 | |||
337 | // |
||
338 | // Walk device path and round sizes to valid boundries |
||
339 | // |
||
340 | |||
341 | Src = DevPath; |
||
342 | Size = 0; |
||
343 | for (; ;) { |
||
344 | Size += DevicePathNodeLength(Src); |
||
345 | Size += ALIGN_SIZE(Size); |
||
346 | |||
347 | if (IsDevicePathEnd(Src)) { |
||
348 | break; |
||
349 | } |
||
350 | |||
351 | Src = NextDevicePathNode(Src); |
||
352 | } |
||
353 | |||
354 | |||
355 | // |
||
356 | // Allocate space for the unpacked path |
||
357 | // |
||
358 | |||
359 | NewPath = AllocateZeroPool (Size); |
||
360 | if (NewPath) { |
||
361 | |||
362 | ASSERT (((UINTN)NewPath) % MIN_ALIGNMENT_SIZE == 0); |
||
363 | |||
364 | // |
||
365 | // Copy each node |
||
366 | // |
||
367 | |||
368 | Src = DevPath; |
||
369 | Dest = NewPath; |
||
370 | for (; ;) { |
||
371 | Size = DevicePathNodeLength(Src); |
||
372 | CopyMem (Dest, Src, Size); |
||
373 | Size += ALIGN_SIZE(Size); |
||
374 | SetDevicePathNodeLength (Dest, Size); |
||
375 | Dest->Type |= EFI_DP_TYPE_UNPACKED; |
||
376 | Dest = (EFI_DEVICE_PATH *) (((UINT8 *) Dest) + Size); |
||
377 | |||
378 | if (IsDevicePathEnd(Src)) { |
||
379 | break; |
||
380 | } |
||
381 | |||
382 | Src = NextDevicePathNode(Src); |
||
383 | } |
||
384 | } |
||
385 | |||
386 | return NewPath; |
||
387 | } |
||
388 | |||
389 | |||
390 | EFI_DEVICE_PATH* |
||
391 | AppendDevicePathInstance ( |
||
392 | IN EFI_DEVICE_PATH *Src, |
||
393 | IN EFI_DEVICE_PATH *Instance |
||
394 | ) |
||
395 | { |
||
396 | UINT8 *Ptr; |
||
397 | EFI_DEVICE_PATH *DevPath; |
||
398 | UINTN SrcSize; |
||
399 | UINTN InstanceSize; |
||
400 | |||
401 | if (Src == NULL) { |
||
402 | return DuplicateDevicePath (Instance); |
||
403 | } |
||
404 | SrcSize = DevicePathSize(Src); |
||
405 | InstanceSize = DevicePathSize(Instance); |
||
406 | Ptr = AllocatePool (SrcSize + InstanceSize); |
||
407 | DevPath = (EFI_DEVICE_PATH *)Ptr; |
||
408 | ASSERT(DevPath); |
||
409 | |||
410 | CopyMem (Ptr, Src, SrcSize); |
||
411 | // FreePool (Src); |
||
412 | |||
413 | while (!IsDevicePathEnd(DevPath)) { |
||
414 | DevPath = NextDevicePathNode(DevPath); |
||
415 | } |
||
416 | // |
||
417 | // Convert the End to an End Instance, since we are |
||
418 | // appending another instacne after this one its a good |
||
419 | // idea. |
||
420 | // |
||
421 | DevPath->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE; |
||
422 | |||
423 | DevPath = NextDevicePathNode(DevPath); |
||
424 | CopyMem (DevPath, Instance, InstanceSize); |
||
425 | return (EFI_DEVICE_PATH *)Ptr; |
||
426 | } |
||
427 | |||
428 | EFI_STATUS |
||
429 | LibDevicePathToInterface ( |
||
430 | IN EFI_GUID *Protocol, |
||
431 | IN EFI_DEVICE_PATH *FilePath, |
||
432 | OUT VOID **Interface |
||
433 | ) |
||
434 | { |
||
435 | EFI_STATUS Status; |
||
436 | EFI_HANDLE Device; |
||
437 | |||
438 | Status = BS->LocateDevicePath (Protocol, &FilePath, &Device); |
||
439 | |||
440 | if (!EFI_ERROR(Status)) { |
||
441 | |||
442 | // If we didn't get a direct match return not found |
||
443 | Status = EFI_NOT_FOUND; |
||
444 | |||
445 | if (IsDevicePathEnd(FilePath)) { |
||
446 | |||
447 | // |
||
448 | // It was a direct match, lookup the protocol interface |
||
449 | // |
||
450 | |||
451 | Status = BS->HandleProtocol (Device, Protocol, Interface); |
||
452 | } |
||
453 | } |
||
454 | |||
455 | // |
||
456 | // If there was an error, do not return an interface |
||
457 | // |
||
458 | |||
459 | if (EFI_ERROR(Status)) { |
||
460 | *Interface = NULL; |
||
461 | } |
||
462 | |||
463 | return Status; |
||
464 | } |
||
465 | |||
466 | VOID |
||
467 | _DevPathPci ( |
||
468 | IN OUT POOL_PRINT *Str, |
||
469 | IN VOID *DevPath |
||
470 | ) |
||
471 | { |
||
472 | PCI_DEVICE_PATH *Pci; |
||
473 | |||
474 | Pci = DevPath; |
||
475 | CatPrint(Str, L"Pci(%x|%x)", Pci->Device, Pci->Function); |
||
476 | } |
||
477 | |||
478 | VOID |
||
479 | _DevPathPccard ( |
||
480 | IN OUT POOL_PRINT *Str, |
||
481 | IN VOID *DevPath |
||
482 | ) |
||
483 | { |
||
484 | PCCARD_DEVICE_PATH *Pccard; |
||
485 | |||
486 | Pccard = DevPath; |
||
487 | CatPrint(Str, L"Pccard(Socket%x)", Pccard->SocketNumber); |
||
488 | } |
||
489 | |||
490 | VOID |
||
491 | _DevPathMemMap ( |
||
492 | IN OUT POOL_PRINT *Str, |
||
493 | IN VOID *DevPath |
||
494 | ) |
||
495 | { |
||
496 | MEMMAP_DEVICE_PATH *MemMap; |
||
497 | |||
498 | MemMap = DevPath; |
||
499 | CatPrint(Str, L"MemMap(%d:%x-%x)", |
||
500 | MemMap->MemoryType, |
||
501 | MemMap->StartingAddress, |
||
502 | MemMap->EndingAddress |
||
503 | ); |
||
504 | } |
||
505 | |||
506 | VOID |
||
507 | _DevPathController ( |
||
508 | IN OUT POOL_PRINT *Str, |
||
509 | IN VOID *DevPath |
||
510 | ) |
||
511 | { |
||
512 | CONTROLLER_DEVICE_PATH *Controller; |
||
513 | |||
514 | Controller = DevPath; |
||
515 | CatPrint(Str, L"Ctrl(%d)", |
||
516 | Controller->Controller |
||
517 | ); |
||
518 | } |
||
519 | |||
520 | VOID |
||
521 | _DevPathVendor ( |
||
522 | IN OUT POOL_PRINT *Str, |
||
523 | IN VOID *DevPath |
||
524 | ) |
||
525 | { |
||
526 | VENDOR_DEVICE_PATH *Vendor; |
||
527 | CHAR16 *Type; |
||
528 | UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *UnknownDevPath; |
||
529 | |||
530 | Vendor = DevPath; |
||
531 | switch (DevicePathType(&Vendor->Header)) { |
||
532 | case HARDWARE_DEVICE_PATH: Type = L"Hw"; break; |
||
533 | case MESSAGING_DEVICE_PATH: Type = L"Msg"; break; |
||
534 | case MEDIA_DEVICE_PATH: Type = L"Media"; break; |
||
535 | default: Type = L"?"; break; |
||
536 | } |
||
537 | |||
538 | CatPrint(Str, L"Ven%s(%g", Type, &Vendor->Guid); |
||
539 | if (CompareGuid (&Vendor->Guid, &UnknownDevice) == 0) { |
||
540 | // |
||
541 | // GUID used by EFI to enumerate an EDD 1.1 device |
||
542 | // |
||
543 | UnknownDevPath = (UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *)Vendor; |
||
544 | CatPrint(Str, L":%02x)", UnknownDevPath->LegacyDriveLetter); |
||
545 | } else { |
||
546 | CatPrint(Str, L")"); |
||
547 | } |
||
548 | } |
||
549 | |||
550 | |||
551 | VOID |
||
552 | _DevPathAcpi ( |
||
553 | IN OUT POOL_PRINT *Str, |
||
554 | IN VOID *DevPath |
||
555 | ) |
||
556 | { |
||
557 | ACPI_HID_DEVICE_PATH *Acpi; |
||
558 | |||
559 | Acpi = DevPath; |
||
560 | if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) { |
||
561 | CatPrint(Str, L"Acpi(PNP%04x,%x)", EISA_ID_TO_NUM (Acpi->HID), Acpi->UID); |
||
562 | } else { |
||
563 | CatPrint(Str, L"Acpi(%08x,%x)", Acpi->HID, Acpi->UID); |
||
564 | } |
||
565 | } |
||
566 | |||
567 | |||
568 | VOID |
||
569 | _DevPathAtapi ( |
||
570 | IN OUT POOL_PRINT *Str, |
||
571 | IN VOID *DevPath |
||
572 | ) |
||
573 | { |
||
574 | ATAPI_DEVICE_PATH *Atapi; |
||
575 | |||
576 | Atapi = DevPath; |
||
577 | CatPrint(Str, L"Ata(%s,%s)", |
||
578 | Atapi->PrimarySecondary ? L"Secondary" : L"Primary", |
||
579 | Atapi->SlaveMaster ? L"Slave" : L"Master" |
||
580 | ); |
||
581 | } |
||
582 | |||
583 | VOID |
||
584 | _DevPathScsi ( |
||
585 | IN OUT POOL_PRINT *Str, |
||
586 | IN VOID *DevPath |
||
587 | ) |
||
588 | { |
||
589 | SCSI_DEVICE_PATH *Scsi; |
||
590 | |||
591 | Scsi = DevPath; |
||
592 | CatPrint(Str, L"Scsi(Pun%x,Lun%x)", Scsi->Pun, Scsi->Lun); |
||
593 | } |
||
594 | |||
595 | |||
596 | VOID |
||
597 | _DevPathFibre ( |
||
598 | IN OUT POOL_PRINT *Str, |
||
599 | IN VOID *DevPath |
||
600 | ) |
||
601 | { |
||
602 | FIBRECHANNEL_DEVICE_PATH *Fibre; |
||
603 | |||
604 | Fibre = DevPath; |
||
605 | CatPrint(Str, L"Fibre(%lx)", Fibre->WWN); |
||
606 | } |
||
607 | |||
608 | VOID |
||
609 | _DevPath1394 ( |
||
610 | IN OUT POOL_PRINT *Str, |
||
611 | IN VOID *DevPath |
||
612 | ) |
||
613 | { |
||
614 | F1394_DEVICE_PATH *F1394; |
||
615 | |||
616 | F1394 = DevPath; |
||
617 | CatPrint(Str, L"1394(%g)", &F1394->Guid); |
||
618 | } |
||
619 | |||
620 | |||
621 | |||
622 | VOID |
||
623 | _DevPathUsb ( |
||
624 | IN OUT POOL_PRINT *Str, |
||
625 | IN VOID *DevPath |
||
626 | ) |
||
627 | { |
||
628 | USB_DEVICE_PATH *Usb; |
||
629 | |||
630 | Usb = DevPath; |
||
631 | CatPrint(Str, L"Usb(%x)", Usb->Port); |
||
632 | } |
||
633 | |||
634 | |||
635 | VOID |
||
636 | _DevPathI2O ( |
||
637 | IN OUT POOL_PRINT *Str, |
||
638 | IN VOID *DevPath |
||
639 | ) |
||
640 | { |
||
641 | I2O_DEVICE_PATH *I2O; |
||
642 | |||
643 | I2O = DevPath; |
||
644 | CatPrint(Str, L"I2O(%x)", I2O->Tid); |
||
645 | } |
||
646 | |||
647 | VOID |
||
648 | _DevPathMacAddr ( |
||
649 | IN OUT POOL_PRINT *Str, |
||
650 | IN VOID *DevPath |
||
651 | ) |
||
652 | { |
||
653 | MAC_ADDR_DEVICE_PATH *MAC; |
||
654 | UINTN HwAddressSize; |
||
655 | UINTN Index; |
||
656 | |||
657 | MAC = DevPath; |
||
658 | |||
659 | HwAddressSize = sizeof(EFI_MAC_ADDRESS); |
||
660 | if (MAC->IfType == 0x01 || MAC->IfType == 0x00) { |
||
661 | HwAddressSize = 6; |
||
662 | } |
||
663 | |||
664 | CatPrint(Str, L"Mac("); |
||
665 | |||
666 | for(Index = 0; Index < HwAddressSize; Index++) { |
||
667 | CatPrint(Str, L"%02x",MAC->MacAddress.Addr[Index]); |
||
668 | } |
||
669 | CatPrint(Str, L")"); |
||
670 | } |
||
671 | |||
672 | VOID |
||
673 | _DevPathIPv4 ( |
||
674 | IN OUT POOL_PRINT *Str, |
||
675 | IN VOID *DevPath |
||
676 | ) |
||
677 | { |
||
678 | IPv4_DEVICE_PATH *IP; |
||
679 | |||
680 | IP = DevPath; |
||
681 | CatPrint(Str, L"IPv4(not-done)"); |
||
682 | } |
||
683 | |||
684 | VOID |
||
685 | _DevPathIPv6 ( |
||
686 | IN OUT POOL_PRINT *Str, |
||
687 | IN VOID *DevPath |
||
688 | ) |
||
689 | { |
||
690 | IPv6_DEVICE_PATH *IP; |
||
691 | |||
692 | IP = DevPath; |
||
693 | CatPrint(Str, L"IP-v6(not-done)"); |
||
694 | } |
||
695 | |||
696 | VOID |
||
697 | _DevPathInfiniBand ( |
||
698 | IN OUT POOL_PRINT *Str, |
||
699 | IN VOID *DevPath |
||
700 | ) |
||
701 | { |
||
702 | INFINIBAND_DEVICE_PATH *InfiniBand; |
||
703 | |||
704 | InfiniBand = DevPath; |
||
705 | CatPrint(Str, L"InfiniBand(not-done)"); |
||
706 | } |
||
707 | |||
708 | VOID |
||
709 | _DevPathUart ( |
||
710 | IN OUT POOL_PRINT *Str, |
||
711 | IN VOID *DevPath |
||
712 | ) |
||
713 | { |
||
714 | UART_DEVICE_PATH *Uart; |
||
715 | CHAR8 Parity; |
||
716 | |||
717 | Uart = DevPath; |
||
718 | switch (Uart->Parity) { |
||
719 | case 0 : Parity = 'D'; break; |
||
720 | case 1 : Parity = 'N'; break; |
||
721 | case 2 : Parity = 'E'; break; |
||
722 | case 3 : Parity = 'O'; break; |
||
723 | case 4 : Parity = 'M'; break; |
||
724 | case 5 : Parity = 'S'; break; |
||
725 | default : Parity = 'x'; break; |
||
726 | } |
||
727 | |||
728 | if (Uart->BaudRate == 0) { |
||
729 | CatPrint(Str, L"Uart(DEFAULT %c",Uart->BaudRate,Parity); |
||
730 | } else { |
||
731 | CatPrint(Str, L"Uart(%d %c",Uart->BaudRate,Parity); |
||
732 | } |
||
733 | |||
734 | if (Uart->DataBits == 0) { |
||
735 | CatPrint(Str, L"D"); |
||
736 | } else { |
||
737 | CatPrint(Str, L"%d",Uart->DataBits); |
||
738 | } |
||
739 | |||
740 | switch (Uart->StopBits) { |
||
741 | case 0 : CatPrint(Str, L"D)"); break; |
||
742 | case 1 : CatPrint(Str, L"1)"); break; |
||
743 | case 2 : CatPrint(Str, L"1.5)"); break; |
||
744 | case 3 : CatPrint(Str, L"2)"); break; |
||
745 | default : CatPrint(Str, L"x)"); break; |
||
746 | } |
||
747 | } |
||
748 | |||
749 | |||
750 | VOID |
||
751 | _DevPathHardDrive ( |
||
752 | IN OUT POOL_PRINT *Str, |
||
753 | IN VOID *DevPath |
||
754 | ) |
||
755 | { |
||
756 | HARDDRIVE_DEVICE_PATH *Hd; |
||
757 | |||
758 | Hd = DevPath; |
||
759 | switch (Hd->SignatureType) { |
||
760 | case SIGNATURE_TYPE_MBR: |
||
761 | CatPrint(Str, L"HD(Part%d,Sig%08X)", |
||
762 | Hd->PartitionNumber, |
||
763 | *((UINT32 *)(&(Hd->Signature[0]))) |
||
764 | ); |
||
765 | break; |
||
766 | case SIGNATURE_TYPE_GUID: |
||
767 | CatPrint(Str, L"HD(Part%d,Sig%g)", |
||
768 | Hd->PartitionNumber, |
||
769 | (EFI_GUID *) &(Hd->Signature[0]) |
||
770 | ); |
||
771 | break; |
||
772 | default: |
||
773 | CatPrint(Str, L"HD(Part%d,MBRType=%02x,SigType=%02x)", |
||
774 | Hd->PartitionNumber, |
||
775 | Hd->MBRType, |
||
776 | Hd->SignatureType |
||
777 | ); |
||
778 | break; |
||
779 | } |
||
780 | } |
||
781 | |||
782 | VOID |
||
783 | _DevPathCDROM ( |
||
784 | IN OUT POOL_PRINT *Str, |
||
785 | IN VOID *DevPath |
||
786 | ) |
||
787 | { |
||
788 | CDROM_DEVICE_PATH *Cd; |
||
789 | |||
790 | Cd = DevPath; |
||
791 | CatPrint(Str, L"CDROM(Entry%x)", Cd->BootEntry); |
||
792 | } |
||
793 | |||
794 | VOID |
||
795 | _DevPathFilePath ( |
||
796 | IN OUT POOL_PRINT *Str, |
||
797 | IN VOID *DevPath |
||
798 | ) |
||
799 | { |
||
800 | FILEPATH_DEVICE_PATH *Fp; |
||
801 | |||
802 | Fp = DevPath; |
||
803 | CatPrint(Str, L"%s", Fp->PathName); |
||
804 | } |
||
805 | |||
806 | VOID |
||
807 | _DevPathMediaProtocol ( |
||
808 | IN OUT POOL_PRINT *Str, |
||
809 | IN VOID *DevPath |
||
810 | ) |
||
811 | { |
||
812 | MEDIA_PROTOCOL_DEVICE_PATH *MediaProt; |
||
813 | |||
814 | MediaProt = DevPath; |
||
815 | CatPrint(Str, L"%g", &MediaProt->Protocol); |
||
816 | } |
||
817 | |||
818 | VOID |
||
819 | _DevPathBssBss ( |
||
820 | IN OUT POOL_PRINT *Str, |
||
821 | IN VOID *DevPath |
||
822 | ) |
||
823 | { |
||
824 | BBS_BBS_DEVICE_PATH *Bss; |
||
825 | CHAR16 *Type; |
||
826 | |||
827 | Bss = DevPath; |
||
828 | switch (Bss->DeviceType) { |
||
829 | case BBS_TYPE_FLOPPY: Type = L"Floppy"; break; |
||
830 | case BBS_TYPE_HARDDRIVE: Type = L"Harddrive"; break; |
||
831 | case BBS_TYPE_CDROM: Type = L"CDROM"; break; |
||
832 | case BBS_TYPE_PCMCIA: Type = L"PCMCIA"; break; |
||
833 | case BBS_TYPE_USB: Type = L"Usb"; break; |
||
834 | case BBS_TYPE_EMBEDDED_NETWORK: Type = L"Net"; break; |
||
835 | default: Type = L"?"; break; |
||
836 | } |
||
837 | |||
838 | CatPrint(Str, L"Bss-%s(%a)", Type, Bss->String); |
||
839 | } |
||
840 | |||
841 | |||
842 | VOID |
||
843 | _DevPathEndInstance ( |
||
844 | IN OUT POOL_PRINT *Str, |
||
845 | IN VOID *DevPath |
||
846 | ) |
||
847 | { |
||
848 | CatPrint(Str, L","); |
||
849 | } |
||
850 | |||
851 | VOID |
||
852 | _DevPathNodeUnknown ( |
||
853 | IN OUT POOL_PRINT *Str, |
||
854 | IN VOID *DevPath |
||
855 | ) |
||
856 | { |
||
857 | CatPrint(Str, L"?"); |
||
858 | } |
||
859 | |||
860 | |||
861 | struct { |
||
862 | UINT8 Type; |
||
863 | UINT8 SubType; |
||
864 | VOID (*Function)(POOL_PRINT *, VOID *); |
||
865 | } DevPathTable[] = { |
||
866 | { HARDWARE_DEVICE_PATH, HW_PCI_DP, _DevPathPci}, |
||
867 | { HARDWARE_DEVICE_PATH, HW_PCCARD_DP, _DevPathPccard}, |
||
868 | { HARDWARE_DEVICE_PATH, HW_MEMMAP_DP, _DevPathMemMap}, |
||
869 | { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, _DevPathVendor}, |
||
870 | { HARDWARE_DEVICE_PATH, HW_CONTROLLER_DP, _DevPathController}, |
||
871 | { ACPI_DEVICE_PATH, ACPI_DP, _DevPathAcpi}, |
||
872 | { MESSAGING_DEVICE_PATH, MSG_ATAPI_DP, _DevPathAtapi}, |
||
873 | { MESSAGING_DEVICE_PATH, MSG_SCSI_DP, _DevPathScsi}, |
||
874 | { MESSAGING_DEVICE_PATH, MSG_FIBRECHANNEL_DP, _DevPathFibre}, |
||
875 | { MESSAGING_DEVICE_PATH, MSG_1394_DP, _DevPath1394}, |
||
876 | { MESSAGING_DEVICE_PATH, MSG_USB_DP, _DevPathUsb}, |
||
877 | { MESSAGING_DEVICE_PATH, MSG_I2O_DP, _DevPathI2O}, |
||
878 | { MESSAGING_DEVICE_PATH, MSG_MAC_ADDR_DP, _DevPathMacAddr}, |
||
879 | { MESSAGING_DEVICE_PATH, MSG_IPv4_DP, _DevPathIPv4}, |
||
880 | { MESSAGING_DEVICE_PATH, MSG_IPv6_DP, _DevPathIPv6}, |
||
881 | { MESSAGING_DEVICE_PATH, MSG_INFINIBAND_DP, _DevPathInfiniBand}, |
||
882 | { MESSAGING_DEVICE_PATH, MSG_UART_DP, _DevPathUart}, |
||
883 | { MESSAGING_DEVICE_PATH, MSG_VENDOR_DP, _DevPathVendor}, |
||
884 | { MEDIA_DEVICE_PATH, MEDIA_HARDDRIVE_DP, _DevPathHardDrive}, |
||
885 | { MEDIA_DEVICE_PATH, MEDIA_CDROM_DP, _DevPathCDROM}, |
||
886 | { MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP, _DevPathVendor}, |
||
887 | { MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP, _DevPathFilePath}, |
||
888 | { MEDIA_DEVICE_PATH, MEDIA_PROTOCOL_DP, _DevPathMediaProtocol}, |
||
889 | { BBS_DEVICE_PATH, BBS_BBS_DP, _DevPathBssBss}, |
||
890 | { END_DEVICE_PATH_TYPE, END_INSTANCE_DEVICE_PATH_SUBTYPE, _DevPathEndInstance}, |
||
891 | { 0, 0, NULL} |
||
892 | }; |
||
893 | |||
894 | |||
895 | CHAR16 * |
||
896 | DevicePathToStr ( |
||
897 | EFI_DEVICE_PATH *DevPath |
||
898 | ) |
||
899 | /*++ |
||
900 | |||
901 | Turns the Device Path into a printable string. Allcoates |
||
902 | the string from pool. The caller must FreePool the returned |
||
903 | string. |
||
904 | |||
905 | --*/ |
||
906 | { |
||
907 | POOL_PRINT Str; |
||
908 | EFI_DEVICE_PATH *DevPathNode; |
||
909 | VOID (*DumpNode)(POOL_PRINT *, VOID *); |
||
910 | UINTN Index, NewSize; |
||
911 | |||
912 | ZeroMem(&Str, sizeof(Str)); |
||
913 | |||
914 | // |
||
915 | // Unpacked the device path |
||
916 | // |
||
917 | |||
918 | DevPath = UnpackDevicePath(DevPath); |
||
919 | ASSERT (DevPath); |
||
920 | |||
921 | |||
922 | // |
||
923 | // Process each device path node |
||
924 | // |
||
925 | |||
926 | DevPathNode = DevPath; |
||
927 | while (!IsDevicePathEnd(DevPathNode)) { |
||
928 | // |
||
929 | // Find the handler to dump this device path node |
||
930 | // |
||
931 | |||
932 | DumpNode = NULL; |
||
933 | for (Index = 0; DevPathTable[Index].Function; Index += 1) { |
||
934 | |||
935 | if (DevicePathType(DevPathNode) == DevPathTable[Index].Type && |
||
936 | DevicePathSubType(DevPathNode) == DevPathTable[Index].SubType) { |
||
937 | DumpNode = DevPathTable[Index].Function; |
||
938 | break; |
||
939 | } |
||
940 | } |
||
941 | |||
942 | // |
||
943 | // If not found, use a generic function |
||
944 | // |
||
945 | |||
946 | if (!DumpNode) { |
||
947 | DumpNode = _DevPathNodeUnknown; |
||
948 | } |
||
949 | |||
950 | // |
||
951 | // Put a path seperator in if needed |
||
952 | // |
||
953 | |||
954 | if (Str.len && DumpNode != _DevPathEndInstance) { |
||
955 | CatPrint (&Str, L"/"); |
||
956 | } |
||
957 | |||
958 | // |
||
959 | // Print this node of the device path |
||
960 | // |
||
961 | |||
962 | DumpNode (&Str, DevPathNode); |
||
963 | |||
964 | // |
||
965 | // Next device path node |
||
966 | // |
||
967 | |||
968 | DevPathNode = NextDevicePathNode(DevPathNode); |
||
969 | } |
||
970 | |||
971 | // |
||
972 | // Shrink pool used for string allocation |
||
973 | // |
||
974 | |||
975 | FreePool (DevPath); |
||
976 | NewSize = (Str.len + 1) * sizeof(CHAR16); |
||
977 | Str.str = ReallocatePool (Str.str, NewSize, NewSize); |
||
978 | Str.str[Str.len] = 0; |
||
979 | return Str.str; |
||
980 | } |
||
981 | |||
982 | BOOLEAN |
||
983 | LibMatchDevicePaths ( |
||
984 | IN EFI_DEVICE_PATH *Multi, |
||
985 | IN EFI_DEVICE_PATH *Single |
||
986 | ) |
||
987 | { |
||
988 | EFI_DEVICE_PATH *DevicePath, *DevicePathInst; |
||
989 | UINTN Size; |
||
990 | |||
991 | if (!Multi || !Single) { |
||
992 | return FALSE; |
||
993 | } |
||
994 | |||
995 | DevicePath = Multi; |
||
996 | while ((DevicePathInst = DevicePathInstance (&DevicePath, &Size))) { |
||
997 | if (CompareMem (Single, DevicePathInst, Size) == 0) { |
||
998 | return TRUE; |
||
999 | } |
||
1000 | } |
||
1001 | return FALSE; |
||
1002 | } |
||
1003 | |||
1004 | EFI_DEVICE_PATH * |
||
1005 | LibDuplicateDevicePathInstance ( |
||
1006 | IN EFI_DEVICE_PATH *DevPath |
||
1007 | ) |
||
1008 | { |
||
1009 | EFI_DEVICE_PATH *NewDevPath,*DevicePathInst,*Temp; |
||
1010 | UINTN Size; |
||
1011 | |||
1012 | // |
||
1013 | // get the size of an instance from the input |
||
1014 | // |
||
1015 | |||
1016 | Temp = DevPath; |
||
1017 | DevicePathInst = DevicePathInstance (&Temp, &Size); |
||
1018 | |||
1019 | // |
||
1020 | // Make a copy and set proper end type |
||
1021 | // |
||
1022 | NewDevPath = NULL; |
||
1023 | if (Size) { |
||
1024 | NewDevPath = AllocatePool (Size + sizeof(EFI_DEVICE_PATH)); |
||
1025 | } |
||
1026 | |||
1027 | if (NewDevPath) { |
||
1028 | CopyMem (NewDevPath, DevicePathInst, Size); |
||
1029 | Temp = NextDevicePathNode(NewDevPath); |
||
1030 | SetDevicePathEndNode(Temp); |
||
1031 | } |
||
1032 | |||
1033 | return NewDevPath; |
||
1034 | } |
||
1035 |