~vojtech-horky/helenos/numa

« back to all changes in this revision

Viewing changes to boot/arch/ia64/loader/gefi/lib/misc.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
    misc.c
 
8
 
 
9
Abstract:
 
10
 
 
11
 
 
12
 
 
13
 
 
14
Revision History
 
15
 
 
16
--*/
 
17
 
 
18
#include "lib.h"
 
19
 
 
20
 
 
21
//
 
22
//
 
23
//
 
24
 
 
25
VOID *
 
26
AllocatePool (
 
27
    IN UINTN                Size
 
28
    )
 
29
{
 
30
    EFI_STATUS              Status;
 
31
    VOID                    *p;
 
32
 
 
33
    Status = BS->AllocatePool (PoolAllocationType, Size, &p);
 
34
    if (EFI_ERROR(Status)) {
 
35
        DEBUG((D_ERROR, "AllocatePool: out of pool  %x\n", Status));
 
36
        p = NULL;
 
37
    }
 
38
    return p;
 
39
}
 
40
 
 
41
VOID *
 
42
AllocateZeroPool (
 
43
    IN UINTN                Size
 
44
    )
 
45
{
 
46
    VOID                    *p;
 
47
 
 
48
    p = AllocatePool (Size);
 
49
    if (p) {
 
50
        ZeroMem (p, Size);
 
51
    }
 
52
 
 
53
    return p;
 
54
}
 
55
 
 
56
VOID *
 
57
ReallocatePool (
 
58
    IN VOID                 *OldPool,
 
59
    IN UINTN                OldSize,
 
60
    IN UINTN                NewSize
 
61
    )
 
62
{
 
63
    VOID                    *NewPool;
 
64
 
 
65
    NewPool = NULL;
 
66
    if (NewSize) {
 
67
        NewPool = AllocatePool (NewSize);
 
68
    }
 
69
 
 
70
    if (OldPool) {
 
71
        if (NewPool) {
 
72
            CopyMem (NewPool, OldPool, OldSize < NewSize ? OldSize : NewSize);
 
73
        }
 
74
    
 
75
        FreePool (OldPool);
 
76
    }
 
77
    
 
78
    return NewPool;
 
79
}
 
80
 
 
81
 
 
82
VOID
 
83
FreePool (
 
84
    IN VOID                 *Buffer
 
85
    )
 
86
{
 
87
    BS->FreePool (Buffer);
 
88
}
 
89
 
 
90
 
 
91
 
 
92
VOID
 
93
ZeroMem (
 
94
    IN VOID     *Buffer,
 
95
    IN UINTN    Size
 
96
    )
 
97
{
 
98
    RtZeroMem (Buffer, Size);
 
99
}
 
100
 
 
101
VOID
 
102
SetMem (
 
103
    IN VOID     *Buffer,
 
104
    IN UINTN    Size,
 
105
    IN UINT8    Value    
 
106
    )
 
107
{
 
108
    RtSetMem (Buffer, Size, Value);
 
109
}
 
110
 
 
111
VOID
 
112
CopyMem (
 
113
    IN VOID     *Dest,
 
114
    IN VOID     *Src,
 
115
    IN UINTN    len
 
116
    )
 
117
{
 
118
    RtCopyMem (Dest, Src, len);
 
119
}
 
120
 
 
121
INTN
 
122
CompareMem (
 
123
    IN VOID     *Dest,
 
124
    IN VOID     *Src,
 
125
    IN UINTN    len
 
126
    )
 
127
{
 
128
    return RtCompareMem (Dest, Src, len);
 
129
}
 
130
 
 
131
BOOLEAN
 
132
GrowBuffer(
 
133
    IN OUT EFI_STATUS   *Status,
 
134
    IN OUT VOID         **Buffer,
 
135
    IN UINTN            BufferSize
 
136
    )
 
137
/*++
 
138
 
 
139
Routine Description:
 
140
 
 
141
    Helper function called as part of the code needed
 
142
    to allocate the proper sized buffer for various 
 
143
    EFI interfaces.
 
144
 
 
145
Arguments:
 
146
 
 
147
    Status      - Current status
 
148
 
 
149
    Buffer      - Current allocated buffer, or NULL
 
150
 
 
151
    BufferSize  - Current buffer size needed
 
152
    
 
153
Returns:
 
154
    
 
155
    TRUE - if the buffer was reallocated and the caller 
 
156
    should try the API again.
 
157
 
 
158
--*/
 
