File indexing completed on 2025-05-11 08:24:10
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #include <bsp.h>
0037 #include <bsp/bootcard.h>
0038
0039 #include <efi.h>
0040 #include <efilib.h>
0041
0042 #include <stdio.h>
0043
0044 extern Heap_Control *RTEMS_Malloc_Heap;
0045
0046 void bsp_memory_heap_extend(void);
0047
0048 extern EFI_BOOT_SERVICES *BS;
0049
0050 static UINT32 total_pages = 0;
0051 static UINT32 allocated_pages = 0;
0052 static UINT32 usable_pages = 0;
0053 static EFI_PHYSICAL_ADDRESS physBuf;
0054
0055 static int error = 0;
0056 static int extension_steps = 0;
0057
0058 #ifdef BSP_EFI_MMAP_PRINTOUT
0059 static const char*
0060 efi_memory_type(EFI_MEMORY_TYPE type);
0061 #endif
0062
0063 void
0064 efi_memory_heap_extend( void );
0065
0066 static UINT64
0067 heap_size(void)
0068 {
0069 return RTEMS_Malloc_Heap->stats.size;
0070 }
0071
0072 static UINT64
0073 allocate_biggest_block( void )
0074 {
0075 UINT64 sz = 0;
0076 EFI_MEMORY_DESCRIPTOR *map = 0, *p = 0;
0077 UINTN key = 0, dsz = 0;
0078 UINT32 dver = 0;
0079 EFI_STATUS status = 0;
0080 int i, ndesc = 0;
0081
0082 UINT64 to_alloc_pages = 0;
0083 bool first_run = false;
0084 if (total_pages == 0)
0085 first_run = true;
0086
0087 status = BS->GetMemoryMap(&sz, 0, &key, &dsz, &dver);
0088 if (status != EFI_BUFFER_TOO_SMALL) {
0089 printf("EFI: Can't determine memory map size\n");
0090 return 0;
0091 }
0092 map = malloc(sz);
0093 if (map == NULL) {
0094 printf("EFI: Can't allocate memory map backing\n");
0095 return 0;
0096 }
0097 status = BS->GetMemoryMap(&sz, map, &key, &dsz, &dver);
0098 if (EFI_ERROR(status)) {
0099 printf("EFI: Can't read memory map\n");
0100 free(map);
0101 return 0;
0102 }
0103 ndesc = sz / dsz;
0104 #ifdef BSP_EFI_MMAP_PRINTOUT
0105 if (first_run)
0106 printf("%23s %12s %8s\n", "Type", "Physical", "#Pages");
0107 #endif
0108 for (i = 0, p = map; i < ndesc;
0109 i++, p = NextMemoryDescriptor(p, dsz)) {
0110 if (first_run) {
0111 #ifdef BSP_EFI_MMAP_PRINTOUT
0112 printf("%23s %012jx %08jx\n", efi_memory_type(p->Type),
0113 (uintmax_t)p->PhysicalStart, (uintmax_t)p->NumberOfPages);
0114 #endif
0115 if (p->Type != EfiReservedMemoryType)
0116 total_pages = total_pages + p->NumberOfPages;
0117 if (p->Type == EfiConventionalMemory) {
0118 usable_pages = usable_pages + p->NumberOfPages;
0119 }
0120 }
0121 if (p->Type == EfiConventionalMemory) {
0122 if (to_alloc_pages < p->NumberOfPages)
0123 to_alloc_pages = p->NumberOfPages;
0124 }
0125 }
0126 status = ST->BootServices->AllocatePages(AllocateAnyPages, EfiLoaderData, to_alloc_pages, &physBuf );
0127 if (EFI_ERROR(status)) {
0128
0129
0130
0131 error++;
0132 status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData, (to_alloc_pages / 2), &physBuf );
0133 if (EFI_ERROR(status)) {
0134 printf("EFI can't allocate: %lu pages nor half of the amount.\n", to_alloc_pages);
0135 free(map);
0136 return 0;
0137 }
0138 else {
0139 to_alloc_pages = to_alloc_pages / 2;
0140 }
0141 }
0142 allocated_pages = allocated_pages + to_alloc_pages;
0143 sz = to_alloc_pages * 4096;
0144 uintptr_t es = 0;
0145 es = _Heap_Extend( RTEMS_Malloc_Heap, (void *)physBuf, sz, 0 );
0146 free(map);
0147 return es;
0148 }
0149
0150 void efi_memory_heap_extend( void )
0151 {
0152 int i;
0153 UINT64 asz = 0;
0154 UINT64 oldsz, newsz = 0;
0155 oldsz = heap_size();
0156 for (i = 0; i < 1024; i++) {
0157
0158 asz = allocate_biggest_block();
0159 if (asz == 0)
0160 break;
0161 extension_steps++;
0162 }
0163 newsz = heap_size();
0164 printf("EFI: Total memory: %u pages, %u megabytes\n", total_pages, (total_pages * 4 / 1024));
0165 printf("EFI: Usable memory: %u pages, %u megabytes\n", usable_pages, (usable_pages * 4 / 1024));
0166 printf("EFI: Allocated memory: %u pages, %u megabytes\n", allocated_pages, (allocated_pages * 4 / 1024));
0167 printf("RTEMS: Heap extended in %u steps with %u steps failed.\n", extension_steps, error);
0168 uint64_t s = newsz - oldsz;
0169 printf("RTEMS: Heap extended by %lu pages, %lu megabytes\n", (s / 4096), ((s / 1024) / 1024));
0170 }
0171
0172 #ifdef BSP_EFI_MMAP_PRINTOUT
0173 static const char*
0174 efi_memory_type(EFI_MEMORY_TYPE type)
0175 {
0176 switch (type) {
0177 case EfiReservedMemoryType:
0178 return "Reserved";
0179 case EfiLoaderCode:
0180 return "LoaderCode";
0181 case EfiLoaderData:
0182 return "LoaderData";
0183 case EfiBootServicesCode:
0184 return "BootServicesCode";
0185 case EfiBootServicesData:
0186 return "BootServicesData";
0187 case EfiRuntimeServicesCode:
0188 return "RuntimeServicesCode";
0189 case EfiRuntimeServicesData:
0190 return "RuntimeServicesData";
0191 case EfiConventionalMemory:
0192 return "ConventionalMemory";
0193 case EfiUnusableMemory:
0194 return "UnusableMemory";
0195 case EfiACPIReclaimMemory:
0196 return "ACPIReclaimMemory";
0197 case EfiACPIMemoryNVS:
0198 return "ACPIMemoryNVS";
0199 case EfiMemoryMappedIO:
0200 return "MemoryMappedIO";
0201 case EfiMemoryMappedIOPortSpace:
0202 return "MemoryMappedIOPortSpace";
0203 case EfiPalCode:
0204 return "PalCode";
0205 case EfiPersistentMemory:
0206 return "PersistentMemory";
0207 default:
0208 return "Unknown Type";
0209 }
0210 }
0211 #endif