1530d68baSNigel Croxon /*++
2530d68baSNigel Croxon
3530d68baSNigel Croxon Copyright (c) 1998 Intel Corporation
4530d68baSNigel Croxon
5530d68baSNigel Croxon Module Name:
6530d68baSNigel Croxon
7530d68baSNigel Croxon
8530d68baSNigel Croxon Abstract:
9530d68baSNigel Croxon
10530d68baSNigel Croxon
11530d68baSNigel Croxon
12530d68baSNigel Croxon
13530d68baSNigel Croxon Revision History
14530d68baSNigel Croxon
15530d68baSNigel Croxon --*/
16530d68baSNigel Croxon
17530d68baSNigel Croxon #include "lib.h"
18*3e6106c4SLoGin #include <dragonstub/limits.h>
19530d68baSNigel Croxon
2078b790faSLoGin VOID EFIDebugVariable(VOID);
21530d68baSNigel Croxon
InitializeLib(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)2278b790faSLoGin VOID InitializeLib(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
23530d68baSNigel Croxon /*++
24530d68baSNigel Croxon
25530d68baSNigel Croxon Routine Description:
26530d68baSNigel Croxon
27530d68baSNigel Croxon Initializes EFI library for use
28530d68baSNigel Croxon
29530d68baSNigel Croxon Arguments:
30530d68baSNigel Croxon
31530d68baSNigel Croxon Firmware's EFI system table
32530d68baSNigel Croxon
33530d68baSNigel Croxon Returns:
34530d68baSNigel Croxon
35530d68baSNigel Croxon None
36530d68baSNigel Croxon
37530d68baSNigel Croxon --*/
38530d68baSNigel Croxon {
39530d68baSNigel Croxon EFI_LOADED_IMAGE *LoadedImage;
40530d68baSNigel Croxon EFI_STATUS Status;
41530d68baSNigel Croxon CHAR8 *LangCode;
42530d68baSNigel Croxon
434f8b339fSPeter Jones if (LibInitialized)
444f8b339fSPeter Jones return;
454f8b339fSPeter Jones
46530d68baSNigel Croxon LibInitialized = TRUE;
47530d68baSNigel Croxon LibFwInstance = FALSE;
483f8935c3SNigel Croxon LibImageHandle = ImageHandle;
493f8935c3SNigel Croxon
50530d68baSNigel Croxon //
51530d68baSNigel Croxon // Set up global pointer to the system table, boot services table,
52530d68baSNigel Croxon // and runtime services table
53530d68baSNigel Croxon //
54530d68baSNigel Croxon
55530d68baSNigel Croxon ST = SystemTable;
56530d68baSNigel Croxon BS = SystemTable->BootServices;
57530d68baSNigel Croxon RT = SystemTable->RuntimeServices;
58530d68baSNigel Croxon // ASSERT (CheckCrc(0, &ST->Hdr));
59530d68baSNigel Croxon // ASSERT (CheckCrc(0, &BS->Hdr));
60530d68baSNigel Croxon // ASSERT (CheckCrc(0, &RT->Hdr));
61530d68baSNigel Croxon
62530d68baSNigel Croxon //
63530d68baSNigel Croxon // Initialize pool allocation type
64530d68baSNigel Croxon //
65530d68baSNigel Croxon
66530d68baSNigel Croxon if (ImageHandle) {
6778b790faSLoGin Status = uefi_call_wrapper(BS->HandleProtocol, 3, ImageHandle,
68530d68baSNigel Croxon &LoadedImageProtocol,
6978b790faSLoGin (VOID *)&LoadedImage);
70530d68baSNigel Croxon
71530d68baSNigel Croxon if (!EFI_ERROR(Status)) {
72530d68baSNigel Croxon PoolAllocationType = LoadedImage->ImageDataType;
73530d68baSNigel Croxon }
74530d68baSNigel Croxon EFIDebugVariable();
75530d68baSNigel Croxon }
76530d68baSNigel Croxon
77530d68baSNigel Croxon //
78530d68baSNigel Croxon // Initialize Guid table
79530d68baSNigel Croxon //
80530d68baSNigel Croxon
81530d68baSNigel Croxon InitializeGuid();
82530d68baSNigel Croxon
83530d68baSNigel Croxon InitializeLibPlatform(ImageHandle, SystemTable);
84530d68baSNigel Croxon
85530d68baSNigel Croxon if (ImageHandle && UnicodeInterface == &LibStubUnicodeInterface) {
86530d68baSNigel Croxon LangCode = LibGetVariable(VarLanguage, &EfiGlobalVariable);
87530d68baSNigel Croxon InitializeUnicodeSupport(LangCode);
88530d68baSNigel Croxon if (LangCode) {
89530d68baSNigel Croxon FreePool(LangCode);
90530d68baSNigel Croxon }
91530d68baSNigel Croxon }
92530d68baSNigel Croxon }
93530d68baSNigel Croxon
InitializeUnicodeSupport(CHAR8 * LangCode)9478b790faSLoGin VOID InitializeUnicodeSupport(CHAR8 *LangCode)
95530d68baSNigel Croxon {
96530d68baSNigel Croxon EFI_UNICODE_COLLATION_INTERFACE *Ui;
97530d68baSNigel Croxon EFI_STATUS Status;
98530d68baSNigel Croxon CHAR8 *Languages;
99530d68baSNigel Croxon UINTN Index, Position, Length;
100530d68baSNigel Croxon UINTN NoHandles;
101530d68baSNigel Croxon EFI_HANDLE *Handles;
102530d68baSNigel Croxon
103530d68baSNigel Croxon //
104530d68baSNigel Croxon // If we don't know it, lookup the current language code
105530d68baSNigel Croxon //
106530d68baSNigel Croxon
10778b790faSLoGin LibLocateHandle(ByProtocol, &UnicodeCollationProtocol, NULL, &NoHandles,
10878b790faSLoGin &Handles);
109530d68baSNigel Croxon if (!LangCode || !NoHandles) {
110530d68baSNigel Croxon goto Done;
111530d68baSNigel Croxon }
112530d68baSNigel Croxon
113530d68baSNigel Croxon //
114530d68baSNigel Croxon // Check all driver's for a matching language code
115530d68baSNigel Croxon //
116530d68baSNigel Croxon
117530d68baSNigel Croxon for (Index = 0; Index < NoHandles; Index++) {
11878b790faSLoGin Status = uefi_call_wrapper(BS->HandleProtocol, 3,
11978b790faSLoGin Handles[Index],
12078b790faSLoGin &UnicodeCollationProtocol,
12178b790faSLoGin (VOID *)&Ui);
122530d68baSNigel Croxon if (EFI_ERROR(Status)) {
123530d68baSNigel Croxon continue;
124530d68baSNigel Croxon }
125530d68baSNigel Croxon
126530d68baSNigel Croxon //
127530d68baSNigel Croxon // Check for a matching language code
128530d68baSNigel Croxon //
129530d68baSNigel Croxon
130530d68baSNigel Croxon Languages = Ui->SupportedLanguages;
131530d68baSNigel Croxon Length = strlena(Languages);
13278b790faSLoGin for (Position = 0; Position < Length;
13378b790faSLoGin Position += ISO_639_2_ENTRY_SIZE) {
134530d68baSNigel Croxon //
135530d68baSNigel Croxon // If this code matches, use this driver
136530d68baSNigel Croxon //
137530d68baSNigel Croxon
13878b790faSLoGin if (CompareMem(Languages + Position, LangCode,
13978b790faSLoGin ISO_639_2_ENTRY_SIZE) == 0) {
140530d68baSNigel Croxon UnicodeInterface = Ui;
141530d68baSNigel Croxon goto Done;
142530d68baSNigel Croxon }
143530d68baSNigel Croxon }
144530d68baSNigel Croxon }
145530d68baSNigel Croxon
146530d68baSNigel Croxon Done:
147530d68baSNigel Croxon //
148530d68baSNigel Croxon // Cleanup
149530d68baSNigel Croxon //
150530d68baSNigel Croxon
151530d68baSNigel Croxon if (Handles) {
152530d68baSNigel Croxon FreePool(Handles);
153530d68baSNigel Croxon }
154530d68baSNigel Croxon }
155530d68baSNigel Croxon
EFIDebugVariable(VOID)15678b790faSLoGin VOID EFIDebugVariable(VOID)
157530d68baSNigel Croxon {
158530d68baSNigel Croxon EFI_STATUS Status;
159530d68baSNigel Croxon UINT32 Attributes;
160530d68baSNigel Croxon UINTN DataSize;
161530d68baSNigel Croxon UINTN NewEFIDebug;
162530d68baSNigel Croxon
163530d68baSNigel Croxon DataSize = sizeof(EFIDebug);
16478b790faSLoGin Status = uefi_call_wrapper(RT->GetVariable, 5, L"EFIDebug",
16578b790faSLoGin &EfiGlobalVariable, &Attributes, &DataSize,
16678b790faSLoGin &NewEFIDebug);
167530d68baSNigel Croxon if (!EFI_ERROR(Status)) {
168530d68baSNigel Croxon EFIDebug = NewEFIDebug;
169530d68baSNigel Croxon }
170530d68baSNigel Croxon }
171b1d426ceSNigel Croxon
172b1d426ceSNigel Croxon /*
173b1d426ceSNigel Croxon * Calls to memset/memcpy may be emitted implicitly by GCC or MSVC
174b1d426ceSNigel Croxon * even when -ffreestanding or /NODEFAULTLIB are in effect.
175b1d426ceSNigel Croxon */
176b1d426ceSNigel Croxon
177b1d426ceSNigel Croxon #ifndef __SIZE_TYPE__
178b1d426ceSNigel Croxon #define __SIZE_TYPE__ UINTN
179b1d426ceSNigel Croxon #endif
180b1d426ceSNigel Croxon
memset(void * s,int c,__SIZE_TYPE__ n)181b1d426ceSNigel Croxon void *memset(void *s, int c, __SIZE_TYPE__ n)
182b1d426ceSNigel Croxon {
183b1d426ceSNigel Croxon unsigned char *p = s;
184b1d426ceSNigel Croxon
185b1d426ceSNigel Croxon while (n--)
186b1d426ceSNigel Croxon *p++ = c;
187b1d426ceSNigel Croxon
188b1d426ceSNigel Croxon return s;
189b1d426ceSNigel Croxon }
190b1d426ceSNigel Croxon
memcpy(void * dest,const void * src,__SIZE_TYPE__ n)191b1d426ceSNigel Croxon void *memcpy(void *dest, const void *src, __SIZE_TYPE__ n)
192b1d426ceSNigel Croxon {
193b1d426ceSNigel Croxon const unsigned char *q = src;
194b1d426ceSNigel Croxon unsigned char *p = dest;
195b1d426ceSNigel Croxon
196b1d426ceSNigel Croxon while (n--)
197b1d426ceSNigel Croxon *p++ = *q++;
198b1d426ceSNigel Croxon
199b1d426ceSNigel Croxon return dest;
200b1d426ceSNigel Croxon }
201f412fd2aSLoGin
202f412fd2aSLoGin /**
203f412fd2aSLoGin * @brief 将数据从src搬运到dst,并能正确处理地址重叠的问题
204f412fd2aSLoGin *
205f412fd2aSLoGin * @param dst 目标地址指针
206f412fd2aSLoGin * @param src 源地址指针
207f412fd2aSLoGin * @param size 大小
208f412fd2aSLoGin * @return void* 指向目标地址的指针
209f412fd2aSLoGin */
memmove(void * dst,const void * src,uint64_t size)210f412fd2aSLoGin void *memmove(void *dst, const void *src, uint64_t size)
211f412fd2aSLoGin {
212f412fd2aSLoGin const char *_src = src;
213f412fd2aSLoGin char *_dst = dst;
214f412fd2aSLoGin
215f412fd2aSLoGin if (!size)
216f412fd2aSLoGin return dst;
217f412fd2aSLoGin
218f412fd2aSLoGin // 当源地址大于目标地址时,使用memcpy来完成
219f412fd2aSLoGin if (dst <= src)
220f412fd2aSLoGin return memcpy(dst, src, size);
221f412fd2aSLoGin
222f412fd2aSLoGin // 当源地址小于目标地址时,为防止重叠覆盖,因此从后往前拷贝
223f412fd2aSLoGin _src += size;
224f412fd2aSLoGin _dst += size;
225f412fd2aSLoGin
226f412fd2aSLoGin // 逐字节拷贝
227f412fd2aSLoGin while (size--)
228f412fd2aSLoGin *--_dst = *--_src;
229f412fd2aSLoGin
230f412fd2aSLoGin return dst;
231f412fd2aSLoGin }
232*3e6106c4SLoGin
233*3e6106c4SLoGin #define SS (sizeof(size_t))
234*3e6106c4SLoGin #define __ALIGN (sizeof(size_t)-1)
235*3e6106c4SLoGin #define ONES ((size_t)-1/UCHAR_MAX)
236*3e6106c4SLoGin #define HIGHS (ONES * (UCHAR_MAX/2+1))
237*3e6106c4SLoGin #define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
238*3e6106c4SLoGin
memchr(const void * src,int c,size_t n)239*3e6106c4SLoGin void *memchr(const void *src, int c, size_t n)
240*3e6106c4SLoGin {
241*3e6106c4SLoGin const unsigned char *s = src;
242*3e6106c4SLoGin c = (unsigned char)c;
243*3e6106c4SLoGin #ifdef __GNUC__
244*3e6106c4SLoGin for (; ((uintptr_t)s & __ALIGN) && n && *s != c; s++, n--);
245*3e6106c4SLoGin if (n && *s != c) {
246*3e6106c4SLoGin typedef size_t __attribute__((__may_alias__)) word;
247*3e6106c4SLoGin const word *w;
248*3e6106c4SLoGin size_t k = ONES * c;
249*3e6106c4SLoGin for (w = (const void *)s; n>=SS && !HASZERO(*w^k); w++, n-=SS);
250*3e6106c4SLoGin s = (const void *)w;
251*3e6106c4SLoGin }
252*3e6106c4SLoGin #endif
253*3e6106c4SLoGin for (; n && *s != c; s++, n--);
254*3e6106c4SLoGin return n ? (void *)s : 0;
255*3e6106c4SLoGin }
256*3e6106c4SLoGin
memcmp(const void * vl,const void * vr,size_t n)257*3e6106c4SLoGin int memcmp(const void *vl, const void *vr, size_t n)
258*3e6106c4SLoGin {
259*3e6106c4SLoGin const unsigned char *l = vl, *r = vr;
260*3e6106c4SLoGin for (; n && *l == *r; n--, l++, r++)
261*3e6106c4SLoGin ;
262*3e6106c4SLoGin return n ? *l - *r : 0;
263*3e6106c4SLoGin }
264*3e6106c4SLoGin
memrchr(const void * m,int c,size_t n)265*3e6106c4SLoGin void *memrchr(const void *m, int c, size_t n)
266*3e6106c4SLoGin {
267*3e6106c4SLoGin const unsigned char *s = m;
268*3e6106c4SLoGin c = (unsigned char)c;
269*3e6106c4SLoGin while (n--) if (s[n]==c) return (void *)(s+n);
270*3e6106c4SLoGin return 0;
271*3e6106c4SLoGin }
272