~jsvoboda/helenos/dnsr

« back to all changes in this revision

Viewing changes to boot/arch/ia64/loader/gefi/lib/hand.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
    hand.c
 
8
 
 
9
Abstract:
 
10
 
 
11
 
 
12
 
 
13
 
 
14
Revision History
 
15
 
 
16
--*/
 
17
 
 
18
#include "lib.h"
 
19
#include "efistdarg.h"                        // !!!
 
20
 
 
21
 
 
22
EFI_STATUS
 
23
LibLocateProtocol (
 
24
    IN  EFI_GUID    *ProtocolGuid,
 
25
    OUT VOID        **Interface
 
26
    )
 
27
//
 
28
// Find the first instance of this Protocol in the system and return it's interface
 
29
//
 
30
{
 
31
    EFI_STATUS      Status;
 
32
    UINTN           NumberHandles, Index;
 
33
    EFI_HANDLE      *Handles;
 
34
 
 
35
    
 
36
    *Interface = NULL;
 
37
    Status = LibLocateHandle (ByProtocol, ProtocolGuid, NULL, &NumberHandles, &Handles);
 
38
    if (EFI_ERROR(Status)) {
 
39
        DEBUG((D_INFO, "LibLocateProtocol: Handle not found\n"));
 
40
        return Status;
 
41
    }
 
42
 
 
43
    for (Index=0; Index < NumberHandles; Index++) {
 
44
        Status = BS->HandleProtocol (Handles[Index], ProtocolGuid, Interface);
 
45
        if (!EFI_ERROR(Status)) {
 
46
            break;
 
47
        }
 
48
    }
 
49
 
 
50
    if (Handles) {
 
51
        FreePool (Handles);
 
52
    }
 
53
 
 
54
    return Status;
 
55
}
 
56
 
 
57
EFI_STATUS
 
58
LibLocateHandle (
 
59
    IN EFI_LOCATE_SEARCH_TYPE       SearchType,
 
60
    IN EFI_GUID                     *Protocol OPTIONAL,
 
61
    IN VOID                         *SearchKey OPTIONAL,
 
62
    IN OUT UINTN                    *NoHandles,
 
63
    OUT EFI_HANDLE                  **Buffer
 
64
    )
 
65
 
 
66
{
 
67
    EFI_STATUS          Status;
 
68
    UINTN               BufferSize;
 
69
 
 
70
    //
 
71
    // Initialize for GrowBuffer loop
 
72
    //
 
73
 
 
74
    Status = EFI_SUCCESS;
 
75
    *Buffer = NULL;
 
76
    BufferSize = 50 * sizeof(EFI_HANDLE);
 
77
 
 
78
    //
 
79
    // Call the real function
 
80
    //
 
81
 
 
82
    while (GrowBuffer (&Status, (VOID **) Buffer, BufferSize)) {
 
83
 
 
84
        Status = BS->LocateHandle (
 
85
                        SearchType,
 
86
                        Protocol,
 
87
                        SearchKey,
 
88
                        &BufferSize,
 
89
                        *Buffer
 
90
                        );
 
91
 
 
92
    }
 
93
 
 
94
    *NoHandles = BufferSize / sizeof (EFI_HANDLE);
 
95
    if (EFI_ERROR(Status)) {
 
96
        *NoHandles = 0;
 
97
    }
 
98
 
 
99
    return Status;
 
100
}
 
101
 
 
102
EFI_STATUS
 
103
LibLocateHandleByDiskSignature (
 
104
    IN UINT8                        MBRType,
 
105
    IN UINT8                        SignatureType,
 
106
    IN VOID                         *Signature,
 
107
    IN OUT UINTN                    *NoHandles,
 
108
    OUT EFI_HANDLE                  **Buffer
 
109
    )
 