159
{
 
160
    BOOLEAN         TryAgain;
 
161
 
 
162
    //
 
163
    // If this is an initial request, buffer will be null with a new buffer size
 
164
    //
 
165
 
 
166
    if (!*Buffer && BufferSize) {
 
167
        *Status = EFI_BUFFER_TOO_SMALL;
 
168
    }
 
169
 
 
170
    //
 
171
    // If the status code is "buffer too small", resize the buffer
 
172
    //
 
173
        
 
174
    TryAgain = FALSE;
 
175
    if (*Status == EFI_BUFFER_TOO_SMALL) {
 
176
 
 
177
        if (*Buffer) {
 
178
            FreePool (*Buffer);
 
179
        }
 
180
 
 
181
        *Buffer = AllocatePool (BufferSize);
 
182
 
 
183
        if (*Buffer) {
 
184
            TryAgain = TRUE;
 
185
        } else {    
 
186
            *Status = EFI_OUT_OF_RESOURCES;
 
187
        } 
 
188
    }
 
189
 
 
190
    //
 
191
    // If there's an error, free the buffer
 
192
    //
 
193
 
 
194
    if (!TryAgain && EFI_ERROR(*Status) && *Buffer) {
 
195
        FreePool (*Buffer);
 
196
        *Buffer = NULL;
 
197
    }
 
198
 
 
199
    return TryAgain;
 
200
}
 
201
 
 
202
 
 
203
EFI_MEMORY_DESCRIPTOR *
 
204
LibMemoryMap (
 
205
    OUT UINTN               *NoEntries,
 
206
    OUT UINTN               *MapKey,
 
207
    OUT UINTN               *DescriptorSize,
 
208
    OUT UINT32              *DescriptorVersion
 
209
    )
 
210
{
 
211
    EFI_STATUS              Status;
 
212
    EFI_MEMORY_DESCRIPTOR   *Buffer;
 
213
    UINTN                   BufferSize;
 
214
 
 
215
    //
 
216
    // Initialize for GrowBuffer loop
 
217
    //
 
218
 
 
219
    Buffer = NULL;
 
220
    BufferSize = sizeof(EFI_MEMORY_DESCRIPTOR);
 
221
 
 
222
    //
 
223
    // Call the real function
 
224
    //
 
225
 
 
226
    while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
 
227
        Status = BS->GetMemoryMap (&BufferSize, Buffer, MapKey, DescriptorSize, DescriptorVersion);
 
228
    }
 
229
 
 
230
    //
 
231
    // Convert buffer size to NoEntries
 
232
    //
 
233
 
 
234
    if (!EFI_ERROR(Status)) {
 
235
        *NoEntries = BufferSize / *DescriptorSize;
 
236
    }
 
237
 
 
238
    return Buffer;
 
239
}
 
240
 
 
241
VOID *
 
242
LibGetVariableAndSize (
 
243
    IN CHAR16               *Name,
 
244
    IN EFI_GUID             *VendorGuid,
 
245
    OUT UINTN               *VarSize
 
246
    )
 
247
{
 
248
    EFI_STATUS              Status;
 
249
    VOID                    *Buffer;
 
250
    UINTN                   BufferSize;
 
251
 
 
252
    //
 
253
    // Initialize for GrowBuffer loop
 
254
    //
 
255
 
 
256
    Buffer = NULL;
 
257
    BufferSize = 100;
 
258
 
 
259
    //
 
260
    // Call the real function
 
261
    //
 
262
 
 
263
    while (GrowBuffer (&Status, &Buffer, BufferSize)) {
 
264
        Status = RT->GetVariable (
 
265
                    Name,
 
266
                    VendorGuid,
 
267
                    NULL,
 
268
                    &BufferSize,
 
269
                    Buffer
 
270
                    );
 
271
    }
 
272
    if (Buffer) {
 
273
        *VarSize = BufferSize;
 
274
    } else {
 
275
        *VarSize = 0;
 
276
    }
 
277
    return Buffer;
 
278
}
 
279
    
 
280
VOID *
 
281
LibGetVariable (
 
282
    IN CHAR16               *Name,
 
283
    IN EFI_GUID             *VendorGuid
 
284
    )
 
285
{
 
286
    UINTN   VarSize;
 
287
 
 
288
    return LibGetVariableAndSize (Name, VendorGuid, &VarSize);
 
289
}
 
290
 
 
291
EFI_STATUS
 
292
LibDeleteVariable (
 
293
    IN CHAR16   *VarName,
 
294
    IN EFI_GUID *VarGuid
 
295
    )
 
