xref: /DragonStub/lib/init.c (revision 3e6106c4d60a23aae3c0740979c5e6fb728b63c3)
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