From 32b70bb7b5e62037fb2feacef50d552bd724311b Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Thu, 4 Feb 2021 14:26:23 -0800 Subject: [PATCH] x86: multiboot: map memory before accessing if necessary Before accessing the multiboot data passed by the bootloader, we need to map the memory first. This adds the code to map the memory if necessary. Signed-off-by: Daniel Leung --- arch/x86/core/multiboot.c | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/arch/x86/core/multiboot.c b/arch/x86/core/multiboot.c index 27240b1b2eb..cdf0a71cbd9 100644 --- a/arch/x86/core/multiboot.c +++ b/arch/x86/core/multiboot.c @@ -28,8 +28,25 @@ static inline void clear_memmap(int index) } } -void z_multiboot_init(struct multiboot_info *info) +void z_multiboot_init(struct multiboot_info *info_pa) { + struct multiboot_info *info; + +#if defined(CONFIG_ARCH_MAPS_ALL_RAM) || !defined(CONFIG_X86_MMU) + /* + * Since the struct from bootloader resides in memory + * and all memory is mapped, there is no need to + * manually map it before accessing. + * + * Without MMU, all memory are identity-mapped already + * so there is no need to map them again. + */ + info = info_pa; +#else + z_phys_map((uint8_t **)&info, POINTER_TO_UINT(info_pa), + sizeof(*info_pa), K_MEM_CACHE_NONE); +#endif /* CONFIG_ARCH_MAPS_ALL_RAM */ + if (info != NULL) { memcpy(&multiboot_info, info, sizeof(*info)); } @@ -42,12 +59,26 @@ void z_multiboot_init(struct multiboot_info *info) if ((info->flags & MULTIBOOT_INFO_FLAGS_MMAP) && (x86_memmap_source < X86_MEMMAP_SOURCE_MULTIBOOT_MMAP)) { - uint32_t address = info->mmap_addr; + uintptr_t address; + uintptr_t address_end; struct multiboot_mmap *mmap; int index = 0; uint32_t type; - while ((address < (info->mmap_addr + info->mmap_length)) && +#if defined(CONFIG_ARCH_MAPS_ALL_RAM) || !defined(CONFIG_X86_MMU) + address = info->mmap_addr; +#else + uint8_t *address_va; + + z_phys_map(&address_va, info->mmap_addr, info->mmap_length, + K_MEM_CACHE_NONE); + + address = POINTER_TO_UINT(address_va); +#endif /* CONFIG_ARCH_MAPS_ALL_RAM */ + + address_end = address + info->mmap_length; + + while ((address < address_end) && (index < CONFIG_X86_MEMMAP_ENTRIES)) { mmap = UINT_TO_POINTER(address);