1 /*++ 2 3 Copyright (c) 1998 Intel Corporation 4 5 Module Name: 6 7 8 Abstract: 9 10 11 12 13 Revision History 14 15 --*/ 16 17 #include "lib.h" 18 19 VOID EFIDebugVariable(VOID); 20 21 VOID InitializeLib(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable) 22 /*++ 23 24 Routine Description: 25 26 Initializes EFI library for use 27 28 Arguments: 29 30 Firmware's EFI system table 31 32 Returns: 33 34 None 35 36 --*/ 37 { 38 EFI_LOADED_IMAGE *LoadedImage; 39 EFI_STATUS Status; 40 CHAR8 *LangCode; 41 42 if (LibInitialized) 43 return; 44 45 LibInitialized = TRUE; 46 LibFwInstance = FALSE; 47 LibImageHandle = ImageHandle; 48 49 // 50 // Set up global pointer to the system table, boot services table, 51 // and runtime services table 52 // 53 54 ST = SystemTable; 55 BS = SystemTable->BootServices; 56 RT = SystemTable->RuntimeServices; 57 // ASSERT (CheckCrc(0, &ST->Hdr)); 58 // ASSERT (CheckCrc(0, &BS->Hdr)); 59 // ASSERT (CheckCrc(0, &RT->Hdr)); 60 61 // 62 // Initialize pool allocation type 63 // 64 65 if (ImageHandle) { 66 Status = uefi_call_wrapper(BS->HandleProtocol, 3, ImageHandle, 67 &LoadedImageProtocol, 68 (VOID *)&LoadedImage); 69 70 if (!EFI_ERROR(Status)) { 71 PoolAllocationType = LoadedImage->ImageDataType; 72 } 73 EFIDebugVariable(); 74 } 75 76 // 77 // Initialize Guid table 78 // 79 80 InitializeGuid(); 81 82 InitializeLibPlatform(ImageHandle, SystemTable); 83 84 if (ImageHandle && UnicodeInterface == &LibStubUnicodeInterface) { 85 LangCode = LibGetVariable(VarLanguage, &EfiGlobalVariable); 86 InitializeUnicodeSupport(LangCode); 87 if (LangCode) { 88 FreePool(LangCode); 89 } 90 } 91 } 92 93 VOID InitializeUnicodeSupport(CHAR8 *LangCode) 94 { 95 EFI_UNICODE_COLLATION_INTERFACE *Ui; 96 EFI_STATUS Status; 97 CHAR8 *Languages; 98 UINTN Index, Position, Length; 99 UINTN NoHandles; 100 EFI_HANDLE *Handles; 101 102 // 103 // If we don't know it, lookup the current language code 104 // 105 106 LibLocateHandle(ByProtocol, &UnicodeCollationProtocol, NULL, &NoHandles, 107 &Handles); 108 if (!LangCode || !NoHandles) { 109 goto Done; 110 } 111 112 // 113 // Check all driver's for a matching language code 114 // 115 116 for (Index = 0; Index < NoHandles; Index++) { 117 Status = uefi_call_wrapper(BS->HandleProtocol, 3, 118 Handles[Index], 119 &UnicodeCollationProtocol, 120 (VOID *)&Ui); 121 if (EFI_ERROR(Status)) { 122 continue; 123 } 124 125 // 126 // Check for a matching language code 127 // 128 129 Languages = Ui->SupportedLanguages; 130 Length = strlena(Languages); 131 for (Position = 0; Position < Length; 132 Position += ISO_639_2_ENTRY_SIZE) { 133 // 134 // If this code matches, use this driver 135 // 136 137 if (CompareMem(Languages + Position, LangCode, 138 ISO_639_2_ENTRY_SIZE) == 0) { 139 UnicodeInterface = Ui; 140 goto Done; 141 } 142 } 143 } 144 145 Done: 146 // 147 // Cleanup 148 // 149 150 if (Handles) { 151 FreePool(Handles); 152 } 153 } 154 155 VOID EFIDebugVariable(VOID) 156 { 157 EFI_STATUS Status; 158 UINT32 Attributes; 159 UINTN DataSize; 160 UINTN NewEFIDebug; 161 162 DataSize = sizeof(EFIDebug); 163 Status = uefi_call_wrapper(RT->GetVariable, 5, L"EFIDebug", 164 &EfiGlobalVariable, &Attributes, &DataSize, 165 &NewEFIDebug); 166 if (!EFI_ERROR(Status)) { 167 EFIDebug = NewEFIDebug; 168 } 169 } 170 171 /* 172 * Calls to memset/memcpy may be emitted implicitly by GCC or MSVC 173 * even when -ffreestanding or /NODEFAULTLIB are in effect. 174 */ 175 176 #ifndef __SIZE_TYPE__ 177 #define __SIZE_TYPE__ UINTN 178 #endif 179 180 void *memset(void *s, int c, __SIZE_TYPE__ n) 181 { 182 unsigned char *p = s; 183 184 while (n--) 185 *p++ = c; 186 187 return s; 188 } 189 190 void *memcpy(void *dest, const void *src, __SIZE_TYPE__ n) 191 { 192 const unsigned char *q = src; 193 unsigned char *p = dest; 194 195 while (n--) 196 *p++ = *q++; 197 198 return dest; 199 } 200 201 /** 202 * @brief 将数据从src搬运到dst,并能正确处理地址重叠的问题 203 * 204 * @param dst 目标地址指针 205 * @param src 源地址指针 206 * @param size 大小 207 * @return void* 指向目标地址的指针 208 */ 209 void *memmove(void *dst, const void *src, uint64_t size) 210 { 211 const char *_src = src; 212 char *_dst = dst; 213 214 if (!size) 215 return dst; 216 217 // 当源地址大于目标地址时,使用memcpy来完成 218 if (dst <= src) 219 return memcpy(dst, src, size); 220 221 // 当源地址小于目标地址时,为防止重叠覆盖,因此从后往前拷贝 222 _src += size; 223 _dst += size; 224 225 // 逐字节拷贝 226 while (size--) 227 *--_dst = *--_src; 228 229 return dst; 230 } 231