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