110
 
 
111
{
 
112
    EFI_STATUS            Status;
 
113
    UINTN                 BufferSize;
 
114
    UINTN                 NoBlockIoHandles;
 
115
    EFI_HANDLE            *BlockIoBuffer;
 
116
    EFI_DEVICE_PATH       *DevicePath;
 
117
    UINTN                 Index;
 
118
    EFI_DEVICE_PATH       *Start, *Next, *DevPath;
 
119
    HARDDRIVE_DEVICE_PATH *HardDriveDevicePath;
 
120
    BOOLEAN               Match;
 
121
    BOOLEAN               PreviousNodeIsHardDriveDevicePath;
 
122
 
 
123
    //
 
124
    // Initialize for GrowBuffer loop
 
125
    //
 
126
 
 
127
    BlockIoBuffer = NULL;
 
128
    BufferSize = 50 * sizeof(EFI_HANDLE);
 
129
 
 
130
    //
 
131
    // Call the real function
 
132
    //
 
133
 
 
134
    while (GrowBuffer (&Status, (VOID **)&BlockIoBuffer, BufferSize)) {
 
135
 
 
136
        //
 
137
        // Get list of device handles that support the BLOCK_IO Protocol.
 
138
        //
 
139
 
 
140
        Status = BS->LocateHandle (
 
141
                        ByProtocol,
 
142
                        &BlockIoProtocol,
 
143
                        NULL,
 
144
                        &BufferSize,
 
145
                        BlockIoBuffer
 
146
                        );
 
147
 
 
148
    }
 
149
 
 
150
    NoBlockIoHandles = BufferSize / sizeof (EFI_HANDLE);
 
151
    if (EFI_ERROR(Status)) {
 
152
        NoBlockIoHandles = 0;
 
153
    }
 
154
 
 
155
    //
 
156
    // If there was an error or there are no device handles that support 
 
157
    // the BLOCK_IO Protocol, then return.
 
158
    //
 
159
 
 
160
    if (NoBlockIoHandles == 0) {
 
161
        FreePool(BlockIoBuffer);
 
162
        *NoHandles = 0;
 
163
        *Buffer = NULL;
 
164
        return Status;
 
165
    }
 
166
 
 
167
    //
 
168
    // Loop through all the device handles that support the BLOCK_IO Protocol
 
169
    //
 
170
 
 
171
    *NoHandles = 0;
 
172
 
 
173
    for(Index=0;Index<NoBlockIoHandles;Index++) {
 
174
 
 
175
        Status = BS->HandleProtocol (BlockIoBuffer[Index], 
 
176
                                     &DevicePathProtocol, 
 
177
                                     (VOID*)&DevicePath
 
178
                                     );
 
179
 
 
180
        //
 
181
        // Search DevicePath for a Hard Drive Media Device Path node.
 
182
        // If one is found, then see if it matches the signature that was
 
183
        // passed in.  If it does match, and the next node is the End of the
 
184
        // device path, and the previous node is not a Hard Drive Media Device
 
185
        // Path, then we have found a match.
 
186
        //
 
187
 
 
188
        Match = FALSE;
 
189
 
 
190
        if (DevicePath != NULL) {
 
191
 
 
192
            PreviousNodeIsHardDriveDevicePath = FALSE;
 
193
 
 
194
            DevPath = DevicePath;
 
195
            Start = DevPath;
 
196
 
 
197
            //
 
198
            // Check for end of device path type
 
199
            //    
 
200
 
 
201
            for (; ;) {
 
202
 
 
203
                if ((DevicePathType(DevPath) == MEDIA_DEVICE_PATH) &&
 
204
                    (DevicePathSubType(DevPath) == MEDIA_HARDDRIVE_DP)) {
 
205
 
 
206
                    HardDriveDevicePath = (HARDDRIVE_DEVICE_PATH *)(DevPath);
 
207
 
 
208
                    if (PreviousNodeIsHardDriveDevicePath == FALSE) {
 
209
 
 
210
                        Next = NextDevicePathNode(DevPath);
 
211
                        if (IsDevicePathEndType(Next)) {
 
212
                            if ((HardDriveDevicePath->MBRType == MBRType) &&
 
213
                                (HardDriveDevicePath->SignatureType == SignatureType)) {
 
214
                                    switch(SignatureType) {
 
215
                                        case SIGNATURE_TYPE_MBR:
 
216
                                            if (*((UINT32 *)(Signature)) == *(UINT32 *)(&(HardDriveDevicePath->Signature[0]))) {
 
217
                                                Match = TRUE;
 
218
                                            }
 
219
                                            break;
 
220
                                        case SIGNATURE_TYPE_GUID:
 
221
                                            if (CompareGuid((EFI_GUID *)Signature,(EFI_GUID *)(&(HardDriveDevicePath->Signature[0]))) == 0) {
 
222
                                                Match = TRUE;
 
223
                                            }
 
224
                                            break;
 
225
                                    }
 
226
                            }
 
227
                        }
 
228
                    }
 
229
                    PreviousNodeIsHardDriveDevicePath = TRUE;
 
230
                } else {
 
231
                    PreviousNodeIsHardDriveDevicePath = FALSE;
 
232
                }
 
233
 
 
234
                if (IsDevicePathEnd(DevPath)) {
 
235
                    break;
 
236
                }
 
237
 
 
238
                DevPath = NextDevicePathNode(DevPath);
 
239
            }
 
240
 
 
241
        }
 
242
 
 
243
        if (Match == FALSE) {
 
244
            BlockIoBuffer[Index] = NULL;
 
245
        } else {
 
246
            *NoHandles = *NoHandles + 1;
 
247
        }
 
248
    }
 
249
 
 
250
    //
 
251
    // If there are no matches, then return
 
252
    //
 
253
 
 
254
    if (*NoHandles == 0) {
 
255
        FreePool(BlockIoBuffer);
 
256
        *NoHandles = 0;
 
257
        *Buffer = NULL;
 
258
        return EFI_SUCCESS;
 
259
    }
 
260
 
 
261
    //
 
262
    // Allocate space for the return buffer of device handles.
 
263
    //
 
264
 
 
265
    *Buffer = AllocatePool(*NoHandles * sizeof(EFI_HANDLE));
 
266
 
 
267
    if (*Buffer == NULL) {
 
268
        FreePool(BlockIoBuffer);
 
269
        *NoHandles = 0;
 
270
        *Buffer = NULL;
 
271
        return EFI_OUT_OF_RESOURCES;
 
272
    }
 
273
 
 
274
    //
 
275
    // Build list of matching device handles.
 
276
    //
 
277
 
 
278
    *NoHandles = 0;
 
279
    for(Index=0;Index<NoBlockIoHandles;Index++) {
 
280
        if (BlockIoBuffer[Index] != NULL) {
 
281
            (*Buffer)[*NoHandles] = BlockIoBuffer[Index];
 
282
            *NoHandles = *NoHandles + 1;
 
283
        }
 
284
    }
 
285
 
 
286
    FreePool(BlockIoBuffer);
 
287
 
 
288
    return EFI_SUCCESS;
 
289
}
 
