mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 02:07:36 +00:00
Kernel/riscv64: Take the memory map from the FDT and dump it
For this the BootInfo struct was made architecture specific
This commit is contained in:
parent
21a21c6a11
commit
d3f6b03733
10 changed files with 368 additions and 119 deletions
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
#include <AK/Types.h>
|
||||
#include <Kernel/Arch/CPU.h>
|
||||
#include <Kernel/Arch/InterruptManagement.h>
|
||||
#include <Kernel/Arch/Processor.h>
|
||||
#include <Kernel/Boot/BootInfo.h>
|
||||
|
@ -217,29 +218,7 @@ extern "C" [[noreturn]] UNMAP_AFTER_INIT void init([[maybe_unused]] BootInfo con
|
|||
// FIXME: Read the /chosen/bootargs property.
|
||||
kernel_cmdline = RPi::Mailbox::the().query_kernel_command_line(s_command_line_buffer);
|
||||
#elif ARCH(RISCV64)
|
||||
// FIXME: Get the actual memory map from the device tree.
|
||||
static multiboot_memory_map_t mmap[] = {
|
||||
{
|
||||
// We currently can't get the actual size of firmware-reserved memory, so mark the first 0x20'0000 bytes as reserved.
|
||||
// This reserved memory region should be large enough for now.
|
||||
sizeof(multiboot_mmap_entry) - sizeof(u32),
|
||||
0x8000'0000,
|
||||
0x20'0000,
|
||||
MULTIBOOT_MEMORY_RESERVED,
|
||||
},
|
||||
{
|
||||
sizeof(multiboot_mmap_entry) - sizeof(u32),
|
||||
0x8020'0000,
|
||||
1 * GiB - 0x20'0000,
|
||||
MULTIBOOT_MEMORY_AVAILABLE,
|
||||
},
|
||||
};
|
||||
|
||||
multiboot_memory_map = mmap;
|
||||
multiboot_memory_map_count = array_size(mmap);
|
||||
multiboot_modules = nullptr;
|
||||
multiboot_modules_count = 0;
|
||||
|
||||
// FIXME: Take this from the flattened device tree (/chosen/bootargs)
|
||||
kernel_cmdline = "serial_debug"sv;
|
||||
#endif
|
||||
|
||||
|
@ -308,6 +287,11 @@ extern "C" [[noreturn]] UNMAP_AFTER_INIT void init([[maybe_unused]] BootInfo con
|
|||
InterruptManagement::initialize();
|
||||
ACPI::initialize();
|
||||
|
||||
#if ARCH(RISCV64)
|
||||
// FIXME: Unflatten the device tree and use it for device discovery
|
||||
dump_fdt();
|
||||
#endif
|
||||
|
||||
// Initialize TimeManagement before using randomness!
|
||||
TimeManagement::initialize(0);
|
||||
|
||||
|
|
25
Kernel/Arch/riscv64/CPU.cpp
Normal file
25
Kernel/Arch/riscv64/CPU.cpp
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Leon Albrecht <leon.a@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <Kernel/Arch/riscv64/CPU.h>
|
||||
#include <Kernel/Memory/MemoryManager.h>
|
||||
#include <Userland/Libraries/LibDeviceTree/FlattenedDeviceTree.h>
|
||||
#include <Userland/Libraries/LibDeviceTree/Validation.h>
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
BootInfo s_boot_info;
|
||||
|
||||
alignas(PAGE_SIZE) __attribute__((section(".bss.fdt"))) u8 s_fdt_storage[fdt_storage_size];
|
||||
|
||||
void dump_fdt()
|
||||
{
|
||||
auto& header = *bit_cast<DeviceTree::FlattenedDeviceTreeHeader*>(&s_fdt_storage[0]);
|
||||
auto fdt = ReadonlyBytes(s_fdt_storage, header.totalsize);
|
||||
MUST(DeviceTree::dump(header, fdt));
|
||||
}
|
||||
|
||||
}
|
|
@ -6,5 +6,18 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <Kernel/Memory/PhysicalAddress.h>
|
||||
#include <Kernel/Prekernel/Prekernel.h>
|
||||
|
||||
#include <AK/Platform.h>
|
||||
VALIDATE_IS_RISCV64()
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
constexpr size_t fdt_storage_size = 2 * MiB;
|
||||
extern u8 s_fdt_storage[fdt_storage_size];
|
||||
|
||||
extern BootInfo s_boot_info;
|
||||
|
||||
void dump_fdt();
|
||||
}
|
||||
|
|
|
@ -6,12 +6,14 @@
|
|||
|
||||
#include <AK/Types.h>
|
||||
|
||||
#include <Kernel/Arch/riscv64/CPU.h>
|
||||
#include <Kernel/Arch/riscv64/MMU.h>
|
||||
#include <Kernel/Arch/riscv64/PageDirectory.h>
|
||||
#include <Kernel/Arch/riscv64/SBI.h>
|
||||
#include <Kernel/Arch/riscv64/pre_init.h>
|
||||
#include <Kernel/Memory/MemoryManager.h>
|
||||
#include <Kernel/Sections.h>
|
||||
#include <LibDeviceTree/FlattenedDeviceTree.h>
|
||||
|
||||
// These come from the linker script
|
||||
extern u8 page_tables_phys_start[];
|
||||
|
@ -173,10 +175,11 @@ static UNMAP_AFTER_INIT void setup_kernel_page_directory(u64* root_table)
|
|||
}
|
||||
|
||||
// This function has to fit into one page as it will be identity mapped.
|
||||
[[gnu::aligned(PAGE_SIZE)]] [[noreturn]] UNMAP_AFTER_INIT static void enable_paging(FlatPtr satp, u64* enable_paging_pte)
|
||||
[[gnu::aligned(PAGE_SIZE)]] [[noreturn]] UNMAP_AFTER_INIT static void enable_paging(BootInfo const& info, FlatPtr satp, u64* enable_paging_pte)
|
||||
{
|
||||
// Switch current root page table to argument 0. This will immediately take effect, but we won't not crash as this function is identity mapped.
|
||||
// Also, set up a temporary trap handler to catch any traps while switching page tables.
|
||||
register FlatPtr a0 asm("a0") = bit_cast<FlatPtr>(&info);
|
||||
asm volatile(
|
||||
" lla t0, 1f \n"
|
||||
" csrw stvec, t0 \n"
|
||||
|
@ -210,21 +213,33 @@ static UNMAP_AFTER_INIT void setup_kernel_page_directory(u64* root_table)
|
|||
" wfi \n"
|
||||
" j 1b \n"
|
||||
:
|
||||
: [satp] "r"(satp), [offset] "r"(calculate_physical_to_link_time_address_offset()), [enable_paging_pte] "r"(enable_paging_pte)
|
||||
: "r"(a0), [satp] "r"(satp), [offset] "r"(calculate_physical_to_link_time_address_offset()), [enable_paging_pte] "r"(enable_paging_pte)
|
||||
: "t0");
|
||||
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
[[noreturn]] UNMAP_AFTER_INIT void init_page_tables_and_jump_to_init()
|
||||
[[noreturn]] UNMAP_AFTER_INIT void init_page_tables_and_jump_to_init(FlatPtr mhartid, PhysicalPtr fdt_phys_addr)
|
||||
{
|
||||
if (RISCV64::CSR::SATP::read().MODE != RISCV64::CSR::SATP::Mode::Bare)
|
||||
panic_without_mmu("Kernel booted with MMU enabled"sv);
|
||||
|
||||
// Copy the FDT to a known location
|
||||
DeviceTree::FlattenedDeviceTreeHeader* fdt_header = bit_cast<DeviceTree::FlattenedDeviceTreeHeader*>(fdt_phys_addr);
|
||||
u8* fdt_storage = bit_cast<u8*>(fdt_phys_addr);
|
||||
if (fdt_header->totalsize > fdt_storage_size)
|
||||
panic_without_mmu("Passed FDT is bigger than the internal storage"sv);
|
||||
for (size_t o = 0; o < fdt_header->totalsize; o += 1) {
|
||||
// FIXME: Maybe increase the IO size here
|
||||
adjust_by_mapping_base(s_fdt_storage)[o] = fdt_storage[o];
|
||||
}
|
||||
|
||||
*adjust_by_mapping_base(&physical_to_virtual_offset) = calculate_physical_to_link_time_address_offset();
|
||||
*adjust_by_mapping_base(&kernel_mapping_base) = KERNEL_MAPPING_BASE;
|
||||
*adjust_by_mapping_base(&kernel_load_base) = KERNEL_MAPPING_BASE;
|
||||
|
||||
*adjust_by_mapping_base(&s_boot_info) = { .mhartid = mhartid, .fdt_phys_addr = fdt_phys_addr };
|
||||
|
||||
PageBumpAllocator allocator(adjust_by_mapping_base(reinterpret_cast<u64*>(page_tables_phys_start)), adjust_by_mapping_base(reinterpret_cast<u64*>(page_tables_phys_end)));
|
||||
auto* root_table = allocator.take_page();
|
||||
build_mappings(allocator, root_table);
|
||||
|
@ -247,7 +262,7 @@ static UNMAP_AFTER_INIT void setup_kernel_page_directory(u64* root_table)
|
|||
.MODE = RISCV64::CSR::SATP::Mode::Sv39,
|
||||
};
|
||||
|
||||
enable_paging(bit_cast<FlatPtr>(satp), &enable_paging_level0_table[enable_paging_vpn_0]);
|
||||
enable_paging(s_boot_info, bit_cast<FlatPtr>(satp), &enable_paging_level0_table[enable_paging_vpn_0]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,12 +7,13 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/Forward.h>
|
||||
#include <Kernel/Prekernel/Prekernel.h>
|
||||
|
||||
#include <AK/Platform.h>
|
||||
VALIDATE_IS_RISCV64()
|
||||
|
||||
namespace Kernel::Memory {
|
||||
|
||||
[[noreturn]] void init_page_tables_and_jump_to_init();
|
||||
[[noreturn]] void init_page_tables_and_jump_to_init(FlatPtr mhartid, PhysicalPtr fdt_phys_addr);
|
||||
|
||||
}
|
||||
|
|
|
@ -45,13 +45,11 @@ UNMAP_AFTER_INIT void dbgln_without_mmu(StringView message)
|
|||
|
||||
extern "C" [[noreturn]] UNMAP_AFTER_INIT void pre_init(FlatPtr mhartid, PhysicalPtr fdt_phys_addr)
|
||||
{
|
||||
(void)mhartid;
|
||||
(void)fdt_phys_addr;
|
||||
|
||||
// Catch traps in pre_init
|
||||
RISCV64::CSR::write(RISCV64::CSR::Address::STVEC, bit_cast<FlatPtr>(&early_trap_handler));
|
||||
|
||||
Memory::init_page_tables_and_jump_to_init();
|
||||
Memory::init_page_tables_and_jump_to_init(mhartid, fdt_phys_addr);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue