source: mainline/boot/arch/ia64/loader/gefi/lib/misc.c@ 7208b6c

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 7208b6c 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: 10.7 KB
Line 
1/*++
2
3Copyright (c) 1998 Intel Corporation
4
5Module Name:
6
7 misc.c
8
9Abstract:
10
11
12
13
14Revision History
15
16--*/
17
18#include "lib.h"
19
20
21//
22//
23//
24
25VOID *
26AllocatePool (
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
41VOID *
42AllocateZeroPool (
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
56VOID *
57ReallocatePool (
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
82VOID
83FreePool (
84 IN VOID *Buffer
85 )
86{
87 BS->FreePool (Buffer);
88}
89
90
91
92VOID
93ZeroMem (
94 IN VOID *Buffer,
95 IN UINTN Size
96 )
97{
98 RtZeroMem (Buffer, Size);
99}
100
101VOID
102SetMem (
103 IN VOID *Buffer,
104 IN UINTN Size,
105 IN UINT8 Value
106 )
107{
108 RtSetMem (Buffer, Size, Value);
109}
110
111VOID
112CopyMem (
113 IN VOID *Dest,
114 IN VOID *Src,
115 IN UINTN len
116 )
117{
118 RtCopyMem (Dest, Src, len);
119}
120
121INTN
122CompareMem (
123 IN VOID *Dest,
124 IN VOID *Src,
125 IN UINTN len
126 )
127{
128 return RtCompareMem (Dest, Src, len);
129}
130
131BOOLEAN
132GrowBuffer(
133 IN OUT EFI_STATUS *Status,
134 IN OUT VOID **Buffer,
135 IN UINTN BufferSize
136 )
137/*++
138
139Routine 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
145Arguments:
146
147 Status - Current status
148
149 Buffer - Current allocated buffer, or NULL
150
151 BufferSize - Current buffer size needed
152
153Returns:
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
203EFI_MEMORY_DESCRIPTOR *
204LibMemoryMap (
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
241VOID *
242LibGetVariableAndSize (
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
280VOID *
281LibGetVariable (
282 IN CHAR16 *Name,
283 IN EFI_GUID *VendorGuid
284 )
285{
286 UINTN VarSize;
287
288 return LibGetVariableAndSize (Name, VendorGuid, &VarSize);
289}
290
291EFI_STATUS
292LibDeleteVariable (
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
320EFI_STATUS
321LibInsertToTailOfBootOrder (
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
367BOOLEAN
368ValidMBR(
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
442UINT8
443DecimaltoBCD(
444 IN UINT8 DecValue
445 )
446{
447 return RtDecimaltoBCD (DecValue);
448}
449
450
451UINT8
452BCDtoDecimal(
453 IN UINT8 BcdValue
454 )
455{
456 return RtBCDtoDecimal (BcdValue);
457}
458
459EFI_STATUS
460LibGetSystemConfigurationTable(
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
478CHAR16 *
479LibGetUiString (
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}
Note: See TracBrowser for help on using the repository browser.