source: mainline/boot/arch/ia64/loader/gefi/lib/hand.c@ 86018c1

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 86018c1 was 7208b6c, checked in by Jakub Vana <jakub.vana@…>, 17 years ago

Basic IA64 boot and kernel suport for real machines

  • Property mode set to 100644
File size: 13.8 KB
Line 
1/*++
2
3Copyright (c) 1998 Intel Corporation
4
5Module Name:
6
7 hand.c
8
9Abstract:
10
11
12
13
14Revision History
15
16--*/
17
18#include "lib.h"
19#include "efistdarg.h" // !!!
20
21
22EFI_STATUS
23LibLocateProtocol (
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
57EFI_STATUS
58LibLocateHandle (
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
102EFI_STATUS
103LibLocateHandleByDiskSignature (
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
291EFI_FILE_HANDLE
292LibOpenRoot (
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
322EFI_FILE_INFO *
323LibFileInfo (
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
355EFI_FILE_SYSTEM_INFO *
356LibFileSystemInfo (
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
387EFI_FILE_SYSTEM_VOLUME_LABEL_INFO *
388LibFileSystemVolumeLabelInfo (
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
421EFI_STATUS
422LibInstallProtocolInterfaces (
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
504VOID
505LibUninstallProtocolInterfaces (
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
542EFI_STATUS
543LibReinstallProtocolInterfaces (
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}
Note: See TracBrowser for help on using the repository browser.