290
 
 
291
EFI_FILE_HANDLE
 
292
LibOpenRoot (
 
293
    IN EFI_HANDLE               DeviceHandle
 
294
    )
 
295
{
 
296
    EFI_STATUS                  Status;
 
297
    EFI_FILE_IO_INTERFACE       *Volume;
 
298
    EFI_FILE_HANDLE             File;
 
299
 
 
300
 
 
301
    //
 
302
    // File the file system interface to the device
 
303
    //
 
304
 
 
305
    Status = BS->HandleProtocol (DeviceHandle, &FileSystemProtocol, (VOID*)&Volume);
 
306
 
 
307
    //
 
308
    // Open the root directory of the volume 
 
309
    //
 
310
 
 
311
    if (!EFI_ERROR(Status)) {
 
312
        Status = Volume->OpenVolume(Volume, &File);
 
313
    }
 
314
 
 
315
    //
 
316
    // Done
 
317
    //
 
318
 
 
319
    return EFI_ERROR(Status) ? NULL : File;
 
320
}
 
321
 
 
322
EFI_FILE_INFO *
 
323
LibFileInfo (
 
324
    IN EFI_FILE_HANDLE      FHand
 
325
    )
 
326
{
 
327
    EFI_STATUS              Status;
 
328
    EFI_FILE_INFO           *Buffer;
 
329
    UINTN                   BufferSize;
 
330
 
 
331
    //
 
332
    // Initialize for GrowBuffer loop
 
333
    //
 
334
 
 
335
    Buffer = NULL;
 
336
    BufferSize = SIZE_OF_EFI_FILE_INFO + 200;
 
337
 
 
338
    //
 
339
    // Call the real function
 
340
    //
 
341
 
 
342
    while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
 
343
        Status = FHand->GetInfo (
 
344
                    FHand,
 
345
                    &GenericFileInfo,
 
346
                    &BufferSize,
 
347
                    Buffer
 
348
                    );
 
349
    }
 
350
 
 
351
    return Buffer;
 
352
}
 
353
 
 
354
    
 
355
EFI_FILE_SYSTEM_INFO *
 
