2 * COPYRIGHT: See COPYING.ARM in the top level directory
3 * PROJECT: ReactOS UEFI Boot Library
4 * FILE: boot/environ/lib/mm/blkalloc.c
5 * PURPOSE: Boot Library Memory Manager Block Allocator
6 * PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org)
9 /* INCLUDES ******************************************************************/
13 /* DATA VARIABLES ************************************************************/
15 PVOID
* MmBlockAllocatorTable
;
16 ULONG MmBlockAllocatorTableEntries
;
17 BOOLEAN MmBlockAllocatorInitialized
;
19 typedef struct _BL_BLOCK_DESCRIPTOR
31 } BL_BLOCK_DESCRIPTOR
, *PBL_BLOCK_DESCRIPTOR
;
33 typedef struct _BL_BLOCK_ENTRY
37 } BL_BLOCK_ENTRY
, *PBL_BLOCK_ENTRY
;
39 /* FUNCTIONS *****************************************************************/
42 MmBapCompareBlockAllocatorTableEntry (
50 PBL_BLOCK_DESCRIPTOR BlockInfo
= (PBL_BLOCK_DESCRIPTOR
)Entry
;
51 ULONG BlockId
= PtrToUlong(Argument1
);
53 /* Check if the block ID matches */
54 return BlockInfo
->BlockId
== BlockId
;
58 MmBapFindBlockInformation (
64 /* Find the block that matches */
66 return BlTblFindEntry(MmBlockAllocatorTable
,
67 MmBlockAllocatorTableEntries
,
69 MmBapCompareBlockAllocatorTableEntry
,
77 MmBapFreeBlockAllocatorDescriptor (
78 _In_ PBL_BLOCK_DESCRIPTOR BlockInfo
,
79 _In_ PBL_BLOCK_ENTRY BlockEntry
82 /* @TODO FIXME: Later */
83 EfiPrintf(L
"Block free not yet implemented\r\n");
84 return STATUS_NOT_IMPLEMENTED
;
88 BlpMmDeleteBlockAllocator (
92 NTSTATUS Status
, LocalStatus
;
93 PBL_BLOCK_DESCRIPTOR BlockInfo
;
94 PLIST_ENTRY ListHead
, NextEntry
;
95 PBL_BLOCK_ENTRY BlockEntry
;
97 /* Nothing to delete if we're not initialized */
98 if (!MmBlockAllocatorInitialized
)
100 return STATUS_UNSUCCESSFUL
;
103 /* Find the block descriptor */
104 BlockInfo
= MmBapFindBlockInformation(BlockId
);
107 /* Assume success for now */
108 Status
= STATUS_SUCCESS
;
110 /* Do we have at least one reference? */
111 if (BlockInfo
->ReferenceCount
)
113 /* Iterate over the allocated blocks */
114 ListHead
= &BlockInfo
->ListHead
;
115 NextEntry
= ListHead
->Flink
;
116 while (NextEntry
!= ListHead
)
119 BlockEntry
= CONTAINING_RECORD(NextEntry
,
122 LocalStatus
= MmBapFreeBlockAllocatorDescriptor(BlockInfo
,
124 if (!NT_SUCCESS(LocalStatus
))
126 /* Remember status on failure only */
127 Status
= LocalStatus
;
131 /* Drop a reference */
132 BlockInfo
->ReferenceCount
--;
136 /* There aren't any references, so why are we being called? */
137 Status
= STATUS_INVALID_PARAMETER
;
142 /* No block exists with this ID */
143 Status
= STATUS_UNSUCCESSFUL
;
151 MmBapFreeBlockAllocatorTableEntry (
156 PBL_BLOCK_DESCRIPTOR BlockInfo
= (PBL_BLOCK_DESCRIPTOR
)Entry
;
157 NTSTATUS Status
, LocalStatus
;
160 Status
= STATUS_SUCCESS
;
162 /* Check if there was at least one reference */
163 if (BlockInfo
->ReferenceCount
> 1)
165 /* Try to delete the allocator */
166 LocalStatus
= BlpMmDeleteBlockAllocator(BlockInfo
->BlockId
);
167 if (!NT_SUCCESS(LocalStatus
))
169 /* Remember status on failure only */
170 Status
= LocalStatus
;
174 /* Now destroy the allocator's descriptor */
175 LocalStatus
= BlMmFreeHeap(BlockInfo
);
176 if (!NT_SUCCESS(LocalStatus
))
178 /* Remember status on failure only */
179 Status
= LocalStatus
;
182 /* Free the entry, and return failure, if any */
183 MmBlockAllocatorTable
[Index
] = NULL
;
188 MmBapPurgeBlockAllocatorTableEntry (
192 PBL_BLOCK_DESCRIPTOR BlockInfo
= (PBL_BLOCK_DESCRIPTOR
)Entry
;
195 /* Check if there's a reference on the block descriptor */
196 if (BlockInfo
->ReferenceCount
)
198 /* Don't allow purging */
199 Status
= STATUS_UNSUCCESSFUL
;
204 Status
= MmBapFreeBlockAllocatorTableEntry(BlockInfo
,
208 /* Return purge status */
213 BlpMmCreateBlockAllocator (
217 PBL_BLOCK_DESCRIPTOR BlockInfo
;
221 /* If the block allocator isn't initialized, bail out */
223 if (!MmBlockAllocatorInitialized
)
228 /* Allocate a block descriptor and zero it out */
229 BlockInfo
= BlMmAllocateHeap(sizeof(*BlockInfo
));
234 RtlZeroMemory(BlockInfo
, sizeof(*BlockInfo
));
236 /* Setup the block descriptor */
237 BlockInfo
->Attributes
= 0;
238 BlockInfo
->Type
= BlLoaderBlockMemory
;
239 BlockInfo
->Unknown
= 1;
240 BlockInfo
->Unknown2
= 1;
241 BlockInfo
->Size
= PAGE_SIZE
;
242 BlockInfo
->Count
= 128;
243 BlockInfo
->Count2
= 128;
244 InitializeListHead(&BlockInfo
->ListHead
);
246 /* Add it to the list of block descriptors */
247 Status
= BlTblSetEntry(&MmBlockAllocatorTable
,
248 &MmBlockAllocatorTableEntries
,
251 MmBapPurgeBlockAllocatorTableEntry
);
252 if (NT_SUCCESS(Status
))
254 /* Add the initial reference and store the block ID */
255 BlockInfo
->ReferenceCount
= 1;
256 BlockInfo
->BlockId
= BlockId
;
260 /* On failure, free the block descriptor */
263 BlMmFreeHeap(BlockInfo
);
266 /* Return the block descriptor ID, or -1 on failure */
278 /* Allocate 8 table entries */
279 MmBlockAllocatorTableEntries
= 8;
280 Size
= sizeof(BL_BLOCK_DESCRIPTOR
) * MmBlockAllocatorTableEntries
;
281 MmBlockAllocatorTable
= BlMmAllocateHeap(Size
);
282 if (MmBlockAllocatorTable
)
284 /* Zero them out -- we're all done */
285 Status
= STATUS_SUCCESS
;
286 RtlZeroMemory(MmBlockAllocatorTable
, Size
);
287 MmBlockAllocatorInitialized
= 1;
291 /* Bail out since we're out of memory */
292 Status
= STATUS_NO_MEMORY
;
293 MmBlockAllocatorInitialized
= 0;
296 /* Return initialization status */