1 /*
2  * Copright (C) 2014 - 2015 Linaro Ltd.
3  * Author: Ard Biesheuvel <ard.biesheuvel@linaro.org>
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice and this list of conditions, without modification.
10  * 2. The name of the author may not be used to endorse or promote products
11  *    derived from this software without specific prior written permission.
12  *
13  * Alternatively, this software may be distributed under the terms of the
14  * GNU General Public License as published by the Free Software Foundation;
15  * either version 2 of the License, or (at your option) any later version.
16  */
17 
18 #include <stdint.h>
19 
20 //
21 // Basic EFI types of various widths
22 //
23 
24 
25 
26 typedef uint64_t                UINT64;
27 typedef int64_t                 INT64;
28 typedef uint32_t                UINT32;
29 typedef int32_t                 INT32;
30 typedef uint16_t                UINT16;
31 typedef int16_t                 INT16;
32 typedef uint8_t                 UINT8;
33 typedef int8_t                  INT8;
34 #ifndef __WCHAR_TYPE__
35 #define __WCHAR_TYPE__          short
36 #endif
37 typedef __WCHAR_TYPE__          WCHAR;
38 #ifndef BOOLEAN
39 typedef uint8_t                 BOOLEAN;
40 #endif
41 #undef VOID
42 #define VOID                    void
43 typedef int64_t                 INTN;
44 typedef uint64_t                UINTN;
45 
46 #define EFI_ERROR_MASK          0x8000000000000000
47 #define EFIERR(a)               (EFI_ERROR_MASK | a)
48 #define EFIERR_OEM(a)           (0xc000000000000000 | a)
49 
50 #define BAD_POINTER             0xFBFBFBFBFBFBFBFB
51 #define MAX_ADDRESS             0xFFFFFFFFFFFFFFFF
52 
53 #define BREAKPOINT()            while(1);
54 
55 //
56 // Pointers must be aligned to these address to function
57 //
58 #define MIN_ALIGNMENT_SIZE      8
59 
60 #define ALIGN_VARIABLE(Value, Adjustment) \
61    (UINTN)Adjustment = 0; \
62    if((UINTN)Value % MIN_ALIGNMENT_SIZE) \
63        (UINTN)Adjustment = MIN_ALIGNMENT_SIZE - ((UINTN)Value % MIN_ALIGNMENT_SIZE); \
64    Value = (UINTN)Value + (UINTN)Adjustment
65 
66 //
67 // Define macros to build data structure signatures from characters.
68 //
69 #define EFI_SIGNATURE_16(A,B)             ((A) | (B<<8))
70 #define EFI_SIGNATURE_32(A,B,C,D)         (EFI_SIGNATURE_16(A,B)     | (EFI_SIGNATURE_16(C,D)     << 16))
71 #define EFI_SIGNATURE_64(A,B,C,D,E,F,G,H) (EFI_SIGNATURE_32(A,B,C,D) | ((UINT64)(EFI_SIGNATURE_32(E,F,G,H)) << 32))
72 
73 //
74 // EFIAPI - prototype calling convention for EFI function pointers
75 // BOOTSERVICE - prototype for implementation of a boot service interface
76 // RUNTIMESERVICE - prototype for implementation of a runtime service interface
77 // RUNTIMEFUNCTION - prototype for implementation of a runtime function that is not a service
78 // RUNTIME_CODE - pragma macro for declaring runtime code
79 //
80 #ifndef EFIAPI                  // Forces EFI calling conventions reguardless of compiler options
81 #define EFIAPI                  // Substitute expresion to force C calling convention
82 #endif
83 #define BOOTSERVICE
84 #define RUNTIMESERVICE
85 #define RUNTIMEFUNCTION
86 #define RUNTIME_CODE(a)         alloc_text("rtcode", a)
87 #define BEGIN_RUNTIME_DATA()    data_seg("rtdata")
88 #define END_RUNTIME_DATA()      data_seg("")
89 
90 #define VOLATILE                volatile
91 #define MEMORY_FENCE            __sync_synchronize
92 
93 //
94 // When build similiar to FW, then link everything together as
95 // one big module. For the MSVC toolchain, we simply tell the
96 // linker what our driver init function is using /ENTRY.
97 //
98 #if defined(_MSC_EXTENSIONS)
99 #define EFI_DRIVER_ENTRY_POINT(InitFunction) \
100     __pragma(comment(linker, "/ENTRY:" # InitFunction))
101 #else
102 #define EFI_DRIVER_ENTRY_POINT(InitFunction)    \
103     UINTN                                       \
104     InitializeDriver (                          \
105         VOID    *ImageHandle,                   \
106         VOID    *SystemTable                    \
107         )                                       \
108     {                                           \
109         return InitFunction(ImageHandle,        \
110                 SystemTable);                   \
111     }                                           \
112                                                 \
113     EFI_STATUS efi_main(                        \
114         EFI_HANDLE image,                       \
115         EFI_SYSTEM_TABLE *systab                \
116         ) __attribute__((weak,                  \
117                 alias ("InitializeDriver")));
118 #endif
119 
120 #define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \
121    (_if)->LoadInternal(type, name, entry)
122 
123 //
124 // Some compilers don't support the forward reference construct:
125 //  typedef struct XXXXX
126 //
127 // The following macro provide a workaround for such cases.
128 #define INTERFACE_DECL(x)       struct x
129 
130 #define uefi_call_wrapper(func, va_num, ...) func(__VA_ARGS__)
131 #define EFI_FUNCTION
132