1 /**
2 	Based on Base.h file, original notice:
3 
4 	Root include file for Mde Package Base type modules
5 
6 	This is the include file for any module of type base. Base modules only use
7 	types defined via this include file and can be ported easily to any
8 	environment. There are a set of base libraries in the Mde Package that can
9 	be used to implement base modules.
10 
11 	Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
12 	This program and the accompanying materials
13 	are licensed and made available under the terms and conditions of the BSD License
14 	which accompanies this distribution.  The full text of the license may be found at
15 	http://opensource.org/licenses/bsd-license.php
16 
17 	THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
18 	WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 **/
20 module uefi.base;
21 
22 public import uefi.bind;
23 
24 public:
25 extern (C):
26 
27 /// Placeholder bitfields implementation, to be fixed
28 template bitfields(T...)
29 {
30 	enum string bitfields = T[0].stringof ~ " bitfield_niy;";
31 }
32 
33 /// 128 bit buffer containing a unique identifier value.
34 /// Unless otherwise specified, aligned on a 64 bit boundary.
35 struct GUID
36 {
37     UINT32 Data1;
38     UINT16 Data2;
39     UINT16 Data3;
40     UINT8[8] Data4;
41     this(UINT32 D1, UINT16 D2, UINT16 D3, UINT8[8] D4)
42     {
43         Data1 = D1;
44         Data2 = D2;
45         Data3 = D3;
46         Data4 = D4;
47     }
48 
49     this(UINT32 D1, UINT16 D2, UINT16 D3, UINT8 D4_0, UINT8 D4_1, UINT8 D4_2,
50         UINT8 D4_3, UINT8 D4_4, UINT8 D4_5, UINT8 D4_6, UINT8 D4_7)
51     {
52         Data1 = D1;
53         Data2 = D2;
54         Data3 = D3;
55         Data4[0] = D4_0;
56         Data4[1] = D4_1;
57         Data4[2] = D4_2;
58         Data4[3] = D4_3;
59         Data4[4] = D4_4;
60         Data4[5] = D4_5;
61         Data4[6] = D4_6;
62         Data4[7] = D4_7;
63     }
64 }
65 
66 /// 8-bytes unsigned value that represents a physical system address.
67 alias PHYSICAL_ADDRESS = UINT64;
68 
69 /// LIST_ENTRY structure definition.
70 struct LIST_ENTRY
71 {
72     LIST_ENTRY* ForwardLink;
73     LIST_ENTRY* BackwardLink;
74 }
75 
76 /// Boolean true value.
77 enum BOOLEAN TRUE = 1;
78 
79 /// Boolean false value.
80 enum BOOLEAN FALSE = 0;
81 
82 /// 
83 enum : UINT32
84 {
85     BIT0 = 0x00000001,
86     BIT1 = 0x00000002,
87     BIT2 = 0x00000004,
88     BIT3 = 0x00000008,
89     BIT4 = 0x00000010,
90     BIT5 = 0x00000020,
91     BIT6 = 0x00000040,
92     BIT7 = 0x00000080,
93     BIT8 = 0x00000100,
94     BIT9 = 0x00000200,
95     BIT10 = 0x00000400,
96     BIT11 = 0x00000800,
97     BIT12 = 0x00001000,
98     BIT13 = 0x00002000,
99     BIT14 = 0x00004000,
100     BIT15 = 0x00008000,
101     BIT16 = 0x00010000,
102     BIT17 = 0x00020000,
103     BIT18 = 0x00040000,
104     BIT19 = 0x00080000,
105     BIT20 = 0x00100000,
106     BIT21 = 0x00200000,
107     BIT22 = 0x00400000,
108     BIT23 = 0x00800000,
109     BIT24 = 0x01000000,
110     BIT25 = 0x02000000,
111     BIT26 = 0x04000000,
112     BIT27 = 0x08000000,
113     BIT28 = 0x10000000,
114     BIT29 = 0x20000000,
115     BIT30 = 0x40000000,
116     BIT31 = 0x80000000,
117 
118     SIZE_1KB = 0x00000400,
119     SIZE_2KB = 0x00000800,
120     SIZE_4KB = 0x00001000,
121     SIZE_8KB = 0x00002000,
122     SIZE_16KB = 0x00004000,
123     SIZE_32KB = 0x00008000,
124     SIZE_64KB = 0x00010000,
125     SIZE_128KB = 0x00020000,
126     SIZE_256KB = 0x00040000,
127     SIZE_512KB = 0x00080000,
128     SIZE_1MB = 0x00100000,
129     SIZE_2MB = 0x00200000,
130     SIZE_4MB = 0x00400000,
131     SIZE_8MB = 0x00800000,
132     SIZE_16MB = 0x01000000,
133     SIZE_32MB = 0x02000000,
134     SIZE_64MB = 0x04000000,
135     SIZE_128MB = 0x08000000,
136     SIZE_256MB = 0x10000000,
137     SIZE_512MB = 0x20000000,
138     SIZE_1GB = 0x40000000,
139     SIZE_2GB = 0x80000000,
140 
141     BASE_1KB = 0x00000400,
142     BASE_2KB = 0x00000800,
143     BASE_4KB = 0x00001000,
144     BASE_8KB = 0x00002000,
145     BASE_16KB = 0x00004000,
146     BASE_32KB = 0x00008000,
147     BASE_64KB = 0x00010000,
148     BASE_128KB = 0x00020000,
149     BASE_256KB = 0x00040000,
150     BASE_512KB = 0x00080000,
151     BASE_1MB = 0x00100000,
152     BASE_2MB = 0x00200000,
153     BASE_4MB = 0x00400000,
154     BASE_8MB = 0x00800000,
155     BASE_16MB = 0x01000000,
156     BASE_32MB = 0x02000000,
157     BASE_64MB = 0x04000000,
158     BASE_128MB = 0x08000000,
159     BASE_256MB = 0x10000000,
160     BASE_512MB = 0x20000000,
161     BASE_1GB = 0x40000000,
162     BASE_2GB = 0x80000000
163 }
164 /// ditto
165 enum : UINT64
166 {
167     BIT32 = 0x0000000100000000UL,
168     BIT33 = 0x0000000200000000UL,
169     BIT34 = 0x0000000400000000UL,
170     BIT35 = 0x0000000800000000UL,
171     BIT36 = 0x0000001000000000UL,
172     BIT37 = 0x0000002000000000UL,
173     BIT38 = 0x0000004000000000UL,
174     BIT39 = 0x0000008000000000UL,
175     BIT40 = 0x0000010000000000UL,
176     BIT41 = 0x0000020000000000UL,
177     BIT42 = 0x0000040000000000UL,
178     BIT43 = 0x0000080000000000UL,
179     BIT44 = 0x0000100000000000UL,
180     BIT45 = 0x0000200000000000UL,
181     BIT46 = 0x0000400000000000UL,
182     BIT47 = 0x0000800000000000UL,
183     BIT48 = 0x0001000000000000UL,
184     BIT49 = 0x0002000000000000UL,
185     BIT50 = 0x0004000000000000UL,
186     BIT51 = 0x0008000000000000UL,
187     BIT52 = 0x0010000000000000UL,
188     BIT53 = 0x0020000000000000UL,
189     BIT54 = 0x0040000000000000UL,
190     BIT55 = 0x0080000000000000UL,
191     BIT56 = 0x0100000000000000UL,
192     BIT57 = 0x0200000000000000UL,
193     BIT58 = 0x0400000000000000UL,
194     BIT59 = 0x0800000000000000UL,
195     BIT60 = 0x1000000000000000UL,
196     BIT61 = 0x2000000000000000UL,
197     BIT62 = 0x4000000000000000UL,
198     BIT63 = 0x8000000000000000UL,
199 
200     SIZE_4GB = 0x0000000100000000UL,
201     SIZE_8GB = 0x0000000200000000UL,
202     SIZE_16GB = 0x0000000400000000UL,
203     SIZE_32GB = 0x0000000800000000UL,
204     SIZE_64GB = 0x0000001000000000UL,
205     SIZE_128GB = 0x0000002000000000UL,
206     SIZE_256GB = 0x0000004000000000UL,
207     SIZE_512GB = 0x0000008000000000UL,
208     SIZE_1TB = 0x0000010000000000UL,
209     SIZE_2TB = 0x0000020000000000UL,
210     SIZE_4TB = 0x0000040000000000UL,
211     SIZE_8TB = 0x0000080000000000UL,
212     SIZE_16TB = 0x0000100000000000UL,
213     SIZE_32TB = 0x0000200000000000UL,
214     SIZE_64TB = 0x0000400000000000UL,
215     SIZE_128TB = 0x0000800000000000UL,
216     SIZE_256TB = 0x0001000000000000UL,
217     SIZE_512TB = 0x0002000000000000UL,
218     SIZE_1PB = 0x0004000000000000UL,
219     SIZE_2PB = 0x0008000000000000UL,
220     SIZE_4PB = 0x0010000000000000UL,
221     SIZE_8PB = 0x0020000000000000UL,
222     SIZE_16PB = 0x0040000000000000UL,
223     SIZE_32PB = 0x0080000000000000UL,
224     SIZE_64PB = 0x0100000000000000UL,
225     SIZE_128PB = 0x0200000000000000UL,
226     SIZE_256PB = 0x0400000000000000UL,
227     SIZE_512PB = 0x0800000000000000UL,
228     SIZE_1EB = 0x1000000000000000UL,
229     SIZE_2EB = 0x2000000000000000UL,
230     SIZE_4EB = 0x4000000000000000UL,
231     SIZE_8EB = 0x8000000000000000UL,
232 
233     BASE_4GB = 0x0000000100000000UL,
234     BASE_8GB = 0x0000000200000000UL,
235     BASE_16GB = 0x0000000400000000UL,
236     BASE_32GB = 0x0000000800000000UL,
237     BASE_64GB = 0x0000001000000000UL,
238     BASE_128GB = 0x0000002000000000UL,
239     BASE_256GB = 0x0000004000000000UL,
240     BASE_512GB = 0x0000008000000000UL,
241     BASE_1TB = 0x0000010000000000UL,
242     BASE_2TB = 0x0000020000000000UL,
243     BASE_4TB = 0x0000040000000000UL,
244     BASE_8TB = 0x0000080000000000UL,
245     BASE_16TB = 0x0000100000000000UL,
246     BASE_32TB = 0x0000200000000000UL,
247     BASE_64TB = 0x0000400000000000UL,
248     BASE_128TB = 0x0000800000000000UL,
249     BASE_256TB = 0x0001000000000000UL,
250     BASE_512TB = 0x0002000000000000UL,
251     BASE_1PB = 0x0004000000000000UL,
252     BASE_2PB = 0x0008000000000000UL,
253     BASE_4PB = 0x0010000000000000UL,
254     BASE_8PB = 0x0020000000000000UL,
255     BASE_16PB = 0x0040000000000000UL,
256     BASE_32PB = 0x0080000000000000UL,
257     BASE_64PB = 0x0100000000000000UL,
258     BASE_128PB = 0x0200000000000000UL,
259     BASE_256PB = 0x0400000000000000UL,
260     BASE_512PB = 0x0800000000000000UL,
261     BASE_1EB = 0x1000000000000000UL,
262     BASE_2EB = 0x2000000000000000UL,
263     BASE_4EB = 0x4000000000000000UL,
264     BASE_8EB = 0x8000000000000000UL
265 }
266 
267 /// Variable used to traverse the list of arguments. This type can vary by
268 /// implementation and could be an array or structure.
269 alias VA_LIST = ubyte*;
270 
271 /// Pointer to the start of a variable argument list stored in a memory buffer. Same as UINT8 *.
272 alias BASE_LIST = UINTN*;
273 
274 /**
275   Rounds a value up to the next boundary using a specified alignment.
276 
277   This function rounds Value up to the next boundary using the specified Alignment.
278   This aligned value is returned.
279 
280   Params:
281      Value     = The value to round up.
282      Alignment = The alignment boundary used to return the aligned value.
283 
284   Returns:  A value up to the next boundary.
285 
286 **/
287 auto ALIGN_VALUE(T)(T Value, T Alignment)
288 {
289     return ((Value) + (((Alignment) - (Value)) & ((Alignment) - 1)));
290 }
291 
292 /**
293   Adjust a pointer by adding the minimum offset required for it to be aligned on
294   a specified alignment boundary.
295 
296   This function rounds the pointer specified by Pointer to the next alignment boundary
297   specified by Alignment. The pointer to the aligned address is returned.
298 
299   Params:
300      Pointer    The pointer to round up.
301      Alignment  The alignment boundary to use to return an aligned pointer.
302 
303   Returns:  Pointer to the aligned address.
304 
305 **/
306 T* ALIGN_POINTER(T)(T* Pointer, INTN Alignment)
307 {
308     return (cast(VOID*)(ALIGN_VALUE(cast(UINTN)(Pointer), (Alignment))));
309 }
310 
311 /**
312   Rounds a value up to the next natural boundary for the current CPU.
313   This is 4-bytes for 32-bit CPUs and 8-bytes for 64-bit CPUs.
314 
315   This function rounds the value specified by Value up to the next natural boundary for the
316   current CPU. This rounded value is returned.
317 
318   @param   Value      The value to round up.
319 
320   @return  Rounded value specified by Value.
321 
322 **/
323 auto ALIGN_VARIABLE(T)(T Value)
324 {
325     return ALIGN_VALUE((Value), UINTN.sizeof);
326 }
327 
328 /**
329   Return the maximum of two operands.
330 
331   Params:
332      a     =   The first operand with any numerical type.
333      b     =   The second operand.
334 
335   Returns:  Maximum of two operands.
336 
337 **/
338 auto MAX(T, U)(T A, U B)
339 {
340     return (A > B) ? A : B;
341 }
342 
343 /**
344   Return the minimum of two operands.
345 
346   Params:
347      a     =   The first operand with any numerical type.
348      b     =   The second operand.
349 
350   Returns:  Minimum of two operands.
351 
352 **/
353 auto MIN(T, U)(T A, U B)
354 {
355     return (A < B) ? A : B;
356 }
357 
358 /**
359   Return the absolute value of a signed operand.
360 
361   Params:
362      a     =   The signed operand.
363 
364   Returns:  The absolute value of the signed operand.
365 
366 **/
367 auto ABS(T)(T A)
368 {
369     return (A < 0) ? (-A) : (A);
370 }
371 
372 /// Status codes common to all execution phases
373 alias RETURN_STATUS = UINTN;
374 
375 /**
376   Returns true if a specified RETURN_STATUS code is an error code.
377 
378   This function returns TRUE if StatusCode has the high bit set.  Otherwise, false is returned.
379 
380   Params:
381     StatusCode  =  The status code value to evaluate.
382 
383   Returns: true if         The high bit of StatusCode is set.
384    false if        The high bit of StatusCode is clear.
385 
386 **/
387 bool RETURN_ERROR(T)(T StatusCode)
388 {
389     return cast(INTN)(cast(RETURN_STATUS)(StatusCode)) < 0;
390 }
391 
392 /**
393   Produces a RETURN_STATUS code with the highest bit set.
394 
395   Params:
396     StatusCode  =  The status code value to convert into a warning code.
397                    StatusCode must be in the range 0x00000000..0x7FFFFFFF.
398 
399   Returns: The value specified by StatusCode with the highest bit set.
400 
401 **/
402 template ENCODE_ERROR(UINTN StatusCode)
403 {
404     enum RETURN_STATUS ENCODE_ERROR = StatusCode | MAX_BIT;
405 }
406 
407 /**
408   Produces a RETURN_STATUS code with the highest bit clear.
409 
410   Params:
411     StatusCode  =  The status code value to convert into a warning code.
412                    StatusCode must be in the range 0x00000000..0x7FFFFFFF.
413 
414   Returns: The value specified by StatusCode with the highest bit clear.
415 
416 **/
417 template ENCODE_WARNING(UINTN StatusCode)
418 {
419     enum RETURN_STATUS ENCODE_WARNING = StatusCode | MAX_BIT;
420 }
421 
422 /// Return status codes
423 enum : RETURN_STATUS
424 {
425 
426     ///
427     /// The operation completed successfully.
428     ///
429     RETURN_SUCCESS = 0,
430     ///
431     /// The image failed to load.
432     ///
433     RETURN_LOAD_ERROR = ENCODE_ERROR!(1),
434 
435     ///
436     /// The parameter was incorrect.
437     ///
438     RETURN_INVALID_PARAMETER = ENCODE_ERROR!(2),
439 
440     ///
441     /// The operation is not supported.
442     ///
443     RETURN_UNSUPPORTED = ENCODE_ERROR!(3),
444 
445     ///
446     /// The buffer was not the proper size for the request.
447     ///
448     RETURN_BAD_BUFFER_SIZE = ENCODE_ERROR!(4),
449 
450     ///
451     /// The buffer was not large enough to hold the requested data.
452     /// The required buffer size is returned in the appropriate
453     /// parameter when this error occurs.
454     ///
455     RETURN_BUFFER_TOO_SMALL = ENCODE_ERROR!(5),
456 
457     ///
458     /// There is no data pending upon return.
459     ///
460     RETURN_NOT_READY = ENCODE_ERROR!(6),
461 
462     ///
463     /// The physical device reported an error while attempting the
464     /// operation.
465     ///
466     RETURN_DEVICE_ERROR = ENCODE_ERROR!(7),
467 
468     ///
469     /// The device can not be written to.
470     ///
471     RETURN_WRITE_PROTECTED = ENCODE_ERROR!(8),
472 
473     ///
474     /// The resource has run out.
475     ///
476     RETURN_OUT_OF_RESOURCES = ENCODE_ERROR!(9),
477 
478     ///
479     /// An inconsistency was detected on the file system causing the
480     /// operation to fail.
481     ///
482     RETURN_VOLUME_CORRUPTED = ENCODE_ERROR!(10),
483 
484     ///
485     /// There is no more space on the file system.
486     ///
487     RETURN_VOLUME_FULL = ENCODE_ERROR!(11),
488 
489     ///
490     /// The device does not contain any medium to perform the
491     /// operation.
492     ///
493     RETURN_NO_MEDIA = ENCODE_ERROR!(12),
494 
495     ///
496     /// The medium in the device has changed since the last
497     /// access.
498     ///
499     RETURN_MEDIA_CHANGED = ENCODE_ERROR!(13),
500 
501     ///
502     /// The item was not found.
503     ///
504     RETURN_NOT_FOUND = ENCODE_ERROR!(14),
505 
506     ///
507     /// Access was denied.
508     ///
509     RETURN_ACCESS_DENIED = ENCODE_ERROR!(15),
510 
511     ///
512     /// The server was not found or did not respond to the request.
513     ///
514     RETURN_NO_RESPONSE = ENCODE_ERROR!(16),
515 
516     ///
517     /// A mapping to the device does not exist.
518     ///
519     RETURN_NO_MAPPING = ENCODE_ERROR!(17),
520 
521     ///
522     /// A timeout time expired.
523     ///
524     RETURN_TIMEOUT = ENCODE_ERROR!(18),
525 
526     ///
527     /// The protocol has not been started.
528     ///
529     RETURN_NOT_STARTED = ENCODE_ERROR!(19),
530 
531     ///
532     /// The protocol has already been started.
533     ///
534     RETURN_ALREADY_STARTED = ENCODE_ERROR!(20),
535 
536     ///
537     /// The operation was aborted.
538     ///
539     RETURN_ABORTED = ENCODE_ERROR!(21),
540 
541     ///
542     /// An ICMP error occurred during the network operation.
543     ///
544     RETURN_ICMP_ERROR = ENCODE_ERROR!(22),
545 
546     ///
547     /// A TFTP error occurred during the network operation.
548     ///
549     RETURN_TFTP_ERROR = ENCODE_ERROR!(23),
550 
551     ///
552     /// A protocol error occurred during the network operation.
553     ///
554     RETURN_PROTOCOL_ERROR = ENCODE_ERROR!(24),
555 
556     ///
557     /// A function encountered an internal version that was
558     /// incompatible with a version requested by the caller.
559     ///
560     RETURN_INCOMPATIBLE_VERSION = ENCODE_ERROR!(25),
561 
562     ///
563     /// The function was not performed due to a security violation.
564     ///
565     RETURN_SECURITY_VIOLATION = ENCODE_ERROR!(26),
566 
567     ///
568     /// A CRC error was detected.
569     ///
570     RETURN_CRC_ERROR = ENCODE_ERROR!(27),
571 
572     ///
573     /// The beginning or end of media was reached.
574     ///
575     RETURN_END_OF_MEDIA = ENCODE_ERROR!(28),
576 
577     ///
578     /// The end of the file was reached.
579     ///
580     RETURN_END_OF_FILE = ENCODE_ERROR!(31),
581 
582     ///
583     /// The language specified was invalid.
584     ///
585     RETURN_INVALID_LANGUAGE = ENCODE_ERROR!(32),
586 
587     ///
588     /// The security status of the data is unknown or compromised
589     /// and the data must be updated or replaced to restore a valid
590     /// security status.
591     ///
592     RETURN_COMPROMISED_DATA = ENCODE_ERROR!(33),
593 
594     ///
595     /// The string contained one or more characters that
596     /// the device could not render and were skipped.
597     ///
598     RETURN_WARN_UNKNOWN_GLYPH = ENCODE_WARNING!(1),
599 
600     ///
601     /// The handle was closed, but the file was not deleted.
602     ///
603     RETURN_WARN_DELETE_FAILURE = ENCODE_WARNING!(2),
604 
605     ///
606     /// The handle was closed, but the data to the file was not
607     /// flushed properly.
608     ///
609     RETURN_WARN_WRITE_FAILURE = ENCODE_WARNING!(3),
610 
611     ///
612     /// The resulting buffer was too small, and the data was
613     /// truncated to the buffer size.
614     ///
615     RETURN_WARN_BUFFER_TOO_SMALL = ENCODE_WARNING!(4),
616 
617     ///
618     /// The data has not been updated within the timeframe set by
619     /// local policy for this type of data.
620     ///
621     RETURN_WARN_STALE_DATA = ENCODE_WARNING!(5),
622 
623 }
624 
625 /**
626   Returns a 16-bit signature built from 2 ASCII characters.
627 
628   This macro returns a 16-bit value built from the two ASCII characters specified
629   by A and B.
630 
631   Params:
632     A =   The first ASCII character.
633     B =   The second ASCII character.
634 
635   Returns: A 16-bit value built from the two ASCII characters specified by A and B.
636 
637 **/
638 auto SIGNATURE_16(T)(T A, T B)
639 {
640     return ((A) | (B << 8));
641 }
642 
643 /**
644   Returns a 32-bit signature built from 2 ASCII characters.
645 
646   This macro returns a 32-bit value built from the four ASCII characters specified
647   by A, B, C, and D.
648 
649   Params:
650     A =   The first ASCII character.
651     B =   The second ASCII character.
652 	C =   The third ASCII character.
653 	D =   The fourth ASCII character.
654 
655   Returns: A 32-bit value built from the two ASCII characters specified by A, B, C and D.
656 
657 **/
658 auto SIGNATURE_32(T)(T A, T B, T C, T D)
659 {
660     return (SIGNATURE_16(A, B) | (SIGNATURE_16(C, D) << 16));
661 }
662 
663 /**
664   Returns a 64-bit signature built from 8 ASCII characters.
665 
666   This macro returns a 64-bit value built from the eight ASCII characters specified
667   by A, B, C, D, E, F, G,and H.
668 
669   Params:
670     A  =  The first ASCII character.
671     B  =  The second ASCII character.
672     C  =  The third ASCII character.
673     D  =  The fourth ASCII character.
674     E  =  The fifth ASCII character.
675     F  =  The sixth ASCII character.
676     G  =  The seventh ASCII character.
677     H  =  The eighth ASCII character.
678 
679   Returns: A 64-bit value built from the two ASCII characters specified by A, B,
680           C, D, E, F, G and H.
681 
682 **/
683 auto SIGNATURE_64(T)(T A, T B, T C, T D, T E, T F, T G, T H)
684 {
685     return (SIGNATURE_32(A, B, C, D) | (cast(UINT64)(SIGNATURE_32(E, F, G, H)) << 32));
686 }