diff --git a/.vs/ProjectSettings.json b/.vs/ProjectSettings.json new file mode 100644 index 0000000..b11371a --- /dev/null +++ b/.vs/ProjectSettings.json @@ -0,0 +1,3 @@ +{ + "CurrentProjectSetting": "No Configurations" +} \ No newline at end of file diff --git a/.vs/VSWorkspaceState.json b/.vs/VSWorkspaceState.json new file mode 100644 index 0000000..9568b22 --- /dev/null +++ b/.vs/VSWorkspaceState.json @@ -0,0 +1,6 @@ +{ + "ExpandedNodes": [ + "" + ], + "PreviewInSolutionExplorer": false +} \ No newline at end of file diff --git a/.vs/binkx86/CopilotIndices/17.14.1091.29919/SemanticSymbols.db b/.vs/binkx86/CopilotIndices/17.14.1091.29919/SemanticSymbols.db new file mode 100644 index 0000000..330f6d0 Binary files /dev/null and b/.vs/binkx86/CopilotIndices/17.14.1091.29919/SemanticSymbols.db differ diff --git a/.vs/binkx86/FileContentIndex/6451e624-7538-4cf0-b10b-7f9fd5b494e2.vsidx b/.vs/binkx86/FileContentIndex/6451e624-7538-4cf0-b10b-7f9fd5b494e2.vsidx new file mode 100644 index 0000000..a9bc7fa Binary files /dev/null and b/.vs/binkx86/FileContentIndex/6451e624-7538-4cf0-b10b-7f9fd5b494e2.vsidx differ diff --git a/.vs/binkx86/v17/.wsuo b/.vs/binkx86/v17/.wsuo new file mode 100644 index 0000000..0912c4a Binary files /dev/null and b/.vs/binkx86/v17/.wsuo differ diff --git a/.vs/binkx86/v17/Browse.VC.db b/.vs/binkx86/v17/Browse.VC.db new file mode 100644 index 0000000..64381ae Binary files /dev/null and b/.vs/binkx86/v17/Browse.VC.db differ diff --git a/.vs/binkx86/v17/DocumentLayout.json b/.vs/binkx86/v17/DocumentLayout.json new file mode 100644 index 0000000..74a3ed6 --- /dev/null +++ b/.vs/binkx86/v17/DocumentLayout.json @@ -0,0 +1,23 @@ +{ + "Version": 1, + "WorkspaceRootPath": "C:\\Users\\Administrator\\Documents\\binkx86\\", + "Documents": [], + "DocumentGroupContainers": [ + { + "Orientation": 0, + "VerticalTabListWidth": 256, + "DocumentGroups": [ + { + "DockedWidth": 200, + "SelectedChildIndex": -1, + "Children": [ + { + "$type": "Bookmark", + "Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite new file mode 100644 index 0000000..e19a856 Binary files /dev/null and b/.vs/slnx.sqlite differ diff --git a/.vscode/settings.json b/.vscode/settings.json index 58be050..432dc97 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,8 @@ { "files.associations": { "cstdio": "cpp", - "chrono": "cpp" + "chrono": "cpp", + "system_error": "cpp", + "xlocale": "cpp" } } \ No newline at end of file diff --git a/OVMF/OVMF_CODE_4M.fd b/OVMF/OVMF_CODE_4M.fd new file mode 100644 index 0000000..24fbf1d Binary files /dev/null and b/OVMF/OVMF_CODE_4M.fd differ diff --git a/OVMF/OVMF_CODE_4M.ms.fd b/OVMF/OVMF_CODE_4M.ms.fd new file mode 100644 index 0000000..d1809b4 Binary files /dev/null and b/OVMF/OVMF_CODE_4M.ms.fd differ diff --git a/OVMF/OVMF_CODE_4M.secboot.fd b/OVMF/OVMF_CODE_4M.secboot.fd new file mode 100644 index 0000000..d1809b4 Binary files /dev/null and b/OVMF/OVMF_CODE_4M.secboot.fd differ diff --git a/OVMF/OVMF_CODE_4M.snakeoil.fd b/OVMF/OVMF_CODE_4M.snakeoil.fd new file mode 100644 index 0000000..d1809b4 Binary files /dev/null and b/OVMF/OVMF_CODE_4M.snakeoil.fd differ diff --git a/OVMF/OVMF_VARS_4M.fd b/OVMF/OVMF_VARS_4M.fd new file mode 100644 index 0000000..0d40440 Binary files /dev/null and b/OVMF/OVMF_VARS_4M.fd differ diff --git a/OVMF/OVMF_VARS_4M.ms.fd b/OVMF/OVMF_VARS_4M.ms.fd new file mode 100644 index 0000000..be30858 Binary files /dev/null and b/OVMF/OVMF_VARS_4M.ms.fd differ diff --git a/OVMF/OVMF_VARS_4M.snakeoil.fd b/OVMF/OVMF_VARS_4M.snakeoil.fd new file mode 100644 index 0000000..d57cc47 Binary files /dev/null and b/OVMF/OVMF_VARS_4M.snakeoil.fd differ diff --git a/bink2w64.lib b/bink2w64.lib deleted file mode 100644 index 082c406..0000000 Binary files a/bink2w64.lib and /dev/null differ diff --git a/bink_loader_gen.c b/bink_loader_gen.c deleted file mode 100644 index a6c77ec..0000000 --- a/bink_loader_gen.c +++ /dev/null @@ -1,131 +0,0 @@ -#include "bink.h" -#include - -// Macro to define function pointer and global variable -#define DECL_FN(ret, name, args, ptr) typedef ret (__cdecl *name##_t) args; name##_t p##name = NULL; - -DECL_FN(RADEXPFUNC void *, BinkLogoAddress, (void), ) -DECL_FN(RADEXPFUNC void, BinkSetError, (char const * err), *) -DECL_FN(RADEXPFUNC char *, BinkGetError, (void), ) -DECL_FN(RADEXPFUNC HBINK, BinkOpen, (char const * name, U32 flags), *) -DECL_FN(RADEXPFUNC HBINK, BinkOpenWithOptions, (char const * name, BINK_OPEN_OPTIONS const * boo, U32 flags), *) -DECL_FN(RADEXPFUNC void, BinkGetFrameBuffersInfo, (HBINK bink, BINKFRAMEBUFFERS * fbset), *) -DECL_FN(RADEXPFUNC void, BinkRegisterFrameBuffers, (HBINK bink, BINKFRAMEBUFFERS * fbset), *) -DECL_FN(RADEXPFUNC S32, BinkDoFrame, (HBINK bnk), *) -DECL_FN(RADEXPFUNC S32, BinkDoFramePlane, (HBINK bnk, U32 which_planes), *) -DECL_FN(RADEXPFUNC void, BinkNextFrame, (HBINK bnk), *) -DECL_FN(RADEXPFUNC S32, BinkWait, (HBINK bnk), *) -DECL_FN(RADEXPFUNC void, BinkClose, (HBINK bnk), *) -DECL_FN(RADEXPFUNC S32, BinkPause, (HBINK bnk, S32 pause), *) -DECL_FN(RADEXPFUNC S32, BinkCopyToBuffer, (HBINK bnk, void* dest, S32 destpitch, U32 destheight, U32 destx, U32 desty, U32 flags), *) -DECL_FN(RADEXPFUNC S32, BinkCopyToBufferRect, (HBINK bnk, void* dest, S32 destpitch, U32 destheight, U32 destx, U32 desty, U32 srcx, U32 srcy, U32 srcw, U32 srch, U32 flags), *) -DECL_FN(RADEXPFUNC S32, BinkGetRects, (HBINK bnk, U32 flags), *) -DECL_FN(RADEXPFUNC void, BinkGoto, (HBINK bnk, U32 frame, S32 flags), *) -DECL_FN(RADEXPFUNC U32, BinkGetKeyFrame, (HBINK bnk, U32 frame, S32 flags), *) -DECL_FN(RADEXPFUNC void, BinkFreeGlobals, (void), *) -DECL_FN(RADEXPFUNC S32, BinkGetPlatformInfo, (S32 bink_platform_enum, void * output), *) -DECL_FN(RADEXPFUNC void, BinkRegisterGPUDataBuffers, (HBINK bink, BINKGPUDATABUFFERS * gpu), *) -DECL_FN(RADEXPFUNC S32, BinkGetGPUDataBuffersInfo, (HBINK bink, BINKGPUDATABUFFERS * gpu), *) -DECL_FN(RADEXPFUNC S32, BinkSetVideoOnOff, (HBINK bnk, S32 onoff), *) -DECL_FN(RADEXPFUNC S32, BinkSetSoundOnOff, (HBINK bnk, S32 onoff), *) -DECL_FN(RADEXPFUNC void, BinkSetVolume, (HBINK bnk, U32 trackid, S32 volume), *) -DECL_FN(RADEXPFUNC void, BinkSetPan, (HBINK bnk, U32 trackid, S32 pan), *) -DECL_FN(RADEXPFUNC void, BinkSetSpeakerVolumes, (HBINK bnk, U32 trackid, U32 * speaker_indexes, S32 * volumes, U32 total), *) -DECL_FN(RADEXPFUNC void, BinkService, (HBINK bink), *) -DECL_FN(RADEXPFUNC S32, BinkShouldSkip, (HBINK bink), *) -DECL_FN(RADEXPFUNC S32, BinkControlBackgroundIO, (HBINK bink, U32 control), *) -DECL_FN(RADEXPFUNC void, BinkSetWillLoop, (HBINK bink, S32 onoff), *) -DECL_FN(RADEXPFUNC S32, BinkStartAsyncThread, (S32 thread_num, void const * param), *) -DECL_FN(RADEXPFUNC S32, BinkDoFrameAsync, (HBINK bink, U32 thread_one, U32 thread_two), *) -DECL_FN(RADEXPFUNC S32, BinkDoFrameAsyncMulti, (HBINK bink, U32* threads, S32 thread_count), *) -DECL_FN(RADEXPFUNC S32, BinkDoFrameAsyncWait, (HBINK bink, S32 us), *) -DECL_FN(RADEXPFUNC S32, BinkRequestStopAsyncThread, (S32 thread_num), *) -DECL_FN(RADEXPFUNC S32, BinkWaitStopAsyncThread, (S32 thread_num), *) -DECL_FN(RADEXPFUNC HBINKTRACK, BinkOpenTrack, (HBINK bnk, U32 trackindex), *) -DECL_FN(RADEXPFUNC void, BinkCloseTrack, (HBINKTRACK bnkt), *) -DECL_FN(RADEXPFUNC U32, BinkGetTrackData, (HBINKTRACK bnkt, void * dest), *) -DECL_FN(RADEXPFUNC U32, BinkGetTrackType, (HBINK bnk, U32 trackindex), *) -DECL_FN(RADEXPFUNC U32, BinkGetTrackMaxSize, (HBINK bnk, U32 trackindex), *) -DECL_FN(RADEXPFUNC U32, BinkGetTrackID, (HBINK bnk, U32 trackindex), *) -DECL_FN(RADEXPFUNC void, BinkGetSummary, (HBINK bnk, BINKSUMMARY * sum), *) -DECL_FN(RADEXPFUNC void, BinkGetRealtime, (HBINK bink, BINKREALTIME * run, U32 frames), *) -DECL_FN(RADEXPFUNC void, BinkSetFileOffset, (U64 offset), *) -DECL_FN(RADEXPFUNC void, BinkSetSoundTrack, (U32 total_tracks, U32 * tracks), *) -DECL_FN(RADEXPFUNC void, BinkSetIO, (BINKIOOPEN io), *) -DECL_FN(RADEXPFUNC void, BinkSetFrameRate, (U32 forcerate, U32 forceratediv), *) -DECL_FN(RADEXPFUNC void, BinkSetSimulate, (U32 sim), *) -DECL_FN(RADEXPFUNC void, BinkSetIOSize, (U32 iosize), *) -DECL_FN(RADEXPFUNC S32, BinkSetSoundSystem, (BINKSNDSYSOPEN open, UINTa param), *) -DECL_FN(RADEXPFUNC S32, BinkSetSoundSystem2, (BINKSNDSYSOPEN2 open, UINTa param1, UINTa param2), *) -DECL_FN(RADEXPFUNC BINKSNDOPEN, BinkOpenDirectSound, (UINTa param), *) -DECL_FN(RADEXPFUNC BINKSNDOPEN, BinkOpenWaveOut, (UINTa param), *) -DECL_FN(RADEXPFUNC BINKSNDOPEN, BinkOpenXAudio2, (UINTa param), *) -DECL_FN(RADEXPFUNC void, BinkSetMemory, (BINKMEMALLOC a, BINKMEMFREE f), *) - -HMODULE dll = NULL; - -int LoadBinkDLL(void) { - if (dll) return 1; - dll = LoadLibraryA("bink2w64.dll"); - if (!dll) return 0; - - pBinkLogoAddress = (BinkLogoAddress_t)GetProcAddress(dll, "BinkLogoAddress"); - pBinkSetError = (BinkSetError_t)GetProcAddress(dll, "BinkSetError"); - pBinkGetError = (BinkGetError_t)GetProcAddress(dll, "BinkGetError"); - pBinkOpen = (BinkOpen_t)GetProcAddress(dll, "BinkOpen"); - pBinkOpenWithOptions = (BinkOpenWithOptions_t)GetProcAddress(dll, "BinkOpenWithOptions"); - pBinkGetFrameBuffersInfo = (BinkGetFrameBuffersInfo_t)GetProcAddress(dll, "BinkGetFrameBuffersInfo"); - pBinkRegisterFrameBuffers = (BinkRegisterFrameBuffers_t)GetProcAddress(dll, "BinkRegisterFrameBuffers"); - pBinkDoFrame = (BinkDoFrame_t)GetProcAddress(dll, "BinkDoFrame"); - pBinkDoFramePlane = (BinkDoFramePlane_t)GetProcAddress(dll, "BinkDoFramePlane"); - pBinkNextFrame = (BinkNextFrame_t)GetProcAddress(dll, "BinkNextFrame"); - pBinkWait = (BinkWait_t)GetProcAddress(dll, "BinkWait"); - pBinkClose = (BinkClose_t)GetProcAddress(dll, "BinkClose"); - pBinkPause = (BinkPause_t)GetProcAddress(dll, "BinkPause"); - pBinkCopyToBuffer = (BinkCopyToBuffer_t)GetProcAddress(dll, "BinkCopyToBuffer"); - pBinkCopyToBufferRect = (BinkCopyToBufferRect_t)GetProcAddress(dll, "BinkCopyToBufferRect"); - pBinkGetRects = (BinkGetRects_t)GetProcAddress(dll, "BinkGetRects"); - pBinkGoto = (BinkGoto_t)GetProcAddress(dll, "BinkGoto"); - pBinkGetKeyFrame = (BinkGetKeyFrame_t)GetProcAddress(dll, "BinkGetKeyFrame"); - pBinkFreeGlobals = (BinkFreeGlobals_t)GetProcAddress(dll, "BinkFreeGlobals"); - pBinkGetPlatformInfo = (BinkGetPlatformInfo_t)GetProcAddress(dll, "BinkGetPlatformInfo"); - pBinkRegisterGPUDataBuffers = (BinkRegisterGPUDataBuffers_t)GetProcAddress(dll, "BinkRegisterGPUDataBuffers"); - pBinkGetGPUDataBuffersInfo = (BinkGetGPUDataBuffersInfo_t)GetProcAddress(dll, "BinkGetGPUDataBuffersInfo"); - pBinkSetVideoOnOff = (BinkSetVideoOnOff_t)GetProcAddress(dll, "BinkSetVideoOnOff"); - pBinkSetSoundOnOff = (BinkSetSoundOnOff_t)GetProcAddress(dll, "BinkSetSoundOnOff"); - pBinkSetVolume = (BinkSetVolume_t)GetProcAddress(dll, "BinkSetVolume"); - pBinkSetPan = (BinkSetPan_t)GetProcAddress(dll, "BinkSetPan"); - pBinkSetSpeakerVolumes = (BinkSetSpeakerVolumes_t)GetProcAddress(dll, "BinkSetSpeakerVolumes"); - pBinkService = (BinkService_t)GetProcAddress(dll, "BinkService"); - pBinkShouldSkip = (BinkShouldSkip_t)GetProcAddress(dll, "BinkShouldSkip"); - pBinkControlBackgroundIO = (BinkControlBackgroundIO_t)GetProcAddress(dll, "BinkControlBackgroundIO"); - pBinkSetWillLoop = (BinkSetWillLoop_t)GetProcAddress(dll, "BinkSetWillLoop"); - pBinkStartAsyncThread = (BinkStartAsyncThread_t)GetProcAddress(dll, "BinkStartAsyncThread"); - pBinkDoFrameAsync = (BinkDoFrameAsync_t)GetProcAddress(dll, "BinkDoFrameAsync"); - pBinkDoFrameAsyncMulti = (BinkDoFrameAsyncMulti_t)GetProcAddress(dll, "BinkDoFrameAsyncMulti"); - pBinkDoFrameAsyncWait = (BinkDoFrameAsyncWait_t)GetProcAddress(dll, "BinkDoFrameAsyncWait"); - pBinkRequestStopAsyncThread = (BinkRequestStopAsyncThread_t)GetProcAddress(dll, "BinkRequestStopAsyncThread"); - pBinkWaitStopAsyncThread = (BinkWaitStopAsyncThread_t)GetProcAddress(dll, "BinkWaitStopAsyncThread"); - pBinkOpenTrack = (BinkOpenTrack_t)GetProcAddress(dll, "BinkOpenTrack"); - pBinkCloseTrack = (BinkCloseTrack_t)GetProcAddress(dll, "BinkCloseTrack"); - pBinkGetTrackData = (BinkGetTrackData_t)GetProcAddress(dll, "BinkGetTrackData"); - pBinkGetTrackType = (BinkGetTrackType_t)GetProcAddress(dll, "BinkGetTrackType"); - pBinkGetTrackMaxSize = (BinkGetTrackMaxSize_t)GetProcAddress(dll, "BinkGetTrackMaxSize"); - pBinkGetTrackID = (BinkGetTrackID_t)GetProcAddress(dll, "BinkGetTrackID"); - pBinkGetSummary = (BinkGetSummary_t)GetProcAddress(dll, "BinkGetSummary"); - pBinkGetRealtime = (BinkGetRealtime_t)GetProcAddress(dll, "BinkGetRealtime"); - pBinkSetFileOffset = (BinkSetFileOffset_t)GetProcAddress(dll, "BinkSetFileOffset"); - pBinkSetSoundTrack = (BinkSetSoundTrack_t)GetProcAddress(dll, "BinkSetSoundTrack"); - pBinkSetIO = (BinkSetIO_t)GetProcAddress(dll, "BinkSetIO"); - pBinkSetFrameRate = (BinkSetFrameRate_t)GetProcAddress(dll, "BinkSetFrameRate"); - pBinkSetSimulate = (BinkSetSimulate_t)GetProcAddress(dll, "BinkSetSimulate"); - pBinkSetIOSize = (BinkSetIOSize_t)GetProcAddress(dll, "BinkSetIOSize"); - pBinkSetSoundSystem = (BinkSetSoundSystem_t)GetProcAddress(dll, "BinkSetSoundSystem"); - pBinkSetSoundSystem2 = (BinkSetSoundSystem2_t)GetProcAddress(dll, "BinkSetSoundSystem2"); - pBinkOpenDirectSound = (BinkOpenDirectSound_t)GetProcAddress(dll, "BinkOpenDirectSound"); - pBinkOpenWaveOut = (BinkOpenWaveOut_t)GetProcAddress(dll, "BinkOpenWaveOut"); - pBinkOpenXAudio2 = (BinkOpenXAudio2_t)GetProcAddress(dll, "BinkOpenXAudio2"); - pBinkSetMemory = (BinkSetMemory_t)GetProcAddress(dll, "BinkSetMemory"); - - return 1; -} diff --git a/build.bat b/build.bat new file mode 100644 index 0000000..8ae8484 --- /dev/null +++ b/build.bat @@ -0,0 +1,9 @@ +@echo off +ml64 /c /nologo /Brepro helpers.asm +cl main.cpp /c /Brepro /GS- /GR- /Oi /EHs-c- /nologo /Zc:threadSafeInit- /I include || pause && exit /b +cl user32.cpp /c /Brepro /GS- /GR- /Oi /EHs-c- /nologo /Zc:threadSafeInit- /I include || pause && exit /b +cl ole32.cpp /c /Brepro /GS- /GR- /Oi /EHs-c- /nologo /Zc:threadSafeInit- /I include || pause && exit /b +cl kernel32.cpp /Brepro /c /GS- /GR- /Oi /EHs-c- /nologo /Zc:threadSafeInit- /I include || pause && exit /b +cl winmm.cpp /c /Brepro /GS- /GR- /Oi /EHs-c- /nologo /Zc:threadSafeInit- /I include || pause && exit /b +link helpers.obj main.obj user32.obj ole32.obj kernel32.obj winmm.obj /Brepro /STACK:16777216 /NODEFAULTLIB /ENTRY:efi_main /NOLOGO /SUBSYSTEM:EFI_APPLICATION /OUT:BootX64.efi efilib.lib /MACHINE:X64 || pause && exit /b +copy /B /Y BootX64.efi fatroot\EFI\Boot\ diff --git a/efilib.lib b/efilib.lib new file mode 100644 index 0000000..8497241 Binary files /dev/null and b/efilib.lib differ diff --git a/efilib.pdb b/efilib.pdb new file mode 100644 index 0000000..d7c86bf Binary files /dev/null and b/efilib.pdb differ diff --git a/fatroot/EFI/Boot/BootX64.efi b/fatroot/EFI/Boot/BootX64.efi new file mode 100644 index 0000000..3f45672 Binary files /dev/null and b/fatroot/EFI/Boot/BootX64.efi differ diff --git a/fatroot/bink2w64.dll b/fatroot/bink2w64.dll new file mode 100644 index 0000000..44111b4 Binary files /dev/null and b/fatroot/bink2w64.dll differ diff --git a/framebuffer.bmp b/framebuffer.bmp deleted file mode 100644 index 353a6da..0000000 Binary files a/framebuffer.bmp and /dev/null differ diff --git a/functions.txt b/functions.txt deleted file mode 100644 index a43bff8..0000000 --- a/functions.txt +++ /dev/null @@ -1,80 +0,0 @@ -BinkAllocateFrameBuffers -BinkClose -BinkCloseTrack -BinkControlBackgroundIO -BinkCopyToBuffer -BinkCopyToBufferRect -BinkCurrentSubtitle -BinkDoFrame -BinkDoFrameAsync -BinkDoFrameAsyncMulti -BinkDoFrameAsyncWait -BinkDoFramePlane -BinkFindXAudio2WinDevice -BinkFreeGlobals -BinkGetError -BinkGetFrameBuffersInfo -BinkGetGPUDataBuffersInfo -BinkGetKeyFrame -BinkGetPlatformInfo -BinkGetRealtime -BinkGetRects -BinkGetSubtitleByIndex -BinkGetSummary -BinkGetTrackData -BinkGetTrackID -BinkGetTrackMaxSize -BinkGetTrackType -BinkGoto -BinkLoadSubtitles -BinkLogoAddress -BinkNextFrame -BinkOpen -BinkOpenDirectSound -BinkOpenTrack -BinkOpenWaveOut -BinkOpenWithOptions -BinkOpenXAudio2 -BinkOpenXAudio27 -BinkOpenXAudio28 -BinkOpenXAudio29 -BinkPause -BinkRegisterFrameBuffers -BinkRegisterGPUDataBuffers -BinkRequestStopAsyncThread -BinkRequestStopAsyncThreadsMulti -BinkService -BinkSetError -BinkSetFileOffset -BinkSetFrameRate -BinkSetIO -BinkSetIOSize -BinkSetMemory -BinkSetOSFileCallbacks -BinkSetPan -BinkSetSimulate -BinkSetSoundOnOff -BinkSetSoundSystem -BinkSetSoundSystem2 -BinkSetSoundSystem4 -BinkSetSoundTrack -BinkSetSpeakerVolumes -BinkSetVideoOnOff -BinkSetVolume -BinkSetWillLoop -BinkShouldSkip -BinkStartAsyncThread -BinkUtilCPUs -BinkUtilFree -BinkUtilMalloc -BinkUtilMutexCreate -BinkUtilMutexDestroy -BinkUtilMutexLock -BinkUtilMutexLockTimeOut -BinkUtilMutexUnlock -BinkUtilSoundGlobalLock -BinkUtilSoundGlobalUnlock -BinkWait -BinkWaitStopAsyncThread -BinkWaitStopAsyncThreadsMulti -RADTimerRead \ No newline at end of file diff --git a/gen.py b/gen.py deleted file mode 100644 index 5bb65c6..0000000 --- a/gen.py +++ /dev/null @@ -1,57 +0,0 @@ -import re - -header_file = "bink.h" -func_list_file = "functions.txt" -out_file = "bink_loader_gen.c" - -# Read function list -with open(func_list_file) as f: - func_names = set(line.strip() for line in f if line.strip()) - -# Read header -with open(header_file) as f: - header = f.read() - -# Remove RADEXPLINK entirely -header = re.sub(r'\bRADEXPLINK\b', '', header) - -functions = [] - -# Regex to match return type + function name + args -prototype_re = re.compile( - r'^[ \t]*(\w[\w\s\*\d]+)[ \t]+(' + '|'.join(func_names) + r')[ \t]*\(([^)]*)\)\s*;', - re.MULTILINE -) - -for match in prototype_re.finditer(header): - ret_type = match.group(1).strip() - name = match.group(2).strip() - args = match.group(3).strip() - args = re.sub(r'\s*,\s*', ', ', args) - - # Only add * if return type is NOT already a pointer - ptr_mark = '' if ret_type.endswith('*') else '*' - - functions.append((ret_type, name, args, ptr_mark)) - -# Generate C file -with open(out_file, "w") as f: - f.write('#include "bink.h"\n#include \n\n') - f.write('// Macro to define function pointer and global variable\n') - f.write('#define DECL_FN(ret, name, args, ptr) typedef ret (__cdecl *name##_t) args; name##_t p##name = NULL;\n\n') - - # Typedefs + globals - for ret, name, args, ptr_mark in functions: - f.write(f'DECL_FN({ret}, {name}, ({args}), {ptr_mark})\n') - - f.write('\nHMODULE dll = NULL;\n\n') - f.write('int LoadBinkDLL(void) {\n') - f.write(' if (dll) return 1;\n') - f.write(' dll = LoadLibraryA("bink2w64.dll");\n') - f.write(' if (!dll) return 0;\n\n') - - # Assign function pointers - for _, name, _, _ in functions: - f.write(f' p{name} = ({name}_t)GetProcAddress(dll, "{name}");\n') - - f.write('\n return 1;\n}\n') diff --git a/helpers.asm b/helpers.asm new file mode 100644 index 0000000..eda2321 --- /dev/null +++ b/helpers.asm @@ -0,0 +1,24 @@ +.code + +; void enable_avx2() +enable_avx2 PROC + ; Set CR4.OSXSAVE (bit 18) + mov rax, cr4 + or eax, 40000h ; set bit 18 + mov cr4, rax + + ; Read XCR0 (xgetbv, ecx=0) + xor ecx, ecx + xgetbv + + ; Enable XMM (bit 0) and YMM (bit 1) + or eax, 6 + + ; Write XCR0 (xsetbv, ecx=0) + xor ecx, ecx + xsetbv + + ret +enable_avx2 ENDP + +END diff --git a/include/Makefile b/include/Makefile new file mode 100644 index 0000000..35361eb --- /dev/null +++ b/include/Makefile @@ -0,0 +1,24 @@ +SRCDIR = . + +VPATH = $(SRCDIR) +TOPDIR = $(SRCDIR)/.. + +include $(SRCDIR)/../Make.defaults + +all: + +clean: + +install: + mkdir -p $(INSTALLROOT)$(INCLUDEDIR)/efi + mkdir -p $(INSTALLROOT)$(INCLUDEDIR)/efi/protocol + mkdir -p $(INSTALLROOT)$(INCLUDEDIR)/efi/$(ARCH) + $(INSTALL) -m 644 $(SRCDIR)/*.h $(INSTALLROOT)$(INCLUDEDIR)/efi + $(INSTALL) -m 644 $(SRCDIR)/protocol/*.h $(INSTALLROOT)$(INCLUDEDIR)/efi/protocol + $(INSTALL) -m 644 $(SRCDIR)/$(ARCH)/*.h $(INSTALLROOT)$(INCLUDEDIR)/efi/$(ARCH) +ifeq ($(ARCH),ia64) + mkdir -p $(INSTALLROOT)$(INCLUDEDIR)/efi/protocol/ia64 + $(INSTALL) -m 644 $(SRCDIR)/protocol/ia64/*.h $(INSTALLROOT)$(INCLUDEDIR)/efi/protocol/ia64 +endif + +include $(SRCDIR)/../Make.rules diff --git a/include/aarch64/efibind.h b/include/aarch64/efibind.h new file mode 100644 index 0000000..7d14687 --- /dev/null +++ b/include/aarch64/efibind.h @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2014 - 2015 Linaro Ltd. + * Author: Ard Biesheuvel + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice and this list of conditions, without modification. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License as published by the Free Software Foundation; + * either version 2 of the License, or (at your option) any later version. + */ + +#if !defined(_MSC_VER) && (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L )) && !defined(__cplusplus) + +// ANSI C 1999/2000 stdint.h integer width declarations + +typedef unsigned long uint64_t; +typedef long int64_t; +typedef unsigned int uint32_t; +typedef int int32_t; +typedef unsigned short uint16_t; +typedef short int16_t; +typedef unsigned char uint8_t; +typedef signed char int8_t; // unqualified 'char' is unsigned on ARM +typedef uint64_t uintptr_t; +typedef int64_t intptr_t; + +#else +#include +#endif + +// +// Basic EFI types of various widths +// + +#include + +typedef wchar_t CHAR16; +#define WCHAR CHAR16 + +typedef uint64_t UINT64; +typedef int64_t INT64; + +typedef uint32_t UINT32; +typedef int32_t INT32; + +typedef uint16_t UINT16; +typedef int16_t INT16; + +typedef uint8_t UINT8; +typedef char CHAR8; +typedef int8_t INT8; + +#undef VOID +typedef void VOID; + +typedef int64_t INTN; +typedef uint64_t UINTN; + +#define EFIERR(a) (0x8000000000000000 | a) +#define EFI_ERROR_MASK 0x8000000000000000 +#define EFIERR_OEM(a) (0xc000000000000000 | a) + +#define BAD_POINTER 0xFBFBFBFBFBFBFBFB +#define MAX_ADDRESS 0xFFFFFFFFFFFFFFFF + +#define BREAKPOINT() while (TRUE); // Make it hang on Bios[Dbg]32 + +// +// Pointers must be aligned to these address to function +// + +#define MIN_ALIGNMENT_SIZE 8 + +#define ALIGN_VARIABLE(Value ,Adjustment) \ + (UINTN)Adjustment = 0; \ + if((UINTN)Value % MIN_ALIGNMENT_SIZE) \ + (UINTN)Adjustment = MIN_ALIGNMENT_SIZE - ((UINTN)Value % MIN_ALIGNMENT_SIZE); \ + Value = (UINTN)Value + (UINTN)Adjustment + + +// +// Define macros to build data structure signatures from characters. +// + +#define EFI_SIGNATURE_16(A,B) ((A) | (B<<8)) +#define EFI_SIGNATURE_32(A,B,C,D) (EFI_SIGNATURE_16(A,B) | (EFI_SIGNATURE_16(C,D) << 16)) +#define EFI_SIGNATURE_64(A,B,C,D,E,F,G,H) (EFI_SIGNATURE_32(A,B,C,D) | ((UINT64)(EFI_SIGNATURE_32(E,F,G,H)) << 32)) + +// +// EFIAPI - prototype calling convention for EFI function pointers +// BOOTSERVICE - prototype for implementation of a boot service interface +// RUNTIMESERVICE - prototype for implementation of a runtime service interface +// RUNTIMEFUNCTION - prototype for implementation of a runtime function that is not a service +// RUNTIME_CODE - pragma macro for declaring runtime code +// + +#ifndef EFIAPI // Forces EFI calling conventions reguardless of compiler options +#define EFIAPI // Substitute expresion to force C calling convention +#endif + +#define BOOTSERVICE +#define RUNTIMESERVICE +#define RUNTIMEFUNCTION + + +#define RUNTIME_CODE(a) alloc_text("rtcode", a) +#define BEGIN_RUNTIME_DATA() data_seg("rtdata") +#define END_RUNTIME_DATA() data_seg("") + +#define VOLATILE volatile + +#define MEMORY_FENCE __sync_synchronize + +// +// When build similiar to FW, then link everything together as +// one big module. For the MSVC toolchain, we simply tell the +// linker what our driver init function is using /ENTRY. +// +#if defined(_MSC_EXTENSIONS) +#define EFI_DRIVER_ENTRY_POINT(InitFunction) \ + __pragma(comment(linker, "/ENTRY:" # InitFunction)) +#else +#define EFI_DRIVER_ENTRY_POINT(InitFunction) \ + UINTN \ + InitializeDriver ( \ + VOID *ImageHandle, \ + VOID *SystemTable \ + ) \ + { \ + return InitFunction(ImageHandle, \ + SystemTable); \ + } \ + \ + EFI_STATUS efi_main( \ + EFI_HANDLE image, \ + EFI_SYSTEM_TABLE *systab \ + ) __attribute__((weak, \ + alias ("InitializeDriver"))); +#endif + +#define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \ + (_if)->LoadInternal(type, name, entry) + + +// +// Some compilers don't support the forward reference construct: +// typedef struct XXXXX +// +// The following macro provide a workaround for such cases. + +#define INTERFACE_DECL(x) struct x + +#define uefi_call_wrapper(func, va_num, ...) func(__VA_ARGS__) +#define EFI_FUNCTION diff --git a/include/aarch64/efilibplat.h b/include/aarch64/efilibplat.h new file mode 100644 index 0000000..f3758af --- /dev/null +++ b/include/aarch64/efilibplat.h @@ -0,0 +1,25 @@ +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efilibplat.h + +Abstract: + + EFI to compile bindings + + + + +Revision History + +--*/ + +VOID +InitializeLibPlatform ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + diff --git a/include/aarch64/efisetjmp_arch.h b/include/aarch64/efisetjmp_arch.h new file mode 100644 index 0000000..14be3c8 --- /dev/null +++ b/include/aarch64/efisetjmp_arch.h @@ -0,0 +1,34 @@ +#ifndef GNU_EFI_AARCH64_SETJMP_H +#define GNU_EFI_AARCH64_SETJMP_H + +#define JMPBUF_ALIGN 8 + +typedef struct { + /* GP regs */ + UINT64 X19; + UINT64 X20; + UINT64 X21; + UINT64 X22; + UINT64 X23; + UINT64 X24; + UINT64 X25; + UINT64 X26; + UINT64 X27; + UINT64 X28; + UINT64 FP; + UINT64 LR; + UINT64 IP0; + UINT64 _pad1; + + /* FP regs */ + UINT64 D8; + UINT64 D9; + UINT64 D10; + UINT64 D11; + UINT64 D12; + UINT64 D13; + UINT64 D14; + UINT64 D15; +} EFI_ALIGN(JMPBUF_ALIGN) jmp_buf[1]; + +#endif /* GNU_EFI_AARCH64_SETJMP_H */ diff --git a/include/arm/efibind.h b/include/arm/efibind.h new file mode 100644 index 0000000..b9b0705 --- /dev/null +++ b/include/arm/efibind.h @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2014 - 2015 Linaro Ltd. + * Author: Ard Biesheuvel + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice and this list of conditions, without modification. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License as published by the Free Software Foundation; + * either version 2 of the License, or (at your option) any later version. + */ + +#if !defined(_MSC_VER) && (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L )) && !defined(__cplusplus) + +// ANSI C 1999/2000 stdint.h integer width declarations + +typedef unsigned long long uint64_t; +typedef long long int64_t; +typedef unsigned int uint32_t; +typedef int int32_t; +typedef unsigned short uint16_t; +typedef short int16_t; +typedef unsigned char uint8_t; +typedef signed char int8_t; // unqualified 'char' is unsigned on ARM +typedef uint32_t uintptr_t; +typedef int32_t intptr_t; + +#else +#include +#endif + +/* + * This prevents GCC from emitting GOT based relocations, and use R_ARM_REL32 + * relative relocations instead, which are more suitable for static binaries. + */ +#if defined(__GNUC__) && !__STDC_HOSTED__ +#pragma GCC visibility push (hidden) +#endif + +// +// Basic EFI types of various widths +// + +#include + +typedef wchar_t CHAR16; +#define WCHAR CHAR16 + +typedef uint64_t UINT64; +typedef int64_t INT64; + +typedef uint32_t UINT32; +typedef int32_t INT32; + +typedef uint16_t UINT16; +typedef int16_t INT16; + +typedef uint8_t UINT8; +typedef char CHAR8; +typedef int8_t INT8; + +#undef VOID +typedef void VOID; + +typedef int32_t INTN; +typedef uint32_t UINTN; + +#define EFIERR(a) (0x80000000 | a) +#define EFI_ERROR_MASK 0x80000000 +#define EFIERR_OEM(a) (0xc0000000 | a) + +#define BAD_POINTER 0xFBFBFBFB +#define MAX_ADDRESS 0xFFFFFFFF + +#define BREAKPOINT() while (TRUE); + +// +// Pointers must be aligned to these address to function +// + +#define MIN_ALIGNMENT_SIZE 4 + +#define ALIGN_VARIABLE(Value ,Adjustment) \ + (UINTN)Adjustment = 0; \ + if((UINTN)Value % MIN_ALIGNMENT_SIZE) \ + (UINTN)Adjustment = MIN_ALIGNMENT_SIZE - ((UINTN)Value % MIN_ALIGNMENT_SIZE); \ + Value = (UINTN)Value + (UINTN)Adjustment + + +// +// Define macros to build data structure signatures from characters. +// + +#define EFI_SIGNATURE_16(A,B) ((A) | (B<<8)) +#define EFI_SIGNATURE_32(A,B,C,D) (EFI_SIGNATURE_16(A,B) | (EFI_SIGNATURE_16(C,D) << 16)) +#define EFI_SIGNATURE_64(A,B,C,D,E,F,G,H) (EFI_SIGNATURE_32(A,B,C,D) | ((UINT64)(EFI_SIGNATURE_32(E,F,G,H)) << 32)) + +// +// EFIAPI - prototype calling convention for EFI function pointers +// BOOTSERVICE - prototype for implementation of a boot service interface +// RUNTIMESERVICE - prototype for implementation of a runtime service interface +// RUNTIMEFUNCTION - prototype for implementation of a runtime function that is not a service +// RUNTIME_CODE - pragma macro for declaring runtime code +// + +#ifndef EFIAPI // Forces EFI calling conventions reguardless of compiler options +#define EFIAPI // Substitute expresion to force C calling convention +#endif + +#define BOOTSERVICE +#define RUNTIMESERVICE +#define RUNTIMEFUNCTION + + +#define RUNTIME_CODE(a) alloc_text("rtcode", a) +#define BEGIN_RUNTIME_DATA() data_seg("rtdata") +#define END_RUNTIME_DATA() data_seg("") + +#define VOLATILE volatile + +#define MEMORY_FENCE __sync_synchronize + +// +// When build similiar to FW, then link everything together as +// one big module. For the MSVC toolchain, we simply tell the +// linker what our driver init function is using /ENTRY. +// +#if defined(_MSC_EXTENSIONS) +#define EFI_DRIVER_ENTRY_POINT(InitFunction) \ + __pragma(comment(linker, "/ENTRY:" # InitFunction)) +#else +#define EFI_DRIVER_ENTRY_POINT(InitFunction) \ + UINTN \ + InitializeDriver ( \ + VOID *ImageHandle, \ + VOID *SystemTable \ + ) \ + { \ + return InitFunction(ImageHandle, \ + SystemTable); \ + } \ + \ + EFI_STATUS efi_main( \ + EFI_HANDLE image, \ + EFI_SYSTEM_TABLE *systab \ + ) __attribute__((weak, \ + alias ("InitializeDriver"))); +#endif + +#define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \ + (_if)->LoadInternal(type, name, entry) + + +// +// Some compilers don't support the forward reference construct: +// typedef struct XXXXX +// +// The following macro provide a workaround for such cases. + +#define INTERFACE_DECL(x) struct x + +#define uefi_call_wrapper(func, va_num, ...) func(__VA_ARGS__) +#define EFI_FUNCTION diff --git a/include/arm/efilibplat.h b/include/arm/efilibplat.h new file mode 100644 index 0000000..f3758af --- /dev/null +++ b/include/arm/efilibplat.h @@ -0,0 +1,25 @@ +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efilibplat.h + +Abstract: + + EFI to compile bindings + + + + +Revision History + +--*/ + +VOID +InitializeLibPlatform ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + diff --git a/include/arm/efisetjmp_arch.h b/include/arm/efisetjmp_arch.h new file mode 100644 index 0000000..3c1d48c --- /dev/null +++ b/include/arm/efisetjmp_arch.h @@ -0,0 +1,21 @@ +#ifndef GNU_EFI_ARM_SETJMP_H +#define GNU_EFI_ARM_SETJMP_H + +#define JMPBUF_ALIGN 4 + +typedef struct { + UINT32 R3; // A copy of R13 + UINT32 R4; + UINT32 R5; + UINT32 R6; + UINT32 R7; + UINT32 R8; + UINT32 R9; + UINT32 R10; + UINT32 R11; + UINT32 R12; + UINT32 R13; + UINT32 R14; +} EFI_ALIGN(JMPBUF_ALIGN) jmp_buf[1]; + +#endif /* GNU_EFI_ARM_SETJMP_H */ diff --git a/include/compiler_defines.h b/include/compiler_defines.h new file mode 100644 index 0000000..d17ce4b --- /dev/null +++ b/include/compiler_defines.h @@ -0,0 +1,9 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + int _fltused = 0; // Or whatever type/value the linker expects, often just 0. +#ifdef __cplusplus +} +#endif diff --git a/include/efi.h b/include/efi.h new file mode 100644 index 0000000..7a98455 --- /dev/null +++ b/include/efi.h @@ -0,0 +1,91 @@ +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efi.h + +Abstract: + + Public EFI header files + + + +Revision History + +--*/ + + +// Add a predefined macro to detect usage of the library +#ifndef _GNU_EFI +#define _GNU_EFI +#endif + +// +// Build flags on input +// EFI32 +// EFI_DEBUG - Enable debugging code +// EFI_NT_EMULATOR - Building for running under NT +// + + +#ifndef _EFI_INCLUDE_ +#define _EFI_INCLUDE_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define EFI_FIRMWARE_VENDOR L"INTEL" +#define EFI_FIRMWARE_MAJOR_REVISION 12 +#define EFI_FIRMWARE_MINOR_REVISION 33 +#define EFI_FIRMWARE_REVISION ((EFI_FIRMWARE_MAJOR_REVISION <<16) | (EFI_FIRMWARE_MINOR_REVISION)) + +#if defined(_M_X64) || defined(__x86_64__) || defined(__amd64__) +#include "x86_64/efibind.h" +#elif defined(_M_IX86) || defined(__i386__) +#include "ia32/efibind.h" +#elif defined(_M_IA64) || defined(__ia64__) +#include "ia64/efibind.h" +#elif defined (_M_ARM64) || defined(__aarch64__) +#include "aarch64/efibind.h" +#elif defined (_M_ARM) || defined(__arm__) +#include "arm/efibind.h" +#elif defined (_M_MIPS64) || defined(__mips64__) || defined(__mips64) +#include "mips64el/efibind.h" +#elif defined (__riscv) && __riscv_xlen == 64 +#include "riscv64/efibind.h" +#elif defined (__loongarch64) +#include "loongarch64/efibind.h" +#else +#error Usupported architecture +#endif + +#include "eficompiler.h" +#include "efidef.h" +#include "legacy.h" +#include "efidevp.h" +#include "efipciio.h" +#include "efiprot.h" +#include "eficon.h" +#include "eficonex.h" +#include "efiser.h" +#include "efi_nii.h" +#include "efipxebc.h" +#include "efinet.h" +#include "efiapi.h" +#include "efifs.h" +#include "efierr.h" +#include "efiui.h" +#include "efiip.h" +#include "efiudp.h" +#include "efitcp.h" +#include "efipoint.h" +#include "efishell.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/efi_nii.h b/include/efi_nii.h new file mode 100644 index 0000000..ccd7d3f --- /dev/null +++ b/include/efi_nii.h @@ -0,0 +1,78 @@ +#ifndef _EFI_NII_H +#define _EFI_NII_H + +/*++ +Copyright (c) 2000 Intel Corporation + +Module name: + efi_nii.h + +Abstract: + +Revision history: + 2000-Feb-18 M(f)J GUID updated. + Structure order changed for machine word alignment. + Added StringId[4] to structure. + + 2000-Feb-14 M(f)J Genesis. +--*/ + +#define EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_GUID \ + { 0xE18541CD, 0xF755, 0x4f73, {0x92, 0x8D, 0x64, 0x3C, 0x8A, 0x79, 0xB2, 0x29} } + +#define EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION 0x00010000 +#define EFI_NETWORK_INTERFACE_IDENTIFIER_INTERFACE_REVISION EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION + +typedef enum { + EfiNetworkInterfaceUndi = 1 +} EFI_NETWORK_INTERFACE_TYPE; + +typedef struct _EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL { + + UINT64 Revision; + // Revision of the network interface identifier protocol interface. + + UINT64 ID; + // Address of the first byte of the identifying structure for this + // network interface. This is set to zero if there is no structure. + // + // For PXE/UNDI this is the first byte of the !PXE structure. + + UINT64 ImageAddr; + // Address of the UNrelocated driver/ROM image. This is set + // to zero if there is no driver/ROM image. + // + // For 16-bit UNDI, this is the first byte of the option ROM in + // upper memory. + // + // For 32/64-bit S/W UNDI, this is the first byte of the EFI ROM + // image. + // + // For H/W UNDI, this is set to zero. + + UINT32 ImageSize; + // Size of the UNrelocated driver/ROM image of this network interface. + // This is set to zero if there is no driver/ROM image. + + CHAR8 StringId[4]; + // 4 char ASCII string to go in class identifier (option 60) in DHCP + // and Boot Server discover packets. + // For EfiNetworkInterfaceUndi this field is "UNDI". + // For EfiNetworkInterfaceSnp this field is "SNPN". + + UINT8 Type; + UINT8 MajorVer; + UINT8 MinorVer; + // Information to be placed into the PXE DHCP and Discover packets. + // This is the network interface type and version number that will + // be placed into DHCP option 94 (client network interface identifier). + BOOLEAN Ipv6Supported; + UINT8 IfNum; // interface number to be used with pxeid structure +} EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL, EFI_NETWORK_INTERFACE_IDENTIFIER_INTERFACE; + +// Note: Because it conflicted with the EDK2 struct name, the +// 'EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL' GUID definition, +// from older versions of gnu-efi, is now obsoleted. +// Use 'EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_GUID' instead. + +#endif // _EFI_NII_H diff --git a/include/efi_pxe.h b/include/efi_pxe.h new file mode 100644 index 0000000..86f7f89 --- /dev/null +++ b/include/efi_pxe.h @@ -0,0 +1,1743 @@ +#ifndef _EFI_PXE_H +#define _EFI_PXE_H + + +/*++ +Copyright (c) Intel 1999 + +Module name: + efi_pxe.h + +32/64-bit PXE specification: + alpha-4, 99-Dec-17 + +Abstract: + This header file contains all of the PXE type definitions, + structure prototypes, global variables and constants that + are needed for porting PXE to EFI. +--*/ + +#pragma pack(1) + +#define PXE_INTEL_ORDER 1 // Intel order +//#define PXE_NETWORK_ORDER 1 // network order + +#define PXE_UINT64_SUPPORT 1 // UINT64 supported +//#define PXE_NO_UINT64_SUPPORT 1 // UINT64 not supported + +#define PXE_BUSTYPE(a,b,c,d) \ +((((PXE_UINT32)(d) & 0xFF) << 24) | \ +(((PXE_UINT32)(c) & 0xFF) << 16) | \ +(((PXE_UINT32)(b) & 0xFF) << 8) | \ +((PXE_UINT32)(a) & 0xFF)) + +// +// UNDI ROM ID and devive ID signature +// +#define PXE_BUSTYPE_PXE PXE_BUSTYPE('!', 'P', 'X', 'E') + +// +// BUS ROM ID signatures +// +#define PXE_BUSTYPE_PCI PXE_BUSTYPE('P', 'C', 'I', 'R') +#define PXE_BUSTYPE_PC_CARD PXE_BUSTYPE('P', 'C', 'C', 'R') +#define PXE_BUSTYPE_USB PXE_BUSTYPE('U', 'S', 'B', 'R') +#define PXE_BUSTYPE_1394 PXE_BUSTYPE('1', '3', '9', '4') + +#define PXE_SWAP_UINT16(n) \ +((((PXE_UINT16)(n) & 0x00FF) << 8) | \ +(((PXE_UINT16)(n) & 0xFF00) >> 8)) + +#define PXE_SWAP_UINT32(n) \ +((((PXE_UINT32)(n) & 0x000000FF) << 24) | \ +(((PXE_UINT32)(n) & 0x0000FF00) << 8) | \ +(((PXE_UINT32)(n) & 0x00FF0000) >> 8) | \ +(((PXE_UINT32)(n) & 0xFF000000) >> 24)) + +#if PXE_UINT64_SUPPORT != 0 +#define PXE_SWAP_UINT64(n) \ +((((PXE_UINT64)(n) & 0x00000000000000FF) << 56) | \ +(((PXE_UINT64)(n) & 0x000000000000FF00) << 40) | \ +(((PXE_UINT64)(n) & 0x0000000000FF0000) << 24) | \ +(((PXE_UINT64)(n) & 0x00000000FF000000) << 8) | \ +(((PXE_UINT64)(n) & 0x000000FF00000000) >> 8) | \ +(((PXE_UINT64)(n) & 0x0000FF0000000000) >> 24) | \ +(((PXE_UINT64)(n) & 0x00FF000000000000) >> 40) | \ +(((PXE_UINT64)(n) & 0xFF00000000000000) >> 56)) +#endif // PXE_UINT64_SUPPORT + +#if PXE_NO_UINT64_SUPPORT != 0 +#define PXE_SWAP_UINT64(n) \ +{ \ +PXE_UINT32 tmp = (PXE_UINT64)(n)[1]; \ +(PXE_UINT64)(n)[1] = PXE_SWAP_UINT32((PXE_UINT64)(n)[0]); \ +(PXE_UINT64)(n)[0] = tmp; \ +} +#endif // PXE_NO_UINT64_SUPPORT + +#define PXE_CPBSIZE_NOT_USED 0 // zero +#define PXE_DBSIZE_NOT_USED 0 // zero +#define PXE_CPBADDR_NOT_USED (PXE_UINT64)0 // zero +#define PXE_DBADDR_NOT_USED (PXE_UINT64)0 // zero + +#define PXE_CONST const + +#define PXE_VOLATILE volatile + +typedef void PXE_VOID; + +typedef unsigned char PXE_UINT8; + +typedef unsigned short PXE_UINT16; + +typedef unsigned PXE_UINT32; + +#if PXE_UINT64_SUPPORT != 0 +// typedef unsigned long PXE_UINT64; +typedef UINT64 PXE_UINT64; +#endif // PXE_UINT64_SUPPORT + +#if PXE_NO_UINT64_SUPPORT != 0 +typedef PXE_UINT32 PXE_UINT64[2]; +#endif // PXE_NO_UINT64_SUPPORT + +typedef unsigned PXE_UINTN; + +typedef PXE_UINT8 PXE_BOOL; + +#define PXE_FALSE 0 // zero +#define PXE_TRUE (!PXE_FALSE) + +typedef PXE_UINT16 PXE_OPCODE; + +// +// Return UNDI operational state. +// +#define PXE_OPCODE_GET_STATE 0x0000 + +// +// Change UNDI operational state from Stopped to Started. +// +#define PXE_OPCODE_START 0x0001 + +// +// Change UNDI operational state from Started to Stopped. +// +#define PXE_OPCODE_STOP 0x0002 + +// +// Get UNDI initialization information. +// +#define PXE_OPCODE_GET_INIT_INFO 0x0003 + +// +// Get NIC configuration information. +// +#define PXE_OPCODE_GET_CONFIG_INFO 0x0004 + +// +// Changed UNDI operational state from Started to Initialized. +// +#define PXE_OPCODE_INITIALIZE 0x0005 + +// +// Re-initialize the NIC H/W. +// +#define PXE_OPCODE_RESET 0x0006 + +// +// Change the UNDI operational state from Initialized to Started. +// +#define PXE_OPCODE_SHUTDOWN 0x0007 + +// +// Read & change state of external interrupt enables. +// +#define PXE_OPCODE_INTERRUPT_ENABLES 0x0008 + +// +// Read & change state of packet receive filters. +// +#define PXE_OPCODE_RECEIVE_FILTERS 0x0009 + +// +// Read & change station MAC address. +// +#define PXE_OPCODE_STATION_ADDRESS 0x000A + +// +// Read traffic statistics. +// +#define PXE_OPCODE_STATISTICS 0x000B + +// +// Convert multicast IP address to multicast MAC address. +// +#define PXE_OPCODE_MCAST_IP_TO_MAC 0x000C + +// +// Read or change non-volatile storage on the NIC. +// +#define PXE_OPCODE_NVDATA 0x000D + +// +// Get & clear interrupt status. +// +#define PXE_OPCODE_GET_STATUS 0x000E + +// +// Fill media header in packet for transmit. +// +#define PXE_OPCODE_FILL_HEADER 0x000F + +// +// Transmit packet(s). +// +#define PXE_OPCODE_TRANSMIT 0x0010 + +// +// Receive packet. +// +#define PXE_OPCODE_RECEIVE 0x0011 + +// last valid opcode: +#define PXE_OPCODE_VALID_MAX 0x0011 + +// +// Last valid PXE UNDI OpCode number. +// +#define PXE_OPCODE_LAST_VALID 0x0011 + +typedef PXE_UINT16 PXE_OPFLAGS; + +#define PXE_OPFLAGS_NOT_USED 0x0000 + +//////////////////////////////////////// +// UNDI Get State +// + +// No OpFlags + +//////////////////////////////////////// +// UNDI Start +// + +// No OpFlags + +//////////////////////////////////////// +// UNDI Stop +// + +// No OpFlags + +//////////////////////////////////////// +// UNDI Get Init Info +// + +// No Opflags + +//////////////////////////////////////// +// UNDI Get Config Info +// + +// No Opflags + +//////////////////////////////////////// +// UNDI Initialize +// + +#define PXE_OPFLAGS_INITIALIZE_CABLE_DETECT_MASK 0x0001 +#define PXE_OPFLAGS_INITIALIZE_DETECT_CABLE 0x0000 +#define PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE 0x0001 + +//////////////////////////////////////// +// UNDI Reset +// + +#define PXE_OPFLAGS_RESET_DISABLE_INTERRUPTS 0x0001 +#define PXE_OPFLAGS_RESET_DISABLE_FILTERS 0x0002 + +//////////////////////////////////////// +// UNDI Shutdown +// + +// No OpFlags + +//////////////////////////////////////// +// UNDI Interrupt Enables +// + +// +// Select whether to enable or disable external interrupt signals. +// Setting both enable and disable will return PXE_STATCODE_INVALID_OPFLAGS. +// +#define PXE_OPFLAGS_INTERRUPT_OPMASK 0xC000 +#define PXE_OPFLAGS_INTERRUPT_ENABLE 0x8000 +#define PXE_OPFLAGS_INTERRUPT_DISABLE 0x4000 +#define PXE_OPFLAGS_INTERRUPT_READ 0x0000 + +// +// Enable receive interrupts. An external interrupt will be generated +// after a complete non-error packet has been received. +// +#define PXE_OPFLAGS_INTERRUPT_RECEIVE 0x0001 + +// +// Enable transmit interrupts. An external interrupt will be generated +// after a complete non-error packet has been transmitted. +// +#define PXE_OPFLAGS_INTERRUPT_TRANSMIT 0x0002 + +// +// Enable command interrupts. An external interrupt will be generated +// when command execution stops. +// +#define PXE_OPFLAGS_INTERRUPT_COMMAND 0x0004 + +// +// Generate software interrupt. Setting this bit generates an external +// interrupt, if it is supported by the hardware. +// +#define PXE_OPFLAGS_INTERRUPT_SOFTWARE 0x0008 + +//////////////////////////////////////// +// UNDI Receive Filters +// + +// +// Select whether to enable or disable receive filters. +// Setting both enable and disable will return PXE_STATCODE_INVALID_OPCODE. +// +#define PXE_OPFLAGS_RECEIVE_FILTER_OPMASK 0xC000 +#define PXE_OPFLAGS_RECEIVE_FILTER_ENABLE 0x8000 +#define PXE_OPFLAGS_RECEIVE_FILTER_DISABLE 0x4000 +#define PXE_OPFLAGS_RECEIVE_FILTER_READ 0x0000 + +// +// To reset the contents of the multicast MAC address filter list, +// set this OpFlag: +// +#define PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST 0x2000 + +// +// Enable unicast packet receiving. Packets sent to the current station +// MAC address will be received. +// +#define PXE_OPFLAGS_RECEIVE_FILTER_UNICAST 0x0001 + +// +// Enable broadcast packet receiving. Packets sent to the broadcast +// MAC address will be received. +// +#define PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST 0x0002 + +// +// Enable filtered multicast packet receiving. Packets sent to any +// of the multicast MAC addresses in the multicast MAC address filter +// list will be received. If the filter list is empty, no multicast +// +#define PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST 0x0004 + +// +// Enable promiscuous packet receiving. All packets will be received. +// +#define PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS 0x0008 + +// +// Enable promiscuous multicast packet receiving. All multicast +// packets will be received. +// +#define PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST 0x0010 + +//////////////////////////////////////// +// UNDI Station Address +// + +#define PXE_OPFLAGS_STATION_ADDRESS_READ 0x0000 +#define PXE_OPFLAGS_STATION_ADDRESS_RESET 0x0001 + +//////////////////////////////////////// +// UNDI Statistics +// + +#define PXE_OPFLAGS_STATISTICS_READ 0x0000 +#define PXE_OPFLAGS_STATISTICS_RESET 0x0001 + +//////////////////////////////////////// +// UNDI MCast IP to MAC +// + +// +// Identify the type of IP address in the CPB. +// +#define PXE_OPFLAGS_MCAST_IP_TO_MAC_OPMASK 0x0003 +#define PXE_OPFLAGS_MCAST_IPV4_TO_MAC 0x0000 +#define PXE_OPFLAGS_MCAST_IPV6_TO_MAC 0x0001 + +//////////////////////////////////////// +// UNDI NvData +// + +// +// Select the type of non-volatile data operation. +// +#define PXE_OPFLAGS_NVDATA_OPMASK 0x0001 +#define PXE_OPFLAGS_NVDATA_READ 0x0000 +#define PXE_OPFLAGS_NVDATA_WRITE 0x0001 + +//////////////////////////////////////// +// UNDI Get Status +// + +// +// Return current interrupt status. This will also clear any interrupts +// that are currently set. This can be used in a polling routine. The +// interrupt flags are still set and cleared even when the interrupts +// are disabled. +// +#define PXE_OPFLAGS_GET_INTERRUPT_STATUS 0x0001 + +// +// Return list of transmitted buffers for recycling. Transmit buffers +// must not be changed or unallocated until they have recycled. After +// issuing a transmit command, wait for a transmit complete interrupt. +// When a transmit complete interrupt is received, read the transmitted +// buffers. Do not plan on getting one buffer per interrupt. Some +// NICs and UNDIs may transmit multiple buffers per interrupt. +// +#define PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS 0x0002 + +//////////////////////////////////////// +// UNDI Fill Header +// + +#define PXE_OPFLAGS_FILL_HEADER_OPMASK 0x0001 +#define PXE_OPFLAGS_FILL_HEADER_FRAGMENTED 0x0001 +#define PXE_OPFLAGS_FILL_HEADER_WHOLE 0x0000 + +//////////////////////////////////////// +// UNDI Transmit +// + +// +// S/W UNDI only. Return after the packet has been transmitted. A +// transmit complete interrupt will still be generated and the transmit +// buffer will have to be recycled. +// +#define PXE_OPFLAGS_SWUNDI_TRANSMIT_OPMASK 0x0001 +#define PXE_OPFLAGS_TRANSMIT_BLOCK 0x0001 +#define PXE_OPFLAGS_TRANSMIT_DONT_BLOCK 0x0000 + +// +// +// +#define PXE_OPFLAGS_TRANSMIT_OPMASK 0x0002 +#define PXE_OPFLAGS_TRANSMIT_FRAGMENTED 0x0002 +#define PXE_OPFLAGS_TRANSMIT_WHOLE 0x0000 + +//////////////////////////////////////// +// UNDI Receive +// + +// No OpFlags + +typedef PXE_UINT16 PXE_STATFLAGS; + +#define PXE_STATFLAGS_INITIALIZE 0x0000 + +//////////////////////////////////////// +// Common StatFlags that can be returned by all commands. +// + +// +// The COMMAND_COMPLETE and COMMAND_FAILED status flags must be +// implemented by all UNDIs. COMMAND_QUEUED is only needed by UNDIs +// that support command queuing. +// +#define PXE_STATFLAGS_STATUS_MASK 0xC000 +#define PXE_STATFLAGS_COMMAND_COMPLETE 0xC000 +#define PXE_STATFLAGS_COMMAND_FAILED 0x8000 +#define PXE_STATFLAGS_COMMAND_QUEUED 0x4000 +//#define PXE_STATFLAGS_INITIALIZE 0x0000 + +#define PXE_STATFLAGS_DB_WRITE_TRUNCATED 0x2000 + +//////////////////////////////////////// +// UNDI Get State +// + +#define PXE_STATFLAGS_GET_STATE_MASK 0x0003 +#define PXE_STATFLAGS_GET_STATE_INITIALIZED 0x0002 +#define PXE_STATFLAGS_GET_STATE_STARTED 0x0001 +#define PXE_STATFLAGS_GET_STATE_STOPPED 0x0000 + +//////////////////////////////////////// +// UNDI Start +// + +// No additional StatFlags + +//////////////////////////////////////// +// UNDI Get Init Info +// + +#define PXE_STATFLAGS_CABLE_DETECT_MASK 0x0001 +#define PXE_STATFLAGS_CABLE_DETECT_NOT_SUPPORTED 0x0000 +#define PXE_STATFLAGS_CABLE_DETECT_SUPPORTED 0x0001 + + +//////////////////////////////////////// +// UNDI Initialize +// + +#define PXE_STATFLAGS_INITIALIZED_NO_MEDIA 0x0001 + +//////////////////////////////////////// +// UNDI Reset +// + +#define PXE_STATFLAGS_RESET_NO_MEDIA 0x0001 + +//////////////////////////////////////// +// UNDI Shutdown +// + +// No additional StatFlags + +//////////////////////////////////////// +// UNDI Interrupt Enables +// + +// +// If set, receive interrupts are enabled. +// +#define PXE_STATFLAGS_INTERRUPT_RECEIVE 0x0001 + +// +// If set, transmit interrupts are enabled. +// +#define PXE_STATFLAGS_INTERRUPT_TRANSMIT 0x0002 + +// +// If set, command interrupts are enabled. +// +#define PXE_STATFLAGS_INTERRUPT_COMMAND 0x0004 + + +//////////////////////////////////////// +// UNDI Receive Filters +// + +// +// If set, unicast packets will be received. +// +#define PXE_STATFLAGS_RECEIVE_FILTER_UNICAST 0x0001 + +// +// If set, broadcast packets will be received. +// +#define PXE_STATFLAGS_RECEIVE_FILTER_BROADCAST 0x0002 + +// +// If set, multicast packets that match up with the multicast address +// filter list will be received. +// +#define PXE_STATFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST 0x0004 + +// +// If set, all packets will be received. +// +#define PXE_STATFLAGS_RECEIVE_FILTER_PROMISCUOUS 0x0008 + +// +// If set, all multicast packets will be received. +// +#define PXE_STATFLAGS_RECEIVE_FILTER_ALL_MULTICAST 0x0010 + +//////////////////////////////////////// +// UNDI Station Address +// + +// No additional StatFlags + +//////////////////////////////////////// +// UNDI Statistics +// + +// No additional StatFlags + +//////////////////////////////////////// +// UNDI MCast IP to MAC +// + +// No additional StatFlags + +//////////////////////////////////////// +// UNDI NvData +// + +// No additional StatFlags + + +//////////////////////////////////////// +// UNDI Get Status +// + +// +// Use to determine if an interrupt has occurred. +// +#define PXE_STATFLAGS_GET_STATUS_INTERRUPT_MASK 0x000F +#define PXE_STATFLAGS_GET_STATUS_NO_INTERRUPTS 0x0000 + +// +// If set, at least one receive interrupt occurred. +// +#define PXE_STATFLAGS_GET_STATUS_RECEIVE 0x0001 + +// +// If set, at least one transmit interrupt occurred. +// +#define PXE_STATFLAGS_GET_STATUS_TRANSMIT 0x0002 + +// +// If set, at least one command interrupt occurred. +// +#define PXE_STATFLAGS_GET_STATUS_COMMAND 0x0004 + +// +// If set, at least one software interrupt occurred. +// +#define PXE_STATFLAGS_GET_STATUS_SOFTWARE 0x0008 + +// +// This flag is set if the transmitted buffer queue is empty. This flag +// will be set if all transmitted buffer addresses get written into the DB. +// +#define PXE_STATFLAGS_GET_STATUS_TXBUF_QUEUE_EMPTY 0x0010 + +// +// This flag is set if no transmitted buffer addresses were written +// into the DB. (This could be because DBsize was too small.) +// +#define PXE_STATFLAGS_GET_STATUS_NO_TXBUFS_WRITTEN 0x0020 + +//////////////////////////////////////// +// UNDI Fill Header +// + +// No additional StatFlags + +//////////////////////////////////////// +// UNDI Transmit +// + +// No additional StatFlags. + +//////////////////////////////////////// +// UNDI Receive +// + +// No additional StatFlags. + +typedef PXE_UINT16 PXE_STATCODE; + +#define PXE_STATCODE_INITIALIZE 0x0000 + +//////////////////////////////////////// +// Common StatCodes returned by all UNDI commands, UNDI protocol functions +// and BC protocol functions. +// + +#define PXE_STATCODE_SUCCESS 0x0000 + +#define PXE_STATCODE_INVALID_CDB 0x0001 +#define PXE_STATCODE_INVALID_CPB 0x0002 +#define PXE_STATCODE_BUSY 0x0003 +#define PXE_STATCODE_QUEUE_FULL 0x0004 +#define PXE_STATCODE_ALREADY_STARTED 0x0005 +#define PXE_STATCODE_NOT_STARTED 0x0006 +#define PXE_STATCODE_NOT_SHUTDOWN 0x0007 +#define PXE_STATCODE_ALREADY_INITIALIZED 0x0008 +#define PXE_STATCODE_NOT_INITIALIZED 0x0009 +#define PXE_STATCODE_DEVICE_FAILURE 0x000A +#define PXE_STATCODE_NVDATA_FAILURE 0x000B +#define PXE_STATCODE_UNSUPPORTED 0x000C +#define PXE_STATCODE_BUFFER_FULL 0x000D +#define PXE_STATCODE_INVALID_PARAMETER 0x000E +#define PXE_STATCODE_INVALID_UNDI 0x000F +#define PXE_STATCODE_IPV4_NOT_SUPPORTED 0x0010 +#define PXE_STATCODE_IPV6_NOT_SUPPORTED 0x0011 +#define PXE_STATCODE_NOT_ENOUGH_MEMORY 0x0012 +#define PXE_STATCODE_NO_DATA 0x0013 + + +typedef PXE_UINT16 PXE_IFNUM; + +// +// This interface number must be passed to the S/W UNDI Start command. +// +#define PXE_IFNUM_START 0x0000 + +// +// This interface number is returned by the S/W UNDI Get State and +// Start commands if information in the CDB, CPB or DB is invalid. +// +#define PXE_IFNUM_INVALID 0x0000 + +typedef PXE_UINT16 PXE_CONTROL; + +// +// Setting this flag directs the UNDI to queue this command for later +// execution if the UNDI is busy and it supports command queuing. +// If queuing is not supported, a PXE_STATCODE_INVALID_CONTROL error +// is returned. If the queue is full, a PXE_STATCODE_CDB_QUEUE_FULL +// error is returned. +// +#define PXE_CONTROL_QUEUE_IF_BUSY 0x0002 + +// +// These two bit values are used to determine if there are more UNDI +// CDB structures following this one. If the link bit is set, there +// must be a CDB structure following this one. Execution will start +// on the next CDB structure as soon as this one completes successfully. +// If an error is generated by this command, execution will stop. +// +#define PXE_CONTROL_LINK 0x0001 +#define PXE_CONTROL_LAST_CDB_IN_LIST 0x0000 + +typedef PXE_UINT8 PXE_FRAME_TYPE; + +#define PXE_FRAME_TYPE_NONE 0x00 +#define PXE_FRAME_TYPE_UNICAST 0x01 +#define PXE_FRAME_TYPE_BROADCAST 0x02 +#define PXE_FRAME_TYPE_MULTICAST 0x03 +#define PXE_FRAME_TYPE_PROMISCUOUS 0x04 + +typedef PXE_UINT32 PXE_IPV4; + +typedef PXE_UINT32 PXE_IPV6[4]; +#define PXE_MAC_LENGTH 32 + +typedef PXE_UINT8 PXE_MAC_ADDR[PXE_MAC_LENGTH]; + +typedef PXE_UINT8 PXE_IFTYPE; +typedef PXE_UINT16 PXE_MEDIA_PROTOCOL; + +// +// This information is from the ARP section of RFC 1700. +// +// 1 Ethernet (10Mb) [JBP] +// 2 Experimental Ethernet (3Mb) [JBP] +// 3 Amateur Radio AX.25 [PXK] +// 4 Proteon ProNET Token Ring [JBP] +// 5 Chaos [GXP] +// 6 IEEE 802 Networks [JBP] +// 7 ARCNET [JBP] +// 8 Hyperchannel [JBP] +// 9 Lanstar [TU] +// 10 Autonet Short Address [MXB1] +// 11 LocalTalk [JKR1] +// 12 LocalNet (IBM PCNet or SYTEK LocalNET) [JXM] +// 13 Ultra link [RXD2] +// 14 SMDS [GXC1] +// 15 Frame Relay [AGM] +// 16 Asynchronous Transmission Mode (ATM) [JXB2] +// 17 HDLC [JBP] +// 18 Fibre Channel [Yakov Rekhter] +// 19 Asynchronous Transmission Mode (ATM) [Mark Laubach] +// 20 Serial Line [JBP] +// 21 Asynchronous Transmission Mode (ATM) [MXB1] +// + +#define PXE_IFTYPE_ETHERNET 0x01 +#define PXE_IFTYPE_TOKENRING 0x04 +#define PXE_IFTYPE_FIBRE_CHANNEL 0x12 + +typedef struct s_pxe_hw_undi { +PXE_UINT32 Signature; // PXE_ROMID_SIGNATURE +PXE_UINT8 Len; // sizeof(PXE_HW_UNDI) +PXE_UINT8 Fudge; // makes 8-bit cksum equal zero +PXE_UINT8 Rev; // PXE_ROMID_REV +PXE_UINT8 IFcnt; // physical connector count +PXE_UINT8 MajorVer; // PXE_ROMID_MAJORVER +PXE_UINT8 MinorVer; // PXE_ROMID_MINORVER +PXE_UINT16 reserved; // zero, not used +PXE_UINT32 Implementation; // implementation flags +// reserved // vendor use +// PXE_UINT32 Status; // status port +// PXE_UINT32 Command; // command port +// PXE_UINT64 CDBaddr; // CDB address port +} PXE_HW_UNDI; + +// +// Status port bit definitions +// + +// +// UNDI operation state +// +#define PXE_HWSTAT_STATE_MASK 0xC0000000 +#define PXE_HWSTAT_BUSY 0xC0000000 +#define PXE_HWSTAT_INITIALIZED 0x80000000 +#define PXE_HWSTAT_STARTED 0x40000000 +#define PXE_HWSTAT_STOPPED 0x00000000 + +// +// If set, last command failed +// +#define PXE_HWSTAT_COMMAND_FAILED 0x20000000 + +// +// If set, identifies enabled receive filters +// +#define PXE_HWSTAT_PROMISCUOUS_MULTICAST_RX_ENABLED 0x00001000 +#define PXE_HWSTAT_PROMISCUOUS_RX_ENABLED 0x00000800 +#define PXE_HWSTAT_BROADCAST_RX_ENABLED 0x00000400 +#define PXE_HWSTAT_MULTICAST_RX_ENABLED 0x00000200 +#define PXE_HWSTAT_UNICAST_RX_ENABLED 0x00000100 + +// +// If set, identifies enabled external interrupts +// +#define PXE_HWSTAT_SOFTWARE_INT_ENABLED 0x00000080 +#define PXE_HWSTAT_TX_COMPLETE_INT_ENABLED 0x00000040 +#define PXE_HWSTAT_PACKET_RX_INT_ENABLED 0x00000020 +#define PXE_HWSTAT_CMD_COMPLETE_INT_ENABLED 0x00000010 + +// +// If set, identifies pending interrupts +// +#define PXE_HWSTAT_SOFTWARE_INT_PENDING 0x00000008 +#define PXE_HWSTAT_TX_COMPLETE_INT_PENDING 0x00000004 +#define PXE_HWSTAT_PACKET_RX_INT_PENDING 0x00000002 +#define PXE_HWSTAT_CMD_COMPLETE_INT_PENDING 0x00000001 + +// +// Command port definitions +// + +// +// If set, CDB identified in CDBaddr port is given to UNDI. +// If not set, other bits in this word will be processed. +// +#define PXE_HWCMD_ISSUE_COMMAND 0x80000000 +#define PXE_HWCMD_INTS_AND_FILTS 0x00000000 + +// +// Use these to enable/disable receive filters. +// +#define PXE_HWCMD_PROMISCUOUS_MULTICAST_RX_ENABLE 0x00001000 +#define PXE_HWCMD_PROMISCUOUS_RX_ENABLE 0x00000800 +#define PXE_HWCMD_BROADCAST_RX_ENABLE 0x00000400 +#define PXE_HWCMD_MULTICAST_RX_ENABLE 0x00000200 +#define PXE_HWCMD_UNICAST_RX_ENABLE 0x00000100 + +// +// Use these to enable/disable external interrupts +// +#define PXE_HWCMD_SOFTWARE_INT_ENABLE 0x00000080 +#define PXE_HWCMD_TX_COMPLETE_INT_ENABLE 0x00000040 +#define PXE_HWCMD_PACKET_RX_INT_ENABLE 0x00000020 +#define PXE_HWCMD_CMD_COMPLETE_INT_ENABLE 0x00000010 + +// +// Use these to clear pending external interrupts +// +#define PXE_HWCMD_CLEAR_SOFTWARE_INT 0x00000008 +#define PXE_HWCMD_CLEAR_TX_COMPLETE_INT 0x00000004 +#define PXE_HWCMD_CLEAR_PACKET_RX_INT 0x00000002 +#define PXE_HWCMD_CLEAR_CMD_COMPLETE_INT 0x00000001 + +typedef struct s_pxe_sw_undi { +PXE_UINT32 Signature; // PXE_ROMID_SIGNATURE +PXE_UINT8 Len; // sizeof(PXE_SW_UNDI) +PXE_UINT8 Fudge; // makes 8-bit cksum zero +PXE_UINT8 Rev; // PXE_ROMID_REV +PXE_UINT8 IFcnt; // physical connector count +PXE_UINT8 MajorVer; // PXE_ROMID_MAJORVER +PXE_UINT8 MinorVer; // PXE_ROMID_MINORVER +PXE_UINT16 reserved1; // zero, not used +PXE_UINT32 Implementation; // Implementation flags +PXE_UINT64 EntryPoint; // API entry point +PXE_UINT8 reserved2[3]; // zero, not used +PXE_UINT8 BusCnt; // number of bustypes supported +PXE_UINT32 BusType[1]; // list of supported bustypes +} PXE_SW_UNDI; + +typedef union u_pxe_undi { +PXE_HW_UNDI hw; +PXE_SW_UNDI sw; +} PXE_UNDI; + +// +// Signature of !PXE structure +// +#define PXE_ROMID_SIGNATURE PXE_BUSTYPE('!', 'P', 'X', 'E') + +// +// !PXE structure format revision +// +#define PXE_ROMID_REV 0x02 + +// +// UNDI command interface revision. These are the values that get sent +// in option 94 (Client Network Interface Identifier) in the DHCP Discover +// and PXE Boot Server Request packets. +// +#define PXE_ROMID_MAJORVER 0x03 +#define PXE_ROMID_MINORVER 0x00 + +// +// Implementation flags +// +#define PXE_ROMID_IMP_HW_UNDI 0x80000000 +#define PXE_ROMID_IMP_SW_VIRT_ADDR 0x40000000 +#define PXE_ROMID_IMP_64BIT_DEVICE 0x00010000 +#define PXE_ROMID_IMP_FRAG_SUPPORTED 0x00008000 +#define PXE_ROMID_IMP_CMD_LINK_SUPPORTED 0x00004000 +#define PXE_ROMID_IMP_CMD_QUEUE_SUPPORTED 0x00002000 +#define PXE_ROMID_IMP_MULTI_FRAME_SUPPORTED 0x00001000 +#define PXE_ROMID_IMP_NVDATA_SUPPORT_MASK 0x00000C00 +#define PXE_ROMID_IMP_NVDATA_BULK_WRITABLE 0x00000C00 +#define PXE_ROMID_IMP_NVDATA_SPARSE_WRITABLE 0x00000800 +#define PXE_ROMID_IMP_NVDATA_READ_ONLY 0x00000400 +#define PXE_ROMID_IMP_NVDATA_NOT_AVAILABLE 0x00000000 +#define PXE_ROMID_IMP_STATISTICS_SUPPORTED 0x00000200 +#define PXE_ROMID_IMP_STATION_ADDR_SETTABLE 0x00000100 +#define PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED 0x00000080 +#define PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED 0x00000040 +#define PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED 0x00000020 +#define PXE_ROMID_IMP_FILTERED_MULTICAST_RX_SUPPORTED 0x00000010 +#define PXE_ROMID_IMP_SOFTWARE_INT_SUPPORTED 0x00000008 +#define PXE_ROMID_IMP_TX_COMPLETE_INT_SUPPORTED 0x00000004 +#define PXE_ROMID_IMP_PACKET_RX_INT_SUPPORTED 0x00000002 +#define PXE_ROMID_IMP_CMD_COMPLETE_INT_SUPPORTED 0x00000001 + + +typedef struct s_pxe_cdb { +PXE_OPCODE OpCode; +PXE_OPFLAGS OpFlags; +PXE_UINT16 CPBsize; +PXE_UINT16 DBsize; +UINT64 CPBaddr; +UINT64 DBaddr; +PXE_STATCODE StatCode; +PXE_STATFLAGS StatFlags; +PXE_UINT16 IFnum; +PXE_CONTROL Control; +} PXE_CDB; + + +typedef union u_pxe_ip_addr { +PXE_IPV6 IPv6; +PXE_IPV4 IPv4; +} PXE_IP_ADDR; + +typedef union pxe_device { +// +// PCI and PC Card NICs are both identified using bus, device +// and function numbers. For PC Card, this may require PC +// Card services to be loaded in the BIOS or preboot +// environment. +// +struct { +// +// See S/W UNDI ROMID structure definition for PCI and +// PCC BusType definitions. +// +PXE_UINT32 BusType; + +// +// Bus, device & function numbers that locate this device. +// +PXE_UINT16 Bus; +PXE_UINT8 Device; +PXE_UINT8 Function; +} PCI, PCC; + +// +// %%TBD - More information is needed about enumerating +// USB and 1394 devices. +// +struct { +PXE_UINT32 BusType; +PXE_UINT32 tdb; +} USB, _1394; +} PXE_DEVICE; + +// cpb and db definitions + +#define MAX_PCI_CONFIG_LEN 64 // # of dwords +#define MAX_EEPROM_LEN 128 // #of dwords +#define MAX_XMIT_BUFFERS 32 // recycling Q length for xmit_done +#define MAX_MCAST_ADDRESS_CNT 8 + +typedef struct s_pxe_cpb_start { + // + // PXE_VOID Delay(PXE_UINT64 microseconds); + // + // UNDI will never request a delay smaller than 10 microseconds + // and will always request delays in increments of 10 microseconds. + // The Delay() CallBack routine must delay between n and n + 10 + // microseconds before returning control to the UNDI. + // + // This field cannot be set to zero. + // + PXE_UINT64 Delay; + + // + // PXE_VOID Block(PXE_UINT32 enable); + // + // UNDI may need to block multi-threaded/multi-processor access to + // critical code sections when programming or accessing the network + // device. To this end, a blocking service is needed by the UNDI. + // When UNDI needs a block, it will call Block() passing a non-zero + // value. When UNDI no longer needs a block, it will call Block() + // with a zero value. When called, if the Block() is already enabled, + // do not return control to the UNDI until the previous Block() is + // disabled. + // + // This field cannot be set to zero. + // + PXE_UINT64 Block; + + // + // PXE_VOID Virt2Phys(PXE_UINT64 virtual, PXE_UINT64 physical_ptr); + // + // UNDI will pass the virtual address of a buffer and the virtual + // address of a 64-bit physical buffer. Convert the virtual address + // to a physical address and write the result to the physical address + // buffer. If virtual and physical addresses are the same, just + // copy the virtual address to the physical address buffer. + // + // This field can be set to zero if virtual and physical addresses + // are equal. + // + PXE_UINT64 Virt2Phys; + // + // PXE_VOID Mem_IO(PXE_UINT8 read_write, PXE_UINT8 len, PXE_UINT64 port, + // PXE_UINT64 buf_addr); + // + // UNDI will read or write the device io space using this call back + // function. It passes the number of bytes as the len parameter and it + // will be either 1,2,4 or 8. + // + // This field can not be set to zero. + // + PXE_UINT64 Mem_IO; +} PXE_CPB_START; + +#define PXE_DELAY_MILLISECOND 1000 +#define PXE_DELAY_SECOND 1000000 +#define PXE_IO_READ 0 +#define PXE_IO_WRITE 1 +#define PXE_MEM_READ 2 +#define PXE_MEM_WRITE 4 + + +typedef struct s_pxe_db_get_init_info { + // + // Minimum length of locked memory buffer that must be given to + // the Initialize command. Giving UNDI more memory will generally + // give better performance. + // + // If MemoryRequired is zero, the UNDI does not need and will not + // use system memory to receive and transmit packets. + // + PXE_UINT32 MemoryRequired; + + // + // Maximum frame data length for Tx/Rx excluding the media header. + // + PXE_UINT32 FrameDataLen; + + // + // Supported link speeds are in units of mega bits. Common ethernet + // values are 10, 100 and 1000. Unused LinkSpeeds[] entries are zero + // filled. + // + PXE_UINT32 LinkSpeeds[4]; + + // + // Number of non-volatile storage items. + // + PXE_UINT32 NvCount; + + // + // Width of non-volatile storage item in bytes. 0, 1, 2 or 4 + // + PXE_UINT16 NvWidth; + + // + // Media header length. This is the typical media header length for + // this UNDI. This information is needed when allocating receive + // and transmit buffers. + // + PXE_UINT16 MediaHeaderLen; + + // + // Number of bytes in the NIC hardware (MAC) address. + // + PXE_UINT16 HWaddrLen; + + // + // Maximum number of multicast MAC addresses in the multicast + // MAC address filter list. + // + PXE_UINT16 MCastFilterCnt; + + // + // Default number and size of transmit and receive buffers that will + // be allocated by the UNDI. If MemoryRequired is non-zero, this + // allocation will come out of the memory buffer given to the Initialize + // command. If MemoryRequired is zero, this allocation will come out of + // memory on the NIC. + // + PXE_UINT16 TxBufCnt; + PXE_UINT16 TxBufSize; + PXE_UINT16 RxBufCnt; + PXE_UINT16 RxBufSize; + + // + // Hardware interface types defined in the Assigned Numbers RFC + // and used in DHCP and ARP packets. + // See the PXE_IFTYPE typedef and PXE_IFTYPE_xxx macros. + // + PXE_UINT8 IFtype; + + // + // Supported duplex. See PXE_DUPLEX_xxxxx #defines below. + // + PXE_UINT8 Duplex; + + // + // Supported loopback options. See PXE_LOOPBACK_xxxxx #defines below. + // + PXE_UINT8 LoopBack; +} PXE_DB_GET_INIT_INFO; + +#define PXE_MAX_TXRX_UNIT_ETHER 1500 + +#define PXE_HWADDR_LEN_ETHER 0x0006 +#define PXE_MAC_HEADER_LEN_ETHER 0x000E + +#define PXE_DUPLEX_ENABLE_FULL_SUPPORTED 1 +#define PXE_DUPLEX_FORCE_FULL_SUPPORTED 2 + +#define PXE_LOOPBACK_INTERNAL_SUPPORTED 1 +#define PXE_LOOPBACK_EXTERNAL_SUPPORTED 2 + + +typedef struct s_pxe_pci_config_info { + // + // This is the flag field for the PXE_DB_GET_CONFIG_INFO union. + // For PCI bus devices, this field is set to PXE_BUSTYPE_PCI. + // + PXE_UINT32 BusType; + + // + // This identifies the PCI network device that this UNDI interface + // is bound to. + // + PXE_UINT16 Bus; + PXE_UINT8 Device; + PXE_UINT8 Function; + + // + // This is a copy of the PCI configuration space for this + // network device. + // + union { + PXE_UINT8 Byte[256]; + PXE_UINT16 Word[128]; + PXE_UINT32 Dword[64]; + } Config; +} PXE_PCI_CONFIG_INFO; + + +typedef struct s_pxe_pcc_config_info { + // + // This is the flag field for the PXE_DB_GET_CONFIG_INFO union. + // For PCC bus devices, this field is set to PXE_BUSTYPE_PCC. + // + PXE_UINT32 BusType; + + // + // This identifies the PCC network device that this UNDI interface + // is bound to. + // + PXE_UINT16 Bus; + PXE_UINT8 Device; + PXE_UINT8 Function; + + // + // This is a copy of the PCC configuration space for this + // network device. + // + union { + PXE_UINT8 Byte[256]; + PXE_UINT16 Word[128]; + PXE_UINT32 Dword[64]; + } Config; +} PXE_PCC_CONFIG_INFO; + + +typedef struct s_pxe_usb_config_info { + PXE_UINT32 BusType; + // %%TBD What should we return here... +} PXE_USB_CONFIG_INFO; + + +typedef struct s_pxe_1394_config_info { + PXE_UINT32 BusType; + // %%TBD What should we return here... +} PXE_1394_CONFIG_INFO; + + +typedef union u_pxe_db_get_config_info { + PXE_PCI_CONFIG_INFO pci; + PXE_PCC_CONFIG_INFO pcc; + PXE_USB_CONFIG_INFO usb; + PXE_1394_CONFIG_INFO _1394; +} PXE_DB_GET_CONFIG_INFO; + + +typedef struct s_pxe_cpb_initialize { + // + // Address of first (lowest) byte of the memory buffer. This buffer must + // be in contiguous physical memory and cannot be swapped out. The UNDI + // will be using this for transmit and receive buffering. + // + PXE_UINT64 MemoryAddr; + + // + // MemoryLength must be greater than or equal to MemoryRequired + // returned by the Get Init Info command. + // + PXE_UINT32 MemoryLength; + + // + // Desired link speed in Mbit/sec. Common ethernet values are 10, 100 + // and 1000. Setting a value of zero will auto-detect and/or use the + // default link speed (operation depends on UNDI/NIC functionality). + // + PXE_UINT32 LinkSpeed; + + // + // Suggested number and size of receive and transmit buffers to + // allocate. If MemoryAddr and MemoryLength are non-zero, this + // allocation comes out of the supplied memory buffer. If MemoryAddr + // and MemoryLength are zero, this allocation comes out of memory + // on the NIC. + // + // If these fields are set to zero, the UNDI will allocate buffer + // counts and sizes as it sees fit. + // + PXE_UINT16 TxBufCnt; + PXE_UINT16 TxBufSize; + PXE_UINT16 RxBufCnt; + PXE_UINT16 RxBufSize; + + // + // The following configuration parameters are optional and must be zero + // to use the default values. + // + PXE_UINT8 Duplex; + + PXE_UINT8 LoopBack; +} PXE_CPB_INITIALIZE; + + +#define PXE_DUPLEX_DEFAULT 0x00 +#define PXE_FORCE_FULL_DUPLEX 0x01 +#define PXE_ENABLE_FULL_DUPLEX 0x02 + +#define LOOPBACK_NORMAL 0 +#define LOOPBACK_INTERNAL 1 +#define LOOPBACK_EXTERNAL 2 + + +typedef struct s_pxe_db_initialize { + // + // Actual amount of memory used from the supplied memory buffer. This + // may be less that the amount of memory suppllied and may be zero if + // the UNDI and network device do not use external memory buffers. + // + // Memory used by the UNDI and network device is allocated from the + // lowest memory buffer address. + // + PXE_UINT32 MemoryUsed; + + // + // Actual number and size of receive and transmit buffers that were + // allocated. + // + PXE_UINT16 TxBufCnt; + PXE_UINT16 TxBufSize; + PXE_UINT16 RxBufCnt; + PXE_UINT16 RxBufSize; +} PXE_DB_INITIALIZE; + + +typedef struct s_pxe_cpb_receive_filters { + // + // List of multicast MAC addresses. This list, if present, will + // replace the existing multicast MAC address filter list. + // + PXE_MAC_ADDR MCastList[MAX_MCAST_ADDRESS_CNT]; +} PXE_CPB_RECEIVE_FILTERS; + + +typedef struct s_pxe_db_receive_filters { + // + // Filtered multicast MAC address list. + // + PXE_MAC_ADDR MCastList[MAX_MCAST_ADDRESS_CNT]; +} PXE_DB_RECEIVE_FILTERS; + + +typedef struct s_pxe_cpb_station_address { + // + // If supplied and supported, the current station MAC address + // will be changed. + // + PXE_MAC_ADDR StationAddr; +} PXE_CPB_STATION_ADDRESS; + + +typedef struct s_pxe_dpb_station_address { + // + // Current station MAC address. + // + PXE_MAC_ADDR StationAddr; + + // + // Station broadcast MAC address. + // + PXE_MAC_ADDR BroadcastAddr; + + // + // Permanent station MAC address. + // + PXE_MAC_ADDR PermanentAddr; +} PXE_DB_STATION_ADDRESS; + + +typedef struct s_pxe_db_statistics { + // + // Bit field identifying what statistic data is collected by the + // UNDI/NIC. + // If bit 0x00 is set, Data[0x00] is collected. + // If bit 0x01 is set, Data[0x01] is collected. + // If bit 0x20 is set, Data[0x20] is collected. + // If bit 0x21 is set, Data[0x21] is collected. + // Etc. + // + PXE_UINT64 Supported; + + // + // Statistic data. + // + PXE_UINT64 Data[64]; +} PXE_DB_STATISTICS; + +// +// Total number of frames received. Includes frames with errors and +// dropped frames. +// +#define PXE_STATISTICS_RX_TOTAL_FRAMES 0x00 + +// +// Number of valid frames received and copied into receive buffers. +// +#define PXE_STATISTICS_RX_GOOD_FRAMES 0x01 + +// +// Number of frames below the minimum length for the media. +// This would be <64 for ethernet. +// +#define PXE_STATISTICS_RX_UNDERSIZE_FRAMES 0x02 + +// +// Number of frames longer than the maxminum length for the +// media. This would be >1500 for ethernet. +// +#define PXE_STATISTICS_RX_OVERSIZE_FRAMES 0x03 + +// +// Valid frames that were dropped because receive buffers were full. +// +#define PXE_STATISTICS_RX_DROPPED_FRAMES 0x04 + +// +// Number of valid unicast frames received and not dropped. +// +#define PXE_STATISTICS_RX_UNICAST_FRAMES 0x05 + +// +// Number of valid broadcast frames received and not dropped. +// +#define PXE_STATISTICS_RX_BROADCAST_FRAMES 0x06 + +// +// Number of valid mutlicast frames received and not dropped. +// +#define PXE_STATISTICS_RX_MULTICAST_FRAMES 0x07 + +// +// Number of frames w/ CRC or alignment errors. +// +#define PXE_STATISTICS_RX_CRC_ERROR_FRAMES 0x08 + +// +// Total number of bytes received. Includes frames with errors +// and dropped frames. +// +#define PXE_STATISTICS_RX_TOTAL_BYTES 0x09 + +// +// Transmit statistics. +// +#define PXE_STATISTICS_TX_TOTAL_FRAMES 0x0A +#define PXE_STATISTICS_TX_GOOD_FRAMES 0x0B +#define PXE_STATISTICS_TX_UNDERSIZE_FRAMES 0x0C +#define PXE_STATISTICS_TX_OVERSIZE_FRAMES 0x0D +#define PXE_STATISTICS_TX_DROPPED_FRAMES 0x0E +#define PXE_STATISTICS_TX_UNICAST_FRAMES 0x0F +#define PXE_STATISTICS_TX_BROADCAST_FRAMES 0x10 +#define PXE_STATISTICS_TX_MULTICAST_FRAMES 0x11 +#define PXE_STATISTICS_TX_CRC_ERROR_FRAMES 0x12 +#define PXE_STATISTICS_TX_TOTAL_BYTES 0x13 + +// +// Number of collisions detection on this subnet. +// +#define PXE_STATISTICS_COLLISIONS 0x14 + +// +// Number of frames destined for unsupported protocol. +// +#define PXE_STATISTICS_UNSUPPORTED_PROTOCOL 0x15 + + +typedef struct s_pxe_cpb_mcast_ip_to_mac { + // + // Multicast IP address to be converted to multicast MAC address. + // + PXE_IP_ADDR IP; +} PXE_CPB_MCAST_IP_TO_MAC; + + +typedef struct s_pxe_db_mcast_ip_to_mac { + // + // Multicast MAC address. + // + PXE_MAC_ADDR MAC; +} PXE_DB_MCAST_IP_TO_MAC; + + +typedef struct s_pxe_cpb_nvdata_sparse { + // + // NvData item list. Only items in this list will be updated. + // + struct { + // Non-volatile storage address to be changed. + PXE_UINT32 Addr; + + // Data item to write into above storage address. + + union { + PXE_UINT8 Byte; + PXE_UINT16 Word; + PXE_UINT32 Dword; + } Data; + } Item[MAX_EEPROM_LEN]; +} PXE_CPB_NVDATA_SPARSE; + + +// +// When using bulk update, the size of the CPB structure must be +// the same size as the non-volatile NIC storage. +// +typedef union u_pxe_cpb_nvdata_bulk { + // + // Array of byte-wide data items. + // + PXE_UINT8 Byte[MAX_EEPROM_LEN << 2]; + + // + // Array of word-wide data items. + // + PXE_UINT16 Word[MAX_EEPROM_LEN << 1]; + + // + // Array of dword-wide data items. + // + PXE_UINT32 Dword[MAX_EEPROM_LEN]; +} PXE_CPB_NVDATA_BULK; + +typedef struct s_pxe_db_nvdata { + + // Arrays of data items from non-volatile storage. + + union { + // + // Array of byte-wide data items. + // + PXE_UINT8 Byte[MAX_EEPROM_LEN << 2]; + + // + // Array of word-wide data items. + // + PXE_UINT16 Word[MAX_EEPROM_LEN << 1]; + + // Array of dword-wide data items. + + PXE_UINT32 Dword[MAX_EEPROM_LEN]; + } Data; +} PXE_DB_NVDATA; + + +typedef struct s_pxe_db_get_status { + // + // Length of next receive frame (header + data). If this is zero, + // there is no next receive frame available. + // + PXE_UINT32 RxFrameLen; + + // + // Reserved, set to zero. + // + PXE_UINT32 reserved; + + // + // Addresses of transmitted buffers that need to be recycled. + // + PXE_UINT64 TxBuffer[MAX_XMIT_BUFFERS]; +} PXE_DB_GET_STATUS; + + + +typedef struct s_pxe_cpb_fill_header { + // + // Source and destination MAC addresses. These will be copied into + // the media header without doing byte swapping. + // + PXE_MAC_ADDR SrcAddr; + PXE_MAC_ADDR DestAddr; + + // + // Address of first byte of media header. The first byte of packet data + // follows the last byte of the media header. + // + PXE_UINT64 MediaHeader; + + // + // Length of packet data in bytes (not including the media header). + // + PXE_UINT32 PacketLen; + + // + // Protocol type. This will be copied into the media header without + // doing byte swapping. Protocol type numbers can be obtained from + // the Assigned Numbers RFC 1700. + // + PXE_UINT16 Protocol; + + // + // Length of the media header in bytes. + // + PXE_UINT16 MediaHeaderLen; +} PXE_CPB_FILL_HEADER; + + +#define PXE_PROTOCOL_ETHERNET_IP 0x0800 +#define PXE_PROTOCOL_ETHERNET_ARP 0x0806 +#define MAX_XMIT_FRAGMENTS 16 + +typedef struct s_pxe_cpb_fill_header_fragmented { + // + // Source and destination MAC addresses. These will be copied into + // the media header without doing byte swapping. + // + PXE_MAC_ADDR SrcAddr; + PXE_MAC_ADDR DestAddr; + + // + // Length of packet data in bytes (not including the media header). + // + PXE_UINT32 PacketLen; + + // + // Protocol type. This will be copied into the media header without + // doing byte swapping. Protocol type numbers can be obtained from + // the Assigned Numbers RFC 1700. + // + PXE_MEDIA_PROTOCOL Protocol; + + // + // Length of the media header in bytes. + // + PXE_UINT16 MediaHeaderLen; + + // + // Number of packet fragment descriptors. + // + PXE_UINT16 FragCnt; + + // + // Reserved, must be set to zero. + // + PXE_UINT16 reserved; + + // + // Array of packet fragment descriptors. The first byte of the media + // header is the first byte of the first fragment. + // + struct { + // + // Address of this packet fragment. + // + PXE_UINT64 FragAddr; + + // + // Length of this packet fragment. + // + PXE_UINT32 FragLen; + + // + // Reserved, must be set to zero. + // + PXE_UINT32 reserved; + } FragDesc[MAX_XMIT_FRAGMENTS]; +} PXE_CPB_FILL_HEADER_FRAGMENTED; + + + +typedef struct s_pxe_cpb_transmit { + // + // Address of first byte of frame buffer. This is also the first byte + // of the media header. + // + PXE_UINT64 FrameAddr; + + // + // Length of the data portion of the frame buffer in bytes. Do not + // include the length of the media header. + // + PXE_UINT32 DataLen; + + // + // Length of the media header in bytes. + // + PXE_UINT16 MediaheaderLen; + + // + // Reserved, must be zero. + // + PXE_UINT16 reserved; +} PXE_CPB_TRANSMIT; + + + +typedef struct s_pxe_cpb_transmit_fragments { + // + // Length of packet data in bytes (not including the media header). + // + PXE_UINT32 FrameLen; + + // + // Length of the media header in bytes. + // + PXE_UINT16 MediaheaderLen; + + // + // Number of packet fragment descriptors. + // + PXE_UINT16 FragCnt; + + // + // Array of frame fragment descriptors. The first byte of the first + // fragment is also the first byte of the media header. + // + struct { + // + // Address of this frame fragment. + // + PXE_UINT64 FragAddr; + + // + // Length of this frame fragment. + // + PXE_UINT32 FragLen; + + // + // Reserved, must be set to zero. + // + PXE_UINT32 reserved; + } FragDesc[MAX_XMIT_FRAGMENTS]; +} PXE_CPB_TRANSMIT_FRAGMENTS; + + +typedef struct s_pxe_cpb_receive { + // + // Address of first byte of receive buffer. This is also the first byte + // of the frame header. + // + PXE_UINT64 BufferAddr; + + // + // Length of receive buffer. This must be large enough to hold the + // received frame (media header + data). If the length of smaller than + // the received frame, data will be lost. + // + PXE_UINT32 BufferLen; + + // + // Reserved, must be set to zero. + // + PXE_UINT32 reserved; +} PXE_CPB_RECEIVE; + + +typedef struct s_pxe_db_receive { + // + // Source and destination MAC addresses from media header. + // + PXE_MAC_ADDR SrcAddr; + PXE_MAC_ADDR DestAddr; + + // + // Length of received frame. May be larger than receive buffer size. + // The receive buffer will not be overwritten. This is how to tell + // if data was lost because the receive buffer was too small. + // + PXE_UINT32 FrameLen; + + // + // Protocol type from media header. + // + PXE_MEDIA_PROTOCOL Protocol; + + // + // Length of media header in received frame. + // + PXE_UINT16 MediaHeaderLen; + + // + // Type of receive frame. + // + PXE_FRAME_TYPE Type; + + // + // Reserved, must be zero. + // + PXE_UINT8 reserved[7]; + +} PXE_DB_RECEIVE; + +#pragma pack() + +/* EOF - efi_pxe.h */ +#endif /* _EFI_PXE_H */ + diff --git a/include/efiapi.h b/include/efiapi.h new file mode 100644 index 0000000..28315d9 --- /dev/null +++ b/include/efiapi.h @@ -0,0 +1,1034 @@ +#ifndef _EFI_API_H +#define _EFI_API_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efiapi.h + +Abstract: + + Global EFI runtime & boot service interfaces + + + + +Revision History + +--*/ + +// +// EFI Specification Revision +// + +#define EFI_SPECIFICATION_REVISION_MAJORMINOR(major, minor) ((major<<16) | (minor)) +#define EFI_SPECIFICATION_MAJOR_REVISION 1 +#define EFI_SPECIFICATION_MINOR_REVISION 02 +#define EFI_SPECIFICATION_VERSION EFI_SPECIFICATION_REVISION_MAJORMINOR(EFI_SPECIFICATION_MAJOR_REVISION, EFI_SPECIFICATION_MINOR_REVISION) + +// +// Declare forward referenced data structures +// + +INTERFACE_DECL(_EFI_SYSTEM_TABLE); + +// +// EFI Memory +// + +typedef +EFI_STATUS +(EFIAPI *EFI_ALLOCATE_PAGES) ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN NoPages, + OUT EFI_PHYSICAL_ADDRESS *Memory + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FREE_PAGES) ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NoPages + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_MEMORY_MAP) ( + IN OUT UINTN *MemoryMapSize, + IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, + OUT UINTN *MapKey, + OUT UINTN *DescriptorSize, + OUT UINT32 *DescriptorVersion + ); + +#define NextMemoryDescriptor(Ptr,Size) ((EFI_MEMORY_DESCRIPTOR *) (((UINT8 *) Ptr) + Size)) + + +typedef +EFI_STATUS +(EFIAPI *EFI_ALLOCATE_POOL) ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN Size, + OUT VOID **Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FREE_POOL) ( + IN VOID *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_VIRTUAL_ADDRESS_MAP) ( + IN UINTN MemoryMapSize, + IN UINTN DescriptorSize, + IN UINT32 DescriptorVersion, + IN EFI_MEMORY_DESCRIPTOR *VirtualMap + ); + + +#define EFI_OPTIONAL_PTR 0x00000001 +#define EFI_INTERNAL_FNC 0x00000002 // Pointer to internal runtime fnc +#define EFI_INTERNAL_PTR 0x00000004 // Pointer to internal runtime data + + +typedef +EFI_STATUS +(EFIAPI *EFI_CONVERT_POINTER) ( + IN UINTN DebugDisposition, + IN OUT VOID **Address + ); + + +// +// EFI Events +// + +#define EVT_TIMER 0x80000000 +#define EVT_RUNTIME 0x40000000 +#define EVT_RUNTIME_CONTEXT 0x20000000 + +#define EVT_NOTIFY_WAIT 0x00000100 +#define EVT_NOTIFY_SIGNAL 0x00000200 + +#define EVT_SIGNAL_EXIT_BOOT_SERVICES 0x00000201 +#define EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE 0x60000202 + +#define EVT_EFI_SIGNAL_MASK 0x000000FF +#define EVT_EFI_SIGNAL_MAX 4 + +#define EFI_EVENT_TIMER EVT_TIMER +#define EFI_EVENT_RUNTIME EVT_RUNTIME +#define EFI_EVENT_RUNTIME_CONTEXT EVT_RUNTIME_CONTEXT +#define EFI_EVENT_NOTIFY_WAIT EVT_NOTIFY_WAIT +#define EFI_EVENT_NOTIFY_SIGNAL EVT_NOTIFY_SIGNAL +#define EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES EVT_SIGNAL_EXIT_BOOT_SERVICES +#define EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE +#define EFI_EVENT_EFI_SIGNAL_MASK EVT_EFI_SIGNAL_MASK +#define EFI_EVENT_EFI_SIGNAL_MAX EVT_EFI_SIGNAL_MAX + + +typedef +VOID +(EFIAPI *EFI_EVENT_NOTIFY) ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_CREATE_EVENT) ( + IN UINT32 Type, + IN EFI_TPL NotifyTpl, + IN EFI_EVENT_NOTIFY NotifyFunction, + IN VOID *NotifyContext, + OUT EFI_EVENT *Event + ); + +typedef enum { + TimerCancel, + TimerPeriodic, + TimerRelative, + TimerTypeMax +} EFI_TIMER_DELAY; + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_TIMER) ( + IN EFI_EVENT Event, + IN EFI_TIMER_DELAY Type, + IN UINT64 TriggerTime + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SIGNAL_EVENT) ( + IN EFI_EVENT Event + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_WAIT_FOR_EVENT) ( + IN UINTN NumberOfEvents, + IN EFI_EVENT *Event, + OUT UINTN *Index + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_CLOSE_EVENT) ( + IN EFI_EVENT Event + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_CHECK_EVENT) ( + IN EFI_EVENT Event + ); + +// +// Task priority level +// + +#define TPL_APPLICATION 4 +#define TPL_CALLBACK 8 +#define TPL_NOTIFY 16 +#define TPL_HIGH_LEVEL 31 +#define EFI_TPL_APPLICATION TPL_APPLICATION +#define EFI_TPL_CALLBACK TPL_CALLBACK +#define EFI_TPL_NOTIFY TPL_NOTIFY +#define EFI_TPL_HIGH_LEVEL TPL_HIGH_LEVEL +typedef +EFI_TPL +(EFIAPI *EFI_RAISE_TPL) ( + IN EFI_TPL NewTpl + ); + +typedef +VOID +(EFIAPI *EFI_RESTORE_TPL) ( + IN EFI_TPL OldTpl + ); + + +// +// EFI platform varibles +// + +#define EFI_GLOBAL_VARIABLE \ + { 0x8BE4DF61, 0x93CA, 0x11d2, {0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C} } + +// Variable attributes +#define EFI_VARIABLE_NON_VOLATILE 0x00000001 +#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002 +#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004 +#define EFI_VARIABLE_HARDWARE_ERROR_RECORD 0x00000008 +#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x00000010 +#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x00000020 +#define EFI_VARIABLE_APPEND_WRITE 0x00000040 +#define EFI_VARIABLE_ENHANCED_AUTHENTICATED_ACCESS 0x00000080 + +// Variable size limitation +#define EFI_MAXIMUM_VARIABLE_SIZE 1024 + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_VARIABLE) ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + OUT UINT32 *Attributes OPTIONAL, + IN OUT UINTN *DataSize, + OUT VOID *Data + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_NEXT_VARIABLE_NAME) ( + IN OUT UINTN *VariableNameSize, + IN OUT CHAR16 *VariableName, + IN OUT EFI_GUID *VendorGuid + ); + + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_VARIABLE) ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ); + + +// +// EFI Time +// + +typedef struct { + UINT32 Resolution; // 1e-6 parts per million + UINT32 Accuracy; // hertz + BOOLEAN SetsToZero; // Set clears sub-second time +} EFI_TIME_CAPABILITIES; + + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_TIME) ( + OUT EFI_TIME *Time, + OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_TIME) ( + IN EFI_TIME *Time + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_WAKEUP_TIME) ( + OUT BOOLEAN *Enabled, + OUT BOOLEAN *Pending, + OUT EFI_TIME *Time + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_WAKEUP_TIME) ( + IN BOOLEAN Enable, + IN EFI_TIME *Time OPTIONAL + ); + + +// +// Image functions +// + + +// PE32+ Subsystem type for EFI images + +#if !defined(IMAGE_SUBSYSTEM_EFI_APPLICATION) +#define IMAGE_SUBSYSTEM_EFI_APPLICATION 10 +#define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11 +#define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 +#endif + +// PE32+ Machine type for EFI images + +#if !defined(EFI_IMAGE_MACHINE_IA32) +#define EFI_IMAGE_MACHINE_IA32 0x014c +#endif + +#if !defined(EFI_IMAGE_MACHINE_IA64) +#define EFI_IMAGE_MACHINE_IA64 0x0200 +#endif + +#if !defined(EFI_IMAGE_MACHINE_EBC) +#define EFI_IMAGE_MACHINE_EBC 0x0EBC +#endif + +#if !defined(EFI_IMAGE_MACHINE_X64) +#define EFI_IMAGE_MACHINE_X64 0x8664 +#endif + +#if !defined(EFI_IMAGE_MACHINE_ARMTHUMB_MIXED) +#define EFI_IMAGE_MACHINE_ARMTHUMB_MIXED 0x01C2 +#endif + +#if !defined(EFI_IMAGE_MACHINE_AARCH64) +#define EFI_IMAGE_MACHINE_AARCH64 0xAA64 +#endif + +#if !defined(EFI_IMAGE_MACHINE_RISCV32) +#define EFI_IMAGE_MACHINE_RISCV32 0x5032 +#endif + +#if !defined(EFI_IMAGE_MACHINE_RISCV64) +#define EFI_IMAGE_MACHINE_RISCV64 0x5064 +#endif + +#if !defined(EFI_IMAGE_MACHINE_RISCV128) +#define EFI_IMAGE_MACHINE_RISCV128 0x5128 +#endif + +#if !defined(EFI_IMAGE_MACHINE_LOONGARCH32) +#define EFI_IMAGE_MACHINE_LOONGARCH32 0x6232 +#endif + +#if !defined(EFI_IMAGE_MACHINE_LOONGARCH64) +#define EFI_IMAGE_MACHINE_LOONGARCH64 0x6264 +#endif + +// Image Entry prototype + +typedef +EFI_STATUS +(EFIAPI *EFI_IMAGE_ENTRY_POINT) ( + IN EFI_HANDLE ImageHandle, + IN struct _EFI_SYSTEM_TABLE *SystemTable + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IMAGE_LOAD) ( + IN BOOLEAN BootPolicy, + IN EFI_HANDLE ParentImageHandle, + IN EFI_DEVICE_PATH *FilePath, + IN VOID *SourceBuffer OPTIONAL, + IN UINTN SourceSize, + OUT EFI_HANDLE *ImageHandle + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IMAGE_START) ( + IN EFI_HANDLE ImageHandle, + OUT UINTN *ExitDataSize, + OUT CHAR16 **ExitData OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_EXIT) ( + IN EFI_HANDLE ImageHandle, + IN EFI_STATUS ExitStatus, + IN UINTN ExitDataSize, + IN CHAR16 *ExitData OPTIONAL + ); + + +// Image handle +/*#define LOADED_IMAGE_PROTOCOL \ + { 0x5B1B31A1, 0x9562, 0x11d2, {0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B} } + +#define EFI_IMAGE_INFORMATION_REVISION 0x1000 +typedef struct { + UINT32 Revision; + EFI_HANDLE ParentHandle; + struct _EFI_SYSTEM_TABLE *SystemTable; + + // Source location of image + EFI_HANDLE DeviceHandle; + EFI_DEVICE_PATH *FilePath; + VOID *Reserved; + + // Images load options + UINT32 LoadOptionsSize; + VOID *LoadOptions; + + // Location of where image was loaded + VOID *ImageBase; + UINT64 ImageSize; + EFI_MEMORY_TYPE ImageCodeType; + EFI_MEMORY_TYPE ImageDataType; + + // If the driver image supports a dynamic unload request + EFI_IMAGE_UNLOAD Unload; + +} EFI_LOADED_IMAGE;*/ + + +typedef +EFI_STATUS +(EFIAPI *EFI_EXIT_BOOT_SERVICES) ( + IN EFI_HANDLE ImageHandle, + IN UINTN MapKey + ); + +// +// Misc +// + + +typedef +EFI_STATUS +(EFIAPI *EFI_STALL) ( + IN UINTN Microseconds + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_WATCHDOG_TIMER) ( + IN UINTN Timeout, + IN UINT64 WatchdogCode, + IN UINTN DataSize, + IN CHAR16 *WatchdogData OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_CONNECT_CONTROLLER) ( + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE *DriverImageHandle OPTIONAL, + IN EFI_DEVICE_PATH *RemainingDevicePath OPTIONAL, + IN BOOLEAN Recursive + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_DISCONNECT_CONTROLLER) ( + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE DriverImageHandle OPTIONAL, + IN EFI_HANDLE ChildHandle OPTIONAL + ); + +#define EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 0x00000001 +#define EFI_OPEN_PROTOCOL_GET_PROTOCOL 0x00000002 +#define EFI_OPEN_PROTOCOL_TEST_PROTOCOL 0x00000004 +#define EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 0x00000008 +#define EFI_OPEN_PROTOCOL_BY_DRIVER 0x00000010 +#define EFI_OPEN_PROTOCOL_EXCLUSIVE 0x00000020 + +typedef +EFI_STATUS +(EFIAPI *EFI_OPEN_PROTOCOL) ( + IN EFI_HANDLE Handle, + IN EFI_GUID *Protocol, + OUT VOID **Interface OPTIONAL, + IN EFI_HANDLE AgentHandle, + IN EFI_HANDLE ControllerHandle, + IN UINT32 Attributes + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_CLOSE_PROTOCOL) ( + IN EFI_HANDLE Handle, + IN EFI_GUID *Protocol, + IN EFI_HANDLE AgentHandle, + IN EFI_HANDLE ControllerHandle + ); + +typedef struct { + EFI_HANDLE AgentHandle; + EFI_HANDLE ControllerHandle; + UINT32 Attributes; + UINT32 OpenCount; +} EFI_OPEN_PROTOCOL_INFORMATION_ENTRY; + +typedef +EFI_STATUS +(EFIAPI *EFI_OPEN_PROTOCOL_INFORMATION) ( + IN EFI_HANDLE Handle, + IN EFI_GUID *Protocol, + OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer, + OUT UINTN *EntryCount + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PROTOCOLS_PER_HANDLE) ( + IN EFI_HANDLE Handle, + OUT EFI_GUID ***ProtocolBuffer, + OUT UINTN *ProtocolBufferCount + ); + +typedef enum { + AllHandles, + ByRegisterNotify, + ByProtocol +} EFI_LOCATE_SEARCH_TYPE; + +typedef +EFI_STATUS +(EFIAPI *EFI_LOCATE_HANDLE_BUFFER) ( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *NoHandles, + OUT EFI_HANDLE **Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_LOCATE_PROTOCOL) ( + IN EFI_GUID *Protocol, + IN VOID *Registration OPTIONAL, + OUT VOID **Interface + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES) ( + IN OUT EFI_HANDLE *Handle, + ... + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES) ( + IN OUT EFI_HANDLE Handle, + ... + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_CALCULATE_CRC32) ( + IN VOID *Data, + IN UINTN DataSize, + OUT UINT32 *Crc32 + ); + +typedef +VOID +(EFIAPI *EFI_COPY_MEM) ( + IN VOID *Destination, + IN VOID *Source, + IN UINTN Length + ); + +typedef +VOID +(EFIAPI *EFI_SET_MEM) ( + IN VOID *Buffer, + IN UINTN Size, + IN UINT8 Value + ); + + +typedef +EFI_STATUS +(EFIAPI *EFI_CREATE_EVENT_EX) ( + IN UINT32 Type, + IN EFI_TPL NotifyTpl, + IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, + IN const VOID *NotifyContext OPTIONAL, + IN const EFI_GUID *EventGroup OPTIONAL, + OUT EFI_EVENT *Event + ); + +typedef enum { + EfiResetCold, + EfiResetWarm, + EfiResetShutdown +} EFI_RESET_TYPE; + +typedef +EFI_STATUS +(EFIAPI *EFI_RESET_SYSTEM) ( + IN EFI_RESET_TYPE ResetType, + IN EFI_STATUS ResetStatus, + IN UINTN DataSize, + IN CHAR16 *ResetData OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_NEXT_MONOTONIC_COUNT) ( + OUT UINT64 *Count + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_NEXT_HIGH_MONO_COUNT) ( + OUT UINT32 *HighCount + ); + +typedef struct { + UINT64 Length; + union { + EFI_PHYSICAL_ADDRESS DataBlock; + EFI_PHYSICAL_ADDRESS ContinuationPointer; + } Union; +} EFI_CAPSULE_BLOCK_DESCRIPTOR; + +typedef struct { + EFI_GUID CapsuleGuid; + UINT32 HeaderSize; + UINT32 Flags; + UINT32 CapsuleImageSize; +} EFI_CAPSULE_HEADER; + +#define CAPSULE_FLAGS_PERSIST_ACROSS_RESET 0x00010000 +#define CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE 0x00020000 +#define CAPSULE_FLAGS_INITIATE_RESET 0x00040000 + +typedef +EFI_STATUS +(EFIAPI *EFI_UPDATE_CAPSULE) ( + IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, + IN UINTN CapsuleCount, + IN EFI_PHYSICAL_ADDRESS ScatterGatherList OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_QUERY_CAPSULE_CAPABILITIES) ( + IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, + IN UINTN CapsuleCount, + OUT UINT64 *MaximumCapsuleSize, + OUT EFI_RESET_TYPE *ResetType + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_QUERY_VARIABLE_INFO) ( + IN UINT32 Attributes, + OUT UINT64 *MaximumVariableStorageSize, + OUT UINT64 *RemainingVariableStorageSize, + OUT UINT64 *MaximumVariableSize + ); + +// +// Protocol handler functions +// + +typedef enum { + EFI_NATIVE_INTERFACE, + EFI_PCODE_INTERFACE +} EFI_INTERFACE_TYPE; + +typedef +EFI_STATUS +(EFIAPI *EFI_INSTALL_PROTOCOL_INTERFACE) ( + IN OUT EFI_HANDLE *Handle, + IN EFI_GUID *Protocol, + IN EFI_INTERFACE_TYPE InterfaceType, + IN VOID *Interface + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_REINSTALL_PROTOCOL_INTERFACE) ( + IN EFI_HANDLE Handle, + IN EFI_GUID *Protocol, + IN VOID *OldInterface, + IN VOID *NewInterface + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_UNINSTALL_PROTOCOL_INTERFACE) ( + IN EFI_HANDLE Handle, + IN EFI_GUID *Protocol, + IN VOID *Interface + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_HANDLE_PROTOCOL) ( + IN EFI_HANDLE Handle, + IN EFI_GUID *Protocol, + OUT VOID **Interface + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_REGISTER_PROTOCOL_NOTIFY) ( + IN EFI_GUID *Protocol, + IN EFI_EVENT Event, + OUT VOID **Registration + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_LOCATE_HANDLE) ( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *BufferSize, + OUT EFI_HANDLE *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_LOCATE_DEVICE_PATH) ( + IN EFI_GUID *Protocol, + IN OUT EFI_DEVICE_PATH **DevicePath, + OUT EFI_HANDLE *Device + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_INSTALL_CONFIGURATION_TABLE) ( + IN EFI_GUID *Guid, + IN VOID *Table + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_RESERVED_SERVICE) ( + ); + +// +// Standard EFI table header +// + +typedef struct _EFI_TABLE_HEADER { + UINT64 Signature; + UINT32 Revision; + UINT32 HeaderSize; + UINT32 CRC32; + UINT32 Reserved; +} EFI_TABLE_HEADER; + + +// +// EFI Runtime Serivces Table +// + +#define EFI_RUNTIME_SERVICES_SIGNATURE 0x56524553544e5552 +#define EFI_1_02_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(1, 02) +#define EFI_1_10_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(1, 10) +#define EFI_2_00_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 00) +#define EFI_2_10_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 10) +#define EFI_2_20_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 20) +#define EFI_2_30_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 30) +#define EFI_2_31_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 31) +#define EFI_2_40_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 40) +#define EFI_2_50_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 50) +#define EFI_2_60_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 60) +#define EFI_2_70_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 70) +#define EFI_2_80_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 80) +#define EFI_2_90_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 90) +#define EFI_2_100_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 100) +#define EFI_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_VERSION + +typedef struct { + EFI_TABLE_HEADER Hdr; + + // + // Time services + // + + EFI_GET_TIME GetTime; + EFI_SET_TIME SetTime; + EFI_GET_WAKEUP_TIME GetWakeupTime; + EFI_SET_WAKEUP_TIME SetWakeupTime; + + // + // Virtual memory services + // + + EFI_SET_VIRTUAL_ADDRESS_MAP SetVirtualAddressMap; + EFI_CONVERT_POINTER ConvertPointer; + + // + // Variable serviers + // + + EFI_GET_VARIABLE GetVariable; + EFI_GET_NEXT_VARIABLE_NAME GetNextVariableName; + EFI_SET_VARIABLE SetVariable; + + // + // Misc + // + + EFI_GET_NEXT_HIGH_MONO_COUNT GetNextHighMonotonicCount; + EFI_RESET_SYSTEM ResetSystem; + + EFI_UPDATE_CAPSULE UpdateCapsule; + EFI_QUERY_CAPSULE_CAPABILITIES QueryCapsuleCapabilities; + EFI_QUERY_VARIABLE_INFO QueryVariableInfo; +} EFI_RUNTIME_SERVICES; + + +// +// EFI Boot Services Table +// + +#define EFI_BOOT_SERVICES_SIGNATURE 0x56524553544f4f42 +#define EFI_1_02_BOOT_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(1, 02) +#define EFI_1_10_BOOT_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(1, 10) +#define EFI_2_00_BOOT_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 00) +#define EFI_2_10_BOOT_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 10) +#define EFI_2_20_BOOT_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 20) +#define EFI_2_30_BOOT_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 30) +#define EFI_2_31_BOOT_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 31) +#define EFI_2_40_BOOT_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 40) +#define EFI_2_50_BOOT_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 50) +#define EFI_2_60_BOOT_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 60) +#define EFI_2_70_BOOT_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 70) +#define EFI_2_80_BOOT_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 80) +#define EFI_2_90_BOOT_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 90) +#define EFI_2_100_BOOT_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 100) +#define EFI_BOOT_SERVICES_REVISION EFI_SPECIFICATION_VERSION + +typedef struct _EFI_BOOT_SERVICES { + + EFI_TABLE_HEADER Hdr; + + // + // Task priority functions + // + + EFI_RAISE_TPL RaiseTPL; + EFI_RESTORE_TPL RestoreTPL; + + // + // Memory functions + // + + EFI_ALLOCATE_PAGES AllocatePages; + EFI_FREE_PAGES FreePages; + EFI_GET_MEMORY_MAP GetMemoryMap; + EFI_ALLOCATE_POOL AllocatePool; + EFI_FREE_POOL FreePool; + + // + // Event & timer functions + // + + EFI_CREATE_EVENT CreateEvent; + EFI_SET_TIMER SetTimer; + EFI_WAIT_FOR_EVENT WaitForEvent; + EFI_SIGNAL_EVENT SignalEvent; + EFI_CLOSE_EVENT CloseEvent; + EFI_CHECK_EVENT CheckEvent; + + // + // Protocol handler functions + // + + EFI_INSTALL_PROTOCOL_INTERFACE InstallProtocolInterface; + EFI_REINSTALL_PROTOCOL_INTERFACE ReinstallProtocolInterface; + EFI_UNINSTALL_PROTOCOL_INTERFACE UninstallProtocolInterface; + EFI_HANDLE_PROTOCOL HandleProtocol; + EFI_HANDLE_PROTOCOL PCHandleProtocol; + EFI_REGISTER_PROTOCOL_NOTIFY RegisterProtocolNotify; + EFI_LOCATE_HANDLE LocateHandle; + EFI_LOCATE_DEVICE_PATH LocateDevicePath; + EFI_INSTALL_CONFIGURATION_TABLE InstallConfigurationTable; + + // + // Image functions + // + + EFI_IMAGE_LOAD LoadImage; + EFI_IMAGE_START StartImage; + EFI_EXIT Exit; + EFI_IMAGE_UNLOAD UnloadImage; + EFI_EXIT_BOOT_SERVICES ExitBootServices; + + // + // Misc functions + // + + EFI_GET_NEXT_MONOTONIC_COUNT GetNextMonotonicCount; + EFI_STALL Stall; + EFI_SET_WATCHDOG_TIMER SetWatchdogTimer; + + // + // DriverSupport Services + // + + EFI_CONNECT_CONTROLLER ConnectController; + EFI_DISCONNECT_CONTROLLER DisconnectController; + + // + // Open and Close Protocol Services + // + EFI_OPEN_PROTOCOL OpenProtocol; + EFI_CLOSE_PROTOCOL CloseProtocol; + EFI_OPEN_PROTOCOL_INFORMATION OpenProtocolInformation; + + // + // Library Services + // + EFI_PROTOCOLS_PER_HANDLE ProtocolsPerHandle; + EFI_LOCATE_HANDLE_BUFFER LocateHandleBuffer; + EFI_LOCATE_PROTOCOL LocateProtocol; + EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces; + EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces; + + // + // 32-bit CRC Services + // + EFI_CALCULATE_CRC32 CalculateCrc32; + + // + // Misc Services + // + EFI_COPY_MEM CopyMem; + EFI_SET_MEM SetMem; + EFI_CREATE_EVENT_EX CreateEventEx; +} EFI_BOOT_SERVICES; + + +// +// EFI Configuration Table and GUID definitions +// + +#define MPS_TABLE_GUID \ + { 0xeb9d2d2f, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define ACPI_TABLE_GUID \ + { 0xeb9d2d30, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define ACPI_20_TABLE_GUID \ + { 0x8868e871, 0xe4f1, 0x11d3, {0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81} } + +#define SMBIOS_TABLE_GUID \ + { 0xeb9d2d31, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define SMBIOS3_TABLE_GUID \ + { 0xf2fd1544, 0x9794, 0x4a2c, {0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94} } + +#define SAL_SYSTEM_TABLE_GUID \ + { 0xeb9d2d32, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define EFI_DTB_TABLE_GUID \ + { 0xb1b621d5, 0xf19c, 0x41a5, {0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0} } + +typedef struct _EFI_CONFIGURATION_TABLE { + EFI_GUID VendorGuid; + VOID *VendorTable; +} EFI_CONFIGURATION_TABLE; + + +// +// EFI System Table +// + + + + +#define EFI_SYSTEM_TABLE_SIGNATURE 0x5453595320494249 +#define EFI_1_02_SYSTEM_TABLE_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(1, 02) +#define EFI_1_10_SYSTEM_TABLE_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(1, 10) +#define EFI_2_00_SYSTEM_TABLE_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 00) +#define EFI_2_10_SYSTEM_TABLE_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 10) +#define EFI_2_20_SYSTEM_TABLE_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 20) +#define EFI_2_30_SYSTEM_TABLE_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 30) +#define EFI_2_31_SYSTEM_TABLE_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 31) +#define EFI_2_40_SYSTEM_TABLE_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 40) +#define EFI_2_50_SYSTEM_TABLE_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 50) +#define EFI_2_60_SYSTEM_TABLE_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 60) +#define EFI_2_70_SYSTEM_TABLE_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 70) +#define EFI_2_80_SYSTEM_TABLE_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 80) +#define EFI_2_90_SYSTEM_TABLE_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 90) +#define EFI_2_100_SYSTEM_TABLE_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 100) +#define EFI_SYSTEM_TABLE_REVISION EFI_SPECIFICATION_VERSION + +typedef struct _EFI_SYSTEM_TABLE { + EFI_TABLE_HEADER Hdr; + + CHAR16 *FirmwareVendor; + UINT32 FirmwareRevision; + + EFI_HANDLE ConsoleInHandle; + SIMPLE_INPUT_INTERFACE *ConIn; + + EFI_HANDLE ConsoleOutHandle; + SIMPLE_TEXT_OUTPUT_INTERFACE *ConOut; + + EFI_HANDLE StandardErrorHandle; + SIMPLE_TEXT_OUTPUT_INTERFACE *StdErr; + + EFI_RUNTIME_SERVICES *RuntimeServices; + EFI_BOOT_SERVICES *BootServices; + + UINTN NumberOfTableEntries; + EFI_CONFIGURATION_TABLE *ConfigurationTable; + +} EFI_SYSTEM_TABLE; + +#endif + diff --git a/include/eficompiler.h b/include/eficompiler.h new file mode 100644 index 0000000..5301399 --- /dev/null +++ b/include/eficompiler.h @@ -0,0 +1,69 @@ +/*++ + +Copyright (c) 2016-2024 Pete Batard + +Module Name: + + eficompiler.h + +Abstract: + + Compiler specific adjustments + +--*/ + +#if defined(__GNUC__) +#define EFI_UNUSED __attribute__((__unused__)) +#else +#define EFI_UNUSED +#endif + +#if defined(__clang__) +#define EFI_NO_TAIL_CALL __attribute__((disable_tail_calls)) +#elif defined(__GNUC__) +#define EFI_NO_TAIL_CALL __attribute__((optimize("no-optimize-sibling-calls"))) +#else +#define EFI_NO_TAIL_CALL +#endif + +#if defined(__clang__) +#define EFI_OPTNONE __attribute__((optnone)) +#elif defined(__GNUC__) +#define EFI_OPTNONE __attribute__((__optimize__("0"))) +#else +#define EFI_OPTNONE +#endif + +#if defined(__GNUC__) +#define EFI_ALIGN(x) __attribute__((__aligned__(x))) +#elif defined(_MSC_VER) +#define EFI_ALIGN(x) __declspec(align(x)) +#else +// Not being able to align is likely to break executables, so report it +#error "No alignement directive is defined for this platform" +#endif + +#if !defined(ALIGN) +#define ALIGN(x) EFI_ALIGN(x) +#endif + +#if defined(__GNUC__) +#define EFI_NORETURN __attribute__((noreturn)) +#elif defined(_MSC_VER) +#define EFI_NORETURN __declspec(noreturn) +#else +#define EFI_NORETURN +#endif + +#if defined(__GNUC__) +#define EFI_NOINLINE __attribute__((noinline)) +#elif defined(_MSC_VER) +#define EFI_NOINLINE __declspec(noinline) +#else +#define EFI_NOINLINE +#endif + +/* Also add a catch-all on __attribute__() for MS compilers */ +#if defined(_MSC_VER) +#define __attribute__(x) +#endif diff --git a/include/eficon.h b/include/eficon.h new file mode 100644 index 0000000..f6f69d7 --- /dev/null +++ b/include/eficon.h @@ -0,0 +1,306 @@ +#ifndef _EFI_CON_H +#define _EFI_CON_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + eficon.h + +Abstract: + + EFI console protocols + + + +Revision History + +--*/ + +// +// Text output protocol +// + +#define EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID \ + { 0x387477c2, 0x69c7, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} } +#define SIMPLE_TEXT_OUTPUT_PROTOCOL EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID + +INTERFACE_DECL(_SIMPLE_TEXT_OUTPUT_INTERFACE); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_RESET) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN BOOLEAN ExtendedVerification + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_OUTPUT_STRING) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN CHAR16 *String + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_TEST_STRING) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN CHAR16 *String + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_QUERY_MODE) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN UINTN ModeNumber, + OUT UINTN *Columns, + OUT UINTN *Rows + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_SET_MODE) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN UINTN ModeNumber + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_SET_ATTRIBUTE) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN UINTN Attribute + ); + +#define EFI_BLACK 0x00 +#define EFI_BLUE 0x01 +#define EFI_GREEN 0x02 +#define EFI_CYAN (EFI_BLUE | EFI_GREEN) +#define EFI_RED 0x04 +#define EFI_MAGENTA (EFI_BLUE | EFI_RED) +#define EFI_BROWN (EFI_GREEN | EFI_RED) +#define EFI_LIGHTGRAY (EFI_BLUE | EFI_GREEN | EFI_RED) +#define EFI_BRIGHT 0x08 +#define EFI_DARKGRAY (EFI_BRIGHT) +#define EFI_LIGHTBLUE (EFI_BLUE | EFI_BRIGHT) +#define EFI_LIGHTGREEN (EFI_GREEN | EFI_BRIGHT) +#define EFI_LIGHTCYAN (EFI_CYAN | EFI_BRIGHT) +#define EFI_LIGHTRED (EFI_RED | EFI_BRIGHT) +#define EFI_LIGHTMAGENTA (EFI_MAGENTA | EFI_BRIGHT) +#define EFI_YELLOW (EFI_BROWN | EFI_BRIGHT) +#define EFI_WHITE (EFI_BLUE | EFI_GREEN | EFI_RED | EFI_BRIGHT) + +#define EFI_TEXT_ATTR(f,b) ((f) | ((b) << 4)) + +#define EFI_BACKGROUND_BLACK 0x00 +#define EFI_BACKGROUND_BLUE 0x10 +#define EFI_BACKGROUND_GREEN 0x20 +#define EFI_BACKGROUND_CYAN (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_GREEN) +#define EFI_BACKGROUND_RED 0x40 +#define EFI_BACKGROUND_MAGENTA (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_RED) +#define EFI_BACKGROUND_BROWN (EFI_BACKGROUND_GREEN | EFI_BACKGROUND_RED) +#define EFI_BACKGROUND_LIGHTGRAY (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_GREEN | EFI_BACKGROUND_RED) + + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_CLEAR_SCREEN) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_SET_CURSOR_POSITION) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN UINTN Column, + IN UINTN Row + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_ENABLE_CURSOR) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN BOOLEAN Enable + ); + +typedef struct { + INT32 MaxMode; + // current settings + INT32 Mode; + INT32 Attribute; + INT32 CursorColumn; + INT32 CursorRow; + BOOLEAN CursorVisible; +} SIMPLE_TEXT_OUTPUT_MODE; + +typedef struct _SIMPLE_TEXT_OUTPUT_INTERFACE { + EFI_TEXT_RESET Reset; + + EFI_TEXT_OUTPUT_STRING OutputString; + EFI_TEXT_TEST_STRING TestString; + + EFI_TEXT_QUERY_MODE QueryMode; + EFI_TEXT_SET_MODE SetMode; + EFI_TEXT_SET_ATTRIBUTE SetAttribute; + + EFI_TEXT_CLEAR_SCREEN ClearScreen; + EFI_TEXT_SET_CURSOR_POSITION SetCursorPosition; + EFI_TEXT_ENABLE_CURSOR EnableCursor; + + // Current mode + SIMPLE_TEXT_OUTPUT_MODE *Mode; +} SIMPLE_TEXT_OUTPUT_INTERFACE, EFI_SIMPLE_TEXT_OUT_PROTOCOL; + +// +// Define's for required EFI Unicode Box Draw character +// + +#define BOXDRAW_HORIZONTAL 0x2500 +#define BOXDRAW_VERTICAL 0x2502 +#define BOXDRAW_DOWN_RIGHT 0x250c +#define BOXDRAW_DOWN_LEFT 0x2510 +#define BOXDRAW_UP_RIGHT 0x2514 +#define BOXDRAW_UP_LEFT 0x2518 +#define BOXDRAW_VERTICAL_RIGHT 0x251c +#define BOXDRAW_VERTICAL_LEFT 0x2524 +#define BOXDRAW_DOWN_HORIZONTAL 0x252c +#define BOXDRAW_UP_HORIZONTAL 0x2534 +#define BOXDRAW_VERTICAL_HORIZONTAL 0x253c + +#define BOXDRAW_DOUBLE_HORIZONTAL 0x2550 +#define BOXDRAW_DOUBLE_VERTICAL 0x2551 +#define BOXDRAW_DOWN_RIGHT_DOUBLE 0x2552 +#define BOXDRAW_DOWN_DOUBLE_RIGHT 0x2553 +#define BOXDRAW_DOUBLE_DOWN_RIGHT 0x2554 + +#define BOXDRAW_DOWN_LEFT_DOUBLE 0x2555 +#define BOXDRAW_DOWN_DOUBLE_LEFT 0x2556 +#define BOXDRAW_DOUBLE_DOWN_LEFT 0x2557 + +#define BOXDRAW_UP_RIGHT_DOUBLE 0x2558 +#define BOXDRAW_UP_DOUBLE_RIGHT 0x2559 +#define BOXDRAW_DOUBLE_UP_RIGHT 0x255a + +#define BOXDRAW_UP_LEFT_DOUBLE 0x255b +#define BOXDRAW_UP_DOUBLE_LEFT 0x255c +#define BOXDRAW_DOUBLE_UP_LEFT 0x255d + +#define BOXDRAW_VERTICAL_RIGHT_DOUBLE 0x255e +#define BOXDRAW_VERTICAL_DOUBLE_RIGHT 0x255f +#define BOXDRAW_DOUBLE_VERTICAL_RIGHT 0x2560 + +#define BOXDRAW_VERTICAL_LEFT_DOUBLE 0x2561 +#define BOXDRAW_VERTICAL_DOUBLE_LEFT 0x2562 +#define BOXDRAW_DOUBLE_VERTICAL_LEFT 0x2563 + +#define BOXDRAW_DOWN_HORIZONTAL_DOUBLE 0x2564 +#define BOXDRAW_DOWN_DOUBLE_HORIZONTAL 0x2565 +#define BOXDRAW_DOUBLE_DOWN_HORIZONTAL 0x2566 + +#define BOXDRAW_UP_HORIZONTAL_DOUBLE 0x2567 +#define BOXDRAW_UP_DOUBLE_HORIZONTAL 0x2568 +#define BOXDRAW_DOUBLE_UP_HORIZONTAL 0x2569 + +#define BOXDRAW_VERTICAL_HORIZONTAL_DOUBLE 0x256a +#define BOXDRAW_VERTICAL_DOUBLE_HORIZONTAL 0x256b +#define BOXDRAW_DOUBLE_VERTICAL_HORIZONTAL 0x256c + +// +// EFI Required Block Elements Code Chart +// + +#define BLOCKELEMENT_FULL_BLOCK 0x2588 +#define BLOCKELEMENT_LIGHT_SHADE 0x2591 +// +// EFI Required Geometric Shapes Code Chart +// + +#define GEOMETRICSHAPE_UP_TRIANGLE 0x25b2 +#define GEOMETRICSHAPE_RIGHT_TRIANGLE 0x25ba +#define GEOMETRICSHAPE_DOWN_TRIANGLE 0x25bc +#define GEOMETRICSHAPE_LEFT_TRIANGLE 0x25c4 + +// +// EFI Required Arrow shapes +// + +#define ARROW_UP 0x2191 +#define ARROW_DOWN 0x2193 + +// +// Text input protocol +// + +#define EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID \ + { 0x387477c1, 0x69c7, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} } +#define SIMPLE_TEXT_INPUT_PROTOCOL EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID + +INTERFACE_DECL(_SIMPLE_INPUT_INTERFACE); + +typedef struct { + UINT16 ScanCode; + CHAR16 UnicodeChar; +} EFI_INPUT_KEY; + +// +// Baseline unicode control chars +// + +#define CHAR_NULL 0x0000 +#define CHAR_BACKSPACE 0x0008 +#define CHAR_TAB 0x0009 +#define CHAR_LINEFEED 0x000A +#define CHAR_CARRIAGE_RETURN 0x000D + +// +// Scan codes for base line keys +// + +#define SCAN_NULL 0x0000 +#define SCAN_UP 0x0001 +#define SCAN_DOWN 0x0002 +#define SCAN_RIGHT 0x0003 +#define SCAN_LEFT 0x0004 +#define SCAN_HOME 0x0005 +#define SCAN_END 0x0006 +#define SCAN_INSERT 0x0007 +#define SCAN_DELETE 0x0008 +#define SCAN_PAGE_UP 0x0009 +#define SCAN_PAGE_DOWN 0x000A +#define SCAN_F1 0x000B +#define SCAN_F2 0x000C +#define SCAN_F3 0x000D +#define SCAN_F4 0x000E +#define SCAN_F5 0x000F +#define SCAN_F6 0x0010 +#define SCAN_F7 0x0011 +#define SCAN_F8 0x0012 +#define SCAN_F9 0x0013 +#define SCAN_F10 0x0014 +#define SCAN_F11 0x0015 +#define SCAN_F12 0x0016 +#define SCAN_ESC 0x0017 + +typedef +EFI_STATUS +(EFIAPI *EFI_INPUT_RESET) ( + IN struct _SIMPLE_INPUT_INTERFACE *This, + IN BOOLEAN ExtendedVerification + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_INPUT_READ_KEY) ( + IN struct _SIMPLE_INPUT_INTERFACE *This, + OUT EFI_INPUT_KEY *Key + ); + +typedef struct _SIMPLE_INPUT_INTERFACE { + EFI_INPUT_RESET Reset; + EFI_INPUT_READ_KEY ReadKeyStroke; + EFI_EVENT WaitForKey; +} SIMPLE_INPUT_INTERFACE, EFI_SIMPLE_TEXT_IN_PROTOCOL; + +#endif + diff --git a/include/eficonex.h b/include/eficonex.h new file mode 100644 index 0000000..d9a4347 --- /dev/null +++ b/include/eficonex.h @@ -0,0 +1,111 @@ +#ifndef _EFI_CONEX_H +#define _EFI_CONEX_H + +/*++ + +Copyright (c) 2020 Kagurazaka Kotori + +Module Name: + + eficonex.h + +Abstract: + + EFI console extension protocols + +--*/ + +// +// Simple Text Input Ex Protocol +// + +#define EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID \ + { 0xdd9e7534, 0x7762, 0x4698, {0x8c, 0x14, 0xf5, 0x85, 0x17, 0xa6, 0x25, 0xaa} } + +INTERFACE_DECL(_EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL); + +typedef UINT8 EFI_KEY_TOGGLE_STATE; + +typedef struct EFI_KEY_STATE { + UINT32 KeyShiftState; + EFI_KEY_TOGGLE_STATE KeyToggleState; +} EFI_KEY_STATE; + +typedef struct { + EFI_INPUT_KEY Key; + EFI_KEY_STATE KeyState; +} EFI_KEY_DATA; + +// Shift states +#define EFI_SHIFT_STATE_VALID 0x80000000 +#define EFI_RIGHT_SHIFT_PRESSED 0x00000001 +#define EFI_LEFT_SHIFT_PRESSED 0x00000002 +#define EFI_RIGHT_CONTROL_PRESSED 0x00000004 +#define EFI_LEFT_CONTROL_PRESSED 0x00000008 +#define EFI_RIGHT_ALT_PRESSED 0x00000010 +#define EFI_LEFT_ALT_PRESSED 0x00000020 +#define EFI_RIGHT_LOGO_PRESSED 0x00000040 +#define EFI_LEFT_LOGO_PRESSED 0x00000080 +#define EFI_MENU_KEY_PRESSED 0x00000100 +#define EFI_SYS_REQ_PRESSED 0x00000200 + +// Toggle states +#define EFI_TOGGLE_STATE_VALID 0x80 +#define EFI_KEY_STATE_EXPOSED 0x40 +#define EFI_SCROLL_LOCK_ACTIVE 0x01 +#define EFI_NUM_LOCK_ACTIVE 0x02 +#define EFI_CAPS_LOCK_ACTIVE 0x04 + +typedef +EFI_STATUS +(EFIAPI *EFI_INPUT_RESET_EX) ( + IN struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_INPUT_READ_KEY_EX) ( + IN struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + OUT EFI_KEY_DATA *KeyData + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_STATE) ( + IN struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + IN EFI_KEY_TOGGLE_STATE *KeyToggleState + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_KEY_NOTIFY_FUNCTION) ( + IN EFI_KEY_DATA *KeyData + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_REGISTER_KEYSTROKE_NOTIFY) ( + IN struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + IN EFI_KEY_DATA *KeyData, + IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction, + OUT VOID **NotifyHandle + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_UNREGISTER_KEYSTROKE_NOTIFY) ( + IN struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + IN VOID *NotificationHandle + ); + +typedef struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL{ + EFI_INPUT_RESET_EX Reset; + EFI_INPUT_READ_KEY_EX ReadKeyStrokeEx; + EFI_EVENT WaitForKeyEx; + EFI_SET_STATE SetState; + EFI_REGISTER_KEYSTROKE_NOTIFY RegisterKeyNotify; + EFI_UNREGISTER_KEYSTROKE_NOTIFY UnregisterKeyNotify; +} EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL; + +#endif diff --git a/include/efidebug.h b/include/efidebug.h new file mode 100644 index 0000000..9944246 --- /dev/null +++ b/include/efidebug.h @@ -0,0 +1,620 @@ +#ifndef _EFI_DEBUG_H +#define _EFI_DEBUG_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efidebug.h + +Abstract: + + EFI library debug functions + + + +Revision History + +--*/ + +extern UINTN EFIDebug; + +#if EFI_DEBUG + + #define DBGASSERT(a) DbgAssert(__FILE__, __LINE__, #a) + #define DEBUG(a) DbgPrint a + +#else + + #define DBGASSERT(a) + #define DEBUG(a) + +#endif + +#if EFI_DEBUG_CLEAR_MEMORY + + #define DBGSETMEM(a,l) SetMem(a,l,(CHAR8)BAD_POINTER) + +#else + + #define DBGSETMEM(a,l) + +#endif + +#define D_INIT 0x00000001 // Initialization style messages +#define D_WARN 0x00000002 // Warnings +#define D_LOAD 0x00000004 // Load events +#define D_FS 0x00000008 // EFI File system +#define D_POOL 0x00000010 // Alloc & Free's +#define D_PAGE 0x00000020 // Alloc & Free's +#define D_INFO 0x00000040 // Verbose +#define D_VAR 0x00000100 // Variable +#define D_PARSE 0x00000200 // Command parsing +#define D_BM 0x00000400 // Boot manager +#define D_BLKIO 0x00001000 // BlkIo Driver +#define D_BLKIO_ULTRA 0x00002000 // BlkIo Driver +#define D_NET 0x00004000 // SNI Driver +#define D_NET_ULTRA 0x00008000 // SNI Driver +#define D_TXTIN 0x00010000 // Simple Input Driver +#define D_TXTOUT 0x00020000 // Simple Text Output Driver +#define D_ERROR_ATA 0x00040000 // ATA error messages +#define D_ERROR 0x80000000 // Error + +#define D_RESERVED 0x7fffC880 // Bits not reserved above + +// +// Current Debug level of the system, value of EFIDebug +// +//#define EFI_DBUG_MASK (D_ERROR | D_WARN | D_LOAD | D_BLKIO | D_INIT) +#define EFI_DBUG_MASK (D_ERROR) + +// +// +// + +#if EFI_DEBUG + + #define ASSERT(a) if(!(a)) DBGASSERT(a) + #define ASSERT_LOCKED(l) if(!(l)->Lock) DBGASSERT(l not locked) + #define ASSERT_STRUCT(p,t) DBGASSERT(t not structure), p + +#else + + #define ASSERT(a) + #define ASSERT_LOCKED(l) + #define ASSERT_STRUCT(p,t) + +#endif + +// +// Prototypes +// + +INTN +DbgAssert ( + CONST CHAR8 *file, + INTN lineno, + CONST CHAR8 *string + ); + +INTN +DbgPrint ( + INTN mask, + CONST CHAR8 *format, + ... + ); + +// +// Instruction Set Architectures definitions for debuggers +// + +typedef INTN EFI_EXCEPTION_TYPE; + +// IA32 +#define EXCEPT_IA32_DIVIDE_ERROR 0 +#define EXCEPT_IA32_DEBUG 1 +#define EXCEPT_IA32_NMI 2 +#define EXCEPT_IA32_BREAKPOINT 3 +#define EXCEPT_IA32_OVERFLOW 4 +#define EXCEPT_IA32_BOUND 5 +#define EXCEPT_IA32_INVALID_OPCODE 6 +#define EXCEPT_IA32_DOUBLE_FAULT 8 +#define EXCEPT_IA32_INVALID_TSS 10 +#define EXCEPT_IA32_SEG_NOT_PRESENT 11 +#define EXCEPT_IA32_STACK_FAULT 12 +#define EXCEPT_IA32_GP_FAULT 13 +#define EXCEPT_IA32_PAGE_FAULT 14 +#define EXCEPT_IA32_FP_ERROR 16 +#define EXCEPT_IA32_ALIGNMENT_CHECK 17 +#define EXCEPT_IA32_MACHINE_CHECK 18 +#define EXCEPT_IA32_SIMD 19 + +typedef struct { + UINT16 Fcw; + UINT16 Fsw; + UINT16 Ftw; + UINT16 Opcode; + UINT32 Eip; + UINT16 Cs; + UINT16 Reserved1; + UINT32 DataOffset; + UINT16 Ds; + UINT8 Reserved2[10]; + UINT8 St0Mm0[10], Reserved3[6]; + UINT8 St1Mm1[10], Reserved4[6]; + UINT8 St2Mm2[10], Reserved5[6]; + UINT8 St3Mm3[10], Reserved6[6]; + UINT8 St4Mm4[10], Reserved7[6]; + UINT8 St5Mm5[10], Reserved8[6]; + UINT8 St6Mm6[10], Reserved9[6]; + UINT8 St7Mm7[10], Reserved10[6]; + UINT8 Xmm0[16]; + UINT8 Xmm1[16]; + UINT8 Xmm2[16]; + UINT8 Xmm3[16]; + UINT8 Xmm4[16]; + UINT8 Xmm5[16]; + UINT8 Xmm6[16]; + UINT8 Xmm7[16]; + UINT8 Reserved11[14 * 16]; +} EFI_FX_SAVE_STATE_IA32; + +typedef struct { + UINT32 ExceptionData; + EFI_FX_SAVE_STATE_IA32 FxSaveState; + UINT32 Dr0; + UINT32 Dr1; + UINT32 Dr2; + UINT32 Dr3; + UINT32 Dr6; + UINT32 Dr7; + UINT32 Cr0; + UINT32 Cr1; + UINT32 Cr2; + UINT32 Cr3; + UINT32 Cr4; + UINT32 Eflags; + UINT32 Ldtr; + UINT32 Tr; + UINT32 Gdtr[2]; + UINT32 Idtr[2]; + UINT32 Eip; + UINT32 Gs; + UINT32 Fs; + UINT32 Es; + UINT32 Ds; + UINT32 Cs; + UINT32 Ss; + UINT32 Edi; + UINT32 Esi; + UINT32 Ebp; + UINT32 Esp; + UINT32 Ebx; + UINT32 Edx; + UINT32 Ecx; + UINT32 Eax; +} EFI_SYSTEM_CONTEXT_IA32; + +// X64 +#define EXCEPT_X64_DIVIDE_ERROR 0 +#define EXCEPT_X64_DEBUG 1 +#define EXCEPT_X64_NMI 2 +#define EXCEPT_X64_BREAKPOINT 3 +#define EXCEPT_X64_OVERFLOW 4 +#define EXCEPT_X64_BOUND 5 +#define EXCEPT_X64_INVALID_OPCODE 6 +#define EXCEPT_X64_DOUBLE_FAULT 8 +#define EXCEPT_X64_INVALID_TSS 10 +#define EXCEPT_X64_SEG_NOT_PRESENT 11 +#define EXCEPT_X64_STACK_FAULT 12 +#define EXCEPT_X64_GP_FAULT 13 +#define EXCEPT_X64_PAGE_FAULT 14 +#define EXCEPT_X64_FP_ERROR 16 +#define EXCEPT_X64_ALIGNMENT_CHECK 17 +#define EXCEPT_X64_MACHINE_CHECK 18 +#define EXCEPT_X64_SIMD 19 + +typedef struct { + UINT16 Fcw; + UINT16 Fsw; + UINT16 Ftw; + UINT16 Opcode; + UINT64 Rip; + UINT64 DataOffset; + UINT8 Reserved1[8]; + UINT8 St0Mm0[10], Reserved2[6]; + UINT8 St1Mm1[10], Reserved3[6]; + UINT8 St2Mm2[10], Reserved4[6]; + UINT8 St3Mm3[10], Reserved5[6]; + UINT8 St4Mm4[10], Reserved6[6]; + UINT8 St5Mm5[10], Reserved7[6]; + UINT8 St6Mm6[10], Reserved8[6]; + UINT8 St7Mm7[10], Reserved9[6]; + UINT8 Xmm0[16]; + UINT8 Xmm1[16]; + UINT8 Xmm2[16]; + UINT8 Xmm3[16]; + UINT8 Xmm4[16]; + UINT8 Xmm5[16]; + UINT8 Xmm6[16]; + UINT8 Xmm7[16]; + UINT8 Reserved11[14 * 16]; +} EFI_FX_SAVE_STATE_X64; + +typedef struct { + UINT64 ExceptionData; + EFI_FX_SAVE_STATE_X64 FxSaveState; + UINT64 Dr0; + UINT64 Dr1; + UINT64 Dr2; + UINT64 Dr3; + UINT64 Dr6; + UINT64 Dr7; + UINT64 Cr0; + UINT64 Cr1; + UINT64 Cr2; + UINT64 Cr3; + UINT64 Cr4; + UINT64 Cr8; + UINT64 Rflags; + UINT64 Ldtr; + UINT64 Tr; + UINT64 Gdtr[2]; + UINT64 Idtr[2]; + UINT64 Rip; + UINT64 Gs; + UINT64 Fs; + UINT64 Es; + UINT64 Ds; + UINT64 Cs; + UINT64 Ss; + UINT64 Rdi; + UINT64 Rsi; + UINT64 Rbp; + UINT64 Rsp; + UINT64 Rbx; + UINT64 Rdx; + UINT64 Rcx; + UINT64 Rax; + UINT64 R8; + UINT64 R9; + UINT64 R10; + UINT64 R11; + UINT64 R12; + UINT64 R13; + UINT64 R14; + UINT64 R15; +} EFI_SYSTEM_CONTEXT_X64; + +/// IA64 +#define EXCEPT_IPF_VHTP_TRANSLATION 0 +#define EXCEPT_IPF_INSTRUCTION_TLB 1 +#define EXCEPT_IPF_DATA_TLB 2 +#define EXCEPT_IPF_ALT_INSTRUCTION_TLB 3 +#define EXCEPT_IPF_ALT_DATA_TLB 4 +#define EXCEPT_IPF_DATA_NESTED_TLB 5 +#define EXCEPT_IPF_INSTRUCTION_KEY_MISSED 6 +#define EXCEPT_IPF_DATA_KEY_MISSED 7 +#define EXCEPT_IPF_DIRTY_BIT 8 +#define EXCEPT_IPF_INSTRUCTION_ACCESS_BIT 9 +#define EXCEPT_IPF_DATA_ACCESS_BIT 10 +#define EXCEPT_IPF_BREAKPOINT 11 +#define EXCEPT_IPF_EXTERNAL_INTERRUPT 12 +#define EXCEPT_IPF_PAGE_NOT_PRESENT 20 +#define EXCEPT_IPF_KEY_PERMISSION 21 +#define EXCEPT_IPF_INSTRUCTION_ACCESS_RIGHTS 22 +#define EXCEPT_IPF_DATA_ACCESS_RIGHTS 23 +#define EXCEPT_IPF_GENERAL_EXCEPTION 24 +#define EXCEPT_IPF_DISABLED_FP_REGISTER 25 +#define EXCEPT_IPF_NAT_CONSUMPTION 26 +#define EXCEPT_IPF_SPECULATION 27 +#define EXCEPT_IPF_DEBUG 29 +#define EXCEPT_IPF_UNALIGNED_REFERENCE 30 +#define EXCEPT_IPF_UNSUPPORTED_DATA_REFERENCE 31 +#define EXCEPT_IPF_FP_FAULT 32 +#define EXCEPT_IPF_FP_TRAP 33 +#define EXCEPT_IPF_LOWER_PRIVILEGE_TRANSFER_TRAP 34 +#define EXCEPT_IPF_TAKEN_BRANCH 35 +#define EXCEPT_IPF_SINGLE_STEP 36 +#define EXCEPT_IPF_IA32_EXCEPTION 45 +#define EXCEPT_IPF_IA32_INTERCEPT 46 +#define EXCEPT_IPF_IA32_INTERRUPT 47 + +typedef struct { + UINT64 Reserved; + UINT64 R1; + UINT64 R2; + UINT64 R3; + UINT64 R4; + UINT64 R5; + UINT64 R6; + UINT64 R7; + UINT64 R8; + UINT64 R9; + UINT64 R10; + UINT64 R11; + UINT64 R12; + UINT64 R13; + UINT64 R14; + UINT64 R15; + UINT64 R16; + UINT64 R17; + UINT64 R18; + UINT64 R19; + UINT64 R20; + UINT64 R21; + UINT64 R22; + UINT64 R23; + UINT64 R24; + UINT64 R25; + UINT64 R26; + UINT64 R27; + UINT64 R28; + UINT64 R29; + UINT64 R30; + UINT64 R31; + UINT64 F2[2]; + UINT64 F3[2]; + UINT64 F4[2]; + UINT64 F5[2]; + UINT64 F6[2]; + UINT64 F7[2]; + UINT64 F8[2]; + UINT64 F9[2]; + UINT64 F10[2]; + UINT64 F11[2]; + UINT64 F12[2]; + UINT64 F13[2]; + UINT64 F14[2]; + UINT64 F15[2]; + UINT64 F16[2]; + UINT64 F17[2]; + UINT64 F18[2]; + UINT64 F19[2]; + UINT64 F20[2]; + UINT64 F21[2]; + UINT64 F22[2]; + UINT64 F23[2]; + UINT64 F24[2]; + UINT64 F25[2]; + UINT64 F26[2]; + UINT64 F27[2]; + UINT64 F28[2]; + UINT64 F29[2]; + UINT64 F30[2]; + UINT64 F31[2]; + UINT64 Pr; + UINT64 B0; + UINT64 B1; + UINT64 B2; + UINT64 B3; + UINT64 B4; + UINT64 B5; + UINT64 B6; + UINT64 B7; + UINT64 ArRsc; + UINT64 ArBsp; + UINT64 ArBspstore; + UINT64 ArRnat; + UINT64 ArFcr; + UINT64 ArEflag; + UINT64 ArCsd; + UINT64 ArSsd; + UINT64 ArCflg; + UINT64 ArFsr; + UINT64 ArFir; + UINT64 ArFdr; + UINT64 ArCcv; + UINT64 ArUnat; + UINT64 ArFpsr; + UINT64 ArPfs; + UINT64 ArLc; + UINT64 ArEc; + UINT64 CrDcr; + UINT64 CrItm; + UINT64 CrIva; + UINT64 CrPta; + UINT64 CrIpsr; + UINT64 CrIsr; + UINT64 CrIip; + UINT64 CrIfa; + UINT64 CrItir; + UINT64 CrIipa; + UINT64 CrIfs; + UINT64 CrIim; + UINT64 CrIha; + UINT64 Dbr0; + UINT64 Dbr1; + UINT64 Dbr2; + UINT64 Dbr3; + UINT64 Dbr4; + UINT64 Dbr5; + UINT64 Dbr6; + UINT64 Dbr7; + UINT64 Ibr0; + UINT64 Ibr1; + UINT64 Ibr2; + UINT64 Ibr3; + UINT64 Ibr4; + UINT64 Ibr5; + UINT64 Ibr6; + UINT64 Ibr7; + UINT64 IntNat; +} EFI_SYSTEM_CONTEXT_IPF; + +// EBC +#define EXCEPT_EBC_UNDEFINED 0 +#define EXCEPT_EBC_DIVIDE_ERROR 1 +#define EXCEPT_EBC_DEBUG 2 +#define EXCEPT_EBC_BREAKPOINT 3 +#define EXCEPT_EBC_OVERFLOW 4 +#define EXCEPT_EBC_INVALID_OPCODE 5 +#define EXCEPT_EBC_STACK_FAULT 6 +#define EXCEPT_EBC_ALIGNMENT_CHECK 7 +#define EXCEPT_EBC_INSTRUCTION_ENCODING 8 +#define EXCEPT_EBC_BAD_BREAK 9 +#define EXCEPT_EBC_STEP 10 +#define MAX_EBC_EXCEPTION EXCEPT_EBC_STEP + +typedef struct { + UINT64 R0; + UINT64 R1; + UINT64 R2; + UINT64 R3; + UINT64 R4; + UINT64 R5; + UINT64 R6; + UINT64 R7; + UINT64 Flags; + UINT64 ControlFlags; + UINT64 Ip; +} EFI_SYSTEM_CONTEXT_EBC; + +// ARM +#define EXCEPT_ARM_RESET 0 +#define EXCEPT_ARM_UNDEFINED_INSTRUCTION 1 +#define EXCEPT_ARM_SOFTWARE_INTERRUPT 2 +#define EXCEPT_ARM_PREFETCH_ABORT 3 +#define EXCEPT_ARM_DATA_ABORT 4 +#define EXCEPT_ARM_RESERVED 5 +#define EXCEPT_ARM_IRQ 6 +#define EXCEPT_ARM_FIQ 7 +#define MAX_ARM_EXCEPTION EXCEPT_ARM_FIQ + +typedef struct { + UINT32 R0; + UINT32 R1; + UINT32 R2; + UINT32 R3; + UINT32 R4; + UINT32 R5; + UINT32 R6; + UINT32 R7; + UINT32 R8; + UINT32 R9; + UINT32 R10; + UINT32 R11; + UINT32 R12; + UINT32 SP; + UINT32 LR; + UINT32 PC; + UINT32 CPSR; + UINT32 DFSR; + UINT32 DFAR; + UINT32 IFSR; + UINT32 IFAR; +} EFI_SYSTEM_CONTEXT_ARM; + + +typedef union { + EFI_SYSTEM_CONTEXT_EBC *SystemContextEbc; + EFI_SYSTEM_CONTEXT_IA32 *SystemContextIa32; + EFI_SYSTEM_CONTEXT_X64 *SystemContextX64; + EFI_SYSTEM_CONTEXT_IPF *SystemContextIpf; + EFI_SYSTEM_CONTEXT_ARM *SystemContextArm; +} EFI_SYSTEM_CONTEXT; + +typedef +VOID +(EFIAPI *EFI_EXCEPTION_CALLBACK)( + IN EFI_EXCEPTION_TYPE ExceptionType, + IN OUT EFI_SYSTEM_CONTEXT SystemContext); + +typedef +VOID +(EFIAPI *EFI_PERIODIC_CALLBACK)( + IN OUT EFI_SYSTEM_CONTEXT SystemContext); + +typedef enum { + IsaIa32 = EFI_IMAGE_MACHINE_IA32, + IsaX64 = EFI_IMAGE_MACHINE_X64, + IsaIpf = EFI_IMAGE_MACHINE_IA64, + IsaEbc = EFI_IMAGE_MACHINE_EBC, + IsaArm = EFI_IMAGE_MACHINE_ARMTHUMB_MIXED, +// IsaArm64 = EFI_IMAGE_MACHINE_AARCH64 +} EFI_INSTRUCTION_SET_ARCHITECTURE; + +// +// DEBUG_IMAGE_INFO +// + +#define EFI_DEBUG_IMAGE_INFO_TABLE_GUID \ + { 0x49152e77, 0x1ada, 0x4764, {0xb7, 0xa2, 0x7a, 0xfe, 0xfe, 0xd9, 0x5e, 0x8b} } + +#define EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS 0x01 +#define EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED 0x02 +#define EFI_DEBUG_IMAGE_INFO_INITIAL_SIZE (EFI_PAGE_SIZE / sizeof (UINTN)) +#define EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL 0x01 + +typedef struct { +UINT64 Signature; +EFI_PHYSICAL_ADDRESS EfiSystemTableBase; +UINT32 Crc32; +} EFI_SYSTEM_TABLE_POINTER; + +typedef struct { +UINT32 ImageInfoType; +EFI_LOADED_IMAGE_PROTOCOL *LoadedImageProtocolInstance; +EFI_HANDLE *ImageHandle; +} EFI_DEBUG_IMAGE_INFO_NORMAL; + +typedef union { +UINT32 *ImageInfoType; +EFI_DEBUG_IMAGE_INFO_NORMAL *NormalImage; +} EFI_DEBUG_IMAGE_INFO; + +typedef struct { +volatile UINT32 UpdateStatus; +UINT32 TableSize; +EFI_DEBUG_IMAGE_INFO *EfiDebugImageInfoTable; +} EFI_DEBUG_IMAGE_INFO_TABLE_HEADER; + +// +// EFI_DEBUGGER_PROTOCOL +// + +#define EFI_DEBUG_SUPPORT_PROTOCOL_GUID \ + { 0x2755590c, 0x6f3c, 0x42fa, {0x9e, 0xa4, 0xa3, 0xba, 0x54, 0x3c, 0xda, 0x25} } + +INTERFACE_DECL(_EFI_DEBUG_SUPPORT_PROTOCOL); + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_MAXIMUM_PROCESSOR_INDEX)( + IN struct _EFI_DEBUG_SUPPORT_PROTOCOL *This, + OUT UINTN *MaxProcessorIndex); + +typedef +EFI_STATUS +(EFIAPI *EFI_REGISTER_PERIODIC_CALLBACK)( + IN struct _EFI_DEBUG_SUPPORT_PROTOCOL *This, + IN UINTN ProcessorIndex, + IN EFI_PERIODIC_CALLBACK PeriodicCallback); + +typedef +EFI_STATUS +(EFIAPI *EFI_REGISTER_EXCEPTION_CALLBACK)( + IN struct _EFI_DEBUG_SUPPORT_PROTOCOL *This, + IN UINTN ProcessorIndex, + IN EFI_EXCEPTION_CALLBACK ExceptionCallback, + IN EFI_EXCEPTION_TYPE ExceptionType); + +typedef +EFI_STATUS +(EFIAPI *EFI_INVALIDATE_INSTRUCTION_CACHE)( + IN struct _EFI_DEBUG_SUPPORT_PROTOCOL *This, + IN UINTN ProcessorIndex, + IN VOID *Start, + IN UINT64 Length); + +typedef struct _EFI_DEBUG_SUPPORT_PROTOCOL { + EFI_INSTRUCTION_SET_ARCHITECTURE Isa; + EFI_GET_MAXIMUM_PROCESSOR_INDEX GetMaximumProcessorIndex; + EFI_REGISTER_PERIODIC_CALLBACK RegisterPeriodicCallback; + EFI_REGISTER_EXCEPTION_CALLBACK RegisterExceptionCallback; + EFI_INVALIDATE_INSTRUCTION_CACHE InvalidateInstructionCache; +} EFI_DEBUG_SUPPORT_PROTOCOL; + +#endif diff --git a/include/efidef.h b/include/efidef.h new file mode 100644 index 0000000..52a3f79 --- /dev/null +++ b/include/efidef.h @@ -0,0 +1,258 @@ +#ifndef _EFI_DEF_H +#define _EFI_DEF_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efidef.h + +Abstract: + + EFI definitions + + + + +Revision History + +--*/ + +#if !defined(__cplusplus) +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +typedef _Bool BOOLEAN; +#else +typedef unsigned char BOOLEAN; +#endif +#else +typedef bool BOOLEAN; +#endif + +#ifndef CONST + #define CONST const +#endif +#ifndef TRUE +#if defined(__cplusplus) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L) + #define TRUE true + #define FALSE false +#else + #define TRUE ((BOOLEAN) 1) + #define FALSE ((BOOLEAN) 0) +#endif +#endif + +#ifndef NULL +#if (defined(__cplusplus) && __cplusplus >= 201103L) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L) + #define NULL nullptr +#else +#if !defined(__cplusplus) + #define NULL ((VOID *) 0) +#else + #define NULL 0 +#endif +#endif +#endif + +typedef UINTN EFI_STATUS; +typedef UINT64 EFI_LBA; +typedef UINTN EFI_TPL; +typedef VOID *EFI_HANDLE; +typedef VOID *EFI_EVENT; + + +// +// Prototype argument decoration for EFI parameters to indicate +// their direction +// +// IN - argument is passed into the function +// OUT - argument (pointer) is returned from the function +// OPTIONAL - argument is optional +// + +#ifndef IN + #define IN + #define OUT + #define OPTIONAL +#endif + + +// +// A GUID +// + +typedef struct { + UINT32 Data1; + UINT16 Data2; + UINT16 Data3; + UINT8 Data4[8]; +} EFI_GUID; + + +// +// Time +// + +typedef struct { + UINT16 Year; // 1998 - 20XX + UINT8 Month; // 1 - 12 + UINT8 Day; // 1 - 31 + UINT8 Hour; // 0 - 23 + UINT8 Minute; // 0 - 59 + UINT8 Second; // 0 - 59 + UINT8 Pad1; + UINT32 Nanosecond; // 0 - 999,999,999 + INT16 TimeZone; // -1440 to 1440 or 2047 + UINT8 Daylight; + UINT8 Pad2; +} EFI_TIME; + +// Bit definitions for EFI_TIME.Daylight +#define EFI_TIME_ADJUST_DAYLIGHT 0x01 +#define EFI_TIME_IN_DAYLIGHT 0x02 + +// Value definition for EFI_TIME.TimeZone +#define EFI_UNSPECIFIED_TIMEZONE 0x07FF + + + +// +// Networking +// + +typedef struct { + UINT8 Addr[4]; +} EFI_IPv4_ADDRESS; + +typedef struct { + UINT8 Addr[16]; +} EFI_IPv6_ADDRESS; + +typedef struct { + UINT8 Addr[32]; +} EFI_MAC_ADDRESS; + +typedef struct { + UINT32 ReceivedQueueTimeoutValue; + UINT32 TransmitQueueTimeoutValue; + UINT16 ProtocolTypeFilter; + BOOLEAN EnableUnicastReceive; + BOOLEAN EnableMulticastReceive; + BOOLEAN EnableBroadcastReceive; + BOOLEAN EnablePromiscuousReceive; + BOOLEAN FlushQueuesOnReset; + BOOLEAN EnableReceiveTimestamps; + BOOLEAN DisableBackgroundPolling; +} EFI_MANAGED_NETWORK_CONFIG_DATA; + +// +// Memory +// + +typedef UINT64 EFI_PHYSICAL_ADDRESS; +typedef UINT64 EFI_VIRTUAL_ADDRESS; + +typedef enum { + AllocateAnyPages, + AllocateMaxAddress, + AllocateAddress, + MaxAllocateType +} EFI_ALLOCATE_TYPE; + +//Preseve the attr on any range supplied. +//ConventialMemory must have WB,SR,SW when supplied. +//When allocating from ConventialMemory always make it WB,SR,SW +//When returning to ConventialMemory always make it WB,SR,SW +//When getting the memory map, or on RT for runtime types + + +typedef enum { + EfiReservedMemoryType, + EfiLoaderCode, + EfiLoaderData, + EfiBootServicesCode, + EfiBootServicesData, + EfiRuntimeServicesCode, + EfiRuntimeServicesData, + EfiConventionalMemory, + EfiUnusableMemory, + EfiACPIReclaimMemory, + EfiACPIMemoryNVS, + EfiMemoryMappedIO, + EfiMemoryMappedIOPortSpace, + EfiPalCode, + EfiPersistentMemory, + EfiUnacceptedMemoryType, + EfiMaxMemoryType +} EFI_MEMORY_TYPE; + + +// Memory cacheability attribute +#define EFI_MEMORY_UC 0x0000000000000001 +#define EFI_MEMORY_WC 0x0000000000000002 +#define EFI_MEMORY_WT 0x0000000000000004 +#define EFI_MEMORY_WB 0x0000000000000008 +#define EFI_MEMORY_UCE 0x0000000000000010 + +// Physical memory protection attribute +#define EFI_MEMORY_WP 0x0000000000001000 +#define EFI_MEMORY_RP 0x0000000000002000 +#define EFI_MEMORY_XP 0x0000000000004000 +#define EFI_MEMORY_RO 0x0000000000020000 + +// Runtime memory attribute +#define EFI_MEMORY_NV 0x0000000000008000 +#define EFI_MEMORY_RUNTIME 0x8000000000000000 + +// Other memory attribute +#define EFI_MEMORY_MORE_RELIABLE 0x0000000000010000 +#define EFI_MEMORY_SP 0x0000000000040000 +#define EFI_MEMORY_CPU_CRYPTO 0x0000000000080000 +#define EFI_MEMORY_ISA_VALID 0x4000000000000000 +#define EFI_MEMORY_ISA_MASK 0x0FFFF00000000000 + + +#define EFI_MEMORY_DESCRIPTOR_VERSION 1 +typedef struct { + UINT32 Type; // Field size is 32 bits followed by 32 bit pad + UINT32 Pad; + EFI_PHYSICAL_ADDRESS PhysicalStart; // Field size is 64 bits + EFI_VIRTUAL_ADDRESS VirtualStart; // Field size is 64 bits + UINT64 NumberOfPages; // Field size is 64 bits + UINT64 Attribute; // Field size is 64 bits +} EFI_MEMORY_DESCRIPTOR; + +// +// International Language +// + +typedef CHAR8 ISO_639_2; +#define ISO_639_2_ENTRY_SIZE 3 + +// +// +// + +#define EFI_PAGE_SIZE 4096 +#define EFI_PAGE_MASK 0xFFF +#define EFI_PAGE_SHIFT 12 + +#define EFI_SIZE_TO_PAGES(a) \ + ( ((a) >> EFI_PAGE_SHIFT) + ((a) & EFI_PAGE_MASK ? 1 : 0) ) + +#define EFI_OS_INDICATIONS_BOOT_TO_FW_UI 0x0000000000000001 +#define EFI_OS_INDICATIONS_TIMESTAMP_REVOCATION 0x0000000000000002 +#define EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED \ + 0x0000000000000004 +#define EFI_OS_INDICATIONS_FMP_CAPSULE_SUPPORTED \ + 0x0000000000000008 +#define EFI_OS_INDICATIONS_CAPSULE_RESULT_VAR_SUPPORTED \ + 0x0000000000000010 +#define EFI_OS_INDICATIONS_START_OS_RECOVERY 0x0000000000000020 +#define EFI_OS_INDICATIONS_START_PLATFORM_RECOVERY \ + 0x0000000000000040 +#define EFI_OS_INDICATIONS_JSON_CONFIG_DATA_REFRESH \ + 0x0000000000000080 + +#endif diff --git a/include/efidevp.h b/include/efidevp.h new file mode 100644 index 0000000..527bb95 --- /dev/null +++ b/include/efidevp.h @@ -0,0 +1,650 @@ +#ifndef _DEVPATH_H +#define _DEVPATH_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + devpath.h + +Abstract: + + Defines for parsing the EFI Device Path structures + + + +Revision History + +--*/ + +// +// Device Path structures - Section C +// + +typedef struct _EFI_DEVICE_PATH_PROTOCOL { + UINT8 Type; + UINT8 SubType; + UINT8 Length[2]; +} EFI_DEVICE_PATH_PROTOCOL; + +typedef struct _EFI_DEVICE_PATH_PROTOCOL _EFI_DEVICE_PATH; +typedef EFI_DEVICE_PATH_PROTOCOL EFI_DEVICE_PATH; + +#define EFI_DP_TYPE_MASK 0x7F +#define EFI_DP_TYPE_UNPACKED 0x80 + +//#define END_DEVICE_PATH_TYPE 0xff +#define END_DEVICE_PATH_TYPE 0x7f +//#define END_DEVICE_PATH_TYPE_UNPACKED 0x7f + +#define END_ENTIRE_DEVICE_PATH_SUBTYPE 0xff +#define END_INSTANCE_DEVICE_PATH_SUBTYPE 0x01 +#define END_DEVICE_PATH_LENGTH (sizeof(EFI_DEVICE_PATH_PROTOCOL)) + + +#define DP_IS_END_TYPE(a) +#define DP_IS_END_SUBTYPE(a) ( ((a)->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE ) + +#define DevicePathType(a) ( ((a)->Type) & EFI_DP_TYPE_MASK ) +#define DevicePathSubType(a) ( (a)->SubType ) +#define DevicePathNodeLength(a) ( ((a)->Length[0]) | ((a)->Length[1] << 8) ) +#define NextDevicePathNode(a) ( (EFI_DEVICE_PATH_PROTOCOL *) ( ((UINT8 *) (a)) + DevicePathNodeLength(a))) +//#define IsDevicePathEndType(a) ( DevicePathType(a) == END_DEVICE_PATH_TYPE_UNPACKED ) +#define IsDevicePathEndType(a) ( DevicePathType(a) == END_DEVICE_PATH_TYPE ) +#define IsDevicePathEndSubType(a) ( (a)->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE ) +#define IsDevicePathEnd(a) ( IsDevicePathEndType(a) && IsDevicePathEndSubType(a) ) +#define IsDevicePathUnpacked(a) ( (a)->Type & EFI_DP_TYPE_UNPACKED ) + + +#define SetDevicePathNodeLength(a,l) { \ + (a)->Length[0] = (UINT8) (l); \ + (a)->Length[1] = (UINT8) ((l) >> 8); \ + } + +#define SetDevicePathEndNode(a) { \ + (a)->Type = END_DEVICE_PATH_TYPE; \ + (a)->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE; \ + (a)->Length[0] = sizeof(EFI_DEVICE_PATH_PROTOCOL); \ + (a)->Length[1] = 0; \ + } + + +/* + * Hardware Device Path (UEFI 2.4 specification, version 2.4 § 9.3.2.) + */ + +#define HARDWARE_DEVICE_PATH 0x01 + +#define HW_PCI_DP 0x01 +typedef struct _PCI_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header; + UINT8 Function; + UINT8 Device; +} PCI_DEVICE_PATH; + +#define HW_PCCARD_DP 0x02 +typedef struct _PCCARD_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header; + UINT8 FunctionNumber ; +} PCCARD_DEVICE_PATH; + +#define HW_MEMMAP_DP 0x03 +typedef struct _MEMMAP_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header; + UINT32 MemoryType; + EFI_PHYSICAL_ADDRESS StartingAddress; + EFI_PHYSICAL_ADDRESS EndingAddress; +} MEMMAP_DEVICE_PATH; + +#define HW_VENDOR_DP 0x04 +typedef struct _VENDOR_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header; + EFI_GUID Guid; +} VENDOR_DEVICE_PATH; + +#define UNKNOWN_DEVICE_GUID \ + { 0xcf31fac5, 0xc24e, 0x11d2, {0x85, 0xf3, 0x0, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b} } + +typedef struct _UKNOWN_DEVICE_VENDOR_DP { + VENDOR_DEVICE_PATH DevicePath; + UINT8 LegacyDriveLetter; +} UNKNOWN_DEVICE_VENDOR_DEVICE_PATH; + +#define HW_CONTROLLER_DP 0x05 +typedef struct _CONTROLLER_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header; + UINT32 Controller; +} CONTROLLER_DEVICE_PATH; + + +/* + * ACPI Device Path (UEFI 2.4 specification, version 2.4 § 9.3.3 and 9.3.4.) + */ +#define ACPI_DEVICE_PATH 0x02 + +#define ACPI_DP 0x01 +typedef struct _ACPI_HID_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header; + UINT32 HID; + UINT32 UID; +} ACPI_HID_DEVICE_PATH; + +#define EXPANDED_ACPI_DP 0x02 +typedef struct _EXPANDED_ACPI_HID_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header; + UINT32 HID; + UINT32 UID; + UINT32 CID; + UINT8 HidStr[1]; +} EXPANDED_ACPI_HID_DEVICE_PATH; + +#define ACPI_ADR_DP 3 +typedef struct _ACPI_ADR_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header ; + UINT32 ADR ; +} ACPI_ADR_DEVICE_PATH ; + +// +// EISA ID Macro +// EISA ID Definition 32-bits +// bits[15:0] - three character compressed ASCII EISA ID. +// bits[31:16] - binary number +// Compressed ASCII is 5 bits per character 0b00001 = 'A' 0b11010 = 'Z' +// +#define PNP_EISA_ID_CONST 0x41d0 +#define EISA_ID(_Name, _Num) ((UINT32) ((_Name) | (_Num) << 16)) +#define EISA_PNP_ID(_PNPId) (EISA_ID(PNP_EISA_ID_CONST, (_PNPId))) + +#define PNP_EISA_ID_MASK 0xffff +#define EISA_ID_TO_NUM(_Id) ((_Id) >> 16) + + +/* + * Messaging Device Path (UEFI 2.4 specification, version 2.4 § 9.3.5.) + */ +#define MESSAGING_DEVICE_PATH 0x03 + +#define MSG_ATAPI_DP 0x01 +typedef struct _ATAPI_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header; + UINT8 PrimarySecondary; + UINT8 SlaveMaster; + UINT16 Lun; +} ATAPI_DEVICE_PATH; + +#define MSG_SCSI_DP 0x02 +typedef struct _SCSI_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header; + UINT16 Pun; + UINT16 Lun; +} SCSI_DEVICE_PATH; + +#define MSG_FIBRECHANNEL_DP 0x03 +typedef struct _FIBRECHANNEL_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header; + UINT32 Reserved; + UINT64 WWN; + UINT64 Lun; +} FIBRECHANNEL_DEVICE_PATH; + +/** + * Fibre Channel Ex SubType. + * UEFI 2.0 specification version 2.4 § 9.3.5.6. + */ +#define MSG_FIBRECHANNELEX_DP 21 +typedef struct _FIBRECHANNELEX_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header ; + UINT32 Reserved ; + UINT8 WWN[ 8 ] ; /* World Wide Name */ + UINT8 Lun[ 8 ] ; /* Logical unit, T-10 SCSI Architecture Model 4 specification */ +} FIBRECHANNELEX_DEVICE_PATH ; + +#define MSG_1394_DP 0x04 +typedef struct _F1394_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header; + UINT32 Reserved; + UINT64 Guid; +} F1394_DEVICE_PATH; + +#define MSG_USB_DP 0x05 +typedef struct _USB_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header; + UINT8 Port; + UINT8 Endpoint; +} USB_DEVICE_PATH; + +/** + * SATA Device Path SubType. + * UEFI 2.0 specification version 2.4 § 9.3.5.6. + */ +#define MSG_SATA_DP 18 +typedef struct _SATA_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header ; + UINT16 HBAPortNumber ; + UINT16 PortMultiplierPortNumber ; + UINT16 Lun ; /* Logical Unit Number */ +} SATA_DEVICE_PATH ; + +/** + * USB WWID Device Path SubType. + * UEFI 2.0 specification version 2.4 § 9.3.5.7. + */ +#define MSG_USB_WWID_DP 16 +typedef struct _USB_WWID_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header ; + UINT16 InterfaceNumber ; + UINT16 VendorId ; + UINT16 ProductId ; + CHAR16 SerialNumber[ 1 ] ; /* UTF-16 characters of the USB serial number */ +} USB_WWID_DEVICE_PATH ; + +/** + * Device Logical Unit SubType. + * UEFI 2.0 specification version 2.4 § 9.3.5.8. + */ +#define MSG_DEVICE_LOGICAL_UNIT_DP 17 +typedef struct _DEVICE_LOGICAL_UNIT_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header ; + UINT8 Lun ; /* Logical Unit Number */ +} DEVICE_LOGICAL_UNIT_DEVICE_PATH ; + +#define MSG_USB_CLASS_DP 0x0F +typedef struct _USB_CLASS_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header; + UINT16 VendorId; + UINT16 ProductId; + UINT8 DeviceClass; + UINT8 DeviceSubclass; + UINT8 DeviceProtocol; +} USB_CLASS_DEVICE_PATH; + +#define MSG_I2O_DP 0x06 +typedef struct _I2O_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header; + UINT32 Tid; +} I2O_DEVICE_PATH; + +#define MSG_MAC_ADDR_DP 0x0b +typedef struct _MAC_ADDR_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header; + EFI_MAC_ADDRESS MacAddress; + UINT8 IfType; +} MAC_ADDR_DEVICE_PATH; + +#define MSG_IPv4_DP 0x0c +typedef struct _IPv4_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header; + EFI_IPv4_ADDRESS LocalIpAddress; + EFI_IPv4_ADDRESS RemoteIpAddress; + UINT16 LocalPort; + UINT16 RemotePort; + UINT16 Protocol; + BOOLEAN StaticIpAddress; + /* new from UEFI version 2, code must check Length field in Header */ + EFI_IPv4_ADDRESS GatewayIpAddress ; + EFI_IPv4_ADDRESS SubnetMask ; +} IPv4_DEVICE_PATH; + +#define MSG_IPv6_DP 0x0d +typedef struct _IPv6_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header; + EFI_IPv6_ADDRESS LocalIpAddress; + EFI_IPv6_ADDRESS RemoteIpAddress; + UINT16 LocalPort; + UINT16 RemotePort; + UINT16 Protocol; + BOOLEAN IPAddressOrigin ; + /* new from UEFI version 2, code must check Length field in Header */ + UINT8 PrefixLength ; + EFI_IPv6_ADDRESS GatewayIpAddress ; +} IPv6_DEVICE_PATH; + + +/** + * Uniform Resource Identifiers SubType. + * UEFI 2.0 specification version 2.4C § 9.3.5.23. + */ +#define MSG_URI_DP 24 +typedef struct _URI_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header; + CHAR8 Uri[1]; +} URI_DEVICE_PATH; + +/** + * Device Logical Unit SubType. + * UEFI 2.0 specification version 2.4 § 9.3.5.8. + */ +#define MSG_VLAN_DP 20 +typedef struct _VLAN_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header ; + UINT16 VlanId ; +} VLAN_DEVICE_PATH; + +#define MSG_INFINIBAND_DP 0x09 +typedef struct _INFINIBAND_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header; + UINT32 ResourceFlags; + UINT8 PortGid[16]; + UINT64 ServiceId; + UINT64 TargetPortId; + UINT64 DeviceId; +} INFINIBAND_DEVICE_PATH; + +#define MSG_UART_DP 0x0e +typedef struct _UART_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header; + UINT32 Reserved; + UINT64 BaudRate; + UINT8 DataBits; + UINT8 Parity; + UINT8 StopBits; +} UART_DEVICE_PATH; + +#define MSG_VENDOR_DP 0x0A +/* Use VENDOR_DEVICE_PATH struct */ + +#define EFI_PC_ANSI_GUID \ + { 0xe0c14753, 0xf9be, 0x11d2, {0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } +#define DEVICE_PATH_MESSAGING_PC_ANSI EFI_PC_ANSI_GUID + +#define EFI_VT_100_GUID \ + { 0xdfa66065, 0xb419, 0x11d3, {0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } +#define DEVICE_PATH_MESSAGING_VT_100 EFI_VT_100_GUID + +#define EFI_VT_100_PLUS_GUID \ + { 0x7baec70b, 0x57e0, 0x4c76, {0x8e, 0x87, 0x2f, 0x9e, 0x28, 0x08, 0x83, 0x43} } +#define DEVICE_PATH_MESSAGING_VT_100_PLUS EFI_VT_100_PLUS_GUID + +#define EFI_VT_UTF8_GUID \ + { 0xad15a0d6, 0x8bec, 0x4acf, {0xa0, 0x73, 0xd0, 0x1d, 0xe7, 0x7e, 0x2d, 0x88} } +#define DEVICE_PATH_MESSAGING_VT_UTF8 EFI_VT_UTF8_GUID + + +/* + * Media Device Path (UEFI 2.4 specification, version 2.4 § 9.3.6.) + */ +#define MEDIA_DEVICE_PATH 0x04 + +#define MEDIA_HARDDRIVE_DP 0x01 +typedef struct _HARDDRIVE_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header; + UINT32 PartitionNumber; + UINT64 PartitionStart; + UINT64 PartitionSize; + UINT8 Signature[16]; + UINT8 MBRType; + UINT8 SignatureType; +} HARDDRIVE_DEVICE_PATH; + +#define MBR_TYPE_PCAT 0x01 +#define MBR_TYPE_EFI_PARTITION_TABLE_HEADER 0x02 + +#define SIGNATURE_TYPE_MBR 0x01 +#define SIGNATURE_TYPE_GUID 0x02 + +#define MEDIA_CDROM_DP 0x02 +typedef struct _CDROM_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header; + UINT32 BootEntry; + UINT64 PartitionStart; + UINT64 PartitionSize; +} CDROM_DEVICE_PATH; + +#define MEDIA_VENDOR_DP 0x03 +/* Use VENDOR_DEVICE_PATH struct */ + +#define MEDIA_FILEPATH_DP 0x04 +typedef struct _FILEPATH_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header; + CHAR16 PathName[1]; +} FILEPATH_DEVICE_PATH; + +#define SIZE_OF_FILEPATH_DEVICE_PATH EFI_FIELD_OFFSET(FILEPATH_DEVICE_PATH,PathName) + +#define MEDIA_PROTOCOL_DP 0x05 +typedef struct _MEDIA_PROTOCOL_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header; + EFI_GUID Protocol; +} MEDIA_PROTOCOL_DEVICE_PATH; + +/** + * PIWG Firmware File SubType. + * UEFI 2.0 specification version 2.4 § 9.3.6.6. + */ +#define MEDIA_PIWG_FW_FILE_DP 6 +typedef struct _MEDIA_FW_VOL_FILEPATH_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header ; + EFI_GUID FvFileName ; +} MEDIA_FW_VOL_FILEPATH_DEVICE_PATH ; + +/** + * PIWG Firmware Volume Device Path SubType. + * UEFI 2.0 specification version 2.4 § 9.3.6.7. + */ +#define MEDIA_PIWG_FW_VOL_DP 7 +typedef struct _MEDIA_FW_VOL_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header ; + EFI_GUID FvName ; +} MEDIA_FW_VOL_DEVICE_PATH ; + +/** + * Media relative offset range device path. + * UEFI 2.0 specification version 2.4 § 9.3.6.8. + */ +#define MEDIA_RELATIVE_OFFSET_RANGE_DP 8 +typedef struct _MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header ; + UINT32 Reserved ; + UINT64 StartingOffset ; + UINT64 EndingOffset ; +} MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH ; + + +/* + * BIOS Boot Specification Device Path (UEFI 2.4 specification, version 2.4 § 9.3.7.) + */ +#define BBS_DEVICE_PATH 0x05 + +#define BBS_BBS_DP 0x01 +typedef struct _BBS_BBS_DEVICE_PATH { + EFI_DEVICE_PATH_PROTOCOL Header; + UINT16 DeviceType; + UINT16 StatusFlag; + CHAR8 String[1]; +} BBS_BBS_DEVICE_PATH; + +/* DeviceType definitions - from BBS specification */ +#define BBS_TYPE_FLOPPY 0x01 +#define BBS_TYPE_HARDDRIVE 0x02 +#define BBS_TYPE_CDROM 0x03 +#define BBS_TYPE_PCMCIA 0x04 +#define BBS_TYPE_USB 0x05 +#define BBS_TYPE_EMBEDDED_NETWORK 0x06 +#define BBS_TYPE_DEV 0x80 +#define BBS_TYPE_UNKNOWN 0xFF + +typedef union { + EFI_DEVICE_PATH_PROTOCOL DevPath; + PCI_DEVICE_PATH Pci; + PCCARD_DEVICE_PATH PcCard; + MEMMAP_DEVICE_PATH MemMap; + VENDOR_DEVICE_PATH Vendor; + UNKNOWN_DEVICE_VENDOR_DEVICE_PATH UnknownVendor; + CONTROLLER_DEVICE_PATH Controller; + ACPI_HID_DEVICE_PATH Acpi; + + ATAPI_DEVICE_PATH Atapi; + SCSI_DEVICE_PATH Scsi; + FIBRECHANNEL_DEVICE_PATH FibreChannel; + + F1394_DEVICE_PATH F1394; + USB_DEVICE_PATH Usb; + USB_CLASS_DEVICE_PATH UsbClass; + I2O_DEVICE_PATH I2O; + MAC_ADDR_DEVICE_PATH MacAddr; + IPv4_DEVICE_PATH Ipv4; + IPv6_DEVICE_PATH Ipv6; + URI_DEVICE_PATH Uri; + INFINIBAND_DEVICE_PATH InfiniBand; + UART_DEVICE_PATH Uart; + + HARDDRIVE_DEVICE_PATH HardDrive; + CDROM_DEVICE_PATH CD; + + FILEPATH_DEVICE_PATH FilePath; + MEDIA_PROTOCOL_DEVICE_PATH MediaProtocol; + + BBS_BBS_DEVICE_PATH Bbs; + +} EFI_DEV_PATH; + +typedef union { + EFI_DEVICE_PATH_PROTOCOL *DevPath; + PCI_DEVICE_PATH *Pci; + PCCARD_DEVICE_PATH *PcCard; + MEMMAP_DEVICE_PATH *MemMap; + VENDOR_DEVICE_PATH *Vendor; + UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *UnknownVendor; + CONTROLLER_DEVICE_PATH *Controller; + ACPI_HID_DEVICE_PATH *Acpi; + + ATAPI_DEVICE_PATH *Atapi; + SCSI_DEVICE_PATH *Scsi; + FIBRECHANNEL_DEVICE_PATH *FibreChannel; + + F1394_DEVICE_PATH *F1394; + USB_DEVICE_PATH *Usb; + USB_CLASS_DEVICE_PATH *UsbClass; + I2O_DEVICE_PATH *I2O; + MAC_ADDR_DEVICE_PATH *MacAddr; + IPv4_DEVICE_PATH *Ipv4; + IPv6_DEVICE_PATH *Ipv6; + URI_DEVICE_PATH *Uri; + INFINIBAND_DEVICE_PATH *InfiniBand; + UART_DEVICE_PATH *Uart; + + HARDDRIVE_DEVICE_PATH *HardDrive; + + FILEPATH_DEVICE_PATH *FilePath; + MEDIA_PROTOCOL_DEVICE_PATH *MediaProtocol; + + CDROM_DEVICE_PATH *CD; + BBS_BBS_DEVICE_PATH *Bbs; + +} EFI_DEV_PATH_PTR; + +#define EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID \ + { 0x8b843e20, 0x8132, 0x4852, {0x90, 0xcc, 0x55, 0x1a, 0x4e, 0x4a, 0x7f, 0x1c} } + +typedef +CHAR16* +(EFIAPI *EFI_DEVICE_PATH_TO_TEXT_NODE) ( + IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode, + IN BOOLEAN DisplayOnly, + IN BOOLEAN AllowShortcuts + ); + +typedef +CHAR16* +(EFIAPI *EFI_DEVICE_PATH_TO_TEXT_PATH) ( + IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN BOOLEAN DisplayOnly, + IN BOOLEAN AllowShortcuts + ); + +typedef struct _EFI_DEVICE_PATH_TO_TEXT_PROTOCOL { + EFI_DEVICE_PATH_TO_TEXT_NODE ConvertDeviceNodeToText; + EFI_DEVICE_PATH_TO_TEXT_PATH ConvertDevicePathToText; +} EFI_DEVICE_PATH_TO_TEXT_PROTOCOL; + +#define EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID \ + { 0x5c99a21, 0xc70f, 0x4ad2, {0x8a, 0x5f, 0x35, 0xdf, 0x33, 0x43, 0xf5, 0x1e} } + +typedef +EFI_DEVICE_PATH_PROTOCOL* +(EFIAPI *EFI_DEVICE_PATH_FROM_TEXT_NODE) ( + IN CONST CHAR16 *TextDeviceNode + ); + +typedef +EFI_DEVICE_PATH_PROTOCOL* +(EFIAPI *EFI_DEVICE_PATH_FROM_TEXT_PATH) ( + IN CONST CHAR16 *TextDevicePath + ); + +typedef struct { + EFI_DEVICE_PATH_FROM_TEXT_NODE ConvertTextToDeviceNode; + EFI_DEVICE_PATH_FROM_TEXT_PATH ConvertTextToDevicePath; +} EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL; + +#define EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID \ + { 0x379be4e, 0xd706, 0x437d, {0xb0, 0x37, 0xed, 0xb8, 0x2f, 0xb7, 0x72, 0xa4} } + +typedef +UINTN +(EFIAPI *EFI_DEVICE_PATH_UTILS_GET_DEVICE_PATH_SIZE) ( + IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath + ); + +typedef +EFI_DEVICE_PATH_PROTOCOL* +(EFIAPI *EFI_DEVICE_PATH_UTILS_DUP_DEVICE_PATH) ( + IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath + ); + +typedef +EFI_DEVICE_PATH_PROTOCOL* +(EFIAPI *EFI_DEVICE_PATH_UTILS_APPEND_PATH) ( + IN CONST EFI_DEVICE_PATH_PROTOCOL *Src1, + IN CONST EFI_DEVICE_PATH_PROTOCOL *Src2 + ); + +typedef +EFI_DEVICE_PATH_PROTOCOL* +(EFIAPI *EFI_DEVICE_PATH_UTILS_APPEND_NODE) ( + IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode +); + +typedef +EFI_DEVICE_PATH_PROTOCOL* +(EFIAPI *EFI_DEVICE_PATH_UTILS_APPEND_INSTANCE) ( + IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance +); + +typedef +EFI_DEVICE_PATH_PROTOCOL* +(EFIAPI *EFI_DEVICE_PATH_UTILS_GET_NEXT_INSTANCE) ( + IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathInstance, + OUT UINTN *DevicePathInstanceSize OPTIONAL +); + +typedef +EFI_DEVICE_PATH_PROTOCOL* +(EFIAPI *EFI_DEVICE_PATH_UTILS_CREATE_NODE) ( + IN UINT8 NodeType, + IN UINT8 NodeSubType, + IN UINT16 NodeLength + ); + +typedef +BOOLEAN +(EFIAPI *EFI_DEVICE_PATH_UTILS_IS_MULTI_INSTANCE) ( + IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath + ); + +typedef struct _EFI_DEVICE_PATH_UTILITIES_PROTOCOL { + EFI_DEVICE_PATH_UTILS_GET_DEVICE_PATH_SIZE GetDevicePathSize; + EFI_DEVICE_PATH_UTILS_DUP_DEVICE_PATH DuplicateDevicePath; + EFI_DEVICE_PATH_UTILS_APPEND_PATH AppendDevicePath; + EFI_DEVICE_PATH_UTILS_APPEND_NODE AppendDeviceNode; + EFI_DEVICE_PATH_UTILS_APPEND_INSTANCE AppendDevicePathInstance; + EFI_DEVICE_PATH_UTILS_GET_NEXT_INSTANCE GetNextDevicePathInstance; + EFI_DEVICE_PATH_UTILS_IS_MULTI_INSTANCE IsDevicePathMultiInstance; + EFI_DEVICE_PATH_UTILS_CREATE_NODE CreateDeviceNode; +} EFI_DEVICE_PATH_UTILITIES_PROTOCOL; + +#endif diff --git a/include/efierr.h b/include/efierr.h new file mode 100644 index 0000000..35b3950 --- /dev/null +++ b/include/efierr.h @@ -0,0 +1,73 @@ +#ifndef _EFI_ERR_H +#define _EFI_ERR_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efierr.h + +Abstract: + + EFI error codes + + + + +Revision History + +--*/ + + +#define EFIWARN(a) (a) +#define EFI_ERROR(a) (((INTN) a) < 0) + + +#define EFI_SUCCESS 0 +#define EFI_LOAD_ERROR EFIERR(1) +#define EFI_INVALID_PARAMETER EFIERR(2) +#define EFI_UNSUPPORTED EFIERR(3) +#define EFI_BAD_BUFFER_SIZE EFIERR(4) +#define EFI_BUFFER_TOO_SMALL EFIERR(5) +#define EFI_NOT_READY EFIERR(6) +#define EFI_DEVICE_ERROR EFIERR(7) +#define EFI_WRITE_PROTECTED EFIERR(8) +#define EFI_OUT_OF_RESOURCES EFIERR(9) +#define EFI_VOLUME_CORRUPTED EFIERR(10) +#define EFI_VOLUME_FULL EFIERR(11) +#define EFI_NO_MEDIA EFIERR(12) +#define EFI_MEDIA_CHANGED EFIERR(13) +#define EFI_NOT_FOUND EFIERR(14) +#define EFI_ACCESS_DENIED EFIERR(15) +#define EFI_NO_RESPONSE EFIERR(16) +#define EFI_NO_MAPPING EFIERR(17) +#define EFI_TIMEOUT EFIERR(18) +#define EFI_NOT_STARTED EFIERR(19) +#define EFI_ALREADY_STARTED EFIERR(20) +#define EFI_ABORTED EFIERR(21) +#define EFI_ICMP_ERROR EFIERR(22) +#define EFI_TFTP_ERROR EFIERR(23) +#define EFI_PROTOCOL_ERROR EFIERR(24) +#define EFI_INCOMPATIBLE_VERSION EFIERR(25) +#define EFI_SECURITY_VIOLATION EFIERR(26) +#define EFI_CRC_ERROR EFIERR(27) +#define EFI_END_OF_MEDIA EFIERR(28) +#define EFI_END_OF_FILE EFIERR(31) +#define EFI_INVALID_LANGUAGE EFIERR(32) +#define EFI_COMPROMISED_DATA EFIERR(33) +#define EFI_IP_ADDRESS_CONFLICT EFIERR(34) +#define EFI_HTTP_ERROR EFIERR(35) + +#define EFI_WARN_UNKOWN_GLYPH EFIWARN(1) +#define EFI_WARN_UNKNOWN_GLYPH EFIWARN(1) +#define EFI_WARN_DELETE_FAILURE EFIWARN(2) +#define EFI_WARN_WRITE_FAILURE EFIWARN(3) +#define EFI_WARN_BUFFER_TOO_SMALL EFIWARN(4) +#define EFI_WARN_STALE_DATA EFIWARN(5) +#define EFI_WARN_FILE_SYSTEM EFIWARN(6) +#define EFI_WARN_RESET_REQUIRED EFIWARN(7) + +#endif + diff --git a/include/efifs.h b/include/efifs.h new file mode 100644 index 0000000..48e6cd0 --- /dev/null +++ b/include/efifs.h @@ -0,0 +1,116 @@ +#ifndef _EFI_FS_H +#define _EFI_FS_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efifs.h + +Abstract: + + EFI File System structures + + + +Revision History + +--*/ + + +// +// EFI Partition header (normaly starts in LBA 1) +// + +#define EFI_PARTITION_SIGNATURE 0x5053595320494249 +#define EFI_PARTITION_REVISION 0x00010001 +#define MIN_EFI_PARTITION_BLOCK_SIZE 512 +#define EFI_PARTITION_LBA 1 + +typedef struct _EFI_PARTITION_HEADER { + EFI_TABLE_HEADER Hdr; + UINT32 DirectoryAllocationNumber; + UINT32 BlockSize; + EFI_LBA FirstUsableLba; + EFI_LBA LastUsableLba; + EFI_LBA UnusableSpace; + EFI_LBA FreeSpace; + EFI_LBA RootFile; + EFI_LBA SecutiryFile; +} EFI_PARTITION_HEADER; + + +// +// File header +// + +#define EFI_FILE_HEADER_SIGNATURE 0x454c494620494249 +#define EFI_FILE_HEADER_REVISION 0x00010000 +#define EFI_FILE_STRING_SIZE 260 + +typedef struct _EFI_FILE_HEADER { + EFI_TABLE_HEADER Hdr; + UINT32 Class; + UINT32 LBALOffset; + EFI_LBA Parent; + UINT64 FileSize; + UINT64 FileAttributes; + EFI_TIME FileCreateTime; + EFI_TIME FileModificationTime; + EFI_GUID VendorGuid; + CHAR16 FileString[EFI_FILE_STRING_SIZE]; +} EFI_FILE_HEADER; + + +// +// Return the file's first LBAL which is in the same +// logical block as the file header +// + +#define EFI_FILE_LBAL(a) ((EFI_LBAL *) (((CHAR8 *) (a)) + (a)->LBALOffset)) + +#define EFI_FILE_CLASS_FREE_SPACE 1 +#define EFI_FILE_CLASS_EMPTY 2 +#define EFI_FILE_CLASS_NORMAL 3 + + +// +// Logical Block Address List - the fundemental block +// description structure +// + +#define EFI_LBAL_SIGNATURE 0x4c41424c20494249 +#define EFI_LBAL_REVISION 0x00010000 + +typedef struct _EFI_LBAL { + EFI_TABLE_HEADER Hdr; + UINT32 Class; + EFI_LBA Parent; + EFI_LBA Next; + UINT32 ArraySize; + UINT32 ArrayCount; +} EFI_LBAL; + +// Array size +#define EFI_LBAL_ARRAY_SIZE(lbal,offs,blks) \ + (((blks) - (offs) - (lbal)->Hdr.HeaderSize) / sizeof(EFI_RL)) + +// +// Logical Block run-length +// + +typedef struct { + EFI_LBA Start; + UINT64 Length; +} EFI_RL; + +// +// Return the run-length structure from an LBAL header +// + +#define EFI_LBAL_RL(a) ((EFI_RL*) (((CHAR8 *) (a)) + (a)->Hdr.HeaderSize)) + +#endif + diff --git a/include/efigpt.h b/include/efigpt.h new file mode 100644 index 0000000..31e13e0 --- /dev/null +++ b/include/efigpt.h @@ -0,0 +1,68 @@ +#ifndef _EFI_GPT_H +#define _EFI_GPT_H +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + EfiGpt.h + +Abstract: + Include file for EFI partitioning scheme + + + +Revision History + +--*/ + +#define PRIMARY_PART_HEADER_LBA 1 + +typedef struct { + EFI_TABLE_HEADER Header; + EFI_LBA MyLBA; + EFI_LBA AlternateLBA; + EFI_LBA FirstUsableLBA; + EFI_LBA LastUsableLBA; + EFI_GUID DiskGUID; + EFI_LBA PartitionEntryLBA; + UINT32 NumberOfPartitionEntries; + UINT32 SizeOfPartitionEntry; + UINT32 PartitionEntryArrayCRC32; +} EFI_PARTITION_TABLE_HEADER; + +#define EFI_PTAB_HEADER_ID "EFI PART" + +typedef struct { + EFI_GUID PartitionTypeGUID; + EFI_GUID UniquePartitionGUID; + EFI_LBA StartingLBA; + EFI_LBA EndingLBA; + UINT64 Attributes; + CHAR16 PartitionName[36]; +} EFI_PARTITION_ENTRY; + +// +// EFI Partition Attributes +// +#define EFI_PART_USED_BY_EFI 0x0000000000000001 +#define EFI_PART_REQUIRED_TO_FUNCTION 0x0000000000000002 +#define EFI_PART_USED_BY_OS 0x0000000000000004 +#define EFI_PART_REQUIRED_BY_OS 0x0000000000000008 +#define EFI_PART_BACKUP_REQUIRED 0x0000000000000010 +#define EFI_PART_USER_DATA 0x0000000000000020 +#define EFI_PART_CRITICAL_USER_DATA 0x0000000000000040 +#define EFI_PART_REDUNDANT_PARTITION 0x0000000000000080 + +#define EFI_PART_TYPE_UNUSED_GUID \ + { 0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} } + +#define EFI_PART_TYPE_EFI_SYSTEM_PART_GUID \ + { 0xc12a7328, 0xf81f, 0x11d2, {0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b} } + +#define EFI_PART_TYPE_LEGACY_MBR_GUID \ + { 0x024dee41, 0x33e7, 0x11d3, {0x9d, 0x69, 0x00, 0x08, 0xc7, 0x81, 0xf3, 0x9f} } + +#endif + diff --git a/include/efiip.h b/include/efiip.h new file mode 100644 index 0000000..9e33f9b --- /dev/null +++ b/include/efiip.h @@ -0,0 +1,459 @@ +#ifndef _EFI_IP_H +#define _EFI_IP_H + +/*++ +Copyright (c) 2013 Intel Corporation + +--*/ + +#define EFI_IP4_SERVICE_BINDING_PROTOCOL \ + {0xc51711e7,0xb4bf,0x404a,{0xbf,0xb8,0x0a,0x04, 0x8e,0xf1,0xff,0xe4}} + +#define EFI_IP4_PROTOCOL \ + {0x41d94cd2,0x35b6,0x455a,{0x82,0x58,0xd4,0xe5,0x13,0x34,0xaa,0xdd}} + +#define EFI_IP6_SERVICE_BINDING_PROTOCOL \ + {0xec835dd3,0xfe0f,0x617b,{0xa6,0x21,0xb3,0x50,0xc3,0xe1,0x33,0x88}} + +#define EFI_IP6_PROTOCOL \ + {0x2c8759d5,0x5c2d,0x66ef,{0x92,0x5f,0xb6,0x6c,0x10,0x19,0x57,0xe2}} + +INTERFACE_DECL(_EFI_IP4); +INTERFACE_DECL(_EFI_IP6); + +typedef struct { + EFI_HANDLE InstanceHandle; + EFI_IPv4_ADDRESS Ip4Address; + EFI_IPv4_ADDRESS SubnetMask; +} EFI_IP4_ADDRESS_PAIR; + +typedef struct { + EFI_HANDLE DriverHandle; + UINT32 AddressCount; + EFI_IP4_ADDRESS_PAIR AddressPairs[1]; +} EFI_IP4_VARIABLE_DATA; + +typedef struct { + UINT8 DefaultProtocol; + BOOLEAN AcceptAnyProtocol; + BOOLEAN AcceptIcmpErrors; + BOOLEAN AcceptBroadcast; + BOOLEAN AcceptPromiscuous; + BOOLEAN UseDefaultAddress; + EFI_IPv4_ADDRESS StationAddress; + EFI_IPv4_ADDRESS SubnetMask; + UINT8 TypeOfService; + UINT8 TimeToLive; + BOOLEAN DoNotFragment; + BOOLEAN RawData; + UINT32 ReceiveTimeout; + UINT32 TransmitTimeout; +} EFI_IP4_CONFIG_DATA; + +typedef struct { + EFI_IPv4_ADDRESS SubnetAddress; + EFI_IPv4_ADDRESS SubnetMask; + EFI_IPv4_ADDRESS GatewayAddress; +} EFI_IP4_ROUTE_TABLE; + +typedef struct { + UINT8 Type; + UINT8 Code; +} EFI_IP4_ICMP_TYPE; + +typedef struct { + BOOLEAN IsStarted; + UINT32 MaxPacketSize; + EFI_IP4_CONFIG_DATA ConfigData; + BOOLEAN IsConfigured; + UINT32 GroupCount; + EFI_IPv4_ADDRESS *GroupTable; + UINT32 RouteCount; + EFI_IP4_ROUTE_TABLE *RouteTable; + UINT32 IcmpTypeCount; + EFI_IP4_ICMP_TYPE *IcmpTypeList; +} EFI_IP4_MODE_DATA; + +typedef +EFI_STATUS +(EFIAPI *EFI_IP4_GET_MODE_DATA) ( + IN struct _EFI_IP4 *This, + OUT EFI_IP4_MODE_DATA *Ip4ModeData OPTIONAL, + OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL, + OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IP4_CONFIGURE) ( + IN struct _EFI_IP4 *This, + IN EFI_IP4_CONFIG_DATA *IpConfigData OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IP4_GROUPS) ( + IN struct _EFI_IP4 *This, + IN BOOLEAN JoinFlag, + IN EFI_IPv4_ADDRESS *GroupAddress OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IP4_ROUTES) ( + IN struct _EFI_IP4 *This, + IN BOOLEAN DeleteRoute, + IN EFI_IPv4_ADDRESS *SubnetAddress, + IN EFI_IPv4_ADDRESS *SubnetMask, + IN EFI_IPv4_ADDRESS *GatewayAddress + ); + +#pragma pack(1) +typedef struct { + UINT8 HeaderLength:4; + UINT8 Version:4; + UINT8 TypeOfService; + UINT16 TotalLength; + UINT16 Identification; + UINT16 Fragmentation; + UINT8 TimeToLive; + UINT8 Protocol; + UINT16 Checksum; + EFI_IPv4_ADDRESS SourceAddress; + EFI_IPv4_ADDRESS DestinationAddress; +} EFI_IP4_HEADER; +#pragma pack() + +typedef struct { + UINT32 FragmentLength; + VOID *FragmentBuffer; +} EFI_IP4_FRAGMENT_DATA; + +typedef struct { + EFI_TIME TimeStamp; + EFI_EVENT RecycleSignal; + UINT32 HeaderLength; + EFI_IP4_HEADER *Header; + UINT32 OptionsLength; + VOID *Options; + UINT32 DataLength; + UINT32 FragmentCount; + EFI_IP4_FRAGMENT_DATA FragmentTable[1]; +} EFI_IP4_RECEIVE_DATA; + +typedef struct { + EFI_IPv4_ADDRESS SourceAddress; + EFI_IPv4_ADDRESS GatewayAddress; + UINT8 Protocol; + UINT8 TypeOfService; + UINT8 TimeToLive; + BOOLEAN DoNotFragment; +} EFI_IP4_OVERRIDE_DATA; + +typedef struct { + EFI_IPv4_ADDRESS DestinationAddress; + EFI_IP4_OVERRIDE_DATA *OverrideData; + UINT32 OptionsLength; + VOID *OptionsBuffer; + UINT32 TotalDataLength; + UINT32 FragmentCount; + EFI_IP4_FRAGMENT_DATA FragmentTable[1]; +} EFI_IP4_TRANSMIT_DATA; + +typedef struct { + EFI_EVENT Event; + EFI_STATUS Status; + union { + EFI_IP4_RECEIVE_DATA *RxData; + EFI_IP4_TRANSMIT_DATA *TxData; + } Packet; +} EFI_IP4_COMPLETION_TOKEN; + +typedef +EFI_STATUS +(EFIAPI *EFI_IP4_TRANSMIT) ( + IN struct _EFI_IP4 *This, + IN EFI_IP4_COMPLETION_TOKEN *Token + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IP4_RECEIVE) ( + IN struct _EFI_IP4 *This, + IN EFI_IP4_COMPLETION_TOKEN *Token + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IP4_CANCEL)( + IN struct _EFI_IP4 *This, + IN EFI_IP4_COMPLETION_TOKEN *Token OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IP4_POLL) ( + IN struct _EFI_IP4 *This + ); + +typedef struct _EFI_IP4 { + EFI_IP4_GET_MODE_DATA GetModeData; + EFI_IP4_CONFIGURE Configure; + EFI_IP4_GROUPS Groups; + EFI_IP4_ROUTES Routes; + EFI_IP4_TRANSMIT Transmit; + EFI_IP4_RECEIVE Receive; + EFI_IP4_CANCEL Cancel; + EFI_IP4_POLL Poll; +} EFI_IP4; + +typedef struct { + UINT8 DefaultProtocol; + BOOLEAN AcceptAnyProtocol; + BOOLEAN AcceptIcmpErrors; + BOOLEAN AcceptPromiscuous; + EFI_IPv6_ADDRESS DestinationAddress; + EFI_IPv6_ADDRESS StationAddress; + UINT8 TrafficClass; + UINT8 HopLimit; + UINT32 FlowLabel; + UINT32 ReceiveTimeout; + UINT32 TransmitTimeout; +} EFI_IP6_CONFIG_DATA; + +typedef struct { + EFI_IPv6_ADDRESS Address; + UINT8 PrefixLength; +} EFI_IP6_ADDRESS_INFO; + +typedef struct { + EFI_IPv6_ADDRESS Gateway; + EFI_IPv6_ADDRESS Destination; + UINT8 PrefixLength; +} EFI_IP6_ROUTE_TABLE; + +typedef enum { + EfiNeighborInComplete, + EfiNeighborReachable, + EfiNeighborStale, + EfiNeighborDelay, + EfiNeighborProbe +} EFI_IP6_NEIGHBOR_STATE; + +typedef struct { + EFI_IPv6_ADDRESS Neighbor; + EFI_MAC_ADDRESS LinkAddress; + EFI_IP6_NEIGHBOR_STATE State; +} EFI_IP6_NEIGHBOR_CACHE; + +typedef struct { + UINT8 Type; + UINT8 Code; +} EFI_IP6_ICMP_TYPE; + +//*********************************************************** +// ICMPv6 type definitions for error messages +//*********************************************************** +#define ICMP_V6_DEST_UNREACHABLE 0x1 +#define ICMP_V6_PACKET_TOO_BIG 0x2 +#define ICMP_V6_TIME_EXCEEDED 0x3 +#define ICMP_V6_PARAMETER_PROBLEM 0x4 + +//*********************************************************** +// ICMPv6 type definition for informational messages +//*********************************************************** +#define ICMP_V6_ECHO_REQUEST 0x80 +#define ICMP_V6_ECHO_REPLY 0x81 +#define ICMP_V6_LISTENER_QUERY 0x82 +#define ICMP_V6_LISTENER_REPORT 0x83 +#define ICMP_V6_LISTENER_DONE 0x84 +#define ICMP_V6_ROUTER_SOLICIT 0x85 +#define ICMP_V6_ROUTER_ADVERTISE 0x86 +#define ICMP_V6_NEIGHBOR_SOLICIT 0x87 +#define ICMP_V6_NEIGHBOR_ADVERTISE 0x88 +#define ICMP_V6_REDIRECT 0x89 +#define ICMP_V6_LISTENER_REPORT_2 0x8F + +//*********************************************************** +// ICMPv6 code definitions for ICMP_V6_DEST_UNREACHABLE +//*********************************************************** +#define ICMP_V6_NO_ROUTE_TO_DEST 0x0 +#define ICMP_V6_COMM_PROHIBITED 0x1 +#define ICMP_V6_BEYOND_SCOPE 0x2 +#define ICMP_V6_ADDR_UNREACHABLE 0x3 +#define ICMP_V6_PORT_UNREACHABLE 0x4 +#define ICMP_V6_SOURCE_ADDR_FAILED 0x5 +#define ICMP_V6_ROUTE_REJECTED 0x6 + +//*********************************************************** +// ICMPv6 code definitions for ICMP_V6_TIME_EXCEEDED +//*********************************************************** +#define ICMP_V6_TIMEOUT_HOP_LIMIT 0x0 +#define ICMP_V6_TIMEOUT_REASSEMBLE 0x1 + +//*********************************************************** +// ICMPv6 code definitions for ICMP_V6_PARAMETER_PROBLEM +//*********************************************************** +#define ICMP_V6_ERRONEOUS_HEADER 0x0 +#define ICMP_V6_UNRECOGNIZE_NEXT_HDR 0x1 +#define ICMP_V6_UNRECOGNIZE_OPTION 0x2 + +typedef struct { + BOOLEAN IsStarted; + UINT32 MaxPacketSize; + EFI_IP6_CONFIG_DATA ConfigData; + BOOLEAN IsConfigured; + UINT32 AddressCount; + EFI_IP6_ADDRESS_INFO *AddressList; + UINT32 GroupCount; + EFI_IPv6_ADDRESS *GroupTable; + UINT32 RouteCount; + EFI_IP6_ROUTE_TABLE *RouteTable; + UINT32 NeighborCount; + EFI_IP6_NEIGHBOR_CACHE *NeighborCache; + UINT32 PrefixCount; + EFI_IP6_ADDRESS_INFO *PrefixTable; + UINT32 IcmpTypeCount; + EFI_IP6_ICMP_TYPE *IcmpTypeList; +} EFI_IP6_MODE_DATA; + +typedef +EFI_STATUS +(EFIAPI *EFI_IP6_GET_MODE_DATA) ( + IN struct _EFI_IP6 *This, + OUT EFI_IP6_MODE_DATA *Ip6ModeData OPTIONAL, + OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL, + OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IP6_CONFIGURE) ( + IN struct _EFI_IP6 *This, + IN EFI_IP6_CONFIG_DATA *Ip6ConfigData OPTIONAL + ); +typedef +EFI_STATUS +(EFIAPI *EFI_IP6_GROUPS) ( + IN struct _EFI_IP6 *This, + IN BOOLEAN JoinFlag, + IN EFI_IPv6_ADDRESS *GroupAddress OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IP6_ROUTES) ( + IN struct _EFI_IP6 *This, + IN BOOLEAN DeleteRoute, + IN EFI_IPv6_ADDRESS *Destination OPTIONAL, + IN UINT8 PrefixLength, + IN EFI_IPv6_ADDRESS *GatewayAddress OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IP6_NEIGHBORS) ( + IN struct _EFI_IP6 *This, + IN BOOLEAN DeleteFlag, + IN EFI_IPv6_ADDRESS *TargetIp6Address, + IN EFI_MAC_ADDRESS *TargetLinkAddress OPTIONAL, + IN UINT32 Timeout, + IN BOOLEAN Override + ); + +typedef struct _EFI_IP6_FRAGMENT_DATA { + UINT32 FragmentLength; + VOID *FragmentBuffer; +} EFI_IP6_FRAGMENT_DATA; + +typedef struct _EFI_IP6_OVERRIDE_DATA { + UINT8 Protocol; + UINT8 HopLimit; + UINT32 FlowLabel; +} EFI_IP6_OVERRIDE_DATA; + +typedef struct _EFI_IP6_TRANSMIT_DATA { + EFI_IPv6_ADDRESS DestinationAddress; + EFI_IP6_OVERRIDE_DATA *OverrideData; + UINT32 ExtHdrsLength; + VOID *ExtHdrs; + UINT8 NextHeader; + UINT32 DataLength; + UINT32 FragmentCount; + EFI_IP6_FRAGMENT_DATA FragmentTable[1]; +} EFI_IP6_TRANSMIT_DATA; + +#pragma pack(1) +typedef struct _EFI_IP6_HEADER { + UINT8 TrafficClassH:4; + UINT8 Version:4; + UINT8 FlowLabelH:4; + UINT8 TrafficClassL:4; + UINT16 FlowLabelL; + UINT16 PayloadLength; + UINT8 NextHeader; + UINT8 HopLimit; + EFI_IPv6_ADDRESS SourceAddress; + EFI_IPv6_ADDRESS DestinationAddress; +} EFI_IP6_HEADER; +#pragma pack() + +typedef struct _EFI_IP6_RECEIVE_DATA { + EFI_TIME TimeStamp; + EFI_EVENT RecycleSignal; + UINT32 HeaderLength; + EFI_IP6_HEADER *Header; + UINT32 DataLength; + UINT32 FragmentCount; + EFI_IP6_FRAGMENT_DATA FragmentTable[1]; +} EFI_IP6_RECEIVE_DATA; + +typedef struct { + EFI_EVENT Event; + EFI_STATUS Status; + union { + EFI_IP6_RECEIVE_DATA *RxData; + EFI_IP6_TRANSMIT_DATA *TxData; + } Packet; +} EFI_IP6_COMPLETION_TOKEN; + +typedef +EFI_STATUS +(EFIAPI *EFI_IP6_TRANSMIT) ( + IN struct _EFI_IP6 *This, + IN EFI_IP6_COMPLETION_TOKEN *Token + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IP6_RECEIVE) ( + IN struct _EFI_IP6 *This, + IN EFI_IP6_COMPLETION_TOKEN *Token + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IP6_CANCEL)( + IN struct _EFI_IP6 *This, + IN EFI_IP6_COMPLETION_TOKEN *Token OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IP6_POLL) ( + IN struct _EFI_IP6 *This + ); + +typedef struct _EFI_IP6 { + EFI_IP6_GET_MODE_DATA GetModeData; + EFI_IP6_CONFIGURE Configure; + EFI_IP6_GROUPS Groups; + EFI_IP6_ROUTES Routes; + EFI_IP6_NEIGHBORS Neighbors; + EFI_IP6_TRANSMIT Transmit; + EFI_IP6_RECEIVE Receive; + EFI_IP6_CANCEL Cancel; + EFI_IP6_POLL Poll; +} EFI_IP6; + +#endif /* _EFI_IP_H */ diff --git a/include/efilib.h b/include/efilib.h new file mode 100644 index 0000000..06a159c --- /dev/null +++ b/include/efilib.h @@ -0,0 +1,1106 @@ +#ifndef _EFILIB_INCLUDE_ +#define _EFILIB_INCLUDE_ + +/*++ + +Copyright (c) 2000 Intel Corporation + +Module Name: + + efilib.h + +Abstract: + + EFI library functions + + + +Revision History + +--*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "efidebug.h" +#include "efipart.h" +#if defined(_M_X64) || defined(__x86_64__) || defined(__amd64__) +#include "x86_64/efilibplat.h" +#elif defined(_M_IX86) || defined(__i386__) +#include "ia32/efilibplat.h" +#elif defined(_M_IA64) || defined(__ia64__) +#include "ia64/efilibplat.h" +#elif defined (_M_ARM64) || defined(__aarch64__) +#include "aarch64/efilibplat.h" +#elif defined (_M_ARM) || defined(__arm__) +#include "arm/efilibplat.h" +#elif defined (_M_MIPS64) || defined(__mips64__) || defined(__mips64) +#include "mips64el/efilibplat.h" +#elif defined (__riscv) && __riscv_xlen == 64 +#include "riscv64/efilibplat.h" +#elif defined (__loongarch64) +#include "loongarch64/efilibplat.h" +#endif +#include "efilink.h" +#include "efirtlib.h" +#include "efistdarg.h" +#include "pci22.h" +#include "libsmbios.h" + +// +// Public read-only data in the EFI library +// + +extern EFI_SYSTEM_TABLE *ST; +#define gST ST +extern EFI_BOOT_SERVICES *BS; +#define gBS BS +extern EFI_RUNTIME_SERVICES *RT; +#define gRT RT + +extern EFI_GUID gEfiDevicePathProtocolGuid; +#define DevicePathProtocol gEfiDevicePathProtocolGuid +extern EFI_GUID gEfiDevicePathToTextProtocolGuid; +#define DevicePathToTextProtocol gEfiDevicePathToTextProtocolGuid +extern EFI_GUID gEfiDevicePathFromTextProtocolGuid; +#define DevicePathFromTextProtocol gEfiDevicePathFromTextProtocolGuid +extern EFI_GUID gEfiDevicePathUtilitiesProtocolGuid; +#define DevicePathUtilitiesProtocol gEfiDevicePathUtilitiesProtocolGuid +extern EFI_GUID gEfiLoadedImageProtocolGuid; +#define LoadedImageProtocol gEfiLoadedImageProtocolGuid +extern EFI_GUID gEfiSimpleTextInProtocolGuid; +#define TextInProtocol gEfiSimpleTextInProtocolGuid +extern EFI_GUID gEfiSimpleTextOutProtocolGuid; +#define TextOutProtocol gEfiSimpleTextOutProtocolGuid +extern EFI_GUID gEfiGraphicsOutputProtocolGuid; +#define GraphicsOutputProtocol gEfiGraphicsOutputProtocolGuid +extern EFI_GUID gEfiEdidDiscoveredProtocolGuid; +#define EdidDiscoveredProtocol gEfiEdidDiscoveredProtocolGuid +extern EFI_GUID gEfiEdidActiveProtocolGuid; +#define EdidActiveProtocol gEfiEdidActiveProtocolGuid +extern EFI_GUID gEfiEdidOverrideProtocolGuid; +#define EdidOverrideProtocol gEfiEdidOverrideProtocolGuid +extern EFI_GUID gEfiBlockIoProtocolGuid; +#define BlockIoProtocol gEfiBlockIoProtocolGuid +extern EFI_GUID gEfiBlockIo2ProtocolGuid; +#define BlockIo2Protocol gEfiBlockIo2ProtocolGuid +extern EFI_GUID gEfiDiskIoProtocolGuid; +#define DiskIoProtocol gEfiDiskIoProtocolGuid +extern EFI_GUID gEfiDiskIo2ProtocolGuid; +#define DiskIo2Protocol gEfiDiskIo2ProtocolGuid +extern EFI_GUID gEfiSimpleFileSystemProtocolGuid; +#define FileSystemProtocol gEfiSimpleFileSystemProtocolGuid +extern EFI_GUID gEfiLoadFileProtocolGuid; +#define LoadFileProtocol gEfiLoadFileProtocolGuid +extern EFI_GUID gEfiDeviceIoProtocolGuid; +#define DeviceIoProtocol gEfiDeviceIoProtocolGuid +extern EFI_GUID VariableStoreProtocol; +extern EFI_GUID LegacyBootProtocol; +extern EFI_GUID gEfiUnicodeCollationProtocolGuid; +#define UnicodeCollationProtocol gEfiUnicodeCollationProtocolGuid +extern EFI_GUID gEfiSerialIoProtocolGuid; +#define SerialIoProtocol gEfiSerialIoProtocolGuid +extern EFI_GUID VgaClassProtocol; +extern EFI_GUID TextOutSpliterProtocol; +extern EFI_GUID ErrorOutSpliterProtocol; +extern EFI_GUID TextInSpliterProtocol; +extern EFI_GUID gEfiSimpleNetworkProtocolGuid; +#define SimpleNetworkProtocol gEfiSimpleNetworkProtocolGuid +extern EFI_GUID gEfiPxeBaseCodeProtocolGuid; +#define PxeBaseCodeProtocol gEfiPxeBaseCodeProtocolGuid +extern EFI_GUID gEfiPxeBaseCodeCallbackProtocolGuid; +#define PxeCallbackProtocol gEfiPxeBaseCodeCallbackProtocolGuid +extern EFI_GUID gEfiNetworkInterfaceIdentifierProtocolGuid; +#define NetworkInterfaceIdentifierProtocol gEfiNetworkInterfaceIdentifierProtocolGuid +extern EFI_GUID gEFiUiInterfaceProtocolGuid; +#define UiProtocol gEFiUiInterfaceProtocolGuid +extern EFI_GUID InternalShellProtocol; +extern EFI_GUID gEfiPciIoProtocolGuid; +#define PciIoProtocol gEfiPciIoProtocolGuid +extern EFI_GUID gEfiPciRootBridgeIoProtocolGuid; +extern EFI_GUID gEfiDriverBindingProtocolGuid; +#define DriverBindingProtocol gEfiDriverBindingProtocolGuid +extern EFI_GUID gEfiComponentNameProtocolGuid; +#define ComponentNameProtocol gEfiComponentNameProtocolGuid +extern EFI_GUID gEfiComponentName2ProtocolGuid; +#define ComponentName2Protocol gEfiComponentName2ProtocolGuid +extern EFI_GUID gEfiHashProtocolGuid; +#define HashProtocol gEfiHashProtocolGuid +extern EFI_GUID gEfiPlatformDriverOverrideProtocolGuid; +#define PlatformDriverOverrideProtocol gEfiPlatformDriverOverrideProtocolGuid +extern EFI_GUID gEfiBusSpecificDriverOverrideProtocolGuid; +#define BusSpecificDriverOverrideProtocol gEfiBusSpecificDriverOverrideProtocolGuid +extern EFI_GUID gEfiDriverFamilyOverrideProtocolGuid; +#define DriverFamilyOverrideProtocol gEfiDriverFamilyOverrideProtocolGuid +extern EFI_GUID gEfiEbcProtocolGuid; + +extern EFI_GUID gEfiGlobalVariableGuid; +#define EfiGlobalVariable gEfiGlobalVariableGuid +extern EFI_GUID gEfiFileInfoGuid; +#define GenericFileInfo gEfiFileInfoGuid +extern EFI_GUID gEfiFileSystemInfoGuid; +#define FileSystemInfo gEfiFileSystemInfoGuid +extern EFI_GUID gEfiFileSystemVolumeLabelInfoIdGuid; +#define FileSystemVolumeLabelInfo gEfiFileSystemVolumeLabelInfoIdGuid +extern EFI_GUID gEfiPcAnsiGuid; +#define PcAnsiProtocol gEfiPcAnsiGuid +extern EFI_GUID gEfiVT100Guid; +#define Vt100Protocol gEfiVT100Guid +extern EFI_GUID gEfiVT100PlusGuid; +extern EFI_GUID gEfiVTUTF8Guid; + +extern EFI_GUID NullGuid; +extern EFI_GUID UnknownDevice; + +extern EFI_GUID EfiPartTypeSystemPartitionGuid; +extern EFI_GUID EfiPartTypeLegacyMbrGuid; + +extern EFI_GUID MpsTableGuid; +extern EFI_GUID AcpiTableGuid; +extern EFI_GUID gEfiSmbiosTableGuid; +#define SMBIOSTableGuid gEfiSmbiosTableGuid +extern EFI_GUID gEfiSmbios3TableGuid; +#define SMBIOS3TableGuid gEfiSmbios3TableGuid +extern EFI_GUID SalSystemTableGuid; +extern EFI_GUID EfiDtbTableGuid; + +extern EFI_GUID SimplePointerProtocol; +extern EFI_GUID AbsolutePointerProtocol; + +extern EFI_GUID gEfiDebugImageInfoTableGuid; +extern EFI_GUID gEfiDebugSupportProtocolGuid; + +extern EFI_GUID SimpleTextInputExProtocol; + +extern EFI_GUID ShellProtocolGuid; +extern EFI_GUID ShellParametersProtocolGuid; +extern EFI_GUID ShellDynamicCommandProtocolGuid; + +// +// EFI Variable strings +// +#define LOAD_OPTION_ACTIVE 0x00000001 + +#define VarLanguageCodes L"LangCodes" +#define VarLanguage L"Lang" +#define VarTimeout L"Timeout" +#define VarConsoleInp L"ConIn" +#define VarConsoleOut L"ConOut" +#define VarErrorOut L"ErrOut" +#define VarBootOption L"Boot%04x" +#define VarBootOrder L"BootOrder" +#define VarBootNext L"BootNext" +#define VarBootCurrent L"BootCurrent" +#define VarDriverOption L"Driver%04x" +#define VarDriverOrder L"DriverOrder" +#define VarConsoleInpDev L"ConInDev" +#define VarConsoleOutDev L"ConOutDev" +#define VarErrorOutDev L"ErrOutDev" + +#define LanguageCodeEnglish "eng" + +extern EFI_DEVICE_PATH RootDevicePath[]; +extern EFI_DEVICE_PATH EndDevicePath[]; +extern EFI_DEVICE_PATH EndInstanceDevicePath[]; + +// +// Other public data in the EFI library +// + +extern EFI_MEMORY_TYPE PoolAllocationType; + +// +// STATIC - Name is internal to the module +// INTERNAL - Name is internal to the component (i.e., directory) +// BOOTSERVCE - Name of a boot service function +// + +#define STATIC static +#define INTERNAL +#define BOOTSERVICE + +// +// Prototypes +// + +VOID +InitializeLib ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +VOID +InitializeUnicodeSupport ( + CHAR8 *LangCode + ); + +VOID +EFIDebugVariable ( + VOID + ); + +VOID +Exit( + IN EFI_STATUS ExitStatus, + IN UINTN ExitDataSize, + IN CHAR16 *ExitData OPTIONAL + ); + +INTN +GetShellArgcArgv( + EFI_HANDLE ImageHandle, + CHAR16 **Argv[] /* Statically allocated */ + ); + +VOID +SetCrc ( + IN OUT EFI_TABLE_HEADER *Hdr + ); + +VOID +SetCrcAltSize ( + IN UINTN Size, + IN OUT EFI_TABLE_HEADER *Hdr + ); + +BOOLEAN +CheckCrc ( + IN UINTN MaxSize, + IN OUT EFI_TABLE_HEADER *Hdr + ); + +BOOLEAN +CheckCrcAltSize ( + IN UINTN MaxSize, + IN UINTN Size, + IN OUT EFI_TABLE_HEADER *Hdr + ); + +UINT32 +CalculateCrc ( + UINT8 *pt, + UINTN Size + ); + +VOID +ZeroMem ( + IN VOID *Buffer, + IN UINTN Size + ); + +VOID EFIAPI +SetMem ( + IN VOID *Buffer, + IN UINTN Size, + IN UINT8 Value + ); + +VOID EFIAPI +CopyMem_1 ( + IN VOID *Dest, + IN VOID *Src, + IN UINTN len + ); + +VOID EFIAPI +CopyMemC ( + IN VOID *Dest, + IN CONST VOID *Src, + IN UINTN len + ); + +INTN +CompareMem ( + IN CONST VOID *Dest, + IN CONST VOID *Src, + IN UINTN len + ); + +INTN +StrCmp ( + IN CONST CHAR16 *s1, + IN CONST CHAR16 *s2 + ); + +INTN +StrnCmp ( + IN CONST CHAR16 *s1, + IN CONST CHAR16 *s2, + IN UINTN len + ); + +INTN +StriCmp ( + IN CONST CHAR16 *s1, + IN CONST CHAR16 *s2 + ); + +VOID +StrLwr ( + IN CHAR16 *Str + ); + +VOID +StrUpr ( + IN CHAR16 *Str + ); + +VOID +StrCpy ( + IN CHAR16 *Dest, + IN CONST CHAR16 *Src + ); + +VOID +StrnCpy ( + IN CHAR16 *Dest, + IN CONST CHAR16 *Src, + IN UINTN Len + ); + +CHAR16 * +StpCpy ( + IN CHAR16 *Dest, + IN CONST CHAR16 *Src + ); + +CHAR16 * +StpnCpy ( + IN CHAR16 *Dest, + IN CONST CHAR16 *Src, + IN UINTN Len + ); + +VOID +StrCat ( + IN CHAR16 *Dest, + IN CONST CHAR16 *Src + ); + +VOID +StrnCat ( + IN CHAR16 *Dest, + IN CONST CHAR16 *Src, + IN UINTN Len + ); + +UINTN +StrLen ( + IN CONST CHAR16 *s1 + ); + +UINTN +StrnLen ( + IN CONST CHAR16 *s1, + IN UINTN Len + ); + +UINTN +StrSize ( + IN CONST CHAR16 *s1 + ); + +CHAR16 * +StrDuplicate ( + IN CONST CHAR16 *Src + ); + +UINTN +AsciiStrLen ( + IN CONST CHAR8 *s1 + ); + +UINTN +AsciiStrCmp ( + IN CONST CHAR8 *s1, + IN CONST CHAR8 *s2 + ); + +UINTN +AsciiStrnCmp ( + IN CONST CHAR8 *s1, + IN CONST CHAR8 *s2, + IN UINTN len + ); + +// +// For compatibility with previous gnu-efi versions +// +#define strlena AsciiStrLen +#define strcmpa AsciiStrCmp +#define strncmpa AsciiStrnCmp + +UINTN +xtoi ( + CONST CHAR16 *str + ); + +UINTN +Atoi ( + CONST CHAR16 *str + ); + +BOOLEAN +MetaMatch ( + IN CHAR16 *String, + IN CHAR16 *Pattern + ); + +BOOLEAN +MetaiMatch ( + IN CHAR16 *String, + IN CHAR16 *Pattern + ); + +UINT64 +LShiftU64 ( + IN UINT64 Operand, + IN UINTN Count + ); + +UINT64 +RShiftU64 ( + IN UINT64 Operand, + IN UINTN Count + ); + +UINT64 +MultU64x32 ( + IN UINT64 Multiplicand, + IN UINTN Multiplier + ); + +UINT64 +DivU64x32 ( + IN UINT64 Dividend, + IN UINTN Divisor, + OUT UINTN *Remainder OPTIONAL + ); + +VOID +InitializeLock ( + IN OUT FLOCK *Lock, + IN EFI_TPL Priority + ); + +VOID +AcquireLock ( + IN FLOCK *Lock + ); + +VOID +ReleaseLock ( + IN FLOCK *Lock + ); + + +INTN +CompareGuid( + IN EFI_GUID *Guid1, + IN EFI_GUID *Guid2 + ); + +VOID * +AllocatePool ( + IN UINTN Size + ); + +VOID * +AllocateZeroPool ( + IN UINTN Size + ); + +VOID * +EFIAPI +ReallocatePool_1 ( + IN UINTN OldSize, + IN UINTN NewSize, + IN VOID *OldPool OPTIONAL +); + +VOID +FreePool ( + IN VOID *p + ); + + +VOID +Output ( + IN CHAR16 *Str + ); + +VOID +Input ( + IN CHAR16 *Prompt OPTIONAL, + OUT CHAR16 *InStr, + IN UINTN StrLen + ); + +VOID +IInput ( + IN SIMPLE_TEXT_OUTPUT_INTERFACE *ConOut, + IN SIMPLE_INPUT_INTERFACE *ConIn, + IN CHAR16 *Prompt OPTIONAL, + OUT CHAR16 *InStr, + IN UINTN StrLen + ); + +UINTN +Print ( + IN CONST CHAR16 *fmt, + ... + ); + +UINTN +VPrint ( + IN CONST CHAR16 *fmt, + va_list args + ); + +UINTN +UnicodeSPrint ( + OUT CHAR16 *Str, + IN UINTN StrSize, + IN CONST CHAR16 *fmt, + ... + ); + +UINTN +UnicodeVSPrint ( + OUT CHAR16 *Str, + IN UINTN StrSize, + IN CONST CHAR16 *fmt, + va_list args + ); + +CHAR16 * +VPoolPrint ( + IN CONST CHAR16 *fmt, + va_list args + ); + +CHAR16 * +PoolPrint ( + IN CONST CHAR16 *fmt, + ... + ); + +typedef struct { + CHAR16 *str; + UINTN len; + UINTN maxlen; +} POOL_PRINT; + +CHAR16 * +CatPrint ( + IN OUT POOL_PRINT *Str, + IN CONST CHAR16 *fmt, + ... + ); + +UINTN +PrintAt ( + IN UINTN Column, + IN UINTN Row, + IN CONST CHAR16 *fmt, + ... + ); + +UINTN +IPrint ( + IN SIMPLE_TEXT_OUTPUT_INTERFACE *Out, + IN CONST CHAR16 *fmt, + ... + ); + +UINTN +IPrintAt ( + IN SIMPLE_TEXT_OUTPUT_INTERFACE *Out, + IN UINTN Column, + IN UINTN Row, + IN CONST CHAR16 *fmt, + ... + ); + +UINTN +AsciiPrint ( + IN CONST CHAR8 *fmt, + ... + ); + +UINTN +AsciiVSPrint( + OUT CHAR8 *Str, + IN UINTN StrSize, + IN CONST CHAR8 *fmt, + va_list args +); + +// +// For compatibility with previous gnu-efi versions +// +#define SPrint UnicodeSPrint +#define VSPrint UnicodeVSPrint +#define APrint AsciiPrint + +VOID +ValueToHex ( + IN CHAR16 *Buffer, + IN UINT64 v + ); + +VOID +ValueToString ( + IN CHAR16 *Buffer, + IN BOOLEAN Comma, + IN INT64 v + ); + +VOID +FloatToString ( + IN CHAR16 *Buffer, + IN BOOLEAN Comma, + IN double v + ); + +VOID +TimeToString ( + OUT CHAR16 *Buffer, + IN EFI_TIME *Time + ); + +VOID +GuidToString ( + OUT CHAR16 *Buffer, + IN EFI_GUID *Guid + ); + +VOID +StatusToString ( + OUT CHAR16 *Buffer, + EFI_STATUS Status + ); + +VOID +DumpHex ( + IN UINTN Indent, + IN UINTN Offset, + IN UINTN DataSize, + IN VOID *UserData + ); + +BOOLEAN +GrowBuffer( + IN OUT EFI_STATUS *Status, + IN OUT VOID **Buffer, + IN UINTN BufferSize + ); + +EFI_MEMORY_DESCRIPTOR * +LibMemoryMap ( + OUT UINTN *NoEntries, + OUT UINTN *MapKey, + OUT UINTN *DescriptorSize, + OUT UINT32 *DescriptorVersion + ); + +VOID * +LibGetVariable ( + IN CHAR16 *Name, + IN EFI_GUID *VendorGuid + ); + +VOID * +LibGetVariableAndSize ( + IN CHAR16 *Name, + IN EFI_GUID *VendorGuid, + OUT UINTN *VarSize + ); + +EFI_STATUS +LibDeleteVariable ( + IN CHAR16 *VarName, + IN EFI_GUID *VarGuid + ); + +EFI_STATUS +LibSetNVVariable ( + IN CHAR16 *VarName, + IN EFI_GUID *VarGuid, + IN UINTN DataSize, + IN VOID *Data + ); + +EFI_STATUS +LibSetVariable ( + IN CHAR16 *VarName, + IN EFI_GUID *VarGuid, + IN UINTN DataSize, + IN VOID *Data + ); +EFI_STATUS +LibInsertToTailOfBootOrder ( + IN UINT16 BootOption, + IN BOOLEAN OnlyInsertIfEmpty + ); + +EFI_STATUS +LibLocateProtocol ( + IN EFI_GUID *ProtocolGuid, + OUT VOID **Interface + ); + +EFI_STATUS +LibLocateHandle ( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *NoHandles, + OUT EFI_HANDLE **Buffer + ); + +EFI_STATUS +LibLocateHandleByDiskSignature ( + IN UINT8 MBRType, + IN UINT8 SignatureType, + IN VOID *Signature, + IN OUT UINTN *NoHandles, + OUT EFI_HANDLE **Buffer + ); + +EFI_STATUS +LibInstallProtocolInterfaces ( + IN OUT EFI_HANDLE *Handle, + ... + ); + +VOID +LibUninstallProtocolInterfaces ( + IN EFI_HANDLE Handle, + ... + ); + +EFI_STATUS +LibReinstallProtocolInterfaces ( + IN OUT EFI_HANDLE *Handle, + ... + ); + +EFI_EVENT +LibCreateProtocolNotifyEvent ( + IN EFI_GUID *ProtocolGuid, + IN EFI_TPL NotifyTpl, + IN EFI_EVENT_NOTIFY NotifyFunction, + IN VOID *NotifyContext, + OUT VOID *Registration + ); + +EFI_STATUS +WaitForSingleEvent ( + IN EFI_EVENT Event, + IN UINT64 Timeout OPTIONAL + ); + +VOID +WaitForEventWithTimeout ( + IN EFI_EVENT Event, + IN UINTN Timeout, + IN UINTN Row, + IN UINTN Column, + IN CHAR16 *String, + IN EFI_INPUT_KEY TimeoutKey, + OUT EFI_INPUT_KEY *Key + ); + +EFI_FILE_HANDLE +LibOpenRoot ( + IN EFI_HANDLE DeviceHandle + ); + +EFI_FILE_INFO * +LibFileInfo ( + IN EFI_FILE_HANDLE FHand + ); + +EFI_FILE_SYSTEM_INFO * +LibFileSystemInfo ( + IN EFI_FILE_HANDLE FHand + ); + +EFI_FILE_SYSTEM_VOLUME_LABEL_INFO * +LibFileSystemVolumeLabelInfo ( + IN EFI_FILE_HANDLE FHand + ); + +BOOLEAN +ValidMBR( + IN MASTER_BOOT_RECORD *Mbr, + IN EFI_BLOCK_IO *BlkIo + ); + +BOOLEAN +LibMatchDevicePaths ( + IN EFI_DEVICE_PATH *Multi, + IN EFI_DEVICE_PATH *Single + ); + +EFI_DEVICE_PATH * +LibDuplicateDevicePathInstance ( + IN EFI_DEVICE_PATH *DevPath + ); + +EFI_DEVICE_PATH * +DevicePathFromHandle ( + IN EFI_HANDLE Handle + ); + +EFI_DEVICE_PATH * +DevicePathInstance ( + IN OUT EFI_DEVICE_PATH **DevicePath, + OUT UINTN *Size + ); + +UINTN +DevicePathInstanceCount ( + IN EFI_DEVICE_PATH *DevicePath + ); + +EFI_DEVICE_PATH * +AppendDevicePath ( + IN EFI_DEVICE_PATH *Src1, + IN EFI_DEVICE_PATH *Src2 + ); + +EFI_DEVICE_PATH * +AppendDevicePathNode ( + IN EFI_DEVICE_PATH *Src1, + IN EFI_DEVICE_PATH *Src2 + ); + +EFI_DEVICE_PATH* +AppendDevicePathInstance ( + IN EFI_DEVICE_PATH *Src, + IN EFI_DEVICE_PATH *Instance + ); + +EFI_DEVICE_PATH * +FileDevicePath ( + IN EFI_HANDLE Device OPTIONAL, + IN CHAR16 *FileName + ); + +UINTN +DevicePathSize ( + IN EFI_DEVICE_PATH *DevPath + ); + +EFI_DEVICE_PATH * +DuplicateDevicePath ( + IN EFI_DEVICE_PATH *DevPath + ); + +EFI_DEVICE_PATH * +UnpackDevicePath ( + IN EFI_DEVICE_PATH *DevPath + ); + +EFI_STATUS +LibDevicePathToInterface ( + IN EFI_GUID *Protocol, + IN EFI_DEVICE_PATH *FilePath, + OUT VOID **Interface + ); + +CHAR16 * +DevicePathToStr ( + EFI_DEVICE_PATH *DevPath + ); + +// +// BugBug: I need my own include files +// +typedef struct { + UINT8 Register; + UINT8 Function; + UINT8 Device; + UINT8 Bus; + UINT32 Reserved; +} EFI_ADDRESS; + +typedef union { + UINT64 Address; + EFI_ADDRESS EfiAddress; +} EFI_PCI_ADDRESS_UNION; + + +EFI_STATUS +PciFindDeviceClass ( + IN OUT EFI_PCI_ADDRESS_UNION *Address, + IN UINT8 BaseClass, + IN UINT8 SubClass + ); + +EFI_STATUS +PciFindDevice ( + IN OUT EFI_PCI_ADDRESS_UNION *DeviceAddress, + IN UINT16 VendorId, + IN UINT16 DeviceId, + IN OUT PCI_TYPE00 *Pci + ); + +// +// SIMPLE_READ_FILE object used to access files +// + +typedef VOID *SIMPLE_READ_FILE; + +EFI_STATUS +OpenSimpleReadFile ( + IN BOOLEAN BootPolicy, + IN VOID *SourceBuffer OPTIONAL, + IN UINTN SourceSize, + IN OUT EFI_DEVICE_PATH **FilePath, + OUT EFI_HANDLE *DeviceHandle, + OUT SIMPLE_READ_FILE *SimpleReadHandle + ); + +EFI_STATUS +ReadSimpleReadFile ( + IN SIMPLE_READ_FILE SimpleReadHandle, + IN UINTN Offset, + IN OUT UINTN *ReadSize, + OUT VOID *Buffer + ); + + +VOID +CloseSimpleReadFile ( + IN SIMPLE_READ_FILE SimpleReadHandle + ); + +VOID +InitializeGuid ( + VOID + ); + +UINT8 +DecimaltoBCD( + IN UINT8 DecValue + ); + +UINT8 +BCDtoDecimal( + IN UINT8 BcdValue + ); + +EFI_STATUS +LibGetSystemConfigurationTable( + IN EFI_GUID *TableGuid, + IN OUT VOID **Table + ); + +BOOLEAN +LibIsValidTextGraphics ( + IN CHAR16 Graphic, + OUT CHAR8 *PcAnsi, OPTIONAL + OUT CHAR8 *Ascii OPTIONAL + ); + +BOOLEAN +IsValidAscii ( + IN CHAR16 Ascii + ); + +BOOLEAN +IsValidEfiCntlChar ( + IN CHAR16 c + ); + +CHAR16 * +LibGetUiString ( + IN EFI_HANDLE Handle, + IN UI_STRING_TYPE StringType, + IN ISO_639_2 *LangCode, + IN BOOLEAN ReturnDevicePathStrOnMismatch + ); + +CHAR8* +LibGetSmbiosString ( + IN SMBIOS_STRUCTURE_POINTER *Smbios, + IN UINT16 StringNumber + ); + +EFI_STATUS +LibGetSmbiosSystemGuidAndSerialNumber ( + IN EFI_GUID *SystemGuid, + OUT CHAR8 **SystemSerialNumber + ); + + +EFI_STATUS +InitializeGlobalIoDevice ( + IN EFI_DEVICE_PATH *DevicePath, + IN EFI_GUID *Protocol, + IN CHAR8 *ErrorStr, + OUT EFI_DEVICE_IO_INTERFACE **GlobalIoFncs + ); + +UINT32 +ReadPort ( + IN EFI_DEVICE_IO_INTERFACE *GlobalIoFncs, + IN EFI_IO_WIDTH Width, + IN UINTN Port + ); + +UINT32 +WritePort ( + IN EFI_DEVICE_IO_INTERFACE *GlobalIoFncs, + IN EFI_IO_WIDTH Width, + IN UINTN Port, + IN UINTN Data + ); + +UINT32 +ReadPciConfig ( + IN EFI_DEVICE_IO_INTERFACE *GlobalIoFncs, + IN EFI_IO_WIDTH Width, + IN UINTN Port + ); + +UINT32 +WritePciConfig ( + IN EFI_DEVICE_IO_INTERFACE *GlobalIoFncs, + IN EFI_IO_WIDTH Width, + IN UINTN Port, + IN UINTN Data + ); + +VOID +Pause ( + VOID +); + +extern EFI_DEVICE_IO_INTERFACE *GlobalIoFncs; + +#define outp(_Port, _DataByte) (UINT8)WritePort(GlobalIoFncs, IO_UINT8, (UINTN)_Port, (UINTN)_DataByte) +#define inp(_Port) (UINT8)ReadPort(GlobalIoFncs, IO_UINT8, (UINTN)_Port) +#define outpw(_Port, _DataByte) (UINT16)WritePort(GlobalIoFncs, IO_UINT16, (UINTN)_Port, (UINTN)_DataByte) +#define inpw(_Port) (UINT16)ReadPort(GlobalIoFncs, IO_UINT16, (UINTN)_Port) +#define outpd(_Port, _DataByte) (UINT32)WritePort(GlobalIoFncs, IO_UINT32, (UINTN)_Port, (UINTN)_DataByte) +#define inpd(_Port) (UINT32)ReadPort(GlobalIoFncs, IO_UINT32, (UINTN)_Port) + +#define writepci8(_Addr, _DataByte) (UINT8)WritePciConfig(GlobalIoFncs, IO_UINT8, (UINTN)_Addr, (UINTN)_DataByte) +#define readpci8(_Addr) (UINT8)ReadPciConfig(GlobalIoFncs, IO_UINT8, (UINTN)_Addr) +#define writepci16(_Addr, _DataByte) (UINT16)WritePciConfig(GlobalIoFncs, IO_UINT16, (UINTN)_Addr, (UINTN)_DataByte) +#define readpci16(_Addr) (UINT16)ReadPciConfig(GlobalIoFncs, IO_UINT16, (UINTN)_Addr) +#define writepci32(_Addr, _DataByte) (UINT32)WritePciConfig(GlobalIoFncs, IO_UINT32, (UINTN)_Addr, (UINTN)_DataByte) +#define readpci32(_Addr) (UINT32)ReadPciConfig(GlobalIoFncs, IO_UINT32, (UINTN)_Addr) + +#define Port80(_PostCode) GlobalIoFncs->Io.Write (GlobalIoFncs, IO_UINT16, (UINT64)0x80, 1, &(_PostCode)) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/efilink.h b/include/efilink.h new file mode 100644 index 0000000..98af94e --- /dev/null +++ b/include/efilink.h @@ -0,0 +1,182 @@ +#ifndef _EFI_LINK_H +#define _EFI_LINK_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + link.h (renamed efilink.h to avoid conflicts) + +Abstract: + + EFI link list macro's + + + +Revision History + +--*/ + +#ifndef EFI_NT_EMUL + +// +// List entry - doubly linked list +// + +typedef struct _LIST_ENTRY { + struct _LIST_ENTRY *Flink; + struct _LIST_ENTRY *Blink; +} LIST_ENTRY, EFI_LIST_ENTRY; + +#endif + + +// +// VOID +// InitializeListHead( +// LIST_ENTRY *ListHead +// ); +// + +#define InitializeListHead(ListHead) \ + (ListHead)->Flink = ListHead; \ + (ListHead)->Blink = ListHead; + +// +// BOOLEAN +// IsListEmpty( +// PLIST_ENTRY ListHead +// ); +// + +#define IsListEmpty(ListHead) \ + ((ListHead)->Flink == (ListHead)) + +// +// VOID +// RemoveEntryList( +// PLIST_ENTRY Entry +// ); +// + +#define _RemoveEntryList(Entry) { \ + LIST_ENTRY *_Blink, *_Flink; \ + _Flink = (Entry)->Flink; \ + _Blink = (Entry)->Blink; \ + _Blink->Flink = _Flink; \ + _Flink->Blink = _Blink; \ + } + +#if EFI_DEBUG + #define RemoveEntryList(Entry) \ + _RemoveEntryList(Entry); \ + (Entry)->Flink = (LIST_ENTRY *) BAD_POINTER; \ + (Entry)->Blink = (LIST_ENTRY *) BAD_POINTER; +#else + #define RemoveEntryList(Entry) \ + _RemoveEntryList(Entry); +#endif + +// +// VOID +// InsertTailList( +// PLIST_ENTRY ListHead, +// PLIST_ENTRY Entry +// ); +// + +#define InsertTailList(ListHead,Entry) {\ + LIST_ENTRY *_ListHead, *_Blink; \ + _ListHead = (ListHead); \ + _Blink = _ListHead->Blink; \ + (Entry)->Flink = _ListHead; \ + (Entry)->Blink = _Blink; \ + _Blink->Flink = (Entry); \ + _ListHead->Blink = (Entry); \ + } + +// +// VOID +// InsertHeadList( +// PLIST_ENTRY ListHead, +// PLIST_ENTRY Entry +// ); +// + +#define InsertHeadList(ListHead,Entry) {\ + LIST_ENTRY *_ListHead, *_Flink; \ + _ListHead = (ListHead); \ + _Flink = _ListHead->Flink; \ + (Entry)->Flink = _Flink; \ + (Entry)->Blink = _ListHead; \ + _Flink->Blink = (Entry); \ + _ListHead->Flink = (Entry); \ + } + +// VOID +// SwapListEntries( +// PLIST_ENTRY Entry1, +// PLIST_ENTRY Entry2 +// ); +// +// Put Entry2 before Entry1 +// +#define SwapListEntries(Entry1,Entry2) {\ + LIST_ENTRY *Entry1Flink, *Entry1Blink; \ + LIST_ENTRY *Entry2Flink, *Entry2Blink; \ + Entry2Flink = (Entry2)->Flink; \ + Entry2Blink = (Entry2)->Blink; \ + Entry1Flink = (Entry1)->Flink; \ + Entry1Blink = (Entry1)->Blink; \ + Entry2Blink->Flink = Entry2Flink; \ + Entry2Flink->Blink = Entry2Blink; \ + (Entry2)->Flink = Entry1; \ + (Entry2)->Blink = Entry1Blink; \ + Entry1Blink->Flink = (Entry2); \ + (Entry1)->Blink = (Entry2); \ + } + +// +// EFI_FIELD_OFFSET - returns the byte offset to a field within a structure +// + +#define EFI_FIELD_OFFSET(TYPE,Field) ((UINTN)(intptr_t)(&(((TYPE *) 0)->Field))) + +// +// CONTAINING_RECORD - returns a pointer to the structure +// from one of it's elements. +// + +#define _CR(Record, TYPE, Field) \ + ((TYPE *) ( (CHAR8 *)(Record) - (CHAR8 *) &(((TYPE *) 0)->Field))) + +// +// EDK2 uses BASE_CR for the above +// +#define BASE_CR _CR + +#if EFI_DEBUG + #define CR(Record, TYPE, Field, Sig) \ + _CR(Record, TYPE, Field)->Signature != Sig ? \ + (TYPE *) ASSERT_STRUCT(_CR(Record, TYPE, Field), Record) : \ + _CR(Record, TYPE, Field) +#else + #define CR(Record, TYPE, Field, Signature) \ + _CR(Record, TYPE, Field) +#endif + + +// +// A lock structure +// + +typedef struct _FLOCK { + EFI_TPL Tpl; + EFI_TPL OwnerTpl; + UINTN Lock; +} FLOCK; + +#endif + diff --git a/include/efinet.h b/include/efinet.h new file mode 100644 index 0000000..6a78507 --- /dev/null +++ b/include/efinet.h @@ -0,0 +1,348 @@ +#ifndef _EFINET_H +#define _EFINET_H + + +/*++ +Copyright (c) 1999 Intel Corporation + +Module Name: + efinet.h + +Abstract: + EFI Simple Network protocol + +Revision History +--*/ + + +/////////////////////////////////////////////////////////////////////////////// +// +// Simple Network Protocol +// + +#define EFI_SIMPLE_NETWORK_PROTOCOL_GUID \ + { 0xA19832B9, 0xAC25, 0x11D3, {0x9A, 0x2D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D} } + +INTERFACE_DECL(_EFI_SIMPLE_NETWORK_PROTOCOL); + +/////////////////////////////////////////////////////////////////////////////// +// + +typedef struct { + // + // Total number of frames received. Includes frames with errors and + // dropped frames. + // + UINT64 RxTotalFrames; + + // + // Number of valid frames received and copied into receive buffers. + // + UINT64 RxGoodFrames; + + // + // Number of frames below the minimum length for the media. + // This would be <64 for ethernet. + // + UINT64 RxUndersizeFrames; + + // + // Number of frames longer than the maxminum length for the + // media. This would be >1500 for ethernet. + // + UINT64 RxOversizeFrames; + + // + // Valid frames that were dropped because receive buffers were full. + // + UINT64 RxDroppedFrames; + + // + // Number of valid unicast frames received and not dropped. + // + UINT64 RxUnicastFrames; + + // + // Number of valid broadcast frames received and not dropped. + // + UINT64 RxBroadcastFrames; + + // + // Number of valid mutlicast frames received and not dropped. + // + UINT64 RxMulticastFrames; + + // + // Number of frames w/ CRC or alignment errors. + // + UINT64 RxCrcErrorFrames; + + // + // Total number of bytes received. Includes frames with errors + // and dropped frames. + // + UINT64 RxTotalBytes; + + // + // Transmit statistics. + // + UINT64 TxTotalFrames; + UINT64 TxGoodFrames; + UINT64 TxUndersizeFrames; + UINT64 TxOversizeFrames; + UINT64 TxDroppedFrames; + UINT64 TxUnicastFrames; + UINT64 TxBroadcastFrames; + UINT64 TxMulticastFrames; + UINT64 TxCrcErrorFrames; + UINT64 TxTotalBytes; + + // + // Number of collisions detection on this subnet. + // + UINT64 Collisions; + + // + // Number of frames destined for unsupported protocol. + // + UINT64 UnsupportedProtocol; + +} EFI_NETWORK_STATISTICS; + +/////////////////////////////////////////////////////////////////////////////// +// + +typedef enum { + EfiSimpleNetworkStopped, + EfiSimpleNetworkStarted, + EfiSimpleNetworkInitialized, + EfiSimpleNetworkMaxState +} EFI_SIMPLE_NETWORK_STATE; + +/////////////////////////////////////////////////////////////////////////////// +// + +#define EFI_SIMPLE_NETWORK_RECEIVE_UNICAST 0x01 +#define EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST 0x02 +#define EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST 0x04 +#define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS 0x08 +#define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST 0x10 + +/////////////////////////////////////////////////////////////////////////////// +// + +#define EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT 0x01 +#define EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT 0x02 +#define EFI_SIMPLE_NETWORK_COMMAND_INTERRUPT 0x04 +#define EFI_SIMPLE_NETWORK_SOFTWARE_INTERRUPT 0x08 + +/////////////////////////////////////////////////////////////////////////////// +// +#define MAX_MCAST_FILTER_CNT 16 +typedef struct { + UINT32 State; + UINT32 HwAddressSize; + UINT32 MediaHeaderSize; + UINT32 MaxPacketSize; + UINT32 NvRamSize; + UINT32 NvRamAccessSize; + UINT32 ReceiveFilterMask; + UINT32 ReceiveFilterSetting; + UINT32 MaxMCastFilterCount; + UINT32 MCastFilterCount; + EFI_MAC_ADDRESS MCastFilter[MAX_MCAST_FILTER_CNT]; + EFI_MAC_ADDRESS CurrentAddress; + EFI_MAC_ADDRESS BroadcastAddress; + EFI_MAC_ADDRESS PermanentAddress; + UINT8 IfType; + BOOLEAN MacAddressChangeable; + BOOLEAN MultipleTxSupported; + BOOLEAN MediaPresentSupported; + BOOLEAN MediaPresent; +} EFI_SIMPLE_NETWORK_MODE; + +/////////////////////////////////////////////////////////////////////////////// +// + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_START) ( + IN struct _EFI_SIMPLE_NETWORK_PROTOCOL *This +); + +/////////////////////////////////////////////////////////////////////////////// +// + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_STOP) ( + IN struct _EFI_SIMPLE_NETWORK_PROTOCOL *This +); + +/////////////////////////////////////////////////////////////////////////////// +// + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_INITIALIZE) ( + IN struct _EFI_SIMPLE_NETWORK_PROTOCOL *This, + IN UINTN ExtraRxBufferSize OPTIONAL, + IN UINTN ExtraTxBufferSize OPTIONAL +); + +/////////////////////////////////////////////////////////////////////////////// +// + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_RESET) ( + IN struct _EFI_SIMPLE_NETWORK_PROTOCOL *This, + IN BOOLEAN ExtendedVerification +); + +/////////////////////////////////////////////////////////////////////////////// +// + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_SHUTDOWN) ( + IN struct _EFI_SIMPLE_NETWORK_PROTOCOL *This +); + +/////////////////////////////////////////////////////////////////////////////// +// + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_RECEIVE_FILTERS) ( + IN struct _EFI_SIMPLE_NETWORK_PROTOCOL *This, + IN UINT32 Enable, + IN UINT32 Disable, + IN BOOLEAN ResetMCastFilter, + IN UINTN MCastFilterCnt OPTIONAL, + IN EFI_MAC_ADDRESS *MCastFilter OPTIONAL +); + +/////////////////////////////////////////////////////////////////////////////// +// + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_STATION_ADDRESS) ( + IN struct _EFI_SIMPLE_NETWORK_PROTOCOL *This, + IN BOOLEAN Reset, + IN EFI_MAC_ADDRESS *New OPTIONAL +); + +/////////////////////////////////////////////////////////////////////////////// +// + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_STATISTICS) ( + IN struct _EFI_SIMPLE_NETWORK_PROTOCOL *This, + IN BOOLEAN Reset, + IN OUT UINTN *StatisticsSize OPTIONAL, + OUT EFI_NETWORK_STATISTICS *StatisticsTable OPTIONAL +); + +/////////////////////////////////////////////////////////////////////////////// +// + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC) ( + IN struct _EFI_SIMPLE_NETWORK_PROTOCOL *This, + IN BOOLEAN IPv6, + IN EFI_IP_ADDRESS *IP, + OUT EFI_MAC_ADDRESS *MAC +); + +/////////////////////////////////////////////////////////////////////////////// +// + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_NVDATA) ( + IN struct _EFI_SIMPLE_NETWORK_PROTOCOL *This, + IN BOOLEAN ReadWrite, + IN UINTN Offset, + IN UINTN BufferSize, + IN OUT VOID *Buffer +); + +/////////////////////////////////////////////////////////////////////////////// +// + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_GET_STATUS) ( + IN struct _EFI_SIMPLE_NETWORK_PROTOCOL *This, + OUT UINT32 *InterruptStatus OPTIONAL, + OUT VOID **TxBuf OPTIONAL +); + +/////////////////////////////////////////////////////////////////////////////// +// + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_TRANSMIT) ( + IN struct _EFI_SIMPLE_NETWORK_PROTOCOL *This, + IN UINTN HeaderSize, + IN UINTN BufferSize, + IN VOID *Buffer, + IN EFI_MAC_ADDRESS *SrcAddr OPTIONAL, + IN EFI_MAC_ADDRESS *DestAddr OPTIONAL, + IN UINT16 *Protocol OPTIONAL +); + +/////////////////////////////////////////////////////////////////////////////// +// + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_NETWORK_RECEIVE) ( + IN struct _EFI_SIMPLE_NETWORK_PROTOCOL *This, + OUT UINTN *HeaderSize OPTIONAL, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer, + OUT EFI_MAC_ADDRESS *SrcAddr OPTIONAL, + OUT EFI_MAC_ADDRESS *DestAddr OPTIONAL, + OUT UINT16 *Protocol OPTIONAL +); + +/////////////////////////////////////////////////////////////////////////////// +// + +#define EFI_SIMPLE_NETWORK_PROTOCOL_REVISION 0x00010000 +#define EFI_SIMPLE_NETWORK_INTERFACE_REVISION EFI_SIMPLE_NETWORK_PROTOCOL_REVISION + +typedef struct _EFI_SIMPLE_NETWORK_PROTOCOL { + UINT64 Revision; + EFI_SIMPLE_NETWORK_START Start; + EFI_SIMPLE_NETWORK_STOP Stop; + EFI_SIMPLE_NETWORK_INITIALIZE Initialize; + EFI_SIMPLE_NETWORK_RESET Reset; + EFI_SIMPLE_NETWORK_SHUTDOWN Shutdown; + EFI_SIMPLE_NETWORK_RECEIVE_FILTERS ReceiveFilters; + EFI_SIMPLE_NETWORK_STATION_ADDRESS StationAddress; + EFI_SIMPLE_NETWORK_STATISTICS Statistics; + EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC MCastIpToMac; + EFI_SIMPLE_NETWORK_NVDATA NvData; + EFI_SIMPLE_NETWORK_GET_STATUS GetStatus; + EFI_SIMPLE_NETWORK_TRANSMIT Transmit; + EFI_SIMPLE_NETWORK_RECEIVE Receive; + EFI_EVENT WaitForPacket; + EFI_SIMPLE_NETWORK_MODE *Mode; +} EFI_SIMPLE_NETWORK_PROTOCOL; + +// Note: Because it conflicted with the EDK2 struct name, the +// 'EFI_SIMPLE_NETWORK_PROTOCOL' GUID definition, from older +// versions of gnu-efi, is now obsoleted. +// Use 'EFI_SIMPLE_NETWORK_PROTOCOL_GUID' instead. + +typedef struct _EFI_SIMPLE_NETWORK_PROTOCOL _EFI_SIMPLE_NETWORK; +typedef EFI_SIMPLE_NETWORK_PROTOCOL EFI_SIMPLE_NETWORK; + +#endif /* _EFINET_H */ diff --git a/include/efipart.h b/include/efipart.h new file mode 100644 index 0000000..8c92814 --- /dev/null +++ b/include/efipart.h @@ -0,0 +1,61 @@ +#ifndef _EFI_PART_H +#define _EFI_PART_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efipart.h + +Abstract: + Info about disk partitions and Master Boot Records + + + + +Revision History + +--*/ + +// +// +// + +#define EFI_PARTITION 0xef +#define MBR_SIZE 512 + +#pragma pack(1) + +typedef struct { + UINT8 BootIndicator; + UINT8 StartHead; + UINT8 StartSector; + UINT8 StartTrack; + UINT8 OSIndicator; + UINT8 EndHead; + UINT8 EndSector; + UINT8 EndTrack; + UINT8 StartingLBA[4]; + UINT8 SizeInLBA[4]; +} MBR_PARTITION_RECORD; + +#define EXTRACT_UINT32(D) (UINT32)(D[0] | (D[1] << 8) | (D[2] << 16) | (D[3] << 24)) + +#define MBR_SIGNATURE 0xaa55 +#define MIN_MBR_DEVICE_SIZE 0x80000 +#define MBR_ERRATA_PAD 0x40000 // 128 MB + +#define MAX_MBR_PARTITIONS 4 +typedef struct { + UINT8 BootStrapCode[440]; + UINT8 UniqueMbrSignature[4]; + UINT8 Unknown[2]; + MBR_PARTITION_RECORD Partition[MAX_MBR_PARTITIONS]; + UINT16 Signature; +} MASTER_BOOT_RECORD; +#pragma pack() + + +#endif diff --git a/include/efipciio.h b/include/efipciio.h new file mode 100644 index 0000000..e71e300 --- /dev/null +++ b/include/efipciio.h @@ -0,0 +1,399 @@ +#ifndef _EFI_PCI_IO_H +#define _EFI_PCI_IO_H + +#define EFI_PCI_IO_PROTOCOL_GUID \ + { 0x4cf5b200, 0x68b8, 0x4ca5, {0x9e, 0xec, 0xb2, 0x3e, 0x3f, 0x50, 0x02, 0x9a} } + +#define EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID \ + { 0x2f707ebb, 0x4a1a, 0x11d4, {0x9a, 0x38, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +INTERFACE_DECL(_EFI_PCI_IO_PROTOCOL); +INTERFACE_DECL(_EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL); + +typedef enum { + EfiPciIoWidthUint8, + EfiPciIoWidthUint16, + EfiPciIoWidthUint32, + EfiPciIoWidthUint64, + EfiPciIoWidthFifoUint8, + EfiPciIoWidthFifoUint16, + EfiPciIoWidthFifoUint32, + EfiPciIoWidthFifoUint64, + EfiPciIoWidthFillUint8, + EfiPciIoWidthFillUint16, + EfiPciIoWidthFillUint32, + EfiPciIoWidthFillUint64, + EfiPciIoWidthMaximum +} EFI_PCI_IO_PROTOCOL_WIDTH, EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH; + +#define EFI_PCI_IO_PASS_THROUGH_BAR 0xff + +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_IO_PROTOCOL_POLL_IO_MEM) ( + IN struct _EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 BarIndex, + IN UINT64 Offset, + IN UINT64 Mask, + IN UINT64 Value, + IN UINT64 Delay, + OUT UINT64 *Result +); + +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_POLL_IO_MEM) ( + IN struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINT64 Mask, + IN UINT64 Value, + IN UINT64 Delay, + OUT UINT64 *Result +); + +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_IO_PROTOCOL_IO_MEM) ( + IN struct _EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 BarIndex, + IN UINT64 Offset, + IN UINTN Count, + IN OUT VOID *Buffer +); + +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_IO_MEM) ( + IN struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer +); + +typedef struct { + EFI_PCI_IO_PROTOCOL_IO_MEM Read; + EFI_PCI_IO_PROTOCOL_IO_MEM Write; +} EFI_PCI_IO_PROTOCOL_ACCESS; + +typedef struct { + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_IO_MEM Read; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_IO_MEM Write; +} EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS; + +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_IO_PROTOCOL_CONFIG) ( + IN struct _EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT32 Offset, + IN UINTN Count, + IN OUT VOID *Buffer +); + +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_CONFIGURATION) ( + IN struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + OUT VOID **Resources +); + +typedef struct { + EFI_PCI_IO_PROTOCOL_CONFIG Read; + EFI_PCI_IO_PROTOCOL_CONFIG Write; +} EFI_PCI_IO_PROTOCOL_CONFIG_ACCESS; + +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_IO_PROTOCOL_COPY_MEM) ( + IN struct _EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_WIDTH Width, + IN UINT8 DestBarIndex, + IN UINT64 DestOffset, + IN UINT8 SrcBarIndex, + IN UINT64 SrcOffset, + IN UINTN Count +); + +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_COPY_MEM) ( + IN struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, + IN UINT64 DestAddress, + IN UINT64 SrcAddress, + IN UINTN Count +); + +typedef enum { + EfiPciIoOperationBusMasterRead, + EfiPciIoOperationBusMasterWrite, + EfiPciIoOperationBusMasterCommonBuffer, + EfiPciIoOperationMaximum +} EFI_PCI_IO_PROTOCOL_OPERATION; + +typedef enum { + EfiPciOperationBusMasterRead, + EfiPciOperationBusMasterWrite, + EfiPciOperationBusMasterCommonBuffer, + EfiPciOperationBusMasterRead64, + EfiPciOperationBusMasterWrite64, + EfiPciOperationBusMasterCommonBuffer64, + EfiPciOperationMaximum +} EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION; + +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_IO_PROTOCOL_MAP) ( + IN struct _EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_OPERATION Operation, + IN VOID *HostAddress, + IN OUT UINTN *NumberOfBytes, + OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, + OUT VOID **Mapping +); + +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_MAP) ( + IN struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation, + IN VOID *HostAddress, + IN OUT UINTN *NumberOfBytes, + OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, + OUT VOID **Mapping +); + +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_IO_PROTOCOL_UNMAP) ( + IN struct _EFI_PCI_IO_PROTOCOL *This, + IN VOID *Mapping +); + +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_UNMAP) ( + IN struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN VOID *Mapping +); + +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_IO_PROTOCOL_ALLOCATE_BUFFER) ( + IN struct _EFI_PCI_IO_PROTOCOL *This, + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + OUT VOID **HostAddress, + IN UINT64 Attributes +); + +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ALLOCATE_BUFFER) ( + IN struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT VOID **HostAddress, + IN UINT64 Attributes +); + +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_IO_PROTOCOL_FREE_BUFFER) ( + IN struct _EFI_PCI_IO_PROTOCOL *This, + IN UINTN Pages, + IN VOID *HostAddress + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_FREE_BUFFER) ( + IN struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN UINTN Pages, + IN VOID *HostAddress +); + +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_IO_PROTOCOL_FLUSH) ( + IN struct _EFI_PCI_IO_PROTOCOL *This +); + +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_FLUSH) ( + IN struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This +); + +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_IO_PROTOCOL_GET_LOCATION) ( + IN struct _EFI_PCI_IO_PROTOCOL *This, + OUT UINTN *SegmentNumber, + OUT UINTN *BusNumber, + OUT UINTN *DeviceNumber, + OUT UINTN *FunctionNumber +); + +#define EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO 0x0001 +#define EFI_PCI_ATTRIBUTE_ISA_IO 0x0002 +#define EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO 0x0004 +#define EFI_PCI_ATTRIBUTE_VGA_MEMORY 0x0008 +#define EFI_PCI_ATTRIBUTE_VGA_IO 0x0010 +#define EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO 0x0020 +#define EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO 0x0040 +#define EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE 0x0080 +#define EFI_PCI_ATTRIBUTE_IO 0x0100 +#define EFI_PCI_ATTRIBUTE_MEMORY 0x0200 +#define EFI_PCI_ATTRIBUTE_BUS_MASTER 0x0400 +#define EFI_PCI_ATTRIBUTE_MEMORY_CACHED 0x0800 +#define EFI_PCI_ATTRIBUTE_MEMORY_DISABLE 0x1000 +#define EFI_PCI_ATTRIBUTE_EMBEDDED_DEVICE 0x2000 +#define EFI_PCI_ATTRIBUTE_EMBEDDED_ROM 0x4000 +#define EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE 0x8000 +#define EFI_PCI_ATTRIBUTE_ISA_IO_16 0x10000 +#define EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16 0x20000 +#define EFI_PCI_ATTRIBUTE_VGA_IO_16 0x40000 + +#define EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO +#define EFI_PCI_IO_ATTRIBUTE_ISA_IO EFI_PCI_ATTRIBUTE_ISA_IO +#define EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO +#define EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY EFI_PCI_ATTRIBUTE_VGA_MEMORY +#define EFI_PCI_IO_ATTRIBUTE_VGA_IO EFI_PCI_ATTRIBUTE_VGA_IO +#define EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO +#define EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO +#define EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE +#define EFI_PCI_IO_ATTRIBUTE_IO EFI_PCI_ATTRIBUTE_IO +#define EFI_PCI_IO_ATTRIBUTE_MEMORY EFI_PCI_ATTRIBUTE_MEMORY +#define EFI_PCI_IO_ATTRIBUTE_BUS_MASTER EFI_PCI_ATTRIBUTE_BUS_MASTER +#define EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED EFI_PCI_ATTRIBUTE_MEMORY_CACHED +#define EFI_PCI_IO_ATTRIBUTE_MEMORY_DISABLE EFI_PCI_ATTRIBUTE_MEMORY_DISABLE +#define EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE EFI_PCI_ATTRIBUTE_EMBEDDED_DEVICE +#define EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM EFI_PCI_ATTRIBUTE_EMBEDDED_ROM +#define EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE +#define EFI_PCI_IO_ATTRIBUTE_ISA_IO_16 EFI_PCI_ATTRIBUTE_ISA_IO_16 +#define EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16 EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16 +#define EFI_PCI_IO_ATTRIBUTE_VGA_IO_16 EFI_PCI_ATTRIBUTE_VGA_IO_16 + +#define EFI_PCI_ATTRIBUTE_VALID_FOR_ALLOCATE_BUFFER \ + (EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE | EFI_PCI_ATTRIBUTE_MEMORY_CACHED | EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE) + +#define EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER \ + (~EFI_PCI_ATTRIBUTE_VALID_FOR_ALLOCATE_BUFFER) + +typedef struct { + UINT8 Register; + UINT8 Function; + UINT8 Device; + UINT8 Bus; + UINT32 ExtendedRegister; +} EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS; + +typedef enum { + EfiPciIoAttributeOperationGet, + EfiPciIoAttributeOperationSet, + EfiPciIoAttributeOperationEnable, + EfiPciIoAttributeOperationDisable, + EfiPciIoAttributeOperationSupported, + EfiPciIoAttributeOperationMaximum +} EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION; + +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_IO_PROTOCOL_ATTRIBUTES) ( + IN struct _EFI_PCI_IO_PROTOCOL *This, + IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation, + IN UINT64 Attributes, + OUT UINT64 *Result OPTIONAL +); + +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_IO_PROTOCOL_GET_BAR_ATTRIBUTES) ( + IN struct _EFI_PCI_IO_PROTOCOL *This, + IN UINT8 BarIndex, + OUT UINT64 *Supports OPTIONAL, + OUT VOID **Resources OPTIONAL +); + +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GET_ATTRIBUTES) ( + IN struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + OUT UINT64 *Supports, + OUT UINT64 *Attributes +); + +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_IO_PROTOCOL_SET_BAR_ATTRIBUTES) ( + IN struct _EFI_PCI_IO_PROTOCOL *This, + IN UINT64 Attributes, + IN UINT8 BarIndex, + IN OUT UINT64 *Offset, + IN OUT UINT64 *Length +); + +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_SET_ATTRIBUTES) ( + IN struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, + IN UINT64 Attributes, + IN OUT UINT64 *ResourceBase, + IN OUT UINT64 *ResourceLength +); + +typedef struct _EFI_PCI_IO_PROTOCOL { + EFI_PCI_IO_PROTOCOL_POLL_IO_MEM PollMem; + EFI_PCI_IO_PROTOCOL_POLL_IO_MEM PollIo; + EFI_PCI_IO_PROTOCOL_ACCESS Mem; + EFI_PCI_IO_PROTOCOL_ACCESS Io; + EFI_PCI_IO_PROTOCOL_CONFIG_ACCESS Pci; + EFI_PCI_IO_PROTOCOL_COPY_MEM CopyMem; + EFI_PCI_IO_PROTOCOL_MAP Map; + EFI_PCI_IO_PROTOCOL_UNMAP Unmap; + EFI_PCI_IO_PROTOCOL_ALLOCATE_BUFFER AllocateBuffer; + EFI_PCI_IO_PROTOCOL_FREE_BUFFER FreeBuffer; + EFI_PCI_IO_PROTOCOL_FLUSH Flush; + EFI_PCI_IO_PROTOCOL_GET_LOCATION GetLocation; + EFI_PCI_IO_PROTOCOL_ATTRIBUTES Attributes; + EFI_PCI_IO_PROTOCOL_GET_BAR_ATTRIBUTES GetBarAttributes; + EFI_PCI_IO_PROTOCOL_SET_BAR_ATTRIBUTES SetBarAttributes; + UINT64 RomSize; + VOID *RomImage; +} EFI_PCI_IO_PROTOCOL; + +// Note: Because it conflicted with the EDK2 struct name, the +// 'EFI_PCI_IO_PROTOCOL' GUID definition, from older versions +// of gnu-efi, is now obsoleted. +// Use 'EFI_PCI_IO_PROTOCOL_GUID' instead. + +typedef struct _EFI_PCI_IO_PROTOCOL _EFI_PCI_IO; +typedef EFI_PCI_IO_PROTOCOL EFI_PCI_IO; + +typedef struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL { + EFI_HANDLE ParentHandle; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_POLL_IO_MEM PollMem; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_POLL_IO_MEM PollIo; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS Mem; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS Io; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS Pci; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_COPY_MEM CopyMem; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_MAP Map; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_UNMAP Unmap; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ALLOCATE_BUFFER AllocateBuffer; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_FREE_BUFFER FreeBuffer; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_FLUSH Flush; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GET_ATTRIBUTES GetAttributes; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_SET_ATTRIBUTES SetAttributes; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_CONFIGURATION Configuration; + UINT32 SegmentNumber; +} EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL; + +#endif /* _EFI_PCI_IO_H */ diff --git a/include/efipoint.h b/include/efipoint.h new file mode 100644 index 0000000..4dbcf18 --- /dev/null +++ b/include/efipoint.h @@ -0,0 +1,115 @@ +/* Copyright (C) 2014 by John Cronin + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef _EFI_POINT_H +#define _EFI_POINT_H + +#define EFI_SIMPLE_POINTER_PROTOCOL_GUID \ + { 0x31878c87, 0xb75, 0x11d5, { 0x9a, 0x4f, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } + +INTERFACE_DECL(_EFI_SIMPLE_POINTER); + +typedef struct { + INT32 RelativeMovementX; + INT32 RelativeMovementY; + INT32 RelativeMovementZ; + BOOLEAN LeftButton; + BOOLEAN RightButton; +} EFI_SIMPLE_POINTER_STATE; + +typedef struct { + UINT64 ResolutionX; + UINT64 ResolutionY; + UINT64 ResolutionZ; + BOOLEAN LeftButton; + BOOLEAN RightButton; +} EFI_SIMPLE_POINTER_MODE; + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_POINTER_RESET) ( + IN struct _EFI_SIMPLE_POINTER *This, + IN BOOLEAN ExtendedVerification +); + +typedef +EFI_STATUS +(EFIAPI *EFI_SIMPLE_POINTER_GET_STATE) ( + IN struct _EFI_SIMPLE_POINTER *This, + IN OUT EFI_SIMPLE_POINTER_STATE *State +); + +typedef struct _EFI_SIMPLE_POINTER { + EFI_SIMPLE_POINTER_RESET Reset; + EFI_SIMPLE_POINTER_GET_STATE GetState; + EFI_EVENT WaitForInput; + EFI_SIMPLE_POINTER_MODE *Mode; +} EFI_SIMPLE_POINTER_PROTOCOL; + +#define EFI_ABSOLUTE_POINTER_PROTOCOL_GUID \ + { 0x8D59D32B, 0xC655, 0x4AE9, { 0x9B, 0x15, 0xF2, 0x59, 0x04, 0x99, 0x2A, 0x43 } } + +INTERFACE_DECL(_EFI_ABSOLUTE_POINTER_PROTOCOL); + +typedef struct { + UINT64 AbsoluteMinX; + UINT64 AbsoluteMinY; + UINT64 AbsoluteMinZ; + UINT64 AbsoluteMaxX; + UINT64 AbsoluteMaxY; + UINT64 AbsoluteMaxZ; + UINT32 Attributes; +} EFI_ABSOLUTE_POINTER_MODE; + +typedef struct { + UINT64 CurrentX; + UINT64 CurrentY; + UINT64 CurrentZ; + UINT32 ActiveButtons; +} EFI_ABSOLUTE_POINTER_STATE; + +#define EFI_ABSP_SupportsAltActive 0x00000001 +#define EFI_ABSP_SupportsPressureAsZ 0x00000002 +#define EFI_ABSP_TouchActive 0x00000001 +#define EFI_ABS_AltActive 0x00000002 + +typedef +EFI_STATUS +(EFIAPI *EFI_ABSOLUTE_POINTER_RESET) ( + IN struct _EFI_ABSOLUTE_POINTER_PROTOCOL *This, + IN BOOLEAN ExtendedVerification +); + +typedef +EFI_STATUS +(EFIAPI *EFI_ABSOLUTE_POINTER_GET_STATE) ( + IN struct _EFI_ABSOLUTE_POINTER_PROTOCOL *This, + IN OUT EFI_ABSOLUTE_POINTER_STATE *State +); + +typedef struct _EFI_ABSOLUTE_POINTER_PROTOCOL { + EFI_ABSOLUTE_POINTER_RESET Reset; + EFI_ABSOLUTE_POINTER_GET_STATE GetState; + EFI_EVENT WaitForInput; + EFI_ABSOLUTE_POINTER_MODE *Mode; +} EFI_ABSOLUTE_POINTER_PROTOCOL; + +#endif diff --git a/include/efiprot.h b/include/efiprot.h new file mode 100644 index 0000000..4f80a2f --- /dev/null +++ b/include/efiprot.h @@ -0,0 +1,1466 @@ +#ifndef _EFI_PROT_H +#define _EFI_PROT_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efiprot.h + +Abstract: + + EFI Protocols + + + +Revision History + +--*/ + +// +// FPSWA library protocol +// +#define EFI_FPSWA_PROTOCOL_GUID \ + { 0xc41b6531, 0x97b9, 0x11d3, {0x9a, 0x29, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } +#define FPSWA_PROTOCOL EFI_FPSWA_PROTOCOL_GUID + +// +// Device Path protocol +// + +#define EFI_DEVICE_PATH_PROTOCOL_GUID \ + { 0x9576e91, 0x6d3f, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} } +#define DEVICE_PATH_PROTOCOL EFI_DEVICE_PATH_PROTOCOL_GUID + + +// +// Block IO protocol +// + +#define EFI_BLOCK_IO_PROTOCOL_GUID \ + { 0x964e5b21, 0x6459, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} } +#define BLOCK_IO_PROTOCOL EFI_BLOCK_IO_PROTOCOL_GUID + +#define EFI_BLOCK_IO_PROTOCOL_REVISION 0x00010000 +#define EFI_BLOCK_IO_PROTOCOL_REVISION2 0x00020001 +#define EFI_BLOCK_IO_PROTOCOL_REVISION3 ((2<<16) | 31) +#define EFI_BLOCK_IO_INTERFACE_REVISION EFI_BLOCK_IO_PROTOCOL_REVISION +#define EFI_BLOCK_IO_INTERFACE_REVISION2 EFI_BLOCK_IO_PROTOCOL_REVISION2 +#define EFI_BLOCK_IO_INTERFACE_REVISION3 EFI_BLOCK_IO_PROTOCOL_REVISION3 + +INTERFACE_DECL(_EFI_BLOCK_IO_PROTOCOL); + +typedef +EFI_STATUS +(EFIAPI *EFI_BLOCK_RESET) ( + IN struct _EFI_BLOCK_IO_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_BLOCK_READ) ( + IN struct _EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA LBA, + IN UINTN BufferSize, + OUT VOID *Buffer + ); + + +typedef +EFI_STATUS +(EFIAPI *EFI_BLOCK_WRITE) ( + IN struct _EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA LBA, + IN UINTN BufferSize, + IN VOID *Buffer + ); + + +typedef +EFI_STATUS +(EFIAPI *EFI_BLOCK_FLUSH) ( + IN struct _EFI_BLOCK_IO_PROTOCOL *This + ); + + + +typedef struct { + UINT32 MediaId; + BOOLEAN RemovableMedia; + BOOLEAN MediaPresent; + + BOOLEAN LogicalPartition; + BOOLEAN ReadOnly; + BOOLEAN WriteCaching; + + UINT32 BlockSize; + UINT32 IoAlign; + + EFI_LBA LastBlock; + + /* revision 2 */ + EFI_LBA LowestAlignedLba; + UINT32 LogicalBlocksPerPhysicalBlock; + /* revision 3 */ + UINT32 OptimalTransferLengthGranularity; +} EFI_BLOCK_IO_MEDIA; + +typedef struct _EFI_BLOCK_IO_PROTOCOL { + UINT64 Revision; + + EFI_BLOCK_IO_MEDIA *Media; + + EFI_BLOCK_RESET Reset; + EFI_BLOCK_READ ReadBlocks; + EFI_BLOCK_WRITE WriteBlocks; + EFI_BLOCK_FLUSH FlushBlocks; + +} EFI_BLOCK_IO_PROTOCOL; + +typedef struct _EFI_BLOCK_IO_PROTOCOL _EFI_BLOCK_IO; +typedef EFI_BLOCK_IO_PROTOCOL EFI_BLOCK_IO; + +#define EFI_BLOCK_IO2_PROTOCOL_GUID \ + { 0xa77b2472, 0xe282, 0x4e9f, {0xa2, 0x45, 0xc2, 0xc0, 0xe2, 0x7b, 0xbc, 0xc1} } + +INTERFACE_DECL(_EFI_BLOCK_IO2_PROTOCOL); + +typedef struct { + EFI_EVENT Event; + EFI_STATUS TransactionStatus; +} EFI_BLOCK_IO2_TOKEN; + +typedef +EFI_STATUS +(EFIAPI *EFI_BLOCK_RESET_EX) ( + IN struct _EFI_BLOCK_IO2_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_BLOCK_READ_EX) ( + IN struct _EFI_BLOCK_IO2_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA LBA, + IN OUT EFI_BLOCK_IO2_TOKEN *Token, + IN UINTN BufferSize, + OUT VOID *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_BLOCK_WRITE_EX) ( + IN struct _EFI_BLOCK_IO2_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA LBA, + IN OUT EFI_BLOCK_IO2_TOKEN *Token, + IN UINTN BufferSize, + IN VOID *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_BLOCK_FLUSH_EX) ( + IN struct _EFI_BLOCK_IO2_PROTOCOL *This, + IN OUT EFI_BLOCK_IO2_TOKEN *Token + ); + +typedef struct _EFI_BLOCK_IO2_PROTOCOL { + EFI_BLOCK_IO_MEDIA *Media; + EFI_BLOCK_RESET_EX Reset; + EFI_BLOCK_READ_EX ReadBlocksEx; + EFI_BLOCK_WRITE_EX WriteBlocksEx; + EFI_BLOCK_FLUSH_EX FlushBlocksEx; +} EFI_BLOCK_IO2_PROTOCOL; + +// +// Disk Block IO protocol +// + +#define EFI_DISK_IO_PROTOCOL_GUID \ + { 0xce345171, 0xba0b, 0x11d2, {0x8e, 0x4f, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} } +#define DISK_IO_PROTOCOL EFI_DISK_IO_PROTOCOL_GUID + +#define EFI_DISK_IO_PROTOCOL_REVISION 0x00010000 +#define EFI_DISK_IO_INTERFACE_REVISION EFI_DISK_IO_PROTOCOL_REVISION + +INTERFACE_DECL(_EFI_DISK_IO_PROTOCOL); + +typedef +EFI_STATUS +(EFIAPI *EFI_DISK_READ) ( + IN struct _EFI_DISK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN UINT64 Offset, + IN UINTN BufferSize, + OUT VOID *Buffer + ); + + +typedef +EFI_STATUS +(EFIAPI *EFI_DISK_WRITE) ( + IN struct _EFI_DISK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN UINT64 Offset, + IN UINTN BufferSize, + IN VOID *Buffer + ); + + +typedef struct _EFI_DISK_IO_PROTOCOL { + UINT64 Revision; + EFI_DISK_READ ReadDisk; + EFI_DISK_WRITE WriteDisk; +} EFI_DISK_IO_PROTOCOL; + +typedef struct _EFI_DISK_IO_PROTOCOL _EFI_DISK_IO; +typedef EFI_DISK_IO_PROTOCOL EFI_DISK_IO; + + +#define EFI_DISK_IO2_PROTOCOL_GUID \ + { 0x151c8eae, 0x7f2c, 0x472c, {0x9e, 0x54, 0x98, 0x28, 0x19, 0x4f, 0x6a, 0x88} } + +#define EFI_DISK_IO2_PROTOCOL_REVISION 0x00020000 + +INTERFACE_DECL(_EFI_DISK_IO2_PROTOCOL); + +typedef struct { + EFI_EVENT Event; + EFI_STATUS TransactionStatus; +} EFI_DISK_IO2_TOKEN; + +typedef +EFI_STATUS +(EFIAPI *EFI_DISK_CANCEL_EX) ( + IN struct _EFI_DISK_IO2_PROTOCOL *This + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_DISK_READ_EX) ( + IN struct _EFI_DISK_IO2_PROTOCOL *This, + IN UINT32 MediaId, + IN UINT64 Offset, + IN OUT EFI_DISK_IO2_TOKEN *Token, + IN UINTN BufferSize, + OUT VOID *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_DISK_WRITE_EX) ( + IN struct _EFI_DISK_IO2_PROTOCOL *This, + IN UINT32 MediaId, + IN UINT64 Offset, + IN OUT EFI_DISK_IO2_TOKEN *Token, + IN UINTN BufferSize, + IN VOID *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_DISK_FLUSH_EX) ( + IN struct _EFI_DISK_IO2_PROTOCOL *This, + IN OUT EFI_DISK_IO2_TOKEN *Token + ); + +typedef struct _EFI_DISK_IO2_PROTOCOL { + UINT64 Revision; + EFI_DISK_CANCEL_EX Cancel; + EFI_DISK_READ_EX ReadDiskEx; + EFI_DISK_WRITE_EX WriteDiskEx; + EFI_DISK_FLUSH_EX FlushDiskEx; +} EFI_DISK_IO2_PROTOCOL; + +// +// Simple file system protocol +// + +#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \ + { 0x964e5b22, 0x6459, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} } +#define SIMPLE_FILE_SYSTEM_PROTOCOL EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID + +INTERFACE_DECL(_EFI_SIMPLE_FILE_SYSTEM_PROTOCOL); +INTERFACE_DECL(_EFI_FILE_HANDLE); + +typedef +EFI_STATUS +(EFIAPI *EFI_VOLUME_OPEN) ( + IN struct _EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, + OUT struct _EFI_FILE_HANDLE **Root + ); + +#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION 0x00010000 +#define EFI_FILE_IO_INTERFACE_REVISION EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION + +typedef struct _EFI_SIMPLE_FILE_SYSTEM_PROTOCOL { + UINT64 Revision; + EFI_VOLUME_OPEN OpenVolume; +} EFI_SIMPLE_FILE_SYSTEM_PROTOCOL; + +typedef struct _EFI_SIMPLE_FILE_SYSTEM_PROTOCOL _EFI_FILE_IO_INTERFACE; +typedef EFI_SIMPLE_FILE_SYSTEM_PROTOCOL EFI_FILE_IO_INTERFACE; + +// +// +// + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_OPEN) ( + IN struct _EFI_FILE_HANDLE *File, + OUT struct _EFI_FILE_HANDLE **NewHandle, + IN CHAR16 *FileName, + IN UINT64 OpenMode, + IN UINT64 Attributes + ); + +// Open modes +#define EFI_FILE_MODE_READ 0x0000000000000001 +#define EFI_FILE_MODE_WRITE 0x0000000000000002 +#define EFI_FILE_MODE_CREATE 0x8000000000000000 + +// File attributes +#define EFI_FILE_READ_ONLY 0x0000000000000001 +#define EFI_FILE_HIDDEN 0x0000000000000002 +#define EFI_FILE_SYSTEM 0x0000000000000004 +#define EFI_FILE_RESERVIED 0x0000000000000008 +#define EFI_FILE_DIRECTORY 0x0000000000000010 +#define EFI_FILE_ARCHIVE 0x0000000000000020 +#define EFI_FILE_VALID_ATTR 0x0000000000000037 + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_CLOSE) ( + IN struct _EFI_FILE_HANDLE *File + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_DELETE) ( + IN struct _EFI_FILE_HANDLE *File + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_READ) ( + IN struct _EFI_FILE_HANDLE *File, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_WRITE) ( + IN struct _EFI_FILE_HANDLE *File, + IN OUT UINTN *BufferSize, + IN VOID *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_SET_POSITION) ( + IN struct _EFI_FILE_HANDLE *File, + IN UINT64 Position + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_GET_POSITION) ( + IN struct _EFI_FILE_HANDLE *File, + OUT UINT64 *Position + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_GET_INFO) ( + IN struct _EFI_FILE_HANDLE *File, + IN EFI_GUID *InformationType, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_SET_INFO) ( + IN struct _EFI_FILE_HANDLE *File, + IN EFI_GUID *InformationType, + IN UINTN BufferSize, + IN VOID *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_FLUSH) ( + IN struct _EFI_FILE_HANDLE *File + ); + +typedef struct { + EFI_EVENT Event; + EFI_STATUS Status; + UINTN BufferSize; + VOID *Buffer; +} EFI_FILE_IO_TOKEN; + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_OPEN_EX)( + IN struct _EFI_FILE_HANDLE *File, + OUT struct _EFI_FILE_HANDLE **NewHandle, + IN CHAR16 *FileName, + IN UINT64 OpenMode, + IN UINT64 Attributes, + IN OUT EFI_FILE_IO_TOKEN *Token + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_READ_EX) ( + IN struct _EFI_FILE_HANDLE *File, + IN OUT EFI_FILE_IO_TOKEN *Token + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_WRITE_EX) ( + IN struct _EFI_FILE_HANDLE *File, + IN OUT EFI_FILE_IO_TOKEN *Token + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FILE_FLUSH_EX) ( + IN struct _EFI_FILE_HANDLE *File, + IN OUT EFI_FILE_IO_TOKEN *Token + ); + +#define EFI_FILE_PROTOCOL_REVISION 0x00010000 +#define EFI_FILE_PROTOCOL_REVISION2 0x00020000 +#define EFI_FILE_PROTOCOL_LATEST_REVISION EFI_FILE_PROTOCOL_REVISION2 +#define EFI_FILE_HANDLE_REVISION EFI_FILE_PROTOCOL_REVISION + +typedef struct _EFI_FILE_HANDLE { + UINT64 Revision; + EFI_FILE_OPEN Open; + EFI_FILE_CLOSE Close; + EFI_FILE_DELETE Delete; + EFI_FILE_READ Read; + EFI_FILE_WRITE Write; + EFI_FILE_GET_POSITION GetPosition; + EFI_FILE_SET_POSITION SetPosition; + EFI_FILE_GET_INFO GetInfo; + EFI_FILE_SET_INFO SetInfo; + EFI_FILE_FLUSH Flush; + EFI_FILE_OPEN_EX OpenEx; + EFI_FILE_READ_EX ReadEx; + EFI_FILE_WRITE_EX WriteEx; + EFI_FILE_FLUSH_EX FlushEx; +} EFI_FILE_PROTOCOL, *EFI_FILE_HANDLE; + +typedef EFI_FILE_PROTOCOL EFI_FILE; + + +// +// File information types +// + +#define EFI_FILE_INFO_ID \ + { 0x9576e92, 0x6d3f, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} } + +typedef struct { + UINT64 Size; + UINT64 FileSize; + UINT64 PhysicalSize; + EFI_TIME CreateTime; + EFI_TIME LastAccessTime; + EFI_TIME ModificationTime; + UINT64 Attribute; + CHAR16 FileName[1]; +} EFI_FILE_INFO; + +// +// The FileName field of the EFI_FILE_INFO data structure is variable length. +// Whenever code needs to know the size of the EFI_FILE_INFO data structure, it needs to +// be the size of the data structure without the FileName field. The following macro +// computes this size correctly no matter how big the FileName array is declared. +// This is required to make the EFI_FILE_INFO data structure ANSI compilant. +// + +#define SIZE_OF_EFI_FILE_INFO EFI_FIELD_OFFSET(EFI_FILE_INFO,FileName) + +#define EFI_FILE_SYSTEM_INFO_ID \ + { 0x9576e93, 0x6d3f, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} } + +typedef struct { + UINT64 Size; + BOOLEAN ReadOnly; + UINT64 VolumeSize; + UINT64 FreeSpace; + UINT32 BlockSize; + CHAR16 VolumeLabel[1]; +} EFI_FILE_SYSTEM_INFO; + +// +// The VolumeLabel field of the EFI_FILE_SYSTEM_INFO data structure is variable length. +// Whenever code needs to know the size of the EFI_FILE_SYSTEM_INFO data structure, it needs +// to be the size of the data structure without the VolumeLable field. The following macro +// computes this size correctly no matter how big the VolumeLable array is declared. +// This is required to make the EFI_FILE_SYSTEM_INFO data structure ANSI compilant. +// + +#define SIZE_OF_EFI_FILE_SYSTEM_INFO EFI_FIELD_OFFSET(EFI_FILE_SYSTEM_INFO,VolumeLabel) + +#define EFI_FILE_SYSTEM_VOLUME_LABEL_ID \ + { 0xDB47D7D3,0xFE81, 0x11d3, {0x9A, 0x35, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D} } + +typedef struct { + CHAR16 VolumeLabel[1]; +} EFI_FILE_SYSTEM_VOLUME_LABEL; + +#define SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL_INFO EFI_FIELD_OFFSET(EFI_FILE_SYSTEM_VOLUME_LABEL,VolumeLabel) + +// +// For compatibility with older versions of gnu-efi +// +#define EFI_FILE_SYSTEM_VOLUME_LABEL_INFO_ID EFI_FILE_SYSTEM_VOLUME_LABEL_ID +#define EFI_FILE_SYSTEM_VOLUME_LABEL_INFO EFI_FILE_SYSTEM_VOLUME_LABEL + +// +// Load file protocol +// + + +#define EFI_LOAD_FILE_PROTOCOL_GUID \ + { 0x56EC3091, 0x954C, 0x11d2, {0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B} } +#define LOAD_FILE_PROTOCOL EFI_LOAD_FILE_PROTOCOL_GUID + +INTERFACE_DECL(_EFI_LOAD_FILE_PROTOCOL); + +typedef +EFI_STATUS +(EFIAPI *EFI_LOAD_FILE) ( + IN struct _EFI_LOAD_FILE_PROTOCOL *This, + IN EFI_DEVICE_PATH *FilePath, + IN BOOLEAN BootPolicy, + IN OUT UINTN *BufferSize, + IN VOID *Buffer OPTIONAL + ); + +typedef struct _EFI_LOAD_FILE_PROTOCOL { + EFI_LOAD_FILE LoadFile; +} EFI_LOAD_FILE_PROTOCOL; + +typedef struct _EFI_LOAD_FILE_PROTOCOL _EFI_LOAD_FILE_INTERFACE; +typedef EFI_LOAD_FILE_PROTOCOL EFI_LOAD_FILE_INTERFACE; + +// +// Device IO protocol +// + +#define EFI_DEVICE_IO_PROTOCOL_GUID \ + { 0xaf6ac311, 0x84c3, 0x11d2, {0x8e, 0x3c, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b} } +#define DEVICE_IO_PROTOCOL EFI_DEVICE_IO_PROTOCOL_GUID + +INTERFACE_DECL(_EFI_DEVICE_IO_PROTOCOL); + +typedef enum { + IO_UINT8, + IO_UINT16, + IO_UINT32, + IO_UINT64, +// +// Specification Change: Copy from MMIO to MMIO vs. MMIO to buffer, buffer to MMIO +// + MMIO_COPY_UINT8, + MMIO_COPY_UINT16, + MMIO_COPY_UINT32, + MMIO_COPY_UINT64 +} EFI_IO_WIDTH; + +#define EFI_PCI_ADDRESS(_bus,_dev,_func) \ + ( (UINT64) ( (((UINTN)_bus) << 24) + (((UINTN)_dev) << 16) + (((UINTN)_func) << 8) ) ) + + +typedef +EFI_STATUS +(EFIAPI *EFI_DEVICE_IO) ( + IN struct _EFI_DEVICE_IO_PROTOCOL *This, + IN EFI_IO_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer + ); + +typedef struct { + EFI_DEVICE_IO Read; + EFI_DEVICE_IO Write; +} EFI_IO_ACCESS; + +typedef +EFI_STATUS +(EFIAPI *EFI_PCI_DEVICE_PATH) ( + IN struct _EFI_DEVICE_IO_PROTOCOL *This, + IN UINT64 Address, + IN OUT EFI_DEVICE_PATH **PciDevicePath + ); + +typedef enum { + EfiBusMasterRead, + EfiBusMasterWrite, + EfiBusMasterCommonBuffer +} EFI_IO_OPERATION_TYPE; + +typedef +EFI_STATUS +(EFIAPI *EFI_IO_MAP) ( + IN struct _EFI_DEVICE_IO_PROTOCOL *This, + IN EFI_IO_OPERATION_TYPE Operation, + IN EFI_PHYSICAL_ADDRESS *HostAddress, + IN OUT UINTN *NumberOfBytes, + OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, + OUT VOID **Mapping + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IO_UNMAP) ( + IN struct _EFI_DEVICE_IO_PROTOCOL *This, + IN VOID *Mapping + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IO_ALLOCATE_BUFFER) ( + IN struct _EFI_DEVICE_IO_PROTOCOL *This, + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *HostAddress + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IO_FLUSH) ( + IN struct _EFI_DEVICE_IO_PROTOCOL *This + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IO_FREE_BUFFER) ( + IN struct _EFI_DEVICE_IO_PROTOCOL *This, + IN UINTN Pages, + IN EFI_PHYSICAL_ADDRESS HostAddress + ); + +typedef struct _EFI_DEVICE_IO_PROTOCOL { + EFI_IO_ACCESS Mem; + EFI_IO_ACCESS Io; + EFI_IO_ACCESS Pci; + EFI_IO_MAP Map; + EFI_PCI_DEVICE_PATH PciDevicePath; + EFI_IO_UNMAP Unmap; + EFI_IO_ALLOCATE_BUFFER AllocateBuffer; + EFI_IO_FLUSH Flush; + EFI_IO_FREE_BUFFER FreeBuffer; +} EFI_DEVICE_IO_PROTOCOL; + +typedef struct _EFI_DEVICE_IO_PROTOCOL _EFI_DEVICE_IO_INTERFACE; +typedef EFI_DEVICE_IO_PROTOCOL EFI_DEVICE_IO_INTERFACE; + +// +// Unicode Collation protocol +// + +#define EFI_UNICODE_COLLATION_PROTOCOL_GUID \ + { 0x1d85cd7f, 0xf43d, 0x11d2, {0x9a, 0xc, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } +#define UNICODE_COLLATION_PROTOCOL EFI_UNICODE_COLLATION_PROTOCOL_GUID + +#define EFI_UNICODE_BYTE_ORDER_MARK (CHAR16)(0xfeff) +#define UNICODE_BYTE_ORDER_MARK EFI_UNICODE_BYTE_ORDER_MARK + +INTERFACE_DECL(_EFI_UNICODE_COLLATION_PROTOCOL); + +typedef +INTN +(EFIAPI *EFI_UNICODE_STRICOLL) ( + IN struct _EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *s1, + IN CHAR16 *s2 + ); + +typedef +BOOLEAN +(EFIAPI *EFI_UNICODE_METAIMATCH) ( + IN struct _EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *String, + IN CHAR16 *Pattern + ); + +typedef +VOID +(EFIAPI *EFI_UNICODE_STRLWR) ( + IN struct _EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str + ); + +typedef +VOID +(EFIAPI *EFI_UNICODE_STRUPR) ( + IN struct _EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str + ); + +typedef +VOID +(EFIAPI *EFI_UNICODE_FATTOSTR) ( + IN struct _EFI_UNICODE_COLLATION_PROTOCOL *This, + IN UINTN FatSize, + IN CHAR8 *Fat, + OUT CHAR16 *String + ); + +typedef +BOOLEAN +(EFIAPI *EFI_UNICODE_STRTOFAT) ( + IN struct _EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *String, + IN UINTN FatSize, + OUT CHAR8 *Fat + ); + +// +// Hash Protocol +// +#define EFI_HASH_PROTOCOL_GUID \ + { 0xC5184932, 0xDBA5, 0x46DB, { 0xA5, 0xBA, 0xCC, 0x0B, 0xDA, 0x9C, 0x14, 0x35 } } +#define HASH_PROTOCOL EFI_HASH_PROTOCOL_GUID + +#define EFI_HASH_ALGORITHM_SHA1_GUID \ + { 0x2AE9D80F, 0x3FB2, 0x4095, { 0xB7, 0xB1, 0xE9, 0x31, 0x57, 0xB9, 0x46, 0xB6 } } // Deprecated +#define EFI_HASH_ALGORITHM_SHA1 EFI_HASH_ALGORITHM_SHA1_GUID + +#define EFI_HASH_ALGORITHM_SHA224_GUID \ + { 0x8DF01A06, 0x9BD5, 0x4BF7, { 0xB0, 0x21, 0xDB, 0x4F, 0xD9, 0xCC, 0xF4, 0x5B } } // Deprecated +#define EFI_HASH_ALGORITHM_SHA224 EFI_HASH_ALGORITHM_SHA224_GUID + +#define EFI_HASH_ALGORITHM_SHA256_GUID \ + { 0x51AA59DE, 0xFDF2, 0x4EA3, { 0xBC, 0x63, 0x87, 0x5F, 0xB7, 0x84, 0x2E, 0xE9 } } // Deprecated +#define EFI_HASH_ALGORITHM_SHA256 EFI_HASH_ALGORITHM_SHA256_GUID + +#define EFI_HASH_ALGORITHM_SHA384_GUID \ + { 0xEFA96432, 0xDE33, 0x4DD2, { 0xAE, 0xE6, 0x32, 0x8C, 0x33, 0xDF, 0x77, 0x7A } } // Deprecated +#define EFI_HASH_ALGORITHM_SHA384 EFI_HASH_ALGORITHM_SHA384_GUID + +#define EFI_HASH_ALGORITHM_SHA512_GUID \ + { 0xCAA4381E, 0x750C, 0x4770, { 0xB8, 0x70, 0x7A, 0x23, 0xB4, 0xE4, 0x21, 0x30 } } // Deprecated +#define EFI_HASH_ALGORITHM_SHA512 EFI_HASH_ALGORITHM_SHA512_GUID + +#define EFI_HASH_ALGORITHM_MD5_GUID \ + { 0x0AF7C79C, 0x65B5, 0x4319, { 0xB0, 0xAE, 0x44, 0xEC, 0x48, 0x4E, 0x4A, 0xD7 } } // Deprecated +#define EFI_HASH_ALGORITHM_MD5 EFI_HASH_ALGORITHM_MD5_GUID + +#define EFI_HASH_ALGORITHM_SHA1_NOPAD_GUID \ + { 0x24C5DC2F, 0x53E2, 0x40CA, { 0x9E, 0xD6, 0xA5, 0xD9, 0xA4, 0x9F, 0x46, 0x3B } } +#define EFI_HASH_ALGORITHM_SHA1_NOPAD EFI_HASH_ALGORITHM_SHA1_NOPAD_GUID + +#define EFI_HASH_ALGORITHM_SHA256_NOPAD_GUID \ + { 0x8628752A, 0x6CB7, 0x4814, { 0x96, 0xFC, 0x24, 0xA8, 0x15, 0xAC, 0x22, 0x26 } } +#define EFI_HASH_ALGORITHM_SHA256_NOPAD EFI_HASH_ALGORITHM_SHA256_NOPAD_GUID + + +INTERFACE_DECL(_EFI_HASH_PROTOCOL); + +typedef UINT8 EFI_MD5_HASH[16]; +typedef UINT8 EFI_SHA1_HASH[20]; +typedef UINT8 EFI_SHA224_HASH[28]; +typedef UINT8 EFI_SHA256_HASH[32]; +typedef UINT8 EFI_SHA384_HASH[48]; +typedef UINT8 EFI_SHA512_HASH[64]; +typedef union _EFI_HASH_OUTPUT { + EFI_MD5_HASH *Md5Hash; + EFI_SHA1_HASH *Sha1Hash; + EFI_SHA224_HASH *Sha224Hash; + EFI_SHA256_HASH *Sha256Hash; + EFI_SHA384_HASH *Sha384Hash; + EFI_SHA512_HASH *Sha512Hash; +} EFI_HASH_OUTPUT; + +typedef +EFI_STATUS +(EFIAPI *EFI_HASH_GET_HASH_SIZE) ( + IN CONST struct _EFI_HASH_PROTOCOL *This, + IN CONST EFI_GUID *HashAlgorithm, + OUT UINTN *HashSize); + +typedef +EFI_STATUS +(EFIAPI *EFI_HASH_HASH) ( + IN CONST struct _EFI_HASH_PROTOCOL *This, + IN CONST EFI_GUID *HashAlgorithm, + IN BOOLEAN Extend, + IN CONST UINT8 *Message, + IN UINT64 MessageSize, + IN OUT EFI_HASH_OUTPUT *Hash); + +typedef struct _EFI_HASH_PROTOCOL { + EFI_HASH_GET_HASH_SIZE GetHashSize; + EFI_HASH_HASH Hash; +} EFI_HASH_PROTOCOL; + +typedef struct _EFI_HASH_PROTOCOL _EFI_HASH; +typedef EFI_HASH_PROTOCOL EFI_HASH; + + +typedef struct _EFI_UNICODE_COLLATION_PROTOCOL { + + // general + EFI_UNICODE_STRICOLL StriColl; + EFI_UNICODE_METAIMATCH MetaiMatch; + EFI_UNICODE_STRLWR StrLwr; + EFI_UNICODE_STRUPR StrUpr; + + // for supporting fat volumes + EFI_UNICODE_FATTOSTR FatToStr; + EFI_UNICODE_STRTOFAT StrToFat; + + CHAR8 *SupportedLanguages; +} EFI_UNICODE_COLLATION_PROTOCOL; + +typedef EFI_UNICODE_COLLATION_PROTOCOL EFI_UNICODE_COLLATION_INTERFACE; + +/* Graphics output protocol */ +#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \ + { 0x9042a9de, 0x23dc, 0x4a38, {0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a } } +typedef struct _EFI_GRAPHICS_OUTPUT_PROTOCOL EFI_GRAPHICS_OUTPUT_PROTOCOL; + +typedef struct { + UINT32 RedMask; + UINT32 GreenMask; + UINT32 BlueMask; + UINT32 ReservedMask; +} EFI_PIXEL_BITMASK; + +typedef enum { + PixelRedGreenBlueReserved8BitPerColor, + PixelBlueGreenRedReserved8BitPerColor, + PixelBitMask, + PixelBltOnly, + PixelFormatMax +} EFI_GRAPHICS_PIXEL_FORMAT; + +typedef struct { + UINT32 Version; + UINT32 HorizontalResolution; + UINT32 VerticalResolution; + EFI_GRAPHICS_PIXEL_FORMAT PixelFormat; + EFI_PIXEL_BITMASK PixelInformation; + UINT32 PixelsPerScanLine; +} EFI_GRAPHICS_OUTPUT_MODE_INFORMATION; + +/** + Return the current video mode information. + + @param This Protocol instance pointer. + @param ModeNumber The mode number to return information on. + @param SizeOfInfo A pointer to the size, in bytes, of the Info buffer. + @param Info A pointer to callee allocated buffer that returns information about ModeNumber. + + @retval EFI_SUCCESS Mode information returned. + @retval EFI_BUFFER_TOO_SMALL The Info buffer was too small. + @retval EFI_DEVICE_ERROR A hardware error occurred trying to retrieve the video mode. + @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode () + @retval EFI_INVALID_PARAMETER One of the input args was NULL. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE) ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN UINT32 ModeNumber, + OUT UINTN *SizeOfInfo, + OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info + ) +; + +/** + Return the current video mode information. + + @param This Protocol instance pointer. + @param ModeNumber The mode number to be set. + + @retval EFI_SUCCESS Graphics mode was changed. + @retval EFI_DEVICE_ERROR The device had an error and could not complete the request. + @retval EFI_UNSUPPORTED ModeNumber is not supported by this device. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE) ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN UINT32 ModeNumber + ); + +typedef struct { + UINT8 Blue; + UINT8 Green; + UINT8 Red; + UINT8 Reserved; +} EFI_GRAPHICS_OUTPUT_BLT_PIXEL; + +typedef union { + EFI_GRAPHICS_OUTPUT_BLT_PIXEL Pixel; + UINT32 Raw; +} EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION; + +typedef enum { + EfiBltVideoFill, + EfiBltVideoToBltBuffer, + EfiBltBufferToVideo, + EfiBltVideoToVideo, + EfiGraphicsOutputBltOperationMax +} EFI_GRAPHICS_OUTPUT_BLT_OPERATION; + +/** + The following table defines actions for BltOperations: + + EfiBltVideoFill - Write data from the BltBuffer pixel (SourceX, SourceY) + directly to every pixel of the video display rectangle + (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height). + Only one pixel will be used from the BltBuffer. Delta is NOT used. + + EfiBltVideoToBltBuffer - Read data from the video display rectangle + (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in + the BltBuffer rectangle (DestinationX, DestinationY ) + (DestinationX + Width, DestinationY + Height). If DestinationX or + DestinationY is not zero then Delta must be set to the length in bytes + of a row in the BltBuffer. + + EfiBltBufferToVideo - Write data from the BltBuffer rectangle + (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the + video display rectangle (DestinationX, DestinationY) + (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is + not zero then Delta must be set to the length in bytes of a row in the + BltBuffer. + + EfiBltVideoToVideo - Copy from the video display rectangle (SourceX, SourceY) + (SourceX + Width, SourceY + Height) .to the video display rectangle + (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height). + The BltBuffer and Delta are not used in this mode. + + @param This Protocol instance pointer. + @param BltBuffer Buffer containing data to blit into video buffer. This + buffer has a size of Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) + @param BltOperation Operation to perform on BlitBuffer and video memory + @param SourceX X coordinate of source for the BltBuffer. + @param SourceY Y coordinate of source for the BltBuffer. + @param DestinationX X coordinate of destination for the BltBuffer. + @param DestinationY Y coordinate of destination for the BltBuffer. + @param Width Width of rectangle in BltBuffer in pixels. + @param Height Hight of rectangle in BltBuffer in pixels. + @param Delta OPTIONAL + + @retval EFI_SUCCESS The Blt operation completed. + @retval EFI_INVALID_PARAMETER BltOperation is not valid. + @retval EFI_DEVICE_ERROR A hardware error occured writting to the video buffer. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT) ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL + IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta OPTIONAL + ); + +typedef struct { + UINT32 MaxMode; + UINT32 Mode; + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info; + UINTN SizeOfInfo; + EFI_PHYSICAL_ADDRESS FrameBufferBase; + UINTN FrameBufferSize; +} EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE; + +struct _EFI_GRAPHICS_OUTPUT_PROTOCOL { + EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE QueryMode; + EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE SetMode; + EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT Blt; + EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode; +}; + + + +/* + * EFI EDID Discovered Protocol + * UEFI Specification Version 2.5 Section 11.9 + */ +#define EFI_EDID_DISCOVERED_PROTOCOL_GUID \ + { 0x1C0C34F6, 0xD380, 0x41FA, { 0xA0, 0x49, 0x8a, 0xD0, 0x6C, 0x1A, 0x66, 0xAA} } + +typedef struct _EFI_EDID_DISCOVERED_PROTOCOL { + UINT32 SizeOfEdid; + UINT8 *Edid; +} EFI_EDID_DISCOVERED_PROTOCOL; + + + +/* + * EFI EDID Active Protocol + * UEFI Specification Version 2.5 Section 11.9 + */ +#define EFI_EDID_ACTIVE_PROTOCOL_GUID \ + { 0xBD8C1056, 0x9F36, 0x44EC, { 0x92, 0xA8, 0xA6, 0x33, 0x7F, 0x81, 0x79, 0x86} } + +typedef struct _EFI_EDID_ACTIVE_PROTOCOL { + UINT32 SizeOfEdid; + UINT8 *Edid; +} EFI_EDID_ACTIVE_PROTOCOL; + + + +/* + * EFI EDID Override Protocol + * UEFI Specification Version 2.5 Section 11.9 + */ +#define EFI_EDID_OVERRIDE_PROTOCOL_GUID \ + { 0x48ECB431, 0xFB72, 0x45C0, { 0xA9, 0x22, 0xF4, 0x58, 0xFE, 0x04, 0x0B, 0xD5} } + +INTERFACE_DECL(_EFI_EDID_OVERRIDE_PROTOCOL); + +typedef +EFI_STATUS +(EFIAPI *EFI_EDID_OVERRIDE_PROTOCOL_GET_EDID) ( + IN struct _EFI_EDID_OVERRIDE_PROTOCOL *This, + IN EFI_HANDLE *ChildHandle, + OUT UINT32 *Attributes, + IN OUT UINTN *EdidSize, + IN OUT UINT8 **Edid); + +typedef struct _EFI_EDID_OVERRIDE_PROTOCOL { + EFI_EDID_OVERRIDE_PROTOCOL_GET_EDID GetEdid; +} EFI_EDID_OVERRIDE_PROTOCOL; + + + +INTERFACE_DECL(_EFI_SERVICE_BINDING); + +typedef +EFI_STATUS +(EFIAPI *EFI_SERVICE_BINDING_CREATE_CHILD) ( + IN struct _EFI_SERVICE_BINDING *This, + IN EFI_HANDLE *ChildHandle + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SERVICE_BINDING_DESTROY_CHILD) ( + IN struct _EFI_SERVICE_BINDING *This, + IN EFI_HANDLE ChildHandle + ); + +typedef struct _EFI_SERVICE_BINDING { + EFI_SERVICE_BINDING_CREATE_CHILD CreateChild; + EFI_SERVICE_BINDING_DESTROY_CHILD DestroyChild; +} EFI_SERVICE_BINDING; + + + +/* + * EFI Driver Binding Protocol + * UEFI Specification Version 2.5 Section 10.1 + */ +#define EFI_DRIVER_BINDING_PROTOCOL_GUID \ + { 0x18A031AB, 0xB443, 0x4D1A, { 0xA5, 0xC0, 0x0C, 0x09, 0x26, 0x1E, 0x9F, 0x71} } +#define DRIVER_BINDING_PROTOCOL EFI_DRIVER_BINDING_PROTOCOL_GUID + +INTERFACE_DECL(_EFI_DRIVER_BINDING_PROTOCOL); + +typedef +EFI_STATUS +(EFIAPI *EFI_DRIVER_BINDING_PROTOCOL_SUPPORTED) ( + IN struct _EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH *RemainingDevicePath OPTIONAL); + +typedef +EFI_STATUS +(EFIAPI *EFI_DRIVER_BINDING_PROTOCOL_START) ( + IN struct _EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH *RemainingDevicePath OPTIONAL); + +typedef +EFI_STATUS +(EFIAPI *EFI_DRIVER_BINDING_PROTOCOL_STOP) ( + IN struct _EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL); + +typedef struct _EFI_DRIVER_BINDING_PROTOCOL { + EFI_DRIVER_BINDING_PROTOCOL_SUPPORTED Supported; + EFI_DRIVER_BINDING_PROTOCOL_START Start; + EFI_DRIVER_BINDING_PROTOCOL_STOP Stop; + UINT32 Version; + EFI_HANDLE ImageHandle; + EFI_HANDLE DriverBindingHandle; +} EFI_DRIVER_BINDING_PROTOCOL; + +typedef struct _EFI_DRIVER_BINDING_PROTOCOL _EFI_DRIVER_BINDING; +typedef EFI_DRIVER_BINDING_PROTOCOL EFI_DRIVER_BINDING; + + +/* + * Backwards compatibility with older GNU-EFI versions. Deprecated. + */ +#define EFI_DRIVER_SUPPORTED EFI_DRIVER_BINDING_PROTOCOL_SUPPORTED +#define EFI_DRIVER_START EFI_DRIVER_BINDING_PROTOCOL_START +#define EFI_DRIVER_STOP EFI_DRIVER_BINDING_PROTOCOL_STOP + + + +/* + * EFI Component Name Protocol + * Deprecated - use EFI Component Name 2 Protocol instead + */ +#define EFI_COMPONENT_NAME_PROTOCOL_GUID \ + {0x107A772C, 0xD5E1, 0x11D4, { 0x9A, 0x46, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D} } +#define COMPONENT_NAME_PROTOCOL EFI_COMPONENT_NAME_PROTOCOL_GUID + +INTERFACE_DECL(_EFI_COMPONENT_NAME_PROTOCOL); + +typedef +EFI_STATUS +(EFIAPI *EFI_COMPONENT_NAME_GET_DRIVER_NAME) ( + IN struct _EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName); + +typedef +EFI_STATUS +(EFIAPI *EFI_COMPONENT_NAME_GET_CONTROLLER_NAME) ( + IN struct _EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName); + +typedef struct _EFI_COMPONENT_NAME_PROTOCOL { + EFI_COMPONENT_NAME_GET_DRIVER_NAME GetDriverName; + EFI_COMPONENT_NAME_GET_CONTROLLER_NAME GetControllerName; + CHAR8 *SupportedLanguages; +} EFI_COMPONENT_NAME_PROTOCOL; + +typedef struct _EFI_COMPONENT_NAME_PROTOCOL _EFI_COMPONENT_NAME; +typedef EFI_COMPONENT_NAME_PROTOCOL EFI_COMPONENT_NAME; + + +/* + * EFI Component Name 2 Protocol + * UEFI Specification Version 2.5 Section 10.5 + */ +#define EFI_COMPONENT_NAME2_PROTOCOL_GUID \ + {0x6A7A5CFF, 0xE8D9, 0x4F70, { 0xBA, 0xDA, 0x75, 0xAB, 0x30, 0x25, 0xCE, 0x14} } +#define COMPONENT_NAME2_PROTOCOL EFI_COMPONENT_NAME2_PROTOCOL_GUID + +INTERFACE_DECL(_EFI_COMPONENT_NAME2_PROTOCOL); + +typedef +EFI_STATUS +(EFIAPI *EFI_COMPONENT_NAME2_GET_DRIVER_NAME) ( + IN struct _EFI_COMPONENT_NAME2_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName); + +typedef +EFI_STATUS +(EFIAPI *EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) ( + IN struct _EFI_COMPONENT_NAME2_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName); + +typedef struct _EFI_COMPONENT_NAME2_PROTOCOL { + EFI_COMPONENT_NAME2_GET_DRIVER_NAME GetDriverName; + EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME GetControllerName; + CHAR8 *SupportedLanguages; +} EFI_COMPONENT_NAME2_PROTOCOL; + +typedef struct _EFI_COMPONENT_NAME2_PROTOCOL _EFI_COMPONENT_NAME2; +typedef EFI_COMPONENT_NAME2_PROTOCOL EFI_COMPONENT_NAME2; + + + +/* + * EFI Loaded Image Protocol + * UEFI Specification Version 2.5 Section 8.1 + */ +#define EFI_LOADED_IMAGE_PROTOCOL_GUID \ + { 0x5B1B31A1, 0x9562, 0x11d2, {0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B} } +#define LOADED_IMAGE_PROTOCOL EFI_LOADED_IMAGE_PROTOCOL_GUID + +#define EFI_LOADED_IMAGE_PROTOCOL_REVISION 0x1000 +#define EFI_IMAGE_INFORMATION_REVISION EFI_LOADED_IMAGE_PROTOCOL_REVISION + +typedef +EFI_STATUS +(EFIAPI *EFI_IMAGE_UNLOAD) ( + IN EFI_HANDLE ImageHandle + ); + +typedef struct { + UINT32 Revision; + EFI_HANDLE ParentHandle; + struct _EFI_SYSTEM_TABLE *SystemTable; + + // Source location of image + EFI_HANDLE DeviceHandle; + EFI_DEVICE_PATH *FilePath; + VOID *Reserved; + + // Images load options + UINT32 LoadOptionsSize; + VOID *LoadOptions; + + // Location of where image was loaded + VOID *ImageBase; + UINT64 ImageSize; + EFI_MEMORY_TYPE ImageCodeType; + EFI_MEMORY_TYPE ImageDataType; + + // If the driver image supports a dynamic unload request + EFI_IMAGE_UNLOAD Unload; +} EFI_LOADED_IMAGE_PROTOCOL; + +typedef EFI_LOADED_IMAGE_PROTOCOL EFI_LOADED_IMAGE; + +#define EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID \ + {0xbc62157e, 0x3e33, 0x4fec, {0x99, 0x20, 0x2d, 0x3b, 0x36, 0xd7, 0x50, 0xdf} } + +/* + * Random Number Generator Protocol + * UEFI Specification Version 2.5 Section 35.5 + */ +#define EFI_RNG_PROTOCOL_GUID \ + { 0x3152bca5, 0xeade, 0x433d, {0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44} } + +typedef EFI_GUID EFI_RNG_ALGORITHM; + +#define EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID \ + {0xa7af67cb, 0x603b, 0x4d42, {0xba, 0x21, 0x70, 0xbf, 0xb6, 0x29, 0x3f, 0x96} } + +#define EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID \ + {0xc5149b43, 0xae85, 0x4f53, {0x99, 0x82, 0xb9, 0x43, 0x35, 0xd3, 0xa9, 0xe7} } + +#define EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID \ + {0x44f0de6e, 0x4d8c, 0x4045, {0xa8, 0xc7, 0x4d, 0xd1, 0x68, 0x85, 0x6b, 0x9e} } + +#define EFI_RNG_ALGORITHM_X9_31_3DES_GUID \ + {0x63c4785a, 0xca34, 0x4012, {0xa3, 0xc8, 0x0b, 0x6a, 0x32, 0x4f, 0x55, 0x46} } + +#define EFI_RNG_ALGORITHM_X9_31_AES_GUID \ + {0xacd03321, 0x777e, 0x4d3d, {0xb1, 0xc8, 0x20, 0xcf, 0xd8, 0x88, 0x20, 0xc9} } + +#define EFI_RNG_ALGORITHM_RAW \ + {0xe43176d7, 0xb6e8, 0x4827, {0xb7, 0x84, 0x7f, 0xfd, 0xc4, 0xb6, 0x85, 0x61} } + +INTERFACE_DECL(_EFI_RNG_PROTOCOL); + +typedef +EFI_STATUS +(EFIAPI *EFI_RNG_GET_INFO) ( + IN struct _EFI_RNG_PROTOCOL *This, + IN OUT UINTN *RNGAlgorithmListSize, + OUT EFI_RNG_ALGORITHM *RNGAlgorithmList +); + +typedef +EFI_STATUS +(EFIAPI *EFI_RNG_GET_RNG) ( + IN struct _EFI_RNG_PROTOCOL *This, + IN EFI_RNG_ALGORITHM *RNGAlgorithm, OPTIONAL + IN UINTN RNGValueLength, + OUT UINT8 *RNGValue +); + +typedef struct _EFI_RNG_PROTOCOL { + EFI_RNG_GET_INFO GetInfo; + EFI_RNG_GET_RNG GetRNG; +} EFI_RNG_PROTOCOL; + + +// +// EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL +// + +#define EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL_GUID \ + { 0x6b30c738, 0xa391, 0x11d4, {0x9a, 0x3b, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +INTERFACE_DECL(_EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL); + +typedef +EFI_STATUS +(EFIAPI *EFI_PLATFORM_DRIVER_OVERRIDE_GET_DRIVER) ( +IN struct _EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This, +IN EFI_HANDLE ControllerHandle, +IN OUT EFI_HANDLE *DriverImageHandle); + +typedef +EFI_STATUS +(EFIAPI *EFI_PLATFORM_DRIVER_OVERRIDE_GET_DRIVER_PATH) ( +IN struct _EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This, +IN EFI_HANDLE ControllerHandle, +IN OUT EFI_DEVICE_PATH **DriverImagePath); + +typedef +EFI_STATUS +(EFIAPI *EFI_PLATFORM_DRIVER_OVERRIDE_DRIVER_LOADED) ( +IN struct _EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This, +IN EFI_HANDLE ControllerHandle, +IN EFI_DEVICE_PATH *DriverImagePath, +IN EFI_HANDLE DriverImageHandle); + +typedef struct _EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL { + EFI_PLATFORM_DRIVER_OVERRIDE_GET_DRIVER GetDriver; + EFI_PLATFORM_DRIVER_OVERRIDE_GET_DRIVER_PATH GetDriverPath; + EFI_PLATFORM_DRIVER_OVERRIDE_DRIVER_LOADED DriverLoaded; +} EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL; + +// +// EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL +// + +#define EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL_GUID \ + { 0x3bc1b285, 0x8a15, 0x4a82, {0xaa, 0xbf, 0x4d, 0x7d, 0x13, 0xfb, 0x32, 0x65} } + +INTERFACE_DECL(_EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL); + +typedef +EFI_STATUS +(EFIAPI *EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_GET_DRIVER) ( +IN struct _EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *This, +IN OUT EFI_HANDLE *DriverImageHandle); + +typedef struct _EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL { + EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_GET_DRIVER GetDriver; +} EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL; + +// +// EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL +// + +#define EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL_GUID \ + { 0xb1ee129e, 0xda36, 0x4181, {0x91, 0xf8, 0x04, 0xa4, 0x92, 0x37, 0x66, 0xa7} } + +INTERFACE_DECL(_EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL); + +typedef +UINT32 +(EFIAPI *EFI_DRIVER_FAMILY_OVERRIDE_GET_VERSION) ( +IN struct _EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL *This); + +typedef struct _EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL { + EFI_DRIVER_FAMILY_OVERRIDE_GET_VERSION GetVersion; +} EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL; + +// +// EFI_EBC_PROTOCOL +// + +#define EFI_EBC_INTERPRETER_PROTOCOL_GUID \ + {0x13ac6dd1, 0x73d0, 0x11d4, {0xb0, 0x6b, 0x00, 0xaa, 0x00, 0xbd, 0x6d, 0xe7} } + +#define EFI_EBC_PROTOCOL_GUID EFI_EBC_INTERPRETER_PROTOCOL_GUID + +INTERFACE_DECL(_EFI_EBC_PROTOCOL); + +typedef +EFI_STATUS +(EFIAPI *EFI_EBC_CREATE_THUNK)( + IN struct _EFI_EBC_PROTOCOL *This, + IN EFI_HANDLE ImageHandle, + IN VOID *EbcEntryPoint, + OUT VOID **Thunk); + +typedef +EFI_STATUS +(EFIAPI *EFI_EBC_UNLOAD_IMAGE)( + IN struct _EFI_EBC_PROTOCOL *This, + IN EFI_HANDLE ImageHandle); + +typedef +EFI_STATUS +(EFIAPI *EBC_ICACHE_FLUSH)( + IN EFI_PHYSICAL_ADDRESS Start, + IN UINT64 Length); + +typedef +EFI_STATUS +(EFIAPI *EFI_EBC_REGISTER_ICACHE_FLUSH)( + IN struct _EFI_EBC_PROTOCOL *This, + IN EBC_ICACHE_FLUSH Flush); + +typedef +EFI_STATUS +(EFIAPI *EFI_EBC_GET_VERSION)( + IN struct _EFI_EBC_PROTOCOL *This, + IN OUT UINT64 *Version); + +typedef struct _EFI_EBC_PROTOCOL { + EFI_EBC_CREATE_THUNK CreateThunk; + EFI_EBC_UNLOAD_IMAGE UnloadImage; + EFI_EBC_REGISTER_ICACHE_FLUSH RegisterICacheFlush; + EFI_EBC_GET_VERSION GetVersion; +} EFI_EBC_PROTOCOL; + +INTERFACE_DECL(_EFI_MEMORY_ATTRIBUTE_PROTOCOL); + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_MEMORY_ATTRIBUTES)( + IN struct _EFI_MEMORY_ATTRIBUTE_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + OUT UINT64 *Attributes + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_MEMORY_ATTRIBUTES)( + IN struct _EFI_MEMORY_ATTRIBUTE_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_CLEAR_MEMORY_ATTRIBUTES)( + IN struct _EFI_MEMORY_ATTRIBUTE_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes + ); + +typedef struct _EFI_MEMORY_ATTRIBUTE_PROTOCOL { + EFI_GET_MEMORY_ATTRIBUTES GetMemoryAttributes; + EFI_SET_MEMORY_ATTRIBUTES SetMemoryAttributes; + EFI_CLEAR_MEMORY_ATTRIBUTES ClearMemoryAttributes; +} EFI_MEMORY_ATTRIBUTE_PROTOCOL; + +#endif diff --git a/include/efipxebc.h b/include/efipxebc.h new file mode 100644 index 0000000..c00b965 --- /dev/null +++ b/include/efipxebc.h @@ -0,0 +1,482 @@ +#ifndef _EFIPXEBC_H +#define _EFIPXEBC_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efipxebc.h + +Abstract: + + EFI PXE Base Code Protocol + + + +Revision History + +--*/ + +// +// PXE Base Code protocol +// + +#define EFI_PXE_BASE_CODE_PROTOCOL_GUID \ + { 0x03c4e603, 0xac28, 0x11d3, {0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +INTERFACE_DECL(_EFI_PXE_BASE_CODE_PROTOCOL); + +#define DEFAULT_TTL 4 +#define DEFAULT_ToS 0 +// +// Address definitions +// + +typedef union { + UINT32 Addr[4]; + EFI_IPv4_ADDRESS v4; + EFI_IPv6_ADDRESS v6; +} EFI_IP_ADDRESS; + +typedef UINT16 EFI_PXE_BASE_CODE_UDP_PORT; + +// +// Packet definitions +// + +typedef struct { + UINT8 BootpOpcode; + UINT8 BootpHwType; + UINT8 BootpHwAddrLen; + UINT8 BootpGateHops; + UINT32 BootpIdent; + UINT16 BootpSeconds; + UINT16 BootpFlags; + UINT8 BootpCiAddr[4]; + UINT8 BootpYiAddr[4]; + UINT8 BootpSiAddr[4]; + UINT8 BootpGiAddr[4]; + UINT8 BootpHwAddr[16]; + UINT8 BootpSrvName[64]; + UINT8 BootpBootFile[128]; + UINT32 DhcpMagik; + UINT8 DhcpOptions[56]; +} EFI_PXE_BASE_CODE_DHCPV4_PACKET; + +typedef struct { + UINT32 MessageType:8; + UINT32 TransactionId:24; + UINT8 DhcpOptions[1024]; +} EFI_PXE_BASE_CODE_DHCPV6_PACKET; + +typedef union { + UINT8 Raw[1472]; + EFI_PXE_BASE_CODE_DHCPV4_PACKET Dhcpv4; + EFI_PXE_BASE_CODE_DHCPV6_PACKET Dhcpv6; +} EFI_PXE_BASE_CODE_PACKET; + +typedef struct { + UINT8 Type; + UINT8 Code; + UINT16 Checksum; + union { + UINT32 reserved; + UINT32 Mtu; + UINT32 Pointer; + struct { + UINT16 Identifier; + UINT16 Sequence; + } Echo; + } u; + UINT8 Data[494]; +} EFI_PXE_BASE_CODE_ICMP_ERROR; + +typedef struct { + UINT8 ErrorCode; + CHAR8 ErrorString[127]; +} EFI_PXE_BASE_CODE_TFTP_ERROR; + +// +// IP Receive Filter definitions +// +#define EFI_PXE_BASE_CODE_MAX_IPCNT 8 +typedef struct { + UINT8 Filters; + UINT8 IpCnt; + UINT16 reserved; + EFI_IP_ADDRESS IpList[EFI_PXE_BASE_CODE_MAX_IPCNT]; +} EFI_PXE_BASE_CODE_IP_FILTER; + +#define EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP 0x0001 +#define EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST 0x0002 +#define EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS 0x0004 +#define EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST 0x0008 + +// +// ARP Cache definitions +// + +typedef struct { + EFI_IP_ADDRESS IpAddr; + EFI_MAC_ADDRESS MacAddr; +} EFI_PXE_BASE_CODE_ARP_ENTRY; + +typedef struct { + EFI_IP_ADDRESS IpAddr; + EFI_IP_ADDRESS SubnetMask; + EFI_IP_ADDRESS GwAddr; +} EFI_PXE_BASE_CODE_ROUTE_ENTRY; + +// +// UDP definitions +// + +#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP 0x0001 +#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT 0x0002 +#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_IP 0x0004 +#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT 0x0008 +#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_USE_FILTER 0x0010 +#define EFI_PXE_BASE_CODE_UDP_OPFLAGS_MAY_FRAGMENT 0x0020 + +// +// Discover() definitions +// + +#define EFI_PXE_BASE_CODE_BOOT_TYPE_BOOTSTRAP 0 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_MS_WINNT_RIS 1 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_INTEL_LCM 2 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_DOSUNDI 3 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_NEC_ESMPRO 4 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_IBM_WSoD 5 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_IBM_LCCM 6 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_CA_UNICENTER_TNG 7 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_HP_OPENVIEW 8 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_ALTIRIS_9 9 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_ALTIRIS_10 10 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_ALTIRIS_11 11 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_NOT_USED_12 12 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_REDHAT_INSTALL 13 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_REDHAT_BOOT 14 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_REMBO 15 +#define EFI_PXE_BASE_CODE_BOOT_TYPE_BEOBOOT 16 +// +// 17 through 32767 are reserved +// 32768 through 65279 are for vendor use +// 65280 through 65534 are reserved +// +#define EFI_PXE_BASE_CODE_BOOT_TYPE_PXETEST 65535 + +#define EFI_PXE_BASE_CODE_BOOT_LAYER_MASK 0x7FFF +#define EFI_PXE_BASE_CODE_BOOT_LAYER_INITIAL 0x0000 + + +typedef struct { + UINT16 Type; + BOOLEAN AcceptAnyResponse; + UINT8 Reserved; + EFI_IP_ADDRESS IpAddr; +} EFI_PXE_BASE_CODE_SRVLIST; + +typedef struct { + BOOLEAN UseMCast; + BOOLEAN UseBCast; + BOOLEAN UseUCast; + BOOLEAN MustUseList; + EFI_IP_ADDRESS ServerMCastIp; + UINT16 IpCnt; + EFI_PXE_BASE_CODE_SRVLIST SrvList[1]; +} EFI_PXE_BASE_CODE_DISCOVER_INFO; + +// +// Mtftp() definitions +// + +typedef enum { + EFI_PXE_BASE_CODE_TFTP_FIRST, + EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE, + EFI_PXE_BASE_CODE_TFTP_READ_FILE, + EFI_PXE_BASE_CODE_TFTP_WRITE_FILE, + EFI_PXE_BASE_CODE_TFTP_READ_DIRECTORY, + EFI_PXE_BASE_CODE_MTFTP_GET_FILE_SIZE, + EFI_PXE_BASE_CODE_MTFTP_READ_FILE, + EFI_PXE_BASE_CODE_MTFTP_READ_DIRECTORY, + EFI_PXE_BASE_CODE_MTFTP_LAST +} EFI_PXE_BASE_CODE_TFTP_OPCODE; + +typedef struct { + EFI_IP_ADDRESS MCastIp; + EFI_PXE_BASE_CODE_UDP_PORT CPort; + EFI_PXE_BASE_CODE_UDP_PORT SPort; + UINT16 ListenTimeout; + UINT16 TransmitTimeout; +} EFI_PXE_BASE_CODE_MTFTP_INFO; + +// +// PXE Base Code Mode structure +// + +#define EFI_PXE_BASE_CODE_MAX_ARP_ENTRIES 8 +#define EFI_PXE_BASE_CODE_MAX_ROUTE_ENTRIES 8 + +typedef struct { + BOOLEAN Started; + BOOLEAN Ipv6Available; + BOOLEAN Ipv6Supported; + BOOLEAN UsingIpv6; + BOOLEAN BisSupported; + BOOLEAN BisDetected; + BOOLEAN AutoArp; + BOOLEAN SendGUID; + BOOLEAN DhcpDiscoverValid; + BOOLEAN DhcpAckReceived; + BOOLEAN ProxyOfferReceived; + BOOLEAN PxeDiscoverValid; + BOOLEAN PxeReplyReceived; + BOOLEAN PxeBisReplyReceived; + BOOLEAN IcmpErrorReceived; + BOOLEAN TftpErrorReceived; + BOOLEAN MakeCallbacks; + UINT8 TTL; + UINT8 ToS; + EFI_IP_ADDRESS StationIp; + EFI_IP_ADDRESS SubnetMask; + EFI_PXE_BASE_CODE_PACKET DhcpDiscover; + EFI_PXE_BASE_CODE_PACKET DhcpAck; + EFI_PXE_BASE_CODE_PACKET ProxyOffer; + EFI_PXE_BASE_CODE_PACKET PxeDiscover; + EFI_PXE_BASE_CODE_PACKET PxeReply; + EFI_PXE_BASE_CODE_PACKET PxeBisReply; + EFI_PXE_BASE_CODE_IP_FILTER IpFilter; + UINT32 ArpCacheEntries; + EFI_PXE_BASE_CODE_ARP_ENTRY ArpCache[EFI_PXE_BASE_CODE_MAX_ARP_ENTRIES]; + UINT32 RouteTableEntries; + EFI_PXE_BASE_CODE_ROUTE_ENTRY RouteTable[EFI_PXE_BASE_CODE_MAX_ROUTE_ENTRIES]; + EFI_PXE_BASE_CODE_ICMP_ERROR IcmpError; + EFI_PXE_BASE_CODE_TFTP_ERROR TftpError; +} EFI_PXE_BASE_CODE_MODE; + +// +// PXE Base Code Interface Function definitions +// + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_START) ( + IN struct _EFI_PXE_BASE_CODE_PROTOCOL *This, + IN BOOLEAN UseIpv6 + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_STOP) ( + IN struct _EFI_PXE_BASE_CODE_PROTOCOL *This + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_DHCP) ( + IN struct _EFI_PXE_BASE_CODE_PROTOCOL *This, + IN BOOLEAN SortOffers + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_DISCOVER) ( + IN struct _EFI_PXE_BASE_CODE_PROTOCOL *This, + IN UINT16 Type, + IN UINT16 *Layer, + IN BOOLEAN UseBis, + IN OUT EFI_PXE_BASE_CODE_DISCOVER_INFO *Info OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_MTFTP) ( + IN struct _EFI_PXE_BASE_CODE_PROTOCOL *This, + IN EFI_PXE_BASE_CODE_TFTP_OPCODE Operation, + IN OUT VOID *BufferPtr OPTIONAL, + IN BOOLEAN Overwrite, + IN OUT UINT64 *BufferSize, + IN UINTN *BlockSize OPTIONAL, + IN EFI_IP_ADDRESS *ServerIp, + IN UINT8 *Filename, + IN EFI_PXE_BASE_CODE_MTFTP_INFO *Info OPTIONAL, + IN BOOLEAN DontUseBuffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_UDP_WRITE) ( + IN struct _EFI_PXE_BASE_CODE_PROTOCOL *This, + IN UINT16 OpFlags, + IN EFI_IP_ADDRESS *DestIp, + IN EFI_PXE_BASE_CODE_UDP_PORT *DestPort, + IN EFI_IP_ADDRESS *GatewayIp, OPTIONAL + IN EFI_IP_ADDRESS *SrcIp, OPTIONAL + IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPort, OPTIONAL + IN UINTN *HeaderSize, OPTIONAL + IN VOID *HeaderPtr, OPTIONAL + IN UINTN *BufferSize, + IN VOID *BufferPtr + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_UDP_READ) ( + IN struct _EFI_PXE_BASE_CODE_PROTOCOL *This, + IN UINT16 OpFlags, + IN OUT EFI_IP_ADDRESS *DestIp, OPTIONAL + IN OUT EFI_PXE_BASE_CODE_UDP_PORT *DestPort, OPTIONAL + IN OUT EFI_IP_ADDRESS *SrcIp, OPTIONAL + IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPort, OPTIONAL + IN UINTN *HeaderSize, OPTIONAL + IN VOID *HeaderPtr, OPTIONAL + IN OUT UINTN *BufferSize, + IN VOID *BufferPtr + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_SET_IP_FILTER) ( + IN struct _EFI_PXE_BASE_CODE_PROTOCOL *This, + IN EFI_PXE_BASE_CODE_IP_FILTER *NewFilter + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_ARP) ( + IN struct _EFI_PXE_BASE_CODE_PROTOCOL *This, + IN EFI_IP_ADDRESS *IpAddr, + IN EFI_MAC_ADDRESS *MacAddr OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_SET_PARAMETERS) ( + IN struct _EFI_PXE_BASE_CODE_PROTOCOL *This, + IN BOOLEAN *NewAutoArp, OPTIONAL + IN BOOLEAN *NewSendGUID, OPTIONAL + IN UINT8 *NewTTL, OPTIONAL + IN UINT8 *NewToS, OPTIONAL + IN BOOLEAN *NewMakeCallback OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_SET_STATION_IP) ( + IN struct _EFI_PXE_BASE_CODE_PROTOCOL *This, + IN EFI_IP_ADDRESS *NewStationIp, OPTIONAL + IN EFI_IP_ADDRESS *NewSubnetMask OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PXE_BASE_CODE_SET_PACKETS) ( + IN struct _EFI_PXE_BASE_CODE_PROTOCOL *This, + BOOLEAN *NewDhcpDiscoverValid, OPTIONAL + BOOLEAN *NewDhcpAckReceived, OPTIONAL + BOOLEAN *NewProxyOfferReceived, OPTIONAL + BOOLEAN *NewPxeDiscoverValid, OPTIONAL + BOOLEAN *NewPxeReplyReceived, OPTIONAL + BOOLEAN *NewPxeBisReplyReceived,OPTIONAL + IN EFI_PXE_BASE_CODE_PACKET *NewDhcpDiscover, OPTIONAL + IN EFI_PXE_BASE_CODE_PACKET *NewDhcpAck, OPTIONAL + IN EFI_PXE_BASE_CODE_PACKET *NewProxyOffer, OPTIONAL + IN EFI_PXE_BASE_CODE_PACKET *NewPxeDiscover, OPTIONAL + IN EFI_PXE_BASE_CODE_PACKET *NewPxeReply, OPTIONAL + IN EFI_PXE_BASE_CODE_PACKET *NewPxeBisReply OPTIONAL + ); + +// +// PXE Base Code Protocol structure +// + +#define EFI_PXE_BASE_CODE_PROTOCOL_REVISION 0x00010000 +#define EFI_PXE_BASE_CODE_INTERFACE_REVISION EFI_PXE_BASE_CODE_PROTOCOL_REVISION + +typedef struct _EFI_PXE_BASE_CODE_PROTOCOL { + UINT64 Revision; + EFI_PXE_BASE_CODE_START Start; + EFI_PXE_BASE_CODE_STOP Stop; + EFI_PXE_BASE_CODE_DHCP Dhcp; + EFI_PXE_BASE_CODE_DISCOVER Discover; + EFI_PXE_BASE_CODE_MTFTP Mtftp; + EFI_PXE_BASE_CODE_UDP_WRITE UdpWrite; + EFI_PXE_BASE_CODE_UDP_READ UdpRead; + EFI_PXE_BASE_CODE_SET_IP_FILTER SetIpFilter; + EFI_PXE_BASE_CODE_ARP Arp; + EFI_PXE_BASE_CODE_SET_PARAMETERS SetParameters; + EFI_PXE_BASE_CODE_SET_STATION_IP SetStationIp; + EFI_PXE_BASE_CODE_SET_PACKETS SetPackets; + EFI_PXE_BASE_CODE_MODE *Mode; +} EFI_PXE_BASE_CODE_PROTOCOL; + +// Note: Because it conflicted with the EDK2 struct name, the +// 'EFI_PXE_BASE_CODE_PROTOCOL' GUID definition, from older +// versions of gnu-efi, is now obsoleted. +// Use 'EFI_PXE_BASE_CODE_PROTOCOL_GUID' instead. + +typedef struct _EFI_PXE_BASE_CODE_PROTOCOL _EFI_PXE_BASE_CODE; +typedef struct _EFI_PXE_BASE_CODE_PROTOCOL EFI_PXE_BASE_CODE; + +// +// Call Back Definitions +// + +#define EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL_GUID \ + { 0x245dca21, 0xfb7b, 0x11d3, {0x8f, 0x01, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b} } + +// +// Revision Number +// + +#define EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL_REVISION 0x00010000 +#define EFI_PXE_BASE_CODE_CALLBACK_INTERFACE_REVISION EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL_REVISION + +INTERFACE_DECL(_EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL); + +typedef enum { + EFI_PXE_BASE_CODE_FUNCTION_FIRST, + EFI_PXE_BASE_CODE_FUNCTION_DHCP, + EFI_PXE_BASE_CODE_FUNCTION_DISCOVER, + EFI_PXE_BASE_CODE_FUNCTION_MTFTP, + EFI_PXE_BASE_CODE_FUNCTION_UDP_WRITE, + EFI_PXE_BASE_CODE_FUNCTION_UDP_READ, + EFI_PXE_BASE_CODE_FUNCTION_ARP, + EFI_PXE_BASE_CODE_FUNCTION_IGMP, + EFI_PXE_BASE_CODE_PXE_FUNCTION_LAST +} EFI_PXE_BASE_CODE_FUNCTION; + +typedef enum { + EFI_PXE_BASE_CODE_CALLBACK_STATUS_FIRST, + EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE, + EFI_PXE_BASE_CODE_CALLBACK_STATUS_ABORT, + EFI_PXE_BASE_CODE_CALLBACK_STATUS_LAST +} EFI_PXE_BASE_CODE_CALLBACK_STATUS; + +typedef +EFI_PXE_BASE_CODE_CALLBACK_STATUS +(EFIAPI *EFI_PXE_CALLBACK) ( + IN struct _EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL *This, + IN EFI_PXE_BASE_CODE_FUNCTION Function, + IN BOOLEAN Received, + IN UINT32 PacketLen, + IN EFI_PXE_BASE_CODE_PACKET *Packet OPTIONAL + ); + +typedef struct _EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL { + UINT64 Revision; + EFI_PXE_CALLBACK Callback; +} EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL; + +// Note: Because it conflicted with the EDK2 struct name, the +// 'EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL' GUID definition, from +// older versions of gnu-efi, is now obsoleted. +// Use 'EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL_GUID' instead. + +typedef struct _EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL _EFI_PXE_BASE_CODE_CALLBACK; +typedef EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL EFI_PXE_BASE_CODE_CALLBACK; + +#endif /* _EFIPXEBC_H */ diff --git a/include/efirtlib.h b/include/efirtlib.h new file mode 100644 index 0000000..3df5714 --- /dev/null +++ b/include/efirtlib.h @@ -0,0 +1,204 @@ +#ifndef _EFI_RT_LIB_INCLUDE_ +#define _EFI_RT_LIB_INCLUDE_ +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efilib.h + +Abstract: + + EFI Runtime library functions + + + +Revision History + +--*/ + +#include "efidebug.h" +#include "efipart.h" +#if defined(_M_X64) || defined(__x86_64__) || defined(__amd64__) +#include "x86_64/efilibplat.h" +#elif defined(_M_IX86) || defined(__i386__) +#include "ia32/efilibplat.h" +#elif defined(_M_IA64) || defined(__ia64__) +#include "ia64/efilibplat.h" +#elif defined (_M_ARM64) || defined(__aarch64__) +#include "aarch64/efilibplat.h" +#elif defined (_M_ARM) || defined(__arm__) +#include "arm/efilibplat.h" +#elif defined (_M_MIPS64) || defined(__mips64__) || defined(__mips64) +#include "mips64el/efilibplat.h" +#elif defined (__riscv) && __riscv_xlen == 64 +#include "riscv64/efilibplat.h" +#endif + + +VOID +RUNTIMEFUNCTION +RtZeroMem ( + IN VOID *Buffer, + IN UINTN Size + ); + +VOID +EFIAPI +RUNTIMEFUNCTION +RtSetMem ( + IN VOID *Buffer, + IN UINTN Size, + IN UINT8 Value + ); + +VOID +EFIAPI +RUNTIMEFUNCTION +RtCopyMem ( + IN VOID *Dest, + IN VOID *Src, + IN UINTN len + ); + +VOID +EFIAPI +RUNTIMEFUNCTION +RtCopyMemC ( + IN VOID *Dest, + IN CONST VOID *Src, + IN UINTN len + ); + +INTN +RUNTIMEFUNCTION +RtCompareMem ( + IN CONST VOID *Dest, + IN CONST VOID *Src, + IN UINTN len + ); + +INTN +RUNTIMEFUNCTION +RtStrCmp ( + IN CONST CHAR16 *s1, + IN CONST CHAR16 *s2 + ); + + +VOID +RUNTIMEFUNCTION +RtStrCpy ( + IN CHAR16 *Dest, + IN CONST CHAR16 *Src + ); + +VOID +RUNTIMEFUNCTION +RtStrnCpy ( + IN CHAR16 *Dest, + IN CONST CHAR16 *Src, + IN UINTN Len + ); + +CHAR16 * +RUNTIMEFUNCTION +RtStpCpy ( + IN CHAR16 *Dest, + IN CONST CHAR16 *Src + ); + +CHAR16 * +RUNTIMEFUNCTION +RtStpnCpy ( + IN CHAR16 *Dest, + IN CONST CHAR16 *Src, + IN UINTN Len + ); + +VOID +RUNTIMEFUNCTION +RtStrCat ( + IN CHAR16 *Dest, + IN CONST CHAR16 *Src + ); + +VOID +RUNTIMEFUNCTION +RtStrnCat ( + IN CHAR16 *Dest, + IN CONST CHAR16 *Src, + IN UINTN Len + ); + +UINTN +RUNTIMEFUNCTION +RtStrLen ( + IN CONST CHAR16 *s1 + ); + +UINTN +RUNTIMEFUNCTION +RtStrnLen ( + IN CONST CHAR16 *s1, + IN UINTN Len + ); + +UINTN +RUNTIMEFUNCTION +RtStrSize ( + IN CONST CHAR16 *s1 + ); + +INTN +RUNTIMEFUNCTION +RtCompareGuid ( + IN EFI_GUID *Guid1, + IN EFI_GUID *Guid2 + ); + +UINT8 +RUNTIMEFUNCTION +RtDecimaltoBCD( + IN UINT8 BcdValue + ); + +UINT8 +RUNTIMEFUNCTION +RtBCDtoDecimal( + IN UINT8 BcdValue + ); + +// +// Virtual mapping transition support. (Only used during +// the virtual address change transisition) +// + +VOID +RUNTIMEFUNCTION +RtLibEnableVirtualMappings ( + VOID + ); + +VOID +RUNTIMEFUNCTION +RtConvertList ( + IN UINTN DebugDisposition, + IN OUT LIST_ENTRY *ListHead + ); + +VOID +RUNTIMEFUNCTION +RtAcquireLock ( + IN FLOCK *Lock + ); + +VOID +RUNTIMEFUNCTION +RtReleaseLock ( + IN FLOCK *Lock + ); + + +#endif diff --git a/include/efiser.h b/include/efiser.h new file mode 100644 index 0000000..00b0d15 --- /dev/null +++ b/include/efiser.h @@ -0,0 +1,136 @@ +#ifndef _EFI_SER_H +#define _EFI_SER_H + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efiser.h + +Abstract: + + EFI serial protocol + +Revision History + +--*/ + +// +// Serial protocol +// + +#define EFI_SERIAL_IO_PROTOCOL_GUID \ + { 0xBB25CF6F, 0xF1D4, 0x11D2, {0x9A, 0x0C, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0xFD} } +#define SERIAL_IO_PROTOCOL EFI_SERIAL_IO_PROTOCOL_GUID + +INTERFACE_DECL(_EFI_SERIAL_IO_PROTOCOL); + +typedef enum { + DefaultParity, + NoParity, + EvenParity, + OddParity, + MarkParity, + SpaceParity +} EFI_PARITY_TYPE; + +typedef enum { + DefaultStopBits, + OneStopBit, // 1 stop bit + OneFiveStopBits, // 1.5 stop bits + TwoStopBits // 2 stop bits +} EFI_STOP_BITS_TYPE; + +#define EFI_SERIAL_CLEAR_TO_SEND 0x0010 // RO +#define EFI_SERIAL_DATA_SET_READY 0x0020 // RO +#define EFI_SERIAL_RING_INDICATE 0x0040 // RO +#define EFI_SERIAL_CARRIER_DETECT 0x0080 // RO +#define EFI_SERIAL_REQUEST_TO_SEND 0x0002 // WO +#define EFI_SERIAL_DATA_TERMINAL_READY 0x0001 // WO +#define EFI_SERIAL_INPUT_BUFFER_EMPTY 0x0100 // RO +#define EFI_SERIAL_OUTPUT_BUFFER_EMPTY 0x0200 // RO +#define EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE 0x1000 // RW +#define EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE 0x2000 // RW +#define EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE 0x4000 // RW + +typedef +EFI_STATUS +(EFIAPI *EFI_SERIAL_RESET) ( + IN struct _EFI_SERIAL_IO_PROTOCOL *This + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SERIAL_SET_ATTRIBUTES) ( + IN struct _EFI_SERIAL_IO_PROTOCOL *This, + IN UINT64 BaudRate, + IN UINT32 ReceiveFifoDepth, + IN UINT32 Timeout, + IN EFI_PARITY_TYPE Parity, + IN UINT8 DataBits, + IN EFI_STOP_BITS_TYPE StopBits + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SERIAL_SET_CONTROL_BITS) ( + IN struct _EFI_SERIAL_IO_PROTOCOL *This, + IN UINT32 Control + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SERIAL_GET_CONTROL_BITS) ( + IN struct _EFI_SERIAL_IO_PROTOCOL *This, + OUT UINT32 *Control + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SERIAL_WRITE) ( + IN struct _EFI_SERIAL_IO_PROTOCOL *This, + IN OUT UINTN *BufferSize, + IN VOID *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SERIAL_READ) ( + IN struct _EFI_SERIAL_IO_PROTOCOL *This, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ); + +typedef struct { + UINT32 ControlMask; + + // current Attributes + UINT32 Timeout; + UINT64 BaudRate; + UINT32 ReceiveFifoDepth; + UINT32 DataBits; + UINT32 Parity; + UINT32 StopBits; +} SERIAL_IO_MODE; + +#define SERIAL_IO_INTERFACE_REVISION 0x00010000 + +typedef struct _EFI_SERIAL_IO_PROTOCOL { + UINT32 Revision; + EFI_SERIAL_RESET Reset; + EFI_SERIAL_SET_ATTRIBUTES SetAttributes; + EFI_SERIAL_SET_CONTROL_BITS SetControl; + EFI_SERIAL_GET_CONTROL_BITS GetControl; + EFI_SERIAL_WRITE Write; + EFI_SERIAL_READ Read; + + SERIAL_IO_MODE *Mode; +} EFI_SERIAL_IO_PROTOCOL; + +typedef struct _EFI_SERIAL_IO_PROTOCOL _SERIAL_IO_INTERFACE; +typedef EFI_SERIAL_IO_PROTOCOL SERIAL_IO_INTERFACE; + +#endif + diff --git a/include/efisetjmp.h b/include/efisetjmp.h new file mode 100644 index 0000000..428cac9 --- /dev/null +++ b/include/efisetjmp.h @@ -0,0 +1,10 @@ +#ifndef GNU_EFI_SETJMP_H +#define GNU_EFI_SETJMP_H + +#include "eficompiler.h" +#include "efisetjmp_arch.h" + +extern UINTN setjmp(jmp_buf env) __attribute__((returns_twice)); +extern VOID longjmp(jmp_buf env, UINTN value) EFI_NORETURN; + +#endif /* GNU_EFI_SETJMP_H */ diff --git a/include/efishell.h b/include/efishell.h new file mode 100644 index 0000000..3602438 --- /dev/null +++ b/include/efishell.h @@ -0,0 +1,449 @@ +/** + EFI Shell protocol as defined in the UEFI Shell Specification 2.2. + + (C) Copyright 2014 Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + This file is based on MdePkg/Include/Protocol/Shell.h from EDK2 + Ported to gnu-efi by Jiaqing Zhao +**/ + +#ifndef _EFI_SHELL_H +#define _EFI_SHELL_H + +#include "efilink.h" + +#define EFI_SHELL_PROTOCOL_GUID \ + { 0x6302d008, 0x7f9b, 0x4f30, { 0x87, 0xac, 0x60, 0xc9, 0xfe, 0xf5, 0xda, 0x4e } } + +INTERFACE_DECL(_EFI_SHELL_PROTOCOL); + +typedef enum { + SHELL_SUCCESS = 0, + SHELL_LOAD_ERROR = 1, + SHELL_INVALID_PARAMETER = 2, + SHELL_UNSUPPORTED = 3, + SHELL_BAD_BUFFER_SIZE = 4, + SHELL_BUFFER_TOO_SMALL = 5, + SHELL_NOT_READY = 6, + SHELL_DEVICE_ERROR = 7, + SHELL_WRITE_PROTECTED = 8, + SHELL_OUT_OF_RESOURCES = 9, + SHELL_VOLUME_CORRUPTED = 10, + SHELL_VOLUME_FULL = 11, + SHELL_NO_MEDIA = 12, + SHELL_MEDIA_CHANGED = 13, + SHELL_NOT_FOUND = 14, + SHELL_ACCESS_DENIED = 15, + SHELL_TIMEOUT = 18, + SHELL_NOT_STARTED = 19, + SHELL_ALREADY_STARTED = 20, + SHELL_ABORTED = 21, + SHELL_INCOMPATIBLE_VERSION = 25, + SHELL_SECURITY_VIOLATION = 26, + SHELL_NOT_EQUAL = 27 +} SHELL_STATUS; + +typedef VOID *SHELL_FILE_HANDLE; + +typedef struct { + EFI_LIST_ENTRY Link; + EFI_STATUS Status; + CONST CHAR16 *FullName; + CONST CHAR16 *FileName; + SHELL_FILE_HANDLE Handle; + EFI_FILE_INFO *Info; +} EFI_SHELL_FILE_INFO; + +typedef +BOOLEAN +(EFIAPI *EFI_SHELL_BATCH_IS_ACTIVE) ( + VOID + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_CLOSE_FILE) ( + IN SHELL_FILE_HANDLE FileHandle + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_CREATE_FILE) ( + IN CONST CHAR16 *FileName, + IN UINT64 FileAttribs, + OUT SHELL_FILE_HANDLE *FileHandle + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_DELETE_FILE) ( + IN SHELL_FILE_HANDLE FileHandle + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_DELETE_FILE_BY_NAME) ( + IN CONST CHAR16 *FileName + ); + +typedef +VOID +(EFIAPI *EFI_SHELL_DISABLE_PAGE_BREAK) ( + VOID + ); + +typedef +VOID +(EFIAPI *EFI_SHELL_ENABLE_PAGE_BREAK) ( + VOID + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_EXECUTE) ( + IN EFI_HANDLE *ParentImageHandle, + IN CHAR16 *CommandLine OPTIONAL, + IN CHAR16 **Environment OPTIONAL, + OUT EFI_STATUS *StatusCode OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_FIND_FILES) ( + IN CONST CHAR16 *FilePattern, + OUT EFI_SHELL_FILE_INFO **FileList + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_FIND_FILES_IN_DIR) ( + IN SHELL_FILE_HANDLE FileDirHandle, + OUT EFI_SHELL_FILE_INFO **FileList + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_FLUSH_FILE) ( + IN SHELL_FILE_HANDLE FileHandle + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_FREE_FILE_LIST) ( + IN EFI_SHELL_FILE_INFO **FileList + ); + +typedef +CONST CHAR16 * +(EFIAPI *EFI_SHELL_GET_ALIAS) ( + IN CONST CHAR16 *Alias, + OUT BOOLEAN *Volatile OPTIONAL + ); + +typedef +CONST CHAR16 * +(EFIAPI *EFI_SHELL_GET_CUR_DIR) ( + IN CONST CHAR16 *FileSystemMapping OPTIONAL + ); + +typedef UINT32 EFI_SHELL_DEVICE_NAME_FLAGS; +#define EFI_DEVICE_NAME_USE_COMPONENT_NAME 0x00000001 +#define EFI_DEVICE_NAME_USE_DEVICE_PATH 0x00000002 + +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_GET_DEVICE_NAME) ( + IN EFI_HANDLE DeviceHandle, + IN EFI_SHELL_DEVICE_NAME_FLAGS Flags, + IN CHAR8 *Language, + OUT CHAR16 **BestDeviceName + ); + +typedef +CONST EFI_DEVICE_PATH_PROTOCOL * +(EFIAPI *EFI_SHELL_GET_DEVICE_PATH_FROM_MAP) ( + IN CONST CHAR16 *Mapping + ); + +typedef +EFI_DEVICE_PATH_PROTOCOL * +(EFIAPI *EFI_SHELL_GET_DEVICE_PATH_FROM_FILE_PATH) ( + IN CONST CHAR16 *Path + ); + +typedef +CONST CHAR16 * +(EFIAPI *EFI_SHELL_GET_ENV) ( + IN CONST CHAR16 *Name + ); + +typedef +CONST CHAR16 * +(EFIAPI *EFI_SHELL_GET_ENV_EX) ( + IN CONST CHAR16 *Name, + OUT UINT32 *Attributes OPTIONAL + ); + +typedef +EFI_FILE_INFO * +(EFIAPI *EFI_SHELL_GET_FILE_INFO) ( + IN SHELL_FILE_HANDLE FileHandle + ); + +typedef +CHAR16 * +(EFIAPI *EFI_SHELL_GET_FILE_PATH_FROM_DEVICE_PATH) ( + IN CONST EFI_DEVICE_PATH_PROTOCOL *Path + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_GET_FILE_POSITION) ( + IN SHELL_FILE_HANDLE FileHandle, + OUT UINT64 *Position + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_GET_FILE_SIZE) ( + IN SHELL_FILE_HANDLE FileHandle, + OUT UINT64 *Size + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_GET_GUID_FROM_NAME) ( + IN CONST CHAR16 *GuidName, + OUT EFI_GUID *Guid + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_GET_GUID_NAME)( + IN CONST EFI_GUID *Guid, + OUT CONST CHAR16 **GuidName + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_GET_HELP_TEXT) ( + IN CONST CHAR16 *Command, + IN CONST CHAR16 *Sections, + OUT CHAR16 **HelpText + ); + +typedef +CONST CHAR16 * +(EFIAPI *EFI_SHELL_GET_MAP_FROM_DEVICE_PATH) ( + IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath + ); + +typedef +BOOLEAN +(EFIAPI *EFI_SHELL_GET_PAGE_BREAK) ( + VOID + ); + +typedef +BOOLEAN +(EFIAPI *EFI_SHELL_IS_ROOT_SHELL) ( + VOID + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_OPEN_FILE_BY_NAME) ( + IN CONST CHAR16 *FileName, + OUT SHELL_FILE_HANDLE *FileHandle, + IN UINT64 OpenMode + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_OPEN_FILE_LIST) ( + IN CHAR16 *Path, + IN UINT64 OpenMode, + IN OUT EFI_SHELL_FILE_INFO **FileList + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_OPEN_ROOT) ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + OUT SHELL_FILE_HANDLE *FileHandle + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_OPEN_ROOT_BY_HANDLE) ( + IN EFI_HANDLE DeviceHandle, + OUT SHELL_FILE_HANDLE *FileHandle + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_READ_FILE) ( + IN SHELL_FILE_HANDLE FileHandle, + IN OUT UINTN *ReadSize, + IN OUT VOID *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_REGISTER_GUID_NAME) ( + IN CONST EFI_GUID *Guid, + IN CONST CHAR16 *GuidName + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_REMOVE_DUP_IN_FILE_LIST) ( + IN EFI_SHELL_FILE_INFO **FileList + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_SET_ALIAS) ( + IN CONST CHAR16 *Command, + IN CONST CHAR16 *Alias, + IN BOOLEAN Replace, + IN BOOLEAN Volatile + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_SET_CUR_DIR) ( + IN CONST CHAR16 *FileSystem OPTIONAL, + IN CONST CHAR16 *Dir + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_SET_ENV) ( + IN CONST CHAR16 *Name, + IN CONST CHAR16 *Value, + IN BOOLEAN Volatile + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_SET_FILE_INFO) ( + IN SHELL_FILE_HANDLE FileHandle, + IN CONST EFI_FILE_INFO *FileInfo + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_SET_FILE_POSITION) ( + IN SHELL_FILE_HANDLE FileHandle, + IN UINT64 Position + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_SET_MAP) ( + IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN CONST CHAR16 *Mapping + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SHELL_WRITE_FILE) ( + IN SHELL_FILE_HANDLE FileHandle, + IN OUT UINTN *BufferSize, + IN VOID *Buffer + ); + +typedef struct _EFI_SHELL_PROTOCOL { + EFI_SHELL_EXECUTE Execute; + EFI_SHELL_GET_ENV GetEnv; + EFI_SHELL_SET_ENV SetEnv; + EFI_SHELL_GET_ALIAS GetAlias; + EFI_SHELL_SET_ALIAS SetAlias; + EFI_SHELL_GET_HELP_TEXT GetHelpText; + EFI_SHELL_GET_DEVICE_PATH_FROM_MAP GetDevicePathFromMap; + EFI_SHELL_GET_MAP_FROM_DEVICE_PATH GetMapFromDevicePath; + EFI_SHELL_GET_DEVICE_PATH_FROM_FILE_PATH GetDevicePathFromFilePath; + EFI_SHELL_GET_FILE_PATH_FROM_DEVICE_PATH GetFilePathFromDevicePath; + EFI_SHELL_SET_MAP SetMap; + EFI_SHELL_GET_CUR_DIR GetCurDir; + EFI_SHELL_SET_CUR_DIR SetCurDir; + EFI_SHELL_OPEN_FILE_LIST OpenFileList; + EFI_SHELL_FREE_FILE_LIST FreeFileList; + EFI_SHELL_REMOVE_DUP_IN_FILE_LIST RemoveDupInFileList; + EFI_SHELL_BATCH_IS_ACTIVE BatchIsActive; + EFI_SHELL_IS_ROOT_SHELL IsRootShell; + EFI_SHELL_ENABLE_PAGE_BREAK EnablePageBreak; + EFI_SHELL_DISABLE_PAGE_BREAK DisablePageBreak; + EFI_SHELL_GET_PAGE_BREAK GetPageBreak; + EFI_SHELL_GET_DEVICE_NAME GetDeviceName; + EFI_SHELL_GET_FILE_INFO GetFileInfo; + EFI_SHELL_SET_FILE_INFO SetFileInfo; + EFI_SHELL_OPEN_FILE_BY_NAME OpenFileByName; + EFI_SHELL_CLOSE_FILE CloseFile; + EFI_SHELL_CREATE_FILE CreateFile; + EFI_SHELL_READ_FILE ReadFile; + EFI_SHELL_WRITE_FILE WriteFile; + EFI_SHELL_DELETE_FILE DeleteFile; + EFI_SHELL_DELETE_FILE_BY_NAME DeleteFileByName; + EFI_SHELL_GET_FILE_POSITION GetFilePosition; + EFI_SHELL_SET_FILE_POSITION SetFilePosition; + EFI_SHELL_FLUSH_FILE FlushFile; + EFI_SHELL_FIND_FILES FindFiles; + EFI_SHELL_FIND_FILES_IN_DIR FindFilesInDir; + EFI_SHELL_GET_FILE_SIZE GetFileSize; + EFI_SHELL_OPEN_ROOT OpenRoot; + EFI_SHELL_OPEN_ROOT_BY_HANDLE OpenRootByHandle; + EFI_EVENT ExecutionBreak; + UINT32 MajorVersion; + UINT32 MinorVersion; + // Added for Shell 2.1 + EFI_SHELL_REGISTER_GUID_NAME RegisterGuidName; + EFI_SHELL_GET_GUID_NAME GetGuidName; + EFI_SHELL_GET_GUID_FROM_NAME GetGuidFromName; + EFI_SHELL_GET_ENV_EX GetEnvEx; +} EFI_SHELL_PROTOCOL; + +#define EFI_SHELL_PARAMETERS_PROTOCOL_GUID \ + { 0x752f3136, 0x4e16, 0x4fdc, { 0xa2, 0x2a, 0xe5, 0xf4, 0x68, 0x12, 0xf4, 0xca } } + +INTERFACE_DECL(_EFI_SHELL_PARAMETERS_PROTOCOL); + +typedef struct _EFI_SHELL_PARAMETERS_PROTOCOL { + CHAR16 **Argv; + UINTN Argc; + SHELL_FILE_HANDLE StdIn; + SHELL_FILE_HANDLE StdOut; + SHELL_FILE_HANDLE StdErr; +} EFI_SHELL_PARAMETERS_PROTOCOL; + +#define EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL_GUID \ + { 0x3c7200e9, 0x005f, 0x4ea4, { 0x87, 0xde, 0xa3, 0xdf, 0xac, 0x8a, 0x27, 0xc3 } } + +INTERFACE_DECL(_EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL); + +typedef +SHELL_STATUS +(EFIAPI *SHELL_COMMAND_HANDLER)( + IN struct _EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This, + IN EFI_SYSTEM_TABLE *SystemTable, + IN EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters, + IN EFI_SHELL_PROTOCOL *Shell + ); + +typedef +CHAR16* +(EFIAPI *SHELL_COMMAND_GETHELP)( + IN struct _EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This, + IN CONST CHAR8 *Language + ); + +typedef struct _EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL { + CONST CHAR16 *CommandName; + SHELL_COMMAND_HANDLER Handler; + SHELL_COMMAND_GETHELP GetHelp; +} EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL; + +#endif diff --git a/include/efishellintf.h b/include/efishellintf.h new file mode 100644 index 0000000..e649acd --- /dev/null +++ b/include/efishellintf.h @@ -0,0 +1,94 @@ +/** @file + SHELL_INTERFACE_PROTOCOL from EDK shell (no spec). + + Shell Interface - additional information (over image_info) provided + to an application started by the shell. + + ConIo provides a file-style interface to the console. + + The shell interface's and data (including ConIo) are only valid during + the applications Entry Point. Once the application returns from it's + entry point the data is freed by the invoking shell. + + Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ +/* + * This is based on ShellPkg/Include/Protocol/EfiShellInterface.h from EDK II. + */ + +#ifndef _SHELLINTERFACE_H_ +#define _SHELLINTERFACE_H_ + + +#define SHELL_INTERFACE_PROTOCOL_GUID \ + { \ + 0x47c7b223, 0xc42a, 0x11d2, {0x8e, 0x57, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} \ + } + +/// +/// Bit definitions for EFI_SHELL_ARG_INFO +/// +typedef enum { + ARG_NO_ATTRIB = 0x0, + ARG_IS_QUOTED = 1<<0, + ARG_PARTIALLY_QUOTED = 1<<1, + ARG_FIRST_HALF_QUOTED = 1<<2, + ARG_FIRST_CHAR_IS_ESC = 1<<3 +} EFI_SHELL_ARG_INFO_TYPES; + +/// +/// Attributes for an argument. +/// +typedef struct _EFI_SHELL_ARG_INFO { + UINT32 Attributes; +} EFI_SHELL_ARG_INFO; + +/// +/// This protocol provides access to additional information about a shell application. +/// +typedef struct { + /// + /// Handle back to original image handle & image information. + /// + EFI_HANDLE ImageHandle; + EFI_LOADED_IMAGE *Info; + + /// + /// Parsed arg list converted more C-like format. + /// + CHAR16 **Argv; + UINTN Argc; + + /// + /// Storage for file redirection args after parsing. + /// + CHAR16 **RedirArgv; + UINTN RedirArgc; + + /// + /// A file style handle for console io. + /// + EFI_FILE *StdIn; + EFI_FILE *StdOut; + EFI_FILE *StdErr; + + /// + /// List of attributes for each argument. + /// + EFI_SHELL_ARG_INFO *ArgInfo; + + /// + /// Whether we are echoing. + /// + BOOLEAN EchoOn; +} EFI_SHELL_INTERFACE; + +#endif diff --git a/include/efistdarg.h b/include/efistdarg.h new file mode 100644 index 0000000..afe4201 --- /dev/null +++ b/include/efistdarg.h @@ -0,0 +1,33 @@ +#ifndef _EFISTDARG_H_ +#define _EFISTDARG_H_ + +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + devpath.h + +Abstract: + + Defines for parsing the EFI Device Path structures + + + +Revision History + +--*/ + +#if !defined(GNU_EFI_USE_EXTERNAL_STDARG) && !defined(_MSC_VER) +typedef __builtin_va_list va_list; + +# define va_start(v,l) __builtin_va_start(v,l) +# define va_end(v) __builtin_va_end(v) +# define va_arg(v,l) __builtin_va_arg(v,l) +# define va_copy(d,s) __builtin_va_copy(d,s) +#else +# include +#endif + +#endif diff --git a/include/efitcp.h b/include/efitcp.h new file mode 100644 index 0000000..a3c2532 --- /dev/null +++ b/include/efitcp.h @@ -0,0 +1,391 @@ +#ifndef _EFI_TCP_H +#define _EFI_TCP_H + +/*++ +Copyright (c) 2013 Intel Corporation + +--*/ + +#define EFI_TCP4_SERVICE_BINDING_PROTOCOL \ + { 0x00720665, 0x67eb, 0x4a99, {0xba, 0xf7, 0xd3, 0xc3, 0x3a, 0x1c,0x7c, 0xc9}} + +#define EFI_TCP4_PROTOCOL \ + { 0x65530bc7, 0xa359, 0x410f, {0xb0, 0x10, 0x5a, 0xad, 0xc7, 0xec, 0x2b, 0x62}} + +#define EFI_TCP6_SERVICE_BINDING_PROTOCOL \ + { 0xec20eb79, 0x6c1a, 0x4664, {0x9a, 0xd, 0xd2, 0xe4, 0xcc, 0x16, 0xd6, 0x64}} + +#define EFI_TCP6_PROTOCOL \ + { 0x46e44855, 0xbd60, 0x4ab7, {0xab, 0xd, 0xa6, 0x79, 0xb9, 0x44, 0x7d, 0x77}} + +INTERFACE_DECL(_EFI_TCP4); +INTERFACE_DECL(_EFI_TCP6); + +typedef struct { + BOOLEAN UseDefaultAddress; + EFI_IPv4_ADDRESS StationAddress; + EFI_IPv4_ADDRESS SubnetMask; + UINT16 StationPort; + EFI_IPv4_ADDRESS RemoteAddress; + UINT16 RemotePort; + BOOLEAN ActiveFlag; +} EFI_TCP4_ACCESS_POINT; + +typedef struct { + UINT32 ReceiveBufferSize; + UINT32 SendBufferSize; + UINT32 MaxSynBackLog; + UINT32 ConnectionTimeout; + UINT32 DataRetries; + UINT32 FinTimeout; + UINT32 TimeWaitTimeout; + UINT32 KeepAliveProbes; + UINT32 KeepAliveTime; + UINT32 KeepAliveInterval; + BOOLEAN EnableNagle; + BOOLEAN EnableTimeStamp; + BOOLEAN EnableWindowScaling; + BOOLEAN EnableSelectiveAck; + BOOLEAN EnablePAthMtuDiscovery; +} EFI_TCP4_OPTION; + +typedef struct { + // Receiving Filters + // I/O parameters + UINT8 TypeOfService; + UINT8 TimeToLive; + + // Access Point + EFI_TCP4_ACCESS_POINT AccessPoint; + + // TCP Control Options + EFI_TCP4_OPTION *ControlOption; +} EFI_TCP4_CONFIG_DATA; + +typedef enum { + Tcp4StateClosed = 0, + Tcp4StateListen = 1, + Tcp4StateSynSent = 2, + Tcp4StateSynReceived = 3, + Tcp4StateEstablished = 4, + Tcp4StateFinWait1 = 5, + Tcp4StateFinWait2 = 6, + Tcp4StateClosing = 7, + Tcp4StateTimeWait = 8, + Tcp4StateCloseWait = 9, + Tcp4StateLastAck = 10 +} EFI_TCP4_CONNECTION_STATE; + +typedef +EFI_STATUS +(EFIAPI *EFI_TCP4_GET_MODE_DATA) ( + IN struct _EFI_TCP4 *This, + OUT EFI_TCP4_CONNECTION_STATE *Tcp4State OPTIONAL, + OUT EFI_TCP4_CONFIG_DATA *Tcp4ConfigData OPTIONAL, + OUT EFI_IP4_MODE_DATA *Ip4ModeData OPTIONAL, + OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL, + OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TCP4_CONFIGURE) ( + IN struct _EFI_TCP4 *This, + IN EFI_TCP4_CONFIG_DATA *TcpConfigData OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TCP4_ROUTES) ( + IN struct _EFI_TCP4 *This, + IN BOOLEAN DeleteRoute, + IN EFI_IPv4_ADDRESS *SubnetAddress, + IN EFI_IPv4_ADDRESS *SubnetMask, + IN EFI_IPv4_ADDRESS *GatewayAddress +); + +typedef struct { + EFI_EVENT Event; + EFI_STATUS Status; +} EFI_TCP4_COMPLETION_TOKEN; + +typedef struct { + EFI_TCP4_COMPLETION_TOKEN CompletionToken; +} EFI_TCP4_CONNECTION_TOKEN; + +typedef +EFI_STATUS +(EFIAPI *EFI_TCP4_CONNECT) ( + IN struct _EFI_TCP4 *This, + IN EFI_TCP4_CONNECTION_TOKEN *ConnectionToken + ); + +typedef struct { + EFI_TCP4_COMPLETION_TOKEN CompletionToken; + EFI_HANDLE NewChildHandle; +} EFI_TCP4_LISTEN_TOKEN; + +typedef +EFI_STATUS +(EFIAPI *EFI_TCP4_ACCEPT) ( + IN struct _EFI_TCP4 *This, + IN EFI_TCP4_LISTEN_TOKEN *ListenToken + ); + +#define EFI_CONNECTION_FIN EFIERR(104) +#define EFI_CONNECTION_RESET EFIERR(105) +#define EFI_CONNECTION_REFUSED EFIERR(106) + +typedef struct { + UINT32 FragmentLength; + VOID *FragmentBuffer; +} EFI_TCP4_FRAGMENT_DATA; + +typedef struct { + BOOLEAN UrgentFlag; + UINT32 DataLength; + UINT32 FragmentCount; + EFI_TCP4_FRAGMENT_DATA FragmentTable[1]; +} EFI_TCP4_RECEIVE_DATA; + +typedef struct { + BOOLEAN Push; + BOOLEAN Urgent; + UINT32 DataLength; + UINT32 FragmentCount; + EFI_TCP4_FRAGMENT_DATA FragmentTable[1]; +} EFI_TCP4_TRANSMIT_DATA; + +typedef struct { + EFI_TCP4_COMPLETION_TOKEN CompletionToken; + union { + EFI_TCP4_RECEIVE_DATA *RxData; + EFI_TCP4_TRANSMIT_DATA *TxData; + } Packet; +} EFI_TCP4_IO_TOKEN; + +typedef +EFI_STATUS +(EFIAPI *EFI_TCP4_TRANSMIT) ( + IN struct _EFI_TCP4 *This, + IN EFI_TCP4_IO_TOKEN *Token + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TCP4_RECEIVE) ( + IN struct _EFI_TCP4 *This, + IN EFI_TCP4_IO_TOKEN *Token + ); + +typedef struct { + EFI_TCP4_COMPLETION_TOKEN CompletionToken; + BOOLEAN AbortOnClose; +} EFI_TCP4_CLOSE_TOKEN; + +typedef +EFI_STATUS +(EFIAPI *EFI_TCP4_CLOSE)( + IN struct _EFI_TCP4 *This, + IN EFI_TCP4_CLOSE_TOKEN *CloseToken + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TCP4_CANCEL)( + IN struct _EFI_TCP4 *This, + IN EFI_TCP4_COMPLETION_TOKEN *Token OPTIONAL +); + +typedef +EFI_STATUS +(EFIAPI *EFI_TCP4_POLL) ( + IN struct _EFI_TCP4 *This + ); + +typedef struct _EFI_TCP4 { + EFI_TCP4_GET_MODE_DATA GetModeData; + EFI_TCP4_CONFIGURE Configure; + EFI_TCP4_ROUTES Routes; + EFI_TCP4_CONNECT Connect; + EFI_TCP4_ACCEPT Accept; + EFI_TCP4_TRANSMIT Transmit; + EFI_TCP4_RECEIVE Receive; + EFI_TCP4_CLOSE Close; + EFI_TCP4_CANCEL Cancel; + EFI_TCP4_POLL Poll; +} EFI_TCP4; + +typedef enum { + Tcp6StateClosed = 0, + Tcp6StateListen = 1, + Tcp6StateSynSent = 2, + Tcp6StateSynReceived = 3, + Tcp6StateEstablished = 4, + Tcp6StateFinWait1 = 5, + Tcp6StateFinWait2 = 6, + Tcp6StateClosing = 7, + Tcp6StateTimeWait = 8, + Tcp6StateCloseWait = 9, + Tcp6StateLastAck = 10 +} EFI_TCP6_CONNECTION_STATE; + +typedef struct { + EFI_IPv6_ADDRESS StationAddress; + UINT16 StationPort; + EFI_IPv6_ADDRESS RemoteAddress; + UINT16 RemotePort; + BOOLEAN ActiveFlag; +} EFI_TCP6_ACCESS_POINT; + +typedef struct { + UINT32 ReceiveBufferSize; + UINT32 SendBufferSize; + UINT32 MaxSynBackLog; + UINT32 ConnectionTimeout; + UINT32 DataRetries; + UINT32 FinTimeout; + UINT32 TimeWaitTimeout; + UINT32 KeepAliveProbes; + UINT32 KeepAliveTime; + UINT32 KeepAliveInterval; + BOOLEAN EnableNagle; + BOOLEAN EnableTimeStamp; + BOOLEAN EnableWindbowScaling; + BOOLEAN EnableSelectiveAck; + BOOLEAN EnablePathMtuDiscovery; +} EFI_TCP6_OPTION; + +typedef struct { + UINT8 TrafficClass; + UINT8 HopLimit; + EFI_TCP6_ACCESS_POINT AccessPoint; + EFI_TCP6_OPTION *ControlOption; +} EFI_TCP6_CONFIG_DATA; + +typedef +EFI_STATUS +(EFIAPI *EFI_TCP6_GET_MODE_DATA) ( + IN struct _EFI_TCP6 *This, + OUT EFI_TCP6_CONNECTION_STATE *Tcp6State OPTIONAL, + OUT EFI_TCP6_CONFIG_DATA *Tcp6ConfigData OPTIONAL, + OUT EFI_IP6_MODE_DATA *Ip6ModeData OPTIONAL, + OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL, + OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TCP6_CONFIGURE) ( + IN struct _EFI_TCP6 *This, + IN EFI_TCP6_CONFIG_DATA *Tcp6ConfigData OPTIONAL + ); + +typedef struct { + EFI_EVENT Event; + EFI_STATUS Status; +} EFI_TCP6_COMPLETION_TOKEN; + +typedef struct { + EFI_TCP6_COMPLETION_TOKEN CompletionToken; +} EFI_TCP6_CONNECTION_TOKEN; + +typedef +EFI_STATUS +(EFIAPI *EFI_TCP6_CONNECT) ( + IN struct _EFI_TCP6 *This, + IN EFI_TCP6_CONNECTION_TOKEN *ConnectionToken + ); + +typedef struct { + EFI_TCP6_COMPLETION_TOKEN CompletionToken; + EFI_HANDLE NewChildHandle; +} EFI_TCP6_LISTEN_TOKEN; + +typedef +EFI_STATUS +(EFIAPI *EFI_TCP6_ACCEPT) ( + IN struct _EFI_TCP6 *This, + IN EFI_TCP6_LISTEN_TOKEN *ListenToken + ); + +typedef struct { + UINT32 FragmentLength; + VOID *FragmentBuffer; +} EFI_TCP6_FRAGMENT_DATA; + +typedef struct { + BOOLEAN UrgentFlag; + UINT32 DataLength; + UINT32 FragmentCount; + EFI_TCP6_FRAGMENT_DATA FragmentTable[1]; +} EFI_TCP6_RECEIVE_DATA; + +typedef struct { + BOOLEAN Push; + BOOLEAN Urgent; + UINT32 DataLength; + UINT32 FragmentCount; + EFI_TCP6_FRAGMENT_DATA FragmentTable[1]; +} EFI_TCP6_TRANSMIT_DATA; + +typedef struct { + EFI_TCP6_COMPLETION_TOKEN CompletionToken; + union { + EFI_TCP6_RECEIVE_DATA *RxData; + EFI_TCP6_TRANSMIT_DATA *TxData; + } Packet; +} EFI_TCP6_IO_TOKEN; + +typedef +EFI_STATUS +(EFIAPI *EFI_TCP6_TRANSMIT) ( + IN struct _EFI_TCP6 *This, + IN EFI_TCP6_IO_TOKEN *Token + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TCP6_RECEIVE) ( + IN struct _EFI_TCP6 *This, + IN EFI_TCP6_IO_TOKEN *Token + ); + +typedef struct { + EFI_TCP6_COMPLETION_TOKEN CompletionToken; + BOOLEAN AbortOnClose; +} EFI_TCP6_CLOSE_TOKEN; + +typedef +EFI_STATUS +(EFIAPI *EFI_TCP6_CLOSE)( + IN struct _EFI_TCP6 *This, + IN EFI_TCP6_CLOSE_TOKEN *CloseToken + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TCP6_CANCEL)( + IN struct _EFI_TCP6 *This, + IN EFI_TCP6_COMPLETION_TOKEN *Token OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TCP6_POLL) ( + IN struct _EFI_TCP6 *This + ); + +typedef struct _EFI_TCP6 { + EFI_TCP6_GET_MODE_DATA GetModeData; + EFI_TCP6_CONFIGURE Configure; + EFI_TCP6_CONNECT Connect; + EFI_TCP6_ACCEPT Accept; + EFI_TCP6_TRANSMIT Transmit; + EFI_TCP6_RECEIVE Receive; + EFI_TCP6_CLOSE Close; + EFI_TCP6_CANCEL Cancel; + EFI_TCP6_POLL Poll; +} EFI_TCP6; + +#endif /* _EFI_TCP_H */ diff --git a/include/efiudp.h b/include/efiudp.h new file mode 100644 index 0000000..3d14966 --- /dev/null +++ b/include/efiudp.h @@ -0,0 +1,272 @@ +#ifndef _EFI_UDP_H +#define _EFI_UDP_H + + +/*++ +Copyright (c) 2013 Intel Corporation + +--*/ + +#define EFI_UDP4_SERVICE_BINDING_PROTOCOL \ + { 0x83f01464, 0x99bd, 0x45e5, {0xb3, 0x83, 0xaf, 0x63, 0x05, 0xd8, 0xe9, 0xe6} } + +#define EFI_UDP4_PROTOCOL \ + { 0x3ad9df29, 0x4501, 0x478d, {0xb1, 0xf8, 0x7f, 0x7f, 0xe7, 0x0e, 0x50, 0xf3} } + +#define EFI_UDP6_SERVICE_BINDING_PROTOCOL \ + { 0x66ed4721, 0x3c98, 0x4d3e, {0x81, 0xe3, 0xd0, 0x3d, 0xd3, 0x9a, 0x72, 0x54} } + +#define EFI_UDP6_PROTOCOL \ + { 0x4f948815, 0xb4b9, 0x43cb, {0x8a, 0x33, 0x90, 0xe0, 0x60, 0xb3,0x49, 0x55} } + +INTERFACE_DECL(_EFI_UDP4); +INTERFACE_DECL(_EFI_UDP6); + +typedef struct { + BOOLEAN AcceptBroadcast; + BOOLEAN AcceptPromiscuous; + BOOLEAN AcceptAnyPort; + BOOLEAN AllowDuplicatePort; + UINT8 TypeOfService; + UINT8 TimeToLive; + BOOLEAN DoNotFragment; + UINT32 ReceiveTimeout; + UINT32 TransmitTimeout; + BOOLEAN UseDefaultAddress; + EFI_IPv4_ADDRESS StationAddress; + EFI_IPv4_ADDRESS SubnetMask; + UINT16 StationPort; + EFI_IPv4_ADDRESS RemoteAddress; + UINT16 RemotePort; +} EFI_UDP4_CONFIG_DATA; + +typedef +EFI_STATUS +(EFIAPI *EFI_UDP4_GET_MODE_DATA) ( + IN struct _EFI_UDP4 *This, + OUT EFI_UDP4_CONFIG_DATA *Udp4ConfigData OPTIONAL, + OUT EFI_IP4_MODE_DATA *Ip4ModeData OPTIONAL, + OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL, + OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_UDP4_CONFIGURE) ( + IN struct _EFI_UDP4 *This, + IN EFI_UDP4_CONFIG_DATA *UdpConfigData OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_UDP4_GROUPS) ( + IN struct _EFI_UDP4 *This, + IN BOOLEAN JoinFlag, + IN EFI_IPv4_ADDRESS *MulticastAddress OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_UDP4_ROUTES) ( + IN struct _EFI_UDP4 *This, + IN BOOLEAN DeleteRoute, + IN EFI_IPv4_ADDRESS *SubnetAddress, + IN EFI_IPv4_ADDRESS *SubnetMask, + IN EFI_IPv4_ADDRESS *GatewayAddress + ); + +#define EFI_NETWORK_UNREACHABLE EFIERR(100) +#define EFI_HOST_UNREACHABLE EFIERR(101) +#define EFI_PROTOCOL_UNREACHABLE EFIERR(102) +#define EFI_PORT_UNREACHABLE EFIERR(103) + +typedef struct { + EFI_IPv4_ADDRESS SourceAddress; + UINT16 SourcePort; + EFI_IPv4_ADDRESS DestinationAddress; + UINT16 DestinationPort; +} EFI_UDP4_SESSION_DATA; + +typedef struct { + UINT32 FragmentLength; + VOID *FragmentBuffer; +} EFI_UDP4_FRAGMENT_DATA; + +typedef struct { + EFI_TIME TimeStamp; + EFI_EVENT RecycleSignal; + EFI_UDP4_SESSION_DATA UdpSession; + UINT32 DataLength; + UINT32 FragmentCount; + EFI_UDP4_FRAGMENT_DATA FragmentTable[1]; +} EFI_UDP4_RECEIVE_DATA; + +typedef struct { + EFI_UDP4_SESSION_DATA *UdpSessionData; + EFI_IPv4_ADDRESS *GatewayAddress; + UINT32 DataLength; + UINT32 FragmentCount; + EFI_UDP4_FRAGMENT_DATA FragmentTable[1]; +} EFI_UDP4_TRANSMIT_DATA; + +typedef struct { + EFI_EVENT Event; + EFI_STATUS Status; + union { + EFI_UDP4_RECEIVE_DATA *RxData; + EFI_UDP4_TRANSMIT_DATA *TxData; + } Packet; +} EFI_UDP4_COMPLETION_TOKEN; + +typedef +EFI_STATUS +(EFIAPI *EFI_UDP4_TRANSMIT) ( + IN struct _EFI_UDP4 *This, + IN EFI_UDP4_COMPLETION_TOKEN *Token + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_UDP4_RECEIVE) ( + IN struct _EFI_UDP4 *This, + IN EFI_UDP4_COMPLETION_TOKEN *Token + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_UDP4_CANCEL)( + IN struct _EFI_UDP4 *This, + IN EFI_UDP4_COMPLETION_TOKEN *Token OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_UDP4_POLL) ( + IN struct _EFI_UDP4 *This + ); + +typedef struct _EFI_UDP4 { + EFI_UDP4_GET_MODE_DATA GetModeData; + EFI_UDP4_CONFIGURE Configure; + EFI_UDP4_GROUPS Groups; + EFI_UDP4_ROUTES Routes; + EFI_UDP4_TRANSMIT Transmit; + EFI_UDP4_RECEIVE Receive; + EFI_UDP4_CANCEL Cancel; + EFI_UDP4_POLL Poll; +} EFI_UDP4; + +typedef struct { + BOOLEAN AcceptPromiscuous; + BOOLEAN AcceptAnyPort; + BOOLEAN AllowDuplicatePort; + UINT8 TrafficClass; + UINT8 HopLimit; + UINT32 ReceiveTimeout; + UINT32 TransmitTimeout; + EFI_IPv6_ADDRESS StationAddress; + UINT16 StationPort; + EFI_IPv6_ADDRESS RemoteAddress; + UINT16 RemotePort; +} EFI_UDP6_CONFIG_DATA; + +typedef +EFI_STATUS +(EFIAPI *EFI_UDP6_GET_MODE_DATA) ( + IN struct _EFI_UDP6 *This, + OUT EFI_UDP6_CONFIG_DATA *Udp6ConfigData OPTIONAL, + OUT EFI_IP6_MODE_DATA *Ip6ModeData OPTIONAL, + OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL, + OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_UDP6_CONFIGURE) ( + IN struct _EFI_UDP6 *This, + IN EFI_UDP6_CONFIG_DATA *UdpConfigData OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_UDP6_GROUPS) ( + IN struct _EFI_UDP6 *This, + IN BOOLEAN JoinFlag, + IN EFI_IPv6_ADDRESS *MulticastAddress OPTIONAL + ); + +typedef struct { + EFI_IPv6_ADDRESS SourceAddress; + UINT16 SourcePort; + EFI_IPv6_ADDRESS DestinationAddress; + UINT16 DestinationPort; +} EFI_UDP6_SESSION_DATA; + +typedef struct { + UINT32 FragmentLength; + VOID *FragmentBuffer; +} EFI_UDP6_FRAGMENT_DATA; + +typedef struct { + EFI_TIME TimeStamp; + EFI_EVENT RecycleSignal; + EFI_UDP6_SESSION_DATA UdpSession; + UINT32 DataLength; + UINT32 FragmentCount; + EFI_UDP6_FRAGMENT_DATA FragmentTable[1]; +} EFI_UDP6_RECEIVE_DATA; + +typedef struct { + EFI_UDP6_SESSION_DATA *UdpSessionData; + UINT32 DataLength; + UINT32 FragmentCount; + EFI_UDP6_FRAGMENT_DATA FragmentTable[1]; +} EFI_UDP6_TRANSMIT_DATA; + +typedef struct { + EFI_EVENT Event; + EFI_STATUS Status; + union { + EFI_UDP6_RECEIVE_DATA *RxData; + EFI_UDP6_TRANSMIT_DATA *TxData; + } Packet; +} EFI_UDP6_COMPLETION_TOKEN; + +typedef +EFI_STATUS +(EFIAPI *EFI_UDP6_TRANSMIT) ( + IN struct _EFI_UDP6 *This, + IN EFI_UDP6_COMPLETION_TOKEN *Token + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_UDP6_RECEIVE) ( + IN struct _EFI_UDP6 *This, + IN EFI_UDP6_COMPLETION_TOKEN *Token + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_UDP6_CANCEL)( + IN struct _EFI_UDP6 *This, + IN EFI_UDP6_COMPLETION_TOKEN *Token OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_UDP6_POLL) ( + IN struct _EFI_UDP6 *This + ); + +typedef struct _EFI_UDP6 { + EFI_UDP6_GET_MODE_DATA GetModeData; + EFI_UDP6_CONFIGURE Configure; + EFI_UDP6_GROUPS Groups; + EFI_UDP6_TRANSMIT Transmit; + EFI_UDP6_RECEIVE Receive; + EFI_UDP6_CANCEL Cancel; + EFI_UDP6_POLL Poll; +} EFI_UDP6; + +#endif /* _EFI_UDP_H */ diff --git a/include/efiui.h b/include/efiui.h new file mode 100644 index 0000000..8935c49 --- /dev/null +++ b/include/efiui.h @@ -0,0 +1,58 @@ +#ifndef _EFI_UI_H +#define _EFI_UI_H + +/*++ + +Copyright (c) 200 Intel Corporation + +Module Name: + + EfiUi.h + +Abstract: + Protocol used to build User Interface (UI) stuff. + + This protocol is just data. It is a multi dimentional array. + For each string there is an array of UI_STRING_ENTRY. Each string + is for a different language translation of the same string. The list + is terminated by a NULL UiString. There can be any number of + UI_STRING_ENTRY arrays. A NULL array terminates the list. A NULL array + entry contains all zeros. + + Thus the shortest possible EFI_UI_PROTOCOL has three UI_STRING_ENTRY. + The String, it's NULL terminator, and the NULL terminator for the entire + thing. + + +Revision History + +--*/ + +#define EFI_UI_INTERFACE_PROTOCOL_GUID \ + { 0x32dd7981, 0x2d27, 0x11d4, {0xbc, 0x8b, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81} } +#define EFI_UI_PROTOCOL EFI_UI_INTERFACE_PROTOCOL_GUID + + +typedef enum { + UiDeviceString, + UiVendorString, + UiMaxString +} UI_STRING_TYPE; + +typedef struct { + ISO_639_2 *LangCode; + CHAR16 *UiString; +} UI_STRING_ENTRY; + +#define EFI_UI_INTERFACE_PROTOCOL_VERSION 0x00010000 +#define EFI_UI_VERSION EFI_UI_INTERFACE_PROTOCOL_VERSION + +typedef struct _EFI_UI_INTERFACE_PROTOCOL { + UINT32 Version; + UI_STRING_ENTRY *Entry; +} EFI_UI_INTERFACE_PROTOCOL; + +typedef struct _EFI_UI_INTERFACE_PROTOCOL _UI_INTERFACE; +typedef EFI_UI_INTERFACE_PROTOCOL UI_INTERFACE; + +#endif diff --git a/include/ia32/efibind.h b/include/ia32/efibind.h new file mode 100644 index 0000000..e337e77 --- /dev/null +++ b/include/ia32/efibind.h @@ -0,0 +1,294 @@ +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efefind.h + +Abstract: + + EFI to compile bindings + + + + +Revision History + +--*/ + +#ifndef __GNUC__ +#pragma pack() +#endif + +// +// Basic int types of various widths +// + +#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L ) && !defined(__cplusplus) + + // No ANSI C 1999/2000 stdint.h integer width declarations + + #if defined(_MSC_EXTENSIONS) + + // Use Microsoft C compiler integer width declarations + + typedef unsigned __int64 uint64_t; + typedef __int64 int64_t; + typedef unsigned __int32 uint32_t; + typedef __int32 int32_t; + typedef unsigned short uint16_t; + typedef short int16_t; + typedef unsigned char uint8_t; + typedef char int8_t; + #elif defined(__GNUC__) + typedef int __attribute__((__mode__(__DI__))) int64_t; + typedef unsigned int __attribute__((__mode__(__DI__))) uint64_t; + typedef unsigned int uint32_t; + typedef int int32_t; + typedef unsigned short uint16_t; + typedef short int16_t; + typedef unsigned char uint8_t; + typedef signed char int8_t; + #elif defined(UNIX_LP64) + + /* Use LP64 programming model from C_FLAGS for integer width declarations */ + + typedef unsigned long uint64_t; + typedef long int64_t; + typedef unsigned int uint32_t; + typedef int int32_t; + typedef unsigned short uint16_t; + typedef short int16_t; + typedef unsigned char uint8_t; + typedef char int8_t; + #else + + /* Assume P64 programming model from C_FLAGS for integer width declarations */ + + typedef unsigned long long uint64_t __attribute__((aligned (8))); + typedef long long int64_t __attribute__((aligned (8))); + typedef unsigned int uint32_t; + typedef int int32_t; + typedef unsigned short uint16_t; + typedef short int16_t; + typedef unsigned char uint8_t; + typedef char int8_t; + #endif + typedef uint32_t uintptr_t; + typedef int32_t intptr_t; +#elif defined(__GNUC__) + #include +#endif + +// +// Basic EFI types of various widths +// + +#include + +typedef wchar_t CHAR16; +#define WCHAR CHAR16 + + +typedef uint64_t UINT64; +typedef int64_t INT64; + +#ifndef _BASETSD_H_ + typedef uint32_t UINT32; + typedef int32_t INT32; +#endif + +typedef uint16_t UINT16; +typedef int16_t INT16; + +typedef uint8_t UINT8; +typedef char CHAR8; +typedef int8_t INT8; + +#undef VOID +typedef void VOID; + + +typedef int32_t INTN; +typedef uint32_t UINTN; + +#ifdef EFI_NT_EMULATOR + #define POST_CODE(_Data) +#else + #ifdef EFI_DEBUG +#define POST_CODE(_Data) __asm mov eax,(_Data) __asm out 0x80,al + #else + #define POST_CODE(_Data) + #endif +#endif + +#define EFIERR(a) (0x80000000 | a) +#define EFI_ERROR_MASK 0x80000000 +#define EFIERR_OEM(a) (0xc0000000 | a) + + +#define BAD_POINTER 0xFBFBFBFB +#define MAX_ADDRESS 0xFFFFFFFF + +#ifdef EFI_NT_EMULATOR + #define BREAKPOINT() __asm { int 3 } +#else + #define BREAKPOINT() while (TRUE); // Make it hang on Bios[Dbg]32 +#endif + +// +// Pointers must be aligned to these address to function +// + +#define MIN_ALIGNMENT_SIZE 4 + +#define ALIGN_VARIABLE(Value ,Adjustment) \ + (UINTN)Adjustment = 0; \ + if((UINTN)Value % MIN_ALIGNMENT_SIZE) \ + (UINTN)Adjustment = MIN_ALIGNMENT_SIZE - ((UINTN)Value % MIN_ALIGNMENT_SIZE); \ + Value = (UINTN)Value + (UINTN)Adjustment + + +// +// Define macros to build data structure signatures from characters. +// + +#define EFI_SIGNATURE_16(A,B) ((A) | (B<<8)) +#define EFI_SIGNATURE_32(A,B,C,D) (EFI_SIGNATURE_16(A,B) | (EFI_SIGNATURE_16(C,D) << 16)) +#define EFI_SIGNATURE_64(A,B,C,D,E,F,G,H) (EFI_SIGNATURE_32(A,B,C,D) | ((UINT64)(EFI_SIGNATURE_32(E,F,G,H)) << 32)) +// +// To export & import functions in the EFI emulator environment +// + +#ifdef EFI_NT_EMULATOR + #define EXPORTAPI __declspec( dllexport ) +#else + #define EXPORTAPI +#endif + + +// +// EFIAPI - prototype calling convention for EFI function pointers +// BOOTSERVICE - prototype for implementation of a boot service interface +// RUNTIMESERVICE - prototype for implementation of a runtime service interface +// RUNTIMEFUNCTION - prototype for implementation of a runtime function that is not a service +// RUNTIME_CODE - pragma macro for declaring runtime code +// + +#ifndef EFIAPI // Forces EFI calling conventions reguardless of compiler options + #ifdef _MSC_EXTENSIONS + #define EFIAPI __cdecl // Force C calling convention for Microsoft C compiler + #else + #define EFIAPI // Substitute expresion to force C calling convention + #endif +#endif + +#define BOOTSERVICE +//#define RUNTIMESERVICE(proto,a) alloc_text("rtcode",a); proto a +//#define RUNTIMEFUNCTION(proto,a) alloc_text("rtcode",a); proto a +#define RUNTIMESERVICE +#define RUNTIMEFUNCTION + + +#define RUNTIME_CODE(a) alloc_text("rtcode", a) +#define BEGIN_RUNTIME_DATA() data_seg("rtdata") +#define END_RUNTIME_DATA() data_seg("") + +#define VOLATILE volatile + +#define MEMORY_FENCE() + +#ifdef EFI_NT_EMULATOR + +// +// To help ensure proper coding of integrated drivers, they are +// compiled as DLLs. In NT they require a dll init entry pointer. +// The macro puts a stub entry point into the DLL so it will load. +// + +#define EFI_DRIVER_ENTRY_POINT(InitFunction) \ + UINTN \ + __stdcall \ + _DllMainCRTStartup ( \ + UINTN Inst, \ + UINTN reason_for_call, \ + VOID *rserved \ + ) \ + { \ + return 1; \ + } \ + \ + int \ + EXPORTAPI \ + __cdecl \ + InitializeDriver ( \ + void *ImageHandle, \ + void *SystemTable \ + ) \ + { \ + return InitFunction(ImageHandle, SystemTable); \ + } + + + #define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \ + (_if)->LoadInternal(type, name, NULL) + +#else // EFI_NT_EMULATOR + +// +// When build similiar to FW, then link everything together as +// one big module. For the MSVC toolchain, we simply tell the +// linker what our driver init function is using /ENTRY. +// +#if defined(_MSC_EXTENSIONS) + #define EFI_DRIVER_ENTRY_POINT(InitFunction) \ + __pragma(comment(linker, "/ENTRY:" # InitFunction)) +#else + #define EFI_DRIVER_ENTRY_POINT(InitFunction) \ + UINTN \ + InitializeDriver ( \ + VOID *ImageHandle, \ + VOID *SystemTable \ + ) \ + { \ + return InitFunction(ImageHandle, \ + SystemTable); \ + } \ + \ + EFI_STATUS efi_main( \ + EFI_HANDLE image, \ + EFI_SYSTEM_TABLE *systab \ + ) __attribute__((weak, \ + alias ("InitializeDriver"))); +#endif + + #define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \ + (_if)->LoadInternal(type, name, entry) + +#endif // EFI_FW_NT + +// +// Some compilers don't support the forward reference construct: +// typedef struct XXXXX +// +// The following macro provide a workaround for such cases. +// +#ifdef NO_INTERFACE_DECL +#define INTERFACE_DECL(x) +#else +#if defined(__GNUC__) || defined(_MSC_EXTENSIONS) +#define INTERFACE_DECL(x) struct x +#else +#define INTERFACE_DECL(x) typedef struct x +#endif +#endif + +/* No efi call wrapper for IA32 architecture */ +#define uefi_call_wrapper(func, va_num, ...) func(__VA_ARGS__) +#define EFI_FUNCTION + +#ifdef _MSC_EXTENSIONS +#pragma warning ( disable : 4731 ) // Suppress warnings about modification of EBP +#endif + diff --git a/include/ia32/efilibplat.h b/include/ia32/efilibplat.h new file mode 100644 index 0000000..fe6c831 --- /dev/null +++ b/include/ia32/efilibplat.h @@ -0,0 +1,26 @@ +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efilibplat.h + +Abstract: + + EFI to compile bindings + + + + +Revision History + +--*/ + +VOID +InitializeLibPlatform ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + + diff --git a/include/ia32/efisetjmp_arch.h b/include/ia32/efisetjmp_arch.h new file mode 100644 index 0000000..3b775e6 --- /dev/null +++ b/include/ia32/efisetjmp_arch.h @@ -0,0 +1,15 @@ +#ifndef GNU_EFI_IA32_SETJMP_H +#define GNU_EFI_IA32_SETJMP_H + +#define JMPBUF_ALIGN 4 + +typedef struct { + UINT32 Ebx; + UINT32 Esi; + UINT32 Edi; + UINT32 Ebp; + UINT32 Esp; + UINT32 Eip; +} EFI_ALIGN(JMPBUF_ALIGN) jmp_buf[1]; + +#endif /* GNU_EFI_IA32_SETJMP_H */ diff --git a/include/ia32/pe.h b/include/ia32/pe.h new file mode 100644 index 0000000..8c23d02 --- /dev/null +++ b/include/ia32/pe.h @@ -0,0 +1,595 @@ +/* + PE32+ header file + */ +#ifndef _PE_H +#define _PE_H + +#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ +#define IMAGE_OS2_SIGNATURE 0x454E // NE +#define IMAGE_OS2_SIGNATURE_LE 0x454C // LE +#define IMAGE_NT_SIGNATURE 0x00004550 // PE00 +#define IMAGE_EDOS_SIGNATURE 0x44454550 // PEED + + +typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header + UINT16 e_magic; // Magic number + UINT16 e_cblp; // Bytes on last page of file + UINT16 e_cp; // Pages in file + UINT16 e_crlc; // Relocations + UINT16 e_cparhdr; // Size of header in paragraphs + UINT16 e_minalloc; // Minimum extra paragraphs needed + UINT16 e_maxalloc; // Maximum extra paragraphs needed + UINT16 e_ss; // Initial (relative) SS value + UINT16 e_sp; // Initial SP value + UINT16 e_csum; // Checksum + UINT16 e_ip; // Initial IP value + UINT16 e_cs; // Initial (relative) CS value + UINT16 e_lfarlc; // File address of relocation table + UINT16 e_ovno; // Overlay number + UINT16 e_res[4]; // Reserved words + UINT16 e_oemid; // OEM identifier (for e_oeminfo) + UINT16 e_oeminfo; // OEM information; e_oemid specific + UINT16 e_res2[10]; // Reserved words + UINT32 e_lfanew; // File address of new exe header + } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; + +typedef struct _IMAGE_OS2_HEADER { // OS/2 .EXE header + UINT16 ne_magic; // Magic number + UINT8 ne_ver; // Version number + UINT8 ne_rev; // Revision number + UINT16 ne_enttab; // Offset of Entry Table + UINT16 ne_cbenttab; // Number of bytes in Entry Table + UINT32 ne_crc; // Checksum of whole file + UINT16 ne_flags; // Flag UINT16 + UINT16 ne_autodata; // Automatic data segment number + UINT16 ne_heap; // Initial heap allocation + UINT16 ne_stack; // Initial stack allocation + UINT32 ne_csip; // Initial CS:IP setting + UINT32 ne_sssp; // Initial SS:SP setting + UINT16 ne_cseg; // Count of file segments + UINT16 ne_cmod; // Entries in Module Reference Table + UINT16 ne_cbnrestab; // Size of non-resident name table + UINT16 ne_segtab; // Offset of Segment Table + UINT16 ne_rsrctab; // Offset of Resource Table + UINT16 ne_restab; // Offset of resident name table + UINT16 ne_modtab; // Offset of Module Reference Table + UINT16 ne_imptab; // Offset of Imported Names Table + UINT32 ne_nrestab; // Offset of Non-resident Names Table + UINT16 ne_cmovent; // Count of movable entries + UINT16 ne_align; // Segment alignment shift count + UINT16 ne_cres; // Count of resource segments + UINT8 ne_exetyp; // Target Operating system + UINT8 ne_flagsothers; // Other .EXE flags + UINT16 ne_pretthunks; // offset to return thunks + UINT16 ne_psegrefbytes; // offset to segment ref. bytes + UINT16 ne_swaparea; // Minimum code swap area size + UINT16 ne_expver; // Expected Windows version number + } IMAGE_OS2_HEADER, *PIMAGE_OS2_HEADER; + +// +// File header format. +// + +typedef struct _IMAGE_FILE_HEADER { + UINT16 Machine; + UINT16 NumberOfSections; + UINT32 TimeDateStamp; + UINT32 PointerToSymbolTable; + UINT32 NumberOfSymbols; + UINT16 SizeOfOptionalHeader; + UINT16 Characteristics; +} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; + +#define IMAGE_SIZEOF_FILE_HEADER 20 + +#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file. +#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references). +#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file. +#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file. +#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed. +#define IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine. +#define IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file +#define IMAGE_FILE_SYSTEM 0x1000 // System File. +#define IMAGE_FILE_DLL 0x2000 // File is a DLL. +#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed. + +#define IMAGE_FILE_MACHINE_UNKNOWN 0 +#define IMAGE_FILE_MACHINE_I386 0x14c // Intel 386. +#define IMAGE_FILE_MACHINE_R3000 0x162 // MIPS little-endian, 0540 big-endian +#define IMAGE_FILE_MACHINE_R4000 0x166 // MIPS little-endian +#define IMAGE_FILE_MACHINE_ALPHA 0x184 // Alpha_AXP +#define IMAGE_FILE_MACHINE_ARMTHUMB_MIXED 0x1c2 // Arm/Thumb +#define IMAGE_FILE_MACHINE_POWERPC 0x1F0 // IBM PowerPC Little-Endian +#define IMAGE_FILE_MACHINE_IA64 0x200 // IA-64 +#define IMAGE_FILE_MACHINE_TAHOE 0x7cc // Intel EM machine +#define IMAGE_FILE_MACHINE_EBC 0xebc // EFI Byte Code +#define IMAGE_FILE_MACHINE_X64 0x8664 // x86_64 +// +// Directory format. +// + +typedef struct _IMAGE_DATA_DIRECTORY { + UINT32 VirtualAddress; + UINT32 Size; +} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; + +#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 + +// +// Optional header format. +// + +typedef struct _IMAGE_OPTIONAL_HEADER { + // + // Standard fields. + // + + UINT16 Magic; + UINT8 MajorLinkerVersion; + UINT8 MinorLinkerVersion; + UINT32 SizeOfCode; + UINT32 SizeOfInitializedData; + UINT32 SizeOfUninitializedData; + UINT32 AddressOfEntryPoint; + UINT32 BaseOfCode; + UINT32 BaseOfData; + + // + // NT additional fields. + // + + UINT32 ImageBase; + UINT32 SectionAlignment; + UINT32 FileAlignment; + UINT16 MajorOperatingSystemVersion; + UINT16 MinorOperatingSystemVersion; + UINT16 MajorImageVersion; + UINT16 MinorImageVersion; + UINT16 MajorSubsystemVersion; + UINT16 MinorSubsystemVersion; + UINT32 Reserved1; + UINT32 SizeOfImage; + UINT32 SizeOfHeaders; + UINT32 CheckSum; + UINT16 Subsystem; + UINT16 DllCharacteristics; + UINT32 SizeOfStackReserve; + UINT32 SizeOfStackCommit; + UINT32 SizeOfHeapReserve; + UINT32 SizeOfHeapCommit; + UINT32 LoaderFlags; + UINT32 NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; +} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER; + +typedef struct _IMAGE_ROM_OPTIONAL_HEADER { + UINT16 Magic; + UINT8 MajorLinkerVersion; + UINT8 MinorLinkerVersion; + UINT32 SizeOfCode; + UINT32 SizeOfInitializedData; + UINT32 SizeOfUninitializedData; + UINT32 AddressOfEntryPoint; + UINT32 BaseOfCode; + UINT32 BaseOfData; + UINT32 BaseOfBss; + UINT32 GprMask; + UINT32 CprMask[4]; + UINT32 GpValue; +} IMAGE_ROM_OPTIONAL_HEADER, *PIMAGE_ROM_OPTIONAL_HEADER; + +#define IMAGE_SIZEOF_ROM_OPTIONAL_HEADER 56 +#define IMAGE_SIZEOF_STD_OPTIONAL_HEADER 28 +#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER 224 + +#define IMAGE_NT_OPTIONAL_HDR_MAGIC 0x10b +#define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107 + +typedef struct _IMAGE_NT_HEADERS { + UINT32 Signature; + IMAGE_FILE_HEADER FileHeader; + IMAGE_OPTIONAL_HEADER OptionalHeader; +} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS; + +typedef struct _IMAGE_ROM_HEADERS { + IMAGE_FILE_HEADER FileHeader; + IMAGE_ROM_OPTIONAL_HEADER OptionalHeader; +} IMAGE_ROM_HEADERS, *PIMAGE_ROM_HEADERS; + +#define IMAGE_FIRST_SECTION( ntheader ) ((PIMAGE_SECTION_HEADER) \ + ((UINT32)ntheader + \ + FIELD_OFFSET( IMAGE_NT_HEADERS, OptionalHeader ) + \ + ((PIMAGE_NT_HEADERS)(ntheader))->FileHeader.SizeOfOptionalHeader \ + )) + + +// Subsystem Values + +#define IMAGE_SUBSYSTEM_UNKNOWN 0 // Unknown subsystem. +#define IMAGE_SUBSYSTEM_NATIVE 1 // Image doesn't require a subsystem. +#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 // Image runs in the Windows GUI subsystem. +#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 // Image runs in the Windows character subsystem. +#define IMAGE_SUBSYSTEM_OS2_CUI 5 // image runs in the OS/2 character subsystem. +#define IMAGE_SUBSYSTEM_POSIX_CUI 7 // image run in the Posix character subsystem. + + +// Directory Entries + +#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory +#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory +#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory +#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory +#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory +#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table +#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory +#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // Description String +#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // Machine Value (MIPS GP) +#define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory +#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory + +// +// Section header format. +// + +#define IMAGE_SIZEOF_SHORT_NAME 8 + +typedef struct _IMAGE_SECTION_HEADER { + UINT8 Name[IMAGE_SIZEOF_SHORT_NAME]; + union { + UINT32 PhysicalAddress; + UINT32 VirtualSize; + } Misc; + UINT32 VirtualAddress; + UINT32 SizeOfRawData; + UINT32 PointerToRawData; + UINT32 PointerToRelocations; + UINT32 PointerToLinenumbers; + UINT16 NumberOfRelocations; + UINT16 NumberOfLinenumbers; + UINT32 Characteristics; +} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; + +#define IMAGE_SIZEOF_SECTION_HEADER 40 + +#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 // Reserved. + +#define IMAGE_SCN_CNT_CODE 0x00000020 // Section contains code. +#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 // Section contains initialized data. +#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 // Section contains uninitialized data. + +#define IMAGE_SCN_LNK_OTHER 0x00000100 // Reserved. +#define IMAGE_SCN_LNK_INFO 0x00000200 // Section contains comments or some other type of information. +#define IMAGE_SCN_LNK_REMOVE 0x00000800 // Section contents will not become part of image. +#define IMAGE_SCN_LNK_COMDAT 0x00001000 // Section contents comdat. + +#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 // +#define IMAGE_SCN_ALIGN_2BYTES 0x00200000 // +#define IMAGE_SCN_ALIGN_4BYTES 0x00300000 // +#define IMAGE_SCN_ALIGN_8BYTES 0x00400000 // +#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 // Default alignment if no others are specified. +#define IMAGE_SCN_ALIGN_32BYTES 0x00600000 // +#define IMAGE_SCN_ALIGN_64BYTES 0x00700000 // + +#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 // Section can be discarded. +#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 // Section is not cachable. +#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 // Section is not pageable. +#define IMAGE_SCN_MEM_SHARED 0x10000000 // Section is shareable. +#define IMAGE_SCN_MEM_EXECUTE 0x20000000 // Section is executable. +#define IMAGE_SCN_MEM_READ 0x40000000 // Section is readable. +#define IMAGE_SCN_MEM_WRITE 0x80000000 // Section is writeable. + +// +// Symbol format. +// + + +#define IMAGE_SIZEOF_SYMBOL 18 + +// +// Section values. +// +// Symbols have a section number of the section in which they are +// defined. Otherwise, section numbers have the following meanings: +// + +#define IMAGE_SYM_UNDEFINED (UINT16)0 // Symbol is undefined or is common. +#define IMAGE_SYM_ABSOLUTE (UINT16)-1 // Symbol is an absolute value. +#define IMAGE_SYM_DEBUG (UINT16)-2 // Symbol is a special debug item. + +// +// Type (fundamental) values. +// + +#define IMAGE_SYM_TYPE_NULL 0 // no type. +#define IMAGE_SYM_TYPE_VOID 1 // +#define IMAGE_SYM_TYPE_CHAR 2 // type character. +#define IMAGE_SYM_TYPE_SHORT 3 // type short integer. +#define IMAGE_SYM_TYPE_INT 4 // +#define IMAGE_SYM_TYPE_LONG 5 // +#define IMAGE_SYM_TYPE_FLOAT 6 // +#define IMAGE_SYM_TYPE_DOUBLE 7 // +#define IMAGE_SYM_TYPE_STRUCT 8 // +#define IMAGE_SYM_TYPE_UNION 9 // +#define IMAGE_SYM_TYPE_ENUM 10 // enumeration. +#define IMAGE_SYM_TYPE_MOE 11 // member of enumeration. +#define IMAGE_SYM_TYPE_BYTE 12 // +#define IMAGE_SYM_TYPE_WORD 13 // +#define IMAGE_SYM_TYPE_UINT 14 // +#define IMAGE_SYM_TYPE_DWORD 15 // + +// +// Type (derived) values. +// + +#define IMAGE_SYM_DTYPE_NULL 0 // no derived type. +#define IMAGE_SYM_DTYPE_POINTER 1 // pointer. +#define IMAGE_SYM_DTYPE_FUNCTION 2 // function. +#define IMAGE_SYM_DTYPE_ARRAY 3 // array. + +// +// Storage classes. +// + +#define IMAGE_SYM_CLASS_END_OF_FUNCTION (BYTE )-1 +#define IMAGE_SYM_CLASS_NULL 0 +#define IMAGE_SYM_CLASS_AUTOMATIC 1 +#define IMAGE_SYM_CLASS_EXTERNAL 2 +#define IMAGE_SYM_CLASS_STATIC 3 +#define IMAGE_SYM_CLASS_REGISTER 4 +#define IMAGE_SYM_CLASS_EXTERNAL_DEF 5 +#define IMAGE_SYM_CLASS_LABEL 6 +#define IMAGE_SYM_CLASS_UNDEFINED_LABEL 7 +#define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 8 +#define IMAGE_SYM_CLASS_ARGUMENT 9 +#define IMAGE_SYM_CLASS_STRUCT_TAG 10 +#define IMAGE_SYM_CLASS_MEMBER_OF_UNION 11 +#define IMAGE_SYM_CLASS_UNION_TAG 12 +#define IMAGE_SYM_CLASS_TYPE_DEFINITION 13 +#define IMAGE_SYM_CLASS_UNDEFINED_STATIC 14 +#define IMAGE_SYM_CLASS_ENUM_TAG 15 +#define IMAGE_SYM_CLASS_MEMBER_OF_ENUM 16 +#define IMAGE_SYM_CLASS_REGISTER_PARAM 17 +#define IMAGE_SYM_CLASS_BIT_FIELD 18 +#define IMAGE_SYM_CLASS_BLOCK 100 +#define IMAGE_SYM_CLASS_FUNCTION 101 +#define IMAGE_SYM_CLASS_END_OF_STRUCT 102 +#define IMAGE_SYM_CLASS_FILE 103 +// new +#define IMAGE_SYM_CLASS_SECTION 104 +#define IMAGE_SYM_CLASS_WEAK_EXTERNAL 105 + +// type packing constants + +#define N_BTMASK 017 +#define N_TMASK 060 +#define N_TMASK1 0300 +#define N_TMASK2 0360 +#define N_BTSHFT 4 +#define N_TSHIFT 2 + +// MACROS + +// +// Communal selection types. +// + +#define IMAGE_COMDAT_SELECT_NODUPLICATES 1 +#define IMAGE_COMDAT_SELECT_ANY 2 +#define IMAGE_COMDAT_SELECT_SAME_SIZE 3 +#define IMAGE_COMDAT_SELECT_EXACT_MATCH 4 +#define IMAGE_COMDAT_SELECT_ASSOCIATIVE 5 + +#define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1 +#define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2 +#define IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3 + + +// +// Relocation format. +// + +typedef struct _IMAGE_RELOCATION { + UINT32 VirtualAddress; + UINT32 SymbolTableIndex; + UINT16 Type; +} IMAGE_RELOCATION; + +#define IMAGE_SIZEOF_RELOCATION 10 + +// +// I386 relocation types. +// + +#define IMAGE_REL_I386_ABSOLUTE 0 // Reference is absolute, no relocation is necessary +#define IMAGE_REL_I386_DIR16 01 // Direct 16-bit reference to the symbols virtual address +#define IMAGE_REL_I386_REL16 02 // PC-relative 16-bit reference to the symbols virtual address +#define IMAGE_REL_I386_DIR32 06 // Direct 32-bit reference to the symbols virtual address +#define IMAGE_REL_I386_DIR32NB 07 // Direct 32-bit reference to the symbols virtual address, base not included +#define IMAGE_REL_I386_SEG12 011 // Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address +#define IMAGE_REL_I386_SECTION 012 +#define IMAGE_REL_I386_SECREL 013 +#define IMAGE_REL_I386_REL32 024 // PC-relative 32-bit reference to the symbols virtual address + +// +// MIPS relocation types. +// + +#define IMAGE_REL_MIPS_ABSOLUTE 0 // Reference is absolute, no relocation is necessary +#define IMAGE_REL_MIPS_REFHALF 01 +#define IMAGE_REL_MIPS_REFWORD 02 +#define IMAGE_REL_MIPS_JMPADDR 03 +#define IMAGE_REL_MIPS_REFHI 04 +#define IMAGE_REL_MIPS_REFLO 05 +#define IMAGE_REL_MIPS_GPREL 06 +#define IMAGE_REL_MIPS_LITERAL 07 +#define IMAGE_REL_MIPS_SECTION 012 +#define IMAGE_REL_MIPS_SECREL 013 +#define IMAGE_REL_MIPS_REFWORDNB 042 +#define IMAGE_REL_MIPS_PAIR 045 + +// +// Alpha Relocation types. +// + +#define IMAGE_REL_ALPHA_ABSOLUTE 0x0 +#define IMAGE_REL_ALPHA_REFLONG 0x1 +#define IMAGE_REL_ALPHA_REFQUAD 0x2 +#define IMAGE_REL_ALPHA_GPREL32 0x3 +#define IMAGE_REL_ALPHA_LITERAL 0x4 +#define IMAGE_REL_ALPHA_LITUSE 0x5 +#define IMAGE_REL_ALPHA_GPDISP 0x6 +#define IMAGE_REL_ALPHA_BRADDR 0x7 +#define IMAGE_REL_ALPHA_HINT 0x8 +#define IMAGE_REL_ALPHA_INLINE_REFLONG 0x9 +#define IMAGE_REL_ALPHA_REFHI 0xA +#define IMAGE_REL_ALPHA_REFLO 0xB +#define IMAGE_REL_ALPHA_PAIR 0xC +#define IMAGE_REL_ALPHA_MATCH 0xD +#define IMAGE_REL_ALPHA_SECTION 0xE +#define IMAGE_REL_ALPHA_SECREL 0xF +#define IMAGE_REL_ALPHA_REFLONGNB 0x10 + +// +// IBM PowerPC relocation types. +// + +#define IMAGE_REL_PPC_ABSOLUTE 0x0000 // NOP +#define IMAGE_REL_PPC_ADDR64 0x0001 // 64-bit address +#define IMAGE_REL_PPC_ADDR32 0x0002 // 32-bit address +#define IMAGE_REL_PPC_ADDR24 0x0003 // 26-bit address, shifted left 2 (branch absolute) +#define IMAGE_REL_PPC_ADDR16 0x0004 // 16-bit address +#define IMAGE_REL_PPC_ADDR14 0x0005 // 16-bit address, shifted left 2 (load doubleword) +#define IMAGE_REL_PPC_REL24 0x0006 // 26-bit PC-relative offset, shifted left 2 (branch relative) +#define IMAGE_REL_PPC_REL14 0x0007 // 16-bit PC-relative offset, shifted left 2 (br cond relative) +#define IMAGE_REL_PPC_TOCREL16 0x0008 // 16-bit offset from TOC base +#define IMAGE_REL_PPC_TOCREL14 0x0009 // 16-bit offset from TOC base, shifted left 2 (load doubleword) + +#define IMAGE_REL_PPC_ADDR32NB 0x000A // 32-bit addr w/o image base +#define IMAGE_REL_PPC_SECREL 0x000B // va of containing section (as in an image sectionhdr) +#define IMAGE_REL_PPC_SECTION 0x000C // sectionheader number +#define IMAGE_REL_PPC_IFGLUE 0x000D // substitute TOC restore instruction iff symbol is glue code +#define IMAGE_REL_PPC_IMGLUE 0x000E // symbol is glue code; virtual address is TOC restore instruction + +#define IMAGE_REL_PPC_TYPEMASK 0x00FF // mask to isolate above values in IMAGE_RELOCATION.Type + +// Flag bits in IMAGE_RELOCATION.TYPE + +#define IMAGE_REL_PPC_NEG 0x0100 // subtract reloc value rather than adding it +#define IMAGE_REL_PPC_BRTAKEN 0x0200 // fix branch prediction bit to predict branch taken +#define IMAGE_REL_PPC_BRNTAKEN 0x0400 // fix branch prediction bit to predict branch not taken +#define IMAGE_REL_PPC_TOCDEFN 0x0800 // toc slot defined in file (or, data in toc) + +// +// Based relocation format. +// + +typedef struct _IMAGE_BASE_RELOCATION { + UINT32 VirtualAddress; + UINT32 SizeOfBlock; +// UINT16 TypeOffset[1]; +} IMAGE_BASE_RELOCATION, *PIMAGE_BASE_RELOCATION; + +#define IMAGE_SIZEOF_BASE_RELOCATION 8 + +// +// Based relocation types. +// + +#define IMAGE_REL_BASED_ABSOLUTE 0 +#define IMAGE_REL_BASED_HIGH 1 +#define IMAGE_REL_BASED_LOW 2 +#define IMAGE_REL_BASED_HIGHLOW 3 +#define IMAGE_REL_BASED_HIGHADJ 4 +#define IMAGE_REL_BASED_MIPS_JMPADDR 5 +#define IMAGE_REL_BASED_IA64_IMM64 9 +#define IMAGE_REL_BASED_DIR64 10 + +// +// Line number format. +// + +typedef struct _IMAGE_LINENUMBER { + union { + UINT32 SymbolTableIndex; // Symbol table index of function name if Linenumber is 0. + UINT32 VirtualAddress; // Virtual address of line number. + } Type; + UINT16 Linenumber; // Line number. +} IMAGE_LINENUMBER; + +#define IMAGE_SIZEOF_LINENUMBER 6 + +// +// Archive format. +// + +#define IMAGE_ARCHIVE_START_SIZE 8 +#define IMAGE_ARCHIVE_START "!\n" +#define IMAGE_ARCHIVE_END "`\n" +#define IMAGE_ARCHIVE_PAD "\n" +#define IMAGE_ARCHIVE_LINKER_MEMBER "/ " +#define IMAGE_ARCHIVE_LONGNAMES_MEMBER "// " + +typedef struct _IMAGE_ARCHIVE_MEMBER_HEADER { + UINT8 Name[16]; // File member name - `/' terminated. + UINT8 Date[12]; // File member date - decimal. + UINT8 UserID[6]; // File member user id - decimal. + UINT8 GroupID[6]; // File member group id - decimal. + UINT8 Mode[8]; // File member mode - octal. + UINT8 Size[10]; // File member size - decimal. + UINT8 EndHeader[2]; // String to end header. +} IMAGE_ARCHIVE_MEMBER_HEADER, *PIMAGE_ARCHIVE_MEMBER_HEADER; + +#define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60 + +// +// DLL support. +// + +// +// Export Format +// + +typedef struct _IMAGE_EXPORT_DIRECTORY { + UINT32 Characteristics; + UINT32 TimeDateStamp; + UINT16 MajorVersion; + UINT16 MinorVersion; + UINT32 Name; + UINT32 Base; + UINT32 NumberOfFunctions; + UINT32 NumberOfNames; + UINT32 *AddressOfFunctions; + UINT32 *AddressOfNames; + UINT32 *AddressOfNameOrdinals; +} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY; + +// +// Import Format +// + +typedef struct _IMAGE_IMPORT_BY_NAME { + UINT16 Hint; + UINT8 Name[1]; +} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME; + +typedef struct _IMAGE_THUNK_DATA { + union { + UINT32 Function; + UINT32 Ordinal; + PIMAGE_IMPORT_BY_NAME AddressOfData; + } u1; +} IMAGE_THUNK_DATA, *PIMAGE_THUNK_DATA; + +#define IMAGE_ORDINAL_FLAG 0x80000000 +#define IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG) != 0) +#define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff) + +typedef struct _IMAGE_IMPORT_DESCRIPTOR { + UINT32 Characteristics; + UINT32 TimeDateStamp; + UINT32 ForwarderChain; + UINT32 Name; + PIMAGE_THUNK_DATA FirstThunk; +} IMAGE_IMPORT_DESCRIPTOR, *PIMAGE_IMPORT_DESCRIPTOR; + +#endif diff --git a/include/ia64/efibind.h b/include/ia64/efibind.h new file mode 100644 index 0000000..5b7806e --- /dev/null +++ b/include/ia64/efibind.h @@ -0,0 +1,236 @@ +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efefind.h + +Abstract: + + EFI to compile bindings + + + + +Revision History + +--*/ + +#pragma pack() + + +// +// Basic int types of various widths +// + +#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L ) && !defined(__cplusplus) + + // No ANSI C 1999/2000 stdint.h integer width declarations + + #ifdef _MSC_EXTENSIONS + // Use Microsoft C compiler integer width declarations + + typedef unsigned __int64 uint64_t; + typedef __int64 int64_t; + typedef unsigned __int32 uint32_t; + typedef __int32 int32_t; + typedef unsigned __int16 uint16_t; + typedef __int16 int16_t; + typedef unsigned __int8 uint8_t; + typedef __int8 int8_t; + #elif defined(UNIX_LP64) + // Use LP64 programming model from C_FLAGS for integer width declarations + + typedef unsigned long uint64_t; + typedef long int64_t; + typedef unsigned int uint32_t; + typedef int int32_t; + typedef unsigned short uint16_t; + typedef short int16_t; + typedef unsigned char uint8_t; + typedef char int8_t; + #else + // Assume P64 programming model from C_FLAGS for integer width declarations + + typedef unsigned long long uint64_t; + typedef long long int64_t; + typedef unsigned int uint32_t; + typedef int int32_t; + typedef unsigned short uint16_t; + typedef short int16_t; + typedef unsigned char uint8_t; + typedef char int8_t; + #endif + typedef uint64_t uintptr_t; + typedef int64_t intptr_t; +#elif defined(__GNUC__) + #include +#endif + +// +// Basic EFI types of various widths +// + +#include + +typedef wchar_t CHAR16; +#define WCHAR CHAR16 + +typedef uint64_t UINT64; +typedef int64_t INT64; + +typedef uint32_t UINT32; +typedef int32_t INT32; + +typedef uint16_t UINT16; +typedef int16_t INT16; + +typedef uint8_t UINT8; +typedef char CHAR8; +typedef int8_t INT8; + +#undef VOID +typedef void VOID; + + +typedef int64_t INTN; +typedef uint64_t UINTN; + +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// BugBug: Code to debug +// +#define BIT63 0x8000000000000000 + +#define PLATFORM_IOBASE_ADDRESS (0xffffc000000 | BIT63) +#define PORT_TO_MEMD(_Port) (PLATFORM_IOBASE_ADDRESS | ( ( ( (_Port) & 0xfffc) << 10 ) | ( (_Port) & 0x0fff) ) ) + +// +// Macro's with casts make this much easier to use and read. +// +#define PORT_TO_MEM8D(_Port) (*(UINT8 *)(PORT_TO_MEMD(_Port))) +#define POST_CODE(_Data) (PORT_TO_MEM8D(0x80) = (_Data)) +// +// BugBug: End Debug Code!!! +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +#define EFIERR(a) (0x8000000000000000 | a) +#define EFI_ERROR_MASK 0x8000000000000000 +#define EFIERR_OEM(a) (0xc000000000000000 | a) + +#define BAD_POINTER 0xFBFBFBFBFBFBFBFB +#define MAX_ADDRESS 0xFFFFFFFFFFFFFFFF + +#define BREAKPOINT() while (TRUE) + +// +// Pointers must be aligned to these address to function +// you will get an alignment fault if this value is less than 8 +// +#define MIN_ALIGNMENT_SIZE 8 + +#define ALIGN_VARIABLE(Value , Adjustment) \ + (UINTN) Adjustment = 0; \ + if((UINTN)Value % MIN_ALIGNMENT_SIZE) \ + (UINTN)Adjustment = MIN_ALIGNMENT_SIZE - ((UINTN)Value % MIN_ALIGNMENT_SIZE); \ + Value = (UINTN)Value + (UINTN)Adjustment + +// +// Define macros to create data structure signatures. +// + +#define EFI_SIGNATURE_16(A,B) ((A) | (B<<8)) +#define EFI_SIGNATURE_32(A,B,C,D) (EFI_SIGNATURE_16(A,B) | (EFI_SIGNATURE_16(C,D) << 16)) +#define EFI_SIGNATURE_64(A,B,C,D,E,F,G,H) (EFI_SIGNATURE_32(A,B,C,D) | ((UINT64)(EFI_SIGNATURE_32(E,F,G,H)) << 32)) +// +// To export & import functions in the EFI emulator environment +// + + #define EXPORTAPI + +// +// EFIAPI - prototype calling convention for EFI function pointers +// BOOTSERVICE - prototype for implementation of a boot service interface +// RUNTIMESERVICE - prototype for implementation of a runtime service interface +// RUNTIMEFUNCTION - prototype for implementation of a runtime function that is not a service +// RUNTIME_CODE - pragma macro for declaring runtime code +// + +#ifndef EFIAPI // Forces EFI calling conventions reguardless of compiler options + #ifdef _MSC_EXTENSIONS + #define EFIAPI __cdecl // Force C calling convention for Microsoft C compiler + #else + #define EFIAPI // Substitute expresion to force C calling convention + #endif +#endif + +#define BOOTSERVICE +#define RUNTIMESERVICE +#define RUNTIMEFUNCTION + +#define RUNTIME_CODE(a) alloc_text("rtcode", a) +#define BEGIN_RUNTIME_DATA() data_seg("rtdata") +#define END_RUNTIME_DATA() data_seg("") + +#define VOLATILE volatile + +// +// BugBug: Need to find out if this is portable accross compliers. +// +#ifdef __GNUC__ +#define MEMORY_FENCE() __asm__ __volatile__ ("mf.a" ::: "memory") +#else +void __mf (void); +#pragma intrinsic (__mf) +#define MEMORY_FENCE() __mf() +#endif + +// +// When build similiar to FW, then link everything together as +// one big module. For the MSVC toolchain, we simply tell the +// linker what our driver init function is using /ENTRY. +// +#if defined(_MSC_EXTENSIONS) + #define EFI_DRIVER_ENTRY_POINT(InitFunction) \ + __pragma(comment(linker, "/ENTRY:" # InitFunction)) +#else + #define EFI_DRIVER_ENTRY_POINT(InitFunction) \ + UINTN \ + InitializeDriver ( \ + VOID *ImageHandle, \ + VOID *SystemTable \ + ) \ + { \ + return InitFunction(ImageHandle, \ + SystemTable); \ + } \ + \ + EFI_STATUS efi_main( \ + EFI_HANDLE image, \ + EFI_SYSTEM_TABLE *systab \ + ) __attribute__((weak, \ + alias ("InitializeDriver"))); +#endif + +#define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \ + (_if)->LoadInternal(type, name, entry) + +// +// Some compilers don't support the forward reference construct: +// typedef struct XXXXX +// +// The following macro provide a workaround for such cases. +// +#ifdef NO_INTERFACE_DECL +#define INTERFACE_DECL(x) +#else +#if defined(__GNUC__) || defined(_MSC_EXTENSIONS) +#define INTERFACE_DECL(x) struct x +#else +#define INTERFACE_DECL(x) typedef struct x +#endif +#endif + +/* No efi call wrapper for IA32 architecture */ +#define uefi_call_wrapper(func, va_num, ...) func(__VA_ARGS__) +#define EFI_FUNCTION diff --git a/include/ia64/efilibplat.h b/include/ia64/efilibplat.h new file mode 100644 index 0000000..5ba95a3 --- /dev/null +++ b/include/ia64/efilibplat.h @@ -0,0 +1,80 @@ +#ifndef _EFI_LIB_PLAT_H +#define _EFI_LIB_PLAT_H +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efilibplat.h + +Abstract: + + EFI to compile bindings + + + +Revision History + +--*/ + +#include "salproc.h" + + +VOID +InitializeLibPlatform ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +VOID +LibInitSalAndPalProc( + OUT PLABEL *SalPlabel, + OUT UINT64 *PalEntry + ); + +EFI_STATUS +LibGetSalIoPortMapping ( + OUT UINT64 *IoPortMapping + ); + +EFI_STATUS +LibGetSalIpiBlock ( + OUT UINT64 *IpiBlock + ); + +EFI_STATUS +LibGetSalWakeupVector ( + OUT UINT64 *WakeVector + ); + +VOID * +LibSearchSalSystemTable ( + IN UINT8 EntryType + ); + + +VOID +LibSalProc ( + IN UINT64 Arg1, + IN UINT64 Arg2, + IN UINT64 Arg3, + IN UINT64 Arg4, + IN UINT64 Arg5, + IN UINT64 Arg6, + IN UINT64 Arg7, + IN UINT64 Arg8, + OUT rArg *Results OPTIONAL + ); + +VOID +LibPalProc ( + IN UINT64 Arg1, + IN UINT64 Arg2, + IN UINT64 Arg3, + IN UINT64 Arg4, + OUT rArg *Results OPTIONAL + ); + +#endif + diff --git a/include/ia64/efisetjmp_arch.h b/include/ia64/efisetjmp_arch.h new file mode 100644 index 0000000..da264fa --- /dev/null +++ b/include/ia64/efisetjmp_arch.h @@ -0,0 +1,47 @@ +#ifndef GNU_EFI_IA64_SETJMP_H +#define GNU_EFI_IA64_SETJMP_H + +#define JMPBUF_ALIGN 0x10 + +typedef struct { + UINT64 F2[2]; + UINT64 F3[2]; + UINT64 F4[2]; + UINT64 F5[2]; + UINT64 F16[2]; + UINT64 F17[2]; + UINT64 F18[2]; + UINT64 F19[2]; + UINT64 F20[2]; + UINT64 F21[2]; + UINT64 F22[2]; + UINT64 F23[2]; + UINT64 F24[2]; + UINT64 F25[2]; + UINT64 F26[2]; + UINT64 F27[2]; + UINT64 F28[2]; + UINT64 F29[2]; + UINT64 F30[2]; + UINT64 F31[2]; + UINT64 R4; + UINT64 R5; + UINT64 R6; + UINT64 R7; + UINT64 SP; + UINT64 BR0; + UINT64 BR1; + UINT64 BR2; + UINT64 BR3; + UINT64 BR4; + UINT64 BR5; + UINT64 InitialUNAT; + UINT64 AfterSpillUNAT; + UINT64 PFS; + UINT64 BSP; + UINT64 Predicates; + UINT64 LoopCount; + UINT64 FPSR; +} EFI_ALIGN(JMPBUF_ALIGN) jmp_buf[1]; + +#endif /* GNU_EFI_IA64_SETJMP_H */ diff --git a/include/ia64/pe.h b/include/ia64/pe.h new file mode 100644 index 0000000..4646b80 --- /dev/null +++ b/include/ia64/pe.h @@ -0,0 +1,601 @@ +/* + PE32+ header file + */ +#ifndef _PE_H +#define _PE_H + +#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ +#define IMAGE_OS2_SIGNATURE 0x454E // NE +#define IMAGE_OS2_SIGNATURE_LE 0x454C // LE +#define IMAGE_NT_SIGNATURE 0x00004550 // PE00 +#define IMAGE_EDOS_SIGNATURE 0x44454550 // PEED + +/***************************************************************************** + * The following stuff comes from winnt.h from the ia64sdk, plus the Plabel for + * loading EM executables. + *****************************************************************************/ +// +// Intel IA64 specific +// + +#define IMAGE_REL_BASED_IA64_IMM64 9 +#define IMAGE_REL_BASED_IA64_DIR64 10 + +struct Plabel { + UINT64 EntryPoint; + UINT64 NewGP; +}; + +typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header + UINT16 e_magic; // Magic number + UINT16 e_cblp; // Bytes on last page of file + UINT16 e_cp; // Pages in file + UINT16 e_crlc; // Relocations + UINT16 e_cparhdr; // Size of header in paragraphs + UINT16 e_minalloc; // Minimum extra paragraphs needed + UINT16 e_maxalloc; // Maximum extra paragraphs needed + UINT16 e_ss; // Initial (relative) SS value + UINT16 e_sp; // Initial SP value + UINT16 e_csum; // Checksum + UINT16 e_ip; // Initial IP value + UINT16 e_cs; // Initial (relative) CS value + UINT16 e_lfarlc; // File address of relocation table + UINT16 e_ovno; // Overlay number + UINT16 e_res[4]; // Reserved words + UINT16 e_oemid; // OEM identifier (for e_oeminfo) + UINT16 e_oeminfo; // OEM information; e_oemid specific + UINT16 e_res2[10]; // Reserved words + UINT32 e_lfanew; // File address of new exe header + } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; + +typedef struct _IMAGE_OS2_HEADER { // OS/2 .EXE header + UINT16 ne_magic; // Magic number + UINT8 ne_ver; // Version number + UINT8 ne_rev; // Revision number + UINT16 ne_enttab; // Offset of Entry Table + UINT16 ne_cbenttab; // Number of bytes in Entry Table + UINT32 ne_crc; // Checksum of whole file + UINT16 ne_flags; // Flag UINT16 + UINT16 ne_autodata; // Automatic data segment number + UINT16 ne_heap; // Initial heap allocation + UINT16 ne_stack; // Initial stack allocation + UINT32 ne_csip; // Initial CS:IP setting + UINT32 ne_sssp; // Initial SS:SP setting + UINT16 ne_cseg; // Count of file segments + UINT16 ne_cmod; // Entries in Module Reference Table + UINT16 ne_cbnrestab; // Size of non-resident name table + UINT16 ne_segtab; // Offset of Segment Table + UINT16 ne_rsrctab; // Offset of Resource Table + UINT16 ne_restab; // Offset of resident name table + UINT16 ne_modtab; // Offset of Module Reference Table + UINT16 ne_imptab; // Offset of Imported Names Table + UINT32 ne_nrestab; // Offset of Non-resident Names Table + UINT16 ne_cmovent; // Count of movable entries + UINT16 ne_align; // Segment alignment shift count + UINT16 ne_cres; // Count of resource segments + UINT8 ne_exetyp; // Target Operating system + UINT8 ne_flagsothers; // Other .EXE flags + UINT16 ne_pretthunks; // offset to return thunks + UINT16 ne_psegrefbytes; // offset to segment ref. bytes + UINT16 ne_swaparea; // Minimum code swap area size + UINT16 ne_expver; // Expected Windows version number + } IMAGE_OS2_HEADER, *PIMAGE_OS2_HEADER; + +// +// File header format. +// + +typedef struct _IMAGE_FILE_HEADER { + UINT16 Machine; + UINT16 NumberOfSections; + UINT32 TimeDateStamp; + UINT32 PointerToSymbolTable; + UINT32 NumberOfSymbols; + UINT16 SizeOfOptionalHeader; + UINT16 Characteristics; +} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; + +#define IMAGE_SIZEOF_FILE_HEADER 20 + +#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file. +#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references). +#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file. +#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file. +#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed. +#define IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine. +#define IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file +#define IMAGE_FILE_SYSTEM 0x1000 // System File. +#define IMAGE_FILE_DLL 0x2000 // File is a DLL. +#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed. + +#define IMAGE_FILE_MACHINE_UNKNOWN 0 +#define IMAGE_FILE_MACHINE_I386 0x14c // Intel 386. +#define IMAGE_FILE_MACHINE_R3000 0x162 // MIPS little-endian, 0540 big-endian +#define IMAGE_FILE_MACHINE_R4000 0x166 // MIPS little-endian +#define IMAGE_FILE_MACHINE_ALPHA 0x184 // Alpha_AXP +#define IMAGE_FILE_MACHINE_ARMTHUMB_MIXED 0x1c2 // Arm/Thumb +#define IMAGE_FILE_MACHINE_POWERPC 0x1F0 // IBM PowerPC Little-Endian +#define IMAGE_FILE_MACHINE_IA64 0x200 // IA-64 +#define IMAGE_FILE_MACHINE_TAHOE 0x7cc // Intel EM machine +#define IMAGE_FILE_MACHINE_EBC 0xebc // EFI Byte Code +#define IMAGE_FILE_MACHINE_X64 0x8664 // x86_64 +// +// Directory format. +// + +typedef struct _IMAGE_DATA_DIRECTORY { + UINT32 VirtualAddress; + UINT32 Size; +} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; + +#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 + + +typedef struct _IMAGE_ROM_OPTIONAL_HEADER { + UINT16 Magic; + UINT8 MajorLinkerVersion; + UINT8 MinorLinkerVersion; + UINT32 SizeOfCode; + UINT32 SizeOfInitializedData; + UINT32 SizeOfUninitializedData; + UINT32 AddressOfEntryPoint; + UINT32 BaseOfCode; + UINT32 BaseOfData; + UINT32 BaseOfBss; + UINT32 GprMask; + UINT32 CprMask[4]; + UINT32 GpValue; +} IMAGE_ROM_OPTIONAL_HEADER, *PIMAGE_ROM_OPTIONAL_HEADER; + +typedef struct _IMAGE_OPTIONAL_HEADER { + UINT16 Magic; + UINT8 MajorLinkerVersion; + UINT8 MinorLinkerVersion; + UINT32 SizeOfCode; + UINT32 SizeOfInitializedData; + UINT32 SizeOfUninitializedData; + UINT32 AddressOfEntryPoint; + UINT32 BaseOfCode; + // UINT32 BaseOfData; + UINT64 ImageBase; + UINT32 SectionAlignment; + UINT32 FileAlignment; + UINT16 MajorOperatingSystemVersion; + UINT16 MinorOperatingSystemVersion; + UINT16 MajorImageVersion; + UINT16 MinorImageVersion; + UINT16 MajorSubsystemVersion; + UINT16 MinorSubsystemVersion; + UINT32 Win32VersionValue; + UINT32 SizeOfImage; + UINT32 SizeOfHeaders; + UINT32 CheckSum; + UINT16 Subsystem; + UINT16 DllCharacteristics; + UINT64 SizeOfStackReserve; + UINT64 SizeOfStackCommit; + UINT64 SizeOfHeapReserve; + UINT64 SizeOfHeapCommit; + UINT32 LoaderFlags; + UINT32 NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; +} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER; + + +#define IMAGE_SIZEOF_ROM_OPTIONAL_HEADER 56 +#define IMAGE_SIZEOF_STD_OPTIONAL_HEADER 28 +#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER 224 +#define IMAGE_SIZEOF_NT_OPTIONAL64_HEADER 244 + +#define IMAGE_NT_OPTIONAL_HDR_MAGIC 0x10b +#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b +#define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107 + +typedef struct _IMAGE_NT_HEADERS { + UINT32 Signature; + IMAGE_FILE_HEADER FileHeader; + IMAGE_OPTIONAL_HEADER OptionalHeader; +} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS; + +typedef struct _IMAGE_ROM_HEADERS { + IMAGE_FILE_HEADER FileHeader; + IMAGE_ROM_OPTIONAL_HEADER OptionalHeader; +} IMAGE_ROM_HEADERS, *PIMAGE_ROM_HEADERS; + +#define IMAGE_FIRST_SECTION( ntheader ) ((PIMAGE_SECTION_HEADER) \ + ((UINT32)ntheader + \ + FIELD_OFFSET( IMAGE_NT_HEADERS, OptionalHeader ) + \ + ((PIMAGE_NT_HEADERS)(ntheader))->FileHeader.SizeOfOptionalHeader \ + )) + + +// Subsystem Values + +#define IMAGE_SUBSYSTEM_UNKNOWN 0 // Unknown subsystem. +#define IMAGE_SUBSYSTEM_NATIVE 1 // Image doesn't require a subsystem. +#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 // Image runs in the Windows GUI subsystem. +#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 // Image runs in the Windows character subsystem. +#define IMAGE_SUBSYSTEM_OS2_CUI 5 // image runs in the OS/2 character subsystem. +#define IMAGE_SUBSYSTEM_POSIX_CUI 7 // image run in the Posix character subsystem. + + +// Directory Entries + +#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory +#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory +#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory +#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory +#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory +#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table +#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory +#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // Description String +#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // Machine Value (MIPS GP) +#define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory +#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory + +// +// Section header format. +// + +#define IMAGE_SIZEOF_SHORT_NAME 8 + +typedef struct _IMAGE_SECTION_HEADER { + UINT8 Name[IMAGE_SIZEOF_SHORT_NAME]; + union { + UINT32 PhysicalAddress; + UINT32 VirtualSize; + } Misc; + UINT32 VirtualAddress; + UINT32 SizeOfRawData; + UINT32 PointerToRawData; + UINT32 PointerToRelocations; + UINT32 PointerToLinenumbers; + UINT16 NumberOfRelocations; + UINT16 NumberOfLinenumbers; + UINT32 Characteristics; +} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; + +#define IMAGE_SIZEOF_SECTION_HEADER 40 + +#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 // Reserved. + +#define IMAGE_SCN_CNT_CODE 0x00000020 // Section contains code. +#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 // Section contains initialized data. +#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 // Section contains uninitialized data. + +#define IMAGE_SCN_LNK_OTHER 0x00000100 // Reserved. +#define IMAGE_SCN_LNK_INFO 0x00000200 // Section contains comments or some other type of information. +#define IMAGE_SCN_LNK_REMOVE 0x00000800 // Section contents will not become part of image. +#define IMAGE_SCN_LNK_COMDAT 0x00001000 // Section contents comdat. + +#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 // +#define IMAGE_SCN_ALIGN_2BYTES 0x00200000 // +#define IMAGE_SCN_ALIGN_4BYTES 0x00300000 // +#define IMAGE_SCN_ALIGN_8BYTES 0x00400000 // +#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 // Default alignment if no others are specified. +#define IMAGE_SCN_ALIGN_32BYTES 0x00600000 // +#define IMAGE_SCN_ALIGN_64BYTES 0x00700000 // + +#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 // Section can be discarded. +#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 // Section is not cachable. +#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 // Section is not pageable. +#define IMAGE_SCN_MEM_SHARED 0x10000000 // Section is shareable. +#define IMAGE_SCN_MEM_EXECUTE 0x20000000 // Section is executable. +#define IMAGE_SCN_MEM_READ 0x40000000 // Section is readable. +#define IMAGE_SCN_MEM_WRITE 0x80000000 // Section is writeable. + +// +// Symbol format. +// + + +#define IMAGE_SIZEOF_SYMBOL 18 + +// +// Section values. +// +// Symbols have a section number of the section in which they are +// defined. Otherwise, section numbers have the following meanings: +// + +#define IMAGE_SYM_UNDEFINED (UINT16)0 // Symbol is undefined or is common. +#define IMAGE_SYM_ABSOLUTE (UINT16)-1 // Symbol is an absolute value. +#define IMAGE_SYM_DEBUG (UINT16)-2 // Symbol is a special debug item. + +// +// Type (fundamental) values. +// + +#define IMAGE_SYM_TYPE_NULL 0 // no type. +#define IMAGE_SYM_TYPE_VOID 1 // +#define IMAGE_SYM_TYPE_CHAR 2 // type character. +#define IMAGE_SYM_TYPE_SHORT 3 // type short integer. +#define IMAGE_SYM_TYPE_INT 4 // +#define IMAGE_SYM_TYPE_LONG 5 // +#define IMAGE_SYM_TYPE_FLOAT 6 // +#define IMAGE_SYM_TYPE_DOUBLE 7 // +#define IMAGE_SYM_TYPE_STRUCT 8 // +#define IMAGE_SYM_TYPE_UNION 9 // +#define IMAGE_SYM_TYPE_ENUM 10 // enumeration. +#define IMAGE_SYM_TYPE_MOE 11 // member of enumeration. +#define IMAGE_SYM_TYPE_BYTE 12 // +#define IMAGE_SYM_TYPE_WORD 13 // +#define IMAGE_SYM_TYPE_UINT 14 // +#define IMAGE_SYM_TYPE_DWORD 15 // + +// +// Type (derived) values. +// + +#define IMAGE_SYM_DTYPE_NULL 0 // no derived type. +#define IMAGE_SYM_DTYPE_POINTER 1 // pointer. +#define IMAGE_SYM_DTYPE_FUNCTION 2 // function. +#define IMAGE_SYM_DTYPE_ARRAY 3 // array. + +// +// Storage classes. +// + +#define IMAGE_SYM_CLASS_END_OF_FUNCTION (BYTE )-1 +#define IMAGE_SYM_CLASS_NULL 0 +#define IMAGE_SYM_CLASS_AUTOMATIC 1 +#define IMAGE_SYM_CLASS_EXTERNAL 2 +#define IMAGE_SYM_CLASS_STATIC 3 +#define IMAGE_SYM_CLASS_REGISTER 4 +#define IMAGE_SYM_CLASS_EXTERNAL_DEF 5 +#define IMAGE_SYM_CLASS_LABEL 6 +#define IMAGE_SYM_CLASS_UNDEFINED_LABEL 7 +#define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 8 +#define IMAGE_SYM_CLASS_ARGUMENT 9 +#define IMAGE_SYM_CLASS_STRUCT_TAG 10 +#define IMAGE_SYM_CLASS_MEMBER_OF_UNION 11 +#define IMAGE_SYM_CLASS_UNION_TAG 12 +#define IMAGE_SYM_CLASS_TYPE_DEFINITION 13 +#define IMAGE_SYM_CLASS_UNDEFINED_STATIC 14 +#define IMAGE_SYM_CLASS_ENUM_TAG 15 +#define IMAGE_SYM_CLASS_MEMBER_OF_ENUM 16 +#define IMAGE_SYM_CLASS_REGISTER_PARAM 17 +#define IMAGE_SYM_CLASS_BIT_FIELD 18 +#define IMAGE_SYM_CLASS_BLOCK 100 +#define IMAGE_SYM_CLASS_FUNCTION 101 +#define IMAGE_SYM_CLASS_END_OF_STRUCT 102 +#define IMAGE_SYM_CLASS_FILE 103 +// new +#define IMAGE_SYM_CLASS_SECTION 104 +#define IMAGE_SYM_CLASS_WEAK_EXTERNAL 105 + +// type packing constants + +#define N_BTMASK 017 +#define N_TMASK 060 +#define N_TMASK1 0300 +#define N_TMASK2 0360 +#define N_BTSHFT 4 +#define N_TSHIFT 2 + +// MACROS + +// +// Communal selection types. +// + +#define IMAGE_COMDAT_SELECT_NODUPLICATES 1 +#define IMAGE_COMDAT_SELECT_ANY 2 +#define IMAGE_COMDAT_SELECT_SAME_SIZE 3 +#define IMAGE_COMDAT_SELECT_EXACT_MATCH 4 +#define IMAGE_COMDAT_SELECT_ASSOCIATIVE 5 + +#define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1 +#define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2 +#define IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3 + + +// +// Relocation format. +// + +typedef struct _IMAGE_RELOCATION { + UINT32 VirtualAddress; + UINT32 SymbolTableIndex; + UINT16 Type; +} IMAGE_RELOCATION; + +#define IMAGE_SIZEOF_RELOCATION 10 + +// +// I386 relocation types. +// + +#define IMAGE_REL_I386_ABSOLUTE 0 // Reference is absolute, no relocation is necessary +#define IMAGE_REL_I386_DIR16 01 // Direct 16-bit reference to the symbols virtual address +#define IMAGE_REL_I386_REL16 02 // PC-relative 16-bit reference to the symbols virtual address +#define IMAGE_REL_I386_DIR32 06 // Direct 32-bit reference to the symbols virtual address +#define IMAGE_REL_I386_DIR32NB 07 // Direct 32-bit reference to the symbols virtual address, base not included +#define IMAGE_REL_I386_SEG12 011 // Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address +#define IMAGE_REL_I386_SECTION 012 +#define IMAGE_REL_I386_SECREL 013 +#define IMAGE_REL_I386_REL32 024 // PC-relative 32-bit reference to the symbols virtual address + +// +// MIPS relocation types. +// + +#define IMAGE_REL_MIPS_ABSOLUTE 0 // Reference is absolute, no relocation is necessary +#define IMAGE_REL_MIPS_REFHALF 01 +#define IMAGE_REL_MIPS_REFWORD 02 +#define IMAGE_REL_MIPS_JMPADDR 03 +#define IMAGE_REL_MIPS_REFHI 04 +#define IMAGE_REL_MIPS_REFLO 05 +#define IMAGE_REL_MIPS_GPREL 06 +#define IMAGE_REL_MIPS_LITERAL 07 +#define IMAGE_REL_MIPS_SECTION 012 +#define IMAGE_REL_MIPS_SECREL 013 +#define IMAGE_REL_MIPS_REFWORDNB 042 +#define IMAGE_REL_MIPS_PAIR 045 + +// +// Alpha Relocation types. +// + +#define IMAGE_REL_ALPHA_ABSOLUTE 0x0 +#define IMAGE_REL_ALPHA_REFLONG 0x1 +#define IMAGE_REL_ALPHA_REFQUAD 0x2 +#define IMAGE_REL_ALPHA_GPREL32 0x3 +#define IMAGE_REL_ALPHA_LITERAL 0x4 +#define IMAGE_REL_ALPHA_LITUSE 0x5 +#define IMAGE_REL_ALPHA_GPDISP 0x6 +#define IMAGE_REL_ALPHA_BRADDR 0x7 +#define IMAGE_REL_ALPHA_HINT 0x8 +#define IMAGE_REL_ALPHA_INLINE_REFLONG 0x9 +#define IMAGE_REL_ALPHA_REFHI 0xA +#define IMAGE_REL_ALPHA_REFLO 0xB +#define IMAGE_REL_ALPHA_PAIR 0xC +#define IMAGE_REL_ALPHA_MATCH 0xD +#define IMAGE_REL_ALPHA_SECTION 0xE +#define IMAGE_REL_ALPHA_SECREL 0xF +#define IMAGE_REL_ALPHA_REFLONGNB 0x10 + +// +// IBM PowerPC relocation types. +// + +#define IMAGE_REL_PPC_ABSOLUTE 0x0000 // NOP +#define IMAGE_REL_PPC_ADDR64 0x0001 // 64-bit address +#define IMAGE_REL_PPC_ADDR32 0x0002 // 32-bit address +#define IMAGE_REL_PPC_ADDR24 0x0003 // 26-bit address, shifted left 2 (branch absolute) +#define IMAGE_REL_PPC_ADDR16 0x0004 // 16-bit address +#define IMAGE_REL_PPC_ADDR14 0x0005 // 16-bit address, shifted left 2 (load doubleword) +#define IMAGE_REL_PPC_REL24 0x0006 // 26-bit PC-relative offset, shifted left 2 (branch relative) +#define IMAGE_REL_PPC_REL14 0x0007 // 16-bit PC-relative offset, shifted left 2 (br cond relative) +#define IMAGE_REL_PPC_TOCREL16 0x0008 // 16-bit offset from TOC base +#define IMAGE_REL_PPC_TOCREL14 0x0009 // 16-bit offset from TOC base, shifted left 2 (load doubleword) + +#define IMAGE_REL_PPC_ADDR32NB 0x000A // 32-bit addr w/o image base +#define IMAGE_REL_PPC_SECREL 0x000B // va of containing section (as in an image sectionhdr) +#define IMAGE_REL_PPC_SECTION 0x000C // sectionheader number +#define IMAGE_REL_PPC_IFGLUE 0x000D // substitute TOC restore instruction iff symbol is glue code +#define IMAGE_REL_PPC_IMGLUE 0x000E // symbol is glue code; virtual address is TOC restore instruction + +#define IMAGE_REL_PPC_TYPEMASK 0x00FF // mask to isolate above values in IMAGE_RELOCATION.Type + +// Flag bits in IMAGE_RELOCATION.TYPE + +#define IMAGE_REL_PPC_NEG 0x0100 // subtract reloc value rather than adding it +#define IMAGE_REL_PPC_BRTAKEN 0x0200 // fix branch prediction bit to predict branch taken +#define IMAGE_REL_PPC_BRNTAKEN 0x0400 // fix branch prediction bit to predict branch not taken +#define IMAGE_REL_PPC_TOCDEFN 0x0800 // toc slot defined in file (or, data in toc) + +// +// Based relocation format. +// + +typedef struct _IMAGE_BASE_RELOCATION { + UINT32 VirtualAddress; + UINT32 SizeOfBlock; +// UINT16 TypeOffset[1]; +} IMAGE_BASE_RELOCATION, *PIMAGE_BASE_RELOCATION; + +#define IMAGE_SIZEOF_BASE_RELOCATION 8 + +// +// Based relocation types. +// + +#define IMAGE_REL_BASED_ABSOLUTE 0 +#define IMAGE_REL_BASED_HIGH 1 +#define IMAGE_REL_BASED_LOW 2 +#define IMAGE_REL_BASED_HIGHLOW 3 +#define IMAGE_REL_BASED_HIGHADJ 4 +#define IMAGE_REL_BASED_MIPS_JMPADDR 5 +#define IMAGE_REL_BASED_IA64_IMM64 9 +#define IMAGE_REL_BASED_DIR64 10 + +// +// Line number format. +// + +typedef struct _IMAGE_LINENUMBER { + union { + UINT32 SymbolTableIndex; // Symbol table index of function name if Linenumber is 0. + UINT32 VirtualAddress; // Virtual address of line number. + } Type; + UINT16 Linenumber; // Line number. +} IMAGE_LINENUMBER; + +#define IMAGE_SIZEOF_LINENUMBER 6 + +// +// Archive format. +// + +#define IMAGE_ARCHIVE_START_SIZE 8 +#define IMAGE_ARCHIVE_START "!\n" +#define IMAGE_ARCHIVE_END "`\n" +#define IMAGE_ARCHIVE_PAD "\n" +#define IMAGE_ARCHIVE_LINKER_MEMBER "/ " +#define IMAGE_ARCHIVE_LONGNAMES_MEMBER "// " + +typedef struct _IMAGE_ARCHIVE_MEMBER_HEADER { + UINT8 Name[16]; // File member name - `/' terminated. + UINT8 Date[12]; // File member date - decimal. + UINT8 UserID[6]; // File member user id - decimal. + UINT8 GroupID[6]; // File member group id - decimal. + UINT8 Mode[8]; // File member mode - octal. + UINT8 Size[10]; // File member size - decimal. + UINT8 EndHeader[2]; // String to end header. +} IMAGE_ARCHIVE_MEMBER_HEADER, *PIMAGE_ARCHIVE_MEMBER_HEADER; + +#define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60 + +// +// DLL support. +// + +// +// Export Format +// + +typedef struct _IMAGE_EXPORT_DIRECTORY { + UINT32 Characteristics; + UINT32 TimeDateStamp; + UINT16 MajorVersion; + UINT16 MinorVersion; + UINT32 Name; + UINT32 Base; + UINT32 NumberOfFunctions; + UINT32 NumberOfNames; + UINT32 AddressOfFunctions; + UINT32 AddressOfNames; + UINT32 AddressOfNameOrdinals; +} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY; + +// +// Import Format +// + +typedef struct _IMAGE_IMPORT_BY_NAME { + UINT16 Hint; + UINT8 Name[1]; +} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME; + +typedef struct _IMAGE_THUNK_DATA { + union { + UINT32 Function; + UINT32 Ordinal; + PIMAGE_IMPORT_BY_NAME AddressOfData; + } u1; +} IMAGE_THUNK_DATA, *PIMAGE_THUNK_DATA; + +#define IMAGE_ORDINAL_FLAG 0x80000000 +#define IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG) != 0) +#define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff) + +typedef struct _IMAGE_IMPORT_DESCRIPTOR { + UINT32 Characteristics; + UINT32 TimeDateStamp; + UINT32 ForwarderChain; + UINT32 Name; + PIMAGE_THUNK_DATA FirstThunk; +} IMAGE_IMPORT_DESCRIPTOR, *PIMAGE_IMPORT_DESCRIPTOR; + +#endif diff --git a/include/ia64/salproc.h b/include/ia64/salproc.h new file mode 100644 index 0000000..9468980 --- /dev/null +++ b/include/ia64/salproc.h @@ -0,0 +1,264 @@ +#ifndef _SAL_PROC_H +#define _SAL_PROC_H +// +// +//Copyright (c) 1999 Intel Corporation +// +//Module Name: +// +// SalProc.h +// +//Abstract: +// +// Main SAL interface routins for IA-64 calls. +// +// +//Revision History +// +// + +// return value that mimicks r8,r9,r10 & r11 registers +typedef struct { + UINT64 p0; + UINT64 p1; + UINT64 p2; + UINT64 p3; +} rArg; + +#define SAL_PCI_CONFIG_READ 0x01000010 +#define SAL_PCI_CONFIG_WRITE 0x01000011 + +typedef VOID (*PFN)(); +typedef rArg (*PFN_SAL_PROC)(UINT64,UINT64,UINT64,UINT64,UINT64,UINT64,UINT64,UINT64); +typedef rArg (*PFN_SAL_CALLBACK)(UINT64,UINT64,UINT64,UINT64,UINT64,UINT64,UINT64,UINT64); + +typedef struct _PLABEL { + UINT64 ProcEntryPoint; + UINT64 GP; +} PLABEL; + +typedef struct tagIA32_BIOS_REGISTER_STATE { + + // general registers + UINT32 eax; + UINT32 ecx; + UINT32 edx; + UINT32 ebx; + + // stack registers + UINT32 esp; + UINT32 ebp; + UINT32 esi; + UINT32 edi; + + // eflags + UINT32 eflags; + + // instruction pointer + UINT32 eip; + + UINT16 cs; + UINT16 ds; + UINT16 es; + UINT16 fs; + UINT16 gs; + UINT16 ss; + + // Reserved + UINT32 Reserved1; + UINT64 Reserved2; +} IA32_BIOS_REGISTER_STATE; + +VOID EFIInitMsg(VOID); + +EFI_STATUS +PlRegisterAndStartTimer( + IN UINTN Period + ); + +EFI_STATUS +PlDeRegisterAndCancelTimer(VOID); + +VOID +SalProc ( + IN UINT64 Arg1, + IN UINT64 Arg2, + IN UINT64 Arg3, + IN UINT64 Arg4, + IN UINT64 Arg5, + IN UINT64 Arg6, + IN UINT64 Arg7, + IN UINT64 Arg8, + OUT rArg *Results OPTIONAL + ); + +VOID +SalCallBack ( + IN UINT64 Arg1, + IN UINT64 Arg2, + IN UINT64 Arg3, + IN UINT64 Arg4, + IN UINT64 Arg5, + IN UINT64 Arg6, + IN UINT64 Arg7, + IN UINT64 Arg8, + OUT rArg *Results OPTIONAL + ); + +VOID +RUNTIMEFUNCTION +RtSalCallBack ( + IN UINT64 Arg1, + IN UINT64 Arg2, + IN UINT64 Arg3, + IN UINT64 Arg4, + IN UINT64 Arg5, + IN UINT64 Arg6, + IN UINT64 Arg7, + IN UINT64 Arg8, + OUT rArg *Results OPTIONAL + ); + + +extern PLABEL RtGlobalSalProcEntry; +extern PLABEL RtGlobalSALCallBack; + +#pragma pack(1) +// +// SAL System Table +// +typedef struct { + UINT32 Signature; + UINT32 Length; + UINT16 Revision; + UINT16 EntryCount; + UINT8 CheckSum; + UINT8 Reserved[7]; + UINT16 SALA_Ver; + UINT16 SALB_Ver; + UINT8 OemId[32]; + UINT8 ProductID[32]; + UINT8 Reserved2[8]; +} SAL_SYSTEM_TABLE_HDR; + +#define SAL_ST_ENTRY_POINT 0 +#define SAL_ST_MEMORY_DESCRIPTOR 1 +#define SAL_ST_PLATFORM_FEATURES 2 +#define SAL_ST_TR_USAGE 3 +#define SAL_ST_PTC 4 +#define SAL_ST_AP_WAKEUP 5 + +typedef struct { + UINT8 Type; // Type == 0 + UINT8 Reserved[7]; + UINT64 PalProcEntry; + UINT64 SalProcEntry; + UINT64 GlobalDataPointer; + UINT64 Reserved2[2]; +} SAL_ST_ENTRY_POINT_DESCRIPTOR; + +typedef struct { + UINT8 Type; // Type == 1 + UINT8 NeedVirtualRegistration; + UINT8 MemoryAttributes; + UINT8 PageAccessRights; + UINT8 SupportedAttributes; + UINT8 Reserved; + UINT16 MemoryType; + UINT64 PhysicalMemoryAddress; + UINT32 Length; + UINT32 Reserved1; + UINT64 OemReserved; +} SAL_ST_MEMORY_DESCRIPTOR_ENTRY; + +// +// MemoryType info +// +#define SAL_SAPIC_IPI_BLOCK 0x0002 +#define SAL_IO_PORT_MAPPING 0x0003 + +typedef struct { + UINT8 Type; // Type == 2 + UINT8 PlatformFeatures; + UINT8 Reserved[14]; +} SAL_ST_MEMORY_DECRIPTOR; + +typedef struct { + UINT8 Type; // Type == 3 + UINT8 TRType; + UINT8 TRNumber; + UINT8 Reserved[5]; + UINT64 VirtualAddress; + UINT64 EncodedPageSize; + UINT64 Reserved1; +} SAL_ST_TR_DECRIPTOR; + +typedef struct { + UINT64 NumberOfProcessors; + UINT64 LocalIDRegister; +} SAL_COHERENCE_DOMAIN_INFO; + +typedef struct { + UINT8 Type; // Type == 4 + UINT8 Reserved[3]; + UINT32 NumberOfDomains; + SAL_COHERENCE_DOMAIN_INFO *DomainInformation; +} SAL_ST_CACHE_COHERENCE_DECRIPTOR; + +typedef struct { + UINT8 Type; // Type == 5 + UINT8 WakeUpType; + UINT8 Reserved[6]; + UINT64 ExternalInterruptVector; +} SAL_ST_AP_WAKEUP_DECRIPTOR; + +typedef struct { + SAL_SYSTEM_TABLE_HDR Header; + SAL_ST_ENTRY_POINT_DESCRIPTOR Entry0; +} SAL_SYSTEM_TABLE_ASCENDING_ORDER; + +#define FIT_ENTRY_PTR (0x100000000 - 32) // 4GB - 24 +#define FIT_PALA_ENTRY (0x100000000 - 48) // 4GB - 32 +#define FIT_PALB_TYPE 01 + +typedef struct { + UINT64 Address; + UINT8 Size[3]; + UINT8 Reserved; + UINT16 Revision; + UINT8 Type:7; + UINT8 CheckSumValid:1; + UINT8 CheckSum; +} FIT_ENTRY; + +#pragma pack() + +typedef + rArg +(*CALL_SAL_PROC)( + IN UINT64 Arg1, + IN UINT64 Arg2, + IN UINT64 Arg3, + IN UINT64 Arg4, + IN UINT64 Arg5, + IN UINT64 Arg6, + IN UINT64 Arg7, + IN UINT64 Arg8 + ); + +typedef + rArg +(*CALL_PAL_PROC)( + IN UINT64 Arg1, + IN UINT64 Arg2, + IN UINT64 Arg3, + IN UINT64 Arg4 + ); + +extern CALL_SAL_PROC GlobalSalProc; +extern CALL_PAL_PROC GlobalPalProc; +extern PLABEL SalProcPlabel; +extern PLABEL PalProcPlabel; + +#endif + diff --git a/include/inc.mak b/include/inc.mak new file mode 100644 index 0000000..64fc7bb --- /dev/null +++ b/include/inc.mak @@ -0,0 +1,23 @@ + + +INC_DEPS = $(INC_DEPS) \ + efi.h \ + efiapi.h \ + efibind.h \ + eficon.h \ + efidebug.h \ + efidef.h \ + efidevp.h \ + efierr.h \ + efifs.h \ + efilib.h \ + efipart.h \ + efipciio.h \ + efiprot.h \ + efipxe.h \ + efivar.h \ + pe.h \ + efiip.h \ + efiudp.h \ + efitcp.h \ + stdarg.h diff --git a/include/legacy.h b/include/legacy.h new file mode 100644 index 0000000..5aa2a8c --- /dev/null +++ b/include/legacy.h @@ -0,0 +1,60 @@ +#ifndef _EFI_LEGACY_H +#define _EFI_LEGACY_H + +/* +ABIs: +Default ABI will be highest number +Older versions can be selected via compiler defines +*/ + +/* ReallocatePool */ +#ifndef GNU_EFI_USE_REALLOCATEPOOL_ABI +#define GNU_EFI_USE_REALLOCATEPOOL_ABI 1 +#endif + +#if GNU_EFI_USE_REALLOCATEPOOL_ABI == 0 +#define ReallocatePool ReallocatePool_0 +#else +#define ReallocatePool ReallocatePool_1 +#endif + +/* prevent circular headers */ +VOID * +EFIAPI +ReallocatePool_1 ( + IN UINTN OldSize, + IN UINTN NewSize, + IN VOID *OldPool OPTIONAL +); + +inline +VOID * +EFIAPI +ReallocatePool_0 ( + IN VOID *OldPool, + IN UINTN OldSize, + IN UINTN NewSize +) +{ + return ReallocatePool_1(OldSize, NewSize, OldPool); +} + +/* end ReallocatePool */ + +/* CopyMem */ +/* CopyMemC isn't deprecated - serves different purpose to CopyMem */ + +#ifndef GNU_EFI_USE_COPYMEM_ABI +#define GNU_EFI_USE_COPYMEM_ABI 1 +#endif + +#if GNU_EFI_USE_COPYMEM_ABI == 0 +#define CopyMem CopyMemC +#else +#define CopyMem CopyMem_1 +#endif + +/* end CopyMem */ + +#endif + diff --git a/include/lib.h b/include/lib.h new file mode 100644 index 0000000..f07b5e6 --- /dev/null +++ b/include/lib.h @@ -0,0 +1,92 @@ +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + lib.h + +Abstract: + + EFI library header files + + + +Revision History + +--*/ + +#ifdef __GNUC__ +#pragma GCC visibility push(hidden) +#endif + +#include "efi.h" +#include "efilib.h" +#include "efirtlib.h" + +// +// Include non architectural protocols +// +#include "protocol/efivar.h" +#include "protocol/legacyboot.h" +#include "protocol/intload.h" +#include "protocol/vgaclass.h" +#include "protocol/eficonsplit.h" +#include "protocol/adapterdebug.h" +#include "protocol/intload.h" + +#include "efigpt.h" +#include "libsmbios.h" + +// +// Prototypes +// + +VOID +InitializeGuid ( + VOID + ); + +INTN EFIAPI +LibStubStriCmp ( + IN EFI_UNICODE_COLLATION_INTERFACE *This, + IN CHAR16 *S1, + IN CHAR16 *S2 + ); + +BOOLEAN EFIAPI +LibStubMetaiMatch ( + IN EFI_UNICODE_COLLATION_INTERFACE *This, + IN CHAR16 *String, + IN CHAR16 *Pattern + ); + +VOID EFIAPI +LibStubStrLwrUpr ( + IN EFI_UNICODE_COLLATION_INTERFACE *This, + IN CHAR16 *Str + ); + +BOOLEAN +LibMatchDevicePaths ( + IN EFI_DEVICE_PATH *Multi, + IN EFI_DEVICE_PATH *Single + ); + +EFI_DEVICE_PATH * +LibDuplicateDevicePathInstance ( + IN EFI_DEVICE_PATH *DevPath + ); + + +// +// Globals +// +extern BOOLEAN LibInitialized; +extern BOOLEAN LibFwInstance; +extern EFI_HANDLE LibImageHandle; +extern SIMPLE_TEXT_OUTPUT_INTERFACE *LibRuntimeDebugOut; +extern EFI_UNICODE_COLLATION_INTERFACE *UnicodeInterface; +extern EFI_UNICODE_COLLATION_INTERFACE LibStubUnicodeInterface; +extern EFI_RAISE_TPL LibRuntimeRaiseTPL; +extern EFI_RESTORE_TPL LibRuntimeRestoreTPL; diff --git a/include/libsmbios.h b/include/libsmbios.h new file mode 100644 index 0000000..e22c51d --- /dev/null +++ b/include/libsmbios.h @@ -0,0 +1,149 @@ +#ifndef _LIB_SMBIOS_H +#define _LIB_SMBIOS_H +/*++ + +Copyright (c) 2000 Intel Corporation + +Module Name: + + LibSmbios.h + +Abstract: + + Lib include for SMBIOS services. Used to get system serial number and GUID + +Revision History + +--*/ + +// +// Define SMBIOS tables. +// +#pragma pack(1) +typedef struct { + UINT8 AnchorString[4]; + UINT8 EntryPointStructureChecksum; + UINT8 EntryPointLength; + UINT8 MajorVersion; + UINT8 MinorVersion; + UINT16 MaxStructureSize; + UINT8 EntryPointRevision; + UINT8 FormattedArea[5]; + UINT8 IntermediateAnchorString[5]; + UINT8 IntermediateChecksum; + UINT16 TableLength; + UINT32 TableAddress; + UINT16 NumberOfSmbiosStructures; + UINT8 SmbiosBcdRevision; +} SMBIOS_TABLE_ENTRY_POINT; + +#define SMBIOS_STRUCTURE_TABLE SMBIOS_TABLE_ENTRY_POINT + +typedef struct { + UINT8 AnchorString[5]; + UINT8 EntryPointStructureChecksum; + UINT8 EntryPointLength; + UINT8 MajorVersion; + UINT8 MinorVersion; + UINT8 DocRev; + UINT8 EntryPointRevision; + UINT8 Reserved; + UINT32 TableMaximumSize; + UINT64 TableAddress; +} SMBIOS_TABLE_3_0_ENTRY_POINT; + +#define SMBIOS3_STRUCTURE_TABLE SMBIOS_TABLE_3_0_ENTRY_POINT + +// +// Please note that SMBIOS structures can be odd byte aligned since the +// unformated section of each record is a set of arbitrary size strings. +// + +typedef struct { + UINT8 Type; + UINT8 Length; + UINT8 Handle[2]; +} SMBIOS_STRUCTURE; + +#define SMBIOS_HEADER SMBIOS_STRUCTURE + +typedef UINT8 SMBIOS_STRING; + +typedef struct { + SMBIOS_HEADER Hdr; + SMBIOS_STRING Vendor; + SMBIOS_STRING BiosVersion; + UINT8 BiosSegment[2]; + SMBIOS_STRING BiosReleaseDate; + UINT8 BiosSize; + UINT8 BiosCharacteristics[8]; +} SMBIOS_TYPE0; + +typedef struct { + SMBIOS_HEADER Hdr; + SMBIOS_STRING Manufacturer; + SMBIOS_STRING ProductName; + SMBIOS_STRING Version; + SMBIOS_STRING SerialNumber; + + // + // always byte copy this data to prevent alignment faults! + // + EFI_GUID Uuid; + + UINT8 WakeUpType; +} SMBIOS_TYPE1; + +typedef struct { + SMBIOS_HEADER Hdr; + SMBIOS_STRING Manufacturer; + SMBIOS_STRING ProductName; + SMBIOS_STRING Version; + SMBIOS_STRING SerialNumber; +} SMBIOS_TYPE2; + +typedef struct { + SMBIOS_HEADER Hdr; + SMBIOS_STRING Manufacturer; + UINT8 Type; + SMBIOS_STRING Version; + SMBIOS_STRING SerialNumber; + SMBIOS_STRING AssetTag; + UINT8 BootupState; + UINT8 PowerSupplyState; + UINT8 ThermalState; + UINT8 SecurityStatus; + UINT8 OemDefined[4]; +} SMBIOS_TYPE3; + +typedef struct { + SMBIOS_HEADER Hdr; + UINT8 Socket; + UINT8 ProcessorType; + UINT8 ProcessorFamily; + SMBIOS_STRING ProcessorManufacture; + UINT8 ProcessorId[8]; + SMBIOS_STRING ProcessorVersion; + UINT8 Voltage; + UINT8 ExternalClock[2]; + UINT8 MaxSpeed[2]; + UINT8 CurrentSpeed[2]; + UINT8 Status; + UINT8 ProcessorUpgrade; + UINT8 L1CacheHandle[2]; + UINT8 L2CacheHandle[2]; + UINT8 L3CacheHandle[2]; +} SMBIOS_TYPE4; + +typedef union { + SMBIOS_HEADER *Hdr; + SMBIOS_TYPE0 *Type0; + SMBIOS_TYPE1 *Type1; + SMBIOS_TYPE2 *Type2; + SMBIOS_TYPE3 *Type3; + SMBIOS_TYPE4 *Type4; + UINT8 *Raw; +} SMBIOS_STRUCTURE_POINTER; +#pragma pack() + +#endif diff --git a/include/loongarch64/efibind.h b/include/loongarch64/efibind.h new file mode 100644 index 0000000..cead320 --- /dev/null +++ b/include/loongarch64/efibind.h @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2014 - 2015 Linaro Ltd. + * Author: Ard Biesheuvel + * Copyright (C) 2017 Lemote Co. + * Author: Heiher + * Copyright (C) 2021 Loongson Technology Corporation Limited. + * Author: zhoumingtao + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice and this list of conditions, without modification. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License as published by the Free Software Foundation; + * either version 2 of the License, or (at your option) any later version. + */ + +#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L ) && !defined(__cplusplus) + +// ANSI C 1999/2000 stdint.h integer width declarations + +typedef unsigned long uint64_t; +typedef long int64_t; +typedef unsigned int uint32_t; +typedef int int32_t; +typedef unsigned short uint16_t; +typedef short int16_t; +typedef unsigned char uint8_t; +typedef signed char int8_t; +typedef uint64_t uintptr_t; +typedef int64_t intptr_t; + +#else +#include +#endif + +// +// Basic EFI types of various widths +// + +#include + +typedef wchar_t CHAR16; +#define WCHAR CHAR16 + +typedef uint64_t UINT64; +typedef int64_t INT64; + +typedef uint32_t UINT32; +typedef int32_t INT32; + +typedef uint16_t UINT16; +typedef int16_t INT16; + +typedef uint8_t UINT8; +typedef char CHAR8; +typedef int8_t INT8; + +#undef VOID +typedef void VOID; + +typedef int64_t INTN; +typedef uint64_t UINTN; + +#define EFIERR(a) (0x8000000000000000 | a) +#define EFI_ERROR_MASK 0x8000000000000000 +#define EFIERR_OEM(a) (0xc000000000000000 | a) + +#define BAD_POINTER 0xFBFBFBFBFBFBFBFB +#define MAX_ADDRESS 0xFFFFFFFFFFFFFFFF + +#define BREAKPOINT() while (TRUE); // Make it hang on Bios[Dbg]32 + +// +// Pointers must be aligned to these address to function +// + +#define MIN_ALIGNMENT_SIZE 8 + +#define ALIGN_VARIABLE(Value ,Adjustment) \ + (UINTN)Adjustment = 0; \ + if((UINTN)Value % MIN_ALIGNMENT_SIZE) \ + (UINTN)Adjustment = MIN_ALIGNMENT_SIZE - ((UINTN)Value % MIN_ALIGNMENT_SIZE); \ + Value = (UINTN)Value + (UINTN)Adjustment + + +// +// Define macros to build data structure signatures from characters. +// + +#define EFI_SIGNATURE_16(A,B) ((A) | (B<<8)) +#define EFI_SIGNATURE_32(A,B,C,D) (EFI_SIGNATURE_16(A,B) | (EFI_SIGNATURE_16(C,D) << 16)) +#define EFI_SIGNATURE_64(A,B,C,D,E,F,G,H) (EFI_SIGNATURE_32(A,B,C,D) | ((UINT64)(EFI_SIGNATURE_32(E,F,G,H)) << 32)) + +// +// EFIAPI - prototype calling convention for EFI function pointers +// BOOTSERVICE - prototype for implementation of a boot service interface +// RUNTIMESERVICE - prototype for implementation of a runtime service interface +// RUNTIMEFUNCTION - prototype for implementation of a runtime function that is not a service +// RUNTIME_CODE - pragma macro for declaring runtime code +// + +#ifndef EFIAPI // Forces EFI calling conventions reguardless of compiler options +#define EFIAPI // Substitute expresion to force C calling convention +#endif + +#define BOOTSERVICE +#define RUNTIMESERVICE +#define RUNTIMEFUNCTION + + +#define RUNTIME_CODE(a) alloc_text("rtcode", a) +#define BEGIN_RUNTIME_DATA() data_seg("rtdata") +#define END_RUNTIME_DATA() data_seg("") + +#define VOLATILE volatile + +#define MEMORY_FENCE __sync_synchronize + +// +// When build similiar to FW, then link everything together as +// one big module. +// + +#define EFI_DRIVER_ENTRY_POINT(InitFunction) \ + UINTN \ + InitializeDriver ( \ + VOID *ImageHandle, \ + VOID *SystemTable \ + ) \ + { \ + return InitFunction(ImageHandle, \ + SystemTable); \ + } \ + \ + EFI_STATUS efi_main( \ + EFI_HANDLE image, \ + EFI_SYSTEM_TABLE *systab \ + ) __attribute__((weak, \ + alias ("InitializeDriver"))); + +#define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \ + (_if)->LoadInternal(type, name, entry) + + +// +// Some compilers don't support the forward reference construct: +// typedef struct XXXXX +// +// The following macro provide a workaround for such cases. + +#define INTERFACE_DECL(x) struct x + +#define uefi_call_wrapper(func, va_num, ...) func(__VA_ARGS__) +#define EFI_FUNCTION diff --git a/include/loongarch64/efilibplat.h b/include/loongarch64/efilibplat.h new file mode 100644 index 0000000..3cabe70 --- /dev/null +++ b/include/loongarch64/efilibplat.h @@ -0,0 +1,24 @@ +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efilibplat.h + +Abstract: + + EFI to compile bindings + + + + +Revision History + +--*/ + +VOID +InitializeLibPlatform ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); diff --git a/include/loongarch64/efisetjmp_arch.h b/include/loongarch64/efisetjmp_arch.h new file mode 100644 index 0000000..91cc554 --- /dev/null +++ b/include/loongarch64/efisetjmp_arch.h @@ -0,0 +1,23 @@ +#ifndef GNU_EFI_LOONGARCH64_SETJMP_H +#define GNU_EFI_LOONGARCH64_SETJMP_H + +#define JMPBUF_ALIGN 8 + +typedef struct { + /* GP regs */ + UINT64 RA; + UINT64 SP; + UINT64 FP; + + UINT64 S0; + UINT64 S1; + UINT64 S2; + UINT64 S3; + UINT64 S4; + UINT64 S5; + UINT64 S6; + UINT64 S7; + UINT64 S8; +} EFI_ALIGN(JMPBUF_ALIGN) jmp_buf[1]; + +#endif /* GNU_EFI_LOONGARCH64_SETJMP_H */ diff --git a/include/make.inf b/include/make.inf new file mode 100644 index 0000000..e9ccc9e --- /dev/null +++ b/include/make.inf @@ -0,0 +1,33 @@ +# +# +# + +[sources] + efi.h + efiapi.h + eficon.h + efidebug.h + efidef.h + efidevp.h + efierr.h + efifs.h + efilib.h + efipart.h + efipciio.h + efiprot.h + efipxebc.h + efistdarg.h + efinet.h + efiip.h + efiudp.h + efitcp.h + +[ia32sources] + efibind.h + pe.h + efilibplat.h + +[ia64sources] + efibind.h + pe.h + efilibplat.h diff --git a/include/makefile.hdr b/include/makefile.hdr new file mode 100644 index 0000000..808d5c5 --- /dev/null +++ b/include/makefile.hdr @@ -0,0 +1,48 @@ + +# +# This is a machine generated file - DO NOT EDIT +# Generated by genmake.exe +# Generated from make.inf +# Copyright (c) 1998 Intel Corporation +# + +INC_DEPS = $(INC_DEPS) \ + $(SDK_INSTALL_DIR)\include\efi\efi.h \ + $(SDK_INSTALL_DIR)\include\efi\efiapi.h \ + $(SDK_INSTALL_DIR)\include\efi\eficon.h \ + $(SDK_INSTALL_DIR)\include\efi\efidebug.h \ + $(SDK_INSTALL_DIR)\include\efi\efidef.h \ + $(SDK_INSTALL_DIR)\include\efi\efidevp.h \ + $(SDK_INSTALL_DIR)\include\efi\efierr.h \ + $(SDK_INSTALL_DIR)\include\efi\efifs.h \ + $(SDK_INSTALL_DIR)\include\efi\efilib.h \ + $(SDK_INSTALL_DIR)\include\efi\efipart.h \ + $(SDK_INSTALL_DIR)\include\efi\efipciio.h \ + $(SDK_INSTALL_DIR)\include\efi\efiprot.h \ + $(SDK_INSTALL_DIR)\include\efi\efipxebc.h \ + $(SDK_INSTALL_DIR)\include\efi\efistdarg.h \ + $(SDK_INSTALL_DIR)\include\efi\efinet.h \ + $(SDK_INSTALL_DIR)\include\efi\efiip.h \ + $(SDK_INSTALL_DIR)\include\efi\efiudp.h \ + $(SDK_INSTALL_DIR)\include\efi\efitcp.h \ + + +!IF "$(PROCESSOR)" == "Ia32" +INC_DEPS = $(INC_DEPS) \ + $(SDK_INSTALL_DIR)\include\efi\Ia32\efibind.h \ + $(SDK_INSTALL_DIR)\include\efi\Ia32\pe.h \ + $(SDK_INSTALL_DIR)\include\efi\Ia32\efilibplat.h \ + + +!ENDIF + + +!IF "$(PROCESSOR)" == "Ia64" +INC_DEPS = $(INC_DEPS) \ + $(SDK_INSTALL_DIR)\include\efi\Ia64\efibind.h \ + $(SDK_INSTALL_DIR)\include\efi\Ia64\pe.h \ + $(SDK_INSTALL_DIR)\include\efi\Ia64\efilibplat.h \ + + +!ENDIF + diff --git a/include/mips64el/efibind.h b/include/mips64el/efibind.h new file mode 100644 index 0000000..0d48e52 --- /dev/null +++ b/include/mips64el/efibind.h @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2014 - 2015 Linaro Ltd. + * Author: Ard Biesheuvel + * Copyright (C) 2017 Lemote Co. + * Author: Heiher + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice and this list of conditions, without modification. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License as published by the Free Software Foundation; + * either version 2 of the License, or (at your option) any later version. + */ + +#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L ) && !defined(__cplusplus) + +// ANSI C 1999/2000 stdint.h integer width declarations + +typedef unsigned long uint64_t; +typedef long int64_t; +typedef unsigned int uint32_t; +typedef int int32_t; +typedef unsigned short uint16_t; +typedef short int16_t; +typedef unsigned char uint8_t; +typedef signed char int8_t; // unqualified 'char' is unsigned on ARM +typedef uint64_t uintptr_t; +typedef int64_t intptr_t; + +#else +#include +#endif + +// +// Basic EFI types of various widths +// + +#include + +typedef wchar_t CHAR16; +#define WCHAR CHAR16 + +typedef uint64_t UINT64; +typedef int64_t INT64; + +typedef uint32_t UINT32; +typedef int32_t INT32; + +typedef uint16_t UINT16; +typedef int16_t INT16; + +typedef uint8_t UINT8; +typedef char CHAR8; +typedef int8_t INT8; + +#undef VOID +typedef void VOID; + +typedef int64_t INTN; +typedef uint64_t UINTN; + +#define EFIERR(a) (0x8000000000000000 | a) +#define EFI_ERROR_MASK 0x8000000000000000 +#define EFIERR_OEM(a) (0xc000000000000000 | a) + +#define BAD_POINTER 0xFBFBFBFBFBFBFBFB +#define MAX_ADDRESS 0xFFFFFFFFFFFFFFFF + +#define BREAKPOINT() while (TRUE); // Make it hang on Bios[Dbg]32 + +// +// Pointers must be aligned to these address to function +// + +#define MIN_ALIGNMENT_SIZE 8 + +#define ALIGN_VARIABLE(Value ,Adjustment) \ + (UINTN)Adjustment = 0; \ + if((UINTN)Value % MIN_ALIGNMENT_SIZE) \ + (UINTN)Adjustment = MIN_ALIGNMENT_SIZE - ((UINTN)Value % MIN_ALIGNMENT_SIZE); \ + Value = (UINTN)Value + (UINTN)Adjustment + + +// +// Define macros to build data structure signatures from characters. +// + +#define EFI_SIGNATURE_16(A,B) ((A) | (B<<8)) +#define EFI_SIGNATURE_32(A,B,C,D) (EFI_SIGNATURE_16(A,B) | (EFI_SIGNATURE_16(C,D) << 16)) +#define EFI_SIGNATURE_64(A,B,C,D,E,F,G,H) (EFI_SIGNATURE_32(A,B,C,D) | ((UINT64)(EFI_SIGNATURE_32(E,F,G,H)) << 32)) + +// +// EFIAPI - prototype calling convention for EFI function pointers +// BOOTSERVICE - prototype for implementation of a boot service interface +// RUNTIMESERVICE - prototype for implementation of a runtime service interface +// RUNTIMEFUNCTION - prototype for implementation of a runtime function that is not a service +// RUNTIME_CODE - pragma macro for declaring runtime code +// + +#ifndef EFIAPI // Forces EFI calling conventions reguardless of compiler options +#define EFIAPI // Substitute expresion to force C calling convention +#endif + +#define BOOTSERVICE +#define RUNTIMESERVICE +#define RUNTIMEFUNCTION + + +#define RUNTIME_CODE(a) alloc_text("rtcode", a) +#define BEGIN_RUNTIME_DATA() data_seg("rtdata") +#define END_RUNTIME_DATA() data_seg("") + +#define VOLATILE volatile + +#define MEMORY_FENCE __sync_synchronize + +// +// When build similiar to FW, then link everything together as +// one big module. +// + +#define EFI_DRIVER_ENTRY_POINT(InitFunction) \ + UINTN \ + InitializeDriver ( \ + VOID *ImageHandle, \ + VOID *SystemTable \ + ) \ + { \ + return InitFunction(ImageHandle, \ + SystemTable); \ + } \ + \ + EFI_STATUS efi_main( \ + EFI_HANDLE image, \ + EFI_SYSTEM_TABLE *systab \ + ) __attribute__((weak, \ + alias ("InitializeDriver"))); + +#define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \ + (_if)->LoadInternal(type, name, entry) + + +// +// Some compilers don't support the forward reference construct: +// typedef struct XXXXX +// +// The following macro provide a workaround for such cases. + +#define INTERFACE_DECL(x) struct x + +#define uefi_call_wrapper(func, va_num, ...) func(__VA_ARGS__) +#define EFI_FUNCTION + +static inline UINT64 swap_uint64 (UINT64 v) +{ + __asm__ volatile ( + "dsbh %[v], %[v] \n\t" + "dshd %[v], %[v] \n\t" + :[v]"+r"(v) + ); + + return v; +} diff --git a/include/mips64el/efilibplat.h b/include/mips64el/efilibplat.h new file mode 100644 index 0000000..f3758af --- /dev/null +++ b/include/mips64el/efilibplat.h @@ -0,0 +1,25 @@ +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efilibplat.h + +Abstract: + + EFI to compile bindings + + + + +Revision History + +--*/ + +VOID +InitializeLibPlatform ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + diff --git a/include/mips64el/efisetjmp_arch.h b/include/mips64el/efisetjmp_arch.h new file mode 100644 index 0000000..6f65513 --- /dev/null +++ b/include/mips64el/efisetjmp_arch.h @@ -0,0 +1,34 @@ +#ifndef GNU_EFI_MIPS64EL_SETJMP_H +#define GNU_EFI_MIPS64EL_SETJMP_H + +#define JMPBUF_ALIGN 8 + +typedef struct { + /* GP regs */ + UINT64 RA; + UINT64 SP; + UINT64 FP; + UINT64 GP; + UINT64 S0; + UINT64 S1; + UINT64 S2; + UINT64 S3; + UINT64 S4; + UINT64 S5; + UINT64 S6; + UINT64 S7; + +#ifdef __mips_hard_float + /* FP regs */ + UINT64 F24; + UINT64 F25; + UINT64 F26; + UINT64 F27; + UINT64 F28; + UINT64 F29; + UINT64 F30; + UINT64 F31; +#endif +} EFI_ALIGN(JMPBUF_ALIGN) jmp_buf[1]; + +#endif /* GNU_EFI_MIPS64EL_SETJMP_H */ diff --git a/include/pci22.h b/include/pci22.h new file mode 100644 index 0000000..26718d1 --- /dev/null +++ b/include/pci22.h @@ -0,0 +1,193 @@ +#ifndef _PCI22_H +#define _PCI22_H + +/*++ + +Copyright (c) 1999 Intel Corporation + +Module Name: + + pci22.h + +Abstract: + Support for PCI 2.2 standard. + + + + +Revision History + +--*/ + +#ifdef SOFT_SDV +#define PCI_MAX_BUS 1 +#else +#define PCI_MAX_BUS 255 +#endif + +#define PCI_MAX_DEVICE 31 +#define PCI_MAX_FUNC 7 + +// +// Command +// +#define PCI_VGA_PALETTE_SNOOP_DISABLED 0x20 + +#pragma pack(1) +typedef struct { + UINT16 VendorId; + UINT16 DeviceId; + UINT16 Command; + UINT16 Status; + UINT8 RevisionID; + UINT8 ClassCode[3]; + UINT8 CacheLineSize; + UINT8 LaytencyTimer; + UINT8 HeaderType; + UINT8 BIST; +} PCI_DEVICE_INDEPENDENT_REGION; + +typedef struct { + UINT32 Bar[6]; + UINT32 CISPtr; + UINT16 SubsystemVendorID; + UINT16 SubsystemID; + UINT32 ExpansionRomBar; + UINT32 Reserved[2]; + UINT8 InterruptLine; + UINT8 InterruptPin; + UINT8 MinGnt; + UINT8 MaxLat; +} PCI_DEVICE_HEADER_TYPE_REGION; + +typedef struct { + PCI_DEVICE_INDEPENDENT_REGION Hdr; + PCI_DEVICE_HEADER_TYPE_REGION Device; +} PCI_TYPE00; + +typedef struct { + UINT32 Bar[2]; + UINT8 PrimaryBus; + UINT8 SecondaryBus; + UINT8 SubordinateBus; + UINT8 SecondaryLatencyTimer; + UINT8 IoBase; + UINT8 IoLimit; + UINT16 SecondaryStatus; + UINT16 MemoryBase; + UINT16 MemoryLimit; + UINT16 PrefetchableMemoryBase; + UINT16 PrefetchableMemoryLimit; + UINT32 PrefetchableBaseUpper32; + UINT32 PrefetchableLimitUpper32; + UINT16 IoBaseUpper16; + UINT16 IoLimitUpper16; + UINT32 Reserved; + UINT32 ExpansionRomBAR; + UINT8 InterruptLine; + UINT8 InterruptPin; + UINT16 BridgeControl; +} PCI_BRIDGE_CONTROL_REGISTER; + +#define PCI_CLASS_DISPLAY_CTRL 0x03 +#define PCI_CLASS_VGA 0x00 + +#define PCI_CLASS_BRIDGE 0x06 +#define PCI_CLASS_ISA 0x01 +#define PCI_CLASS_ISA_POSITIVE_DECODE 0x80 + +#define PCI_CLASS_NETWORK 0x02 +#define PCI_CLASS_ETHERNET 0x00 + +#define HEADER_TYPE_DEVICE 0x00 +#define HEADER_TYPE_PCI_TO_PCI_BRIDGE 0x01 +#define HEADER_TYPE_MULTI_FUNCTION 0x80 +#define HEADER_LAYOUT_CODE 0x7f + +#define IS_PCI_BRIDGE(_p) ((((_p)->Hdr.HeaderType) & HEADER_LAYOUT_CODE) == HEADER_TYPE_PCI_TO_PCI_BRIDGE) +#define IS_PCI_MULTI_FUNC(_p) (((_p)->Hdr.HeaderType) & HEADER_TYPE_MULTI_FUNCTION) + +typedef struct { + PCI_DEVICE_INDEPENDENT_REGION Hdr; + PCI_BRIDGE_CONTROL_REGISTER Bridge; +} PCI_TYPE01; + +typedef struct { + UINT8 Register; + UINT8 Function; + UINT8 Device; + UINT8 Bus; + UINT8 Reserved[4]; +} DEFIO_PCI_ADDR; + +typedef struct { + UINT32 Reg : 8; + UINT32 Func : 3; + UINT32 Dev : 5; + UINT32 Bus : 8; + UINT32 Reserved: 7; + UINT32 Enable : 1; +} PCI_CONFIG_ACCESS_CF8; + +#pragma pack() + +#define EFI_ROOT_BRIDGE_LIST 'eprb' +typedef struct { + UINTN Signature; + + UINT16 BridgeNumber; + UINT16 PrimaryBus; + UINT16 SubordinateBus; + + EFI_DEVICE_PATH *DevicePath; + + LIST_ENTRY Link; +} PCI_ROOT_BRIDGE_ENTRY; + + +#define PCI_EXPANSION_ROM_HEADER_SIGNATURE 0xaa55 +#define EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE 0x0EF1 +#define PCI_DATA_STRUCTURE_SIGNATURE EFI_SIGNATURE_32('P','C','I','R') + +#pragma pack(1) +typedef struct { + UINT16 Signature; // 0xaa55 + UINT8 Reserved[0x16]; + UINT16 PcirOffset; +} PCI_EXPANSION_ROM_HEADER; + + +typedef struct { + UINT16 Signature; // 0xaa55 + UINT16 InitializationSize; + UINT16 EfiSignature; // 0x0EF1 + UINT16 EfiSubsystem; + UINT16 EfiMachineType; + UINT8 Reserved[0x0A]; + UINT16 EfiImageHeaderOffset; + UINT16 PcirOffset; +} EFI_PCI_EXPANSION_ROM_HEADER; + +typedef struct { + UINT32 Signature; // "PCIR" + UINT16 VendorId; + UINT16 DeviceId; + UINT16 Reserved0; + UINT16 Length; + UINT8 Revision; + UINT8 ClassCode[3]; + UINT16 ImageLength; + UINT16 CodeRevision; + UINT8 CodeType; + UINT8 Indicator; + UINT16 Reserved1; +} PCI_DATA_STRUCTURE; +#pragma pack() + +#endif + + + + + + diff --git a/include/protocol/adapterdebug.h b/include/protocol/adapterdebug.h new file mode 100644 index 0000000..06d461a --- /dev/null +++ b/include/protocol/adapterdebug.h @@ -0,0 +1,32 @@ +#ifndef _ADAPTER_DEBUG_H +#define _ADAPTER_DEBUG_H + +/*++ + +Copyright (c) 1999 Intel Corporation + +Module Name: + + AdapterDebug.h + +Abstract: + + Protocol to debug the EDD 3.0 enablement of BIOS option ROMs + + + +Revision History + +--*/ + +// {82F86881-282B-11d4-BC7D-0080C73C8881} +#define ADAPTER_DEBUG_PROTOCOL \ +{ 0x82f86881, 0x282b, 0x11d4, {0xbc, 0x7d, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81} } + +// +// This protocol points to the BIOS_LEGACY_DRIVE data structure +// see edd.h for more details +// + +#endif + diff --git a/include/protocol/eficonsplit.h b/include/protocol/eficonsplit.h new file mode 100644 index 0000000..366cda0 --- /dev/null +++ b/include/protocol/eficonsplit.h @@ -0,0 +1,32 @@ +#ifndef _EFI_CONFORK_H +#define _EFI_CONFORK_H +/*++ + +Copyright (c) 1999 Intel Corporation + +Module Name: + +Abstract: + + + +Revision History + +--*/ + + + +// +// ConOut Forker Protocol +// + +#define TEXT_OUT_SPLITER_PROTOCOL \ + { 0x56d830a0, 0x7e7a, 0x11d3, {0xbb, 0xa0, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} } + +#define ERROR_OUT_SPLITER_PROTOCOL \ + { 0xf0ba9039, 0x68f1, 0x425e, {0xaa, 0x7f, 0xd9, 0xaa, 0xf9, 0x1b, 0x82, 0xa1}} + +#define TEXT_IN_SPLITER_PROTOCOL \ + { 0xf9a3c550, 0x7fb5, 0x11d3, {0xbb, 0xa0, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} } + +#endif diff --git a/include/protocol/efidbg.h b/include/protocol/efidbg.h new file mode 100644 index 0000000..1aa09c1 --- /dev/null +++ b/include/protocol/efidbg.h @@ -0,0 +1,210 @@ +/* + * Copyright (c) 1999, 2000 + * Intel Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * + * This product includes software developed by Intel Corporation and + * its contributors. + * + * 4. Neither the name of Intel Corporation or its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef _EFIDBG_H_ +#define _EFIDBG_H_ + +#include "eficontext.h" +#include "efiser.h" + +typedef struct _DEBUGPORT_16550_CONFIG_DATA { + UINT32 PortAddress; + UINT64 BaudRate; + UINT32 ReceiveFifoDepth; + UINT32 Timeout; + UINT8 Parity; + UINT8 DataBits; + UINT8 StopBits; + UINT32 ControlMask; + BOOLEAN RtsCtsEnable; // RTS, CTS control +} DEBUGPORT_16550_CONFIG_DATA; + +typedef struct _DEBUGPORT_16550_DEVICE_PATH { + EFI_DEVICE_PATH Header; + DEBUGPORT_16550_CONFIG_DATA ConfigData; +} DEBUGPORT_16550_DEVICE_PATH; + +typedef union { + EFI_DEVICE_PATH DevPath; + DEBUGPORT_16550_DEVICE_PATH Uart; + // add new types of debugport device paths to this union... +} DEBUGPORT_DEV_PATH; + + +// +// Debug Support protocol {2755590C-6F3C-42FA-9EA4-A3BA543CDA25} +// + +#define DEBUG_SUPPORT_PROTOCOL \ +{ 0x2755590C, 0x6F3C, 0x42fa, 0x9E, 0xA4, 0xA3, 0xBA, 0x54, 0x3C, 0xDA, 0x25 } + + +typedef UINTN EXCEPTION_TYPE; + +typedef +VOID +(*EXCEPTION_HANDLER) ( + IN EXCEPTION_TYPE ExceptionType, + IN SYSTEM_CONTEXT *SystemContext + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_REGISTER_TIMER_TICK_CALLBACK) ( + IN struct _EFI_DEBUG_SUPPORT_INTERFACE *This, + IN EXCEPTION_HANDLER TimerTickCallback + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_REGISTER_EXCEPTION_HANDLER) ( + IN struct _EFI_DEBUG_SUPPORT_INTERFACE *This, + IN EXCEPTION_HANDLER ExceptionHandler, + IN EXCEPTION_TYPE ExceptionType + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IP_CALL_TRACE) ( + IN struct _EFI_DEBUG_SUPPORT_INTERFACE *This + ); + + +#define EFI_DEBUG_SUPPORT_INTERFACE_REVISION 0x00010000 + +typedef struct _EFI_DEBUG_SUPPORT_INTERFACE { + UINT32 Revision; + EFI_REGISTER_TIMER_TICK_CALLBACK RegisterTimerTickCallback; + EFI_REGISTER_EXCEPTION_HANDLER RegisterExceptionHandler; + EFI_IP_CALL_TRACE IpCallTrace; +} EFI_DEBUG_SUPPORT_INTERFACE; + + +// +// Debugport io protocol {EBA4E8D2-3858-41EC-A281-2647BA9660D0} +// + +#define DEBUGPORT_IO_PROTOCOL \ +{ 0XEBA4E8D2, 0X3858, 0X41EC, 0XA2, 0X81, 0X26, 0X47, 0XBA, 0X96, 0X60, 0XD0 } + + +typedef +EFI_STATUS +(EFIAPI *EFI_DEBUGPORT_IO_RESET) ( + IN struct _EFI_DEBUGPORT_IO_INTERFACE *This + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_DEBUGPORT_IO_READ) ( + IN struct _EFI_DEBUGPORT_IO_INTERFACE *This, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_DEBUGPORT_IO_WRITE) ( + IN struct _EFI_DEBUGPORT_IO_INTERFACE *This, + IN OUT UINTN *BufferSize, + IN VOID *Buffer + ); + +#define EFI_DEBUGPORT_IO_INTERFACE_REVISION 0x00010000 + +typedef struct _EFI_DEBUGPORT_IO_INTERFACE { + UINT32 Revision; + EFI_DEBUGPORT_IO_READ Read; + EFI_DEBUGPORT_IO_WRITE Write; + EFI_DEBUGPORT_IO_RESET Reset; +} EFI_DEBUGPORT_IO_INTERFACE; + + +// +// Debugport UART16550 control protocol {628EA978-4C26-4605-BC02-A42A496917DD} +// + +#define DEBUGPORT_UART16550_CONTROL_PROTOCOL \ +{ 0X628EA978, 0X4C26, 0X4605, 0XBC, 0X2, 0XA4, 0X2A, 0X49, 0X69, 0X17, 0XDD } + +// Note: The definitions for EFI_PARITY_TYPE, EFI_STOP_BITS_TYPE, and +// SERIAL_IO_MODE are included from efiser.h + +typedef +EFI_STATUS +(EFIAPI *EFI_UART16550_SET_ATTRIBUTES) ( + IN struct _EFI_DEBUGPORT_UART16550_CONTROL_INTERFACE *This, + IN UINT64 BaudRate, + IN UINT32 ReceiveFifoDepth, + IN UINT32 Timeout, + IN EFI_PARITY_TYPE Parity, + IN UINT8 DataBits, + IN EFI_STOP_BITS_TYPE StopBits + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_UART16550_SET_CONTROL_BITS) ( + IN struct _EFI_DEBUGPORT_UART16550_CONTROL_INTERFACE *This, + IN UINT32 Control + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_UART16550_GET_CONTROL_BITS) ( + IN struct _EFI_DEBUGPORT_UART16550_CONTROL_INTERFACE *This, + OUT UINT32 *Control + ); + +#define EFI_DEBUGPORT_UART16550_CONTROL_INTERFACE_REVISION 0x00010000 + +typedef struct _EFI_DEBUGPORT_UART16550_CONTROL_INTERFACE { + UINT32 Revision; + EFI_UART16550_SET_ATTRIBUTES SetAttributes; + EFI_UART16550_SET_CONTROL_BITS SetControl; + EFI_UART16550_GET_CONTROL_BITS GetControl; + DEBUGPORT_16550_CONFIG_DATA *Mode; +} EFI_DEBUGPORT_UART16550_CONTROL_INTERFACE; + + +#define DEVICE_PATH_DEBUGPORT DEBUGPORT_IO_PROTOCOL + +#endif /* _EFIDBG_H_ */ diff --git a/include/protocol/efivar.h b/include/protocol/efivar.h new file mode 100644 index 0000000..91414e8 --- /dev/null +++ b/include/protocol/efivar.h @@ -0,0 +1,133 @@ +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + +Abstract: + + + +Revision History + +--*/ + + + +// +// The variable store protocol interface is specific to the reference +// implementation. The initialization code adds variable store devices +// to the system, and the FW connects to the devices to provide the +// variable store interfaces through these devices. +// + +// +// Variable Store Device protocol +// + +#define VARIABLE_STORE_PROTOCOL \ + { 0xf088cd91, 0xa046, 0x11d2, {0x8e, 0x42, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} } + +INTERFACE_DECL(_EFI_VARIABLE_STORE); + +typedef +EFI_STATUS +(EFIAPI *EFI_STORE_CLEAR) ( + IN struct _EFI_VARIABLE_STORE *This, + IN UINTN BankNo, + IN OUT VOID *Scratch + ); + + +typedef +EFI_STATUS +(EFIAPI *EFI_STORE_READ) ( + IN struct _EFI_VARIABLE_STORE *This, + IN UINTN BankNo, + IN UINTN Offset, + IN UINTN BufferSize, + OUT VOID *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_STORE_UPDATE) ( + IN struct _EFI_VARIABLE_STORE *This, + IN UINTN BankNo, + IN UINTN Offset, + IN UINTN BufferSize, + IN VOID *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_STORE_SIZE) ( + IN struct _EFI_VARIABLE_STORE *This, + IN UINTN NoBanks + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TRANSACTION_UPDATE) ( + IN struct _EFI_VARIABLE_STORE *This, + IN UINTN BankNo, + IN VOID *NewContents + ); + +typedef struct _EFI_VARIABLE_STORE { + + // + // Number of banks and bank size + // + + UINT32 Attributes; + UINT32 BankSize; + UINT32 NoBanks; + + // + // Functions to access the storage banks + // + + EFI_STORE_CLEAR ClearStore; + EFI_STORE_READ ReadStore; + EFI_STORE_UPDATE UpdateStore; + EFI_STORE_SIZE SizeStore OPTIONAL; + EFI_TRANSACTION_UPDATE TransactionUpdate OPTIONAL; + +} EFI_VARIABLE_STORE; + + +// +// +// ClearStore() - A function to clear the requested storage bank. A cleared +// bank contains all "on" bits. +// +// ReadStore() - Read data from the requested store. +// +// UpdateStore() - Updates data on the requested store. The FW will only +// ever issue updates to clear bits in the store. Updates must be +// performed in LSb to MSb order of the update buffer. +// +// SizeStore() - An optional function for non-runtime stores that can be +// dynamically sized. The FW will only ever increase or decrease the store +// by 1 banksize at a time, and it is always adding or removing a bank from +// the end of the store. +// +// By default the FW will update variables and storage banks in an +// "atomic" manner by keeping 1 old copy of the data during an update, +// and recovering appropiately if the power is lost during the middle +// of an operation. To do this the FW needs to have multiple banks +// of storage dedicated to its use. If that's not possible, the driver +// can implement an atomic bank update function and the FW will allow +// 1 bank in this case. (It will allow any number of banks, +// but it won't require an "extra" bank to provide its bank transaction +// function). +// +// TransactionUpdate() - An optional function that can clear & update an +// entire bank in an "atomic" fashion. If the operation fails in the +// middle the driver is responsible for having either the previous copy +// of the bank's data or the new copy. A copy that's partially written +// is not valid as internal data settings may get lost. Supply this +// function only when needed. +// + diff --git a/include/protocol/ia64/eficontext.h b/include/protocol/ia64/eficontext.h new file mode 100644 index 0000000..1a39a6d --- /dev/null +++ b/include/protocol/ia64/eficontext.h @@ -0,0 +1,208 @@ +/* + * Copyright (c) 1999, 2000 + * Intel Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * + * This product includes software developed by Intel Corporation and + * its contributors. + * + * 4. Neither the name of Intel Corporation or its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef _EFICONTEXT_H_ +#define _EFICONTEXT_H_ + + +// +// IA-64 processor exception types +// +#define EXCPT_ALT_DTLB 4 +#define EXCPT_DNESTED_TLB 5 +#define EXCPT_BREAKPOINT 11 +#define EXCPT_EXTERNAL_INTERRUPT 12 +#define EXCPT_GEN_EXCEPT 24 +#define EXCPT_NAT_CONSUMPTION 26 +#define EXCPT_DEBUG_EXCEPT 29 +#define EXCPT_UNALIGNED_ACCESS 30 +#define EXCPT_FP_FAULT 32 +#define EXCPT_FP_TRAP 33 +#define EXCPT_TAKEN_BRANCH 35 +#define EXCPT_SINGLE_STEP 36 + +// +// IA-64 processor context definition - must be 512 byte aligned!!! +// +typedef +struct { + UINT64 reserved; // necessary to preserve alignment for the correct bits in UNAT and to insure F2 is 16 byte aligned... + + UINT64 r1; + UINT64 r2; + UINT64 r3; + UINT64 r4; + UINT64 r5; + UINT64 r6; + UINT64 r7; + UINT64 r8; + UINT64 r9; + UINT64 r10; + UINT64 r11; + UINT64 r12; + UINT64 r13; + UINT64 r14; + UINT64 r15; + UINT64 r16; + UINT64 r17; + UINT64 r18; + UINT64 r19; + UINT64 r20; + UINT64 r21; + UINT64 r22; + UINT64 r23; + UINT64 r24; + UINT64 r25; + UINT64 r26; + UINT64 r27; + UINT64 r28; + UINT64 r29; + UINT64 r30; + UINT64 r31; + + UINT64 f2[2]; + UINT64 f3[2]; + UINT64 f4[2]; + UINT64 f5[2]; + UINT64 f6[2]; + UINT64 f7[2]; + UINT64 f8[2]; + UINT64 f9[2]; + UINT64 f10[2]; + UINT64 f11[2]; + UINT64 f12[2]; + UINT64 f13[2]; + UINT64 f14[2]; + UINT64 f15[2]; + UINT64 f16[2]; + UINT64 f17[2]; + UINT64 f18[2]; + UINT64 f19[2]; + UINT64 f20[2]; + UINT64 f21[2]; + UINT64 f22[2]; + UINT64 f23[2]; + UINT64 f24[2]; + UINT64 f25[2]; + UINT64 f26[2]; + UINT64 f27[2]; + UINT64 f28[2]; + UINT64 f29[2]; + UINT64 f30[2]; + UINT64 f31[2]; + + UINT64 pr; + + UINT64 b0; + UINT64 b1; + UINT64 b2; + UINT64 b3; + UINT64 b4; + UINT64 b5; + UINT64 b6; + UINT64 b7; + + // application registers + UINT64 ar_rsc; + UINT64 ar_bsp; + UINT64 ar_bspstore; + UINT64 ar_rnat; + + UINT64 ar_fcr; + + UINT64 ar_eflag; + UINT64 ar_csd; + UINT64 ar_ssd; + UINT64 ar_cflg; + UINT64 ar_fsr; + UINT64 ar_fir; + UINT64 ar_fdr; + + UINT64 ar_ccv; + + UINT64 ar_unat; + + UINT64 ar_fpsr; + + UINT64 ar_pfs; + UINT64 ar_lc; + UINT64 ar_ec; + + // control registers + UINT64 cr_dcr; + UINT64 cr_itm; + UINT64 cr_iva; + UINT64 cr_pta; + UINT64 cr_ipsr; + UINT64 cr_isr; + UINT64 cr_iip; + UINT64 cr_ifa; + UINT64 cr_itir; + UINT64 cr_iipa; + UINT64 cr_ifs; + UINT64 cr_iim; + UINT64 cr_iha; + + // debug registers + UINT64 dbr0; + UINT64 dbr1; + UINT64 dbr2; + UINT64 dbr3; + UINT64 dbr4; + UINT64 dbr5; + UINT64 dbr6; + UINT64 dbr7; + + UINT64 ibr0; + UINT64 ibr1; + UINT64 ibr2; + UINT64 ibr3; + UINT64 ibr4; + UINT64 ibr5; + UINT64 ibr6; + UINT64 ibr7; + + // virtual registers + UINT64 int_nat; // nat bits for R1-R31 + +} SYSTEM_CONTEXT; + +#endif /* _EFI_CONTEXT_H_ */ diff --git a/include/protocol/intload.h b/include/protocol/intload.h new file mode 100644 index 0000000..911add9 --- /dev/null +++ b/include/protocol/intload.h @@ -0,0 +1,27 @@ +/*++ + +Copyright (c) 1999 Intel Corporation + +Module Name: + + intload + +Abstract: + + EFI support for loading internally linked in apps + + + +Revision History + +--*/ + +#ifndef _INTERNAL_LOAD_INCLUDE_ +#define _INTERNAL_LOAD_INCLUDE_ + +// {D65A6B8C-71E5-4df0-A909-F0D2992B5AA9} +#define INTERNAL_SHELL_GUID \ + { 0xd65a6b8c, 0x71e5, 0x4df0, {0xa9, 0x09, 0xf0, 0xd2, 0x99, 0x2b, 0x5a, 0xa9} } + + +#endif diff --git a/include/protocol/legacyboot.h b/include/protocol/legacyboot.h new file mode 100644 index 0000000..1762e03 --- /dev/null +++ b/include/protocol/legacyboot.h @@ -0,0 +1,119 @@ +/*++ + +Copyright (c) 1999 Intel Corporation + +Module Name: + + legacyboot + +Abstract: + + EFI support for legacy boot + + + +Revision History + +--*/ + +#ifndef _LEGACY_BOOT_INCLUDE_ +#define _LEGACY_BOOT_INCLUDE_ + +#define LEGACY_BOOT_PROTOCOL \ + { 0x376e5eb2, 0x30e4, 0x11d3, { 0xba, 0xe5, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } + +#pragma pack(1) + +// +// BBS 1.01 (See Appendix A) IPL and BCV Table Entry Data structure. +// Seg:Off pointers have been converted to EFI pointers in this data structure +// This is the structure that also maps to the EFI device path for the boot selection +// +typedef struct { + UINT16 DeviceType; + UINT16 StatusFlag; + UINT32 Reserved; + VOID *BootHandler; // Not an EFI entry point + CHAR8 *DescString; +} BBS_TABLE_ENTRY; +#pragma pack() + +typedef +EFI_STATUS +(EFIAPI *LEGACY_BOOT_CALL) ( + IN EFI_DEVICE_PATH *DevicePath + ); + + +// +// BBS support functions +// PnP Call numbers and BiosSelector hidden in implementation +// + +typedef enum { + IplRelative, + BcvRelative +} BBS_TYPE; + +INTERFACE_DECL(_LEGACY_BOOT_INTERFACE); + +// +// == PnP Function 0x60 then BbsVersion == 0x0101 if this call fails then BbsVersion == 0x0000 +// + +// +// == PnP Function 0x61 +// +typedef +EFI_STATUS +(EFIAPI *GET_DEVICE_COUNT) ( + IN struct _LEGACY_BOOT_INTERFACE *This, + IN BBS_TYPE *TableType, + OUT UINTN *DeviceCount, + OUT UINTN *MaxCount + ); + +// +// == PnP Function 0x62 +// +typedef +EFI_STATUS +(EFIAPI *GET_PRIORITY_AND_TABLE) ( + IN struct _LEGACY_BOOT_INTERFACE *This, + IN BBS_TYPE *TableType, + IN OUT UINTN *PrioritySize, // MaxCount * sizeof(UINT8) + OUT UINTN *Priority, + IN OUT UINTN *TableSize, // MaxCount * sizeof(BBS_TABLE_ENTRY) + OUT BBS_TABLE_ENTRY *TableEntrySize + ); + +// +// == PnP Function 0x63 +// +typedef +EFI_STATUS +(EFIAPI *SET_PRIORITY) ( + IN struct _LEGACY_BOOT_INTERFACE *This, + IN BBS_TYPE *TableType, + IN OUT UINTN *PrioritySize, + OUT UINTN *Priority + ); + +typedef struct _LEGACY_BOOT_INTERFACE { + LEGACY_BOOT_CALL BootIt; + + // + // New functions to allow BBS booting to be configured from EFI + // + UINTN BbsVersion; // Currently 0x0101 + GET_DEVICE_COUNT GetDeviceCount; + GET_PRIORITY_AND_TABLE GetPriorityAndTable; + SET_PRIORITY SetPriority; +} LEGACY_BOOT_INTERFACE; + +EFI_STATUS +PlInitializeLegacyBoot ( + VOID + ); + +#endif diff --git a/include/protocol/make.inf b/include/protocol/make.inf new file mode 100644 index 0000000..f3bb907 --- /dev/null +++ b/include/protocol/make.inf @@ -0,0 +1,13 @@ +# +# +# + +[sources] + efivar.h + legacyboot.h + VgaClass.h + intload.h + +[ia32sources] + +[ia64sources] diff --git a/include/protocol/makefile.hdr b/include/protocol/makefile.hdr new file mode 100644 index 0000000..118d6ba --- /dev/null +++ b/include/protocol/makefile.hdr @@ -0,0 +1,29 @@ + +# +# This is a machine generated file - DO NOT EDIT +# Generated by genmake.exe +# Generated from make.inf +# Copyright (c) 1998 Intel Corporation +# + +INC_DEPS = $(INC_DEPS) \ + $(SDK_INSTALL_DIR)\include\efi\protocol\efivar.h \ + $(SDK_INSTALL_DIR)\include\efi\protocol\legacyboot.h \ + $(SDK_INSTALL_DIR)\include\efi\protocol\vgaclass.h \ + $(SDK_INSTALL_DIR)\include\efi\protocol\efidbg.h \ + + +!IF "$(PROCESSOR)" == "Ia32" +INC_DEPS = $(INC_DEPS) \ + + +!ENDIF + + +!IF "$(PROCESSOR)" == "Ia64" +INC_DEPS = $(INC_DEPS) \ + $(SDK_INSTALL_DIR)\include\efi\protocol\$(PROCESSOR)\eficontext.h \ + + +!ENDIF + diff --git a/include/protocol/piflash64.h b/include/protocol/piflash64.h new file mode 100644 index 0000000..3566d4d --- /dev/null +++ b/include/protocol/piflash64.h @@ -0,0 +1,121 @@ +#ifndef _PIFLASH64_H +#define _PIFLASH64_H + +/*++ + +Copyright (c) 1999 Intel Corporation + +Module Name: + + PIflash64.h + +Abstract: + + Iflash64.efi protocol to abstract iflash from + the system. + +Revision History + +--*/ + +// +// Guid that identifies the IFLASH protocol +// +#define IFLASH64_PROTOCOL_PROTOCOL \ + { 0x65cba110, 0x74ab, 0x11d3, 0xbb, 0x89, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 }; + +// +// Unlock FLASH from StartAddress to EndAddress and return a LockKey +// +typedef +EFI_STATUS +(EFIAPI *UNLOCK_FLASH_API)( + IN struct _IFLASH64_PROTOCOL_INTERFACE *This + ); + +// +// Lock the flash represented by the LockKey +// +typedef +EFI_STATUS +(EFIAPI *LOCK_FLASH_API)( + IN struct _IFLASH64_PROTOCOL_INTERFACE *This + ); + +// +// Status callback for a utility like IFLASH64 +// +// Token would map to a list like Ted proposed. The utility has no idea what +// happens on the other side. +// ErrorStatus - Level of Error or success. Independent of Token. If you +// don't know the token you will at least know pass or fail. +// String - Optional extra information about the error. Could be used for +// debug or future expansion +// +// Attributes - Options screen attributes for String. Could allow the string to be different colors. +// +typedef +EFI_STATUS +(EFIAPI *UTILITY_PROGRESS_API)( + IN struct _IFLASH64_PROTOCOL_INTERFACE *This, + IN UINTN Token, + IN EFI_STATUS ErrorStatus, + IN CHAR16 *String, OPTIONAL + IN UINTN *Attributes OPTIONAL + ); + +// +// Token Values +// +// IFlash64 Token Codes +#define IFLASH_TOKEN_IFLASHSTART 0xB0 // IFlash64 has started +#define IFLASH_TOKEN_READINGFILE 0xB1 // Reading File +#define IFLASH_TOKEN_INITVPP 0xB2 // Initializing Vpp +#define IFLASH_TOKEN_DISABLEVPP 0x10 // Disable Vpp +#define IFLASH_TOKEN_FLASHUNLOCK 0xB3 // Unlocking FLASH Devices +#define IFLASH_TOKEN_FLASHERASE 0xB4 // Erasing FLASH Devices +#define IFLASH_TOKEN_FLASHPROGRAM 0xB5 // Programming FLASH +#define IFLASH_TOKEN_FLASHVERIFY 0xB6 // Verifying FLASH +#define IFLASH_TOKEN_UPDATESUCCES 0xB7 // FLASH Updage Success! + +#define IFLASH_TOKEN_PROGRESS_READINGFILE 0x11 // % Reading File +#define IFLASH_TOKEN_PROGRESS_FLASHUNLOCK 0x13 // % Unlocking FLASH Devices +#define IFLASH_TOKEN_PROGRESS_FLASHERASE 0x14 // % Erasing FLASH Devices +#define IFLASH_TOKEN_PROGRESS_FLASHPROGRAM 0x15 // % Programming FLASH +#define IFLASH_TOKEN_PROGRESS_FLASHVERIFY 0x16 // % Verifying FLASH + +#define IFLASH_TOKEN_READINGFILE_ER 0xB8 // File Read Error +#define IFLASH_TOKEN_INITVPP_ER 0xB9 // Initialization of IFB Error +#define IFLASH_TOKEN_FLASHUNLOCK_ER 0xBA // FLASH Unlock Error +#define IFLASH_TOKEN_FLASHERASE_ER 0xBB // FLASH Erase Error +#define IFLASH_TOKEN_FLASHVERIFY_ER 0xBC // FLASH Verify Error +#define IFLASH_TOKEN_FLASHPROG_ER 0xBD // FLASH Program Error + +#define IFLASH_TABLE_END 0x00 + +// +// If this number changes one of the existing API's has changes +// +#define IFLASH_PI_MAJOR_VERSION 0x01 + +// +// This number changes when new APIs or data variables get added to the end +// of the data structure +// +#define IFLASH_PI_MINOR_VERSION 0x01 + +typedef struct _IFLASH64_PROTOCOL_INTERFACE { + UINT32 MajorVersion; + UINT32 MinorVersion; + UNLOCK_FLASH_API UnlockFlash; + LOCK_FLASH_API LockFlash; + UTILITY_PROGRESS_API Progress; + + // + // Future expansion goes here + // + +} IFLASH64_PROTOCOL_INTERFACE; + + +#endif diff --git a/include/protocol/readme.txt b/include/protocol/readme.txt new file mode 100644 index 0000000..66e155c --- /dev/null +++ b/include/protocol/readme.txt @@ -0,0 +1,3 @@ +The protocol directory contains non Architectural +Protocols that span the FW, Platform, or application +space. \ No newline at end of file diff --git a/include/protocol/vgaclass.h b/include/protocol/vgaclass.h new file mode 100644 index 0000000..1a0e828 --- /dev/null +++ b/include/protocol/vgaclass.h @@ -0,0 +1,95 @@ +#ifndef _VGA_CLASS_H +#define _VGA_CLASS_H + +/*++ + +Copyright (c) 1999 Intel Corporation + +Module Name: + + VgaClass.h + +Abstract: + + Vga Mini port binding to Vga Class protocol + + + +Revision History + +--*/ + +// +// VGA Device Structure +// + +// {0E3D6310-6FE4-11d3-BB81-0080C73C8881} +#define VGA_CLASS_DRIVER_PROTOCOL \ + { 0xe3d6310, 0x6fe4, 0x11d3, {0xbb, 0x81, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81} } + +typedef +EFI_STATUS +(* INIT_VGA_CARD) ( + IN UINTN VgaMode, + IN VOID *Context + ); + +typedef struct { + UINTN MaxColumns; + UINTN MaxRows; +} MAX_CONSOLE_GEOMETRY; + +#define VGA_CON_OUT_DEV_SIGNATURE EFI_SIGNATURE_32('c','v','g','a') +typedef struct { + UINTN Signature; + + EFI_HANDLE Handle; + SIMPLE_TEXT_OUTPUT_INTERFACE ConOut; + SIMPLE_TEXT_OUTPUT_MODE ConOutMode; + EFI_DEVICE_PATH *DevicePath; + + UINT8 *Buffer; + EFI_DEVICE_IO_INTERFACE *DeviceIo; + + // + // Video Card Context + // + INIT_VGA_CARD InitVgaCard; + VOID *VgaCardContext; + MAX_CONSOLE_GEOMETRY *Geometry; + // + // Video buffer normally 0xb8000 + // + UINT64 VideoBuffer; + + // + // Clear Screen & Default Attribute + // + UINT32 Attribute; + + // + // -1 means search for active VGA device + // + EFI_PCI_ADDRESS_UNION Pci; +} VGA_CON_OUT_DEV; + +#define VGA_CON_OUT_DEV_FROM_THIS(a) CR(a, VGA_CON_OUT_DEV, ConOut, VGA_CON_OUT_DEV_SIGNATURE) + +// +// Vga Class Driver Protocol. +// GUID defined in EFI Lib +// + +typedef +EFI_STATUS +(EFIAPI *INSTALL_VGA_DRIVER) ( + IN VGA_CON_OUT_DEV *ConOutDev + ); + +typedef struct { + UINT32 Version; + INSTALL_VGA_DRIVER InstallGenericVgaDriver; +} INSTALL_VGA_DRIVER_INTERFACE; + +#endif + diff --git a/include/riscv64/efibind.h b/include/riscv64/efibind.h new file mode 100644 index 0000000..7e5ef35 --- /dev/null +++ b/include/riscv64/efibind.h @@ -0,0 +1,128 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-2-Clause */ +/* + * Copyright (C) 2014 - 2015 Linaro Ltd. + * Author: Ard Biesheuvel + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice and this list of conditions, without modification. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License as published by the Free Software Foundation; + * either version 2 of the License, or (at your option) any later version. + */ + +#include + +// +// Basic EFI types of various widths +// + +#include + +typedef uint64_t UINT64; +typedef int64_t INT64; +typedef uint32_t UINT32; +typedef int32_t INT32; +typedef uint16_t UINT16; +typedef int16_t INT16; +typedef uint8_t UINT8; +typedef int8_t INT8; +typedef char CHAR8; +typedef wchar_t CHAR16; +#define WCHAR CHAR16 +#undef VOID +typedef void VOID; +typedef int64_t INTN; +typedef uint64_t UINTN; + +#define EFI_ERROR_MASK 0x8000000000000000 +#define EFIERR(a) (EFI_ERROR_MASK | a) +#define EFIERR_OEM(a) (0xc000000000000000 | a) + +#define BAD_POINTER 0xFBFBFBFBFBFBFBFB +#define MAX_ADDRESS 0xFFFFFFFFFFFFFFFF + +#define BREAKPOINT() while(1); + +// +// Pointers must be aligned to these address to function +// +#define MIN_ALIGNMENT_SIZE 8 + +#define ALIGN_VARIABLE(Value, Adjustment) \ + (UINTN)Adjustment = 0; \ + if((UINTN)Value % MIN_ALIGNMENT_SIZE) \ + (UINTN)Adjustment = MIN_ALIGNMENT_SIZE - ((UINTN)Value % MIN_ALIGNMENT_SIZE); \ + Value = (UINTN)Value + (UINTN)Adjustment + +// +// Define macros to build data structure signatures from characters. +// +#define EFI_SIGNATURE_16(A,B) ((A) | (B<<8)) +#define EFI_SIGNATURE_32(A,B,C,D) (EFI_SIGNATURE_16(A,B) | (EFI_SIGNATURE_16(C,D) << 16)) +#define EFI_SIGNATURE_64(A,B,C,D,E,F,G,H) (EFI_SIGNATURE_32(A,B,C,D) | ((UINT64)(EFI_SIGNATURE_32(E,F,G,H)) << 32)) + +// +// EFIAPI - prototype calling convention for EFI function pointers +// BOOTSERVICE - prototype for implementation of a boot service interface +// RUNTIMESERVICE - prototype for implementation of a runtime service interface +// RUNTIMEFUNCTION - prototype for implementation of a runtime function that is not a service +// RUNTIME_CODE - pragma macro for declaring runtime code +// +#ifndef EFIAPI // Forces EFI calling conventions reguardless of compiler options +#define EFIAPI // Substitute expresion to force C calling convention +#endif +#define BOOTSERVICE +#define RUNTIMESERVICE +#define RUNTIMEFUNCTION +#define RUNTIME_CODE(a) alloc_text("rtcode", a) +#define BEGIN_RUNTIME_DATA() data_seg("rtdata") +#define END_RUNTIME_DATA() data_seg("") + +#define VOLATILE volatile +#define MEMORY_FENCE __sync_synchronize + +// +// When build similiar to FW, then link everything together as +// one big module. For the MSVC toolchain, we simply tell the +// linker what our driver init function is using /ENTRY. +// +#if defined(_MSC_EXTENSIONS) +#define EFI_DRIVER_ENTRY_POINT(InitFunction) \ + __pragma(comment(linker, "/ENTRY:" # InitFunction)) +#else +#define EFI_DRIVER_ENTRY_POINT(InitFunction) \ + UINTN \ + InitializeDriver ( \ + VOID *ImageHandle, \ + VOID *SystemTable \ + ) \ + { \ + return InitFunction(ImageHandle, \ + SystemTable); \ + } \ + \ + EFI_STATUS efi_main( \ + EFI_HANDLE image, \ + EFI_SYSTEM_TABLE *systab \ + ) __attribute__((weak, \ + alias ("InitializeDriver"))); +#endif + +#define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \ + (_if)->LoadInternal(type, name, entry) + +// +// Some compilers don't support the forward reference construct: +// typedef struct XXXXX +// +// The following macro provide a workaround for such cases. +#define INTERFACE_DECL(x) struct x + +#define uefi_call_wrapper(func, va_num, ...) func(__VA_ARGS__) +#define EFI_FUNCTION diff --git a/include/riscv64/efilibplat.h b/include/riscv64/efilibplat.h new file mode 100644 index 0000000..11f91e0 --- /dev/null +++ b/include/riscv64/efilibplat.h @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-2-Clause */ + +VOID +InitializeLibPlatform ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); diff --git a/include/riscv64/efisetjmp_arch.h b/include/riscv64/efisetjmp_arch.h new file mode 100644 index 0000000..f526143 --- /dev/null +++ b/include/riscv64/efisetjmp_arch.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-2-Clause */ + +#ifndef GNU_EFI_RISCV64_SETJMP_H +#define GNU_EFI_RISCV64_SETJMP_H + +#define JMPBUF_ALIGN 8 + +typedef struct { + /* GP regs */ + UINT64 s0; + UINT64 s1; + UINT64 s2; + UINT64 s3; + UINT64 s4; + UINT64 s5; + UINT64 s6; + UINT64 s7; + UINT64 s8; + UINT64 s9; + UINT64 s10; + UINT64 s11; + UINT64 sp; + UINT64 ra; + + /* FP regs */ + UINT64 fs0; + UINT64 fs1; + UINT64 fs2; + UINT64 fs3; + UINT64 fs4; + UINT64 fs5; + UINT64 fs6; + UINT64 fs7; + UINT64 fs8; + UINT64 fs9; + UINT64 fs10; + UINT64 fs11; +} EFI_ALIGN(JMPBUF_ALIGN) jmp_buf[1]; + +#endif /* GNU_EFI_RISCV64_SETJMP_H */ diff --git a/include/romload.h b/include/romload.h new file mode 100644 index 0000000..de747a7 --- /dev/null +++ b/include/romload.h @@ -0,0 +1,41 @@ +#ifndef _EFI_ROMLOAD_H +#define _EFI_ROMLOAD_H + +#define ROM_SIGNATURE 0xaa55 +#define PCIDS_SIGNATURE "PCIR" +#pragma pack(push) +#pragma pack(1) +typedef struct +{ + UINT8 Pcids_Sig[4]; + UINT16 VendId; + UINT16 DevId; + UINT16 Vpd_Off; + UINT16 Size; + UINT8 Rev; + UINT8 Class_Code[3]; + UINT16 Image_Len; + UINT16 Rev_Lvl; + UINT8 Code_Type; + UINT8 Indi; + UINT16 Rsvd; +}PciDataStructure; +typedef struct +{ + UINT16 Size; + UINT32 Header_Sig; + UINT16 SubSystem; + UINT16 MachineType; + UINT8 Resvd[10]; + UINT16 EfiOffset; +}ArchData; +typedef struct +{ + UINT16 Rom_Sig; + ArchData Arch_Data; + UINT16 Pcids_Off; + UINT8 resvd[38]; +}RomHeader; +#pragma pack(pop) + +#endif diff --git a/include/stb_truetype.h b/include/stb_truetype.h new file mode 100644 index 0000000..90a5c2e --- /dev/null +++ b/include/stb_truetype.h @@ -0,0 +1,5079 @@ +// stb_truetype.h - v1.26 - public domain +// authored from 2009-2021 by Sean Barrett / RAD Game Tools +// +// ======================================================================= +// +// NO SECURITY GUARANTEE -- DO NOT USE THIS ON UNTRUSTED FONT FILES +// +// This library does no range checking of the offsets found in the file, +// meaning an attacker can use it to read arbitrary memory. +// +// ======================================================================= +// +// This library processes TrueType files: +// parse files +// extract glyph metrics +// extract glyph shapes +// render glyphs to one-channel bitmaps with antialiasing (box filter) +// render glyphs to one-channel SDF bitmaps (signed-distance field/function) +// +// Todo: +// non-MS cmaps +// crashproof on bad data +// hinting? (no longer patented) +// cleartype-style AA? +// optimize: use simple memory allocator for intermediates +// optimize: build edge-list directly from curves +// optimize: rasterize directly from curves? +// +// ADDITIONAL CONTRIBUTORS +// +// Mikko Mononen: compound shape support, more cmap formats +// Tor Andersson: kerning, subpixel rendering +// Dougall Johnson: OpenType / Type 2 font handling +// Daniel Ribeiro Maciel: basic GPOS-based kerning +// +// Misc other: +// Ryan Gordon +// Simon Glass +// github:IntellectualKitty +// Imanol Celaya +// Daniel Ribeiro Maciel +// +// Bug/warning reports/fixes: +// "Zer" on mollyrocket Fabian "ryg" Giesen github:NiLuJe +// Cass Everitt Martins Mozeiko github:aloucks +// stoiko (Haemimont Games) Cap Petschulat github:oyvindjam +// Brian Hook Omar Cornut github:vassvik +// Walter van Niftrik Ryan Griege +// David Gow Peter LaValle +// David Given Sergey Popov +// Ivan-Assen Ivanov Giumo X. Clanjor +// Anthony Pesch Higor Euripedes +// Johan Duparc Thomas Fields +// Hou Qiming Derek Vinyard +// Rob Loach Cort Stratton +// Kenney Phillis Jr. Brian Costabile +// Ken Voskuil (kaesve) Yakov Galka +// +// VERSION HISTORY +// +// 1.26 (2021-08-28) fix broken rasterizer +// 1.25 (2021-07-11) many fixes +// 1.24 (2020-02-05) fix warning +// 1.23 (2020-02-02) query SVG data for glyphs; query whole kerning table (but only kern not GPOS) +// 1.22 (2019-08-11) minimize missing-glyph duplication; fix kerning if both 'GPOS' and 'kern' are defined +// 1.21 (2019-02-25) fix warning +// 1.20 (2019-02-07) PackFontRange skips missing codepoints; GetScaleFontVMetrics() +// 1.19 (2018-02-11) GPOS kerning, STBTT_fmod +// 1.18 (2018-01-29) add missing function +// 1.17 (2017-07-23) make more arguments const; doc fix +// 1.16 (2017-07-12) SDF support +// 1.15 (2017-03-03) make more arguments const +// 1.14 (2017-01-16) num-fonts-in-TTC function +// 1.13 (2017-01-02) support OpenType fonts, certain Apple fonts +// 1.12 (2016-10-25) suppress warnings about casting away const with -Wcast-qual +// 1.11 (2016-04-02) fix unused-variable warning +// 1.10 (2016-04-02) user-defined fabs(); rare memory leak; remove duplicate typedef +// 1.09 (2016-01-16) warning fix; avoid crash on outofmem; use allocation userdata properly +// 1.08 (2015-09-13) document stbtt_Rasterize(); fixes for vertical & horizontal edges +// 1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints; +// variant PackFontRanges to pack and render in separate phases; +// fix stbtt_GetFontOFfsetForIndex (never worked for non-0 input?); +// fixed an assert() bug in the new rasterizer +// replace assert() with STBTT_assert() in new rasterizer +// +// Full history can be found at the end of this file. +// +// LICENSE +// +// See end of file for license information. +// +// USAGE +// +// Include this file in whatever places need to refer to it. In ONE C/C++ +// file, write: +// #define STB_TRUETYPE_IMPLEMENTATION +// before the #include of this file. This expands out the actual +// implementation into that C/C++ file. +// +// To make the implementation private to the file that generates the implementation, +// #define STBTT_STATIC +// +// Simple 3D API (don't ship this, but it's fine for tools and quick start) +// stbtt_BakeFontBitmap() -- bake a font to a bitmap for use as texture +// stbtt_GetBakedQuad() -- compute quad to draw for a given char +// +// Improved 3D API (more shippable): +// #include "stb_rect_pack.h" -- optional, but you really want it +// stbtt_PackBegin() +// stbtt_PackSetOversampling() -- for improved quality on small fonts +// stbtt_PackFontRanges() -- pack and renders +// stbtt_PackEnd() +// stbtt_GetPackedQuad() +// +// "Load" a font file from a memory buffer (you have to keep the buffer loaded) +// stbtt_InitFont() +// stbtt_GetFontOffsetForIndex() -- indexing for TTC font collections +// stbtt_GetNumberOfFonts() -- number of fonts for TTC font collections +// +// Render a unicode codepoint to a bitmap +// stbtt_GetCodepointBitmap() -- allocates and returns a bitmap +// stbtt_MakeCodepointBitmap() -- renders into bitmap you provide +// stbtt_GetCodepointBitmapBox() -- how big the bitmap must be +// +// Character advance/positioning +// stbtt_GetCodepointHMetrics() +// stbtt_GetFontVMetrics() +// stbtt_GetFontVMetricsOS2() +// stbtt_GetCodepointKernAdvance() +// +// Starting with version 1.06, the rasterizer was replaced with a new, +// faster and generally-more-precise rasterizer. The new rasterizer more +// accurately measures pixel coverage for anti-aliasing, except in the case +// where multiple shapes overlap, in which case it overestimates the AA pixel +// coverage. Thus, anti-aliasing of intersecting shapes may look wrong. If +// this turns out to be a problem, you can re-enable the old rasterizer with +// #define STBTT_RASTERIZER_VERSION 1 +// which will incur about a 15% speed hit. +// +// ADDITIONAL DOCUMENTATION +// +// Immediately after this block comment are a series of sample programs. +// +// After the sample programs is the "header file" section. This section +// includes documentation for each API function. +// +// Some important concepts to understand to use this library: +// +// Codepoint +// Characters are defined by unicode codepoints, e.g. 65 is +// uppercase A, 231 is lowercase c with a cedilla, 0x7e30 is +// the hiragana for "ma". +// +// Glyph +// A visual character shape (every codepoint is rendered as +// some glyph) +// +// Glyph index +// A font-specific integer ID representing a glyph +// +// Baseline +// Glyph shapes are defined relative to a baseline, which is the +// bottom of uppercase characters. Characters extend both above +// and below the baseline. +// +// Current Point +// As you draw text to the screen, you keep track of a "current point" +// which is the origin of each character. The current point's vertical +// position is the baseline. Even "baked fonts" use this model. +// +// Vertical Font Metrics +// The vertical qualities of the font, used to vertically position +// and space the characters. See docs for stbtt_GetFontVMetrics. +// +// Font Size in Pixels or Points +// The preferred interface for specifying font sizes in stb_truetype +// is to specify how tall the font's vertical extent should be in pixels. +// If that sounds good enough, skip the next paragraph. +// +// Most font APIs instead use "points", which are a common typographic +// measurement for describing font size, defined as 72 points per inch. +// stb_truetype provides a point API for compatibility. However, true +// "per inch" conventions don't make much sense on computer displays +// since different monitors have different number of pixels per +// inch. For example, Windows traditionally uses a convention that +// there are 96 pixels per inch, thus making 'inch' measurements have +// nothing to do with inches, and thus effectively defining a point to +// be 1.333 pixels. Additionally, the TrueType font data provides +// an explicit scale factor to scale a given font's glyphs to points, +// but the author has observed that this scale factor is often wrong +// for non-commercial fonts, thus making fonts scaled in points +// according to the TrueType spec incoherently sized in practice. +// +// DETAILED USAGE: +// +// Scale: +// Select how high you want the font to be, in points or pixels. +// Call ScaleForPixelHeight or ScaleForMappingEmToPixels to compute +// a scale factor SF that will be used by all other functions. +// +// Baseline: +// You need to select a y-coordinate that is the baseline of where +// your text will appear. Call GetFontBoundingBox to get the baseline-relative +// bounding box for all characters. SF*-y0 will be the distance in pixels +// that the worst-case character could extend above the baseline, so if +// you want the top edge of characters to appear at the top of the +// screen where y=0, then you would set the baseline to SF*-y0. +// +// Current point: +// Set the current point where the first character will appear. The +// first character could extend left of the current point; this is font +// dependent. You can either choose a current point that is the leftmost +// point and hope, or add some padding, or check the bounding box or +// left-side-bearing of the first character to be displayed and set +// the current point based on that. +// +// Displaying a character: +// Compute the bounding box of the character. It will contain signed values +// relative to . I.e. if it returns x0,y0,x1,y1, +// then the character should be displayed in the rectangle from +// to = 32 && *text < 128) { + stbtt_aligned_quad q; + stbtt_GetBakedQuad(cdata, 512,512, *text-32, &x,&y,&q,1);//1=opengl & d3d10+,0=d3d9 + glTexCoord2f(q.s0,q.t0); glVertex2f(q.x0,q.y0); + glTexCoord2f(q.s1,q.t0); glVertex2f(q.x1,q.y0); + glTexCoord2f(q.s1,q.t1); glVertex2f(q.x1,q.y1); + glTexCoord2f(q.s0,q.t1); glVertex2f(q.x0,q.y1); + } + ++text; + } + glEnd(); +} +#endif +// +// +////////////////////////////////////////////////////////////////////////////// +// +// Complete program (this compiles): get a single bitmap, print as ASCII art +// +#if 0 +#include +#define STB_TRUETYPE_IMPLEMENTATION // force following include to generate implementation +#include "stb_truetype.h" + +char ttf_buffer[1<<25]; + +int main(int argc, char **argv) +{ + stbtt_fontinfo font; + unsigned char *bitmap; + int w,h,i,j,c = (argc > 1 ? atoi(argv[1]) : 'a'), s = (argc > 2 ? atoi(argv[2]) : 20); + + fread(ttf_buffer, 1, 1<<25, fopen(argc > 3 ? argv[3] : "c:/windows/fonts/arialbd.ttf", "rb")); + + stbtt_InitFont(&font, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer,0)); + bitmap = stbtt_GetCodepointBitmap(&font, 0,stbtt_ScaleForPixelHeight(&font, s), c, &w, &h, 0,0); + + for (j=0; j < h; ++j) { + for (i=0; i < w; ++i) + putchar(" .:ioVM@"[bitmap[j*w+i]>>5]); + putchar('\n'); + } + return 0; +} +#endif +// +// Output: +// +// .ii. +// @@@@@@. +// V@Mio@@o +// :i. V@V +// :oM@@M +// :@@@MM@M +// @@o o@M +// :@@. M@M +// @@@o@@@@ +// :M@@V:@@. +// +////////////////////////////////////////////////////////////////////////////// +// +// Complete program: print "Hello World!" banner, with bugs +// +#if 0 +char buffer[24<<20]; +unsigned char screen[20][79]; + +int main(int arg, char **argv) +{ + stbtt_fontinfo font; + int i,j,ascent,baseline,ch=0; + float scale, xpos=2; // leave a little padding in case the character extends left + char *text = "Heljo World!"; // intentionally misspelled to show 'lj' brokenness + + fread(buffer, 1, 1000000, fopen("c:/windows/fonts/arialbd.ttf", "rb")); + stbtt_InitFont(&font, buffer, 0); + + scale = stbtt_ScaleForPixelHeight(&font, 15); + stbtt_GetFontVMetrics(&font, &ascent,0,0); + baseline = (int) (ascent*scale); + + while (text[ch]) { + int advance,lsb,x0,y0,x1,y1; + float x_shift = xpos - (float) floor(xpos); + stbtt_GetCodepointHMetrics(&font, text[ch], &advance, &lsb); + stbtt_GetCodepointBitmapBoxSubpixel(&font, text[ch], scale,scale,x_shift,0, &x0,&y0,&x1,&y1); + stbtt_MakeCodepointBitmapSubpixel(&font, &screen[baseline + y0][(int) xpos + x0], x1-x0,y1-y0, 79, scale,scale,x_shift,0, text[ch]); + // note that this stomps the old data, so where character boxes overlap (e.g. 'lj') it's wrong + // because this API is really for baking character bitmaps into textures. if you want to render + // a sequence of characters, you really need to render each bitmap to a temp buffer, then + // "alpha blend" that into the working buffer + xpos += (advance * scale); + if (text[ch+1]) + xpos += scale*stbtt_GetCodepointKernAdvance(&font, text[ch],text[ch+1]); + ++ch; + } + + for (j=0; j < 20; ++j) { + for (i=0; i < 78; ++i) + putchar(" .:ioVM@"[screen[j][i]>>5]); + putchar('\n'); + } + + return 0; +} +#endif + + +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +//// +//// INTEGRATION WITH YOUR CODEBASE +//// +//// The following sections allow you to supply alternate definitions +//// of C library functions used by stb_truetype, e.g. if you don't +//// link with the C runtime library. + +#ifdef STB_TRUETYPE_IMPLEMENTATION + // #define your own (u)stbtt_int8/16/32 before including to override this + #ifndef stbtt_uint8 + typedef unsigned char stbtt_uint8; + typedef signed char stbtt_int8; + typedef unsigned short stbtt_uint16; + typedef signed short stbtt_int16; + typedef unsigned int stbtt_uint32; + typedef signed int stbtt_int32; + #endif + + typedef char stbtt__check_size32[sizeof(stbtt_int32)==4 ? 1 : -1]; + typedef char stbtt__check_size16[sizeof(stbtt_int16)==2 ? 1 : -1]; + + // e.g. #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h + #ifndef STBTT_ifloor + #include + #define STBTT_ifloor(x) ((int) floor(x)) + #define STBTT_iceil(x) ((int) ceil(x)) + #endif + + #ifndef STBTT_sqrt + #include + #define STBTT_sqrt(x) sqrt(x) + #define STBTT_pow(x,y) pow(x,y) + #endif + + #ifndef STBTT_fmod + #include + #define STBTT_fmod(x,y) fmod(x,y) + #endif + + #ifndef STBTT_cos + #include + #define STBTT_cos(x) cos(x) + #define STBTT_acos(x) acos(x) + #endif + + #ifndef STBTT_fabs + #include + #define STBTT_fabs(x) fabs(x) + #endif + + // #define your own functions "STBTT_malloc" / "STBTT_free" to avoid malloc.h + #ifndef STBTT_malloc + #include + #define STBTT_malloc(x,u) ((void)(u),malloc(x)) + #define STBTT_free(x,u) ((void)(u),free(x)) + #endif + + #ifndef STBTT_assert + #include + #define STBTT_assert(x) assert(x) + #endif + + #ifndef STBTT_strlen + #include + #define STBTT_strlen(x) strlen(x) + #endif + + #ifndef STBTT_memcpy + #include + #define STBTT_memcpy memcpy + #define STBTT_memset memset + #endif +#endif + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +//// +//// INTERFACE +//// +//// + +#ifndef __STB_INCLUDE_STB_TRUETYPE_H__ +#define __STB_INCLUDE_STB_TRUETYPE_H__ + +#ifdef STBTT_STATIC +#define STBTT_DEF static +#else +#define STBTT_DEF extern +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +// private structure +typedef struct +{ + unsigned char *data; + int cursor; + int size; +} stbtt__buf; + +////////////////////////////////////////////////////////////////////////////// +// +// TEXTURE BAKING API +// +// If you use this API, you only have to call two functions ever. +// + +typedef struct +{ + unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap + float xoff,yoff,xadvance; +} stbtt_bakedchar; + +STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // font location (use offset=0 for plain .ttf) + float pixel_height, // height of font in pixels + unsigned char *pixels, int pw, int ph, // bitmap to be filled in + int first_char, int num_chars, // characters to bake + stbtt_bakedchar *chardata); // you allocate this, it's num_chars long +// if return is positive, the first unused row of the bitmap +// if return is negative, returns the negative of the number of characters that fit +// if return is 0, no characters fit and no rows were used +// This uses a very crappy packing. + +typedef struct +{ + float x0,y0,s0,t0; // top-left + float x1,y1,s1,t1; // bottom-right +} stbtt_aligned_quad; + +STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar *chardata, int pw, int ph, // same data as above + int char_index, // character to display + float *xpos, float *ypos, // pointers to current position in screen pixel space + stbtt_aligned_quad *q, // output: quad to draw + int opengl_fillrule); // true if opengl fill rule; false if DX9 or earlier +// Call GetBakedQuad with char_index = 'character - first_char', and it +// creates the quad you need to draw and advances the current position. +// +// The coordinate system used assumes y increases downwards. +// +// Characters will extend both above and below the current position; +// see discussion of "BASELINE" above. +// +// It's inefficient; you might want to c&p it and optimize it. + +STBTT_DEF void stbtt_GetScaledFontVMetrics(const unsigned char *fontdata, int index, float size, float *ascent, float *descent, float *lineGap); +// Query the font vertical metrics without having to create a font first. + + +////////////////////////////////////////////////////////////////////////////// +// +// NEW TEXTURE BAKING API +// +// This provides options for packing multiple fonts into one atlas, not +// perfectly but better than nothing. + +typedef struct +{ + unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap + float xoff,yoff,xadvance; + float xoff2,yoff2; +} stbtt_packedchar; + +typedef struct stbtt_pack_context stbtt_pack_context; +typedef struct stbtt_fontinfo stbtt_fontinfo; +#ifndef STB_RECT_PACK_VERSION +typedef struct stbrp_rect stbrp_rect; +#endif + +STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int width, int height, int stride_in_bytes, int padding, void *alloc_context); +// Initializes a packing context stored in the passed-in stbtt_pack_context. +// Future calls using this context will pack characters into the bitmap passed +// in here: a 1-channel bitmap that is width * height. stride_in_bytes is +// the distance from one row to the next (or 0 to mean they are packed tightly +// together). "padding" is the amount of padding to leave between each +// character (normally you want '1' for bitmaps you'll use as textures with +// bilinear filtering). +// +// Returns 0 on failure, 1 on success. + +STBTT_DEF void stbtt_PackEnd (stbtt_pack_context *spc); +// Cleans up the packing context and frees all memory. + +#define STBTT_POINT_SIZE(x) (-(x)) + +STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, float font_size, + int first_unicode_char_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range); +// Creates character bitmaps from the font_index'th font found in fontdata (use +// font_index=0 if you don't know what that is). It creates num_chars_in_range +// bitmaps for characters with unicode values starting at first_unicode_char_in_range +// and increasing. Data for how to render them is stored in chardata_for_range; +// pass these to stbtt_GetPackedQuad to get back renderable quads. +// +// font_size is the full height of the character from ascender to descender, +// as computed by stbtt_ScaleForPixelHeight. To use a point size as computed +// by stbtt_ScaleForMappingEmToPixels, wrap the point size in STBTT_POINT_SIZE() +// and pass that result as 'font_size': +// ..., 20 , ... // font max minus min y is 20 pixels tall +// ..., STBTT_POINT_SIZE(20), ... // 'M' is 20 pixels tall + +typedef struct +{ + float font_size; + int first_unicode_codepoint_in_range; // if non-zero, then the chars are continuous, and this is the first codepoint + int *array_of_unicode_codepoints; // if non-zero, then this is an array of unicode codepoints + int num_chars; + stbtt_packedchar *chardata_for_range; // output + unsigned char h_oversample, v_oversample; // don't set these, they're used internally +} stbtt_pack_range; + +STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges); +// Creates character bitmaps from multiple ranges of characters stored in +// ranges. This will usually create a better-packed bitmap than multiple +// calls to stbtt_PackFontRange. Note that you can call this multiple +// times within a single PackBegin/PackEnd. + +STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample); +// Oversampling a font increases the quality by allowing higher-quality subpixel +// positioning, and is especially valuable at smaller text sizes. +// +// This function sets the amount of oversampling for all following calls to +// stbtt_PackFontRange(s) or stbtt_PackFontRangesGatherRects for a given +// pack context. The default (no oversampling) is achieved by h_oversample=1 +// and v_oversample=1. The total number of pixels required is +// h_oversample*v_oversample larger than the default; for example, 2x2 +// oversampling requires 4x the storage of 1x1. For best results, render +// oversampled textures with bilinear filtering. Look at the readme in +// stb/tests/oversample for information about oversampled fonts +// +// To use with PackFontRangesGather etc., you must set it before calls +// call to PackFontRangesGatherRects. + +STBTT_DEF void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *spc, int skip); +// If skip != 0, this tells stb_truetype to skip any codepoints for which +// there is no corresponding glyph. If skip=0, which is the default, then +// codepoints without a glyph recived the font's "missing character" glyph, +// typically an empty box by convention. + +STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, // same data as above + int char_index, // character to display + float *xpos, float *ypos, // pointers to current position in screen pixel space + stbtt_aligned_quad *q, // output: quad to draw + int align_to_integer); + +STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects); +STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect *rects, int num_rects); +STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects); +// Calling these functions in sequence is roughly equivalent to calling +// stbtt_PackFontRanges(). If you more control over the packing of multiple +// fonts, or if you want to pack custom data into a font texture, take a look +// at the source to of stbtt_PackFontRanges() and create a custom version +// using these functions, e.g. call GatherRects multiple times, +// building up a single array of rects, then call PackRects once, +// then call RenderIntoRects repeatedly. This may result in a +// better packing than calling PackFontRanges multiple times +// (or it may not). + +// this is an opaque structure that you shouldn't mess with which holds +// all the context needed from PackBegin to PackEnd. +struct stbtt_pack_context { + void *user_allocator_context; + void *pack_info; + int width; + int height; + int stride_in_bytes; + int padding; + int skip_missing; + unsigned int h_oversample, v_oversample; + unsigned char *pixels; + void *nodes; +}; + +////////////////////////////////////////////////////////////////////////////// +// +// FONT LOADING +// +// + +STBTT_DEF int stbtt_GetNumberOfFonts(const unsigned char *data); +// This function will determine the number of fonts in a font file. TrueType +// collection (.ttc) files may contain multiple fonts, while TrueType font +// (.ttf) files only contain one font. The number of fonts can be used for +// indexing with the previous function where the index is between zero and one +// less than the total fonts. If an error occurs, -1 is returned. + +STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index); +// Each .ttf/.ttc file may have more than one font. Each font has a sequential +// index number starting from 0. Call this function to get the font offset for +// a given index; it returns -1 if the index is out of range. A regular .ttf +// file will only define one font and it always be at offset 0, so it will +// return '0' for index 0, and -1 for all other indices. + +// The following structure is defined publicly so you can declare one on +// the stack or as a global or etc, but you should treat it as opaque. +struct stbtt_fontinfo +{ + void * userdata; + unsigned char * data; // pointer to .ttf file + int fontstart; // offset of start of font + + int numGlyphs; // number of glyphs, needed for range checking + + int loca,head,glyf,hhea,hmtx,kern,gpos,svg; // table locations as offset from start of .ttf + int index_map; // a cmap mapping for our chosen character encoding + int indexToLocFormat; // format needed to map from glyph index to glyph + + stbtt__buf cff; // cff font data + stbtt__buf charstrings; // the charstring index + stbtt__buf gsubrs; // global charstring subroutines index + stbtt__buf subrs; // private charstring subroutines index + stbtt__buf fontdicts; // array of font dicts + stbtt__buf fdselect; // map from glyph to fontdict +}; + +STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset); +// Given an offset into the file that defines a font, this function builds +// the necessary cached info for the rest of the system. You must allocate +// the stbtt_fontinfo yourself, and stbtt_InitFont will fill it out. You don't +// need to do anything special to free it, because the contents are pure +// value data with no additional data structures. Returns 0 on failure. + + +////////////////////////////////////////////////////////////////////////////// +// +// CHARACTER TO GLYPH-INDEX CONVERSIOn + +STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint); +// If you're going to perform multiple operations on the same character +// and you want a speed-up, call this function with the character you're +// going to process, then use glyph-based functions instead of the +// codepoint-based functions. +// Returns 0 if the character codepoint is not defined in the font. + + +////////////////////////////////////////////////////////////////////////////// +// +// CHARACTER PROPERTIES +// + +STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float pixels); +// computes a scale factor to produce a font whose "height" is 'pixels' tall. +// Height is measured as the distance from the highest ascender to the lowest +// descender; in other words, it's equivalent to calling stbtt_GetFontVMetrics +// and computing: +// scale = pixels / (ascent - descent) +// so if you prefer to measure height by the ascent only, use a similar calculation. + +STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels); +// computes a scale factor to produce a font whose EM size is mapped to +// 'pixels' tall. This is probably what traditional APIs compute, but +// I'm not positive. + +STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap); +// ascent is the coordinate above the baseline the font extends; descent +// is the coordinate below the baseline the font extends (i.e. it is typically negative) +// lineGap is the spacing between one row's descent and the next row's ascent... +// so you should advance the vertical position by "*ascent - *descent + *lineGap" +// these are expressed in unscaled coordinates, so you must multiply by +// the scale factor for a given size + +STBTT_DEF int stbtt_GetFontVMetricsOS2(const stbtt_fontinfo *info, int *typoAscent, int *typoDescent, int *typoLineGap); +// analogous to GetFontVMetrics, but returns the "typographic" values from the OS/2 +// table (specific to MS/Windows TTF files). +// +// Returns 1 on success (table present), 0 on failure. + +STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1); +// the bounding box around all possible characters + +STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing); +// leftSideBearing is the offset from the current horizontal position to the left edge of the character +// advanceWidth is the offset from the current horizontal position to the next horizontal position +// these are expressed in unscaled coordinates + +STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2); +// an additional amount to add to the 'advance' value between ch1 and ch2 + +STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1); +// Gets the bounding box of the visible part of the glyph, in unscaled coordinates + +STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing); +STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2); +STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1); +// as above, but takes one or more glyph indices for greater efficiency + +typedef struct stbtt_kerningentry +{ + int glyph1; // use stbtt_FindGlyphIndex + int glyph2; + int advance; +} stbtt_kerningentry; + +STBTT_DEF int stbtt_GetKerningTableLength(const stbtt_fontinfo *info); +STBTT_DEF int stbtt_GetKerningTable(const stbtt_fontinfo *info, stbtt_kerningentry* table, int table_length); +// Retrieves a complete list of all of the kerning pairs provided by the font +// stbtt_GetKerningTable never writes more than table_length entries and returns how many entries it did write. +// The table will be sorted by (a.glyph1 == b.glyph1)?(a.glyph2 < b.glyph2):(a.glyph1 < b.glyph1) + +////////////////////////////////////////////////////////////////////////////// +// +// GLYPH SHAPES (you probably don't need these, but they have to go before +// the bitmaps for C declaration-order reasons) +// + +#ifndef STBTT_vmove // you can predefine these to use different values (but why?) + enum { + STBTT_vmove=1, + STBTT_vline, + STBTT_vcurve, + STBTT_vcubic + }; +#endif + +#ifndef stbtt_vertex // you can predefine this to use different values + // (we share this with other code at RAD) + #define stbtt_vertex_type short // can't use stbtt_int16 because that's not visible in the header file + typedef struct + { + stbtt_vertex_type x,y,cx,cy,cx1,cy1; + unsigned char type,padding; + } stbtt_vertex; +#endif + +STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index); +// returns non-zero if nothing is drawn for this glyph + +STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices); +STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **vertices); +// returns # of vertices and fills *vertices with the pointer to them +// these are expressed in "unscaled" coordinates +// +// The shape is a series of contours. Each one starts with +// a STBTT_moveto, then consists of a series of mixed +// STBTT_lineto and STBTT_curveto segments. A lineto +// draws a line from previous endpoint to its x,y; a curveto +// draws a quadratic bezier from previous endpoint to +// its x,y, using cx,cy as the bezier control point. + +STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices); +// frees the data allocated above + +STBTT_DEF unsigned char *stbtt_FindSVGDoc(const stbtt_fontinfo *info, int gl); +STBTT_DEF int stbtt_GetCodepointSVG(const stbtt_fontinfo *info, int unicode_codepoint, const char **svg); +STBTT_DEF int stbtt_GetGlyphSVG(const stbtt_fontinfo *info, int gl, const char **svg); +// fills svg with the character's SVG data. +// returns data size or 0 if SVG not found. + +////////////////////////////////////////////////////////////////////////////// +// +// BITMAP RENDERING +// + +STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata); +// frees the bitmap allocated below + +STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff); +// allocates a large-enough single-channel 8bpp bitmap and renders the +// specified character/glyph at the specified scale into it, with +// antialiasing. 0 is no coverage (transparent), 255 is fully covered (opaque). +// *width & *height are filled out with the width & height of the bitmap, +// which is stored left-to-right, top-to-bottom. +// +// xoff/yoff are the offset it pixel space from the glyph origin to the top-left of the bitmap + +STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff); +// the same as stbtt_GetCodepoitnBitmap, but you can specify a subpixel +// shift for the character + +STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint); +// the same as stbtt_GetCodepointBitmap, but you pass in storage for the bitmap +// in the form of 'output', with row spacing of 'out_stride' bytes. the bitmap +// is clipped to out_w/out_h bytes. Call stbtt_GetCodepointBitmapBox to get the +// width and height and positioning info for it first. + +STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint); +// same as stbtt_MakeCodepointBitmap, but you can specify a subpixel +// shift for the character + +STBTT_DEF void stbtt_MakeCodepointBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x, int oversample_y, float *sub_x, float *sub_y, int codepoint); +// same as stbtt_MakeCodepointBitmapSubpixel, but prefiltering +// is performed (see stbtt_PackSetOversampling) + +STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1); +// get the bbox of the bitmap centered around the glyph origin; so the +// bitmap width is ix1-ix0, height is iy1-iy0, and location to place +// the bitmap top left is (leftSideBearing*scale,iy0). +// (Note that the bitmap uses y-increases-down, but the shape uses +// y-increases-up, so CodepointBitmapBox and CodepointBox are inverted.) + +STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1); +// same as stbtt_GetCodepointBitmapBox, but you can specify a subpixel +// shift for the character + +// the following functions are equivalent to the above functions, but operate +// on glyph indices instead of Unicode codepoints (for efficiency) +STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff); +STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff); +STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph); +STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph); +STBTT_DEF void stbtt_MakeGlyphBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x, int oversample_y, float *sub_x, float *sub_y, int glyph); +STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1); +STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1); + + +// @TODO: don't expose this structure +typedef struct +{ + int w,h,stride; + unsigned char *pixels; +} stbtt__bitmap; + +// rasterize a shape with quadratic beziers into a bitmap +STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, // 1-channel bitmap to draw into + float flatness_in_pixels, // allowable error of curve in pixels + stbtt_vertex *vertices, // array of vertices defining shape + int num_verts, // number of vertices in above array + float scale_x, float scale_y, // scale applied to input vertices + float shift_x, float shift_y, // translation applied to input vertices + int x_off, int y_off, // another translation applied to input + int invert, // if non-zero, vertically flip shape + void *userdata); // context for to STBTT_MALLOC + +////////////////////////////////////////////////////////////////////////////// +// +// Signed Distance Function (or Field) rendering + +STBTT_DEF void stbtt_FreeSDF(unsigned char *bitmap, void *userdata); +// frees the SDF bitmap allocated below + +STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float scale, int glyph, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff); +STBTT_DEF unsigned char * stbtt_GetCodepointSDF(const stbtt_fontinfo *info, float scale, int codepoint, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff); +// These functions compute a discretized SDF field for a single character, suitable for storing +// in a single-channel texture, sampling with bilinear filtering, and testing against +// larger than some threshold to produce scalable fonts. +// info -- the font +// scale -- controls the size of the resulting SDF bitmap, same as it would be creating a regular bitmap +// glyph/codepoint -- the character to generate the SDF for +// padding -- extra "pixels" around the character which are filled with the distance to the character (not 0), +// which allows effects like bit outlines +// onedge_value -- value 0-255 to test the SDF against to reconstruct the character (i.e. the isocontour of the character) +// pixel_dist_scale -- what value the SDF should increase by when moving one SDF "pixel" away from the edge (on the 0..255 scale) +// if positive, > onedge_value is inside; if negative, < onedge_value is inside +// width,height -- output height & width of the SDF bitmap (including padding) +// xoff,yoff -- output origin of the character +// return value -- a 2D array of bytes 0..255, width*height in size +// +// pixel_dist_scale & onedge_value are a scale & bias that allows you to make +// optimal use of the limited 0..255 for your application, trading off precision +// and special effects. SDF values outside the range 0..255 are clamped to 0..255. +// +// Example: +// scale = stbtt_ScaleForPixelHeight(22) +// padding = 5 +// onedge_value = 180 +// pixel_dist_scale = 180/5.0 = 36.0 +// +// This will create an SDF bitmap in which the character is about 22 pixels +// high but the whole bitmap is about 22+5+5=32 pixels high. To produce a filled +// shape, sample the SDF at each pixel and fill the pixel if the SDF value +// is greater than or equal to 180/255. (You'll actually want to antialias, +// which is beyond the scope of this example.) Additionally, you can compute +// offset outlines (e.g. to stroke the character border inside & outside, +// or only outside). For example, to fill outside the character up to 3 SDF +// pixels, you would compare against (180-36.0*3)/255 = 72/255. The above +// choice of variables maps a range from 5 pixels outside the shape to +// 2 pixels inside the shape to 0..255; this is intended primarily for apply +// outside effects only (the interior range is needed to allow proper +// antialiasing of the font at *smaller* sizes) +// +// The function computes the SDF analytically at each SDF pixel, not by e.g. +// building a higher-res bitmap and approximating it. In theory the quality +// should be as high as possible for an SDF of this size & representation, but +// unclear if this is true in practice (perhaps building a higher-res bitmap +// and computing from that can allow drop-out prevention). +// +// The algorithm has not been optimized at all, so expect it to be slow +// if computing lots of characters or very large sizes. + + + +////////////////////////////////////////////////////////////////////////////// +// +// Finding the right font... +// +// You should really just solve this offline, keep your own tables +// of what font is what, and don't try to get it out of the .ttf file. +// That's because getting it out of the .ttf file is really hard, because +// the names in the file can appear in many possible encodings, in many +// possible languages, and e.g. if you need a case-insensitive comparison, +// the details of that depend on the encoding & language in a complex way +// (actually underspecified in truetype, but also gigantic). +// +// But you can use the provided functions in two possible ways: +// stbtt_FindMatchingFont() will use *case-sensitive* comparisons on +// unicode-encoded names to try to find the font you want; +// you can run this before calling stbtt_InitFont() +// +// stbtt_GetFontNameString() lets you get any of the various strings +// from the file yourself and do your own comparisons on them. +// You have to have called stbtt_InitFont() first. + + +STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *fontdata, const char *name, int flags); +// returns the offset (not index) of the font that matches, or -1 if none +// if you use STBTT_MACSTYLE_DONTCARE, use a font name like "Arial Bold". +// if you use any other flag, use a font name like "Arial"; this checks +// the 'macStyle' header field; i don't know if fonts set this consistently +#define STBTT_MACSTYLE_DONTCARE 0 +#define STBTT_MACSTYLE_BOLD 1 +#define STBTT_MACSTYLE_ITALIC 2 +#define STBTT_MACSTYLE_UNDERSCORE 4 +#define STBTT_MACSTYLE_NONE 8 // <= not same as 0, this makes us check the bitfield is 0 + +STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2); +// returns 1/0 whether the first string interpreted as utf8 is identical to +// the second string interpreted as big-endian utf16... useful for strings from next func + +STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID); +// returns the string (which may be big-endian double byte, e.g. for unicode) +// and puts the length in bytes in *length. +// +// some of the values for the IDs are below; for more see the truetype spec: +// http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6name.html +// http://www.microsoft.com/typography/otspec/name.htm + +enum { // platformID + STBTT_PLATFORM_ID_UNICODE =0, + STBTT_PLATFORM_ID_MAC =1, + STBTT_PLATFORM_ID_ISO =2, + STBTT_PLATFORM_ID_MICROSOFT =3 +}; + +enum { // encodingID for STBTT_PLATFORM_ID_UNICODE + STBTT_UNICODE_EID_UNICODE_1_0 =0, + STBTT_UNICODE_EID_UNICODE_1_1 =1, + STBTT_UNICODE_EID_ISO_10646 =2, + STBTT_UNICODE_EID_UNICODE_2_0_BMP=3, + STBTT_UNICODE_EID_UNICODE_2_0_FULL=4 +}; + +enum { // encodingID for STBTT_PLATFORM_ID_MICROSOFT + STBTT_MS_EID_SYMBOL =0, + STBTT_MS_EID_UNICODE_BMP =1, + STBTT_MS_EID_SHIFTJIS =2, + STBTT_MS_EID_UNICODE_FULL =10 +}; + +enum { // encodingID for STBTT_PLATFORM_ID_MAC; same as Script Manager codes + STBTT_MAC_EID_ROMAN =0, STBTT_MAC_EID_ARABIC =4, + STBTT_MAC_EID_JAPANESE =1, STBTT_MAC_EID_HEBREW =5, + STBTT_MAC_EID_CHINESE_TRAD =2, STBTT_MAC_EID_GREEK =6, + STBTT_MAC_EID_KOREAN =3, STBTT_MAC_EID_RUSSIAN =7 +}; + +enum { // languageID for STBTT_PLATFORM_ID_MICROSOFT; same as LCID... + // problematic because there are e.g. 16 english LCIDs and 16 arabic LCIDs + STBTT_MS_LANG_ENGLISH =0x0409, STBTT_MS_LANG_ITALIAN =0x0410, + STBTT_MS_LANG_CHINESE =0x0804, STBTT_MS_LANG_JAPANESE =0x0411, + STBTT_MS_LANG_DUTCH =0x0413, STBTT_MS_LANG_KOREAN =0x0412, + STBTT_MS_LANG_FRENCH =0x040c, STBTT_MS_LANG_RUSSIAN =0x0419, + STBTT_MS_LANG_GERMAN =0x0407, STBTT_MS_LANG_SPANISH =0x0409, + STBTT_MS_LANG_HEBREW =0x040d, STBTT_MS_LANG_SWEDISH =0x041D +}; + +enum { // languageID for STBTT_PLATFORM_ID_MAC + STBTT_MAC_LANG_ENGLISH =0 , STBTT_MAC_LANG_JAPANESE =11, + STBTT_MAC_LANG_ARABIC =12, STBTT_MAC_LANG_KOREAN =23, + STBTT_MAC_LANG_DUTCH =4 , STBTT_MAC_LANG_RUSSIAN =32, + STBTT_MAC_LANG_FRENCH =1 , STBTT_MAC_LANG_SPANISH =6 , + STBTT_MAC_LANG_GERMAN =2 , STBTT_MAC_LANG_SWEDISH =5 , + STBTT_MAC_LANG_HEBREW =10, STBTT_MAC_LANG_CHINESE_SIMPLIFIED =33, + STBTT_MAC_LANG_ITALIAN =3 , STBTT_MAC_LANG_CHINESE_TRAD =19 +}; + +#ifdef __cplusplus +} +#endif + +#endif // __STB_INCLUDE_STB_TRUETYPE_H__ + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +//// +//// IMPLEMENTATION +//// +//// + +#ifdef STB_TRUETYPE_IMPLEMENTATION + +#ifndef STBTT_MAX_OVERSAMPLE +#define STBTT_MAX_OVERSAMPLE 8 +#endif + +#if STBTT_MAX_OVERSAMPLE > 255 +#error "STBTT_MAX_OVERSAMPLE cannot be > 255" +#endif + +typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERSAMPLE-1)) == 0 ? 1 : -1]; + +#ifndef STBTT_RASTERIZER_VERSION +#define STBTT_RASTERIZER_VERSION 2 +#endif + +#ifdef _MSC_VER +#define STBTT__NOTUSED(v) (void)(v) +#else +#define STBTT__NOTUSED(v) (void)sizeof(v) +#endif + +////////////////////////////////////////////////////////////////////////// +// +// stbtt__buf helpers to parse data from file +// + +static stbtt_uint8 stbtt__buf_get8(stbtt__buf *b) +{ + if (b->cursor >= b->size) + return 0; + return b->data[b->cursor++]; +} + +static stbtt_uint8 stbtt__buf_peek8(stbtt__buf *b) +{ + if (b->cursor >= b->size) + return 0; + return b->data[b->cursor]; +} + +static void stbtt__buf_seek(stbtt__buf *b, int o) +{ + STBTT_assert(!(o > b->size || o < 0)); + b->cursor = (o > b->size || o < 0) ? b->size : o; +} + +static void stbtt__buf_skip(stbtt__buf *b, int o) +{ + stbtt__buf_seek(b, b->cursor + o); +} + +static stbtt_uint32 stbtt__buf_get(stbtt__buf *b, int n) +{ + stbtt_uint32 v = 0; + int i; + STBTT_assert(n >= 1 && n <= 4); + for (i = 0; i < n; i++) + v = (v << 8) | stbtt__buf_get8(b); + return v; +} + +static stbtt__buf stbtt__new_buf(const void *p, size_t size) +{ + stbtt__buf r; + STBTT_assert(size < 0x40000000); + r.data = (stbtt_uint8*) p; + r.size = (int) size; + r.cursor = 0; + return r; +} + +#define stbtt__buf_get16(b) stbtt__buf_get((b), 2) +#define stbtt__buf_get32(b) stbtt__buf_get((b), 4) + +static stbtt__buf stbtt__buf_range(const stbtt__buf *b, int o, int s) +{ + stbtt__buf r = stbtt__new_buf(NULL, 0); + if (o < 0 || s < 0 || o > b->size || s > b->size - o) return r; + r.data = b->data + o; + r.size = s; + return r; +} + +static stbtt__buf stbtt__cff_get_index(stbtt__buf *b) +{ + int count, start, offsize; + start = b->cursor; + count = stbtt__buf_get16(b); + if (count) { + offsize = stbtt__buf_get8(b); + STBTT_assert(offsize >= 1 && offsize <= 4); + stbtt__buf_skip(b, offsize * count); + stbtt__buf_skip(b, stbtt__buf_get(b, offsize) - 1); + } + return stbtt__buf_range(b, start, b->cursor - start); +} + +static stbtt_uint32 stbtt__cff_int(stbtt__buf *b) +{ + int b0 = stbtt__buf_get8(b); + if (b0 >= 32 && b0 <= 246) return b0 - 139; + else if (b0 >= 247 && b0 <= 250) return (b0 - 247)*256 + stbtt__buf_get8(b) + 108; + else if (b0 >= 251 && b0 <= 254) return -(b0 - 251)*256 - stbtt__buf_get8(b) - 108; + else if (b0 == 28) return stbtt__buf_get16(b); + else if (b0 == 29) return stbtt__buf_get32(b); + STBTT_assert(0); + return 0; +} + +static void stbtt__cff_skip_operand(stbtt__buf *b) { + int v, b0 = stbtt__buf_peek8(b); + STBTT_assert(b0 >= 28); + if (b0 == 30) { + stbtt__buf_skip(b, 1); + while (b->cursor < b->size) { + v = stbtt__buf_get8(b); + if ((v & 0xF) == 0xF || (v >> 4) == 0xF) + break; + } + } else { + stbtt__cff_int(b); + } +} + +static stbtt__buf stbtt__dict_get(stbtt__buf *b, int key) +{ + stbtt__buf_seek(b, 0); + while (b->cursor < b->size) { + int start = b->cursor, end, op; + while (stbtt__buf_peek8(b) >= 28) + stbtt__cff_skip_operand(b); + end = b->cursor; + op = stbtt__buf_get8(b); + if (op == 12) op = stbtt__buf_get8(b) | 0x100; + if (op == key) return stbtt__buf_range(b, start, end-start); + } + return stbtt__buf_range(b, 0, 0); +} + +static void stbtt__dict_get_ints(stbtt__buf *b, int key, int outcount, stbtt_uint32 *out) +{ + int i; + stbtt__buf operands = stbtt__dict_get(b, key); + for (i = 0; i < outcount && operands.cursor < operands.size; i++) + out[i] = stbtt__cff_int(&operands); +} + +static int stbtt__cff_index_count(stbtt__buf *b) +{ + stbtt__buf_seek(b, 0); + return stbtt__buf_get16(b); +} + +static stbtt__buf stbtt__cff_index_get(stbtt__buf b, int i) +{ + int count, offsize, start, end; + stbtt__buf_seek(&b, 0); + count = stbtt__buf_get16(&b); + offsize = stbtt__buf_get8(&b); + STBTT_assert(i >= 0 && i < count); + STBTT_assert(offsize >= 1 && offsize <= 4); + stbtt__buf_skip(&b, i*offsize); + start = stbtt__buf_get(&b, offsize); + end = stbtt__buf_get(&b, offsize); + return stbtt__buf_range(&b, 2+(count+1)*offsize+start, end - start); +} + +////////////////////////////////////////////////////////////////////////// +// +// accessors to parse data from file +// + +// on platforms that don't allow misaligned reads, if we want to allow +// truetype fonts that aren't padded to alignment, define ALLOW_UNALIGNED_TRUETYPE + +#define ttBYTE(p) (* (stbtt_uint8 *) (p)) +#define ttCHAR(p) (* (stbtt_int8 *) (p)) +#define ttFixed(p) ttLONG(p) + +static stbtt_uint16 ttUSHORT(stbtt_uint8 *p) { return p[0]*256 + p[1]; } +static stbtt_int16 ttSHORT(stbtt_uint8 *p) { return p[0]*256 + p[1]; } +static stbtt_uint32 ttULONG(stbtt_uint8 *p) { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; } +static stbtt_int32 ttLONG(stbtt_uint8 *p) { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; } + +#define stbtt_tag4(p,c0,c1,c2,c3) ((p)[0] == (c0) && (p)[1] == (c1) && (p)[2] == (c2) && (p)[3] == (c3)) +#define stbtt_tag(p,str) stbtt_tag4(p,str[0],str[1],str[2],str[3]) + +static int stbtt__isfont(stbtt_uint8 *font) +{ + // check the version number + if (stbtt_tag4(font, '1',0,0,0)) return 1; // TrueType 1 + if (stbtt_tag(font, "typ1")) return 1; // TrueType with type 1 font -- we don't support this! + if (stbtt_tag(font, "OTTO")) return 1; // OpenType with CFF + if (stbtt_tag4(font, 0,1,0,0)) return 1; // OpenType 1.0 + if (stbtt_tag(font, "true")) return 1; // Apple specification for TrueType fonts + return 0; +} + +// @OPTIMIZE: binary search +static stbtt_uint32 stbtt__find_table(stbtt_uint8 *data, stbtt_uint32 fontstart, const char *tag) +{ + stbtt_int32 num_tables = ttUSHORT(data+fontstart+4); + stbtt_uint32 tabledir = fontstart + 12; + stbtt_int32 i; + for (i=0; i < num_tables; ++i) { + stbtt_uint32 loc = tabledir + 16*i; + if (stbtt_tag(data+loc+0, tag)) + return ttULONG(data+loc+8); + } + return 0; +} + +static int stbtt_GetFontOffsetForIndex_internal(unsigned char *font_collection, int index) +{ + // if it's just a font, there's only one valid index + if (stbtt__isfont(font_collection)) + return index == 0 ? 0 : -1; + + // check if it's a TTC + if (stbtt_tag(font_collection, "ttcf")) { + // version 1? + if (ttULONG(font_collection+4) == 0x00010000 || ttULONG(font_collection+4) == 0x00020000) { + stbtt_int32 n = ttLONG(font_collection+8); + if (index >= n) + return -1; + return ttULONG(font_collection+12+index*4); + } + } + return -1; +} + +static int stbtt_GetNumberOfFonts_internal(unsigned char *font_collection) +{ + // if it's just a font, there's only one valid font + if (stbtt__isfont(font_collection)) + return 1; + + // check if it's a TTC + if (stbtt_tag(font_collection, "ttcf")) { + // version 1? + if (ttULONG(font_collection+4) == 0x00010000 || ttULONG(font_collection+4) == 0x00020000) { + return ttLONG(font_collection+8); + } + } + return 0; +} + +static stbtt__buf stbtt__get_subrs(stbtt__buf cff, stbtt__buf fontdict) +{ + stbtt_uint32 subrsoff = 0, private_loc[2] = { 0, 0 }; + stbtt__buf pdict; + stbtt__dict_get_ints(&fontdict, 18, 2, private_loc); + if (!private_loc[1] || !private_loc[0]) return stbtt__new_buf(NULL, 0); + pdict = stbtt__buf_range(&cff, private_loc[1], private_loc[0]); + stbtt__dict_get_ints(&pdict, 19, 1, &subrsoff); + if (!subrsoff) return stbtt__new_buf(NULL, 0); + stbtt__buf_seek(&cff, private_loc[1]+subrsoff); + return stbtt__cff_get_index(&cff); +} + +// since most people won't use this, find this table the first time it's needed +static int stbtt__get_svg(stbtt_fontinfo *info) +{ + stbtt_uint32 t; + if (info->svg < 0) { + t = stbtt__find_table(info->data, info->fontstart, "SVG "); + if (t) { + stbtt_uint32 offset = ttULONG(info->data + t + 2); + info->svg = t + offset; + } else { + info->svg = 0; + } + } + return info->svg; +} + +static int stbtt_InitFont_internal(stbtt_fontinfo *info, unsigned char *data, int fontstart) +{ + stbtt_uint32 cmap, t; + stbtt_int32 i,numTables; + + info->data = data; + info->fontstart = fontstart; + info->cff = stbtt__new_buf(NULL, 0); + + cmap = stbtt__find_table(data, fontstart, "cmap"); // required + info->loca = stbtt__find_table(data, fontstart, "loca"); // required + info->head = stbtt__find_table(data, fontstart, "head"); // required + info->glyf = stbtt__find_table(data, fontstart, "glyf"); // required + info->hhea = stbtt__find_table(data, fontstart, "hhea"); // required + info->hmtx = stbtt__find_table(data, fontstart, "hmtx"); // required + info->kern = stbtt__find_table(data, fontstart, "kern"); // not required + info->gpos = stbtt__find_table(data, fontstart, "GPOS"); // not required + + if (!cmap || !info->head || !info->hhea || !info->hmtx) + return 0; + if (info->glyf) { + // required for truetype + if (!info->loca) return 0; + } else { + // initialization for CFF / Type2 fonts (OTF) + stbtt__buf b, topdict, topdictidx; + stbtt_uint32 cstype = 2, charstrings = 0, fdarrayoff = 0, fdselectoff = 0; + stbtt_uint32 cff; + + cff = stbtt__find_table(data, fontstart, "CFF "); + if (!cff) return 0; + + info->fontdicts = stbtt__new_buf(NULL, 0); + info->fdselect = stbtt__new_buf(NULL, 0); + + // @TODO this should use size from table (not 512MB) + info->cff = stbtt__new_buf(data+cff, 512*1024*1024); + b = info->cff; + + // read the header + stbtt__buf_skip(&b, 2); + stbtt__buf_seek(&b, stbtt__buf_get8(&b)); // hdrsize + + // @TODO the name INDEX could list multiple fonts, + // but we just use the first one. + stbtt__cff_get_index(&b); // name INDEX + topdictidx = stbtt__cff_get_index(&b); + topdict = stbtt__cff_index_get(topdictidx, 0); + stbtt__cff_get_index(&b); // string INDEX + info->gsubrs = stbtt__cff_get_index(&b); + + stbtt__dict_get_ints(&topdict, 17, 1, &charstrings); + stbtt__dict_get_ints(&topdict, 0x100 | 6, 1, &cstype); + stbtt__dict_get_ints(&topdict, 0x100 | 36, 1, &fdarrayoff); + stbtt__dict_get_ints(&topdict, 0x100 | 37, 1, &fdselectoff); + info->subrs = stbtt__get_subrs(b, topdict); + + // we only support Type 2 charstrings + if (cstype != 2) return 0; + if (charstrings == 0) return 0; + + if (fdarrayoff) { + // looks like a CID font + if (!fdselectoff) return 0; + stbtt__buf_seek(&b, fdarrayoff); + info->fontdicts = stbtt__cff_get_index(&b); + info->fdselect = stbtt__buf_range(&b, fdselectoff, b.size-fdselectoff); + } + + stbtt__buf_seek(&b, charstrings); + info->charstrings = stbtt__cff_get_index(&b); + } + + t = stbtt__find_table(data, fontstart, "maxp"); + if (t) + info->numGlyphs = ttUSHORT(data+t+4); + else + info->numGlyphs = 0xffff; + + info->svg = -1; + + // find a cmap encoding table we understand *now* to avoid searching + // later. (todo: could make this installable) + // the same regardless of glyph. + numTables = ttUSHORT(data + cmap + 2); + info->index_map = 0; + for (i=0; i < numTables; ++i) { + stbtt_uint32 encoding_record = cmap + 4 + 8 * i; + // find an encoding we understand: + switch(ttUSHORT(data+encoding_record)) { + case STBTT_PLATFORM_ID_MICROSOFT: + switch (ttUSHORT(data+encoding_record+2)) { + case STBTT_MS_EID_UNICODE_BMP: + case STBTT_MS_EID_UNICODE_FULL: + // MS/Unicode + info->index_map = cmap + ttULONG(data+encoding_record+4); + break; + } + break; + case STBTT_PLATFORM_ID_UNICODE: + // Mac/iOS has these + // all the encodingIDs are unicode, so we don't bother to check it + info->index_map = cmap + ttULONG(data+encoding_record+4); + break; + } + } + if (info->index_map == 0) + return 0; + + info->indexToLocFormat = ttUSHORT(data+info->head + 50); + return 1; +} + +STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint) +{ + stbtt_uint8 *data = info->data; + stbtt_uint32 index_map = info->index_map; + + stbtt_uint16 format = ttUSHORT(data + index_map + 0); + if (format == 0) { // apple byte encoding + stbtt_int32 bytes = ttUSHORT(data + index_map + 2); + if (unicode_codepoint < bytes-6) + return ttBYTE(data + index_map + 6 + unicode_codepoint); + return 0; + } else if (format == 6) { + stbtt_uint32 first = ttUSHORT(data + index_map + 6); + stbtt_uint32 count = ttUSHORT(data + index_map + 8); + if ((stbtt_uint32) unicode_codepoint >= first && (stbtt_uint32) unicode_codepoint < first+count) + return ttUSHORT(data + index_map + 10 + (unicode_codepoint - first)*2); + return 0; + } else if (format == 2) { + STBTT_assert(0); // @TODO: high-byte mapping for japanese/chinese/korean + return 0; + } else if (format == 4) { // standard mapping for windows fonts: binary search collection of ranges + stbtt_uint16 segcount = ttUSHORT(data+index_map+6) >> 1; + stbtt_uint16 searchRange = ttUSHORT(data+index_map+8) >> 1; + stbtt_uint16 entrySelector = ttUSHORT(data+index_map+10); + stbtt_uint16 rangeShift = ttUSHORT(data+index_map+12) >> 1; + + // do a binary search of the segments + stbtt_uint32 endCount = index_map + 14; + stbtt_uint32 search = endCount; + + if (unicode_codepoint > 0xffff) + return 0; + + // they lie from endCount .. endCount + segCount + // but searchRange is the nearest power of two, so... + if (unicode_codepoint >= ttUSHORT(data + search + rangeShift*2)) + search += rangeShift*2; + + // now decrement to bias correctly to find smallest + search -= 2; + while (entrySelector) { + stbtt_uint16 end; + searchRange >>= 1; + end = ttUSHORT(data + search + searchRange*2); + if (unicode_codepoint > end) + search += searchRange*2; + --entrySelector; + } + search += 2; + + { + stbtt_uint16 offset, start, last; + stbtt_uint16 item = (stbtt_uint16) ((search - endCount) >> 1); + + start = ttUSHORT(data + index_map + 14 + segcount*2 + 2 + 2*item); + last = ttUSHORT(data + endCount + 2*item); + if (unicode_codepoint < start || unicode_codepoint > last) + return 0; + + offset = ttUSHORT(data + index_map + 14 + segcount*6 + 2 + 2*item); + if (offset == 0) + return (stbtt_uint16) (unicode_codepoint + ttSHORT(data + index_map + 14 + segcount*4 + 2 + 2*item)); + + return ttUSHORT(data + offset + (unicode_codepoint-start)*2 + index_map + 14 + segcount*6 + 2 + 2*item); + } + } else if (format == 12 || format == 13) { + stbtt_uint32 ngroups = ttULONG(data+index_map+12); + stbtt_int32 low,high; + low = 0; high = (stbtt_int32)ngroups; + // Binary search the right group. + while (low < high) { + stbtt_int32 mid = low + ((high-low) >> 1); // rounds down, so low <= mid < high + stbtt_uint32 start_char = ttULONG(data+index_map+16+mid*12); + stbtt_uint32 end_char = ttULONG(data+index_map+16+mid*12+4); + if ((stbtt_uint32) unicode_codepoint < start_char) + high = mid; + else if ((stbtt_uint32) unicode_codepoint > end_char) + low = mid+1; + else { + stbtt_uint32 start_glyph = ttULONG(data+index_map+16+mid*12+8); + if (format == 12) + return start_glyph + unicode_codepoint-start_char; + else // format == 13 + return start_glyph; + } + } + return 0; // not found + } + // @TODO + STBTT_assert(0); + return 0; +} + +STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices) +{ + return stbtt_GetGlyphShape(info, stbtt_FindGlyphIndex(info, unicode_codepoint), vertices); +} + +static void stbtt_setvertex(stbtt_vertex *v, stbtt_uint8 type, stbtt_int32 x, stbtt_int32 y, stbtt_int32 cx, stbtt_int32 cy) +{ + v->type = type; + v->x = (stbtt_int16) x; + v->y = (stbtt_int16) y; + v->cx = (stbtt_int16) cx; + v->cy = (stbtt_int16) cy; +} + +static int stbtt__GetGlyfOffset(const stbtt_fontinfo *info, int glyph_index) +{ + int g1,g2; + + STBTT_assert(!info->cff.size); + + if (glyph_index >= info->numGlyphs) return -1; // glyph index out of range + if (info->indexToLocFormat >= 2) return -1; // unknown index->glyph map format + + if (info->indexToLocFormat == 0) { + g1 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2) * 2; + g2 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2 + 2) * 2; + } else { + g1 = info->glyf + ttULONG (info->data + info->loca + glyph_index * 4); + g2 = info->glyf + ttULONG (info->data + info->loca + glyph_index * 4 + 4); + } + + return g1==g2 ? -1 : g1; // if length is 0, return -1 +} + +static int stbtt__GetGlyphInfoT2(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1); + +STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1) +{ + if (info->cff.size) { + stbtt__GetGlyphInfoT2(info, glyph_index, x0, y0, x1, y1); + } else { + int g = stbtt__GetGlyfOffset(info, glyph_index); + if (g < 0) return 0; + + if (x0) *x0 = ttSHORT(info->data + g + 2); + if (y0) *y0 = ttSHORT(info->data + g + 4); + if (x1) *x1 = ttSHORT(info->data + g + 6); + if (y1) *y1 = ttSHORT(info->data + g + 8); + } + return 1; +} + +STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1) +{ + return stbtt_GetGlyphBox(info, stbtt_FindGlyphIndex(info,codepoint), x0,y0,x1,y1); +} + +STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index) +{ + stbtt_int16 numberOfContours; + int g; + if (info->cff.size) + return stbtt__GetGlyphInfoT2(info, glyph_index, NULL, NULL, NULL, NULL) == 0; + g = stbtt__GetGlyfOffset(info, glyph_index); + if (g < 0) return 1; + numberOfContours = ttSHORT(info->data + g); + return numberOfContours == 0; +} + +static int stbtt__close_shape(stbtt_vertex *vertices, int num_vertices, int was_off, int start_off, + stbtt_int32 sx, stbtt_int32 sy, stbtt_int32 scx, stbtt_int32 scy, stbtt_int32 cx, stbtt_int32 cy) +{ + if (start_off) { + if (was_off) + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx+scx)>>1, (cy+scy)>>1, cx,cy); + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, sx,sy,scx,scy); + } else { + if (was_off) + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve,sx,sy,cx,cy); + else + stbtt_setvertex(&vertices[num_vertices++], STBTT_vline,sx,sy,0,0); + } + return num_vertices; +} + +static int stbtt__GetGlyphShapeTT(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices) +{ + stbtt_int16 numberOfContours; + stbtt_uint8 *endPtsOfContours; + stbtt_uint8 *data = info->data; + stbtt_vertex *vertices=0; + int num_vertices=0; + int g = stbtt__GetGlyfOffset(info, glyph_index); + + *pvertices = NULL; + + if (g < 0) return 0; + + numberOfContours = ttSHORT(data + g); + + if (numberOfContours > 0) { + stbtt_uint8 flags=0,flagcount; + stbtt_int32 ins, i,j=0,m,n, next_move, was_off=0, off, start_off=0; + stbtt_int32 x,y,cx,cy,sx,sy, scx,scy; + stbtt_uint8 *points; + endPtsOfContours = (data + g + 10); + ins = ttUSHORT(data + g + 10 + numberOfContours * 2); + points = data + g + 10 + numberOfContours * 2 + 2 + ins; + + n = 1+ttUSHORT(endPtsOfContours + numberOfContours*2-2); + + m = n + 2*numberOfContours; // a loose bound on how many vertices we might need + vertices = (stbtt_vertex *) STBTT_malloc(m * sizeof(vertices[0]), info->userdata); + if (vertices == 0) + return 0; + + next_move = 0; + flagcount=0; + + // in first pass, we load uninterpreted data into the allocated array + // above, shifted to the end of the array so we won't overwrite it when + // we create our final data starting from the front + + off = m - n; // starting offset for uninterpreted data, regardless of how m ends up being calculated + + // first load flags + + for (i=0; i < n; ++i) { + if (flagcount == 0) { + flags = *points++; + if (flags & 8) + flagcount = *points++; + } else + --flagcount; + vertices[off+i].type = flags; + } + + // now load x coordinates + x=0; + for (i=0; i < n; ++i) { + flags = vertices[off+i].type; + if (flags & 2) { + stbtt_int16 dx = *points++; + x += (flags & 16) ? dx : -dx; // ??? + } else { + if (!(flags & 16)) { + x = x + (stbtt_int16) (points[0]*256 + points[1]); + points += 2; + } + } + vertices[off+i].x = (stbtt_int16) x; + } + + // now load y coordinates + y=0; + for (i=0; i < n; ++i) { + flags = vertices[off+i].type; + if (flags & 4) { + stbtt_int16 dy = *points++; + y += (flags & 32) ? dy : -dy; // ??? + } else { + if (!(flags & 32)) { + y = y + (stbtt_int16) (points[0]*256 + points[1]); + points += 2; + } + } + vertices[off+i].y = (stbtt_int16) y; + } + + // now convert them to our format + num_vertices=0; + sx = sy = cx = cy = scx = scy = 0; + for (i=0; i < n; ++i) { + flags = vertices[off+i].type; + x = (stbtt_int16) vertices[off+i].x; + y = (stbtt_int16) vertices[off+i].y; + + if (next_move == i) { + if (i != 0) + num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy); + + // now start the new one + start_off = !(flags & 1); + if (start_off) { + // if we start off with an off-curve point, then when we need to find a point on the curve + // where we can start, and we need to save some state for when we wraparound. + scx = x; + scy = y; + if (!(vertices[off+i+1].type & 1)) { + // next point is also a curve point, so interpolate an on-point curve + sx = (x + (stbtt_int32) vertices[off+i+1].x) >> 1; + sy = (y + (stbtt_int32) vertices[off+i+1].y) >> 1; + } else { + // otherwise just use the next point as our start point + sx = (stbtt_int32) vertices[off+i+1].x; + sy = (stbtt_int32) vertices[off+i+1].y; + ++i; // we're using point i+1 as the starting point, so skip it + } + } else { + sx = x; + sy = y; + } + stbtt_setvertex(&vertices[num_vertices++], STBTT_vmove,sx,sy,0,0); + was_off = 0; + next_move = 1 + ttUSHORT(endPtsOfContours+j*2); + ++j; + } else { + if (!(flags & 1)) { // if it's a curve + if (was_off) // two off-curve control points in a row means interpolate an on-curve midpoint + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx+x)>>1, (cy+y)>>1, cx, cy); + cx = x; + cy = y; + was_off = 1; + } else { + if (was_off) + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, x,y, cx, cy); + else + stbtt_setvertex(&vertices[num_vertices++], STBTT_vline, x,y,0,0); + was_off = 0; + } + } + } + num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy); + } else if (numberOfContours < 0) { + // Compound shapes. + int more = 1; + stbtt_uint8 *comp = data + g + 10; + num_vertices = 0; + vertices = 0; + while (more) { + stbtt_uint16 flags, gidx; + int comp_num_verts = 0, i; + stbtt_vertex *comp_verts = 0, *tmp = 0; + float mtx[6] = {1,0,0,1,0,0}, m, n; + + flags = ttSHORT(comp); comp+=2; + gidx = ttSHORT(comp); comp+=2; + + if (flags & 2) { // XY values + if (flags & 1) { // shorts + mtx[4] = ttSHORT(comp); comp+=2; + mtx[5] = ttSHORT(comp); comp+=2; + } else { + mtx[4] = ttCHAR(comp); comp+=1; + mtx[5] = ttCHAR(comp); comp+=1; + } + } + else { + // @TODO handle matching point + STBTT_assert(0); + } + if (flags & (1<<3)) { // WE_HAVE_A_SCALE + mtx[0] = mtx[3] = ttSHORT(comp)/16384.0f; comp+=2; + mtx[1] = mtx[2] = 0; + } else if (flags & (1<<6)) { // WE_HAVE_AN_X_AND_YSCALE + mtx[0] = ttSHORT(comp)/16384.0f; comp+=2; + mtx[1] = mtx[2] = 0; + mtx[3] = ttSHORT(comp)/16384.0f; comp+=2; + } else if (flags & (1<<7)) { // WE_HAVE_A_TWO_BY_TWO + mtx[0] = ttSHORT(comp)/16384.0f; comp+=2; + mtx[1] = ttSHORT(comp)/16384.0f; comp+=2; + mtx[2] = ttSHORT(comp)/16384.0f; comp+=2; + mtx[3] = ttSHORT(comp)/16384.0f; comp+=2; + } + + // Find transformation scales. + m = (float) STBTT_sqrt(mtx[0]*mtx[0] + mtx[1]*mtx[1]); + n = (float) STBTT_sqrt(mtx[2]*mtx[2] + mtx[3]*mtx[3]); + + // Get indexed glyph. + comp_num_verts = stbtt_GetGlyphShape(info, gidx, &comp_verts); + if (comp_num_verts > 0) { + // Transform vertices. + for (i = 0; i < comp_num_verts; ++i) { + stbtt_vertex* v = &comp_verts[i]; + stbtt_vertex_type x,y; + x=v->x; y=v->y; + v->x = (stbtt_vertex_type)(m * (mtx[0]*x + mtx[2]*y + mtx[4])); + v->y = (stbtt_vertex_type)(n * (mtx[1]*x + mtx[3]*y + mtx[5])); + x=v->cx; y=v->cy; + v->cx = (stbtt_vertex_type)(m * (mtx[0]*x + mtx[2]*y + mtx[4])); + v->cy = (stbtt_vertex_type)(n * (mtx[1]*x + mtx[3]*y + mtx[5])); + } + // Append vertices. + tmp = (stbtt_vertex*)STBTT_malloc((num_vertices+comp_num_verts)*sizeof(stbtt_vertex), info->userdata); + if (!tmp) { + if (vertices) STBTT_free(vertices, info->userdata); + if (comp_verts) STBTT_free(comp_verts, info->userdata); + return 0; + } + if (num_vertices > 0 && vertices) STBTT_memcpy(tmp, vertices, num_vertices*sizeof(stbtt_vertex)); + STBTT_memcpy(tmp+num_vertices, comp_verts, comp_num_verts*sizeof(stbtt_vertex)); + if (vertices) STBTT_free(vertices, info->userdata); + vertices = tmp; + STBTT_free(comp_verts, info->userdata); + num_vertices += comp_num_verts; + } + // More components ? + more = flags & (1<<5); + } + } else { + // numberOfCounters == 0, do nothing + } + + *pvertices = vertices; + return num_vertices; +} + +typedef struct +{ + int bounds; + int started; + float first_x, first_y; + float x, y; + stbtt_int32 min_x, max_x, min_y, max_y; + + stbtt_vertex *pvertices; + int num_vertices; +} stbtt__csctx; + +#define STBTT__CSCTX_INIT(bounds) {bounds,0, 0,0, 0,0, 0,0,0,0, NULL, 0} + +static void stbtt__track_vertex(stbtt__csctx *c, stbtt_int32 x, stbtt_int32 y) +{ + if (x > c->max_x || !c->started) c->max_x = x; + if (y > c->max_y || !c->started) c->max_y = y; + if (x < c->min_x || !c->started) c->min_x = x; + if (y < c->min_y || !c->started) c->min_y = y; + c->started = 1; +} + +static void stbtt__csctx_v(stbtt__csctx *c, stbtt_uint8 type, stbtt_int32 x, stbtt_int32 y, stbtt_int32 cx, stbtt_int32 cy, stbtt_int32 cx1, stbtt_int32 cy1) +{ + if (c->bounds) { + stbtt__track_vertex(c, x, y); + if (type == STBTT_vcubic) { + stbtt__track_vertex(c, cx, cy); + stbtt__track_vertex(c, cx1, cy1); + } + } else { + stbtt_setvertex(&c->pvertices[c->num_vertices], type, x, y, cx, cy); + c->pvertices[c->num_vertices].cx1 = (stbtt_int16) cx1; + c->pvertices[c->num_vertices].cy1 = (stbtt_int16) cy1; + } + c->num_vertices++; +} + +static void stbtt__csctx_close_shape(stbtt__csctx *ctx) +{ + if (ctx->first_x != ctx->x || ctx->first_y != ctx->y) + stbtt__csctx_v(ctx, STBTT_vline, (int)ctx->first_x, (int)ctx->first_y, 0, 0, 0, 0); +} + +static void stbtt__csctx_rmove_to(stbtt__csctx *ctx, float dx, float dy) +{ + stbtt__csctx_close_shape(ctx); + ctx->first_x = ctx->x = ctx->x + dx; + ctx->first_y = ctx->y = ctx->y + dy; + stbtt__csctx_v(ctx, STBTT_vmove, (int)ctx->x, (int)ctx->y, 0, 0, 0, 0); +} + +static void stbtt__csctx_rline_to(stbtt__csctx *ctx, float dx, float dy) +{ + ctx->x += dx; + ctx->y += dy; + stbtt__csctx_v(ctx, STBTT_vline, (int)ctx->x, (int)ctx->y, 0, 0, 0, 0); +} + +static void stbtt__csctx_rccurve_to(stbtt__csctx *ctx, float dx1, float dy1, float dx2, float dy2, float dx3, float dy3) +{ + float cx1 = ctx->x + dx1; + float cy1 = ctx->y + dy1; + float cx2 = cx1 + dx2; + float cy2 = cy1 + dy2; + ctx->x = cx2 + dx3; + ctx->y = cy2 + dy3; + stbtt__csctx_v(ctx, STBTT_vcubic, (int)ctx->x, (int)ctx->y, (int)cx1, (int)cy1, (int)cx2, (int)cy2); +} + +static stbtt__buf stbtt__get_subr(stbtt__buf idx, int n) +{ + int count = stbtt__cff_index_count(&idx); + int bias = 107; + if (count >= 33900) + bias = 32768; + else if (count >= 1240) + bias = 1131; + n += bias; + if (n < 0 || n >= count) + return stbtt__new_buf(NULL, 0); + return stbtt__cff_index_get(idx, n); +} + +static stbtt__buf stbtt__cid_get_glyph_subrs(const stbtt_fontinfo *info, int glyph_index) +{ + stbtt__buf fdselect = info->fdselect; + int nranges, start, end, v, fmt, fdselector = -1, i; + + stbtt__buf_seek(&fdselect, 0); + fmt = stbtt__buf_get8(&fdselect); + if (fmt == 0) { + // untested + stbtt__buf_skip(&fdselect, glyph_index); + fdselector = stbtt__buf_get8(&fdselect); + } else if (fmt == 3) { + nranges = stbtt__buf_get16(&fdselect); + start = stbtt__buf_get16(&fdselect); + for (i = 0; i < nranges; i++) { + v = stbtt__buf_get8(&fdselect); + end = stbtt__buf_get16(&fdselect); + if (glyph_index >= start && glyph_index < end) { + fdselector = v; + break; + } + start = end; + } + } + if (fdselector == -1) stbtt__new_buf(NULL, 0); + return stbtt__get_subrs(info->cff, stbtt__cff_index_get(info->fontdicts, fdselector)); +} + +static int stbtt__run_charstring(const stbtt_fontinfo *info, int glyph_index, stbtt__csctx *c) +{ + int in_header = 1, maskbits = 0, subr_stack_height = 0, sp = 0, v, i, b0; + int has_subrs = 0, clear_stack; + float s[48]; + stbtt__buf subr_stack[10], subrs = info->subrs, b; + float f; + +#define STBTT__CSERR(s) (0) + + // this currently ignores the initial width value, which isn't needed if we have hmtx + b = stbtt__cff_index_get(info->charstrings, glyph_index); + while (b.cursor < b.size) { + i = 0; + clear_stack = 1; + b0 = stbtt__buf_get8(&b); + switch (b0) { + // @TODO implement hinting + case 0x13: // hintmask + case 0x14: // cntrmask + if (in_header) + maskbits += (sp / 2); // implicit "vstem" + in_header = 0; + stbtt__buf_skip(&b, (maskbits + 7) / 8); + break; + + case 0x01: // hstem + case 0x03: // vstem + case 0x12: // hstemhm + case 0x17: // vstemhm + maskbits += (sp / 2); + break; + + case 0x15: // rmoveto + in_header = 0; + if (sp < 2) return STBTT__CSERR("rmoveto stack"); + stbtt__csctx_rmove_to(c, s[sp-2], s[sp-1]); + break; + case 0x04: // vmoveto + in_header = 0; + if (sp < 1) return STBTT__CSERR("vmoveto stack"); + stbtt__csctx_rmove_to(c, 0, s[sp-1]); + break; + case 0x16: // hmoveto + in_header = 0; + if (sp < 1) return STBTT__CSERR("hmoveto stack"); + stbtt__csctx_rmove_to(c, s[sp-1], 0); + break; + + case 0x05: // rlineto + if (sp < 2) return STBTT__CSERR("rlineto stack"); + for (; i + 1 < sp; i += 2) + stbtt__csctx_rline_to(c, s[i], s[i+1]); + break; + + // hlineto/vlineto and vhcurveto/hvcurveto alternate horizontal and vertical + // starting from a different place. + + case 0x07: // vlineto + if (sp < 1) return STBTT__CSERR("vlineto stack"); + goto vlineto; + case 0x06: // hlineto + if (sp < 1) return STBTT__CSERR("hlineto stack"); + for (;;) { + if (i >= sp) break; + stbtt__csctx_rline_to(c, s[i], 0); + i++; + vlineto: + if (i >= sp) break; + stbtt__csctx_rline_to(c, 0, s[i]); + i++; + } + break; + + case 0x1F: // hvcurveto + if (sp < 4) return STBTT__CSERR("hvcurveto stack"); + goto hvcurveto; + case 0x1E: // vhcurveto + if (sp < 4) return STBTT__CSERR("vhcurveto stack"); + for (;;) { + if (i + 3 >= sp) break; + stbtt__csctx_rccurve_to(c, 0, s[i], s[i+1], s[i+2], s[i+3], (sp - i == 5) ? s[i + 4] : 0.0f); + i += 4; + hvcurveto: + if (i + 3 >= sp) break; + stbtt__csctx_rccurve_to(c, s[i], 0, s[i+1], s[i+2], (sp - i == 5) ? s[i+4] : 0.0f, s[i+3]); + i += 4; + } + break; + + case 0x08: // rrcurveto + if (sp < 6) return STBTT__CSERR("rcurveline stack"); + for (; i + 5 < sp; i += 6) + stbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]); + break; + + case 0x18: // rcurveline + if (sp < 8) return STBTT__CSERR("rcurveline stack"); + for (; i + 5 < sp - 2; i += 6) + stbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]); + if (i + 1 >= sp) return STBTT__CSERR("rcurveline stack"); + stbtt__csctx_rline_to(c, s[i], s[i+1]); + break; + + case 0x19: // rlinecurve + if (sp < 8) return STBTT__CSERR("rlinecurve stack"); + for (; i + 1 < sp - 6; i += 2) + stbtt__csctx_rline_to(c, s[i], s[i+1]); + if (i + 5 >= sp) return STBTT__CSERR("rlinecurve stack"); + stbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]); + break; + + case 0x1A: // vvcurveto + case 0x1B: // hhcurveto + if (sp < 4) return STBTT__CSERR("(vv|hh)curveto stack"); + f = 0.0; + if (sp & 1) { f = s[i]; i++; } + for (; i + 3 < sp; i += 4) { + if (b0 == 0x1B) + stbtt__csctx_rccurve_to(c, s[i], f, s[i+1], s[i+2], s[i+3], 0.0); + else + stbtt__csctx_rccurve_to(c, f, s[i], s[i+1], s[i+2], 0.0, s[i+3]); + f = 0.0; + } + break; + + case 0x0A: // callsubr + if (!has_subrs) { + if (info->fdselect.size) + subrs = stbtt__cid_get_glyph_subrs(info, glyph_index); + has_subrs = 1; + } + // FALLTHROUGH + case 0x1D: // callgsubr + if (sp < 1) return STBTT__CSERR("call(g|)subr stack"); + v = (int) s[--sp]; + if (subr_stack_height >= 10) return STBTT__CSERR("recursion limit"); + subr_stack[subr_stack_height++] = b; + b = stbtt__get_subr(b0 == 0x0A ? subrs : info->gsubrs, v); + if (b.size == 0) return STBTT__CSERR("subr not found"); + b.cursor = 0; + clear_stack = 0; + break; + + case 0x0B: // return + if (subr_stack_height <= 0) return STBTT__CSERR("return outside subr"); + b = subr_stack[--subr_stack_height]; + clear_stack = 0; + break; + + case 0x0E: // endchar + stbtt__csctx_close_shape(c); + return 1; + + case 0x0C: { // two-byte escape + float dx1, dx2, dx3, dx4, dx5, dx6, dy1, dy2, dy3, dy4, dy5, dy6; + float dx, dy; + int b1 = stbtt__buf_get8(&b); + switch (b1) { + // @TODO These "flex" implementations ignore the flex-depth and resolution, + // and always draw beziers. + case 0x22: // hflex + if (sp < 7) return STBTT__CSERR("hflex stack"); + dx1 = s[0]; + dx2 = s[1]; + dy2 = s[2]; + dx3 = s[3]; + dx4 = s[4]; + dx5 = s[5]; + dx6 = s[6]; + stbtt__csctx_rccurve_to(c, dx1, 0, dx2, dy2, dx3, 0); + stbtt__csctx_rccurve_to(c, dx4, 0, dx5, -dy2, dx6, 0); + break; + + case 0x23: // flex + if (sp < 13) return STBTT__CSERR("flex stack"); + dx1 = s[0]; + dy1 = s[1]; + dx2 = s[2]; + dy2 = s[3]; + dx3 = s[4]; + dy3 = s[5]; + dx4 = s[6]; + dy4 = s[7]; + dx5 = s[8]; + dy5 = s[9]; + dx6 = s[10]; + dy6 = s[11]; + //fd is s[12] + stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3); + stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6); + break; + + case 0x24: // hflex1 + if (sp < 9) return STBTT__CSERR("hflex1 stack"); + dx1 = s[0]; + dy1 = s[1]; + dx2 = s[2]; + dy2 = s[3]; + dx3 = s[4]; + dx4 = s[5]; + dx5 = s[6]; + dy5 = s[7]; + dx6 = s[8]; + stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, 0); + stbtt__csctx_rccurve_to(c, dx4, 0, dx5, dy5, dx6, -(dy1+dy2+dy5)); + break; + + case 0x25: // flex1 + if (sp < 11) return STBTT__CSERR("flex1 stack"); + dx1 = s[0]; + dy1 = s[1]; + dx2 = s[2]; + dy2 = s[3]; + dx3 = s[4]; + dy3 = s[5]; + dx4 = s[6]; + dy4 = s[7]; + dx5 = s[8]; + dy5 = s[9]; + dx6 = dy6 = s[10]; + dx = dx1+dx2+dx3+dx4+dx5; + dy = dy1+dy2+dy3+dy4+dy5; + if (STBTT_fabs(dx) > STBTT_fabs(dy)) + dy6 = -dy; + else + dx6 = -dx; + stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3); + stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6); + break; + + default: + return STBTT__CSERR("unimplemented"); + } + } break; + + default: + if (b0 != 255 && b0 != 28 && b0 < 32) + return STBTT__CSERR("reserved operator"); + + // push immediate + if (b0 == 255) { + f = (float)(stbtt_int32)stbtt__buf_get32(&b) / 0x10000; + } else { + stbtt__buf_skip(&b, -1); + f = (float)(stbtt_int16)stbtt__cff_int(&b); + } + if (sp >= 48) return STBTT__CSERR("push stack overflow"); + s[sp++] = f; + clear_stack = 0; + break; + } + if (clear_stack) sp = 0; + } + return STBTT__CSERR("no endchar"); + +#undef STBTT__CSERR +} + +static int stbtt__GetGlyphShapeT2(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices) +{ + // runs the charstring twice, once to count and once to output (to avoid realloc) + stbtt__csctx count_ctx = STBTT__CSCTX_INIT(1); + stbtt__csctx output_ctx = STBTT__CSCTX_INIT(0); + if (stbtt__run_charstring(info, glyph_index, &count_ctx)) { + *pvertices = (stbtt_vertex*)STBTT_malloc(count_ctx.num_vertices*sizeof(stbtt_vertex), info->userdata); + output_ctx.pvertices = *pvertices; + if (stbtt__run_charstring(info, glyph_index, &output_ctx)) { + STBTT_assert(output_ctx.num_vertices == count_ctx.num_vertices); + return output_ctx.num_vertices; + } + } + *pvertices = NULL; + return 0; +} + +static int stbtt__GetGlyphInfoT2(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1) +{ + stbtt__csctx c = STBTT__CSCTX_INIT(1); + int r = stbtt__run_charstring(info, glyph_index, &c); + if (x0) *x0 = r ? c.min_x : 0; + if (y0) *y0 = r ? c.min_y : 0; + if (x1) *x1 = r ? c.max_x : 0; + if (y1) *y1 = r ? c.max_y : 0; + return r ? c.num_vertices : 0; +} + +STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices) +{ + if (!info->cff.size) + return stbtt__GetGlyphShapeTT(info, glyph_index, pvertices); + else + return stbtt__GetGlyphShapeT2(info, glyph_index, pvertices); +} + +STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing) +{ + stbtt_uint16 numOfLongHorMetrics = ttUSHORT(info->data+info->hhea + 34); + if (glyph_index < numOfLongHorMetrics) { + if (advanceWidth) *advanceWidth = ttSHORT(info->data + info->hmtx + 4*glyph_index); + if (leftSideBearing) *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*glyph_index + 2); + } else { + if (advanceWidth) *advanceWidth = ttSHORT(info->data + info->hmtx + 4*(numOfLongHorMetrics-1)); + if (leftSideBearing) *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*numOfLongHorMetrics + 2*(glyph_index - numOfLongHorMetrics)); + } +} + +STBTT_DEF int stbtt_GetKerningTableLength(const stbtt_fontinfo *info) +{ + stbtt_uint8 *data = info->data + info->kern; + + // we only look at the first table. it must be 'horizontal' and format 0. + if (!info->kern) + return 0; + if (ttUSHORT(data+2) < 1) // number of tables, need at least 1 + return 0; + if (ttUSHORT(data+8) != 1) // horizontal flag must be set in format + return 0; + + return ttUSHORT(data+10); +} + +STBTT_DEF int stbtt_GetKerningTable(const stbtt_fontinfo *info, stbtt_kerningentry* table, int table_length) +{ + stbtt_uint8 *data = info->data + info->kern; + int k, length; + + // we only look at the first table. it must be 'horizontal' and format 0. + if (!info->kern) + return 0; + if (ttUSHORT(data+2) < 1) // number of tables, need at least 1 + return 0; + if (ttUSHORT(data+8) != 1) // horizontal flag must be set in format + return 0; + + length = ttUSHORT(data+10); + if (table_length < length) + length = table_length; + + for (k = 0; k < length; k++) + { + table[k].glyph1 = ttUSHORT(data+18+(k*6)); + table[k].glyph2 = ttUSHORT(data+20+(k*6)); + table[k].advance = ttSHORT(data+22+(k*6)); + } + + return length; +} + +static int stbtt__GetGlyphKernInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) +{ + stbtt_uint8 *data = info->data + info->kern; + stbtt_uint32 needle, straw; + int l, r, m; + + // we only look at the first table. it must be 'horizontal' and format 0. + if (!info->kern) + return 0; + if (ttUSHORT(data+2) < 1) // number of tables, need at least 1 + return 0; + if (ttUSHORT(data+8) != 1) // horizontal flag must be set in format + return 0; + + l = 0; + r = ttUSHORT(data+10) - 1; + needle = glyph1 << 16 | glyph2; + while (l <= r) { + m = (l + r) >> 1; + straw = ttULONG(data+18+(m*6)); // note: unaligned read + if (needle < straw) + r = m - 1; + else if (needle > straw) + l = m + 1; + else + return ttSHORT(data+22+(m*6)); + } + return 0; +} + +static stbtt_int32 stbtt__GetCoverageIndex(stbtt_uint8 *coverageTable, int glyph) +{ + stbtt_uint16 coverageFormat = ttUSHORT(coverageTable); + switch (coverageFormat) { + case 1: { + stbtt_uint16 glyphCount = ttUSHORT(coverageTable + 2); + + // Binary search. + stbtt_int32 l=0, r=glyphCount-1, m; + int straw, needle=glyph; + while (l <= r) { + stbtt_uint8 *glyphArray = coverageTable + 4; + stbtt_uint16 glyphID; + m = (l + r) >> 1; + glyphID = ttUSHORT(glyphArray + 2 * m); + straw = glyphID; + if (needle < straw) + r = m - 1; + else if (needle > straw) + l = m + 1; + else { + return m; + } + } + break; + } + + case 2: { + stbtt_uint16 rangeCount = ttUSHORT(coverageTable + 2); + stbtt_uint8 *rangeArray = coverageTable + 4; + + // Binary search. + stbtt_int32 l=0, r=rangeCount-1, m; + int strawStart, strawEnd, needle=glyph; + while (l <= r) { + stbtt_uint8 *rangeRecord; + m = (l + r) >> 1; + rangeRecord = rangeArray + 6 * m; + strawStart = ttUSHORT(rangeRecord); + strawEnd = ttUSHORT(rangeRecord + 2); + if (needle < strawStart) + r = m - 1; + else if (needle > strawEnd) + l = m + 1; + else { + stbtt_uint16 startCoverageIndex = ttUSHORT(rangeRecord + 4); + return startCoverageIndex + glyph - strawStart; + } + } + break; + } + + default: return -1; // unsupported + } + + return -1; +} + +static stbtt_int32 stbtt__GetGlyphClass(stbtt_uint8 *classDefTable, int glyph) +{ + stbtt_uint16 classDefFormat = ttUSHORT(classDefTable); + switch (classDefFormat) + { + case 1: { + stbtt_uint16 startGlyphID = ttUSHORT(classDefTable + 2); + stbtt_uint16 glyphCount = ttUSHORT(classDefTable + 4); + stbtt_uint8 *classDef1ValueArray = classDefTable + 6; + + if (glyph >= startGlyphID && glyph < startGlyphID + glyphCount) + return (stbtt_int32)ttUSHORT(classDef1ValueArray + 2 * (glyph - startGlyphID)); + break; + } + + case 2: { + stbtt_uint16 classRangeCount = ttUSHORT(classDefTable + 2); + stbtt_uint8 *classRangeRecords = classDefTable + 4; + + // Binary search. + stbtt_int32 l=0, r=classRangeCount-1, m; + int strawStart, strawEnd, needle=glyph; + while (l <= r) { + stbtt_uint8 *classRangeRecord; + m = (l + r) >> 1; + classRangeRecord = classRangeRecords + 6 * m; + strawStart = ttUSHORT(classRangeRecord); + strawEnd = ttUSHORT(classRangeRecord + 2); + if (needle < strawStart) + r = m - 1; + else if (needle > strawEnd) + l = m + 1; + else + return (stbtt_int32)ttUSHORT(classRangeRecord + 4); + } + break; + } + + default: + return -1; // Unsupported definition type, return an error. + } + + // "All glyphs not assigned to a class fall into class 0". (OpenType spec) + return 0; +} + +// Define to STBTT_assert(x) if you want to break on unimplemented formats. +#define STBTT_GPOS_TODO_assert(x) + +static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) +{ + stbtt_uint16 lookupListOffset; + stbtt_uint8 *lookupList; + stbtt_uint16 lookupCount; + stbtt_uint8 *data; + stbtt_int32 i, sti; + + if (!info->gpos) return 0; + + data = info->data + info->gpos; + + if (ttUSHORT(data+0) != 1) return 0; // Major version 1 + if (ttUSHORT(data+2) != 0) return 0; // Minor version 0 + + lookupListOffset = ttUSHORT(data+8); + lookupList = data + lookupListOffset; + lookupCount = ttUSHORT(lookupList); + + for (i=0; i= pairSetCount) return 0; + + needle=glyph2; + r=pairValueCount-1; + l=0; + + // Binary search. + while (l <= r) { + stbtt_uint16 secondGlyph; + stbtt_uint8 *pairValue; + m = (l + r) >> 1; + pairValue = pairValueArray + (2 + valueRecordPairSizeInBytes) * m; + secondGlyph = ttUSHORT(pairValue); + straw = secondGlyph; + if (needle < straw) + r = m - 1; + else if (needle > straw) + l = m + 1; + else { + stbtt_int16 xAdvance = ttSHORT(pairValue + 2); + return xAdvance; + } + } + } else + return 0; + break; + } + + case 2: { + stbtt_uint16 valueFormat1 = ttUSHORT(table + 4); + stbtt_uint16 valueFormat2 = ttUSHORT(table + 6); + if (valueFormat1 == 4 && valueFormat2 == 0) { // Support more formats? + stbtt_uint16 classDef1Offset = ttUSHORT(table + 8); + stbtt_uint16 classDef2Offset = ttUSHORT(table + 10); + int glyph1class = stbtt__GetGlyphClass(table + classDef1Offset, glyph1); + int glyph2class = stbtt__GetGlyphClass(table + classDef2Offset, glyph2); + + stbtt_uint16 class1Count = ttUSHORT(table + 12); + stbtt_uint16 class2Count = ttUSHORT(table + 14); + stbtt_uint8 *class1Records, *class2Records; + stbtt_int16 xAdvance; + + if (glyph1class < 0 || glyph1class >= class1Count) return 0; // malformed + if (glyph2class < 0 || glyph2class >= class2Count) return 0; // malformed + + class1Records = table + 16; + class2Records = class1Records + 2 * (glyph1class * class2Count); + xAdvance = ttSHORT(class2Records + 2 * glyph2class); + return xAdvance; + } else + return 0; + break; + } + + default: + return 0; // Unsupported position format + } + } + } + + return 0; +} + +STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int g1, int g2) +{ + int xAdvance = 0; + + if (info->gpos) + xAdvance += stbtt__GetGlyphGPOSInfoAdvance(info, g1, g2); + else if (info->kern) + xAdvance += stbtt__GetGlyphKernInfoAdvance(info, g1, g2); + + return xAdvance; +} + +STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2) +{ + if (!info->kern && !info->gpos) // if no kerning table, don't waste time looking up both codepoint->glyphs + return 0; + return stbtt_GetGlyphKernAdvance(info, stbtt_FindGlyphIndex(info,ch1), stbtt_FindGlyphIndex(info,ch2)); +} + +STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing) +{ + stbtt_GetGlyphHMetrics(info, stbtt_FindGlyphIndex(info,codepoint), advanceWidth, leftSideBearing); +} + +STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap) +{ + if (ascent ) *ascent = ttSHORT(info->data+info->hhea + 4); + if (descent) *descent = ttSHORT(info->data+info->hhea + 6); + if (lineGap) *lineGap = ttSHORT(info->data+info->hhea + 8); +} + +STBTT_DEF int stbtt_GetFontVMetricsOS2(const stbtt_fontinfo *info, int *typoAscent, int *typoDescent, int *typoLineGap) +{ + int tab = stbtt__find_table(info->data, info->fontstart, "OS/2"); + if (!tab) + return 0; + if (typoAscent ) *typoAscent = ttSHORT(info->data+tab + 68); + if (typoDescent) *typoDescent = ttSHORT(info->data+tab + 70); + if (typoLineGap) *typoLineGap = ttSHORT(info->data+tab + 72); + return 1; +} + +STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1) +{ + *x0 = ttSHORT(info->data + info->head + 36); + *y0 = ttSHORT(info->data + info->head + 38); + *x1 = ttSHORT(info->data + info->head + 40); + *y1 = ttSHORT(info->data + info->head + 42); +} + +STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float height) +{ + int fheight = ttSHORT(info->data + info->hhea + 4) - ttSHORT(info->data + info->hhea + 6); + return (float) height / fheight; +} + +STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels) +{ + int unitsPerEm = ttUSHORT(info->data + info->head + 18); + return pixels / unitsPerEm; +} + +STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v) +{ + STBTT_free(v, info->userdata); +} + +STBTT_DEF stbtt_uint8 *stbtt_FindSVGDoc(const stbtt_fontinfo *info, int gl) +{ + int i; + stbtt_uint8 *data = info->data; + stbtt_uint8 *svg_doc_list = data + stbtt__get_svg((stbtt_fontinfo *) info); + + int numEntries = ttUSHORT(svg_doc_list); + stbtt_uint8 *svg_docs = svg_doc_list + 2; + + for(i=0; i= ttUSHORT(svg_doc)) && (gl <= ttUSHORT(svg_doc + 2))) + return svg_doc; + } + return 0; +} + +STBTT_DEF int stbtt_GetGlyphSVG(const stbtt_fontinfo *info, int gl, const char **svg) +{ + stbtt_uint8 *data = info->data; + stbtt_uint8 *svg_doc; + + if (info->svg == 0) + return 0; + + svg_doc = stbtt_FindSVGDoc(info, gl); + if (svg_doc != NULL) { + *svg = (char *) data + info->svg + ttULONG(svg_doc + 4); + return ttULONG(svg_doc + 8); + } else { + return 0; + } +} + +STBTT_DEF int stbtt_GetCodepointSVG(const stbtt_fontinfo *info, int unicode_codepoint, const char **svg) +{ + return stbtt_GetGlyphSVG(info, stbtt_FindGlyphIndex(info, unicode_codepoint), svg); +} + +////////////////////////////////////////////////////////////////////////////// +// +// antialiasing software rasterizer +// + +STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1) +{ + int x0=0,y0=0,x1,y1; // =0 suppresses compiler warning + if (!stbtt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1)) { + // e.g. space character + if (ix0) *ix0 = 0; + if (iy0) *iy0 = 0; + if (ix1) *ix1 = 0; + if (iy1) *iy1 = 0; + } else { + // move to integral bboxes (treating pixels as little squares, what pixels get touched)? + if (ix0) *ix0 = STBTT_ifloor( x0 * scale_x + shift_x); + if (iy0) *iy0 = STBTT_ifloor(-y1 * scale_y + shift_y); + if (ix1) *ix1 = STBTT_iceil ( x1 * scale_x + shift_x); + if (iy1) *iy1 = STBTT_iceil (-y0 * scale_y + shift_y); + } +} + +STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1) +{ + stbtt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y,0.0f,0.0f, ix0, iy0, ix1, iy1); +} + +STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1) +{ + stbtt_GetGlyphBitmapBoxSubpixel(font, stbtt_FindGlyphIndex(font,codepoint), scale_x, scale_y,shift_x,shift_y, ix0,iy0,ix1,iy1); +} + +STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1) +{ + stbtt_GetCodepointBitmapBoxSubpixel(font, codepoint, scale_x, scale_y,0.0f,0.0f, ix0,iy0,ix1,iy1); +} + +////////////////////////////////////////////////////////////////////////////// +// +// Rasterizer + +typedef struct stbtt__hheap_chunk +{ + struct stbtt__hheap_chunk *next; +} stbtt__hheap_chunk; + +typedef struct stbtt__hheap +{ + struct stbtt__hheap_chunk *head; + void *first_free; + int num_remaining_in_head_chunk; +} stbtt__hheap; + +static void *stbtt__hheap_alloc(stbtt__hheap *hh, size_t size, void *userdata) +{ + if (hh->first_free) { + void *p = hh->first_free; + hh->first_free = * (void **) p; + return p; + } else { + if (hh->num_remaining_in_head_chunk == 0) { + int count = (size < 32 ? 2000 : size < 128 ? 800 : 100); + stbtt__hheap_chunk *c = (stbtt__hheap_chunk *) STBTT_malloc(sizeof(stbtt__hheap_chunk) + size * count, userdata); + if (c == NULL) + return NULL; + c->next = hh->head; + hh->head = c; + hh->num_remaining_in_head_chunk = count; + } + --hh->num_remaining_in_head_chunk; + return (char *) (hh->head) + sizeof(stbtt__hheap_chunk) + size * hh->num_remaining_in_head_chunk; + } +} + +static void stbtt__hheap_free(stbtt__hheap *hh, void *p) +{ + *(void **) p = hh->first_free; + hh->first_free = p; +} + +static void stbtt__hheap_cleanup(stbtt__hheap *hh, void *userdata) +{ + stbtt__hheap_chunk *c = hh->head; + while (c) { + stbtt__hheap_chunk *n = c->next; + STBTT_free(c, userdata); + c = n; + } +} + +typedef struct stbtt__edge { + float x0,y0, x1,y1; + int invert; +} stbtt__edge; + + +typedef struct stbtt__active_edge +{ + struct stbtt__active_edge *next; + #if STBTT_RASTERIZER_VERSION==1 + int x,dx; + float ey; + int direction; + #elif STBTT_RASTERIZER_VERSION==2 + float fx,fdx,fdy; + float direction; + float sy; + float ey; + #else + #error "Unrecognized value of STBTT_RASTERIZER_VERSION" + #endif +} stbtt__active_edge; + +#if STBTT_RASTERIZER_VERSION == 1 +#define STBTT_FIXSHIFT 10 +#define STBTT_FIX (1 << STBTT_FIXSHIFT) +#define STBTT_FIXMASK (STBTT_FIX-1) + +static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point, void *userdata) +{ + stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata); + float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); + STBTT_assert(z != NULL); + if (!z) return z; + + // round dx down to avoid overshooting + if (dxdy < 0) + z->dx = -STBTT_ifloor(STBTT_FIX * -dxdy); + else + z->dx = STBTT_ifloor(STBTT_FIX * dxdy); + + z->x = STBTT_ifloor(STBTT_FIX * e->x0 + z->dx * (start_point - e->y0)); // use z->dx so when we offset later it's by the same amount + z->x -= off_x * STBTT_FIX; + + z->ey = e->y1; + z->next = 0; + z->direction = e->invert ? 1 : -1; + return z; +} +#elif STBTT_RASTERIZER_VERSION == 2 +static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point, void *userdata) +{ + stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata); + float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); + STBTT_assert(z != NULL); + //STBTT_assert(e->y0 <= start_point); + if (!z) return z; + z->fdx = dxdy; + z->fdy = dxdy != 0.0f ? (1.0f/dxdy) : 0.0f; + z->fx = e->x0 + dxdy * (start_point - e->y0); + z->fx -= off_x; + z->direction = e->invert ? 1.0f : -1.0f; + z->sy = e->y0; + z->ey = e->y1; + z->next = 0; + return z; +} +#else +#error "Unrecognized value of STBTT_RASTERIZER_VERSION" +#endif + +#if STBTT_RASTERIZER_VERSION == 1 +// note: this routine clips fills that extend off the edges... ideally this +// wouldn't happen, but it could happen if the truetype glyph bounding boxes +// are wrong, or if the user supplies a too-small bitmap +static void stbtt__fill_active_edges(unsigned char *scanline, int len, stbtt__active_edge *e, int max_weight) +{ + // non-zero winding fill + int x0=0, w=0; + + while (e) { + if (w == 0) { + // if we're currently at zero, we need to record the edge start point + x0 = e->x; w += e->direction; + } else { + int x1 = e->x; w += e->direction; + // if we went to zero, we need to draw + if (w == 0) { + int i = x0 >> STBTT_FIXSHIFT; + int j = x1 >> STBTT_FIXSHIFT; + + if (i < len && j >= 0) { + if (i == j) { + // x0,x1 are the same pixel, so compute combined coverage + scanline[i] = scanline[i] + (stbtt_uint8) ((x1 - x0) * max_weight >> STBTT_FIXSHIFT); + } else { + if (i >= 0) // add antialiasing for x0 + scanline[i] = scanline[i] + (stbtt_uint8) (((STBTT_FIX - (x0 & STBTT_FIXMASK)) * max_weight) >> STBTT_FIXSHIFT); + else + i = -1; // clip + + if (j < len) // add antialiasing for x1 + scanline[j] = scanline[j] + (stbtt_uint8) (((x1 & STBTT_FIXMASK) * max_weight) >> STBTT_FIXSHIFT); + else + j = len; // clip + + for (++i; i < j; ++i) // fill pixels between x0 and x1 + scanline[i] = scanline[i] + (stbtt_uint8) max_weight; + } + } + } + } + + e = e->next; + } +} + +static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata) +{ + stbtt__hheap hh = { 0, 0, 0 }; + stbtt__active_edge *active = NULL; + int y,j=0; + int max_weight = (255 / vsubsample); // weight per vertical scanline + int s; // vertical subsample index + unsigned char scanline_data[512], *scanline; + + if (result->w > 512) + scanline = (unsigned char *) STBTT_malloc(result->w, userdata); + else + scanline = scanline_data; + + y = off_y * vsubsample; + e[n].y0 = (off_y + result->h) * (float) vsubsample + 1; + + while (j < result->h) { + STBTT_memset(scanline, 0, result->w); + for (s=0; s < vsubsample; ++s) { + // find center of pixel for this scanline + float scan_y = y + 0.5f; + stbtt__active_edge **step = &active; + + // update all active edges; + // remove all active edges that terminate before the center of this scanline + while (*step) { + stbtt__active_edge * z = *step; + if (z->ey <= scan_y) { + *step = z->next; // delete from list + STBTT_assert(z->direction); + z->direction = 0; + stbtt__hheap_free(&hh, z); + } else { + z->x += z->dx; // advance to position for current scanline + step = &((*step)->next); // advance through list + } + } + + // resort the list if needed + for(;;) { + int changed=0; + step = &active; + while (*step && (*step)->next) { + if ((*step)->x > (*step)->next->x) { + stbtt__active_edge *t = *step; + stbtt__active_edge *q = t->next; + + t->next = q->next; + q->next = t; + *step = q; + changed = 1; + } + step = &(*step)->next; + } + if (!changed) break; + } + + // insert all edges that start before the center of this scanline -- omit ones that also end on this scanline + while (e->y0 <= scan_y) { + if (e->y1 > scan_y) { + stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y, userdata); + if (z != NULL) { + // find insertion point + if (active == NULL) + active = z; + else if (z->x < active->x) { + // insert at front + z->next = active; + active = z; + } else { + // find thing to insert AFTER + stbtt__active_edge *p = active; + while (p->next && p->next->x < z->x) + p = p->next; + // at this point, p->next->x is NOT < z->x + z->next = p->next; + p->next = z; + } + } + } + ++e; + } + + // now process all active edges in XOR fashion + if (active) + stbtt__fill_active_edges(scanline, result->w, active, max_weight); + + ++y; + } + STBTT_memcpy(result->pixels + j * result->stride, scanline, result->w); + ++j; + } + + stbtt__hheap_cleanup(&hh, userdata); + + if (scanline != scanline_data) + STBTT_free(scanline, userdata); +} + +#elif STBTT_RASTERIZER_VERSION == 2 + +// the edge passed in here does not cross the vertical line at x or the vertical line at x+1 +// (i.e. it has already been clipped to those) +static void stbtt__handle_clipped_edge(float *scanline, int x, stbtt__active_edge *e, float x0, float y0, float x1, float y1) +{ + if (y0 == y1) return; + STBTT_assert(y0 < y1); + STBTT_assert(e->sy <= e->ey); + if (y0 > e->ey) return; + if (y1 < e->sy) return; + if (y0 < e->sy) { + x0 += (x1-x0) * (e->sy - y0) / (y1-y0); + y0 = e->sy; + } + if (y1 > e->ey) { + x1 += (x1-x0) * (e->ey - y1) / (y1-y0); + y1 = e->ey; + } + + if (x0 == x) + STBTT_assert(x1 <= x+1); + else if (x0 == x+1) + STBTT_assert(x1 >= x); + else if (x0 <= x) + STBTT_assert(x1 <= x); + else if (x0 >= x+1) + STBTT_assert(x1 >= x+1); + else + STBTT_assert(x1 >= x && x1 <= x+1); + + if (x0 <= x && x1 <= x) + scanline[x] += e->direction * (y1-y0); + else if (x0 >= x+1 && x1 >= x+1) + ; + else { + STBTT_assert(x0 >= x && x0 <= x+1 && x1 >= x && x1 <= x+1); + scanline[x] += e->direction * (y1-y0) * (1-((x0-x)+(x1-x))/2); // coverage = 1 - average x position + } +} + +static float stbtt__sized_trapezoid_area(float height, float top_width, float bottom_width) +{ + STBTT_assert(top_width >= 0); + STBTT_assert(bottom_width >= 0); + return (top_width + bottom_width) / 2.0f * height; +} + +static float stbtt__position_trapezoid_area(float height, float tx0, float tx1, float bx0, float bx1) +{ + return stbtt__sized_trapezoid_area(height, tx1 - tx0, bx1 - bx0); +} + +static float stbtt__sized_triangle_area(float height, float width) +{ + return height * width / 2; +} + +static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill, int len, stbtt__active_edge *e, float y_top) +{ + float y_bottom = y_top+1; + + while (e) { + // brute force every pixel + + // compute intersection points with top & bottom + STBTT_assert(e->ey >= y_top); + + if (e->fdx == 0) { + float x0 = e->fx; + if (x0 < len) { + if (x0 >= 0) { + stbtt__handle_clipped_edge(scanline,(int) x0,e, x0,y_top, x0,y_bottom); + stbtt__handle_clipped_edge(scanline_fill-1,(int) x0+1,e, x0,y_top, x0,y_bottom); + } else { + stbtt__handle_clipped_edge(scanline_fill-1,0,e, x0,y_top, x0,y_bottom); + } + } + } else { + float x0 = e->fx; + float dx = e->fdx; + float xb = x0 + dx; + float x_top, x_bottom; + float sy0,sy1; + float dy = e->fdy; + STBTT_assert(e->sy <= y_bottom && e->ey >= y_top); + + // compute endpoints of line segment clipped to this scanline (if the + // line segment starts on this scanline. x0 is the intersection of the + // line with y_top, but that may be off the line segment. + if (e->sy > y_top) { + x_top = x0 + dx * (e->sy - y_top); + sy0 = e->sy; + } else { + x_top = x0; + sy0 = y_top; + } + if (e->ey < y_bottom) { + x_bottom = x0 + dx * (e->ey - y_top); + sy1 = e->ey; + } else { + x_bottom = xb; + sy1 = y_bottom; + } + + if (x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len) { + // from here on, we don't have to range check x values + + if ((int) x_top == (int) x_bottom) { + float height; + // simple case, only spans one pixel + int x = (int) x_top; + height = (sy1 - sy0) * e->direction; + STBTT_assert(x >= 0 && x < len); + scanline[x] += stbtt__position_trapezoid_area(height, x_top, x+1.0f, x_bottom, x+1.0f); + scanline_fill[x] += height; // everything right of this pixel is filled + } else { + int x,x1,x2; + float y_crossing, y_final, step, sign, area; + // covers 2+ pixels + if (x_top > x_bottom) { + // flip scanline vertically; signed area is the same + float t; + sy0 = y_bottom - (sy0 - y_top); + sy1 = y_bottom - (sy1 - y_top); + t = sy0, sy0 = sy1, sy1 = t; + t = x_bottom, x_bottom = x_top, x_top = t; + dx = -dx; + dy = -dy; + t = x0, x0 = xb, xb = t; + } + STBTT_assert(dy >= 0); + STBTT_assert(dx >= 0); + + x1 = (int) x_top; + x2 = (int) x_bottom; + // compute intersection with y axis at x1+1 + y_crossing = y_top + dy * (x1+1 - x0); + + // compute intersection with y axis at x2 + y_final = y_top + dy * (x2 - x0); + + // x1 x_top x2 x_bottom + // y_top +------|-----+------------+------------+--------|---+------------+ + // | | | | | | + // | | | | | | + // sy0 | Txxxxx|............|............|............|............| + // y_crossing | *xxxxx.......|............|............|............| + // | | xxxxx..|............|............|............| + // | | /- xx*xxxx........|............|............| + // | | dy < | xxxxxx..|............|............| + // y_final | | \- | xx*xxx.........|............| + // sy1 | | | | xxxxxB...|............| + // | | | | | | + // | | | | | | + // y_bottom +------------+------------+------------+------------+------------+ + // + // goal is to measure the area covered by '.' in each pixel + + // if x2 is right at the right edge of x1, y_crossing can blow up, github #1057 + // @TODO: maybe test against sy1 rather than y_bottom? + if (y_crossing > y_bottom) + y_crossing = y_bottom; + + sign = e->direction; + + // area of the rectangle covered from sy0..y_crossing + area = sign * (y_crossing-sy0); + + // area of the triangle (x_top,sy0), (x1+1,sy0), (x1+1,y_crossing) + scanline[x1] += stbtt__sized_triangle_area(area, x1+1 - x_top); + + // check if final y_crossing is blown up; no test case for this + if (y_final > y_bottom) { + y_final = y_bottom; + dy = (y_final - y_crossing ) / (x2 - (x1+1)); // if denom=0, y_final = y_crossing, so y_final <= y_bottom + } + + // in second pixel, area covered by line segment found in first pixel + // is always a rectangle 1 wide * the height of that line segment; this + // is exactly what the variable 'area' stores. it also gets a contribution + // from the line segment within it. the THIRD pixel will get the first + // pixel's rectangle contribution, the second pixel's rectangle contribution, + // and its own contribution. the 'own contribution' is the same in every pixel except + // the leftmost and rightmost, a trapezoid that slides down in each pixel. + // the second pixel's contribution to the third pixel will be the + // rectangle 1 wide times the height change in the second pixel, which is dy. + + step = sign * dy * 1; // dy is dy/dx, change in y for every 1 change in x, + // which multiplied by 1-pixel-width is how much pixel area changes for each step in x + // so the area advances by 'step' every time + + for (x = x1+1; x < x2; ++x) { + scanline[x] += area + step/2; // area of trapezoid is 1*step/2 + area += step; + } + STBTT_assert(STBTT_fabs(area) <= 1.01f); // accumulated error from area += step unless we round step down + STBTT_assert(sy1 > y_final-0.01f); + + // area covered in the last pixel is the rectangle from all the pixels to the left, + // plus the trapezoid filled by the line segment in this pixel all the way to the right edge + scanline[x2] += area + sign * stbtt__position_trapezoid_area(sy1-y_final, (float) x2, x2+1.0f, x_bottom, x2+1.0f); + + // the rest of the line is filled based on the total height of the line segment in this pixel + scanline_fill[x2] += sign * (sy1-sy0); + } + } else { + // if edge goes outside of box we're drawing, we require + // clipping logic. since this does not match the intended use + // of this library, we use a different, very slow brute + // force implementation + // note though that this does happen some of the time because + // x_top and x_bottom can be extrapolated at the top & bottom of + // the shape and actually lie outside the bounding box + int x; + for (x=0; x < len; ++x) { + // cases: + // + // there can be up to two intersections with the pixel. any intersection + // with left or right edges can be handled by splitting into two (or three) + // regions. intersections with top & bottom do not necessitate case-wise logic. + // + // the old way of doing this found the intersections with the left & right edges, + // then used some simple logic to produce up to three segments in sorted order + // from top-to-bottom. however, this had a problem: if an x edge was epsilon + // across the x border, then the corresponding y position might not be distinct + // from the other y segment, and it might ignored as an empty segment. to avoid + // that, we need to explicitly produce segments based on x positions. + + // rename variables to clearly-defined pairs + float y0 = y_top; + float x1 = (float) (x); + float x2 = (float) (x+1); + float x3 = xb; + float y3 = y_bottom; + + // x = e->x + e->dx * (y-y_top) + // (y-y_top) = (x - e->x) / e->dx + // y = (x - e->x) / e->dx + y_top + float y1 = (x - x0) / dx + y_top; + float y2 = (x+1 - x0) / dx + y_top; + + if (x0 < x1 && x3 > x2) { // three segments descending down-right + stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1); + stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x2,y2); + stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3); + } else if (x3 < x1 && x0 > x2) { // three segments descending down-left + stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2); + stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x1,y1); + stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3); + } else if (x0 < x1 && x3 > x1) { // two segments across x, down-right + stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1); + stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3); + } else if (x3 < x1 && x0 > x1) { // two segments across x, down-left + stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1); + stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3); + } else if (x0 < x2 && x3 > x2) { // two segments across x+1, down-right + stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2); + stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3); + } else if (x3 < x2 && x0 > x2) { // two segments across x+1, down-left + stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2); + stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3); + } else { // one segment + stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x3,y3); + } + } + } + } + e = e->next; + } +} + +// directly AA rasterize edges w/o supersampling +static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata) +{ + stbtt__hheap hh = { 0, 0, 0 }; + stbtt__active_edge *active = NULL; + int y,j=0, i; + float scanline_data[129], *scanline, *scanline2; + + STBTT__NOTUSED(vsubsample); + + if (result->w > 64) + scanline = (float *) STBTT_malloc((result->w*2+1) * sizeof(float), userdata); + else + scanline = scanline_data; + + scanline2 = scanline + result->w; + + y = off_y; + e[n].y0 = (float) (off_y + result->h) + 1; + + while (j < result->h) { + // find center of pixel for this scanline + float scan_y_top = y + 0.0f; + float scan_y_bottom = y + 1.0f; + stbtt__active_edge **step = &active; + + STBTT_memset(scanline , 0, result->w*sizeof(scanline[0])); + STBTT_memset(scanline2, 0, (result->w+1)*sizeof(scanline[0])); + + // update all active edges; + // remove all active edges that terminate before the top of this scanline + while (*step) { + stbtt__active_edge * z = *step; + if (z->ey <= scan_y_top) { + *step = z->next; // delete from list + STBTT_assert(z->direction); + z->direction = 0; + stbtt__hheap_free(&hh, z); + } else { + step = &((*step)->next); // advance through list + } + } + + // insert all edges that start before the bottom of this scanline + while (e->y0 <= scan_y_bottom) { + if (e->y0 != e->y1) { + stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata); + if (z != NULL) { + if (j == 0 && off_y != 0) { + if (z->ey < scan_y_top) { + // this can happen due to subpixel positioning and some kind of fp rounding error i think + z->ey = scan_y_top; + } + } + STBTT_assert(z->ey >= scan_y_top); // if we get really unlucky a tiny bit of an edge can be out of bounds + // insert at front + z->next = active; + active = z; + } + } + ++e; + } + + // now process all active edges + if (active) + stbtt__fill_active_edges_new(scanline, scanline2+1, result->w, active, scan_y_top); + + { + float sum = 0; + for (i=0; i < result->w; ++i) { + float k; + int m; + sum += scanline2[i]; + k = scanline[i] + sum; + k = (float) STBTT_fabs(k)*255 + 0.5f; + m = (int) k; + if (m > 255) m = 255; + result->pixels[j*result->stride + i] = (unsigned char) m; + } + } + // advance all the edges + step = &active; + while (*step) { + stbtt__active_edge *z = *step; + z->fx += z->fdx; // advance to position for current scanline + step = &((*step)->next); // advance through list + } + + ++y; + ++j; + } + + stbtt__hheap_cleanup(&hh, userdata); + + if (scanline != scanline_data) + STBTT_free(scanline, userdata); +} +#else +#error "Unrecognized value of STBTT_RASTERIZER_VERSION" +#endif + +#define STBTT__COMPARE(a,b) ((a)->y0 < (b)->y0) + +static void stbtt__sort_edges_ins_sort(stbtt__edge *p, int n) +{ + int i,j; + for (i=1; i < n; ++i) { + stbtt__edge t = p[i], *a = &t; + j = i; + while (j > 0) { + stbtt__edge *b = &p[j-1]; + int c = STBTT__COMPARE(a,b); + if (!c) break; + p[j] = p[j-1]; + --j; + } + if (i != j) + p[j] = t; + } +} + +static void stbtt__sort_edges_quicksort(stbtt__edge *p, int n) +{ + /* threshold for transitioning to insertion sort */ + while (n > 12) { + stbtt__edge t; + int c01,c12,c,m,i,j; + + /* compute median of three */ + m = n >> 1; + c01 = STBTT__COMPARE(&p[0],&p[m]); + c12 = STBTT__COMPARE(&p[m],&p[n-1]); + /* if 0 >= mid >= end, or 0 < mid < end, then use mid */ + if (c01 != c12) { + /* otherwise, we'll need to swap something else to middle */ + int z; + c = STBTT__COMPARE(&p[0],&p[n-1]); + /* 0>mid && midn => n; 0 0 */ + /* 0n: 0>n => 0; 0 n */ + z = (c == c12) ? 0 : n-1; + t = p[z]; + p[z] = p[m]; + p[m] = t; + } + /* now p[m] is the median-of-three */ + /* swap it to the beginning so it won't move around */ + t = p[0]; + p[0] = p[m]; + p[m] = t; + + /* partition loop */ + i=1; + j=n-1; + for(;;) { + /* handling of equality is crucial here */ + /* for sentinels & efficiency with duplicates */ + for (;;++i) { + if (!STBTT__COMPARE(&p[i], &p[0])) break; + } + for (;;--j) { + if (!STBTT__COMPARE(&p[0], &p[j])) break; + } + /* make sure we haven't crossed */ + if (i >= j) break; + t = p[i]; + p[i] = p[j]; + p[j] = t; + + ++i; + --j; + } + /* recurse on smaller side, iterate on larger */ + if (j < (n-i)) { + stbtt__sort_edges_quicksort(p,j); + p = p+i; + n = n-i; + } else { + stbtt__sort_edges_quicksort(p+i, n-i); + n = j; + } + } +} + +static void stbtt__sort_edges(stbtt__edge *p, int n) +{ + stbtt__sort_edges_quicksort(p, n); + stbtt__sort_edges_ins_sort(p, n); +} + +typedef struct +{ + float x,y; +} stbtt__point; + +static void stbtt__rasterize(stbtt__bitmap *result, stbtt__point *pts, int *wcount, int windings, float scale_x, float scale_y, float shift_x, float shift_y, int off_x, int off_y, int invert, void *userdata) +{ + float y_scale_inv = invert ? -scale_y : scale_y; + stbtt__edge *e; + int n,i,j,k,m; +#if STBTT_RASTERIZER_VERSION == 1 + int vsubsample = result->h < 8 ? 15 : 5; +#elif STBTT_RASTERIZER_VERSION == 2 + int vsubsample = 1; +#else + #error "Unrecognized value of STBTT_RASTERIZER_VERSION" +#endif + // vsubsample should divide 255 evenly; otherwise we won't reach full opacity + + // now we have to blow out the windings into explicit edge lists + n = 0; + for (i=0; i < windings; ++i) + n += wcount[i]; + + e = (stbtt__edge *) STBTT_malloc(sizeof(*e) * (n+1), userdata); // add an extra one as a sentinel + if (e == 0) return; + n = 0; + + m=0; + for (i=0; i < windings; ++i) { + stbtt__point *p = pts + m; + m += wcount[i]; + j = wcount[i]-1; + for (k=0; k < wcount[i]; j=k++) { + int a=k,b=j; + // skip the edge if horizontal + if (p[j].y == p[k].y) + continue; + // add edge from j to k to the list + e[n].invert = 0; + if (invert ? p[j].y > p[k].y : p[j].y < p[k].y) { + e[n].invert = 1; + a=j,b=k; + } + e[n].x0 = p[a].x * scale_x + shift_x; + e[n].y0 = (p[a].y * y_scale_inv + shift_y) * vsubsample; + e[n].x1 = p[b].x * scale_x + shift_x; + e[n].y1 = (p[b].y * y_scale_inv + shift_y) * vsubsample; + ++n; + } + } + + // now sort the edges by their highest point (should snap to integer, and then by x) + //STBTT_sort(e, n, sizeof(e[0]), stbtt__edge_compare); + stbtt__sort_edges(e, n); + + // now, traverse the scanlines and find the intersections on each scanline, use xor winding rule + stbtt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, userdata); + + STBTT_free(e, userdata); +} + +static void stbtt__add_point(stbtt__point *points, int n, float x, float y) +{ + if (!points) return; // during first pass, it's unallocated + points[n].x = x; + points[n].y = y; +} + +// tessellate until threshold p is happy... @TODO warped to compensate for non-linear stretching +static int stbtt__tesselate_curve(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float objspace_flatness_squared, int n) +{ + // midpoint + float mx = (x0 + 2*x1 + x2)/4; + float my = (y0 + 2*y1 + y2)/4; + // versus directly drawn line + float dx = (x0+x2)/2 - mx; + float dy = (y0+y2)/2 - my; + if (n > 16) // 65536 segments on one curve better be enough! + return 1; + if (dx*dx+dy*dy > objspace_flatness_squared) { // half-pixel error allowed... need to be smaller if AA + stbtt__tesselate_curve(points, num_points, x0,y0, (x0+x1)/2.0f,(y0+y1)/2.0f, mx,my, objspace_flatness_squared,n+1); + stbtt__tesselate_curve(points, num_points, mx,my, (x1+x2)/2.0f,(y1+y2)/2.0f, x2,y2, objspace_flatness_squared,n+1); + } else { + stbtt__add_point(points, *num_points,x2,y2); + *num_points = *num_points+1; + } + return 1; +} + +static void stbtt__tesselate_cubic(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, float objspace_flatness_squared, int n) +{ + // @TODO this "flatness" calculation is just made-up nonsense that seems to work well enough + float dx0 = x1-x0; + float dy0 = y1-y0; + float dx1 = x2-x1; + float dy1 = y2-y1; + float dx2 = x3-x2; + float dy2 = y3-y2; + float dx = x3-x0; + float dy = y3-y0; + float longlen = (float) (STBTT_sqrt(dx0*dx0+dy0*dy0)+STBTT_sqrt(dx1*dx1+dy1*dy1)+STBTT_sqrt(dx2*dx2+dy2*dy2)); + float shortlen = (float) STBTT_sqrt(dx*dx+dy*dy); + float flatness_squared = longlen*longlen-shortlen*shortlen; + + if (n > 16) // 65536 segments on one curve better be enough! + return; + + if (flatness_squared > objspace_flatness_squared) { + float x01 = (x0+x1)/2; + float y01 = (y0+y1)/2; + float x12 = (x1+x2)/2; + float y12 = (y1+y2)/2; + float x23 = (x2+x3)/2; + float y23 = (y2+y3)/2; + + float xa = (x01+x12)/2; + float ya = (y01+y12)/2; + float xb = (x12+x23)/2; + float yb = (y12+y23)/2; + + float mx = (xa+xb)/2; + float my = (ya+yb)/2; + + stbtt__tesselate_cubic(points, num_points, x0,y0, x01,y01, xa,ya, mx,my, objspace_flatness_squared,n+1); + stbtt__tesselate_cubic(points, num_points, mx,my, xb,yb, x23,y23, x3,y3, objspace_flatness_squared,n+1); + } else { + stbtt__add_point(points, *num_points,x3,y3); + *num_points = *num_points+1; + } +} + +// returns number of contours +static stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, float objspace_flatness, int **contour_lengths, int *num_contours, void *userdata) +{ + stbtt__point *points=0; + int num_points=0; + + float objspace_flatness_squared = objspace_flatness * objspace_flatness; + int i,n=0,start=0, pass; + + // count how many "moves" there are to get the contour count + for (i=0; i < num_verts; ++i) + if (vertices[i].type == STBTT_vmove) + ++n; + + *num_contours = n; + if (n == 0) return 0; + + *contour_lengths = (int *) STBTT_malloc(sizeof(**contour_lengths) * n, userdata); + + if (*contour_lengths == 0) { + *num_contours = 0; + return 0; + } + + // make two passes through the points so we don't need to realloc + for (pass=0; pass < 2; ++pass) { + float x=0,y=0; + if (pass == 1) { + points = (stbtt__point *) STBTT_malloc(num_points * sizeof(points[0]), userdata); + if (points == NULL) goto error; + } + num_points = 0; + n= -1; + for (i=0; i < num_verts; ++i) { + switch (vertices[i].type) { + case STBTT_vmove: + // start the next contour + if (n >= 0) + (*contour_lengths)[n] = num_points - start; + ++n; + start = num_points; + + x = vertices[i].x, y = vertices[i].y; + stbtt__add_point(points, num_points++, x,y); + break; + case STBTT_vline: + x = vertices[i].x, y = vertices[i].y; + stbtt__add_point(points, num_points++, x, y); + break; + case STBTT_vcurve: + stbtt__tesselate_curve(points, &num_points, x,y, + vertices[i].cx, vertices[i].cy, + vertices[i].x, vertices[i].y, + objspace_flatness_squared, 0); + x = vertices[i].x, y = vertices[i].y; + break; + case STBTT_vcubic: + stbtt__tesselate_cubic(points, &num_points, x,y, + vertices[i].cx, vertices[i].cy, + vertices[i].cx1, vertices[i].cy1, + vertices[i].x, vertices[i].y, + objspace_flatness_squared, 0); + x = vertices[i].x, y = vertices[i].y; + break; + } + } + (*contour_lengths)[n] = num_points - start; + } + + return points; +error: + STBTT_free(points, userdata); + STBTT_free(*contour_lengths, userdata); + *contour_lengths = 0; + *num_contours = 0; + return NULL; +} + +STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off, int invert, void *userdata) +{ + float scale = scale_x > scale_y ? scale_y : scale_x; + int winding_count = 0; + int *winding_lengths = NULL; + stbtt__point *windings = stbtt_FlattenCurves(vertices, num_verts, flatness_in_pixels / scale, &winding_lengths, &winding_count, userdata); + if (windings) { + stbtt__rasterize(result, windings, winding_lengths, winding_count, scale_x, scale_y, shift_x, shift_y, x_off, y_off, invert, userdata); + STBTT_free(winding_lengths, userdata); + STBTT_free(windings, userdata); + } +} + +STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata) +{ + STBTT_free(bitmap, userdata); +} + +STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff) +{ + int ix0,iy0,ix1,iy1; + stbtt__bitmap gbm; + stbtt_vertex *vertices; + int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices); + + if (scale_x == 0) scale_x = scale_y; + if (scale_y == 0) { + if (scale_x == 0) { + STBTT_free(vertices, info->userdata); + return NULL; + } + scale_y = scale_x; + } + + stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,&ix1,&iy1); + + // now we get the size + gbm.w = (ix1 - ix0); + gbm.h = (iy1 - iy0); + gbm.pixels = NULL; // in case we error + + if (width ) *width = gbm.w; + if (height) *height = gbm.h; + if (xoff ) *xoff = ix0; + if (yoff ) *yoff = iy0; + + if (gbm.w && gbm.h) { + gbm.pixels = (unsigned char *) STBTT_malloc(gbm.w * gbm.h, info->userdata); + if (gbm.pixels) { + gbm.stride = gbm.w; + + stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0, iy0, 1, info->userdata); + } + } + STBTT_free(vertices, info->userdata); + return gbm.pixels; +} + +STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff) +{ + return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y, 0.0f, 0.0f, glyph, width, height, xoff, yoff); +} + +STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph) +{ + int ix0,iy0; + stbtt_vertex *vertices; + int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices); + stbtt__bitmap gbm; + + stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,0,0); + gbm.pixels = output; + gbm.w = out_w; + gbm.h = out_h; + gbm.stride = out_stride; + + if (gbm.w && gbm.h) + stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0,iy0, 1, info->userdata); + + STBTT_free(vertices, info->userdata); +} + +STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph) +{ + stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f,0.0f, glyph); +} + +STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff) +{ + return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y,shift_x,shift_y, stbtt_FindGlyphIndex(info,codepoint), width,height,xoff,yoff); +} + +STBTT_DEF void stbtt_MakeCodepointBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x, int oversample_y, float *sub_x, float *sub_y, int codepoint) +{ + stbtt_MakeGlyphBitmapSubpixelPrefilter(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, oversample_x, oversample_y, sub_x, sub_y, stbtt_FindGlyphIndex(info,codepoint)); +} + +STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint) +{ + stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, stbtt_FindGlyphIndex(info,codepoint)); +} + +STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff) +{ + return stbtt_GetCodepointBitmapSubpixel(info, scale_x, scale_y, 0.0f,0.0f, codepoint, width,height,xoff,yoff); +} + +STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint) +{ + stbtt_MakeCodepointBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f,0.0f, codepoint); +} + +////////////////////////////////////////////////////////////////////////////// +// +// bitmap baking +// +// This is SUPER-CRAPPY packing to keep source code small + +static int stbtt_BakeFontBitmap_internal(unsigned char *data, int offset, // font location (use offset=0 for plain .ttf) + float pixel_height, // height of font in pixels + unsigned char *pixels, int pw, int ph, // bitmap to be filled in + int first_char, int num_chars, // characters to bake + stbtt_bakedchar *chardata) +{ + float scale; + int x,y,bottom_y, i; + stbtt_fontinfo f; + f.userdata = NULL; + if (!stbtt_InitFont(&f, data, offset)) + return -1; + STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels + x=y=1; + bottom_y = 1; + + scale = stbtt_ScaleForPixelHeight(&f, pixel_height); + + for (i=0; i < num_chars; ++i) { + int advance, lsb, x0,y0,x1,y1,gw,gh; + int g = stbtt_FindGlyphIndex(&f, first_char + i); + stbtt_GetGlyphHMetrics(&f, g, &advance, &lsb); + stbtt_GetGlyphBitmapBox(&f, g, scale,scale, &x0,&y0,&x1,&y1); + gw = x1-x0; + gh = y1-y0; + if (x + gw + 1 >= pw) + y = bottom_y, x = 1; // advance to next row + if (y + gh + 1 >= ph) // check if it fits vertically AFTER potentially moving to next row + return -i; + STBTT_assert(x+gw < pw); + STBTT_assert(y+gh < ph); + stbtt_MakeGlyphBitmap(&f, pixels+x+y*pw, gw,gh,pw, scale,scale, g); + chardata[i].x0 = (stbtt_int16) x; + chardata[i].y0 = (stbtt_int16) y; + chardata[i].x1 = (stbtt_int16) (x + gw); + chardata[i].y1 = (stbtt_int16) (y + gh); + chardata[i].xadvance = scale * advance; + chardata[i].xoff = (float) x0; + chardata[i].yoff = (float) y0; + x = x + gw + 1; + if (y+gh+1 > bottom_y) + bottom_y = y+gh+1; + } + return bottom_y; +} + +STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int opengl_fillrule) +{ + float d3d_bias = opengl_fillrule ? 0 : -0.5f; + float ipw = 1.0f / pw, iph = 1.0f / ph; + const stbtt_bakedchar *b = chardata + char_index; + int round_x = STBTT_ifloor((*xpos + b->xoff) + 0.5f); + int round_y = STBTT_ifloor((*ypos + b->yoff) + 0.5f); + + q->x0 = round_x + d3d_bias; + q->y0 = round_y + d3d_bias; + q->x1 = round_x + b->x1 - b->x0 + d3d_bias; + q->y1 = round_y + b->y1 - b->y0 + d3d_bias; + + q->s0 = b->x0 * ipw; + q->t0 = b->y0 * iph; + q->s1 = b->x1 * ipw; + q->t1 = b->y1 * iph; + + *xpos += b->xadvance; +} + +////////////////////////////////////////////////////////////////////////////// +// +// rectangle packing replacement routines if you don't have stb_rect_pack.h +// + +#ifndef STB_RECT_PACK_VERSION + +typedef int stbrp_coord; + +//////////////////////////////////////////////////////////////////////////////////// +// // +// // +// COMPILER WARNING ?!?!? // +// // +// // +// if you get a compile warning due to these symbols being defined more than // +// once, move #include "stb_rect_pack.h" before #include "stb_truetype.h" // +// // +//////////////////////////////////////////////////////////////////////////////////// + +typedef struct +{ + int width,height; + int x,y,bottom_y; +} stbrp_context; + +typedef struct +{ + unsigned char x; +} stbrp_node; + +struct stbrp_rect +{ + stbrp_coord x,y; + int id,w,h,was_packed; +}; + +static void stbrp_init_target(stbrp_context *con, int pw, int ph, stbrp_node *nodes, int num_nodes) +{ + con->width = pw; + con->height = ph; + con->x = 0; + con->y = 0; + con->bottom_y = 0; + STBTT__NOTUSED(nodes); + STBTT__NOTUSED(num_nodes); +} + +static void stbrp_pack_rects(stbrp_context *con, stbrp_rect *rects, int num_rects) +{ + int i; + for (i=0; i < num_rects; ++i) { + if (con->x + rects[i].w > con->width) { + con->x = 0; + con->y = con->bottom_y; + } + if (con->y + rects[i].h > con->height) + break; + rects[i].x = con->x; + rects[i].y = con->y; + rects[i].was_packed = 1; + con->x += rects[i].w; + if (con->y + rects[i].h > con->bottom_y) + con->bottom_y = con->y + rects[i].h; + } + for ( ; i < num_rects; ++i) + rects[i].was_packed = 0; +} +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// bitmap baking +// +// This is SUPER-AWESOME (tm Ryan Gordon) packing using stb_rect_pack.h. If +// stb_rect_pack.h isn't available, it uses the BakeFontBitmap strategy. + +STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int pw, int ph, int stride_in_bytes, int padding, void *alloc_context) +{ + stbrp_context *context = (stbrp_context *) STBTT_malloc(sizeof(*context) ,alloc_context); + int num_nodes = pw - padding; + stbrp_node *nodes = (stbrp_node *) STBTT_malloc(sizeof(*nodes ) * num_nodes,alloc_context); + + if (context == NULL || nodes == NULL) { + if (context != NULL) STBTT_free(context, alloc_context); + if (nodes != NULL) STBTT_free(nodes , alloc_context); + return 0; + } + + spc->user_allocator_context = alloc_context; + spc->width = pw; + spc->height = ph; + spc->pixels = pixels; + spc->pack_info = context; + spc->nodes = nodes; + spc->padding = padding; + spc->stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw; + spc->h_oversample = 1; + spc->v_oversample = 1; + spc->skip_missing = 0; + + stbrp_init_target(context, pw-padding, ph-padding, nodes, num_nodes); + + if (pixels) + STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels + + return 1; +} + +STBTT_DEF void stbtt_PackEnd (stbtt_pack_context *spc) +{ + STBTT_free(spc->nodes , spc->user_allocator_context); + STBTT_free(spc->pack_info, spc->user_allocator_context); +} + +STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample) +{ + STBTT_assert(h_oversample <= STBTT_MAX_OVERSAMPLE); + STBTT_assert(v_oversample <= STBTT_MAX_OVERSAMPLE); + if (h_oversample <= STBTT_MAX_OVERSAMPLE) + spc->h_oversample = h_oversample; + if (v_oversample <= STBTT_MAX_OVERSAMPLE) + spc->v_oversample = v_oversample; +} + +STBTT_DEF void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *spc, int skip) +{ + spc->skip_missing = skip; +} + +#define STBTT__OVER_MASK (STBTT_MAX_OVERSAMPLE-1) + +static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width) +{ + unsigned char buffer[STBTT_MAX_OVERSAMPLE]; + int safe_w = w - kernel_width; + int j; + STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze + for (j=0; j < h; ++j) { + int i; + unsigned int total; + STBTT_memset(buffer, 0, kernel_width); + + total = 0; + + // make kernel_width a constant in common cases so compiler can optimize out the divide + switch (kernel_width) { + case 2: + for (i=0; i <= safe_w; ++i) { + total += pixels[i] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i]; + pixels[i] = (unsigned char) (total / 2); + } + break; + case 3: + for (i=0; i <= safe_w; ++i) { + total += pixels[i] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i]; + pixels[i] = (unsigned char) (total / 3); + } + break; + case 4: + for (i=0; i <= safe_w; ++i) { + total += pixels[i] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i]; + pixels[i] = (unsigned char) (total / 4); + } + break; + case 5: + for (i=0; i <= safe_w; ++i) { + total += pixels[i] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i]; + pixels[i] = (unsigned char) (total / 5); + } + break; + default: + for (i=0; i <= safe_w; ++i) { + total += pixels[i] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i]; + pixels[i] = (unsigned char) (total / kernel_width); + } + break; + } + + for (; i < w; ++i) { + STBTT_assert(pixels[i] == 0); + total -= buffer[i & STBTT__OVER_MASK]; + pixels[i] = (unsigned char) (total / kernel_width); + } + + pixels += stride_in_bytes; + } +} + +static void stbtt__v_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width) +{ + unsigned char buffer[STBTT_MAX_OVERSAMPLE]; + int safe_h = h - kernel_width; + int j; + STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze + for (j=0; j < w; ++j) { + int i; + unsigned int total; + STBTT_memset(buffer, 0, kernel_width); + + total = 0; + + // make kernel_width a constant in common cases so compiler can optimize out the divide + switch (kernel_width) { + case 2: + for (i=0; i <= safe_h; ++i) { + total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; + pixels[i*stride_in_bytes] = (unsigned char) (total / 2); + } + break; + case 3: + for (i=0; i <= safe_h; ++i) { + total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; + pixels[i*stride_in_bytes] = (unsigned char) (total / 3); + } + break; + case 4: + for (i=0; i <= safe_h; ++i) { + total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; + pixels[i*stride_in_bytes] = (unsigned char) (total / 4); + } + break; + case 5: + for (i=0; i <= safe_h; ++i) { + total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; + pixels[i*stride_in_bytes] = (unsigned char) (total / 5); + } + break; + default: + for (i=0; i <= safe_h; ++i) { + total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; + buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; + pixels[i*stride_in_bytes] = (unsigned char) (total / kernel_width); + } + break; + } + + for (; i < h; ++i) { + STBTT_assert(pixels[i*stride_in_bytes] == 0); + total -= buffer[i & STBTT__OVER_MASK]; + pixels[i*stride_in_bytes] = (unsigned char) (total / kernel_width); + } + + pixels += 1; + } +} + +static float stbtt__oversample_shift(int oversample) +{ + if (!oversample) + return 0.0f; + + // The prefilter is a box filter of width "oversample", + // which shifts phase by (oversample - 1)/2 pixels in + // oversampled space. We want to shift in the opposite + // direction to counter this. + return (float)-(oversample - 1) / (2.0f * (float)oversample); +} + +// rects array must be big enough to accommodate all characters in the given ranges +STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) +{ + int i,j,k; + int missing_glyph_added = 0; + + k=0; + for (i=0; i < num_ranges; ++i) { + float fh = ranges[i].font_size; + float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh); + ranges[i].h_oversample = (unsigned char) spc->h_oversample; + ranges[i].v_oversample = (unsigned char) spc->v_oversample; + for (j=0; j < ranges[i].num_chars; ++j) { + int x0,y0,x1,y1; + int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j]; + int glyph = stbtt_FindGlyphIndex(info, codepoint); + if (glyph == 0 && (spc->skip_missing || missing_glyph_added)) { + rects[k].w = rects[k].h = 0; + } else { + stbtt_GetGlyphBitmapBoxSubpixel(info,glyph, + scale * spc->h_oversample, + scale * spc->v_oversample, + 0,0, + &x0,&y0,&x1,&y1); + rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1); + rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1); + if (glyph == 0) + missing_glyph_added = 1; + } + ++k; + } + } + + return k; +} + +STBTT_DEF void stbtt_MakeGlyphBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int prefilter_x, int prefilter_y, float *sub_x, float *sub_y, int glyph) +{ + stbtt_MakeGlyphBitmapSubpixel(info, + output, + out_w - (prefilter_x - 1), + out_h - (prefilter_y - 1), + out_stride, + scale_x, + scale_y, + shift_x, + shift_y, + glyph); + + if (prefilter_x > 1) + stbtt__h_prefilter(output, out_w, out_h, out_stride, prefilter_x); + + if (prefilter_y > 1) + stbtt__v_prefilter(output, out_w, out_h, out_stride, prefilter_y); + + *sub_x = stbtt__oversample_shift(prefilter_x); + *sub_y = stbtt__oversample_shift(prefilter_y); +} + +// rects array must be big enough to accommodate all characters in the given ranges +STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) +{ + int i,j,k, missing_glyph = -1, return_value = 1; + + // save current values + int old_h_over = spc->h_oversample; + int old_v_over = spc->v_oversample; + + k = 0; + for (i=0; i < num_ranges; ++i) { + float fh = ranges[i].font_size; + float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh); + float recip_h,recip_v,sub_x,sub_y; + spc->h_oversample = ranges[i].h_oversample; + spc->v_oversample = ranges[i].v_oversample; + recip_h = 1.0f / spc->h_oversample; + recip_v = 1.0f / spc->v_oversample; + sub_x = stbtt__oversample_shift(spc->h_oversample); + sub_y = stbtt__oversample_shift(spc->v_oversample); + for (j=0; j < ranges[i].num_chars; ++j) { + stbrp_rect *r = &rects[k]; + if (r->was_packed && r->w != 0 && r->h != 0) { + stbtt_packedchar *bc = &ranges[i].chardata_for_range[j]; + int advance, lsb, x0,y0,x1,y1; + int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j]; + int glyph = stbtt_FindGlyphIndex(info, codepoint); + stbrp_coord pad = (stbrp_coord) spc->padding; + + // pad on left and top + r->x += pad; + r->y += pad; + r->w -= pad; + r->h -= pad; + stbtt_GetGlyphHMetrics(info, glyph, &advance, &lsb); + stbtt_GetGlyphBitmapBox(info, glyph, + scale * spc->h_oversample, + scale * spc->v_oversample, + &x0,&y0,&x1,&y1); + stbtt_MakeGlyphBitmapSubpixel(info, + spc->pixels + r->x + r->y*spc->stride_in_bytes, + r->w - spc->h_oversample+1, + r->h - spc->v_oversample+1, + spc->stride_in_bytes, + scale * spc->h_oversample, + scale * spc->v_oversample, + 0,0, + glyph); + + if (spc->h_oversample > 1) + stbtt__h_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes, + r->w, r->h, spc->stride_in_bytes, + spc->h_oversample); + + if (spc->v_oversample > 1) + stbtt__v_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes, + r->w, r->h, spc->stride_in_bytes, + spc->v_oversample); + + bc->x0 = (stbtt_int16) r->x; + bc->y0 = (stbtt_int16) r->y; + bc->x1 = (stbtt_int16) (r->x + r->w); + bc->y1 = (stbtt_int16) (r->y + r->h); + bc->xadvance = scale * advance; + bc->xoff = (float) x0 * recip_h + sub_x; + bc->yoff = (float) y0 * recip_v + sub_y; + bc->xoff2 = (x0 + r->w) * recip_h + sub_x; + bc->yoff2 = (y0 + r->h) * recip_v + sub_y; + + if (glyph == 0) + missing_glyph = j; + } else if (spc->skip_missing) { + return_value = 0; + } else if (r->was_packed && r->w == 0 && r->h == 0 && missing_glyph >= 0) { + ranges[i].chardata_for_range[j] = ranges[i].chardata_for_range[missing_glyph]; + } else { + return_value = 0; // if any fail, report failure + } + + ++k; + } + } + + // restore original values + spc->h_oversample = old_h_over; + spc->v_oversample = old_v_over; + + return return_value; +} + +STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect *rects, int num_rects) +{ + stbrp_pack_rects((stbrp_context *) spc->pack_info, rects, num_rects); +} + +STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges) +{ + stbtt_fontinfo info; + int i,j,n, return_value = 1; + //stbrp_context *context = (stbrp_context *) spc->pack_info; + stbrp_rect *rects; + + // flag all characters as NOT packed + for (i=0; i < num_ranges; ++i) + for (j=0; j < ranges[i].num_chars; ++j) + ranges[i].chardata_for_range[j].x0 = + ranges[i].chardata_for_range[j].y0 = + ranges[i].chardata_for_range[j].x1 = + ranges[i].chardata_for_range[j].y1 = 0; + + n = 0; + for (i=0; i < num_ranges; ++i) + n += ranges[i].num_chars; + + rects = (stbrp_rect *) STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context); + if (rects == NULL) + return 0; + + info.userdata = spc->user_allocator_context; + stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata,font_index)); + + n = stbtt_PackFontRangesGatherRects(spc, &info, ranges, num_ranges, rects); + + stbtt_PackFontRangesPackRects(spc, rects, n); + + return_value = stbtt_PackFontRangesRenderIntoRects(spc, &info, ranges, num_ranges, rects); + + STBTT_free(rects, spc->user_allocator_context); + return return_value; +} + +STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, float font_size, + int first_unicode_codepoint_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range) +{ + stbtt_pack_range range; + range.first_unicode_codepoint_in_range = first_unicode_codepoint_in_range; + range.array_of_unicode_codepoints = NULL; + range.num_chars = num_chars_in_range; + range.chardata_for_range = chardata_for_range; + range.font_size = font_size; + return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1); +} + +STBTT_DEF void stbtt_GetScaledFontVMetrics(const unsigned char *fontdata, int index, float size, float *ascent, float *descent, float *lineGap) +{ + int i_ascent, i_descent, i_lineGap; + float scale; + stbtt_fontinfo info; + stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata, index)); + scale = size > 0 ? stbtt_ScaleForPixelHeight(&info, size) : stbtt_ScaleForMappingEmToPixels(&info, -size); + stbtt_GetFontVMetrics(&info, &i_ascent, &i_descent, &i_lineGap); + *ascent = (float) i_ascent * scale; + *descent = (float) i_descent * scale; + *lineGap = (float) i_lineGap * scale; +} + +STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int align_to_integer) +{ + float ipw = 1.0f / pw, iph = 1.0f / ph; + const stbtt_packedchar *b = chardata + char_index; + + if (align_to_integer) { + float x = (float) STBTT_ifloor((*xpos + b->xoff) + 0.5f); + float y = (float) STBTT_ifloor((*ypos + b->yoff) + 0.5f); + q->x0 = x; + q->y0 = y; + q->x1 = x + b->xoff2 - b->xoff; + q->y1 = y + b->yoff2 - b->yoff; + } else { + q->x0 = *xpos + b->xoff; + q->y0 = *ypos + b->yoff; + q->x1 = *xpos + b->xoff2; + q->y1 = *ypos + b->yoff2; + } + + q->s0 = b->x0 * ipw; + q->t0 = b->y0 * iph; + q->s1 = b->x1 * ipw; + q->t1 = b->y1 * iph; + + *xpos += b->xadvance; +} + +////////////////////////////////////////////////////////////////////////////// +// +// sdf computation +// + +#define STBTT_min(a,b) ((a) < (b) ? (a) : (b)) +#define STBTT_max(a,b) ((a) < (b) ? (b) : (a)) + +static int stbtt__ray_intersect_bezier(float orig[2], float ray[2], float q0[2], float q1[2], float q2[2], float hits[2][2]) +{ + float q0perp = q0[1]*ray[0] - q0[0]*ray[1]; + float q1perp = q1[1]*ray[0] - q1[0]*ray[1]; + float q2perp = q2[1]*ray[0] - q2[0]*ray[1]; + float roperp = orig[1]*ray[0] - orig[0]*ray[1]; + + float a = q0perp - 2*q1perp + q2perp; + float b = q1perp - q0perp; + float c = q0perp - roperp; + + float s0 = 0., s1 = 0.; + int num_s = 0; + + if (a != 0.0) { + float discr = b*b - a*c; + if (discr > 0.0) { + float rcpna = -1 / a; + float d = (float) STBTT_sqrt(discr); + s0 = (b+d) * rcpna; + s1 = (b-d) * rcpna; + if (s0 >= 0.0 && s0 <= 1.0) + num_s = 1; + if (d > 0.0 && s1 >= 0.0 && s1 <= 1.0) { + if (num_s == 0) s0 = s1; + ++num_s; + } + } + } else { + // 2*b*s + c = 0 + // s = -c / (2*b) + s0 = c / (-2 * b); + if (s0 >= 0.0 && s0 <= 1.0) + num_s = 1; + } + + if (num_s == 0) + return 0; + else { + float rcp_len2 = 1 / (ray[0]*ray[0] + ray[1]*ray[1]); + float rayn_x = ray[0] * rcp_len2, rayn_y = ray[1] * rcp_len2; + + float q0d = q0[0]*rayn_x + q0[1]*rayn_y; + float q1d = q1[0]*rayn_x + q1[1]*rayn_y; + float q2d = q2[0]*rayn_x + q2[1]*rayn_y; + float rod = orig[0]*rayn_x + orig[1]*rayn_y; + + float q10d = q1d - q0d; + float q20d = q2d - q0d; + float q0rd = q0d - rod; + + hits[0][0] = q0rd + s0*(2.0f - 2.0f*s0)*q10d + s0*s0*q20d; + hits[0][1] = a*s0+b; + + if (num_s > 1) { + hits[1][0] = q0rd + s1*(2.0f - 2.0f*s1)*q10d + s1*s1*q20d; + hits[1][1] = a*s1+b; + return 2; + } else { + return 1; + } + } +} + +static int equal(float *a, float *b) +{ + return (a[0] == b[0] && a[1] == b[1]); +} + +static int stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex *verts) +{ + int i; + float orig[2], ray[2] = { 1, 0 }; + float y_frac; + int winding = 0; + + // make sure y never passes through a vertex of the shape + y_frac = (float) STBTT_fmod(y, 1.0f); + if (y_frac < 0.01f) + y += 0.01f; + else if (y_frac > 0.99f) + y -= 0.01f; + + orig[0] = x; + orig[1] = y; + + // test a ray from (-infinity,y) to (x,y) + for (i=0; i < nverts; ++i) { + if (verts[i].type == STBTT_vline) { + int x0 = (int) verts[i-1].x, y0 = (int) verts[i-1].y; + int x1 = (int) verts[i ].x, y1 = (int) verts[i ].y; + if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) { + float x_inter = (y - y0) / (y1 - y0) * (x1-x0) + x0; + if (x_inter < x) + winding += (y0 < y1) ? 1 : -1; + } + } + if (verts[i].type == STBTT_vcurve) { + int x0 = (int) verts[i-1].x , y0 = (int) verts[i-1].y ; + int x1 = (int) verts[i ].cx, y1 = (int) verts[i ].cy; + int x2 = (int) verts[i ].x , y2 = (int) verts[i ].y ; + int ax = STBTT_min(x0,STBTT_min(x1,x2)), ay = STBTT_min(y0,STBTT_min(y1,y2)); + int by = STBTT_max(y0,STBTT_max(y1,y2)); + if (y > ay && y < by && x > ax) { + float q0[2],q1[2],q2[2]; + float hits[2][2]; + q0[0] = (float)x0; + q0[1] = (float)y0; + q1[0] = (float)x1; + q1[1] = (float)y1; + q2[0] = (float)x2; + q2[1] = (float)y2; + if (equal(q0,q1) || equal(q1,q2)) { + x0 = (int)verts[i-1].x; + y0 = (int)verts[i-1].y; + x1 = (int)verts[i ].x; + y1 = (int)verts[i ].y; + if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) { + float x_inter = (y - y0) / (y1 - y0) * (x1-x0) + x0; + if (x_inter < x) + winding += (y0 < y1) ? 1 : -1; + } + } else { + int num_hits = stbtt__ray_intersect_bezier(orig, ray, q0, q1, q2, hits); + if (num_hits >= 1) + if (hits[0][0] < 0) + winding += (hits[0][1] < 0 ? -1 : 1); + if (num_hits >= 2) + if (hits[1][0] < 0) + winding += (hits[1][1] < 0 ? -1 : 1); + } + } + } + } + return winding; +} + +static float stbtt__cuberoot( float x ) +{ + if (x<0) + return -(float) STBTT_pow(-x,1.0f/3.0f); + else + return (float) STBTT_pow( x,1.0f/3.0f); +} + +// x^3 + a*x^2 + b*x + c = 0 +static int stbtt__solve_cubic(float a, float b, float c, float* r) +{ + float s = -a / 3; + float p = b - a*a / 3; + float q = a * (2*a*a - 9*b) / 27 + c; + float p3 = p*p*p; + float d = q*q + 4*p3 / 27; + if (d >= 0) { + float z = (float) STBTT_sqrt(d); + float u = (-q + z) / 2; + float v = (-q - z) / 2; + u = stbtt__cuberoot(u); + v = stbtt__cuberoot(v); + r[0] = s + u + v; + return 1; + } else { + float u = (float) STBTT_sqrt(-p/3); + float v = (float) STBTT_acos(-STBTT_sqrt(-27/p3) * q / 2) / 3; // p3 must be negative, since d is negative + float m = (float) STBTT_cos(v); + float n = (float) STBTT_cos(v-3.141592/2)*1.732050808f; + r[0] = s + u * 2 * m; + r[1] = s - u * (m + n); + r[2] = s - u * (m - n); + + //STBTT_assert( STBTT_fabs(((r[0]+a)*r[0]+b)*r[0]+c) < 0.05f); // these asserts may not be safe at all scales, though they're in bezier t parameter units so maybe? + //STBTT_assert( STBTT_fabs(((r[1]+a)*r[1]+b)*r[1]+c) < 0.05f); + //STBTT_assert( STBTT_fabs(((r[2]+a)*r[2]+b)*r[2]+c) < 0.05f); + return 3; + } +} + +STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float scale, int glyph, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff) +{ + float scale_x = scale, scale_y = scale; + int ix0,iy0,ix1,iy1; + int w,h; + unsigned char *data; + + if (scale == 0) return NULL; + + stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale, scale, 0.0f,0.0f, &ix0,&iy0,&ix1,&iy1); + + // if empty, return NULL + if (ix0 == ix1 || iy0 == iy1) + return NULL; + + ix0 -= padding; + iy0 -= padding; + ix1 += padding; + iy1 += padding; + + w = (ix1 - ix0); + h = (iy1 - iy0); + + if (width ) *width = w; + if (height) *height = h; + if (xoff ) *xoff = ix0; + if (yoff ) *yoff = iy0; + + // invert for y-downwards bitmaps + scale_y = -scale_y; + + { + // distance from singular values (in the same units as the pixel grid) + const float eps = 1./1024, eps2 = eps*eps; + int x,y,i,j; + float *precompute; + stbtt_vertex *verts; + int num_verts = stbtt_GetGlyphShape(info, glyph, &verts); + data = (unsigned char *) STBTT_malloc(w * h, info->userdata); + precompute = (float *) STBTT_malloc(num_verts * sizeof(float), info->userdata); + + for (i=0,j=num_verts-1; i < num_verts; j=i++) { + if (verts[i].type == STBTT_vline) { + float x0 = verts[i].x*scale_x, y0 = verts[i].y*scale_y; + float x1 = verts[j].x*scale_x, y1 = verts[j].y*scale_y; + float dist = (float) STBTT_sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0)); + precompute[i] = (dist < eps) ? 0.0f : 1.0f / dist; + } else if (verts[i].type == STBTT_vcurve) { + float x2 = verts[j].x *scale_x, y2 = verts[j].y *scale_y; + float x1 = verts[i].cx*scale_x, y1 = verts[i].cy*scale_y; + float x0 = verts[i].x *scale_x, y0 = verts[i].y *scale_y; + float bx = x0 - 2*x1 + x2, by = y0 - 2*y1 + y2; + float len2 = bx*bx + by*by; + if (len2 >= eps2) + precompute[i] = 1.0f / len2; + else + precompute[i] = 0.0f; + } else + precompute[i] = 0.0f; + } + + for (y=iy0; y < iy1; ++y) { + for (x=ix0; x < ix1; ++x) { + float val; + float min_dist = 999999.0f; + float sx = (float) x + 0.5f; + float sy = (float) y + 0.5f; + float x_gspace = (sx / scale_x); + float y_gspace = (sy / scale_y); + + int winding = stbtt__compute_crossings_x(x_gspace, y_gspace, num_verts, verts); // @OPTIMIZE: this could just be a rasterization, but needs to be line vs. non-tesselated curves so a new path + + for (i=0; i < num_verts; ++i) { + float x0 = verts[i].x*scale_x, y0 = verts[i].y*scale_y; + + if (verts[i].type == STBTT_vline && precompute[i] != 0.0f) { + float x1 = verts[i-1].x*scale_x, y1 = verts[i-1].y*scale_y; + + float dist,dist2 = (x0-sx)*(x0-sx) + (y0-sy)*(y0-sy); + if (dist2 < min_dist*min_dist) + min_dist = (float) STBTT_sqrt(dist2); + + // coarse culling against bbox + //if (sx > STBTT_min(x0,x1)-min_dist && sx < STBTT_max(x0,x1)+min_dist && + // sy > STBTT_min(y0,y1)-min_dist && sy < STBTT_max(y0,y1)+min_dist) + dist = (float) STBTT_fabs((x1-x0)*(y0-sy) - (y1-y0)*(x0-sx)) * precompute[i]; + STBTT_assert(i != 0); + if (dist < min_dist) { + // check position along line + // x' = x0 + t*(x1-x0), y' = y0 + t*(y1-y0) + // minimize (x'-sx)*(x'-sx)+(y'-sy)*(y'-sy) + float dx = x1-x0, dy = y1-y0; + float px = x0-sx, py = y0-sy; + // minimize (px+t*dx)^2 + (py+t*dy)^2 = px*px + 2*px*dx*t + t^2*dx*dx + py*py + 2*py*dy*t + t^2*dy*dy + // derivative: 2*px*dx + 2*py*dy + (2*dx*dx+2*dy*dy)*t, set to 0 and solve + float t = -(px*dx + py*dy) / (dx*dx + dy*dy); + if (t >= 0.0f && t <= 1.0f) + min_dist = dist; + } + } else if (verts[i].type == STBTT_vcurve) { + float x2 = verts[i-1].x *scale_x, y2 = verts[i-1].y *scale_y; + float x1 = verts[i ].cx*scale_x, y1 = verts[i ].cy*scale_y; + float box_x0 = STBTT_min(STBTT_min(x0,x1),x2); + float box_y0 = STBTT_min(STBTT_min(y0,y1),y2); + float box_x1 = STBTT_max(STBTT_max(x0,x1),x2); + float box_y1 = STBTT_max(STBTT_max(y0,y1),y2); + // coarse culling against bbox to avoid computing cubic unnecessarily + if (sx > box_x0-min_dist && sx < box_x1+min_dist && sy > box_y0-min_dist && sy < box_y1+min_dist) { + int num=0; + float ax = x1-x0, ay = y1-y0; + float bx = x0 - 2*x1 + x2, by = y0 - 2*y1 + y2; + float mx = x0 - sx, my = y0 - sy; + float res[3] = {0.f,0.f,0.f}; + float px,py,t,it,dist2; + float a_inv = precompute[i]; + if (a_inv == 0.0) { // if a_inv is 0, it's 2nd degree so use quadratic formula + float a = 3*(ax*bx + ay*by); + float b = 2*(ax*ax + ay*ay) + (mx*bx+my*by); + float c = mx*ax+my*ay; + if (STBTT_fabs(a) < eps2) { // if a is 0, it's linear + if (STBTT_fabs(b) >= eps2) { + res[num++] = -c/b; + } + } else { + float discriminant = b*b - 4*a*c; + if (discriminant < 0) + num = 0; + else { + float root = (float) STBTT_sqrt(discriminant); + res[0] = (-b - root)/(2*a); + res[1] = (-b + root)/(2*a); + num = 2; // don't bother distinguishing 1-solution case, as code below will still work + } + } + } else { + float b = 3*(ax*bx + ay*by) * a_inv; // could precompute this as it doesn't depend on sample point + float c = (2*(ax*ax + ay*ay) + (mx*bx+my*by)) * a_inv; + float d = (mx*ax+my*ay) * a_inv; + num = stbtt__solve_cubic(b, c, d, res); + } + dist2 = (x0-sx)*(x0-sx) + (y0-sy)*(y0-sy); + if (dist2 < min_dist*min_dist) + min_dist = (float) STBTT_sqrt(dist2); + + if (num >= 1 && res[0] >= 0.0f && res[0] <= 1.0f) { + t = res[0], it = 1.0f - t; + px = it*it*x0 + 2*t*it*x1 + t*t*x2; + py = it*it*y0 + 2*t*it*y1 + t*t*y2; + dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy); + if (dist2 < min_dist * min_dist) + min_dist = (float) STBTT_sqrt(dist2); + } + if (num >= 2 && res[1] >= 0.0f && res[1] <= 1.0f) { + t = res[1], it = 1.0f - t; + px = it*it*x0 + 2*t*it*x1 + t*t*x2; + py = it*it*y0 + 2*t*it*y1 + t*t*y2; + dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy); + if (dist2 < min_dist * min_dist) + min_dist = (float) STBTT_sqrt(dist2); + } + if (num >= 3 && res[2] >= 0.0f && res[2] <= 1.0f) { + t = res[2], it = 1.0f - t; + px = it*it*x0 + 2*t*it*x1 + t*t*x2; + py = it*it*y0 + 2*t*it*y1 + t*t*y2; + dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy); + if (dist2 < min_dist * min_dist) + min_dist = (float) STBTT_sqrt(dist2); + } + } + } + } + if (winding == 0) + min_dist = -min_dist; // if outside the shape, value is negative + val = onedge_value + pixel_dist_scale * min_dist; + if (val < 0) + val = 0; + else if (val > 255) + val = 255; + data[(y-iy0)*w+(x-ix0)] = (unsigned char) val; + } + } + STBTT_free(precompute, info->userdata); + STBTT_free(verts, info->userdata); + } + return data; +} + +STBTT_DEF unsigned char * stbtt_GetCodepointSDF(const stbtt_fontinfo *info, float scale, int codepoint, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff) +{ + return stbtt_GetGlyphSDF(info, scale, stbtt_FindGlyphIndex(info, codepoint), padding, onedge_value, pixel_dist_scale, width, height, xoff, yoff); +} + +STBTT_DEF void stbtt_FreeSDF(unsigned char *bitmap, void *userdata) +{ + STBTT_free(bitmap, userdata); +} + +////////////////////////////////////////////////////////////////////////////// +// +// font name matching -- recommended not to use this +// + +// check if a utf8 string contains a prefix which is the utf16 string; if so return length of matching utf8 string +static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(stbtt_uint8 *s1, stbtt_int32 len1, stbtt_uint8 *s2, stbtt_int32 len2) +{ + stbtt_int32 i=0; + + // convert utf16 to utf8 and compare the results while converting + while (len2) { + stbtt_uint16 ch = s2[0]*256 + s2[1]; + if (ch < 0x80) { + if (i >= len1) return -1; + if (s1[i++] != ch) return -1; + } else if (ch < 0x800) { + if (i+1 >= len1) return -1; + if (s1[i++] != 0xc0 + (ch >> 6)) return -1; + if (s1[i++] != 0x80 + (ch & 0x3f)) return -1; + } else if (ch >= 0xd800 && ch < 0xdc00) { + stbtt_uint32 c; + stbtt_uint16 ch2 = s2[2]*256 + s2[3]; + if (i+3 >= len1) return -1; + c = ((ch - 0xd800) << 10) + (ch2 - 0xdc00) + 0x10000; + if (s1[i++] != 0xf0 + (c >> 18)) return -1; + if (s1[i++] != 0x80 + ((c >> 12) & 0x3f)) return -1; + if (s1[i++] != 0x80 + ((c >> 6) & 0x3f)) return -1; + if (s1[i++] != 0x80 + ((c ) & 0x3f)) return -1; + s2 += 2; // plus another 2 below + len2 -= 2; + } else if (ch >= 0xdc00 && ch < 0xe000) { + return -1; + } else { + if (i+2 >= len1) return -1; + if (s1[i++] != 0xe0 + (ch >> 12)) return -1; + if (s1[i++] != 0x80 + ((ch >> 6) & 0x3f)) return -1; + if (s1[i++] != 0x80 + ((ch ) & 0x3f)) return -1; + } + s2 += 2; + len2 -= 2; + } + return i; +} + +static int stbtt_CompareUTF8toUTF16_bigendian_internal(char *s1, int len1, char *s2, int len2) +{ + return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((stbtt_uint8*) s1, len1, (stbtt_uint8*) s2, len2); +} + +// returns results in whatever encoding you request... but note that 2-byte encodings +// will be BIG-ENDIAN... use stbtt_CompareUTF8toUTF16_bigendian() to compare +STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID) +{ + stbtt_int32 i,count,stringOffset; + stbtt_uint8 *fc = font->data; + stbtt_uint32 offset = font->fontstart; + stbtt_uint32 nm = stbtt__find_table(fc, offset, "name"); + if (!nm) return NULL; + + count = ttUSHORT(fc+nm+2); + stringOffset = nm + ttUSHORT(fc+nm+4); + for (i=0; i < count; ++i) { + stbtt_uint32 loc = nm + 6 + 12 * i; + if (platformID == ttUSHORT(fc+loc+0) && encodingID == ttUSHORT(fc+loc+2) + && languageID == ttUSHORT(fc+loc+4) && nameID == ttUSHORT(fc+loc+6)) { + *length = ttUSHORT(fc+loc+8); + return (const char *) (fc+stringOffset+ttUSHORT(fc+loc+10)); + } + } + return NULL; +} + +static int stbtt__matchpair(stbtt_uint8 *fc, stbtt_uint32 nm, stbtt_uint8 *name, stbtt_int32 nlen, stbtt_int32 target_id, stbtt_int32 next_id) +{ + stbtt_int32 i; + stbtt_int32 count = ttUSHORT(fc+nm+2); + stbtt_int32 stringOffset = nm + ttUSHORT(fc+nm+4); + + for (i=0; i < count; ++i) { + stbtt_uint32 loc = nm + 6 + 12 * i; + stbtt_int32 id = ttUSHORT(fc+loc+6); + if (id == target_id) { + // find the encoding + stbtt_int32 platform = ttUSHORT(fc+loc+0), encoding = ttUSHORT(fc+loc+2), language = ttUSHORT(fc+loc+4); + + // is this a Unicode encoding? + if (platform == 0 || (platform == 3 && encoding == 1) || (platform == 3 && encoding == 10)) { + stbtt_int32 slen = ttUSHORT(fc+loc+8); + stbtt_int32 off = ttUSHORT(fc+loc+10); + + // check if there's a prefix match + stbtt_int32 matchlen = stbtt__CompareUTF8toUTF16_bigendian_prefix(name, nlen, fc+stringOffset+off,slen); + if (matchlen >= 0) { + // check for target_id+1 immediately following, with same encoding & language + if (i+1 < count && ttUSHORT(fc+loc+12+6) == next_id && ttUSHORT(fc+loc+12) == platform && ttUSHORT(fc+loc+12+2) == encoding && ttUSHORT(fc+loc+12+4) == language) { + slen = ttUSHORT(fc+loc+12+8); + off = ttUSHORT(fc+loc+12+10); + if (slen == 0) { + if (matchlen == nlen) + return 1; + } else if (matchlen < nlen && name[matchlen] == ' ') { + ++matchlen; + if (stbtt_CompareUTF8toUTF16_bigendian_internal((char*) (name+matchlen), nlen-matchlen, (char*)(fc+stringOffset+off),slen)) + return 1; + } + } else { + // if nothing immediately following + if (matchlen == nlen) + return 1; + } + } + } + + // @TODO handle other encodings + } + } + return 0; +} + +static int stbtt__matches(stbtt_uint8 *fc, stbtt_uint32 offset, stbtt_uint8 *name, stbtt_int32 flags) +{ + stbtt_int32 nlen = (stbtt_int32) STBTT_strlen((char *) name); + stbtt_uint32 nm,hd; + if (!stbtt__isfont(fc+offset)) return 0; + + // check italics/bold/underline flags in macStyle... + if (flags) { + hd = stbtt__find_table(fc, offset, "head"); + if ((ttUSHORT(fc+hd+44) & 7) != (flags & 7)) return 0; + } + + nm = stbtt__find_table(fc, offset, "name"); + if (!nm) return 0; + + if (flags) { + // if we checked the macStyle flags, then just check the family and ignore the subfamily + if (stbtt__matchpair(fc, nm, name, nlen, 16, -1)) return 1; + if (stbtt__matchpair(fc, nm, name, nlen, 1, -1)) return 1; + if (stbtt__matchpair(fc, nm, name, nlen, 3, -1)) return 1; + } else { + if (stbtt__matchpair(fc, nm, name, nlen, 16, 17)) return 1; + if (stbtt__matchpair(fc, nm, name, nlen, 1, 2)) return 1; + if (stbtt__matchpair(fc, nm, name, nlen, 3, -1)) return 1; + } + + return 0; +} + +static int stbtt_FindMatchingFont_internal(unsigned char *font_collection, char *name_utf8, stbtt_int32 flags) +{ + stbtt_int32 i; + for (i=0;;++i) { + stbtt_int32 off = stbtt_GetFontOffsetForIndex(font_collection, i); + if (off < 0) return off; + if (stbtt__matches((stbtt_uint8 *) font_collection, off, (stbtt_uint8*) name_utf8, flags)) + return off; + } +} + +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-qual" +#endif + +STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, + float pixel_height, unsigned char *pixels, int pw, int ph, + int first_char, int num_chars, stbtt_bakedchar *chardata) +{ + return stbtt_BakeFontBitmap_internal((unsigned char *) data, offset, pixel_height, pixels, pw, ph, first_char, num_chars, chardata); +} + +STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index) +{ + return stbtt_GetFontOffsetForIndex_internal((unsigned char *) data, index); +} + +STBTT_DEF int stbtt_GetNumberOfFonts(const unsigned char *data) +{ + return stbtt_GetNumberOfFonts_internal((unsigned char *) data); +} + +STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset) +{ + return stbtt_InitFont_internal(info, (unsigned char *) data, offset); +} + +STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *fontdata, const char *name, int flags) +{ + return stbtt_FindMatchingFont_internal((unsigned char *) fontdata, (char *) name, flags); +} + +STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2) +{ + return stbtt_CompareUTF8toUTF16_bigendian_internal((char *) s1, len1, (char *) s2, len2); +} + +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic pop +#endif + +#endif // STB_TRUETYPE_IMPLEMENTATION + + +// FULL VERSION HISTORY +// +// 1.25 (2021-07-11) many fixes +// 1.24 (2020-02-05) fix warning +// 1.23 (2020-02-02) query SVG data for glyphs; query whole kerning table (but only kern not GPOS) +// 1.22 (2019-08-11) minimize missing-glyph duplication; fix kerning if both 'GPOS' and 'kern' are defined +// 1.21 (2019-02-25) fix warning +// 1.20 (2019-02-07) PackFontRange skips missing codepoints; GetScaleFontVMetrics() +// 1.19 (2018-02-11) OpenType GPOS kerning (horizontal only), STBTT_fmod +// 1.18 (2018-01-29) add missing function +// 1.17 (2017-07-23) make more arguments const; doc fix +// 1.16 (2017-07-12) SDF support +// 1.15 (2017-03-03) make more arguments const +// 1.14 (2017-01-16) num-fonts-in-TTC function +// 1.13 (2017-01-02) support OpenType fonts, certain Apple fonts +// 1.12 (2016-10-25) suppress warnings about casting away const with -Wcast-qual +// 1.11 (2016-04-02) fix unused-variable warning +// 1.10 (2016-04-02) allow user-defined fabs() replacement +// fix memory leak if fontsize=0.0 +// fix warning from duplicate typedef +// 1.09 (2016-01-16) warning fix; avoid crash on outofmem; use alloc userdata for PackFontRanges +// 1.08 (2015-09-13) document stbtt_Rasterize(); fixes for vertical & horizontal edges +// 1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints; +// allow PackFontRanges to pack and render in separate phases; +// fix stbtt_GetFontOFfsetForIndex (never worked for non-0 input?); +// fixed an assert() bug in the new rasterizer +// replace assert() with STBTT_assert() in new rasterizer +// 1.06 (2015-07-14) performance improvements (~35% faster on x86 and x64 on test machine) +// also more precise AA rasterizer, except if shapes overlap +// remove need for STBTT_sort +// 1.05 (2015-04-15) fix misplaced definitions for STBTT_STATIC +// 1.04 (2015-04-15) typo in example +// 1.03 (2015-04-12) STBTT_STATIC, fix memory leak in new packing, various fixes +// 1.02 (2014-12-10) fix various warnings & compile issues w/ stb_rect_pack, C++ +// 1.01 (2014-12-08) fix subpixel position when oversampling to exactly match +// non-oversampled; STBTT_POINT_SIZE for packed case only +// 1.00 (2014-12-06) add new PackBegin etc. API, w/ support for oversampling +// 0.99 (2014-09-18) fix multiple bugs with subpixel rendering (ryg) +// 0.9 (2014-08-07) support certain mac/iOS fonts without an MS platformID +// 0.8b (2014-07-07) fix a warning +// 0.8 (2014-05-25) fix a few more warnings +// 0.7 (2013-09-25) bugfix: subpixel glyph bug fixed in 0.5 had come back +// 0.6c (2012-07-24) improve documentation +// 0.6b (2012-07-20) fix a few more warnings +// 0.6 (2012-07-17) fix warnings; added stbtt_ScaleForMappingEmToPixels, +// stbtt_GetFontBoundingBox, stbtt_IsGlyphEmpty +// 0.5 (2011-12-09) bugfixes: +// subpixel glyph renderer computed wrong bounding box +// first vertex of shape can be off-curve (FreeSans) +// 0.4b (2011-12-03) fixed an error in the font baking example +// 0.4 (2011-12-01) kerning, subpixel rendering (tor) +// bugfixes for: +// codepoint-to-glyph conversion using table fmt=12 +// codepoint-to-glyph conversion using table fmt=4 +// stbtt_GetBakedQuad with non-square texture (Zer) +// updated Hello World! sample to use kerning and subpixel +// fixed some warnings +// 0.3 (2009-06-24) cmap fmt=12, compound shapes (MM) +// userdata, malloc-from-userdata, non-zero fill (stb) +// 0.2 (2009-03-11) Fix unsigned/signed char warnings +// 0.1 (2009-03-09) First public release +// + +/* +------------------------------------------------------------------------------ +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------------------------------ +*/ diff --git a/include/x86_64/efibind.h b/include/x86_64/efibind.h new file mode 100644 index 0000000..936ee3a --- /dev/null +++ b/include/x86_64/efibind.h @@ -0,0 +1,396 @@ +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efefind.h + +Abstract: + + EFI to compile bindings + + + + +Revision History + +--*/ +#ifndef X86_64_EFI_BIND +#define X86_64_EFI_BIND +#ifndef __GNUC__ +#pragma pack() +#endif + +#if defined(_MSC_VER) + #define HAVE_USE_MS_ABI 1 +#elif defined(GNU_EFI_USE_MS_ABI) + #if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)))||(defined(__clang__) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 2))) + #define HAVE_USE_MS_ABI 1 + #else + #error Compiler is too old for GNU_EFI_USE_MS_ABI + #endif +#endif + +// +// Basic int types of various widths +// + +#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L ) && !defined(__cplusplus) + + // No ANSI C 1999/2000 stdint.h integer width declarations + + #if defined(_MSC_EXTENSIONS) + + // Use Microsoft C compiler integer width declarations + + typedef unsigned __int64 uint64_t; + typedef __int64 int64_t; + typedef unsigned __int32 uint32_t; + typedef __int32 int32_t; + typedef unsigned short uint16_t; + typedef short int16_t; + typedef unsigned char uint8_t; + typedef char int8_t; + #elif defined(__GNUC__) + typedef int __attribute__((__mode__(__DI__))) int64_t; + typedef unsigned int __attribute__((__mode__(__DI__))) uint64_t; + typedef unsigned int uint32_t; + typedef int int32_t; + typedef unsigned short uint16_t; + typedef short int16_t; + typedef unsigned char uint8_t; + typedef signed char int8_t; + #elif defined(UNIX_LP64) + + /* Use LP64 programming model from C_FLAGS for integer width declarations */ + + typedef unsigned long uint64_t; + typedef long int64_t; + typedef unsigned int uint32_t; + typedef int int32_t; + typedef unsigned short uint16_t; + typedef short int16_t; + typedef unsigned char uint8_t; + typedef char int8_t; + #else + + /* Assume P64 programming model from C_FLAGS for integer width declarations */ + + typedef unsigned long long uint64_t __attribute__((aligned (8))); + typedef long long int64_t __attribute__((aligned (8))); + typedef unsigned int uint32_t; + typedef int int32_t; + typedef unsigned short uint16_t; + typedef short int16_t; + typedef unsigned char uint8_t; + typedef char int8_t; + #endif + typedef uint64_t uintptr_t; + typedef int64_t intptr_t; +#else + #include +#endif + +// +// Basic EFI types of various widths +// + +#include + +typedef wchar_t CHAR16; +#define WCHAR CHAR16 + +typedef uint64_t UINT64; +typedef int64_t INT64; + +#ifndef _BASETSD_H_ + typedef uint32_t UINT32; + typedef int32_t INT32; +#endif + +typedef uint16_t UINT16; +typedef int16_t INT16; + +typedef uint8_t UINT8; +typedef char CHAR8; +typedef int8_t INT8; + +#undef VOID +typedef void VOID; + + +typedef int64_t INTN; +typedef uint64_t UINTN; + +#ifdef EFI_NT_EMULATOR + #define POST_CODE(_Data) +#else + #ifdef EFI_DEBUG +#define POST_CODE(_Data) __asm mov eax,(_Data) __asm out 0x80,al + #else + #define POST_CODE(_Data) + #endif +#endif + +#define EFIERR(a) (0x8000000000000000 | a) +#define EFI_ERROR_MASK 0x8000000000000000 +#define EFIERR_OEM(a) (0xc000000000000000 | a) + + +#define BAD_POINTER 0xFBFBFBFBFBFBFBFB +#define MAX_ADDRESS 0xFFFFFFFFFFFFFFFF + +#ifdef EFI_NT_EMULATOR + #define BREAKPOINT() __asm { int 3 } +#else + #define BREAKPOINT() while (TRUE); // Make it hang on Bios[Dbg]32 +#endif + +// +// Pointers must be aligned to these address to function +// + +#define MIN_ALIGNMENT_SIZE 4 + +#define ALIGN_VARIABLE(Value ,Adjustment) \ + (UINTN)Adjustment = 0; \ + if((UINTN)Value % MIN_ALIGNMENT_SIZE) \ + (UINTN)Adjustment = MIN_ALIGNMENT_SIZE - ((UINTN)Value % MIN_ALIGNMENT_SIZE); \ + Value = (UINTN)Value + (UINTN)Adjustment + + +// +// Define macros to build data structure signatures from characters. +// + +#define EFI_SIGNATURE_16(A,B) ((A) | (B<<8)) +#define EFI_SIGNATURE_32(A,B,C,D) (EFI_SIGNATURE_16(A,B) | (EFI_SIGNATURE_16(C,D) << 16)) +#define EFI_SIGNATURE_64(A,B,C,D,E,F,G,H) (EFI_SIGNATURE_32(A,B,C,D) | ((UINT64)(EFI_SIGNATURE_32(E,F,G,H)) << 32)) +// +// To export & import functions in the EFI emulator environment +// + +#ifdef EFI_NT_EMULATOR + #define EXPORTAPI __declspec( dllexport ) +#else + #define EXPORTAPI +#endif + + +// +// EFIAPI - prototype calling convention for EFI function pointers +// BOOTSERVICE - prototype for implementation of a boot service interface +// RUNTIMESERVICE - prototype for implementation of a runtime service interface +// RUNTIMEFUNCTION - prototype for implementation of a runtime function that is not a service +// RUNTIME_CODE - pragma macro for declaring runtime code +// + +#ifndef EFIAPI // Forces EFI calling conventions reguardless of compiler options + #ifdef _MSC_EXTENSIONS + #define EFIAPI __cdecl // Force C calling convention for Microsoft C compiler + #elif defined(HAVE_USE_MS_ABI) + // Force amd64/ms calling conventions. + #define EFIAPI __attribute__((ms_abi)) + #else + #define EFIAPI // Substitute expresion to force C calling convention + #endif +#endif + +#define BOOTSERVICE +//#define RUNTIMESERVICE(proto,a) alloc_text("rtcode",a); proto a +//#define RUNTIMEFUNCTION(proto,a) alloc_text("rtcode",a); proto a +#define RUNTIMESERVICE +#define RUNTIMEFUNCTION + + +#define RUNTIME_CODE(a) alloc_text("rtcode", a) +#define BEGIN_RUNTIME_DATA() data_seg("rtdata") +#define END_RUNTIME_DATA() data_seg("") + +#define VOLATILE volatile + +#define MEMORY_FENCE() + +#ifdef EFI_NT_EMULATOR + +// +// To help ensure proper coding of integrated drivers, they are +// compiled as DLLs. In NT they require a dll init entry pointer. +// The macro puts a stub entry point into the DLL so it will load. +// + +#define EFI_DRIVER_ENTRY_POINT(InitFunction) \ + UINTN \ + __stdcall \ + _DllMainCRTStartup ( \ + UINTN Inst, \ + UINTN reason_for_call, \ + VOID *rserved \ + ) \ + { \ + return 1; \ + } \ + \ + int \ + EXPORTAPI \ + __cdecl \ + InitializeDriver ( \ + void *ImageHandle, \ + void *SystemTable \ + ) \ + { \ + return InitFunction(ImageHandle, SystemTable); \ + } + + + #define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \ + (_if)->LoadInternal(type, name, NULL) + +#else // EFI_NT_EMULATOR + +// +// When build similiar to FW, then link everything together as +// one big module. For the MSVC toolchain, we simply tell the +// linker what our driver init function is using /ENTRY. +// +#if defined(_MSC_EXTENSIONS) + #define EFI_DRIVER_ENTRY_POINT(InitFunction) \ + __pragma(comment(linker, "/ENTRY:" # InitFunction)) +#else + #define EFI_DRIVER_ENTRY_POINT(InitFunction) \ + UINTN \ + InitializeDriver ( \ + VOID *ImageHandle, \ + VOID *SystemTable \ + ) \ + { \ + return InitFunction(ImageHandle, \ + SystemTable); \ + } \ + \ + EFI_STATUS efi_main( \ + EFI_HANDLE image, \ + EFI_SYSTEM_TABLE *systab \ + ) __attribute__((weak, \ + alias ("InitializeDriver"))); +#endif + + #define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \ + (_if)->LoadInternal(type, name, entry) + +#endif // EFI_NT_EMULATOR + +// +// Some compilers don't support the forward reference construct: +// typedef struct XXXXX +// +// The following macro provide a workaround for such cases. +// +#ifdef NO_INTERFACE_DECL +#define INTERFACE_DECL(x) +#else +#if defined(__GNUC__) || defined(_MSC_EXTENSIONS) +#define INTERFACE_DECL(x) struct x +#else +#define INTERFACE_DECL(x) typedef struct x +#endif +#endif + +/* for x86_64, EFI_FUNCTION_WRAPPER must be defined */ +#if defined(HAVE_USE_MS_ABI) +#define uefi_call_wrapper(func, va_num, ...) func(__VA_ARGS__) +#else +/* + Credits for macro-magic: + https://groups.google.com/forum/?fromgroups#!topic/comp.std.c/d-6Mj5Lko_s + http://efesx.com/2010/08/31/overloading-macros/ +*/ +#define __VA_NARG__(...) \ + __VA_NARG_(_0, ## __VA_ARGS__, __RSEQ_N()) +#define __VA_NARG_(...) \ + __VA_ARG_N(__VA_ARGS__) +#define __VA_ARG_N( \ + _0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,N,...) N +#define __RSEQ_N() \ + 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 + +#define __VA_ARG_NSUFFIX__(prefix,...) \ + __VA_ARG_NSUFFIX_N(prefix, __VA_NARG__(__VA_ARGS__)) +#define __VA_ARG_NSUFFIX_N(prefix,nargs) \ + __VA_ARG_NSUFFIX_N_(prefix, nargs) +#define __VA_ARG_NSUFFIX_N_(prefix,nargs) \ + prefix ## nargs + +/* Prototypes of EFI cdecl -> stdcall trampolines */ +UINT64 efi_call0(void *func); +UINT64 efi_call1(void *func, UINT64 arg1); +UINT64 efi_call2(void *func, UINT64 arg1, UINT64 arg2); +UINT64 efi_call3(void *func, UINT64 arg1, UINT64 arg2, UINT64 arg3); +UINT64 efi_call4(void *func, UINT64 arg1, UINT64 arg2, UINT64 arg3, + UINT64 arg4); +UINT64 efi_call5(void *func, UINT64 arg1, UINT64 arg2, UINT64 arg3, + UINT64 arg4, UINT64 arg5); +UINT64 efi_call6(void *func, UINT64 arg1, UINT64 arg2, UINT64 arg3, + UINT64 arg4, UINT64 arg5, UINT64 arg6); +UINT64 efi_call7(void *func, UINT64 arg1, UINT64 arg2, UINT64 arg3, + UINT64 arg4, UINT64 arg5, UINT64 arg6, UINT64 arg7); +UINT64 efi_call8(void *func, UINT64 arg1, UINT64 arg2, UINT64 arg3, + UINT64 arg4, UINT64 arg5, UINT64 arg6, UINT64 arg7, + UINT64 arg8); +UINT64 efi_call9(void *func, UINT64 arg1, UINT64 arg2, UINT64 arg3, + UINT64 arg4, UINT64 arg5, UINT64 arg6, UINT64 arg7, + UINT64 arg8, UINT64 arg9); +UINT64 efi_call10(void *func, UINT64 arg1, UINT64 arg2, UINT64 arg3, + UINT64 arg4, UINT64 arg5, UINT64 arg6, UINT64 arg7, + UINT64 arg8, UINT64 arg9, UINT64 arg10); + +/* Front-ends to efi_callX to avoid compiler warnings */ +#define _cast64_efi_call0(f) \ + efi_call0(f) +#define _cast64_efi_call1(f,a1) \ + efi_call1(f, (UINT64)(a1)) +#define _cast64_efi_call2(f,a1,a2) \ + efi_call2(f, (UINT64)(a1), (UINT64)(a2)) +#define _cast64_efi_call3(f,a1,a2,a3) \ + efi_call3(f, (UINT64)(a1), (UINT64)(a2), (UINT64)(a3)) +#define _cast64_efi_call4(f,a1,a2,a3,a4) \ + efi_call4(f, (UINT64)(a1), (UINT64)(a2), (UINT64)(a3), (UINT64)(a4)) +#define _cast64_efi_call5(f,a1,a2,a3,a4,a5) \ + efi_call5(f, (UINT64)(a1), (UINT64)(a2), (UINT64)(a3), (UINT64)(a4), \ + (UINT64)(a5)) +#define _cast64_efi_call6(f,a1,a2,a3,a4,a5,a6) \ + efi_call6(f, (UINT64)(a1), (UINT64)(a2), (UINT64)(a3), (UINT64)(a4), \ + (UINT64)(a5), (UINT64)(a6)) +#define _cast64_efi_call7(f,a1,a2,a3,a4,a5,a6,a7) \ + efi_call7(f, (UINT64)(a1), (UINT64)(a2), (UINT64)(a3), (UINT64)(a4), \ + (UINT64)(a5), (UINT64)(a6), (UINT64)(a7)) +#define _cast64_efi_call8(f,a1,a2,a3,a4,a5,a6,a7,a8) \ + efi_call8(f, (UINT64)(a1), (UINT64)(a2), (UINT64)(a3), (UINT64)(a4), \ + (UINT64)(a5), (UINT64)(a6), (UINT64)(a7), (UINT64)(a8)) +#define _cast64_efi_call9(f,a1,a2,a3,a4,a5,a6,a7,a8,a9) \ + efi_call9(f, (UINT64)(a1), (UINT64)(a2), (UINT64)(a3), (UINT64)(a4), \ + (UINT64)(a5), (UINT64)(a6), (UINT64)(a7), (UINT64)(a8), \ + (UINT64)(a9)) +#define _cast64_efi_call10(f,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) \ + efi_call10(f, (UINT64)(a1), (UINT64)(a2), (UINT64)(a3), (UINT64)(a4), \ + (UINT64)(a5), (UINT64)(a6), (UINT64)(a7), (UINT64)(a8), \ + (UINT64)(a9), (UINT64)(a10)) + +/* main wrapper (va_num ignored) */ +#define uefi_call_wrapper(func,va_num,...) \ + __VA_ARG_NSUFFIX__(_cast64_efi_call, __VA_ARGS__) (func , ##__VA_ARGS__) + +#endif + +#if defined(HAVE_USE_MS_ABI) && !defined(_MSC_EXTENSIONS) + #define EFI_FUNCTION __attribute__((ms_abi)) +#else + #define EFI_FUNCTION +#endif + +#ifdef _MSC_EXTENSIONS +#pragma warning ( disable : 4731 ) // Suppress warnings about modification of EBP +#endif + +#endif diff --git a/include/x86_64/efilibplat.h b/include/x86_64/efilibplat.h new file mode 100644 index 0000000..fe6c831 --- /dev/null +++ b/include/x86_64/efilibplat.h @@ -0,0 +1,26 @@ +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efilibplat.h + +Abstract: + + EFI to compile bindings + + + + +Revision History + +--*/ + +VOID +InitializeLibPlatform ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + + diff --git a/include/x86_64/efisetjmp_arch.h b/include/x86_64/efisetjmp_arch.h new file mode 100644 index 0000000..9657514 --- /dev/null +++ b/include/x86_64/efisetjmp_arch.h @@ -0,0 +1,22 @@ +#ifndef GNU_EFI_X86_64_SETJMP_H +#define GNU_EFI_X86_64_SETJMP_H + +#define JMPBUF_ALIGN 8 + +typedef struct { + UINT64 Rbx; + UINT64 Rsp; + UINT64 Rbp; + + UINT64 Rdi; + UINT64 Rsi; + UINT64 R12; + UINT64 R13; + UINT64 R14; + UINT64 R15; + UINT64 Rip; + UINT64 MxCsr; + UINT8 XmmBuffer[160]; // XMM6 - XMM15 +} EFI_ALIGN(JMPBUF_ALIGN) jmp_buf[1]; + +#endif /* GNU_EFI_X86_64_SETJMP_H */ diff --git a/include/x86_64/pe.h b/include/x86_64/pe.h new file mode 100644 index 0000000..ad62c78 --- /dev/null +++ b/include/x86_64/pe.h @@ -0,0 +1,598 @@ +/* + PE32+ header file + */ +#ifndef _PE_H +#define _PE_H + +#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ +#define IMAGE_OS2_SIGNATURE 0x454E // NE +#define IMAGE_OS2_SIGNATURE_LE 0x454C // LE +#define IMAGE_NT_SIGNATURE 0x00004550 // PE00 +#define IMAGE_EDOS_SIGNATURE 0x44454550 // PEED + + +typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header + UINT16 e_magic; // Magic number + UINT16 e_cblp; // Bytes on last page of file + UINT16 e_cp; // Pages in file + UINT16 e_crlc; // Relocations + UINT16 e_cparhdr; // Size of header in paragraphs + UINT16 e_minalloc; // Minimum extra paragraphs needed + UINT16 e_maxalloc; // Maximum extra paragraphs needed + UINT16 e_ss; // Initial (relative) SS value + UINT16 e_sp; // Initial SP value + UINT16 e_csum; // Checksum + UINT16 e_ip; // Initial IP value + UINT16 e_cs; // Initial (relative) CS value + UINT16 e_lfarlc; // File address of relocation table + UINT16 e_ovno; // Overlay number + UINT16 e_res[4]; // Reserved words + UINT16 e_oemid; // OEM identifier (for e_oeminfo) + UINT16 e_oeminfo; // OEM information; e_oemid specific + UINT16 e_res2[10]; // Reserved words + UINT32 e_lfanew; // File address of new exe header + } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; + +typedef struct _IMAGE_OS2_HEADER { // OS/2 .EXE header + UINT16 ne_magic; // Magic number + UINT8 ne_ver; // Version number + UINT8 ne_rev; // Revision number + UINT16 ne_enttab; // Offset of Entry Table + UINT16 ne_cbenttab; // Number of bytes in Entry Table + UINT32 ne_crc; // Checksum of whole file + UINT16 ne_flags; // Flag UINT16 + UINT16 ne_autodata; // Automatic data segment number + UINT16 ne_heap; // Initial heap allocation + UINT16 ne_stack; // Initial stack allocation + UINT32 ne_csip; // Initial CS:IP setting + UINT32 ne_sssp; // Initial SS:SP setting + UINT16 ne_cseg; // Count of file segments + UINT16 ne_cmod; // Entries in Module Reference Table + UINT16 ne_cbnrestab; // Size of non-resident name table + UINT16 ne_segtab; // Offset of Segment Table + UINT16 ne_rsrctab; // Offset of Resource Table + UINT16 ne_restab; // Offset of resident name table + UINT16 ne_modtab; // Offset of Module Reference Table + UINT16 ne_imptab; // Offset of Imported Names Table + UINT32 ne_nrestab; // Offset of Non-resident Names Table + UINT16 ne_cmovent; // Count of movable entries + UINT16 ne_align; // Segment alignment shift count + UINT16 ne_cres; // Count of resource segments + UINT8 ne_exetyp; // Target Operating system + UINT8 ne_flagsothers; // Other .EXE flags + UINT16 ne_pretthunks; // offset to return thunks + UINT16 ne_psegrefbytes; // offset to segment ref. bytes + UINT16 ne_swaparea; // Minimum code swap area size + UINT16 ne_expver; // Expected Windows version number + } IMAGE_OS2_HEADER, *PIMAGE_OS2_HEADER; + +// +// File header format. +// + +typedef struct _IMAGE_FILE_HEADER { + UINT16 Machine; + UINT16 NumberOfSections; + UINT32 TimeDateStamp; + UINT32 PointerToSymbolTable; + UINT32 NumberOfSymbols; + UINT16 SizeOfOptionalHeader; + UINT16 Characteristics; +} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; + +#define IMAGE_SIZEOF_FILE_HEADER 20 + +#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file. +#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references). +#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file. +#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file. +#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed. +#define IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine. +#define IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file +#define IMAGE_FILE_SYSTEM 0x1000 // System File. +#define IMAGE_FILE_DLL 0x2000 // File is a DLL. +#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed. + +#define IMAGE_FILE_MACHINE_UNKNOWN 0 +#define IMAGE_FILE_MACHINE_I386 0x14c // Intel 386. +#define IMAGE_FILE_MACHINE_R3000 0x162 // MIPS little-endian, 0540 big-endian +#define IMAGE_FILE_MACHINE_R4000 0x166 // MIPS little-endian +#define IMAGE_FILE_MACHINE_ALPHA 0x184 // Alpha_AXP +#define IMAGE_FILE_MACHINE_ARMTHUMB_MIXED 0x1c2 // Arm/Thumb +#define IMAGE_FILE_MACHINE_POWERPC 0x1F0 // IBM PowerPC Little-Endian +#define IMAGE_FILE_MACHINE_IA64 0x200 // IA-64 +#define IMAGE_FILE_MACHINE_TAHOE 0x7cc // Intel EM machine +#define IMAGE_FILE_MACHINE_EBC 0xebc // EFI Byte Code +#define IMAGE_FILE_MACHINE_X64 0x8664 // x86_64 +// +// Directory format. +// + +typedef struct _IMAGE_DATA_DIRECTORY { + UINT32 VirtualAddress; + UINT32 Size; +} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; + +#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 + +// +// Optional header format. +// + +typedef struct _IMAGE_OPTIONAL_HEADER { + // + // Standard fields. + // + + UINT16 Magic; + UINT8 MajorLinkerVersion; + UINT8 MinorLinkerVersion; + UINT32 SizeOfCode; + UINT32 SizeOfInitializedData; + UINT32 SizeOfUninitializedData; + UINT32 AddressOfEntryPoint; + UINT32 BaseOfCode; + UINT32 BaseOfData; + + // + // NT additional fields. + // + + UINT32 ImageBase; + UINT32 SectionAlignment; + UINT32 FileAlignment; + UINT16 MajorOperatingSystemVersion; + UINT16 MinorOperatingSystemVersion; + UINT16 MajorImageVersion; + UINT16 MinorImageVersion; + UINT16 MajorSubsystemVersion; + UINT16 MinorSubsystemVersion; + UINT32 Reserved1; + UINT32 SizeOfImage; + UINT32 SizeOfHeaders; + UINT32 CheckSum; + UINT16 Subsystem; + UINT16 DllCharacteristics; + UINT32 SizeOfStackReserve; + UINT32 SizeOfStackCommit; + UINT32 SizeOfHeapReserve; + UINT32 SizeOfHeapCommit; + UINT32 LoaderFlags; + UINT32 NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; +} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER; + +typedef struct _IMAGE_ROM_OPTIONAL_HEADER { + UINT16 Magic; + UINT8 MajorLinkerVersion; + UINT8 MinorLinkerVersion; + UINT32 SizeOfCode; + UINT32 SizeOfInitializedData; + UINT32 SizeOfUninitializedData; + UINT32 AddressOfEntryPoint; + UINT32 BaseOfCode; + UINT32 BaseOfData; + UINT32 BaseOfBss; + UINT32 GprMask; + UINT32 CprMask[4]; + UINT32 GpValue; +} IMAGE_ROM_OPTIONAL_HEADER, *PIMAGE_ROM_OPTIONAL_HEADER; + +#define IMAGE_SIZEOF_ROM_OPTIONAL_HEADER 56 +#define IMAGE_SIZEOF_STD_OPTIONAL_HEADER 28 +#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER 224 + +#define IMAGE_NT_OPTIONAL_HDR_MAGIC 0x10b +#define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107 + +typedef struct _IMAGE_NT_HEADERS { + UINT32 Signature; + IMAGE_FILE_HEADER FileHeader; + IMAGE_OPTIONAL_HEADER OptionalHeader; +} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS; + +typedef struct _IMAGE_ROM_HEADERS { + IMAGE_FILE_HEADER FileHeader; + IMAGE_ROM_OPTIONAL_HEADER OptionalHeader; +} IMAGE_ROM_HEADERS, *PIMAGE_ROM_HEADERS; + +#define IMAGE_FIRST_SECTION( ntheader ) ((PIMAGE_SECTION_HEADER) \ + ((UINTN)ntheader + \ + FIELD_OFFSET( IMAGE_NT_HEADERS, OptionalHeader ) + \ + ((PIMAGE_NT_HEADERS)(ntheader))->FileHeader.SizeOfOptionalHeader \ + )) + + +// Subsystem Values + +#define IMAGE_SUBSYSTEM_UNKNOWN 0 // Unknown subsystem. +#define IMAGE_SUBSYSTEM_NATIVE 1 // Image doesn't require a subsystem. +#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 // Image runs in the Windows GUI subsystem. +#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 // Image runs in the Windows character subsystem. +#define IMAGE_SUBSYSTEM_OS2_CUI 5 // image runs in the OS/2 character subsystem. +#define IMAGE_SUBSYSTEM_POSIX_CUI 7 // image run in the Posix character subsystem. + + +// Directory Entries + +#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory +#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory +#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory +#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory +#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory +#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table +#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory +#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // Description String +#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // Machine Value (MIPS GP) +#define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory +#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory + +// +// Section header format. +// + +#define IMAGE_SIZEOF_SHORT_NAME 8 + +typedef struct _IMAGE_SECTION_HEADER { + UINT8 Name[IMAGE_SIZEOF_SHORT_NAME]; + union { + UINT32 PhysicalAddress; + UINT32 VirtualSize; + } Misc; + UINT32 VirtualAddress; + UINT32 SizeOfRawData; + UINT32 PointerToRawData; + UINT32 PointerToRelocations; + UINT32 PointerToLinenumbers; + UINT16 NumberOfRelocations; + UINT16 NumberOfLinenumbers; + UINT32 Characteristics; +} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; + +#define IMAGE_SIZEOF_SECTION_HEADER 40 + +#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 // Reserved. + +#define IMAGE_SCN_CNT_CODE 0x00000020 // Section contains code. +#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 // Section contains initialized data. +#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 // Section contains uninitialized data. + +#define IMAGE_SCN_LNK_OTHER 0x00000100 // Reserved. +#define IMAGE_SCN_LNK_INFO 0x00000200 // Section contains comments or some other type of information. +#define IMAGE_SCN_LNK_REMOVE 0x00000800 // Section contents will not become part of image. +#define IMAGE_SCN_LNK_COMDAT 0x00001000 // Section contents comdat. + +#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 // +#define IMAGE_SCN_ALIGN_2BYTES 0x00200000 // +#define IMAGE_SCN_ALIGN_4BYTES 0x00300000 // +#define IMAGE_SCN_ALIGN_8BYTES 0x00400000 // +#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 // Default alignment if no others are specified. +#define IMAGE_SCN_ALIGN_32BYTES 0x00600000 // +#define IMAGE_SCN_ALIGN_64BYTES 0x00700000 // + +#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 // Section can be discarded. +#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 // Section is not cachable. +#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 // Section is not pageable. +#define IMAGE_SCN_MEM_SHARED 0x10000000 // Section is shareable. +#define IMAGE_SCN_MEM_EXECUTE 0x20000000 // Section is executable. +#define IMAGE_SCN_MEM_READ 0x40000000 // Section is readable. +#define IMAGE_SCN_MEM_WRITE 0x80000000 // Section is writeable. + +// +// Symbol format. +// + + +#define IMAGE_SIZEOF_SYMBOL 18 + +// +// Section values. +// +// Symbols have a section number of the section in which they are +// defined. Otherwise, section numbers have the following meanings: +// + +#define IMAGE_SYM_UNDEFINED (UINT16)0 // Symbol is undefined or is common. +#define IMAGE_SYM_ABSOLUTE (UINT16)-1 // Symbol is an absolute value. +#define IMAGE_SYM_DEBUG (UINT16)-2 // Symbol is a special debug item. + +// +// Type (fundamental) values. +// + +#define IMAGE_SYM_TYPE_NULL 0 // no type. +#define IMAGE_SYM_TYPE_VOID 1 // +#define IMAGE_SYM_TYPE_CHAR 2 // type character. +#define IMAGE_SYM_TYPE_SHORT 3 // type short integer. +#define IMAGE_SYM_TYPE_INT 4 // +#define IMAGE_SYM_TYPE_LONG 5 // +#define IMAGE_SYM_TYPE_FLOAT 6 // +#define IMAGE_SYM_TYPE_DOUBLE 7 // +#define IMAGE_SYM_TYPE_STRUCT 8 // +#define IMAGE_SYM_TYPE_UNION 9 // +#define IMAGE_SYM_TYPE_ENUM 10 // enumeration. +#define IMAGE_SYM_TYPE_MOE 11 // member of enumeration. +#define IMAGE_SYM_TYPE_BYTE 12 // +#define IMAGE_SYM_TYPE_WORD 13 // +#define IMAGE_SYM_TYPE_UINT 14 // +#define IMAGE_SYM_TYPE_DWORD 15 // + +// +// Type (derived) values. +// + +#define IMAGE_SYM_DTYPE_NULL 0 // no derived type. +#define IMAGE_SYM_DTYPE_POINTER 1 // pointer. +#define IMAGE_SYM_DTYPE_FUNCTION 2 // function. +#define IMAGE_SYM_DTYPE_ARRAY 3 // array. + +// +// Storage classes. +// + +#define IMAGE_SYM_CLASS_END_OF_FUNCTION (BYTE )-1 +#define IMAGE_SYM_CLASS_NULL 0 +#define IMAGE_SYM_CLASS_AUTOMATIC 1 +#define IMAGE_SYM_CLASS_EXTERNAL 2 +#define IMAGE_SYM_CLASS_STATIC 3 +#define IMAGE_SYM_CLASS_REGISTER 4 +#define IMAGE_SYM_CLASS_EXTERNAL_DEF 5 +#define IMAGE_SYM_CLASS_LABEL 6 +#define IMAGE_SYM_CLASS_UNDEFINED_LABEL 7 +#define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 8 +#define IMAGE_SYM_CLASS_ARGUMENT 9 +#define IMAGE_SYM_CLASS_STRUCT_TAG 10 +#define IMAGE_SYM_CLASS_MEMBER_OF_UNION 11 +#define IMAGE_SYM_CLASS_UNION_TAG 12 +#define IMAGE_SYM_CLASS_TYPE_DEFINITION 13 +#define IMAGE_SYM_CLASS_UNDEFINED_STATIC 14 +#define IMAGE_SYM_CLASS_ENUM_TAG 15 +#define IMAGE_SYM_CLASS_MEMBER_OF_ENUM 16 +#define IMAGE_SYM_CLASS_REGISTER_PARAM 17 +#define IMAGE_SYM_CLASS_BIT_FIELD 18 +#define IMAGE_SYM_CLASS_BLOCK 100 +#define IMAGE_SYM_CLASS_FUNCTION 101 +#define IMAGE_SYM_CLASS_END_OF_STRUCT 102 +#define IMAGE_SYM_CLASS_FILE 103 +// new +#define IMAGE_SYM_CLASS_SECTION 104 +#define IMAGE_SYM_CLASS_WEAK_EXTERNAL 105 + +// type packing constants + +#define N_BTMASK 017 +#define N_TMASK 060 +#define N_TMASK1 0300 +#define N_TMASK2 0360 +#define N_BTSHFT 4 +#define N_TSHIFT 2 + +// MACROS + +// +// Communal selection types. +// + +#define IMAGE_COMDAT_SELECT_NODUPLICATES 1 +#define IMAGE_COMDAT_SELECT_ANY 2 +#define IMAGE_COMDAT_SELECT_SAME_SIZE 3 +#define IMAGE_COMDAT_SELECT_EXACT_MATCH 4 +#define IMAGE_COMDAT_SELECT_ASSOCIATIVE 5 + +#define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1 +#define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2 +#define IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3 + + +// +// Relocation format. +// + +typedef struct _IMAGE_RELOCATION { + UINT32 VirtualAddress; + UINT32 SymbolTableIndex; + UINT16 Type; +} IMAGE_RELOCATION; + +#define IMAGE_SIZEOF_RELOCATION 10 + +// +// I386 relocation types. +// + +#define IMAGE_REL_I386_ABSOLUTE 0 // Reference is absolute, no relocation is necessary +#define IMAGE_REL_I386_DIR16 01 // Direct 16-bit reference to the symbols virtual address +#define IMAGE_REL_I386_REL16 02 // PC-relative 16-bit reference to the symbols virtual address +#define IMAGE_REL_I386_DIR32 06 // Direct 32-bit reference to the symbols virtual address +#define IMAGE_REL_I386_DIR32NB 07 // Direct 32-bit reference to the symbols virtual address, base not included +#define IMAGE_REL_I386_SEG12 011 // Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address +#define IMAGE_REL_I386_SECTION 012 +#define IMAGE_REL_I386_SECREL 013 +#define IMAGE_REL_I386_REL32 024 // PC-relative 32-bit reference to the symbols virtual address + +// +// MIPS relocation types. +// + +#define IMAGE_REL_MIPS_ABSOLUTE 0 // Reference is absolute, no relocation is necessary +#define IMAGE_REL_MIPS_REFHALF 01 +#define IMAGE_REL_MIPS_REFWORD 02 +#define IMAGE_REL_MIPS_JMPADDR 03 +#define IMAGE_REL_MIPS_REFHI 04 +#define IMAGE_REL_MIPS_REFLO 05 +#define IMAGE_REL_MIPS_GPREL 06 +#define IMAGE_REL_MIPS_LITERAL 07 +#define IMAGE_REL_MIPS_SECTION 012 +#define IMAGE_REL_MIPS_SECREL 013 +#define IMAGE_REL_MIPS_REFWORDNB 042 +#define IMAGE_REL_MIPS_PAIR 045 + +// +// Alpha Relocation types. +// + +#define IMAGE_REL_ALPHA_ABSOLUTE 0x0 +#define IMAGE_REL_ALPHA_REFLONG 0x1 +#define IMAGE_REL_ALPHA_REFQUAD 0x2 +#define IMAGE_REL_ALPHA_GPREL32 0x3 +#define IMAGE_REL_ALPHA_LITERAL 0x4 +#define IMAGE_REL_ALPHA_LITUSE 0x5 +#define IMAGE_REL_ALPHA_GPDISP 0x6 +#define IMAGE_REL_ALPHA_BRADDR 0x7 +#define IMAGE_REL_ALPHA_HINT 0x8 +#define IMAGE_REL_ALPHA_INLINE_REFLONG 0x9 +#define IMAGE_REL_ALPHA_REFHI 0xA +#define IMAGE_REL_ALPHA_REFLO 0xB +#define IMAGE_REL_ALPHA_PAIR 0xC +#define IMAGE_REL_ALPHA_MATCH 0xD +#define IMAGE_REL_ALPHA_SECTION 0xE +#define IMAGE_REL_ALPHA_SECREL 0xF +#define IMAGE_REL_ALPHA_REFLONGNB 0x10 + +// +// IBM PowerPC relocation types. +// + +#define IMAGE_REL_PPC_ABSOLUTE 0x0000 // NOP +#define IMAGE_REL_PPC_ADDR64 0x0001 // 64-bit address +#define IMAGE_REL_PPC_ADDR32 0x0002 // 32-bit address +#define IMAGE_REL_PPC_ADDR24 0x0003 // 26-bit address, shifted left 2 (branch absolute) +#define IMAGE_REL_PPC_ADDR16 0x0004 // 16-bit address +#define IMAGE_REL_PPC_ADDR14 0x0005 // 16-bit address, shifted left 2 (load doubleword) +#define IMAGE_REL_PPC_REL24 0x0006 // 26-bit PC-relative offset, shifted left 2 (branch relative) +#define IMAGE_REL_PPC_REL14 0x0007 // 16-bit PC-relative offset, shifted left 2 (br cond relative) +#define IMAGE_REL_PPC_TOCREL16 0x0008 // 16-bit offset from TOC base +#define IMAGE_REL_PPC_TOCREL14 0x0009 // 16-bit offset from TOC base, shifted left 2 (load doubleword) + +#define IMAGE_REL_PPC_ADDR32NB 0x000A // 32-bit addr w/o image base +#define IMAGE_REL_PPC_SECREL 0x000B // va of containing section (as in an image sectionhdr) +#define IMAGE_REL_PPC_SECTION 0x000C // sectionheader number +#define IMAGE_REL_PPC_IFGLUE 0x000D // substitute TOC restore instruction iff symbol is glue code +#define IMAGE_REL_PPC_IMGLUE 0x000E // symbol is glue code; virtual address is TOC restore instruction + +#define IMAGE_REL_PPC_TYPEMASK 0x00FF // mask to isolate above values in IMAGE_RELOCATION.Type + +// Flag bits in IMAGE_RELOCATION.TYPE + +#define IMAGE_REL_PPC_NEG 0x0100 // subtract reloc value rather than adding it +#define IMAGE_REL_PPC_BRTAKEN 0x0200 // fix branch prediction bit to predict branch taken +#define IMAGE_REL_PPC_BRNTAKEN 0x0400 // fix branch prediction bit to predict branch not taken +#define IMAGE_REL_PPC_TOCDEFN 0x0800 // toc slot defined in file (or, data in toc) + +// +// Based relocation format. +// + +typedef struct _IMAGE_BASE_RELOCATION { + UINT32 VirtualAddress; + UINT32 SizeOfBlock; +// UINT16 TypeOffset[1]; +} IMAGE_BASE_RELOCATION, *PIMAGE_BASE_RELOCATION; + +#define IMAGE_SIZEOF_BASE_RELOCATION 8 + +// +// Based relocation types. +// + +#define IMAGE_REL_BASED_ABSOLUTE 0 +#define IMAGE_REL_BASED_HIGH 1 +#define IMAGE_REL_BASED_LOW 2 +#define IMAGE_REL_BASED_HIGHLOW 3 +#define IMAGE_REL_BASED_HIGHADJ 4 +#define IMAGE_REL_BASED_MIPS_JMPADDR 5 +#define IMAGE_REL_BASED_IA64_IMM64 9 +#define IMAGE_REL_BASED_DIR64 10 + +// +// Line number format. +// + +typedef struct _IMAGE_LINENUMBER { + union { + UINT32 SymbolTableIndex; // Symbol table index of function name if Linenumber is 0. + UINT32 VirtualAddress; // Virtual address of line number. + } Type; + UINT16 Linenumber; // Line number. +} IMAGE_LINENUMBER; + +#define IMAGE_SIZEOF_LINENUMBER 6 + +// +// Archive format. +// + +#define IMAGE_ARCHIVE_START_SIZE 8 +#define IMAGE_ARCHIVE_START "!\n" +#define IMAGE_ARCHIVE_END "`\n" +#define IMAGE_ARCHIVE_PAD "\n" +#define IMAGE_ARCHIVE_LINKER_MEMBER "/ " +#define IMAGE_ARCHIVE_LONGNAMES_MEMBER "// " + +typedef struct _IMAGE_ARCHIVE_MEMBER_HEADER { + UINT8 Name[16]; // File member name - `/' terminated. + UINT8 Date[12]; // File member date - decimal. + UINT8 UserID[6]; // File member user id - decimal. + UINT8 GroupID[6]; // File member group id - decimal. + UINT8 Mode[8]; // File member mode - octal. + UINT8 Size[10]; // File member size - decimal. + UINT8 EndHeader[2]; // String to end header. +} IMAGE_ARCHIVE_MEMBER_HEADER, *PIMAGE_ARCHIVE_MEMBER_HEADER; + +#define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60 + +// +// DLL support. +// + +// +// Export Format +// + +// typedef struct _IMAGE_EXPORT_DIRECTORY { +// UINT32 Characteristics; +// UINT32 TimeDateStamp; +// UINT16 MajorVersion; +// UINT16 MinorVersion; +// UINT32 Name; +// UINT32 Base; +// UINT32 NumberOfFunctions; +// UINT32 NumberOfNames; +// UINT32 *AddressOfFunctions; +// UINT32 *AddressOfNames; +// UINT32 *AddressOfNameOrdinals; +// } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY; + +// +// Import Format +// + +// typedef struct _IMAGE_IMPORT_BY_NAME { +// UINT16 Hint; +// UINT8 Name[1]; +// } IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME; + +// typedef struct _IMAGE_THUNK_DATA { +// union { +// UINT32 Function; +// UINT32 Ordinal; +// PIMAGE_IMPORT_BY_NAME AddressOfData; +// } u1; +// } IMAGE_THUNK_DATA, *PIMAGE_THUNK_DATA; + +#define IMAGE_ORDINAL_FLAG 0x80000000 +#define IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG) != 0) +#define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff) + +// typedef struct _IMAGE_IMPORT_DESCRIPTOR { +// union { +// UINT32 Characteristics; +// UINT32 OriginalFirstThunk; +// }; +// UINT32 TimeDateStamp; +// UINT32 ForwarderChain; +// UINT32 Name; +// UINT32 FirstThunk; +// } IMAGE_IMPORT_DESCRIPTOR, *PIMAGE_IMPORT_DESCRIPTOR; + +#endif diff --git a/kernel32.cpp b/kernel32.cpp index c7d7b27..002c494 100644 --- a/kernel32.cpp +++ b/kernel32.cpp @@ -1,3 +1,9 @@ +#include +#include +#include +#include "print.h" + +#pragma region types typedef void* HWND; typedef void* LPUNKNOWN; typedef void* REFIID; @@ -8,14 +14,17 @@ typedef unsigned int UINT; typedef int BOOL; typedef void* HANDLE; typedef void* LPVOID; +typedef const void* LPCVOID; typedef long LONG; typedef long LONG_PTR; +typedef char* LPSTR; typedef const char* LPCSTR; typedef size_t SIZE_T; typedef void* HMODULE; typedef HMODULE HINSTANCE; typedef void* FARPROC; typedef DWORD (*LPTHREAD_START_ROUTINE)(LPVOID lpThreadParameter); + typedef union _LARGE_INTEGER { struct { unsigned long LowPart; @@ -23,230 +32,865 @@ typedef union _LARGE_INTEGER { }; long long QuadPart; } LARGE_INTEGER; -#define S_OK ((HRESULT)0L) -#define TRUE 1 -#define FALSE 0 -#include -#include -extern "C" { +typedef int BOOL; +typedef unsigned long DWORD; +typedef void* LPVOID; +typedef LPVOID LPCRITICAL_SECTION; -typedef HANDLE (*HeapCreate_t)(DWORD, SIZE_T, SIZE_T); -typedef BOOL (*HeapDestroy_t)(HANDLE); -typedef LPVOID (*HeapAlloc_t)(HANDLE, DWORD, SIZE_T); -typedef BOOL (*HeapFree_t)(HANDLE, DWORD, LPVOID); -typedef LPVOID (*HeapReAlloc_t)(HANDLE a, DWORD b, LPVOID c, SIZE_T d); +// Basic types +typedef void* PVOID; +typedef unsigned long DWORD; +typedef int BOOL; +typedef unsigned int UINT; +typedef unsigned short USHORT; +typedef unsigned long long ULONG64; +typedef unsigned long ULONG; +typedef void* HANDLE; +typedef long LONG; +typedef unsigned short WORD; +typedef unsigned char BYTE; +typedef long LONG_PTR; +typedef unsigned long long ULONG_PTR; +typedef unsigned char* LPBYTE; +typedef ULONG_PTR DWORD_PTR; -HeapCreate_t pHeapCreate = nullptr; -HeapDestroy_t pHeapDestroy = nullptr; -HeapAlloc_t pHeapAlloc = nullptr; -HeapFree_t pHeapFree = nullptr; -HeapReAlloc_t pHeapReAlloc = nullptr; - -// Memory -__declspec(dllexport) HANDLE HeapCreate(DWORD a, SIZE_T b, SIZE_T c) { return pHeapCreate(a, b, c); } -__declspec(dllexport) BOOL HeapDestroy(HANDLE a) { return pHeapDestroy(a); } -__declspec(dllexport) LPVOID HeapAlloc(HANDLE a, DWORD b, SIZE_T c) { return pHeapAlloc(a, b, c); } -__declspec(dllexport) BOOL HeapFree(HANDLE a, DWORD b, LPVOID c) { return pHeapFree(a, b, c); } -__declspec(dllexport) LPVOID HeapReAlloc(HANDLE a, DWORD b, LPVOID c, SIZE_T d) { return pHeapReAlloc(a, b, c, d); } +// Pointer to Const types +typedef const char* LPCSTR; +typedef const char* LPCTSTR; +typedef const void* LPCVOID; +typedef const wchar_t* LPCWSTR; -// Threads (fake) -__declspec(dllexport) DWORD GetCurrentThreadId() { return 1; } -__declspec(dllexport) HANDLE GetCurrentThread() { return (HANDLE)1; } -__declspec(dllexport) HANDLE CreateThread(void*, SIZE_T, LPTHREAD_START_ROUTINE, void*, DWORD, DWORD*) { return (HANDLE)1; } -__declspec(dllexport) DWORD WaitForSingleObject(HANDLE, DWORD) { return 0; } -__declspec(dllexport) BOOL CloseHandle(HANDLE) { return 1; } +// Pointers to variables +typedef DWORD* LPDWORD; +typedef long* PLONG; +typedef char* LPSTR; +typedef char* LPCH; +typedef wchar_t* LPWSTR; +typedef wchar_t* LPWCH; +typedef BOOL* LPBOOL; +typedef void* LPVOID; +typedef void* HMODULE; -typedef DWORD (*GetTickCount_t)(); -typedef BOOL (*QueryPerformanceCounter_t)(LARGE_INTEGER* li); -typedef BOOL (*QueryPerformanceFrequency_t)(LARGE_INTEGER* li); +typedef long* LPLONG; +typedef ULONG64* PULONG64; -GetTickCount_t pGetTickCount = nullptr; -QueryPerformanceCounter_t pQueryPerformanceCounter = nullptr; -QueryPerformanceFrequency_t pQueryPerformanceFrequency = nullptr; +// Structures and callbacks +typedef struct _SECURITY_ATTRIBUTES { + DWORD nLength; + LPVOID lpSecurityDescriptor; + BOOL bInheritHandle; +} SECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES; -// Timing -__declspec(dllexport) DWORD GetTickCount() { - return pGetTickCount(); -} +typedef struct _OVERLAPPED { + ULONG_PTR Internal; + ULONG_PTR InternalHigh; + DWORD Offset; + DWORD OffsetHigh; + HANDLE hEvent; +} OVERLAPPED, *LPOVERLAPPED; -__declspec(dllexport) BOOL QueryPerformanceCounter(LARGE_INTEGER* li) { - return pQueryPerformanceCounter(li); -} +typedef struct _STARTUPINFOA { + DWORD cb; + LPSTR lpReserved; + LPSTR lpDesktop; + LPSTR lpTitle; + DWORD dwX; + DWORD dwY; + DWORD dwXSize; + DWORD dwYSize; + DWORD dwXCountChars; + DWORD dwYCountChars; + DWORD dwFillAttribute; + DWORD dwFlags; + USHORT wShowWindow; + USHORT cbReserved2; + LPBYTE lpReserved2; + HANDLE hStdInput; + HANDLE hStdOutput; + HANDLE hStdError; +} STARTUPINFOA, *LPSTARTUPINFOA; -__declspec(dllexport) BOOL QueryPerformanceFrequency(LARGE_INTEGER* li) { - return pQueryPerformanceFrequency(li); -} +typedef struct _FILETIME { + DWORD dwLowDateTime; + DWORD dwHighDateTime; +} FILETIME, *LPFILETIME; -// Module / file -__declspec(dllexport) HMODULE GetModuleHandleA(LPCSTR) { return (HMODULE)1; } -__declspec(dllexport) FARPROC GetProcAddress(HMODULE, LPCSTR) { return nullptr; } -__declspec(dllexport) HMODULE LoadLibraryA(LPCSTR) { return (HMODULE)1; } +typedef struct _CPINFO { + UINT MaxCharSize; + BYTE DefaultChar[2]; + BYTE LeadByte[12]; +} CPINFO, *LPCPINFO; -// Process -__declspec(dllexport) DWORD GetCurrentProcessId() { return 1; } -__declspec(dllexport) HANDLE GetCurrentProcess() { return (HANDLE)1; } -__declspec(dllexport) void ExitProcess(UINT) { while(1); } +typedef unsigned short* LPWORD; +typedef char* PSTR; -typedef void (*OutputDebugStringA_t)(LPCSTR lpOutputString); +// Function pointer for Fiber Local Storage callback +typedef void (*PFLS_CALLBACK_FUNCTION)(PVOID lpFlsData); -OutputDebugStringA_t pOutputDebugStringA = nullptr; +// Heap information enumeration +typedef enum _HEAP_INFORMATION_CLASS { + HeapCompatibilityInformation, + HeapEnableTerminationOnCorruption +} HEAP_INFORMATION_CLASS; -__declspec(dllexport) void OutputDebugStringA(LPCSTR lpOutputString) { - pOutputDebugStringA(lpOutputString); -} +typedef struct _SYSTEM_INFO { + union { + DWORD dwOemId; + struct { + WORD wProcessorArchitecture; + WORD wReserved; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + DWORD dwPageSize; + LPVOID lpMinimumApplicationAddress; + LPVOID lpMaximumApplicationAddress; + DWORD_PTR dwActiveProcessorMask; + DWORD dwNumberOfProcessors; + DWORD dwProcessorType; + DWORD dwAllocationGranularity; + WORD wProcessorLevel; + WORD wProcessorRevision; +} SYSTEM_INFO, *LPSYSTEM_INFO; -HMODULE LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags); +// Exception handling types +typedef PVOID PVECTORED_EXCEPTION_HANDLER; +typedef struct _CONTEXT {} CONTEXT, *PCONTEXT; +typedef struct _RUNTIME_FUNCTION {} RUNTIME_FUNCTION, *PRUNTIME_FUNCTION; +typedef LONG(*LPTOP_LEVEL_EXCEPTION_FILTER)(PVOID ExceptionInfo); -#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ -#define IMAGE_NT_SIGNATURE 0x00004550 // PE00 -#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 +// Locale and Codepage types +typedef DWORD LCID; +typedef DWORD LCTYPE; +#pragma endregion -struct IMAGE_DOS_HEADER { - uint16_t e_magic; - uint16_t e_cblp; - uint16_t e_cp; - uint16_t e_crlc; - uint16_t e_cparhdr; - uint16_t e_minalloc; - uint16_t e_maxalloc; - uint16_t e_ss; - uint16_t e_sp; - uint16_t e_csum; - uint16_t e_ip; - uint16_t e_cs; - uint16_t e_lfarlc; - uint16_t e_ovno; - uint16_t e_res[4]; - uint16_t e_oemid; - uint16_t e_oeminfo; - uint16_t e_res2[10]; - uint32_t e_lfanew; -}; - -struct IMAGE_FILE_HEADER { - uint16_t Machine; - uint16_t NumberOfSections; - uint32_t TimeDateStamp; - uint32_t PointerToSymbolTable; - uint32_t NumberOfSymbols; - uint16_t SizeOfOptionalHeader; - uint16_t Characteristics; -}; - -struct IMAGE_DATA_DIRECTORY { - uint32_t VirtualAddress; - uint32_t Size; -}; - -struct IMAGE_OPTIONAL_HEADER64 { - uint16_t Magic; - uint8_t MajorLinkerVersion; - uint8_t MinorLinkerVersion; - uint32_t SizeOfCode; - uint32_t SizeOfInitializedData; - uint32_t SizeOfUninitializedData; - uint32_t AddressOfEntryPoint; - uint32_t BaseOfCode; - uint64_t ImageBase; - uint32_t SectionAlignment; - uint32_t FileAlignment; - uint16_t MajorOperatingSystemVersion; - uint16_t MinorOperatingSystemVersion; - uint16_t MajorImageVersion; - uint16_t MinorImageVersion; - uint16_t MajorSubsystemVersion; - uint16_t MinorSubsystemVersion; - uint32_t Win32VersionValue; - uint32_t SizeOfImage; - uint32_t SizeOfHeaders; - uint32_t CheckSum; - uint16_t Subsystem; - uint16_t DllCharacteristics; - uint64_t SizeOfStackReserve; - uint64_t SizeOfStackCommit; - uint64_t SizeOfHeapReserve; - uint64_t SizeOfHeapCommit; - uint32_t LoaderFlags; - uint32_t NumberOfRvaAndSizes; - IMAGE_DATA_DIRECTORY DataDirectory[16]; -}; - -struct IMAGE_NT_HEADERS64 { - uint32_t Signature; - IMAGE_FILE_HEADER FileHeader; - IMAGE_OPTIONAL_HEADER64 OptionalHeader; -}; - -struct IMAGE_EXPORT_DIRECTORY { - uint32_t Characteristics; - uint32_t TimeDateStamp; - uint16_t MajorVersion; - uint16_t MinorVersion; - uint32_t Name; - uint32_t Base; - uint32_t NumberOfFunctions; - uint32_t NumberOfNames; - uint32_t AddressOfFunctions; // RVA from base of image - uint32_t AddressOfNames; // RVA from base of image - uint32_t AddressOfNameOrdinals; // RVA from base of image -}; - -int strcmp(const char* a, const char* b) { - while (*a && (*a == *b)) { - ++a; - ++b; - } - return static_cast(*a) - static_cast(*b); -} - -FARPROC GetRealGetProcAddress(HMODULE hModule) { - auto base = reinterpret_cast(hModule); - auto dos = reinterpret_cast(base); - if (dos->e_magic != IMAGE_DOS_SIGNATURE) return nullptr; - - auto nt = reinterpret_cast(base + dos->e_lfanew); - if (nt->Signature != IMAGE_NT_SIGNATURE) return nullptr; - - auto exportDirRVA = nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; - auto exportDir = reinterpret_cast(base + exportDirRVA); - - auto names = reinterpret_cast(base + exportDir->AddressOfNames); - auto ordinals = reinterpret_cast(base + exportDir->AddressOfNameOrdinals); - auto functions = reinterpret_cast(base + exportDir->AddressOfFunctions); - - for (uint32_t i = 0; i < exportDir->NumberOfNames; i++) { - const char* name = reinterpret_cast(base + names[i]); - if (strcmp(name, "GetProcAddress") == 0) { - uint16_t ord = ordinals[i]; - uint32_t funcRVA = functions[ord]; - return reinterpret_cast(base + funcRVA); - } - } +// --- Memory --- +HANDLE HeapCreate(DWORD, SIZE_T, SIZE_T) { + PRINT(L"Called: HeapCreate\n"); return nullptr; } -typedef FARPROC (*GetProcAddress_t)(HMODULE, LPCSTR); -GetProcAddress_t pGetProcAddress = nullptr; +BOOL HeapDestroy(HANDLE) { + PRINT(L"Called: HeapDestroy\n"); + return TRUE; // nothing to do +} -BOOL DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { - if (fdwReason == 1) { // DLL_PROCESS_ATTACH - HMODULE kernel32 = LoadLibraryExA("kernel32.dll", NULL, 0x00000800); - pGetProcAddress = (GetProcAddress_t)GetRealGetProcAddress(kernel32); +LPVOID HeapAlloc(HANDLE, DWORD, SIZE_T size) { + PRINT(L"Called: HeapAlloc with size: %ull\n", size); + return AllocatePool(size); +} - pHeapCreate = (HeapCreate_t)pGetProcAddress(kernel32, "HeapCreate"); - pHeapDestroy = (HeapDestroy_t)pGetProcAddress(kernel32, "HeapDestroy"); - pHeapAlloc = (HeapAlloc_t)pGetProcAddress(kernel32, "HeapAlloc"); - pHeapFree = (HeapFree_t)pGetProcAddress(kernel32, "HeapFree"); - pHeapReAlloc = (HeapReAlloc_t)pGetProcAddress(kernel32, "HeapReAlloc"); - - pGetTickCount = (GetTickCount_t)pGetProcAddress(kernel32, "GetTickCount"); - pQueryPerformanceCounter = (QueryPerformanceCounter_t)pGetProcAddress(kernel32, "QueryPerformanceCounter"); - pQueryPerformanceFrequency = (QueryPerformanceFrequency_t)pGetProcAddress(kernel32, "QueryPerformanceFrequency"); - - pOutputDebugStringA = (OutputDebugStringA_t)pGetProcAddress(kernel32, "OutputDebugStringA"); - } +BOOL HeapFree(HANDLE, DWORD, LPVOID ptr) { + PRINT(L"Called: HeapFree with ptr: %p\n", ptr); + if (ptr) + FreePool(ptr); return TRUE; } +LPVOID HeapReAlloc(HANDLE, DWORD, LPVOID ptr, SIZE_T size) { + PRINT(L"Called: HeapReAlloc with size: %ull and ptr: %p\n", size, ptr); + if (!ptr) return AllocatePool(size); + LPVOID newPtr = AllocatePool(size); + if (!newPtr) return nullptr; + // No original size info; can't fully emulate, user must handle + CopyMem(newPtr, ptr, size); + FreePool(ptr); + return newPtr; +} + +SIZE_T HeapSize(HANDLE, DWORD, LPCVOID) { + PRINT(L"Called: HeapSize\n"); + return 0; +} + +// --- Threads (fake, UEFI is single-threaded at boot) --- +HANDLE GetCurrentThread() { + PRINT(L"Called: GetCurrentThread\n"); + return reinterpret_cast(1); +} + +HANDLE CreateThread(void*, SIZE_T, LPTHREAD_START_ROUTINE, void*, DWORD, DWORD*) { + PRINT(L"Called: CreateThread\n"); + return reinterpret_cast(1); +} + +DWORD WaitForSingleObject(HANDLE, DWORD) { + PRINT(L"Called: WaitForSingleObject\n"); + return 0; +} + +// --- Timing --- +static unsigned long long tsc_freq = 0; + +static void init_tsc_freq() { + int cpuInfo[4] = {0}; + __cpuid(cpuInfo, 0x15); + + if (cpuInfo[0] && cpuInfo[1]) { + // leaf 0x15 gives: eax = denom, ebx = numer, ecx = crystal Hz + unsigned eax = cpuInfo[0]; // denom + unsigned ebx = cpuInfo[1]; // numer + unsigned ecx = cpuInfo[2]; // crystal freq Hz + + if (ecx != 0) { + tsc_freq = (unsigned long long)ecx * ebx / eax; + return; + } + } + + // fallback: CPUID 0x16 (nominal core frequency MHz) + __cpuid(cpuInfo, 0x16); + if (cpuInfo[0]) { + tsc_freq = (unsigned long long)cpuInfo[0] * 1000000ULL; + } +} + +BOOL QueryPerformanceCounter(LARGE_INTEGER *li) { + if (!tsc_freq) init_tsc_freq(); + unsigned long long tsc = __rdtsc(); + // convert to microseconds + li->QuadPart = (tsc * 1000000ULL) / tsc_freq; + return TRUE; +} + +BOOL QueryPerformanceFrequency(LARGE_INTEGER *li) { + if (!tsc_freq) init_tsc_freq(); + // frequency in Hz (ticks per second) + li->QuadPart = 1000000ULL; // since we convert to µs above + return TRUE; +} + +DWORD GetTickCount() { + LARGE_INTEGER counter; + QueryPerformanceCounter(&counter); + return (DWORD)(counter.QuadPart / 1000ULL); // ms +} + +// --- Module / File --- +HMODULE GetModuleHandleA(LPCSTR name) { + PRINT(L"Called: GetModuleHandleA with name: %a\n", name); + return reinterpret_cast(1); +} + +FARPROC GetProcAddress(HMODULE, LPCSTR func) { + PRINT(L"Called: GetProcAddress with string: %a\n", func); + return nullptr; +} + +HMODULE LoadLibraryA(LPCSTR) { + PRINT(L"Called: LoadLibraryA\n"); + return reinterpret_cast(1); +} + +// --- Process --- +DWORD GetCurrentProcessId() { + PRINT(L"Called: GetCurrentProcessId\n"); + return 1; +} + +void ExitProcess(UINT uExitCode) { + PRINT(L"Called: ExitProcess\n"); + while(1); // halt +} + +BOOL InitializeCriticalSectionAndSpinCount(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount) { + PRINT(L"Called: InitializeCriticalSectionAndSpinCount\n"); + return TRUE; +} + +DWORD GetSystemDirectoryA(LPSTR lpBuffer, DWORD uSize) { + PRINT(L"Called: GetSystemDirectoryA\n"); + if (lpBuffer && uSize > 0) { + *lpBuffer = '\0'; + return 1; + } + return 0; +} + +DWORD GetWindowsDirectoryA(LPSTR lpBuffer, DWORD uSize) { + PRINT(L"Called: GetWindowsDirectoryA\n"); + if (lpBuffer && uSize > 0) { + *lpBuffer = '\0'; + return 1; + } + return 0; +} + +DWORD GetModuleFileNameA(HMODULE hModule, LPSTR lpFilename, DWORD nSize) { + PRINT(L"Called: GetModuleFileNameA\n"); + if (lpFilename && nSize > 0) { + *lpFilename = '\0'; + return 1; + } + return 0; +} + +void Sleep(DWORD dwMilliseconds) { + PRINT(L"Called: Sleep\n"); + UINTN microseconds = (UINTN)dwMilliseconds * 1000; + BS->Stall(microseconds); +} + +DWORD SetErrorMode(DWORD uMode) { + PRINT(L"Called: SetErrorMode\n"); + return 0; +} + +DWORD GetEnvironmentVariableA(LPCTSTR lpName, LPSTR lpBuffer, DWORD nSize) { + PRINT(L"Called: GetEnvironmentVariableA\n"); + if (lpBuffer && nSize > 0) lpBuffer[0] = 0; + return 1; +} + +BOOL CloseHandle(HANDLE hObject) { + PRINT(L"Called: CloseHandle\n"); + return TRUE; +} + +DWORD GetLastError() { + PRINT(L"Called: GetLastError\n"); + return 0; +} + +DWORD GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh) { + PRINT(L"Called: GetFileSize\n"); + if (lpFileSizeHigh) *lpFileSizeHigh = 0; + return 0; +} + +HANDLE CreateFileA(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) { + PRINT(L"Called: CreateFileA\n"); + return NULL; +} + +BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped) { + PRINT(L"Called: ReadFile\n"); + *lpNumberOfBytesRead = 0; + return TRUE; +} + +DWORD SetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod) { + PRINT(L"Called: SetFilePointer\n"); + return 0; +} + +BOOL FreeLibrary(HMODULE hLibModule) { + PRINT(L"Called: FreeLibrary\n"); + return TRUE; +} + +int GetThreadPriority(HANDLE hThread) { + PRINT(L"Called: GetThreadPriority\n"); + return 0; +} + +PVOID RemoveVectoredExceptionHandler(PVOID Handle) { + PRINT(L"Called: RemoveVectoredExceptionHandler\n"); + return NULL; +} + +void RaiseException(DWORD dwExceptionCode, DWORD dwExceptionFlags, DWORD nNumberOfArguments, const ULONG_PTR* lpArguments) { + PRINT(L"Called: RaiseException\n"); + return; +} + +PVOID AddVectoredExceptionHandler(ULONG FirstHandler, PVECTORED_EXCEPTION_HANDLER VectoredHandler) { + PRINT(L"Called: AddVectoredExceptionHandler\n"); + return NULL; +} + +DWORD_PTR SetThreadAffinityMask(HANDLE hThread, DWORD_PTR dwThreadAffinityMask) { + PRINT(L"Called: SetThreadAffinityMask\n"); + return 1; +} + +DWORD ResumeThread(HANDLE hThread) { + PRINT(L"Called: ResumeThread\n"); + return 1; +} + +BOOL SetThreadPriority(HANDLE hThread, int nPriority) { + PRINT(L"Called: SetThreadPriority\n"); + return TRUE; +} + +void InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection) { + PRINT(L"Called: InitializeCriticalSection\n"); +} + +void DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection) { + PRINT(L"Called: DeleteCriticalSection\n"); +} + +void EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection) { + PRINT(L"Called: EnterCriticalSection\n"); +} + +void LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection) { + PRINT(L"Called: LeaveCriticalSection\n"); +} + +DWORD GetCurrentThreadId() { + PRINT(L"Called: GetCurrentThreadId\n"); + return 1; +} + +HANDLE CreateMutexA(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCTSTR lpName) { + PRINT(L"Called: CreateMutexA with name: lpName: %a\n", lpName); + return reinterpret_cast(1); +} + +BOOL ReleaseMutex(HANDLE hMutex) { + PRINT(L"Called: ReleaseMutex\n"); + return TRUE; +} + +HANDLE CreateSemaphoreA(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCTSTR lpName) { + PRINT(L"Called: CreateSemaphoreA with name: lpName: %a\n", lpName); + return reinterpret_cast(1); +} + +BOOL ReleaseSemaphore(HANDLE hSemaphore, LONG lReleaseCount, LPLONG lpPreviousCount) { + PRINT(L"Called: ReleaseSemaphore\n"); + if (lpPreviousCount) *lpPreviousCount = 0; + return TRUE; +} + +BOOL TerminateProcess(HANDLE hProcess, UINT uExitCode) { + PRINT(L"Called: TerminateProcess\n"); + return TRUE; +} + +HANDLE GetCurrentProcess() { + PRINT(L"Called: GetCurrentProcess\n"); + return reinterpret_cast(1); +} + +LPTOP_LEVEL_EXCEPTION_FILTER UnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter) { + PRINT(L"Called: UnhandledExceptionFilter\n"); + return NULL; +} + +LPTOP_LEVEL_EXCEPTION_FILTER SetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter) { + PRINT(L"Called: SetUnhandledExceptionFilter\n"); + return NULL; +} + +BOOL IsDebuggerPresent() { + PRINT(L"Called: IsDebuggerPresent\n"); + return FALSE; +} + +PVOID RtlVirtualUnwind(ULONG HandlerType, ULONG64 ImageBase, ULONG64 ControlPc, PRUNTIME_FUNCTION FunctionEntry, PCONTEXT ContextRecord, PVOID* HandlerData, PULONG64 EstablisherFrame, PCONTEXT ContextRecord2) { + PRINT(L"Called: RtlVirtualUnwind\n"); + return NULL; +} + +PRUNTIME_FUNCTION RtlLookupFunctionEntry(ULONG64 ControlPc, PULONG64 ImageBase, PVOID HistoryTable) { + PRINT(L"Called: RtlLookupFunctionEntry\n"); + return NULL; +} + +void RtlCaptureContext(PCONTEXT ContextRecord) { + PRINT(L"Called: RtlCaptureContext\n"); +} + +void RtlUnwindEx(PVOID TargetFrame, PVOID TargetIp, PVOID ExceptionRecord, PVOID ReturnValue, PCONTEXT ContextRecord, PVOID HistoryTable) { + PRINT(L"Called: RtlUnwindEx\n"); +} + +BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped) { + PRINT(L"Called: WriteFile\n"); + if (lpNumberOfBytesWritten) *lpNumberOfBytesWritten = 0; + return TRUE; +} + +HMODULE GetModuleHandleW(LPCWSTR lpModuleName) { + PRINT(L"Called: GetModuleHandleW with name: %s\n", lpModuleName); + return NULL; +} + +int SetHandleCount(int n) { + PRINT(L"Called: SetHandleCount\n"); + return 0; +} + +HANDLE GetStdHandle(DWORD nStdHandle) { + PRINT(L"Called: GetStdHandle\n"); + return reinterpret_cast(1); +} + +DWORD GetFileType(HANDLE hFile) { + PRINT(L"Called: GetFileType\n"); + return 0; +} + +void GetStartupInfoA(LPSTARTUPINFOA lpStartupInfo) { + PRINT(L"Called: GetStartupInfoA\n"); +} + +LPCH GetEnvironmentStrings() { + PRINT(L"Called: GetEnvironmentStrings\n"); + return NULL; +} + +BOOL FreeEnvironmentStringsA(LPCH lpszString) { + PRINT(L"Called: FreeEnvironmentStringsA\n"); + return TRUE; +} + +LPWCH GetEnvironmentStringsW() { + PRINT(L"Called: GetEnvironmentStringsW\n"); + return NULL; +} + +BOOL FreeEnvironmentStringsW(LPWCH lpszString) { + PRINT(L"Called: FreeEnvironmentStringsW\n"); + return TRUE; +} + +void GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime) { + PRINT(L"Called: GetSystemTimeAsFileTime\n"); +} + +int GetACP() { + PRINT(L"Called: GetACP\n"); + return 0; +} + +BOOL GetCPInfo(UINT CodePage, LPCPINFO lpCPInfo) { + PRINT(L"Called: GetCPInfo\n"); + return FALSE; +} + +UINT GetOEMCP() { + PRINT(L"Called: GetOEMCP\n"); + return 0; +} + +BOOL IsValidCodePage(UINT CodePage) { + PRINT(L"Called: IsValidCodePage\n"); + return FALSE; +} + +int WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar) { + PRINT(L"Called: WideCharToMultiByte\n"); + if (lpWideCharStr == NULL || cchWideChar <= 0) { + return 0; // Return 0 for invalid input + } + + int convertedCount = 0; + while (*lpWideCharStr != '\0' && convertedCount < cchWideChar) { + *lpMultiByteStr = (char)*lpWideCharStr; + lpMultiByteStr++; + lpWideCharStr++; + convertedCount++; + } + + // Null-terminate the string if there is space + if (convertedCount < cchWideChar) { + *lpMultiByteStr = '\0'; + } + + return convertedCount; +} + +int LCMapStringA(LCID Locale, DWORD dwMapFlags, LPCSTR lpSrcStr, int cchSrc, LPSTR lpDestStr, int cchDest) { + PRINT(L"Called: LCMapStringA\n"); + return 0; +} + +int LCMapStringW(LCID Locale, DWORD dwMapFlags, LPCWSTR lpSrcStr, int cchSrc, LPWSTR lpDestStr, int cchDest) { + PRINT(L"Called: LCMapStringW\n"); + return 0; +} + +BOOL GetStringTypeA(LCID Locale, DWORD dwInfoType, LPCSTR lpSrcStr, int cchSrc, LPWORD lpCharType) { + PRINT(L"Called: GetStringTypeA\n"); + return FALSE; +} + +BOOL GetStringTypeW(DWORD dwInfoType, LPCWSTR lpSrcStr, int cchSrc, LPWORD lpCharType) { + PRINT(L"Called: GetStringTypeW\n"); + return FALSE; +} + +int GetLocaleInfoA(LCID Locale, LCTYPE LCType, LPSTR lpLCData, int cchData) { + PRINT(L"Called: GetLocaleInfoA\n"); + *lpLCData = '\0'; + return 1; +} + +BOOL FlsSetValue(DWORD dwFlsIndex, PVOID lpFlsData) { + PRINT(L"Called: FlsSetValue\n"); + return TRUE; +} + +PSTR GetCommandLineA() { + PRINT(L"Called: GetCommandLineA\n"); + return NULL; +} + +LPVOID EncodePointer(LPVOID Ptr) { + PRINT(L"Called: EncodePointer\n"); + return Ptr; +} + +LPVOID DecodePointer(LPVOID Ptr) { + PRINT(L"Called: DecodePointer\n"); + return Ptr; +} + +BOOL FlsGetValue(DWORD dwFlsIndex) { + PRINT(L"Called: FlsGetValue\n"); + return NULL; +} + +BOOL FlsFree(DWORD dwFlsIndex) { + PRINT(L"Called: FlsFree\n"); + return TRUE; +} + +void SetLastError(DWORD dwErrCode) { + PRINT(L"Called: SetLastError\n"); +} + +DWORD FlsAlloc(PFLS_CALLBACK_FUNCTION lpCallback) { + PRINT(L"Called: FlsAlloc\n"); + return 0; +} + +BOOL HeapSetInformation(HANDLE HeapHandle, HEAP_INFORMATION_CLASS HeapInformationClass, PVOID HeapInformation, SIZE_T HeapInformationLength) { + PRINT(L"Called: HeapSetInformation\n"); + return TRUE; +} + +void GetSystemInfo(LPSYSTEM_INFO lpSystemInfo) { + PRINT(L"Called: GetSystemInfo\n"); + if (lpSystemInfo) { + // Fill the struct with dummy values consistent with an x64 environment + lpSystemInfo->DUMMYUNIONNAME.DUMMYSTRUCTNAME.wProcessorArchitecture = 9; // PROCESSOR_ARCHITECTURE_AMD64 + lpSystemInfo->dwPageSize = 0x1000; // 4 KB page size + lpSystemInfo->lpMinimumApplicationAddress = (LPVOID)0x10000; + lpSystemInfo->lpMaximumApplicationAddress = (LPVOID)0x7FFFFFFFFFFFFFFF; + lpSystemInfo->dwActiveProcessorMask = 1; + lpSystemInfo->dwNumberOfProcessors = 1; + lpSystemInfo->dwProcessorType = 8664; // PROCESSOR_AMD_X8664 + lpSystemInfo->dwAllocationGranularity = 0x10000; // 64 KB + lpSystemInfo->wProcessorLevel = 6; + lpSystemInfo->wProcessorRevision = 0; + } +} + +int MultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar) { + PRINT(L"Called: MultiByteToWideChar\n"); + if (lpMultiByteStr == NULL || cchWideChar <= 0) { + return 0; // Return 0 for invalid input + } + + int convertedCount = 0; + while (*lpMultiByteStr != '\0' && convertedCount < cchWideChar) { + *lpWideCharStr = (wchar_t)*lpMultiByteStr; + lpMultiByteStr++; + lpWideCharStr++; + convertedCount++; + } + + // Null-terminate the string if there is space + if (convertedCount < cchWideChar) { + *lpWideCharStr = L'\0'; + } + + return convertedCount; +} + +extern int stricmp(const char *s1, const char *s2); + +void* ResolveKernel32(const char* functionName) { + if (stricmp(functionName, "HeapCreate") == 0) { + return HeapCreate; + } else if (stricmp(functionName, "HeapDestroy") == 0) { + return HeapDestroy; + } else if (stricmp(functionName, "HeapAlloc") == 0) { + return HeapAlloc; + } else if (stricmp(functionName, "HeapFree") == 0) { + return HeapFree; + } else if (stricmp(functionName, "HeapReAlloc") == 0) { + return HeapReAlloc; + } else if (stricmp(functionName, "HeapSize") == 0) { + return HeapSize; + } else if (stricmp(functionName, "GetCurrentThreadId") == 0) { + return GetCurrentThreadId; + } else if (stricmp(functionName, "GetCurrentThread") == 0) { + return GetCurrentThread; + } else if (stricmp(functionName, "CreateThread") == 0) { + return CreateThread; + } else if (stricmp(functionName, "WaitForSingleObject") == 0) { + return WaitForSingleObject; + } else if (stricmp(functionName, "CloseHandle") == 0) { + return CloseHandle; + } else if (stricmp(functionName, "QueryPerformanceCounter") == 0) { + return QueryPerformanceCounter; + } else if (stricmp(functionName, "QueryPerformanceFrequency") == 0) { + return QueryPerformanceFrequency; + } else if (stricmp(functionName, "GetTickCount") == 0) { + return GetTickCount; + } else if (stricmp(functionName, "GetModuleHandleA") == 0) { + return GetModuleHandleA; + } else if (stricmp(functionName, "GetProcAddress") == 0) { + return GetProcAddress; + } else if (stricmp(functionName, "LoadLibraryA") == 0) { + return LoadLibraryA; + } else if (stricmp(functionName, "GetCurrentProcessId") == 0) { + return GetCurrentProcessId; + } else if (stricmp(functionName, "GetCurrentProcess") == 0) { + return GetCurrentProcess; + } else if (stricmp(functionName, "ExitProcess") == 0) { + return ExitProcess; + } else if (stricmp(functionName, "InitializeCriticalSectionAndSpinCount") == 0) { + return InitializeCriticalSectionAndSpinCount; + } else if (stricmp(functionName, "GetSystemDirectoryA") == 0) { + return GetSystemDirectoryA; + } else if (stricmp(functionName, "GetWindowsDirectoryA") == 0) { + return GetWindowsDirectoryA; + } else if (stricmp(functionName, "GetModuleFileNameA") == 0) { + return GetModuleFileNameA; + } else if (stricmp(functionName, "Sleep") == 0) { + return Sleep; + } else if (stricmp(functionName, "SetErrorMode") == 0) { + return SetErrorMode; + } else if (stricmp(functionName, "GetEnvironmentVariableA") == 0) { + return GetEnvironmentVariableA; + } else if (stricmp(functionName, "CloseHandle") == 0) { + return CloseHandle; + } else if (stricmp(functionName, "GetLastError") == 0) { + return GetLastError; + } else if (stricmp(functionName, "GetFileSize") == 0) { + return GetFileSize; + } else if (stricmp(functionName, "CreateFileA") == 0) { + return CreateFileA; + } else if (stricmp(functionName, "ReadFile") == 0) { + return ReadFile; + } else if (stricmp(functionName, "SetFilePointer") == 0) { + return SetFilePointer; + } else if (stricmp(functionName, "FreeLibrary") == 0) { + return FreeLibrary; + } else if (stricmp(functionName, "GetThreadPriority") == 0) { + return GetThreadPriority; + } else if (stricmp(functionName, "RemoveVectoredExceptionHandler") == 0) { + return RemoveVectoredExceptionHandler; + } else if (stricmp(functionName, "RaiseException") == 0) { + return RaiseException; + } else if (stricmp(functionName, "AddVectoredExceptionHandler") == 0) { + return AddVectoredExceptionHandler; + } else if (stricmp(functionName, "SetThreadAffinityMask") == 0) { + return SetThreadAffinityMask; + } else if (stricmp(functionName, "ResumeThread") == 0) { + return ResumeThread; + } else if (stricmp(functionName, "SetThreadPriority") == 0) { + return SetThreadPriority; + } else if (stricmp(functionName, "InitializeCriticalSection") == 0) { + return InitializeCriticalSection; + } else if (stricmp(functionName, "DeleteCriticalSection") == 0) { + return DeleteCriticalSection; + } else if (stricmp(functionName, "EnterCriticalSection") == 0) { + return EnterCriticalSection; + } else if (stricmp(functionName, "LeaveCriticalSection") == 0) { + return LeaveCriticalSection; + } else if (stricmp(functionName, "GetCurrentThreadId") == 0) { + return GetCurrentThreadId; + } else if (stricmp(functionName, "CreateMutexA") == 0) { + return CreateMutexA; + } else if (stricmp(functionName, "ReleaseMutex") == 0) { + return ReleaseMutex; + } else if (stricmp(functionName, "CreateSemaphoreA") == 0) { + return CreateSemaphoreA; + } else if (stricmp(functionName, "ReleaseSemaphore") == 0) { + return ReleaseSemaphore; + } else if (stricmp(functionName, "TerminateProcess") == 0) { + return TerminateProcess; + } else if (stricmp(functionName, "GetCurrentProcess") == 0) { + return GetCurrentProcess; + } else if (stricmp(functionName, "UnhandledExceptionFilter") == 0) { + return UnhandledExceptionFilter; + } else if (stricmp(functionName, "SetUnhandledExceptionFilter") == 0) { + return SetUnhandledExceptionFilter; + } else if (stricmp(functionName, "IsDebuggerPresent") == 0) { + return IsDebuggerPresent; + } else if (stricmp(functionName, "RtlVirtualUnwind") == 0) { + return RtlVirtualUnwind; + } else if (stricmp(functionName, "RtlLookupFunctionEntry") == 0) { + return RtlLookupFunctionEntry; + } else if (stricmp(functionName, "RtlCaptureContext") == 0) { + return RtlCaptureContext; + } else if (stricmp(functionName, "RtlUnwindEx") == 0) { + return RtlUnwindEx; + } else if (stricmp(functionName, "WriteFile") == 0) { + return WriteFile; + } else if (stricmp(functionName, "GetModuleHandleW") == 0) { + return GetModuleHandleW; + } else if (stricmp(functionName, "SetHandleCount") == 0) { + return SetHandleCount; + } else if (stricmp(functionName, "GetStdHandle") == 0) { + return GetStdHandle; + } else if (stricmp(functionName, "GetFileType") == 0) { + return GetFileType; + } else if (stricmp(functionName, "GetStartupInfoA") == 0) { + return GetStartupInfoA; + } else if (stricmp(functionName, "GetEnvironmentStrings") == 0) { + return GetEnvironmentStrings; + } else if (stricmp(functionName, "FreeEnvironmentStringsA") == 0) { + return FreeEnvironmentStringsA; + } else if (stricmp(functionName, "GetEnvironmentStringsW") == 0) { + return GetEnvironmentStringsW; + } else if (stricmp(functionName, "FreeEnvironmentStringsW") == 0) { + return FreeEnvironmentStringsW; + } else if (stricmp(functionName, "GetSystemTimeAsFileTime") == 0) { + return GetSystemTimeAsFileTime; + } else if (stricmp(functionName, "GetACP") == 0) { + return GetACP; + } else if (stricmp(functionName, "GetCPInfo") == 0) { + return GetCPInfo; + } else if (stricmp(functionName, "GetOEMCP") == 0) { + return GetOEMCP; + } else if (stricmp(functionName, "IsValidCodePage") == 0) { + return IsValidCodePage; + } else if (stricmp(functionName, "WideCharToMultiByte") == 0) { + return WideCharToMultiByte; + } else if (stricmp(functionName, "LCMapStringA") == 0) { + return LCMapStringA; + } else if (stricmp(functionName, "LCMapStringW") == 0) { + return LCMapStringW; + } else if (stricmp(functionName, "GetStringTypeA") == 0) { + return GetStringTypeA; + } else if (stricmp(functionName, "GetStringTypeW") == 0) { + return GetStringTypeW; + } else if (stricmp(functionName, "GetLocaleInfoA") == 0) { + return GetLocaleInfoA; + } else if (stricmp(functionName, "FlsSetValue") == 0) { + return FlsSetValue; + } else if (stricmp(functionName, "GetCommandLineA") == 0) { + return GetCommandLineA; + } else if (stricmp(functionName, "EncodePointer") == 0) { + return EncodePointer; + } else if (stricmp(functionName, "DecodePointer") == 0) { + return DecodePointer; + } else if (stricmp(functionName, "FlsGetValue") == 0) { + return FlsGetValue; + } else if (stricmp(functionName, "FlsFree") == 0) { + return FlsFree; + } else if (stricmp(functionName, "SetLastError") == 0) { + return SetLastError; + } else if (stricmp(functionName, "FlsAlloc") == 0) { + return FlsAlloc; + } else if (stricmp(functionName, "GetSystemInfo") == 0) { + return GetSystemInfo; + } else if (stricmp(functionName, "HeapSetInformation") == 0) { + return HeapSetInformation; + } else if (stricmp(functionName, "MultiByteToWideChar") == 0) { + return MultiByteToWideChar; + } + + Print(L"Unknown function: %a\n", functionName); + return NULL; } diff --git a/kernel32.dll b/kernel32.dll deleted file mode 100644 index 9f01405..0000000 Binary files a/kernel32.dll and /dev/null differ diff --git a/kernel32.exp b/kernel32.exp deleted file mode 100644 index 9fa5471..0000000 Binary files a/kernel32.exp and /dev/null differ diff --git a/kernel32.lib b/kernel32.lib deleted file mode 100644 index 3a59495..0000000 Binary files a/kernel32.lib and /dev/null differ diff --git a/kernel32.obj b/kernel32.obj deleted file mode 100644 index fe697b2..0000000 Binary files a/kernel32.obj and /dev/null differ diff --git a/main.cpp b/main.cpp index dd5ddea..cdc0f01 100644 --- a/main.cpp +++ b/main.cpp @@ -1,7 +1,14 @@ +#include +#include +#include +#define malloc AllocatePool +#define free FreePool +#include +#include #include "bink.h" -#include -#include -#include +#include "print.h" + +#pragma region // Macro to define function pointer and global variable #define DECL_FN(ret, name, args, ptr) typedef ret (__cdecl *name##_t) args; name##_t p##name = NULL; @@ -64,187 +71,701 @@ DECL_FN(BINKSNDOPEN, BinkOpenWaveOut, (UINTa param), *) DECL_FN(BINKSNDOPEN, BinkOpenXAudio2, (UINTa param), *) DECL_FN(void, BinkSetMemory, (BINKMEMALLOC a, BINKMEMFREE f), *) -HMODULE dll = NULL; +#pragma endregion +#pragma region -int LoadBinkDLL(void) { - if (dll) return 1; - dll = LoadLibraryExA("bink2w64.dll", 0, 0); - if (!dll) return 0; +EFI_GRAPHICS_OUTPUT_PROTOCOL* gop; +EFI_GRAPHICS_OUTPUT_BLT_PIXEL* framebuffer; +EFI_GRAPHICS_OUTPUT_MODE_INFORMATION* mode_info; - pBinkLogoAddress = (BinkLogoAddress_t)GetProcAddress(dll, "BinkLogoAddress"); - pBinkSetError = (BinkSetError_t)GetProcAddress(dll, "BinkSetError"); - pBinkGetError = (BinkGetError_t)GetProcAddress(dll, "BinkGetError"); - pBinkOpen = (BinkOpen_t)GetProcAddress(dll, "BinkOpen"); - pBinkOpenWithOptions = (BinkOpenWithOptions_t)GetProcAddress(dll, "BinkOpenWithOptions"); - pBinkGetFrameBuffersInfo = (BinkGetFrameBuffersInfo_t)GetProcAddress(dll, "BinkGetFrameBuffersInfo"); - pBinkRegisterFrameBuffers = (BinkRegisterFrameBuffers_t)GetProcAddress(dll, "BinkRegisterFrameBuffers"); - pBinkDoFrame = (BinkDoFrame_t)GetProcAddress(dll, "BinkDoFrame"); - pBinkDoFramePlane = (BinkDoFramePlane_t)GetProcAddress(dll, "BinkDoFramePlane"); - pBinkNextFrame = (BinkNextFrame_t)GetProcAddress(dll, "BinkNextFrame"); - pBinkWait = (BinkWait_t)GetProcAddress(dll, "BinkWait"); - pBinkClose = (BinkClose_t)GetProcAddress(dll, "BinkClose"); - pBinkPause = (BinkPause_t)GetProcAddress(dll, "BinkPause"); - pBinkCopyToBuffer = (BinkCopyToBuffer_t)GetProcAddress(dll, "BinkCopyToBuffer"); - pBinkCopyToBufferRect = (BinkCopyToBufferRect_t)GetProcAddress(dll, "BinkCopyToBufferRect"); - pBinkGetRects = (BinkGetRects_t)GetProcAddress(dll, "BinkGetRects"); - pBinkGoto = (BinkGoto_t)GetProcAddress(dll, "BinkGoto"); - pBinkGetKeyFrame = (BinkGetKeyFrame_t)GetProcAddress(dll, "BinkGetKeyFrame"); - pBinkFreeGlobals = (BinkFreeGlobals_t)GetProcAddress(dll, "BinkFreeGlobals"); - pBinkGetPlatformInfo = (BinkGetPlatformInfo_t)GetProcAddress(dll, "BinkGetPlatformInfo"); - pBinkRegisterGPUDataBuffers = (BinkRegisterGPUDataBuffers_t)GetProcAddress(dll, "BinkRegisterGPUDataBuffers"); - pBinkGetGPUDataBuffersInfo = (BinkGetGPUDataBuffersInfo_t)GetProcAddress(dll, "BinkGetGPUDataBuffersInfo"); - pBinkSetVideoOnOff = (BinkSetVideoOnOff_t)GetProcAddress(dll, "BinkSetVideoOnOff"); - pBinkSetSoundOnOff = (BinkSetSoundOnOff_t)GetProcAddress(dll, "BinkSetSoundOnOff"); - pBinkSetVolume = (BinkSetVolume_t)GetProcAddress(dll, "BinkSetVolume"); - pBinkSetPan = (BinkSetPan_t)GetProcAddress(dll, "BinkSetPan"); - pBinkSetSpeakerVolumes = (BinkSetSpeakerVolumes_t)GetProcAddress(dll, "BinkSetSpeakerVolumes"); - pBinkService = (BinkService_t)GetProcAddress(dll, "BinkService"); - pBinkShouldSkip = (BinkShouldSkip_t)GetProcAddress(dll, "BinkShouldSkip"); - pBinkControlBackgroundIO = (BinkControlBackgroundIO_t)GetProcAddress(dll, "BinkControlBackgroundIO"); - pBinkSetWillLoop = (BinkSetWillLoop_t)GetProcAddress(dll, "BinkSetWillLoop"); - pBinkStartAsyncThread = (BinkStartAsyncThread_t)GetProcAddress(dll, "BinkStartAsyncThread"); - pBinkDoFrameAsync = (BinkDoFrameAsync_t)GetProcAddress(dll, "BinkDoFrameAsync"); - pBinkDoFrameAsyncMulti = (BinkDoFrameAsyncMulti_t)GetProcAddress(dll, "BinkDoFrameAsyncMulti"); - pBinkDoFrameAsyncWait = (BinkDoFrameAsyncWait_t)GetProcAddress(dll, "BinkDoFrameAsyncWait"); - pBinkRequestStopAsyncThread = (BinkRequestStopAsyncThread_t)GetProcAddress(dll, "BinkRequestStopAsyncThread"); - pBinkWaitStopAsyncThread = (BinkWaitStopAsyncThread_t)GetProcAddress(dll, "BinkWaitStopAsyncThread"); - pBinkOpenTrack = (BinkOpenTrack_t)GetProcAddress(dll, "BinkOpenTrack"); - pBinkCloseTrack = (BinkCloseTrack_t)GetProcAddress(dll, "BinkCloseTrack"); - pBinkGetTrackData = (BinkGetTrackData_t)GetProcAddress(dll, "BinkGetTrackData"); - pBinkGetTrackType = (BinkGetTrackType_t)GetProcAddress(dll, "BinkGetTrackType"); - pBinkGetTrackMaxSize = (BinkGetTrackMaxSize_t)GetProcAddress(dll, "BinkGetTrackMaxSize"); - pBinkGetTrackID = (BinkGetTrackID_t)GetProcAddress(dll, "BinkGetTrackID"); - pBinkGetSummary = (BinkGetSummary_t)GetProcAddress(dll, "BinkGetSummary"); - pBinkGetRealtime = (BinkGetRealtime_t)GetProcAddress(dll, "BinkGetRealtime"); - pBinkSetFileOffset = (BinkSetFileOffset_t)GetProcAddress(dll, "BinkSetFileOffset"); - pBinkSetSoundTrack = (BinkSetSoundTrack_t)GetProcAddress(dll, "BinkSetSoundTrack"); - pBinkSetIO = (BinkSetIO_t)GetProcAddress(dll, "BinkSetIO"); - pBinkSetFrameRate = (BinkSetFrameRate_t)GetProcAddress(dll, "BinkSetFrameRate"); - pBinkSetSimulate = (BinkSetSimulate_t)GetProcAddress(dll, "BinkSetSimulate"); - pBinkSetIOSize = (BinkSetIOSize_t)GetProcAddress(dll, "BinkSetIOSize"); - pBinkSetSoundSystem = (BinkSetSoundSystem_t)GetProcAddress(dll, "BinkSetSoundSystem"); - pBinkSetSoundSystem2 = (BinkSetSoundSystem2_t)GetProcAddress(dll, "BinkSetSoundSystem2"); - pBinkOpenDirectSound = (BinkOpenDirectSound_t)GetProcAddress(dll, "BinkOpenDirectSound"); - pBinkOpenWaveOut = (BinkOpenWaveOut_t)GetProcAddress(dll, "BinkOpenWaveOut"); - pBinkOpenXAudio2 = (BinkOpenXAudio2_t)GetProcAddress(dll, "BinkOpenXAudio2"); - pBinkSetMemory = (BinkSetMemory_t)GetProcAddress(dll, "BinkSetMemory"); +EFI_STATUS InitializeGop() { + EFI_STATUS Status; - return 1; + // 1. Locate the Graphics Output Protocol + Status = LibLocateProtocol(&gEfiGraphicsOutputProtocolGuid, (VOID**)&gop); + if (EFI_ERROR(Status)) { + Print(L"Failed to locate Graphics Output Protocol: %r\n", Status); + return Status; + } + + // 2. Get framebuffer information + mode_info = gop->Mode->Info; + framebuffer = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL*)gop->Mode->FrameBufferBase; // yeah yeah blah blah + + return EFI_SUCCESS; } -char* read_binary_file_to_memory(const char* filename, size_t* file_size) { - FILE* file = fopen(filename, "rb"); // Use "rb" for binary mode - if (file == NULL) { - perror("Failed to open file"); - return NULL; - } +EFI_FILE_HANDLE GetVolume(EFI_HANDLE ImageHandle) +{ + EFI_LOADED_IMAGE* loaded_image = NULL; /* image interface */ + EFI_GUID lipGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; /* image interface GUID */ + EFI_FILE_IO_INTERFACE* IOVolume; /* file system interface */ + EFI_GUID fsGuid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; /* file system interface GUID */ + EFI_FILE_HANDLE Volume; /* the volume's interface */ - // Get file size - fseek(file, 0, SEEK_END); - long size = ftell(file); - rewind(file); + /* get the loaded image protocol interface for our "image" */ + BS->HandleProtocol(ImageHandle, &lipGuid, (void**)&loaded_image); - if (size < 0) { - perror("Failed to determine file size"); - fclose(file); - return NULL; - } - - // Allocate memory. Note: no need for a null terminator since it's not a string. - char* buffer = (char*)malloc(size); - if (buffer == NULL) { - perror("Memory allocation failed"); - fclose(file); - return NULL; - } - - // Read file into buffer - size_t bytes_read = fread(buffer, 1, size, file); - if (bytes_read != (size_t)size) { - perror("Failed to read file"); - free(buffer); - fclose(file); - return NULL; - } - - fclose(file); - - if (file_size) { - *file_size = (size_t)size; - } - - return buffer; + /* get the volume handle */ + BS->HandleProtocol(loaded_image->DeviceHandle, &fsGuid, (VOID**)&IOVolume); + IOVolume->OpenVolume(IOVolume, &Volume); + return Volume; } -int main() { - if (!LoadBinkDLL()) { - printf("we fucked up\n"); +UINT64 FileSize(EFI_FILE_HANDLE FileHandle) { + EFI_FILE_INFO* FileInfo = LibFileInfo(FileHandle); + UINT64 size = FileInfo->FileSize; + FreePool(FileInfo); + return size; +} + +void* LoadFile(EFI_FILE_HANDLE volume, const wchar_t* filename) { + EFI_FILE_HANDLE file; + EFI_STATUS file_loading_status = volume->Open(volume, &file, (wchar_t*)filename, + EFI_FILE_MODE_READ, 0); + if (EFI_ERROR(file_loading_status)) { + Print(L"Failed to open file: %r\n", file_loading_status); + return NULL; + } + + // Get the file size + UINT64 file_size = FileSize(file); + if (file_size == 0) { + file->Close(file); + return NULL; + } + + VOID* file_buffer = AllocatePool(file_size); + if (!file_buffer) { return NULL; } + + SetMem(file_buffer, file_size, 0); + + // Read the file into the allocated buffer + UINTN read_size = (UINTN)file_size; + file_loading_status = file->Read(file, &read_size, file_buffer); + file->Close(file); + + if (EFI_ERROR(file_loading_status)) { + Print(L"Failed to read file: %r\n", file_loading_status); + // Free the allocated memory if the read fails + FreePool(file_buffer); + return NULL; + } + + if (read_size != file_size) { + Print(L"Read size mismatch: expected %llu, got %llu\n", file_size, read_size); + FreePool(file_buffer); + return NULL; + } + + return file_buffer; +} + +#pragma endregion +#pragma region + +#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b +#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 +#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 +#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 +#define IMAGE_ORDINAL_FLAG64 0x8000000000000000ULL + +#pragma pack(push, 1) +typedef struct IMAGE_OPTIONAL_HEADER64 { + uint16_t Magic; + uint8_t MajorLinkerVersion; + uint8_t MinorLinkerVersion; + uint32_t SizeOfCode; + uint32_t SizeOfInitializedData; + uint32_t SizeOfUninitializedData; + uint32_t AddressOfEntryPoint; + uint32_t BaseOfCode; + uint64_t ImageBase; + uint32_t SectionAlignment; + uint32_t FileAlignment; + uint16_t MajorOperatingSystemVersion; + uint16_t MinorOperatingSystemVersion; + uint16_t MajorImageVersion; + uint16_t MinorImageVersion; + uint16_t MajorSubsystemVersion; + uint16_t MinorSubsystemVersion; + uint32_t Win32VersionValue; + uint32_t SizeOfImage; + uint32_t SizeOfHeaders; + uint32_t CheckSum; + uint16_t Subsystem; + uint16_t DllCharacteristics; + uint64_t SizeOfStackReserve; + uint64_t SizeOfStackCommit; + uint64_t SizeOfHeapReserve; + uint64_t SizeOfHeapCommit; + uint32_t LoaderFlags; + uint32_t NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; +} __attribute__((packed)) IMAGE_OPTIONAL_HEADER64; + +typedef struct IMAGE_NT_HEADERS64 { + uint32_t Signature; + struct { + uint16_t Machine; + uint16_t NumberOfSections; + uint32_t TimeDateStamp; + uint32_t PointerToSymbolTable; + uint32_t NumberOfSymbols; + uint16_t SizeOfOptionalHeader; + uint16_t Characteristics; + } FileHeader; + IMAGE_OPTIONAL_HEADER64 OptionalHeader; +} __attribute__((packed)) IMAGE_NT_HEADERS64; + +typedef struct _IMAGE_IMPORT_BY_NAME { + uint16_t Hint; + char Name[1]; +} __attribute__((packed)) IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME; + +typedef struct _IMAGE_THUNK_DATA64 { + union { + uint64_t ForwarderString; + uint64_t Function; + uint64_t Ordinal; + uint64_t AddressOfData; + } u1; +} __attribute__((packed)) IMAGE_THUNK_DATA64, *PIMAGE_THUNK_DATA64; + +typedef struct _IMAGE_IMPORT_DESCRIPTOR { + union { + uint32_t Characteristics; + uint32_t OriginalFirstThunk; + } u1; + uint32_t TimeDateStamp; + uint32_t ForwarderChain; + uint32_t Name; + uint32_t FirstThunk; +} __attribute__((packed)) IMAGE_IMPORT_DESCRIPTOR, *PIMAGE_IMPORT_DESCRIPTOR; + +typedef struct _IMAGE_EXPORT_DIRECTORY { + uint32_t Characteristics; + uint32_t TimeDateStamp; + uint16_t MajorVersion; + uint16_t MinorVersion; + uint32_t Name; + uint32_t Base; + uint32_t NumberOfFunctions; + uint32_t NumberOfNames; + uint32_t AddressOfFunctions; + uint32_t AddressOfNames; + uint32_t AddressOfNameOrdinals; +} __attribute__((packed)) IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY; +#pragma pack(pop) + +int stricmp(const char *s1, const char *s2) { while (*s1 && ((*s1 | 0x20) == (*s2 | 0x20))) { s1++; s2++; } return *(const unsigned char*)s1 - *(const unsigned char*)s2; } + +extern void* ResolveUser32(const char* functionName); +extern void* ResolveKernel32(const char* functionName); +extern void* ResolveOle32(const char* functionName); +extern void* ResolveWinMM(const char* functionName); + +void* ResolveImport(const char* dllName, const char* functionName) { + // user32 + if (stricmp(dllName, "user32.dll") == 0) { + return ResolveUser32(functionName); + } else if (stricmp(dllName, "kernel32.dll") == 0) { + return ResolveKernel32(functionName); + } else if (stricmp(dllName, "ole32.dll") == 0) { + return ResolveOle32(functionName); + } else if (stricmp(dllName, "winmm.dll") == 0) { + return ResolveWinMM(functionName); + } + + // If the import is not a known dependency, print an error + Print(L"Unknown dll: %a\n", dllName); + return NULL; +} + +void* GetExportByName(void* imageBase, const char* functionName) { + if (!imageBase || !functionName) return NULL; + + uint8_t* base = (uint8_t*)imageBase; + IMAGE_DOS_HEADER* dos = (IMAGE_DOS_HEADER*)base; + IMAGE_NT_HEADERS64* pe = (IMAGE_NT_HEADERS64*)(base + dos->e_lfanew); + + // Get the export directory + IMAGE_DATA_DIRECTORY exportDirEntry = pe->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; + if (exportDirEntry.Size == 0) { + return NULL; // No export directory + } + + IMAGE_EXPORT_DIRECTORY* exportDir = (IMAGE_EXPORT_DIRECTORY*)(base + exportDirEntry.VirtualAddress); + + // Get pointers to the key tables + uint32_t* names = (uint32_t*)(base + exportDir->AddressOfNames); + uint32_t* functions = (uint32_t*)(base + exportDir->AddressOfFunctions); + uint16_t* ordinals = (uint16_t*)(base + exportDir->AddressOfNameOrdinals); + + // Search for the function by name + for (uint32_t i = 0; i < exportDir->NumberOfNames; i++) { + const char* currentName = (const char*)(base + names[i]); + if (stricmp(functionName, currentName) == 0) { + // Name found, get the ordinal + uint16_t ordinal = ordinals[i]; + // Use the ordinal to find the function's RVA + uint32_t functionRva = functions[ordinal]; + // Return the absolute address + return (void*)(base + functionRva); + } + } + + return NULL; // Function not found +} + +void* LoadPeImage(void* buffer) { + uint8_t* data = (uint8_t*)buffer; + IMAGE_DOS_HEADER* dos = (IMAGE_DOS_HEADER*)data; + if (dos->e_magic != IMAGE_DOS_SIGNATURE) { + Print(L"Invalid MZ header\n"); + return NULL; + } + + IMAGE_NT_HEADERS64* pe = (IMAGE_NT_HEADERS64*)(data + dos->e_lfanew); + if (pe->Signature != IMAGE_NT_SIGNATURE) { + Print(L"Invalid PE header\n"); + return NULL; + } + + if (pe->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) { + Print(L"Not PE32+\n"); + return NULL; + } + + // Allocate memory for the full image + uint64_t imageSize = pe->OptionalHeader.SizeOfImage; + uint64_t imageBase = (uint64_t)AllocatePool(imageSize); + if (!imageBase) { + Print(L"Failed to allocate image memory\n"); + return NULL; + } + + ZeroMem((void*)imageBase, imageSize); + + // Copy headers + CopyMem((void*)imageBase, data, pe->OptionalHeader.SizeOfHeaders); + + // Copy each section + IMAGE_SECTION_HEADER* sections = (IMAGE_SECTION_HEADER*)((uint8_t*)&pe->OptionalHeader + pe->FileHeader.SizeOfOptionalHeader); + for (uint64_t i = 0; i < pe->FileHeader.NumberOfSections; i++) { + void* dest = (void*)(imageBase + sections[i].VirtualAddress); + void* src = (void*)(data + sections[i].PointerToRawData); + uint64_t size = sections[i].SizeOfRawData; + if (size > 0) { + CopyMem(dest, src, size); + } + } + + // Relocation + uint64_t imageDelta = imageBase - pe->OptionalHeader.ImageBase; + if (imageDelta != 0 && pe->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_BASERELOC) { + IMAGE_DATA_DIRECTORY relocDir = pe->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]; + if (relocDir.Size > 0) { + uint8_t* relocBase = (uint8_t*)(imageBase + relocDir.VirtualAddress); + uint8_t* relocEnd = relocBase + relocDir.Size; + + while (relocBase < relocEnd) { + IMAGE_BASE_RELOCATION* rel = (IMAGE_BASE_RELOCATION*)relocBase; + if (rel->SizeOfBlock < sizeof(IMAGE_BASE_RELOCATION)) { + Print(L"Relocation block too small at %p\n", rel); + return NULL; + } + uint64_t entryCount = (rel->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(uint16_t); + uint16_t* relocs = (uint16_t*)(rel + 1); + + for (uint64_t i = 0; i < entryCount; i++) { + uint16_t entry = relocs[i]; + uint16_t type = entry >> 12; + uint16_t offset = entry & 0xFFF; + + if (type == IMAGE_REL_BASED_DIR64) { + uint64_t* patchAddr = (uint64_t*)(imageBase + rel->VirtualAddress + offset); + // Check patchAddr is within image + if ((uintptr_t)patchAddr < imageBase || (uintptr_t)patchAddr >= imageBase + imageSize) { + Print(L"Relocation address out of bounds: %p\n", patchAddr); + return NULL; + } + *patchAddr += imageDelta; + } else if (type != 0) { + Print(L"Unknown relocation type %u at RVA %x\n", type, (unsigned)(rel->VirtualAddress + offset)); + return NULL; + } + } + relocBase += rel->SizeOfBlock; + } + } + } + + if (pe->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_IMPORT) { + IMAGE_DATA_DIRECTORY importDirEntry = pe->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; + if (importDirEntry.Size > 0) { + IMAGE_IMPORT_DESCRIPTOR* importDesc = (IMAGE_IMPORT_DESCRIPTOR*)(imageBase + importDirEntry.VirtualAddress); + + // Iterate over each DLL descriptor + while (importDesc->Name != 0) { + const char* dllName = (const char*)(imageBase + importDesc->Name); + IMAGE_THUNK_DATA64* thunkINT = (IMAGE_THUNK_DATA64*)(imageBase + importDesc->u1.OriginalFirstThunk); + IMAGE_THUNK_DATA64* thunkIAT = (IMAGE_THUNK_DATA64*)(imageBase + importDesc->FirstThunk); + + // Iterate over each function in the DLL + while (thunkINT->u1.AddressOfData != 0) { + void* funcPtr = NULL; + if (thunkINT->u1.Ordinal & IMAGE_ORDINAL_FLAG64) { + // Import by ordinal - your ResolveImport doesn't support this + Print(L"Import by ordinal is not supported.\n"); + return NULL; + } else { + // Import by name + IMAGE_IMPORT_BY_NAME* importByName = (IMAGE_IMPORT_BY_NAME*)(imageBase + thunkINT->u1.AddressOfData); + const char* funcName = importByName->Name; + funcPtr = ResolveImport(dllName, funcName); + + if (!funcPtr) { + Print(L"Failed to resolve import: %a -> %a\n", dllName, importByName->Name); + return NULL; + } + } + + // Write the resolved address into the IAT + thunkIAT->u1.Function = (uint64_t)funcPtr; + + thunkINT++; + thunkIAT++; + } + importDesc++; // Move to the next DLL + } + } + } + + // Return base + return (void*)imageBase; +} + +bool LoadBinkDLL(EFI_FILE_HANDLE volume) { + void* binkFileBuffer = LoadFile(volume, L"bink2w64.dll"); + if (!binkFileBuffer) { + return false; + } + + void* binkBase = LoadPeImage(binkFileBuffer); + FreePool(binkFileBuffer); // Free the file buffer, as LoadPeImage copied it. + if (!binkBase) { + return false; + } + + // Grab exports + #define GRAB(name) p##name = (name##_t)GetExportByName(binkBase, #name); \ + if (!p##name) { Print(L"Missing export: %a\n", #name); return false; } + + GRAB(BinkLogoAddress) + GRAB(BinkSetError) + GRAB(BinkGetError) + GRAB(BinkOpen) + GRAB(BinkOpenWithOptions) + GRAB(BinkGetFrameBuffersInfo) + GRAB(BinkRegisterFrameBuffers) + GRAB(BinkDoFrame) + GRAB(BinkDoFramePlane) + GRAB(BinkNextFrame) + GRAB(BinkWait) + GRAB(BinkClose) + GRAB(BinkPause) + GRAB(BinkCopyToBuffer) + GRAB(BinkCopyToBufferRect) + GRAB(BinkGetRects) + GRAB(BinkGoto) + GRAB(BinkGetKeyFrame) + GRAB(BinkFreeGlobals) + GRAB(BinkGetPlatformInfo) + GRAB(BinkRegisterGPUDataBuffers) + GRAB(BinkGetGPUDataBuffersInfo) + GRAB(BinkSetVideoOnOff) + GRAB(BinkSetSoundOnOff) + GRAB(BinkSetVolume) + GRAB(BinkSetPan) + GRAB(BinkSetSpeakerVolumes) + GRAB(BinkService) + GRAB(BinkShouldSkip) + GRAB(BinkControlBackgroundIO) + GRAB(BinkSetWillLoop) + GRAB(BinkStartAsyncThread) + GRAB(BinkDoFrameAsync) + GRAB(BinkDoFrameAsyncMulti) + GRAB(BinkDoFrameAsyncWait) + GRAB(BinkRequestStopAsyncThread) + GRAB(BinkWaitStopAsyncThread) + GRAB(BinkOpenTrack) + GRAB(BinkCloseTrack) + GRAB(BinkGetTrackData) + GRAB(BinkGetTrackType) + GRAB(BinkGetTrackMaxSize) + GRAB(BinkGetTrackID) + GRAB(BinkGetSummary) + GRAB(BinkGetRealtime) + GRAB(BinkSetFileOffset) + GRAB(BinkSetSoundTrack) + GRAB(BinkSetIO) + GRAB(BinkSetFrameRate) + GRAB(BinkSetSimulate) + GRAB(BinkSetIOSize) + GRAB(BinkSetSoundSystem) + GRAB(BinkSetSoundSystem2) + GRAB(BinkOpenDirectSound) + GRAB(BinkOpenWaveOut) + GRAB(BinkOpenXAudio2) + GRAB(BinkSetMemory) + + #undef GRAB + return true; +} +#pragma endregion + +void Blit1280x720_AVX2_NT( + EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop, + uint32_t *src, + UINTN src_width, UINTN src_height +) { + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info = Gop->Mode->Info; + UINTN fb_width = info->HorizontalResolution; + UINTN fb_height = info->VerticalResolution; + UINTN stride = info->PixelsPerScanLine; + + uint32_t *fb = (uint32_t *)Gop->Mode->FrameBufferBase; + + // Center offsets + UINTN x0 = (fb_width - src_width) / 2; + UINTN y0 = (fb_height - src_height) / 2; + + for (UINTN y = 0; y < src_height; y++) { + uint32_t *dst = fb + (y0 + y) * stride + x0; + uint32_t *s = src + y * src_width; + + UINTN x = 0; + + // Align destination pointer to 32-byte boundary for AVX2 streaming + for (; ((uintptr_t)(dst + x) & 31) && x < src_width; x++) + dst[x] = s[x]; + + // Copy 8 pixels (32 bytes) at a time using AVX2 non-temporal stores + for (; x + 7 < src_width; x += 8) { + __m256i data = _mm256_loadu_si256((__m256i *)(s + x)); + _mm256_stream_si256((__m256i *)(dst + x), data); + } + + // Copy any remaining pixels + for (; x < src_width; x++) + dst[x] = s[x]; + } + + // Ensure non-temporal stores are flushed to memory + _mm_sfence(); +} + +EFI_STATUS SetMaxResolution(EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop) { + EFI_STATUS Status; + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *MaxModeInfo; + UINTN MaxModeNumber; + + // Iterate through all available modes to find the one with the maximum resolution + MaxModeNumber = 0; + MaxModeInfo = NULL; + for (UINTN i = 0; i < Gop->Mode->MaxMode; i++) { + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info; + UINTN SizeOfInfo; + + Status = Gop->QueryMode(Gop, i, &SizeOfInfo, &Info); + if (EFI_ERROR(Status)) { + continue; + } + + // Compare resolutions + if (Info->HorizontalResolution > Gop->Mode->Info->HorizontalResolution || + (Info->HorizontalResolution == Gop->Mode->Info->HorizontalResolution && Info->VerticalResolution > Gop->Mode->Info->VerticalResolution)) { + MaxModeNumber = i; + MaxModeInfo = Info; + } + } + + if (MaxModeInfo) { + Print(L"Found max resolution mode: %u x %u at mode %u\n", + MaxModeInfo->HorizontalResolution, MaxModeInfo->VerticalResolution, MaxModeNumber); + + // Set the mode to the maximum resolution + Status = Gop->SetMode(Gop, MaxModeNumber); + if (EFI_ERROR(Status)) { + Print(L"Failed to set mode: %r\n", Status); + } else { + Print(L"Successfully set max resolution mode.\n"); + } + FreePool(MaxModeInfo); // Free the memory for MaxModeInfo + } else { + Print(L"Could not find a valid mode.\n"); + Status = EFI_NOT_FOUND; + } + + return Status; +} + +extern "C" void enable_avx2(); + +void* Malloc(size_t size) { + PRINT(L"Malloc called with size: %u\n", size); + + void* addr = AllocatePool(size); + if (!addr) { + PRINT(L"Allocation failed!\n"); + return NULL; + } + + ZeroMem(addr, size); + + return addr; +} + +void Free(void* ptr) { + PRINT(L"Free called with ptr: %p\n", ptr); + + if (!ptr) { + PRINT(L"Pointer is NULL, nothing to free!\n"); + return; + } + + FreePool(ptr); +} + +EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE* SystemTable) { + InitializeLib(ImageHandle, SystemTable); + SystemTable->BootServices->SetWatchdogTimer(0, 0, 0, NULL); + Print(L"Hello, World!\n"); + + InitializeGop(); + Print(L"GOP initialized\n"); + + SetMaxResolution(gop); + + enable_avx2(); + + EFI_FILE_HANDLE volume = GetVolume(ImageHandle); + Print(L"Got volume\n"); + + if (!LoadBinkDLL(volume)) { + Print(L"Failed to load Bink Video DLL\n"); + gBS->Stall(5 * 1000 * 1000); + gST->RuntimeServices->ResetSystem(EfiResetShutdown, EFI_SUCCESS, 0, NULL); return 1; } - pBinkSetSoundSystem((BINKSNDSYSOPEN)pBinkOpenDirectSound, 0); - pBinkSetMemory((BINKMEMALLOC)malloc, (BINKMEMFREE)free); - pBinkSetIO(NULL); // no io - //pBinkSetTimerRead() // r.i.p. + Print(L"Bink function pointers initialized (propably)!\n"); - size_t size = 0; - char* buffer = read_binary_file_to_memory("you_are_nothing.bk2", &size); + pBinkSetSoundSystem(0, 0); // no sound + pBinkSetMemory((BINKMEMALLOC)Malloc, (BINKMEMFREE)Free); // debug allocators + pBinkSetIO(0); // no io + //pBinkSetTimerRead() // r.i.p. my version of the sdk + // UPDATE: spoofed in kernel32.cpp + + Print(L"BinkSet* called\n"); + + void* video_file = LoadFile(volume, L"video.bk2"); + + Print(L"Video file loaded into memory\n"); HBINK bink = NULL; - bink = pBinkOpen(buffer, BINKFROMMEMORY); + bink = pBinkOpen((const char*)video_file, BINKFROMMEMORY); + Print(L"Opened Bink!\n"); int width = bink->Width, height = bink->Height; + Print(L"Width: %d, Height: %d\n", width, height); // Allocate framebuffer - uint32_t* framebuffer = (uint32_t*)malloc(width * height * sizeof(uint32_t)); - if (!framebuffer) return 1; + uint32_t* framebuffer = (uint32_t*)AllocatePool(width * height * sizeof(uint32_t)); + if (!framebuffer) { + Print(L"Failed to allocate framebuffer!\n"); + gBS->Stall(5 * 1000 * 1000); + pBinkClose(bink); + FreePool(video_file); + return 1; + } - // Decode one frame - pBinkDoFrame(bink); + Print(L"Framebuffer allocated!\n"); - // Copy frame to our buffer - pBinkCopyToBuffer( - bink, - framebuffer, // dest - width * 4, // destpitch in bytes - height, // destheight - 0, // destx - 0, // desty - BINKSURFACE32 | BINKCOPYALL // flags - ); + size_t skipped_frames = 0; - // Create BMP headers - BITMAPFILEHEADER bfh = {0}; - BITMAPINFOHEADER bih = {0}; + // start the decode loop + while (true) { + // Check if the video is done + if (bink->FrameNum >= bink->Frames) { + Print(L"Video playback finished!\n"); + break; // exit the loop if the video is done + } + + // Wait for the next frame + if (pBinkWait(bink)) { + _mm_pause(); // don't burn CPU cycles + continue; // wait for the next frame + } - bfh.bfType = 0x4D42; // 'BM' - bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); - bfh.bfSize = bfh.bfOffBits + width * height * 4; + // Check if we should skip the frame + if (pBinkShouldSkip(bink)) { + pBinkNextFrame(bink); + skipped_frames++; + continue; // skip this frame + } - bih.biSize = sizeof(BITMAPINFOHEADER); - bih.biWidth = width; - bih.biHeight = -height; // negative = top-down - bih.biPlanes = 1; - bih.biBitCount = 32; - bih.biCompression = 0; // BI_RGB - bih.biSizeImage = width * height * 4; + // int code = pBinkDoFrame(bink); + // if (code != 0) { + // Print(L"BinkDoFrame failed!\n"); + // pBinkClose(bink); + // FreePool(video_file); + // gBS->Stall(5 * 1000 * 1000); + // gST->RuntimeServices->ResetSystem(EfiResetShutdown, EFI_SUCCESS, 0, NULL); + // return 1; + // } + pBinkDoFrame(bink); + // no error handling? that's right! + // because it uses SEH internally and i don't have the will power to tackle that + // no SEH handling = #GP on throw, #GP on throw = no error handling, no error handling = no video - // Write BMP - FILE* f = fopen("framebuffer.bmp", "wb"); - if (!f) return 1; + // Copy frame to our buffer + int code = pBinkCopyToBuffer( + bink, + framebuffer, + width * 4, + height, + 0, + 0, + BINKSURFACE32 | BINKCOPYALL + ); + if (code != 0 && code != 1) { + Print(L"BinkCopyToBuffer failed!\n"); + pBinkClose(bink); + FreePool(video_file); + gBS->Stall(5 * 1000 * 1000); + gST->RuntimeServices->ResetSystem(EfiResetShutdown, EFI_SUCCESS, 0, NULL); + return 1; + } + + pBinkNextFrame(bink); - fwrite(&bfh, sizeof(bfh), 1, f); - fwrite(&bih, sizeof(bih), 1, f); - fwrite(framebuffer, 4, width * height, f); + Blit1280x720_AVX2_NT(gop, framebuffer, width, height); - fclose(f); - free(framebuffer); + Print(L"\rframe %d done", bink->FrameNum); + } - printf("Saved framebuffer.bmp\n"); + Print(L"\nSkipped frames: %u\n", skipped_frames); pBinkClose(bink); - free(buffer); + FreePool(video_file); + FreePool(framebuffer); + + Print(L"Exiting\n"); + gBS->Stall(5 * 1000 * 1000); + gST->RuntimeServices->ResetSystem(EfiResetShutdown, EFI_SUCCESS, 0, NULL); return 0; -} \ No newline at end of file +} diff --git a/main.exe b/main.exe deleted file mode 100644 index e1699b1..0000000 Binary files a/main.exe and /dev/null differ diff --git a/main.ilk b/main.ilk deleted file mode 100644 index 0d0be7f..0000000 Binary files a/main.ilk and /dev/null differ diff --git a/main.obj b/main.obj deleted file mode 100644 index 0cb03f3..0000000 Binary files a/main.obj and /dev/null differ diff --git a/main.pdb b/main.pdb deleted file mode 100644 index 0fdaa9f..0000000 Binary files a/main.pdb and /dev/null differ diff --git a/ole32.cpp b/ole32.cpp index fb3a02f..73fb3f0 100644 --- a/ole32.cpp +++ b/ole32.cpp @@ -1,44 +1,43 @@ -typedef void* HWND; +#include +#include +#include "print.h" + typedef void* LPUNKNOWN; typedef void* REFIID; typedef void* REFCLSID; typedef long HRESULT; typedef unsigned long DWORD; -typedef unsigned int UINT; typedef int BOOL; -typedef void* HANDLE; typedef void* LPVOID; -typedef long LONG; -typedef long LONG_PTR; -typedef const char* LPCSTR; -typedef size_t SIZE_T; typedef void* HMODULE; -typedef HMODULE HINSTANCE; -typedef void* FARPROC; -typedef DWORD (*LPTHREAD_START_ROUTINE)(LPVOID lpThreadParameter); -typedef union _LARGE_INTEGER { - struct { - unsigned long LowPart; - long HighPart; - }; - long long QuadPart; -} LARGE_INTEGER; #define S_OK ((HRESULT)0L) -#define TRUE 1 -#define FALSE 0 - -extern "C" { // COM stubs -__declspec(dllexport) HRESULT CoCreateInstance(REFCLSID, LPUNKNOWN, DWORD, REFIID, LPVOID* ppv) { +HRESULT CoCreateInstance(REFCLSID, LPUNKNOWN, DWORD, REFIID, LPVOID* ppv) { + PRINT(L"CoCreateInstance called\n"); if (ppv) *ppv = nullptr; return S_OK; } -__declspec(dllexport) HRESULT CoInitializeEx(LPVOID, DWORD) { return S_OK; } -__declspec(dllexport) void CoUninitialize() {} -__declspec(dllexport) void CoTaskMemFree(LPVOID) {} -__declspec(dllexport) HRESULT PropVariantClear(LPVOID) { return S_OK; } +HRESULT CoInitializeEx(LPVOID, DWORD) { PRINT(L"CoInitializeEx called\n"); return S_OK; } +void CoUninitialize() { PRINT(L"CoUninitialize called\n"); } +void CoTaskMemFree(LPVOID) { PRINT(L"CoTaskMemFree called\n"); } +HRESULT PropVariantClear(LPVOID) { PRINT(L"PropVariantClear called\n"); return S_OK; } -BOOL DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { return TRUE; } +extern int stricmp(const char *s1, const char *s2); +void* ResolveOle32(const char* functionName) { + if (stricmp(functionName, "CoCreateInstance") == 0) { + return CoCreateInstance; + } else if (stricmp(functionName, "CoInitializeEx") == 0) { + return CoInitializeEx; + } else if (stricmp(functionName, "CoUninitialize") == 0) { + return CoUninitialize; + } else if (stricmp(functionName, "CoTaskMemFree") == 0) { + return CoTaskMemFree; + } else if (stricmp(functionName, "PropVariantClear") == 0) { + return PropVariantClear; + } + + Print(L"Unknown function: %a\n", functionName); + return NULL; } diff --git a/ole32.dll b/ole32.dll deleted file mode 100644 index daec45d..0000000 Binary files a/ole32.dll and /dev/null differ diff --git a/ole32.exp b/ole32.exp deleted file mode 100644 index 7a01f9e..0000000 Binary files a/ole32.exp and /dev/null differ diff --git a/ole32.lib b/ole32.lib deleted file mode 100644 index 08e04f9..0000000 Binary files a/ole32.lib and /dev/null differ diff --git a/ole32.obj b/ole32.obj deleted file mode 100644 index e79823f..0000000 Binary files a/ole32.obj and /dev/null differ diff --git a/print.h b/print.h new file mode 100644 index 0000000..01e4f71 --- /dev/null +++ b/print.h @@ -0,0 +1,2 @@ +#define PRINT Print +//#define PRINT(...) \ No newline at end of file diff --git a/run.bat b/run.bat new file mode 100644 index 0000000..dcb209e --- /dev/null +++ b/run.bat @@ -0,0 +1 @@ +@start qemu-system-x86_64 -cpu Haswell -drive if=pflash,format=raw,readonly=on,file=OVMF\OVMF_CODE_4M.fd -drive if=pflash,format=raw,file=OVMF\OVMF_VARS_4M.fd -drive file=fat:rw:fatroot,format=raw,if=none,id=nvme0 -device nvme,drive=nvme0,serial=1234 -m 1G -serial stdio -d in_asm,cpu_reset,int -D qemu.log \ No newline at end of file diff --git a/user32.cpp b/user32.cpp index 437eb60..df4f74c 100644 --- a/user32.cpp +++ b/user32.cpp @@ -1,199 +1,51 @@ +#include +#include +#include "print.h" + typedef void* HWND; -typedef void* LPUNKNOWN; -typedef void* REFIID; -typedef void* REFCLSID; -typedef long HRESULT; typedef unsigned long DWORD; typedef unsigned int UINT; -typedef int BOOL; -typedef void* HANDLE; -typedef void* LPVOID; typedef long LONG; typedef long LONG_PTR; typedef const char* LPCSTR; -typedef size_t SIZE_T; -typedef void* HMODULE; -typedef HMODULE HINSTANCE; -typedef void* FARPROC; -typedef DWORD (*LPTHREAD_START_ROUTINE)(LPVOID lpThreadParameter); -typedef union _LARGE_INTEGER { - struct { - unsigned long LowPart; - long HighPart; - }; - long long QuadPart; -} LARGE_INTEGER; -#define S_OK ((HRESULT)0L) -#define TRUE 1 -#define FALSE 0 -#include - -extern "C" { // Window stubs -__declspec(dllexport) HWND GetDesktopWindow() { return (HWND)1; } -__declspec(dllexport) HWND GetActiveWindow() { return (HWND)1; } -__declspec(dllexport) HWND GetTopWindow(HWND) { return (HWND)1; } -__declspec(dllexport) HWND GetWindow(HWND, UINT) { return (HWND)1; } -__declspec(dllexport) LONG GetWindowLongA(HWND, int) { return 0; } -__declspec(dllexport) LONG_PTR GetWindowLongPtrA(HWND, int) { return 0; } -__declspec(dllexport) void GetWindowThreadProcessId(HWND, DWORD*) {} - -typedef void (*OutputDebugStringA_t)(LPCSTR lpOutputString); - -OutputDebugStringA_t pOutputDebugStringA = nullptr; +HWND GetDesktopWindow() { PRINT(L"GetDesktopWindow called\n"); return (HWND)1; } +HWND GetActiveWindow() { PRINT(L"GetActiveWindow called\n"); return (HWND)1; } +HWND GetTopWindow(HWND) { PRINT(L"GetTopWindow called\n"); return (HWND)1; } +HWND GetWindow(HWND, UINT) { PRINT(L"GetWindow called\n"); return (HWND)1; } +LONG GetWindowLongA(HWND, int) { PRINT(L"GetWindowLongA called\n"); return 0; } +LONG_PTR GetWindowLongPtrA(HWND, int) { PRINT(L"GetWindowLongPtrA called\n"); return 0; } +void GetWindowThreadProcessId(HWND, DWORD*) { PRINT(L"GetWindowThreadProcessId called\n"); } // MessageBox -__declspec(dllexport) int MessageBoxA(HWND, LPCSTR text, LPCSTR caption, UINT) { - pOutputDebugStringA("[MessageBox] "); - pOutputDebugStringA(caption); - pOutputDebugStringA(": "); - pOutputDebugStringA(text); - pOutputDebugStringA("\n"); +int MessageBoxA(HWND, LPCSTR text, LPCSTR caption, UINT) { + PRINT(L"MessageBoxA called\n"); + PRINT(L"[MessageBox] %s: %s\n", caption, text); return 1; } -HMODULE LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags); +extern int stricmp(const char *s1, const char *s2); -#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ -#define IMAGE_NT_SIGNATURE 0x00004550 // PE00 -#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 - -struct IMAGE_DOS_HEADER { - uint16_t e_magic; - uint16_t e_cblp; - uint16_t e_cp; - uint16_t e_crlc; - uint16_t e_cparhdr; - uint16_t e_minalloc; - uint16_t e_maxalloc; - uint16_t e_ss; - uint16_t e_sp; - uint16_t e_csum; - uint16_t e_ip; - uint16_t e_cs; - uint16_t e_lfarlc; - uint16_t e_ovno; - uint16_t e_res[4]; - uint16_t e_oemid; - uint16_t e_oeminfo; - uint16_t e_res2[10]; - uint32_t e_lfanew; -}; - -struct IMAGE_FILE_HEADER { - uint16_t Machine; - uint16_t NumberOfSections; - uint32_t TimeDateStamp; - uint32_t PointerToSymbolTable; - uint32_t NumberOfSymbols; - uint16_t SizeOfOptionalHeader; - uint16_t Characteristics; -}; - -struct IMAGE_DATA_DIRECTORY { - uint32_t VirtualAddress; - uint32_t Size; -}; - -struct IMAGE_OPTIONAL_HEADER64 { - uint16_t Magic; - uint8_t MajorLinkerVersion; - uint8_t MinorLinkerVersion; - uint32_t SizeOfCode; - uint32_t SizeOfInitializedData; - uint32_t SizeOfUninitializedData; - uint32_t AddressOfEntryPoint; - uint32_t BaseOfCode; - uint64_t ImageBase; - uint32_t SectionAlignment; - uint32_t FileAlignment; - uint16_t MajorOperatingSystemVersion; - uint16_t MinorOperatingSystemVersion; - uint16_t MajorImageVersion; - uint16_t MinorImageVersion; - uint16_t MajorSubsystemVersion; - uint16_t MinorSubsystemVersion; - uint32_t Win32VersionValue; - uint32_t SizeOfImage; - uint32_t SizeOfHeaders; - uint32_t CheckSum; - uint16_t Subsystem; - uint16_t DllCharacteristics; - uint64_t SizeOfStackReserve; - uint64_t SizeOfStackCommit; - uint64_t SizeOfHeapReserve; - uint64_t SizeOfHeapCommit; - uint32_t LoaderFlags; - uint32_t NumberOfRvaAndSizes; - IMAGE_DATA_DIRECTORY DataDirectory[16]; -}; - -struct IMAGE_NT_HEADERS64 { - uint32_t Signature; - IMAGE_FILE_HEADER FileHeader; - IMAGE_OPTIONAL_HEADER64 OptionalHeader; -}; - -struct IMAGE_EXPORT_DIRECTORY { - uint32_t Characteristics; - uint32_t TimeDateStamp; - uint16_t MajorVersion; - uint16_t MinorVersion; - uint32_t Name; - uint32_t Base; - uint32_t NumberOfFunctions; - uint32_t NumberOfNames; - uint32_t AddressOfFunctions; // RVA from base of image - uint32_t AddressOfNames; // RVA from base of image - uint32_t AddressOfNameOrdinals; // RVA from base of image -}; - -int strcmp(const char* a, const char* b) { - while (*a && (*a == *b)) { - ++a; - ++b; +void* ResolveUser32(const char* functionName) { + if (stricmp(functionName, "GetDesktopWindow") == 0) { + return GetDesktopWindow; + } else if (stricmp(functionName, "GetActiveWindow") == 0) { + return GetActiveWindow; + } else if (stricmp(functionName, "GetTopWindow") == 0) { + return GetTopWindow; + } else if (stricmp(functionName, "GetWindow") == 0) { + return GetWindow; + } else if (stricmp(functionName, "GetWindowLongA") == 0) { + return GetWindowLongA; + } else if (stricmp(functionName, "GetWindowLongPtrA") == 0) { + return GetWindowLongPtrA; + } else if (stricmp(functionName, "GetWindowThreadProcessId") == 0) { + return GetWindowThreadProcessId; + } else if (stricmp(functionName, "MessageBoxA") == 0) { + return MessageBoxA; } - return static_cast(*a) - static_cast(*b); -} - -FARPROC GetRealGetProcAddress(HMODULE hModule) { - auto base = reinterpret_cast(hModule); - auto dos = reinterpret_cast(base); - if (dos->e_magic != IMAGE_DOS_SIGNATURE) return nullptr; - - auto nt = reinterpret_cast(base + dos->e_lfanew); - if (nt->Signature != IMAGE_NT_SIGNATURE) return nullptr; - - auto exportDirRVA = nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; - auto exportDir = reinterpret_cast(base + exportDirRVA); - - auto names = reinterpret_cast(base + exportDir->AddressOfNames); - auto ordinals = reinterpret_cast(base + exportDir->AddressOfNameOrdinals); - auto functions = reinterpret_cast(base + exportDir->AddressOfFunctions); - - for (uint32_t i = 0; i < exportDir->NumberOfNames; i++) { - const char* name = reinterpret_cast(base + names[i]); - if (strcmp(name, "GetProcAddress") == 0) { - uint16_t ord = ordinals[i]; - uint32_t funcRVA = functions[ord]; - return reinterpret_cast(base + funcRVA); - } - } - return nullptr; -} - -typedef FARPROC (*GetProcAddress_t)(HMODULE, LPCSTR); -GetProcAddress_t pGetProcAddress = nullptr; - -BOOL DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { - if (fdwReason == 1) { // DLL_PROCESS_ATTACH - HMODULE kernel32 = LoadLibraryExA("kernel32.dll", 0, 0x00000800); - pGetProcAddress = (GetProcAddress_t)GetRealGetProcAddress(kernel32); - - pOutputDebugStringA = (OutputDebugStringA_t)pGetProcAddress(kernel32, "OutputDebugStringA"); - } - return TRUE; -} - + + Print(L"Unknown function: %a\n", functionName); + return NULL; } diff --git a/user32.dll b/user32.dll deleted file mode 100644 index 805702e..0000000 Binary files a/user32.dll and /dev/null differ diff --git a/user32.exp b/user32.exp deleted file mode 100644 index 28edadf..0000000 Binary files a/user32.exp and /dev/null differ diff --git a/user32.lib b/user32.lib deleted file mode 100644 index f696739..0000000 Binary files a/user32.lib and /dev/null differ diff --git a/user32.obj b/user32.obj deleted file mode 100644 index c7c4f48..0000000 Binary files a/user32.obj and /dev/null differ diff --git a/vc140.pdb b/vc140.pdb deleted file mode 100644 index 1f1947c..0000000 Binary files a/vc140.pdb and /dev/null differ diff --git a/winmm.cpp b/winmm.cpp index a81aedf..f3fb102 100644 --- a/winmm.cpp +++ b/winmm.cpp @@ -1,183 +1,33 @@ -typedef void* HWND; -typedef void* LPUNKNOWN; -typedef void* REFIID; -typedef void* REFCLSID; -typedef long HRESULT; -typedef unsigned long DWORD; -typedef unsigned int UINT; -typedef int BOOL; -typedef void* HANDLE; -typedef void* LPVOID; -typedef long LONG; -typedef long LONG_PTR; -typedef const char* LPCSTR; -typedef size_t SIZE_T; -typedef void* HMODULE; -typedef HMODULE HINSTANCE; -typedef void* FARPROC; -typedef DWORD (*LPTHREAD_START_ROUTINE)(LPVOID lpThreadParameter); -typedef union _LARGE_INTEGER { - struct { - unsigned long LowPart; - long HighPart; - }; - long long QuadPart; -} LARGE_INTEGER; -#define S_OK ((HRESULT)0L) -#define TRUE 1 -#define FALSE 0 -#include +#include +#include +#include "print.h" -extern "C" { +typedef unsigned long DWORD; +typedef int BOOL; typedef DWORD (*timeGetTime_t)(); timeGetTime_t ptimeGetTime = nullptr; -__declspec(dllexport) DWORD timeGetTime() { - return ptimeGetTime(); -} - -HMODULE LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags); - -#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ -#define IMAGE_NT_SIGNATURE 0x00004550 // PE00 -#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 - -struct IMAGE_DOS_HEADER { - uint16_t e_magic; - uint16_t e_cblp; - uint16_t e_cp; - uint16_t e_crlc; - uint16_t e_cparhdr; - uint16_t e_minalloc; - uint16_t e_maxalloc; - uint16_t e_ss; - uint16_t e_sp; - uint16_t e_csum; - uint16_t e_ip; - uint16_t e_cs; - uint16_t e_lfarlc; - uint16_t e_ovno; - uint16_t e_res[4]; - uint16_t e_oemid; - uint16_t e_oeminfo; - uint16_t e_res2[10]; - uint32_t e_lfanew; -}; - -struct IMAGE_FILE_HEADER { - uint16_t Machine; - uint16_t NumberOfSections; - uint32_t TimeDateStamp; - uint32_t PointerToSymbolTable; - uint32_t NumberOfSymbols; - uint16_t SizeOfOptionalHeader; - uint16_t Characteristics; -}; - -struct IMAGE_DATA_DIRECTORY { - uint32_t VirtualAddress; - uint32_t Size; -}; - -struct IMAGE_OPTIONAL_HEADER64 { - uint16_t Magic; - uint8_t MajorLinkerVersion; - uint8_t MinorLinkerVersion; - uint32_t SizeOfCode; - uint32_t SizeOfInitializedData; - uint32_t SizeOfUninitializedData; - uint32_t AddressOfEntryPoint; - uint32_t BaseOfCode; - uint64_t ImageBase; - uint32_t SectionAlignment; - uint32_t FileAlignment; - uint16_t MajorOperatingSystemVersion; - uint16_t MinorOperatingSystemVersion; - uint16_t MajorImageVersion; - uint16_t MinorImageVersion; - uint16_t MajorSubsystemVersion; - uint16_t MinorSubsystemVersion; - uint32_t Win32VersionValue; - uint32_t SizeOfImage; - uint32_t SizeOfHeaders; - uint32_t CheckSum; - uint16_t Subsystem; - uint16_t DllCharacteristics; - uint64_t SizeOfStackReserve; - uint64_t SizeOfStackCommit; - uint64_t SizeOfHeapReserve; - uint64_t SizeOfHeapCommit; - uint32_t LoaderFlags; - uint32_t NumberOfRvaAndSizes; - IMAGE_DATA_DIRECTORY DataDirectory[16]; -}; - -struct IMAGE_NT_HEADERS64 { - uint32_t Signature; - IMAGE_FILE_HEADER FileHeader; - IMAGE_OPTIONAL_HEADER64 OptionalHeader; -}; - -struct IMAGE_EXPORT_DIRECTORY { - uint32_t Characteristics; - uint32_t TimeDateStamp; - uint16_t MajorVersion; - uint16_t MinorVersion; - uint32_t Name; - uint32_t Base; - uint32_t NumberOfFunctions; - uint32_t NumberOfNames; - uint32_t AddressOfFunctions; // RVA from base of image - uint32_t AddressOfNames; // RVA from base of image - uint32_t AddressOfNameOrdinals; // RVA from base of image -}; - -int strcmp(const char* a, const char* b) { - while (*a && (*a == *b)) { - ++a; - ++b; +DWORD timeGetTime() { + PRINT(L"timeGetTime called\n"); + EFI_TIME t; + if (EFI_SUCCESS == gRT->GetTime(&t, nullptr)) { + // convert to milliseconds since midnight + return (DWORD)( + ((t.Hour * 3600 + t.Minute * 60 + t.Second) * 1000ULL) + + (t.Nanosecond / 1000000ULL) + ); } - return static_cast(*a) - static_cast(*b); + return 0; } -FARPROC GetRealGetProcAddress(HMODULE hModule) { - auto base = reinterpret_cast(hModule); - auto dos = reinterpret_cast(base); - if (dos->e_magic != IMAGE_DOS_SIGNATURE) return nullptr; +extern int stricmp(const char *s1, const char *s2); - auto nt = reinterpret_cast(base + dos->e_lfanew); - if (nt->Signature != IMAGE_NT_SIGNATURE) return nullptr; - - auto exportDirRVA = nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; - auto exportDir = reinterpret_cast(base + exportDirRVA); - - auto names = reinterpret_cast(base + exportDir->AddressOfNames); - auto ordinals = reinterpret_cast(base + exportDir->AddressOfNameOrdinals); - auto functions = reinterpret_cast(base + exportDir->AddressOfFunctions); - - for (uint32_t i = 0; i < exportDir->NumberOfNames; i++) { - const char* name = reinterpret_cast(base + names[i]); - if (strcmp(name, "GetProcAddress") == 0) { - uint16_t ord = ordinals[i]; - uint32_t funcRVA = functions[ord]; - return reinterpret_cast(base + funcRVA); - } +void* ResolveWinMM(const char* functionName) { + if (stricmp(functionName, "timeGetTime") == 0) { + return timeGetTime; } - return nullptr; -} - -typedef FARPROC (*GetProcAddress_t)(HMODULE, LPCSTR); -GetProcAddress_t pGetProcAddress = nullptr; - -BOOL DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { - if (fdwReason == 1) { // DLL_PROCESS_ATTACH - HMODULE kernel32 = LoadLibraryExA("kernel32.dll", 0, 0x00000800); - pGetProcAddress = (GetProcAddress_t)GetRealGetProcAddress(kernel32); - - ptimeGetTime = (timeGetTime_t)pGetProcAddress(kernel32, "timeGetTime"); - } - return TRUE; -} - + + Print(L"Unknown function: %a\n", functionName); + return NULL; } diff --git a/winmm.dll b/winmm.dll deleted file mode 100644 index fe07a22..0000000 Binary files a/winmm.dll and /dev/null differ diff --git a/winmm.exp b/winmm.exp deleted file mode 100644 index 81ac7d1..0000000 Binary files a/winmm.exp and /dev/null differ diff --git a/winmm.lib b/winmm.lib deleted file mode 100644 index b8731ab..0000000 Binary files a/winmm.lib and /dev/null differ diff --git a/winmm.obj b/winmm.obj deleted file mode 100644 index 718a165..0000000 Binary files a/winmm.obj and /dev/null differ diff --git a/you_are_nothing.bk2 b/you_are_nothing.bk2 deleted file mode 100644 index 2503128..0000000 Binary files a/you_are_nothing.bk2 and /dev/null differ