~galfy/helenos/bird-port-mainline

« back to all changes in this revision

Viewing changes to boot/arch/ia64/loader/gefi/lib/dpath.c

  • Committer: Martin Decky
  • Date: 2009-08-04 11:19:19 UTC
  • Revision ID: martin@uranus.dsrg.hide.ms.mff.cuni.cz-20090804111919-evyclddlr3v5lhmp
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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