296
{
 
297
    VOID        *VarBuf;
 
298
    EFI_STATUS  Status;
 
299
 
 
300
    VarBuf = LibGetVariable(VarName,VarGuid);
 
301
 
 
302
    Status = EFI_NOT_FOUND;
 
303
 
 
304
    if (VarBuf) {
 
305
        //
 
306
        // Delete variable from Storage
 
307
        //
 
308
        Status = RT->SetVariable (
 
309
                    VarName, VarGuid,
 
310
                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
 
311
                    0, NULL
 
312
                 );
 
313
        ASSERT (!EFI_ERROR(Status));
 
314
        FreePool(VarBuf);
 
315
    }
 
316
 
 
317
    return (Status);
 
318
}
 
319
 
 
320
EFI_STATUS
 
321
LibInsertToTailOfBootOrder (
 
322
    IN  UINT16  BootOption,
 
323
    IN  BOOLEAN OnlyInsertIfEmpty
 
324
    )
 
325
{
 
326
    UINT16      *BootOptionArray;
 
327
    UINT16      *NewBootOptionArray;
 
328
    UINTN       VarSize;
 
329
    UINTN       Index;
 
330
    EFI_STATUS  Status;
 
331
 
 
332
    BootOptionArray = LibGetVariableAndSize (VarBootOrder, &EfiGlobalVariable, &VarSize);    
 
333
    if (VarSize != 0 && OnlyInsertIfEmpty) {
 
334
        if (BootOptionArray) {
 
335
            FreePool (BootOptionArray);
 
336
        }
 
337
        return EFI_UNSUPPORTED;
 
338
    }
 
339
 
 
340
    VarSize += sizeof(UINT16);
 
341
    NewBootOptionArray = AllocatePool (VarSize);
 
342
    
 
343
    for (Index = 0; Index < ((VarSize/sizeof(UINT16)) - 1); Index++) {
 
344
        NewBootOptionArray[Index] = BootOptionArray[Index];
 
345
    }
 
346
    //
 
347
    // Insert in the tail of the array
 
348
    //
 
349
    NewBootOptionArray[Index] = BootOption;
 
350
 
 
351
    Status = RT->SetVariable (
 
352
                VarBootOrder, &EfiGlobalVariable,
 
353
                EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
 
354
                VarSize, (VOID*) NewBootOptionArray
 
355
                );
 
356
 
 
357
    if (NewBootOptionArray) {
 
358
        FreePool (NewBootOptionArray);
 
359
    }
 
360
    if (BootOptionArray) {
 
361
        FreePool (BootOptionArray);
 
362
    }
 
363
    return Status;
 
364
}
 
365
 
 
366
 
 
367
BOOLEAN
 
368
ValidMBR(
 
369
    IN  MASTER_BOOT_RECORD  *Mbr,
 
370
    IN  EFI_BLOCK_IO        *BlkIo
 
371
    )
 
