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