356
LibFileSystemInfo (
 
357
    IN EFI_FILE_HANDLE      FHand
 
358
    )
 
359
{
 
360
    EFI_STATUS              Status;
 
361
    EFI_FILE_SYSTEM_INFO    *Buffer;
 
362
    UINTN                   BufferSize;
 
363
 
 
364
    //
 
365
    // Initialize for GrowBuffer loop
 
366
    //
 
367
 
 
368
    Buffer = NULL;
 
369
    BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + 200;
 
370
 
 
371
    //
 
372
    // Call the real function
 
373
    //
 
374
 
 
375
    while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
 
376
        Status = FHand->GetInfo (
 
377
                    FHand,
 
378
                    &FileSystemInfo,
 
379
                    &BufferSize,
 
380
                    Buffer
 
381
                    );
 
382
    }
 
383
 
 
384
    return Buffer;
 
385
}
 
386
 
 
387
EFI_FILE_SYSTEM_VOLUME_LABEL_INFO *
 
388
LibFileSystemVolumeLabelInfo (
 
389
    IN EFI_FILE_HANDLE      FHand
 
390
    )
 
391
{
 
392
    EFI_STATUS                        Status;
 
393
    EFI_FILE_SYSTEM_VOLUME_LABEL_INFO *Buffer;
 
394
    UINTN                             BufferSize;
 
395
 
 
396
    //
 
397
    // Initialize for GrowBuffer loop
 
398
    //
 
399
 
 
400
    Buffer = NULL;
 
401
    BufferSize = SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL_INFO + 200;
 
402
 
 
403
    //
 
404
    // Call the real function
 
405
    //
 
406
 
 
407
    while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
 
408
        Status = FHand->GetInfo (
 
409
                    FHand,
 
410
                    &FileSystemVolumeLabelInfo,
 
411
                    &BufferSize,
 
412
                    Buffer
 
413
                    );
 
414
    }
 
415
 
 
416
    return Buffer;
 
417
}
 
418
 
 
419
    
 
420
 
 
421
EFI_STATUS
 
422
LibInstallProtocolInterfaces (
 
423
    IN OUT EFI_HANDLE           *Handle,
 
424
    ...
 
425
    )
 
426
{
 
427
    va_list         args;
 
428
    EFI_STATUS      Status;
 
429
    EFI_GUID        *Protocol;
 
430
    VOID            *Interface;
 
431
    EFI_TPL         OldTpl;
 
432
    UINTN           Index;
 
433
    EFI_HANDLE      OldHandle;
 
434
 
 
435
    //
 
436
    // Syncronize with notifcations
 
437
    // 
 
438
 
 
439
    OldTpl = BS->RaiseTPL(TPL_NOTIFY);
 
440
    OldHandle = *Handle;
 
441
 
 
442
    //
 
443
    // Install the protocol interfaces
 
444
    //
 
445
 
 
446
    Index = 0;
 
447
    Status = EFI_SUCCESS;
 
448
    va_start (args, Handle);
 
449
 
 
450
    while (!EFI_ERROR(Status)) {
 
451
 
 
452
        //
 
453
        // If protocol is NULL, then it's the end of the list
 
454
        //
 
455
 
 
456
        Protocol = va_arg(args, EFI_GUID *);
 
457
        if (!Protocol) {
 
458
            break;
 
459
        }
 
460
 
 
461
        Interface = va_arg(args, VOID *);
 
462
 
 
463
        //
 
464
        // Install it
 
465
        //
 
466
 
 
467
        DEBUG((D_INFO, "LibInstallProtocolInterface: %d %x\n", Protocol, Interface));
 
468
        Status = BS->InstallProtocolInterface (Handle, Protocol, EFI_NATIVE_INTERFACE, Interface);
 
469
        if (EFI_ERROR(Status)) {
 
470
            break;
 
471
        }
 
472
 
 
473
        Index += 1;
 
474
    }
 
475
 
 
476
    //
 
477
    // If there was an error, remove all the interfaces that were
 
478
    // installed without any errors
 
479
    //
 
480
 
 
481
    if (EFI_ERROR(Status)) {
 
482
        va_start (args, Handle);
 
483
        while (Index) {
 
484
 
 
485
            Protocol = va_arg(args, EFI_GUID *);
 
486
            Interface = va_arg(args, VOID *);
 
487
            BS->UninstallProtocolInterface (*Handle, Protocol, Interface);
 
488
 
 
489
            Index -= 1;
 
490
        }        
 
491
 
 
492
        *Handle = OldHandle;
 
493
    }
 
494
 
 
495
    //
 
496
    // Done
 
497
    //
 
498
 
 
499
    BS->RestoreTPL(OldTpl);
 
500
    return Status;
 
501
}
 