372
{
 
373
    UINT32      StartingLBA, EndingLBA;
 
374
    UINT32      NewEndingLBA;
 
375
    INTN        i, j;
 
376
    BOOLEAN     ValidMbr;
 
377
 
 
378
    if (Mbr->Signature != MBR_SIGNATURE) {
 
379
        //
 
380
        // The BPB also has this signature, so it can not be used alone.
 
381
        //
 
382
        return FALSE;
 
383
    } 
 
384
 
 
385
    ValidMbr = FALSE;
 
386
    for (i=0; i<MAX_MBR_PARTITIONS; i++) {
 
387
        if ( Mbr->Partition[i].OSIndicator == 0x00 || EXTRACT_UINT32(Mbr->Partition[i].SizeInLBA) == 0 ) {
 
388
            continue;
 
389
        }
 
390
        ValidMbr = TRUE;
 
391
        StartingLBA = EXTRACT_UINT32(Mbr->Partition[i].StartingLBA);
 
392
        EndingLBA = StartingLBA + EXTRACT_UINT32(Mbr->Partition[i].SizeInLBA) - 1;
 
393
        if (EndingLBA > BlkIo->Media->LastBlock) {
 
394
            //
 
395
            // Compatability Errata:
 
396
            //  Some systems try to hide drive space with thier INT 13h driver
 
397
            //  This does not hide space from the OS driver. This means the MBR
 
398
            //  that gets created from DOS is smaller than the MBR created from 
 
399
            //  a real OS (NT & Win98). This leads to BlkIo->LastBlock being 
 
400
            //  wrong on some systems FDISKed by the OS.
 
401
            //
 
402
            //
 
403
            if (BlkIo->Media->LastBlock < MIN_MBR_DEVICE_SIZE) {
 
404
                //
 
405
                // If this is a very small device then trust the BlkIo->LastBlock
 
406
                //
 
407
                return FALSE;
 
408
            }
 
409
 
 
410
            if (EndingLBA > (BlkIo->Media->LastBlock + MBR_ERRATA_PAD)) {
 
411
                return FALSE;
 
412
            }
 
413
 
 
414
        }
 
415
        for (j=i+1; j<MAX_MBR_PARTITIONS; j++) {
 
416
            if (Mbr->Partition[j].OSIndicator == 0x00 || EXTRACT_UINT32(Mbr->Partition[j].SizeInLBA) == 0) {
 
417
                continue;
 
418
            }
 
419
            if (   EXTRACT_UINT32(Mbr->Partition[j].StartingLBA) >= StartingLBA && 
 
420
                   EXTRACT_UINT32(Mbr->Partition[j].StartingLBA) <= EndingLBA       ) {
 
421
                //
 
422
                // The Start of this region overlaps with the i'th region
 
423
                //
 
424
                return FALSE;
 
425
            } 
 
426
            NewEndingLBA = EXTRACT_UINT32(Mbr->Partition[j].StartingLBA) + EXTRACT_UINT32(Mbr->Partition[j].SizeInLBA) - 1;
 
427
            if ( NewEndingLBA >= StartingLBA && NewEndingLBA <= EndingLBA ) {
 
428
                //
 
429
                // The End of this region overlaps with the i'th region
 
430
                //
 
431
                return FALSE;
 
432
            }
 
433
        }
 
434
    }
 
435
    //
 
436
    // Non of the regions overlapped so MBR is O.K.
 
437
    //
 
438
    return ValidMbr;
 
439
 
440
   
 
441
 
 
442
UINT8
 
443
DecimaltoBCD(
 
444
    IN  UINT8 DecValue
 
445
    )
 
446
{
 
447
    return RtDecimaltoBCD (DecValue);
 
448
}
 
449
 
 
450
 
 
451
UINT8
 
452
BCDtoDecimal(
 
453
    IN  UINT8 BcdValue
 
454
    )
 
455
{
 
456
    return RtBCDtoDecimal (BcdValue);
 
457
}
 
458
 
 
459
EFI_STATUS
 
460
LibGetSystemConfigurationTable(
 
461
    IN EFI_GUID *TableGuid,
 
462
    IN OUT VOID **Table
 
463
    )
 
464
 
 
465
{
 
466
    UINTN Index;
 
467
 
 
468
    for(Index=0;Index<ST->NumberOfTableEntries;Index++) {
 
469
        if (CompareGuid(TableGuid,&(ST->ConfigurationTable[Index].VendorGuid))==0) {
 
470
            *Table = ST->ConfigurationTable[Index].VendorTable;
 
471
            return EFI_SUCCESS;
 
472
        }
 
473
    }
 
474
    return EFI_NOT_FOUND;
 
475
}
 
476
 
 
477
 
 
478
CHAR16 *
 
479
LibGetUiString (
 
480
    IN  EFI_HANDLE      Handle,
 
481
    IN  UI_STRING_TYPE  StringType,
 
482
    IN  ISO_639_2       *LangCode,
 
483
    IN  BOOLEAN         ReturnDevicePathStrOnMismatch
 
484
    )
 
485
{
 
486
    UI_INTERFACE    *Ui;
 
487
    UI_STRING_TYPE  Index;
 
488
    UI_STRING_ENTRY *Array;
 
489
    EFI_STATUS      Status;
 
490
    
 
491
    Status = BS->HandleProtocol (Handle, &UiProtocol, (VOID *)&Ui);
 
492
    if (EFI_ERROR(Status)) {
 
493
        return (ReturnDevicePathStrOnMismatch) ? DevicePathToStr(DevicePathFromHandle(Handle)) : NULL;
 
494
    }
 
495
 
 
496
    //
 
497
    // Skip the first strings
 
498
    //
 
499
    for (Index = UiDeviceString, Array = Ui->Entry; Index < StringType; Index++, Array++) {
 
500
        while (Array->LangCode) {
 
501
            Array++;
 
502
        }
 
503
    }
 
504
 
 
505
    //
 
506
    // Search for the match
 
507
    //
 
508
    while (Array->LangCode) {
 
509
        if (strcmpa (Array->LangCode, LangCode) == 0) {
 
510
            return Array->UiString; 
 
511
        }
 
512
    }
 
513
    return (ReturnDevicePathStrOnMismatch) ? DevicePathToStr(DevicePathFromHandle(Handle)) : NULL;
 
514
}