Reorganise memory map handling
This commit is contained in:
parent
dda060dd0f
commit
df3df23d5c
51 changed files with 301 additions and 443 deletions
|
@ -29,9 +29,7 @@
|
|||
((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
|
||||
|
||||
grub_err_t
|
||||
grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
|
||||
grub_uint64_t,
|
||||
grub_uint32_t))
|
||||
grub_machine_mmap_iterate (grub_memory_hook_t hook)
|
||||
{
|
||||
grub_efi_uintn_t mmap_size = 0;
|
||||
grub_efi_memory_descriptor_t *map_buf = 0;
|
||||
|
@ -69,7 +67,12 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
|
|||
{
|
||||
case GRUB_EFI_RUNTIME_SERVICES_CODE:
|
||||
hook (desc->physical_start, desc->num_pages * 4096,
|
||||
GRUB_MACHINE_MEMORY_CODE);
|
||||
GRUB_MEMORY_CODE);
|
||||
break;
|
||||
|
||||
case GRUB_EFI_UNUSABLE_MEMORY:
|
||||
hook (desc->physical_start, desc->num_pages * 4096,
|
||||
GRUB_MEMORY_BADRAM);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -78,12 +81,11 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
|
|||
|
||||
case GRUB_EFI_RESERVED_MEMORY_TYPE:
|
||||
case GRUB_EFI_RUNTIME_SERVICES_DATA:
|
||||
case GRUB_EFI_UNUSABLE_MEMORY:
|
||||
case GRUB_EFI_MEMORY_MAPPED_IO:
|
||||
case GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE:
|
||||
case GRUB_EFI_PAL_CODE:
|
||||
hook (desc->physical_start, desc->num_pages * 4096,
|
||||
GRUB_MACHINE_MEMORY_RESERVED);
|
||||
GRUB_MEMORY_RESERVED);
|
||||
break;
|
||||
|
||||
case GRUB_EFI_LOADER_CODE:
|
||||
|
@ -92,17 +94,17 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
|
|||
case GRUB_EFI_BOOT_SERVICES_DATA:
|
||||
case GRUB_EFI_CONVENTIONAL_MEMORY:
|
||||
hook (desc->physical_start, desc->num_pages * 4096,
|
||||
GRUB_MACHINE_MEMORY_AVAILABLE);
|
||||
GRUB_MEMORY_AVAILABLE);
|
||||
break;
|
||||
|
||||
case GRUB_EFI_ACPI_RECLAIM_MEMORY:
|
||||
hook (desc->physical_start, desc->num_pages * 4096,
|
||||
GRUB_MACHINE_MEMORY_ACPI);
|
||||
GRUB_MEMORY_ACPI);
|
||||
break;
|
||||
|
||||
case GRUB_EFI_ACPI_MEMORY_NVS:
|
||||
hook (desc->physical_start, desc->num_pages * 4096,
|
||||
GRUB_MACHINE_MEMORY_NVS);
|
||||
GRUB_MEMORY_NVS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -115,29 +117,26 @@ make_efi_memtype (int type)
|
|||
{
|
||||
switch (type)
|
||||
{
|
||||
case GRUB_MACHINE_MEMORY_CODE:
|
||||
case GRUB_MEMORY_CODE:
|
||||
return GRUB_EFI_RUNTIME_SERVICES_CODE;
|
||||
|
||||
/* No way to remove a chunk of memory from EFI mmap.
|
||||
So mark it as unusable. */
|
||||
case GRUB_MACHINE_MEMORY_HOLE:
|
||||
|
||||
default:
|
||||
|
||||
case GRUB_MACHINE_MEMORY_RESERVED:
|
||||
case GRUB_MEMORY_HOLE:
|
||||
case GRUB_MEMORY_RESERVED:
|
||||
return GRUB_EFI_UNUSABLE_MEMORY;
|
||||
|
||||
case GRUB_MACHINE_MEMORY_AVAILABLE:
|
||||
case GRUB_MEMORY_AVAILABLE:
|
||||
return GRUB_EFI_CONVENTIONAL_MEMORY;
|
||||
|
||||
case GRUB_MACHINE_MEMORY_ACPI:
|
||||
return GRUB_EFI_ACPI_RECLAIM_MEMORY;
|
||||
|
||||
case GRUB_MACHINE_MEMORY_NVS:
|
||||
case GRUB_MEMORY_ACPI:
|
||||
return GRUB_EFI_ACPI_RECLAIM_MEMORY;
|
||||
|
||||
case GRUB_MEMORY_NVS:
|
||||
return GRUB_EFI_ACPI_MEMORY_NVS;
|
||||
}
|
||||
|
||||
return GRUB_EFI_UNUSABLE_MEMORY;
|
||||
}
|
||||
|
||||
struct overlay
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
|
||||
#include <grub/machine/memory.h>
|
||||
#include <grub/i386/memory.h>
|
||||
#include <grub/memory.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/misc.h>
|
||||
|
@ -33,12 +34,12 @@ grub_mmap_malign_and_register (grub_uint64_t align, grub_uint64_t size,
|
|||
grub_uint64_t highestlow = 0;
|
||||
|
||||
auto int NESTED_FUNC_ATTR find_hook (grub_uint64_t, grub_uint64_t,
|
||||
grub_uint32_t);
|
||||
grub_memory_type_t);
|
||||
int NESTED_FUNC_ATTR find_hook (grub_uint64_t start, grub_uint64_t rangesize,
|
||||
grub_uint32_t memtype)
|
||||
grub_memory_type_t memtype)
|
||||
{
|
||||
grub_uint64_t end = start + rangesize;
|
||||
if (memtype != GRUB_MACHINE_MEMORY_AVAILABLE)
|
||||
if (memtype != GRUB_MEMORY_AVAILABLE)
|
||||
return 0;
|
||||
if (end > 0x100000)
|
||||
end = 0x100000;
|
||||
|
|
|
@ -57,7 +57,7 @@ preboot (int noreturn __attribute__ ((unused)))
|
|||
auto int NESTED_FUNC_ATTR fill_hook (grub_uint64_t, grub_uint64_t,
|
||||
grub_uint32_t);
|
||||
int NESTED_FUNC_ATTR fill_hook (grub_uint64_t addr, grub_uint64_t size,
|
||||
grub_uint32_t type)
|
||||
grub_memory_type_t type)
|
||||
{
|
||||
grub_dprintf ("mmap", "mmap chunk %llx-%llx:%x\n", addr, addr + size, type);
|
||||
hookmmapcur->addr = addr;
|
||||
|
@ -135,7 +135,7 @@ malloc_hook (void)
|
|||
grub_uint32_t);
|
||||
int NESTED_FUNC_ATTR count_hook (grub_uint64_t addr __attribute__ ((unused)),
|
||||
grub_uint64_t size __attribute__ ((unused)),
|
||||
grub_uint32_t type __attribute__ ((unused)))
|
||||
grub_memory_type_t type __attribute__ ((unused)))
|
||||
{
|
||||
regcount++;
|
||||
return 0;
|
||||
|
@ -172,7 +172,7 @@ malloc_hook (void)
|
|||
reentry = 1;
|
||||
hooktarget
|
||||
= grub_mmap_malign_and_register (16, hooksize, &mmapregion,
|
||||
GRUB_MACHINE_MEMORY_RESERVED,
|
||||
GRUB_MEMORY_RESERVED,
|
||||
GRUB_MMAP_MALLOC_LOW);
|
||||
reentry = 0;
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
|
||||
#include <grub/memory.h>
|
||||
#include <grub/i386/memory.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/misc.h>
|
||||
|
||||
|
@ -26,11 +27,12 @@ grub_mmap_get_lower (void)
|
|||
{
|
||||
grub_uint64_t lower = 0;
|
||||
|
||||
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
|
||||
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t,
|
||||
grub_memory_type_t);
|
||||
int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
|
||||
grub_uint32_t type)
|
||||
grub_memory_type_t type)
|
||||
{
|
||||
if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
|
||||
if (type != GRUB_MEMORY_AVAILABLE)
|
||||
return 0;
|
||||
if (addr == 0)
|
||||
lower = size;
|
||||
|
@ -48,11 +50,12 @@ grub_mmap_get_upper (void)
|
|||
{
|
||||
grub_uint64_t upper = 0;
|
||||
|
||||
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
|
||||
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t,
|
||||
grub_memory_type_t);
|
||||
int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
|
||||
grub_uint32_t type)
|
||||
grub_memory_type_t type)
|
||||
{
|
||||
if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
|
||||
if (type != GRUB_MEMORY_AVAILABLE)
|
||||
return 0;
|
||||
if (addr <= 0x100000 && addr + size > 0x100000)
|
||||
upper = addr + size - 0x100000;
|
||||
|
@ -69,11 +72,12 @@ grub_mmap_get_post64 (void)
|
|||
{
|
||||
grub_uint64_t post64 = 0;
|
||||
|
||||
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
|
||||
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t,
|
||||
grub_memory_type_t);
|
||||
int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
|
||||
grub_uint32_t type)
|
||||
grub_memory_type_t type)
|
||||
{
|
||||
if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
|
||||
if (type != GRUB_MEMORY_AVAILABLE)
|
||||
return 0;
|
||||
if (addr <= 0x4000000 && addr + size > 0x4000000)
|
||||
post64 = addr + size - 0x4000000;
|
||||
|
|
|
@ -27,11 +27,12 @@ grub_mmap_get_lower (void)
|
|||
{
|
||||
grub_uint64_t lower = 0;
|
||||
|
||||
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
|
||||
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t,
|
||||
grub_memory_type_t);
|
||||
int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
|
||||
grub_uint32_t type)
|
||||
grub_memory_type_t type)
|
||||
{
|
||||
if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
|
||||
if (type != GRUB_MEMORY_AVAILABLE)
|
||||
return 0;
|
||||
if (addr == 0)
|
||||
lower = size;
|
||||
|
@ -49,11 +50,12 @@ grub_mmap_get_upper (void)
|
|||
{
|
||||
grub_uint64_t upper = 0;
|
||||
|
||||
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
|
||||
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t,
|
||||
grub_memory_type_t);
|
||||
int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
|
||||
grub_uint32_t type)
|
||||
grub_memory_type_t type)
|
||||
{
|
||||
if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
|
||||
if (type != GRUB_MEMORY_AVAILABLE)
|
||||
return 0;
|
||||
if (addr <= GRUB_ARCH_HIGHMEMPSTART && addr + size
|
||||
> GRUB_ARCH_HIGHMEMPSTART)
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/machine/memory.h>
|
||||
#include <grub/memory.h>
|
||||
#include <grub/machine/memory.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/mm.h>
|
||||
|
@ -34,8 +34,7 @@ static int curhandle = 1;
|
|||
#endif
|
||||
|
||||
grub_err_t
|
||||
grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
|
||||
grub_uint64_t, grub_uint32_t))
|
||||
grub_mmap_iterate (grub_memory_hook_t hook)
|
||||
{
|
||||
|
||||
/* This function resolves overlapping regions and sorts the memory map.
|
||||
|
@ -48,27 +47,17 @@ grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
|
|||
3 - unusable memory
|
||||
4 - a range deliberately empty
|
||||
*/
|
||||
int priority[GRUB_MACHINE_MEMORY_MAX_TYPE + 2] =
|
||||
int priority[] =
|
||||
{
|
||||
#ifdef GRUB_MACHINE_MEMORY_AVAILABLE
|
||||
[GRUB_MACHINE_MEMORY_AVAILABLE] = 1,
|
||||
#endif
|
||||
#if defined (GRUB_MACHINE_MEMORY_RESERVED) && GRUB_MACHINE_MEMORY_RESERVED != GRUB_MACHINE_MEMORY_HOLE
|
||||
[GRUB_MACHINE_MEMORY_RESERVED] = 3,
|
||||
#endif
|
||||
#ifdef GRUB_MACHINE_MEMORY_ACPI
|
||||
[GRUB_MACHINE_MEMORY_ACPI] = 2,
|
||||
#endif
|
||||
#ifdef GRUB_MACHINE_MEMORY_CODE
|
||||
[GRUB_MACHINE_MEMORY_CODE] = 3,
|
||||
#endif
|
||||
#ifdef GRUB_MACHINE_MEMORY_NVS
|
||||
[GRUB_MACHINE_MEMORY_NVS] = 3,
|
||||
#endif
|
||||
[GRUB_MACHINE_MEMORY_HOLE] = 4,
|
||||
[GRUB_MEMORY_AVAILABLE] = 1,
|
||||
[GRUB_MEMORY_RESERVED] = 3,
|
||||
[GRUB_MEMORY_ACPI] = 2,
|
||||
[GRUB_MEMORY_CODE] = 3,
|
||||
[GRUB_MEMORY_NVS] = 3,
|
||||
[GRUB_MEMORY_HOLE] = 4,
|
||||
};
|
||||
|
||||
int i, k, done;
|
||||
int i, done;
|
||||
|
||||
/* Scanline events. */
|
||||
struct grub_mmap_scan
|
||||
|
@ -89,7 +78,7 @@ grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
|
|||
/* Current scanline event. */
|
||||
int curtype;
|
||||
/* How many regions of given type overlap at current location? */
|
||||
int present[GRUB_MACHINE_MEMORY_MAX_TYPE + 2];
|
||||
int present[ARRAY_SIZE (priority)];
|
||||
/* Number of mmap chunks. */
|
||||
int mmap_num;
|
||||
|
||||
|
@ -101,7 +90,7 @@ grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
|
|||
grub_uint32_t);
|
||||
int NESTED_FUNC_ATTR count_hook (grub_uint64_t addr __attribute__ ((unused)),
|
||||
grub_uint64_t size __attribute__ ((unused)),
|
||||
grub_uint32_t type __attribute__ ((unused)))
|
||||
grub_memory_type_t type __attribute__ ((unused)))
|
||||
{
|
||||
mmap_num++;
|
||||
return 0;
|
||||
|
@ -111,17 +100,17 @@ grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
|
|||
grub_uint32_t);
|
||||
int NESTED_FUNC_ATTR fill_hook (grub_uint64_t addr,
|
||||
grub_uint64_t size,
|
||||
grub_uint32_t type)
|
||||
grub_memory_type_t type)
|
||||
{
|
||||
scanline_events[i].pos = addr;
|
||||
scanline_events[i].type = 0;
|
||||
if (type <= GRUB_MACHINE_MEMORY_MAX_TYPE && priority[type])
|
||||
if (type < ARRAY_SIZE (priority) && priority[type])
|
||||
scanline_events[i].memtype = type;
|
||||
else
|
||||
{
|
||||
grub_dprintf ("mmap", "Unknown memory type %d. Assuming unusable\n",
|
||||
type);
|
||||
scanline_events[i].memtype = GRUB_MACHINE_MEMORY_RESERVED;
|
||||
scanline_events[i].memtype = GRUB_MEMORY_RESERVED;
|
||||
}
|
||||
i++;
|
||||
|
||||
|
@ -160,12 +149,10 @@ grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
|
|||
{
|
||||
scanline_events[i].pos = cur->start;
|
||||
scanline_events[i].type = 0;
|
||||
if (cur->type == GRUB_MACHINE_MEMORY_HOLE
|
||||
|| (cur->type >= 0 && cur->type <= GRUB_MACHINE_MEMORY_MAX_TYPE
|
||||
&& priority[cur->type]))
|
||||
if (cur->type < ARRAY_SIZE (priority) && priority[cur->type])
|
||||
scanline_events[i].memtype = cur->type;
|
||||
else
|
||||
scanline_events[i].memtype = GRUB_MACHINE_MEMORY_RESERVED;
|
||||
scanline_events[i].memtype = GRUB_MEMORY_RESERVED;
|
||||
i++;
|
||||
|
||||
scanline_events[i].pos = cur->end;
|
||||
|
@ -201,6 +188,7 @@ grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
|
|||
lasttype = scanline_events[0].memtype;
|
||||
for (i = 0; i < 2 * mmap_num; i++)
|
||||
{
|
||||
unsigned k;
|
||||
/* Process event. */
|
||||
if (scanline_events[i].type)
|
||||
present[scanline_events[i].memtype]--;
|
||||
|
@ -209,7 +197,7 @@ grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
|
|||
|
||||
/* Determine current region type. */
|
||||
curtype = -1;
|
||||
for (k = 0; k <= GRUB_MACHINE_MEMORY_MAX_TYPE + 1; k++)
|
||||
for (k = 0; k < ARRAY_SIZE (priority); k++)
|
||||
if (present[k] && (curtype == -1 || priority[k] > priority[curtype]))
|
||||
curtype = k;
|
||||
|
||||
|
@ -217,7 +205,7 @@ grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
|
|||
if ((curtype == -1 || curtype != lasttype)
|
||||
&& lastaddr != scanline_events[i].pos
|
||||
&& lasttype != -1
|
||||
&& lasttype != GRUB_MACHINE_MEMORY_HOLE
|
||||
&& lasttype != GRUB_MEMORY_HOLE
|
||||
&& hook (lastaddr, scanline_events[i].pos - lastaddr, lasttype))
|
||||
{
|
||||
grub_free (scanline_events);
|
||||
|
@ -324,10 +312,11 @@ grub_cmd_badram (grub_command_t cmd __attribute__ ((unused)),
|
|||
char * str;
|
||||
grub_uint64_t badaddr, badmask;
|
||||
|
||||
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
|
||||
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t,
|
||||
grub_memory_type_t);
|
||||
int NESTED_FUNC_ATTR hook (grub_uint64_t addr,
|
||||
grub_uint64_t size,
|
||||
grub_uint32_t type __attribute__ ((unused)))
|
||||
grub_memory_type_t type __attribute__ ((unused)))
|
||||
{
|
||||
grub_uint64_t iterator, low, high, cur;
|
||||
int tail, var;
|
||||
|
@ -370,7 +359,7 @@ grub_cmd_badram (grub_command_t cmd __attribute__ ((unused)),
|
|||
{
|
||||
grub_dprintf ("badram", "%llx (size %llx) is a badram range\n",
|
||||
(unsigned long long) cur, (1ULL << tail));
|
||||
grub_mmap_register (cur, (1ULL << tail), GRUB_MACHINE_MEMORY_HOLE);
|
||||
grub_mmap_register (cur, (1ULL << tail), GRUB_MEMORY_HOLE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue