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