502
 
 
503
 
 
504
VOID
 
505
LibUninstallProtocolInterfaces (
 
506
    IN EFI_HANDLE           Handle,
 
507
    ...
 
508
    )
 
509
{
 
510
    va_list         args;
 
511
    EFI_STATUS      Status;
 
512
    EFI_GUID        *Protocol;
 
513
    VOID            *Interface;
 
514
 
 
515
    
 
516
    va_start (args, Handle);
 
517
    for (; ;) {
 
518
 
 
519
        //
 
520
        // If protocol is NULL, then it's the end of the list
 
521
        //
 
522
 
 
523
        Protocol = va_arg(args, EFI_GUID *);
 
524
        if (!Protocol) {
 
525
            break;
 
526
        }
 
527
 
 
528
        Interface = va_arg(args, VOID *);
 
529
 
 
530
        //
 
531
        // Uninstall it
 
532
        //
 
533
 
 
534
        Status = BS->UninstallProtocolInterface (Handle, Protocol, Interface);
 
535
        if (EFI_ERROR(Status)) {
 
536
            DEBUG((D_ERROR, "LibUninstallProtocolInterfaces: failed %g, %r\n", Protocol, Handle));
 
537
        }
 
538
    }
 
539
}    
 
540
 
 
541
 
 
542
EFI_STATUS
 
543
LibReinstallProtocolInterfaces (
 
544
    IN OUT EFI_HANDLE           *Handle,
 
545
    ...
 
546
    )
 
547
{
 
548
    va_list         args;
 
549
    EFI_STATUS      Status;
 
550
    EFI_GUID        *Protocol;
 
551
    VOID            *OldInterface, *NewInterface;
 
552
    EFI_TPL         OldTpl;
 
553
    UINTN           Index;
 
554
 
 
555
    //
 
556
    // Syncronize with notifcations
 
557
    // 
 
558
 
 
559
    OldTpl = BS->RaiseTPL(TPL_NOTIFY);
 
560
 
 
561
    //
 
562
    // Install the protocol interfaces
 
563
    //
 
564
 
 
565
    Index = 0;
 
566
    Status = EFI_SUCCESS;
 
567
    va_start (args, Handle);
 
568
 
 
569
    while (!EFI_ERROR(Status)) {
 
570
 
 
571
        //
 
572
        // If protocol is NULL, then it's the end of the list
 
573
        //
 
574
 
 
575
        Protocol = va_arg(args, EFI_GUID *);
 
576
        if (!Protocol) {
 
577
            break;
 
578
        }
 
579
 
 
580
        OldInterface = va_arg(args, VOID *);
 
581
        NewInterface = va_arg(args, VOID *);
 
582
 
 
583
        //
 
584
        // Reinstall it
 
585
        //
 
586
 
 
587
        Status = BS->ReinstallProtocolInterface (Handle, Protocol, OldInterface, NewInterface);
 
588
        if (EFI_ERROR(Status)) {
 
589
            break;
 
590
        }
 
591
 
 
592
        Index += 1;
 
593
    }
 
594
 
 
595
    //
 
596
    // If there was an error, undo all the interfaces that were
 
597
    // reinstalled without any errors
 
598
    //
 
599
 
 
600
    if (EFI_ERROR(Status)) {
 
601
        va_start (args, Handle);
 
602
        while (Index) {
 
603
 
 
604
            Protocol = va_arg(args, EFI_GUID *);
 
605
            OldInterface = va_arg(args, VOID *);
 
606
            NewInterface = va_arg(args, VOID *);
 
607
 
 
608
            BS->ReinstallProtocolInterface (Handle, Protocol, NewInterface, OldInterface);
 
609
 
 
610
            Index -= 1;
 
611
        }        
 
612
    }
 
613
 
 
614
    //
 
615
    // Done
 
616
    //
 
617
 
 
618
    BS->RestoreTPL(OldTpl);
 
619
    return Status;
 
620
}