Home | History | Annotate | Download | only in x86_64
      1 /*++
      2 
      3 Copyright (c) 1998  Intel Corporation
      4 
      5 Module Name:
      6 
      7     efefind.h
      8 
      9 Abstract:
     10 
     11     EFI to compile bindings
     12 
     13 
     14 
     15 
     16 Revision History
     17 
     18 --*/
     19 #ifndef X86_64_EFI_BIND
     20 #define X86_64_EFI_BIND
     21 #ifndef __GNUC__
     22 #pragma pack()
     23 #endif
     24 
     25 #if defined(GNU_EFI_USE_MS_ABI)
     26     #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))
     27         #define HAVE_USE_MS_ABI 1
     28     #else
     29         #error Compiler is too old for GNU_EFI_USE_MS_ABI
     30     #endif
     31 #endif
     32 
     33 //
     34 // Basic int types of various widths
     35 //
     36 
     37 #if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L )
     38 
     39     // No ANSI C 1999/2000 stdint.h integer width declarations
     40 
     41     #if defined(_MSC_EXTENSIONS)
     42 
     43         // Use Microsoft C compiler integer width declarations
     44 
     45         typedef unsigned __int64    uint64_t;
     46         typedef __int64             int64_t;
     47         typedef unsigned __int32    uint32_t;
     48         typedef __int32             int32_t;
     49         typedef unsigned short      uint16_t;
     50         typedef short               int16_t;
     51         typedef unsigned char       uint8_t;
     52         typedef char                int8_t;
     53     #elif defined(__GNUC__)
     54         typedef int __attribute__((__mode__(__DI__)))           int64_t;
     55         typedef unsigned int __attribute__((__mode__(__DI__)))  uint64_t;
     56         typedef unsigned int        uint32_t;
     57         typedef int                 int32_t;
     58         typedef unsigned short      uint16_t;
     59         typedef short               int16_t;
     60         typedef unsigned char       uint8_t;
     61         typedef signed char         int8_t;
     62     #elif defined(UNIX_LP64)
     63 
     64         /*  Use LP64 programming model from C_FLAGS for integer width declarations */
     65 
     66        typedef unsigned long       uint64_t;
     67        typedef long                int64_t;
     68        typedef unsigned int        uint32_t;
     69        typedef int                 int32_t;
     70        typedef unsigned short      uint16_t;
     71        typedef short               int16_t;
     72        typedef unsigned char       uint8_t;
     73        typedef char                int8_t;
     74     #else
     75 
     76        /*  Assume P64 programming model from C_FLAGS for integer width declarations */
     77 
     78        typedef unsigned long long  uint64_t __attribute__((aligned (8)));
     79        typedef long long           int64_t __attribute__((aligned (8)));
     80        typedef unsigned int        uint32_t;
     81        typedef int                 int32_t;
     82        typedef unsigned short      uint16_t;
     83        typedef short               int16_t;
     84        typedef unsigned char       uint8_t;
     85        typedef char                int8_t;
     86     #endif
     87 #elif defined(__GNUC__)
     88     #include <stdint.h>
     89 #endif
     90 
     91 //
     92 // Basic EFI types of various widths
     93 //
     94 
     95 #ifndef __WCHAR_TYPE__
     96 # define __WCHAR_TYPE__ short
     97 #endif
     98 
     99 typedef uint64_t   UINT64;
    100 typedef int64_t    INT64;
    101 
    102 #ifndef _BASETSD_H_
    103     typedef uint32_t   UINT32;
    104     typedef int32_t    INT32;
    105 #endif
    106 
    107 typedef uint16_t   UINT16;
    108 typedef int16_t    INT16;
    109 typedef uint8_t    UINT8;
    110 typedef int8_t     INT8;
    111 typedef __WCHAR_TYPE__ WCHAR;
    112 
    113 #undef VOID
    114 #define VOID    void
    115 
    116 
    117 typedef int64_t    INTN;
    118 typedef uint64_t   UINTN;
    119 
    120 #ifdef EFI_NT_EMULATOR
    121     #define POST_CODE(_Data)
    122 #else
    123     #ifdef EFI_DEBUG
    124 #define POST_CODE(_Data)    __asm mov eax,(_Data) __asm out 0x80,al
    125     #else
    126         #define POST_CODE(_Data)
    127     #endif
    128 #endif
    129 
    130 #define EFIERR(a)           (0x8000000000000000 | a)
    131 #define EFI_ERROR_MASK      0x8000000000000000
    132 #define EFIERR_OEM(a)       (0xc000000000000000 | a)
    133 
    134 
    135 #define BAD_POINTER         0xFBFBFBFBFBFBFBFB
    136 #define MAX_ADDRESS         0xFFFFFFFFFFFFFFFF
    137 
    138 #ifdef EFI_NT_EMULATOR
    139     #define BREAKPOINT()        __asm { int 3 }
    140 #else
    141     #define BREAKPOINT()        while (TRUE);    // Make it hang on Bios[Dbg]32
    142 #endif
    143 
    144 //
    145 // Pointers must be aligned to these address to function
    146 //
    147 
    148 #define MIN_ALIGNMENT_SIZE  4
    149 
    150 #define ALIGN_VARIABLE(Value ,Adjustment) \
    151             (UINTN)Adjustment = 0; \
    152             if((UINTN)Value % MIN_ALIGNMENT_SIZE) \
    153                 (UINTN)Adjustment = MIN_ALIGNMENT_SIZE - ((UINTN)Value % MIN_ALIGNMENT_SIZE); \
    154             Value = (UINTN)Value + (UINTN)Adjustment
    155 
    156 
    157 //
    158 // Define macros to build data structure signatures from characters.
    159 //
    160 
    161 #define EFI_SIGNATURE_16(A,B)             ((A) | (B<<8))
    162 #define EFI_SIGNATURE_32(A,B,C,D)         (EFI_SIGNATURE_16(A,B)     | (EFI_SIGNATURE_16(C,D)     << 16))
    163 #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))
    164 //
    165 // To export & import functions in the EFI emulator environment
    166 //
    167 
    168 #ifdef EFI_NT_EMULATOR
    169     #define EXPORTAPI           __declspec( dllexport )
    170 #else
    171     #define EXPORTAPI
    172 #endif
    173 
    174 
    175 //
    176 // EFIAPI - prototype calling convention for EFI function pointers
    177 // BOOTSERVICE - prototype for implementation of a boot service interface
    178 // RUNTIMESERVICE - prototype for implementation of a runtime service interface
    179 // RUNTIMEFUNCTION - prototype for implementation of a runtime function that is not a service
    180 // RUNTIME_CODE - pragma macro for declaring runtime code
    181 //
    182 
    183 #ifndef EFIAPI                  // Forces EFI calling conventions reguardless of compiler options
    184     #ifdef _MSC_EXTENSIONS
    185         #define EFIAPI __cdecl  // Force C calling convention for Microsoft C compiler
    186     #elif defined(HAVE_USE_MS_ABI)
    187         // Force amd64/ms calling conventions.
    188         #define EFIAPI __attribute__((ms_abi))
    189     #else
    190         #define EFIAPI          // Substitute expresion to force C calling convention
    191     #endif
    192 #endif
    193 
    194 #define BOOTSERVICE
    195 //#define RUNTIMESERVICE(proto,a)    alloc_text("rtcode",a); proto a
    196 //#define RUNTIMEFUNCTION(proto,a)   alloc_text("rtcode",a); proto a
    197 #define RUNTIMESERVICE
    198 #define RUNTIMEFUNCTION
    199 
    200 
    201 #define RUNTIME_CODE(a)         alloc_text("rtcode", a)
    202 #define BEGIN_RUNTIME_DATA()    data_seg("rtdata")
    203 #define END_RUNTIME_DATA()      data_seg("")
    204 
    205 #define VOLATILE    volatile
    206 
    207 #define MEMORY_FENCE()
    208 
    209 #ifdef EFI_NT_EMULATOR
    210 
    211 //
    212 // To help ensure proper coding of integrated drivers, they are
    213 // compiled as DLLs.  In NT they require a dll init entry pointer.
    214 // The macro puts a stub entry point into the DLL so it will load.
    215 //
    216 
    217 #define EFI_DRIVER_ENTRY_POINT(InitFunction)    \
    218     UINTN                                       \
    219     __stdcall                                   \
    220     _DllMainCRTStartup (                        \
    221         UINTN    Inst,                          \
    222         UINTN    reason_for_call,               \
    223         VOID    *rserved                        \
    224         )                                       \
    225     {                                           \
    226         return 1;                               \
    227     }                                           \
    228                                                 \
    229     int                                         \
    230     EXPORTAPI                                   \
    231     __cdecl                                     \
    232     InitializeDriver (                          \
    233         void *ImageHandle,                      \
    234         void *SystemTable                       \
    235         )                                       \
    236     {                                           \
    237         return InitFunction(ImageHandle, SystemTable);       \
    238     }
    239 
    240 
    241     #define LOAD_INTERNAL_DRIVER(_if, type, name, entry)      \
    242         (_if)->LoadInternal(type, name, NULL)
    243 
    244 #else // EFI_NT_EMULATOR
    245 
    246 //
    247 // When build similiar to FW, then link everything together as
    248 // one big module.
    249 //
    250 
    251     #define EFI_DRIVER_ENTRY_POINT(InitFunction)    \
    252         UINTN                                       \
    253         InitializeDriver (                          \
    254             VOID    *ImageHandle,                   \
    255             VOID    *SystemTable                    \
    256             )                                       \
    257         {                                           \
    258             return InitFunction(ImageHandle,        \
    259                     SystemTable);                   \
    260         }                                           \
    261                                                     \
    262         EFI_STATUS efi_main(                        \
    263             EFI_HANDLE image,                       \
    264             EFI_SYSTEM_TABLE *systab                \
    265             ) __attribute__((weak,                  \
    266                     alias ("InitializeDriver")));
    267 
    268     #define LOAD_INTERNAL_DRIVER(_if, type, name, entry)    \
    269             (_if)->LoadInternal(type, name, entry)
    270 
    271 #endif // EFI_FW_NT
    272 
    273 //
    274 // Some compilers don't support the forward reference construct:
    275 //  typedef struct XXXXX
    276 //
    277 // The following macro provide a workaround for such cases.
    278 //
    279 #ifdef NO_INTERFACE_DECL
    280 #define INTERFACE_DECL(x)
    281 #else
    282 #ifdef __GNUC__
    283 #define INTERFACE_DECL(x) struct x
    284 #else
    285 #define INTERFACE_DECL(x) typedef struct x
    286 #endif
    287 #endif
    288 
    289 /* for x86_64, EFI_FUNCTION_WRAPPER must be defined */
    290 #if defined(HAVE_USE_MS_ABI)
    291 #define uefi_call_wrapper(func, va_num, ...) func(__VA_ARGS__)
    292 #else
    293 /*
    294   Credits for macro-magic:
    295     https://groups.google.com/forum/?fromgroups#!topic/comp.std.c/d-6Mj5Lko_s
    296     http://efesx.com/2010/08/31/overloading-macros/
    297 */
    298 #define __VA_NARG__(...)                        \
    299   __VA_NARG_(_0, ## __VA_ARGS__, __RSEQ_N())
    300 #define __VA_NARG_(...)                         \
    301   __VA_ARG_N(__VA_ARGS__)
    302 #define __VA_ARG_N(                             \
    303   _0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,N,...) N
    304 #define __RSEQ_N()                              \
    305   10, 9,  8,  7,  6,  5,  4,  3,  2,  1,  0
    306 
    307 #define __VA_ARG_NSUFFIX__(prefix,...)                  \
    308   __VA_ARG_NSUFFIX_N(prefix, __VA_NARG__(__VA_ARGS__))
    309 #define __VA_ARG_NSUFFIX_N(prefix,nargs)        \
    310   __VA_ARG_NSUFFIX_N_(prefix, nargs)
    311 #define __VA_ARG_NSUFFIX_N_(prefix,nargs)       \
    312   prefix ## nargs
    313 
    314 /* Prototypes of EFI cdecl -> stdcall trampolines */
    315 UINT64 efi_call0(void *func);
    316 UINT64 efi_call1(void *func, UINT64 arg1);
    317 UINT64 efi_call2(void *func, UINT64 arg1, UINT64 arg2);
    318 UINT64 efi_call3(void *func, UINT64 arg1, UINT64 arg2, UINT64 arg3);
    319 UINT64 efi_call4(void *func, UINT64 arg1, UINT64 arg2, UINT64 arg3,
    320                  UINT64 arg4);
    321 UINT64 efi_call5(void *func, UINT64 arg1, UINT64 arg2, UINT64 arg3,
    322                  UINT64 arg4, UINT64 arg5);
    323 UINT64 efi_call6(void *func, UINT64 arg1, UINT64 arg2, UINT64 arg3,
    324                  UINT64 arg4, UINT64 arg5, UINT64 arg6);
    325 UINT64 efi_call7(void *func, UINT64 arg1, UINT64 arg2, UINT64 arg3,
    326                  UINT64 arg4, UINT64 arg5, UINT64 arg6, UINT64 arg7);
    327 UINT64 efi_call8(void *func, UINT64 arg1, UINT64 arg2, UINT64 arg3,
    328                  UINT64 arg4, UINT64 arg5, UINT64 arg6, UINT64 arg7,
    329                  UINT64 arg8);
    330 UINT64 efi_call9(void *func, UINT64 arg1, UINT64 arg2, UINT64 arg3,
    331                  UINT64 arg4, UINT64 arg5, UINT64 arg6, UINT64 arg7,
    332                  UINT64 arg8, UINT64 arg9);
    333 UINT64 efi_call10(void *func, UINT64 arg1, UINT64 arg2, UINT64 arg3,
    334                   UINT64 arg4, UINT64 arg5, UINT64 arg6, UINT64 arg7,
    335                   UINT64 arg8, UINT64 arg9, UINT64 arg10);
    336 
    337 /* Front-ends to efi_callX to avoid compiler warnings */
    338 #define _cast64_efi_call0(f) \
    339   efi_call0(f)
    340 #define _cast64_efi_call1(f,a1) \
    341   efi_call1(f, (UINT64)(a1))
    342 #define _cast64_efi_call2(f,a1,a2) \
    343   efi_call2(f, (UINT64)(a1), (UINT64)(a2))
    344 #define _cast64_efi_call3(f,a1,a2,a3) \
    345   efi_call3(f, (UINT64)(a1), (UINT64)(a2), (UINT64)(a3))
    346 #define _cast64_efi_call4(f,a1,a2,a3,a4) \
    347   efi_call4(f, (UINT64)(a1), (UINT64)(a2), (UINT64)(a3), (UINT64)(a4))
    348 #define _cast64_efi_call5(f,a1,a2,a3,a4,a5) \
    349   efi_call5(f, (UINT64)(a1), (UINT64)(a2), (UINT64)(a3), (UINT64)(a4), \
    350             (UINT64)(a5))
    351 #define _cast64_efi_call6(f,a1,a2,a3,a4,a5,a6) \
    352   efi_call6(f, (UINT64)(a1), (UINT64)(a2), (UINT64)(a3), (UINT64)(a4), \
    353             (UINT64)(a5), (UINT64)(a6))
    354 #define _cast64_efi_call7(f,a1,a2,a3,a4,a5,a6,a7) \
    355   efi_call7(f, (UINT64)(a1), (UINT64)(a2), (UINT64)(a3), (UINT64)(a4), \
    356             (UINT64)(a5), (UINT64)(a6), (UINT64)(a7))
    357 #define _cast64_efi_call8(f,a1,a2,a3,a4,a5,a6,a7,a8) \
    358   efi_call8(f, (UINT64)(a1), (UINT64)(a2), (UINT64)(a3), (UINT64)(a4), \
    359             (UINT64)(a5), (UINT64)(a6), (UINT64)(a7), (UINT64)(a8))
    360 #define _cast64_efi_call9(f,a1,a2,a3,a4,a5,a6,a7,a8,a9) \
    361   efi_call9(f, (UINT64)(a1), (UINT64)(a2), (UINT64)(a3), (UINT64)(a4), \
    362             (UINT64)(a5), (UINT64)(a6), (UINT64)(a7), (UINT64)(a8), \
    363             (UINT64)(a9))
    364 #define _cast64_efi_call10(f,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) \
    365   efi_call10(f, (UINT64)(a1), (UINT64)(a2), (UINT64)(a3), (UINT64)(a4), \
    366              (UINT64)(a5), (UINT64)(a6), (UINT64)(a7), (UINT64)(a8), \
    367              (UINT64)(a9), (UINT64)(a10))
    368 
    369 /* main wrapper (va_num ignored) */
    370 #define uefi_call_wrapper(func,va_num,...)                        \
    371   __VA_ARG_NSUFFIX__(_cast64_efi_call, __VA_ARGS__) (func , ##__VA_ARGS__)
    372 
    373 #endif
    374 #define EFI_FUNCTION __attribute__((ms_abi))
    375 
    376 #ifdef _MSC_EXTENSIONS
    377 #pragma warning ( disable : 4731 )  // Suppress warnings about modification of EBP
    378 #endif
    379 
    380 #endif
    381