23#define RT_PAGE_SIZE 0x200
24#define RT_PAGE_MASK 0x1FF
25#define RT_PAGE_SHIFT 9
27#define RT_SIZE_TO_PAGES(a) (((a) >> RT_PAGE_SHIFT) + (((a) & RT_PAGE_MASK) ? 1 : 0))
28#define RT_PAGES_TO_SIZE(a) ((a) << RT_PAGE_SHIFT)
33#define RT_PAGE_FREE 0x00000000
34#define RT_PAGE_USED 0x00000001
36#define MIN_REQUIRED_BLOCKS 600
42 UINTN StartPageOffset;
49 UINTN LastEmptyPageOffset;
76 IN OUT UINT8 *ScratchBuffer,
86 if (ScratchBuffer ==
NULL) {
87 return EFI_INVALID_PARAMETER;
90 if (ScratchBufferSize < MIN_REQUIRED_BLOCKS * 1024) {
91 return EFI_BUFFER_TOO_SMALL;
99 SetMem (mRTPageTable, ScratchBufferSize, 0xFF);
103 mRTPageTable->LastEmptyPageOffset = 0x0;
105 for (Index = 0; Index < mRTPageTable->PageCount; Index++) {
106 mRTPageTable->Pages[Index].PageFlag = RT_PAGE_FREE;
107 mRTPageTable->Pages[Index].StartPageOffset = 0;
129 UINTN StartPageIndex;
134 StartPageIndex = RT_SIZE_TO_PAGES (mRTPageTable->LastEmptyPageOffset);
135 ReqPages = RT_SIZE_TO_PAGES (AllocationSize);
136 if (ReqPages > mRTPageTable->PageCount) {
146 for (Index = StartPageIndex; Index <= (mRTPageTable->PageCount - ReqPages); ) {
150 for (SubIndex = 0; SubIndex < ReqPages; SubIndex++) {
151 if ((mRTPageTable->Pages[SubIndex + Index].PageFlag & RT_PAGE_USED) != 0) {
156 if (SubIndex == ReqPages) {
160 return RT_PAGES_TO_SIZE (Index);
166 while ((mRTPageTable->Pages[SubIndex + Index].PageFlag & RT_PAGE_USED) != 0) {
177 if (ReqPages > StartPageIndex) {
184 for (Index = 0; Index < (StartPageIndex - ReqPages); ) {
188 for (SubIndex = 0; SubIndex < ReqPages; SubIndex++) {
189 if ((mRTPageTable->Pages[SubIndex + Index].PageFlag & RT_PAGE_USED) != 0) {
194 if (SubIndex == ReqPages) {
198 return RT_PAGES_TO_SIZE (Index);
204 while ((SubIndex < (StartPageIndex - ReqPages)) &&
205 ((mRTPageTable->Pages[SubIndex + Index].PageFlag & RT_PAGE_USED) != 0))
247 if (AllocOffset == (
UINTN)(-1)) {
255 ReqPages = RT_SIZE_TO_PAGES (AllocationSize);
256 AllocPtr = mRTPageTable->DataAreaBase + AllocOffset;
257 StartPage = RT_SIZE_TO_PAGES (AllocOffset);
259 while (Index < ReqPages) {
260 mRTPageTable->Pages[StartPage + Index].PageFlag |= RT_PAGE_USED;
261 mRTPageTable->Pages[StartPage + Index].StartPageOffset = AllocOffset;
266 mRTPageTable->LastEmptyPageOffset = AllocOffset + RT_PAGES_TO_SIZE (ReqPages);
268 ZeroMem (AllocPtr, AllocationSize);
288 UINTN StartPageIndex;
290 StartOffset = (
UINTN)Buffer - (
UINTN)mRTPageTable->DataAreaBase;
291 StartPageIndex = RT_SIZE_TO_PAGES (mRTPageTable->Pages[RT_SIZE_TO_PAGES (StartOffset)].StartPageOffset);
293 while (StartPageIndex < mRTPageTable->PageCount) {
294 if (((mRTPageTable->Pages[StartPageIndex].PageFlag & RT_PAGE_USED) != 0) &&
295 (mRTPageTable->Pages[StartPageIndex].StartPageOffset == StartOffset))
300 mRTPageTable->Pages[StartPageIndex].PageFlag &= ~RT_PAGE_USED;
301 mRTPageTable->Pages[StartPageIndex].PageFlag |= RT_PAGE_FREE;
302 mRTPageTable->Pages[StartPageIndex].StartPageOffset = 0;
364 if (EFI_ERROR (Status)) {
371 Status =
gBS->CreateEventEx (
376 &gEfiEventVirtualAddressChangeGuid,
377 &mVirtualAddressChangeEvent
406 UINTN StartPageIndex;
410 return malloc (size);
416 StartOffset = (
UINTN)ptr - (
UINTN)mRTPageTable->DataAreaBase;
417 StartPageIndex = RT_SIZE_TO_PAGES (mRTPageTable->Pages[RT_SIZE_TO_PAGES (StartOffset)].StartPageOffset);
419 while (StartPageIndex < mRTPageTable->PageCount) {
420 if (((mRTPageTable->Pages[StartPageIndex].PageFlag & RT_PAGE_USED) != 0) &&
421 (mRTPageTable->Pages[StartPageIndex].StartPageOffset == StartOffset))
430 if (size <= RT_PAGES_TO_SIZE (PageCount)) {
438 if (NewPtr ==
NULL) {
442 CopyMem (NewPtr, ptr, RT_PAGES_TO_SIZE (PageCount));
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI SetMem(OUT VOID *Buffer, IN UINTN Length, IN UINT8 Value)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID *EFIAPI AllocateRuntimePool(IN UINTN AllocationSize)
#define ASSERT_EFI_ERROR(StatusParameter)
VOID EFIAPI RuntimeCryptLibAddressChangeEvent(IN EFI_EVENT Event, IN VOID *Context)
UINTN LookupFreeMemRegion(IN UINTN AllocationSize)
VOID * RuntimeAllocateMem(IN UINTN AllocationSize)
EFI_STATUS EFIAPI RuntimeCryptLibConstructor(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
EFI_STATUS InitializeScratchMemory(IN OUT UINT8 *ScratchBuffer, IN UINTN ScratchBufferSize)
VOID RuntimeFreeMem(IN VOID *Buffer)
EFI_STATUS EFIAPI EfiConvertPointer(IN UINTN DebugDisposition, IN OUT VOID **Address)