Subversion Repositories HelenOS

Rev

Rev 2726 | Details | Compare with Previous | 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
    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
}