Parcourir la source

Kernel: Merge x86_64 and aarch64 init.cpp files

Timon Kruiper il y a 2 ans
Parent
commit
bd2011406e
4 fichiers modifiés avec 62 ajouts et 217 suppressions
  1. 9 30
      Kernel/Arch/aarch64/Dummy.cpp
  2. 0 180
      Kernel/Arch/aarch64/init.cpp
  3. 52 4
      Kernel/Arch/init.cpp
  4. 1 3
      Kernel/CMakeLists.txt

+ 9 - 30
Kernel/Arch/aarch64/Dummy.cpp

@@ -8,6 +8,7 @@
 #include <AK/Types.h>
 
 #include <Kernel/Arch/Delay.h>
+#include <Kernel/Bus/PCI/Initializer.h>
 #include <Kernel/Process.h>
 #include <Kernel/Sections.h>
 #include <Kernel/kstdio.h>
@@ -28,38 +29,16 @@ namespace Kernel::PCI {
 bool g_pci_access_io_probe_failed { false };
 bool g_pci_access_is_disabled_from_commandline { true };
 
+void initialize()
+{
+    dbgln("PCI: FIXME: Enable PCI for aarch64 platforms");
+    g_pci_access_io_probe_failed = true;
 }
 
-// x86 init
-
-multiboot_module_entry_t multiboot_copy_boot_modules_array[16];
-size_t multiboot_copy_boot_modules_count;
-
-extern "C" {
-READONLY_AFTER_INIT PhysicalAddress start_of_prekernel_image;
-READONLY_AFTER_INIT PhysicalAddress end_of_prekernel_image;
-READONLY_AFTER_INIT size_t physical_to_virtual_offset;
-// READONLY_AFTER_INIT FlatPtr kernel_mapping_base;
-READONLY_AFTER_INIT FlatPtr kernel_load_base;
-READONLY_AFTER_INIT PhysicalAddress boot_pml4t;
-READONLY_AFTER_INIT PhysicalAddress boot_pdpt;
-READONLY_AFTER_INIT PhysicalAddress boot_pd0;
-READONLY_AFTER_INIT PhysicalAddress boot_pd_kernel;
-READONLY_AFTER_INIT Kernel::Memory::PageTableEntry* boot_pd_kernel_pt1023;
-READONLY_AFTER_INIT char const* kernel_cmdline;
-READONLY_AFTER_INIT u32 multiboot_flags;
-READONLY_AFTER_INIT multiboot_memory_map_t* multiboot_memory_map;
-READONLY_AFTER_INIT size_t multiboot_memory_map_count;
-READONLY_AFTER_INIT multiboot_module_entry_t* multiboot_modules;
-READONLY_AFTER_INIT size_t multiboot_modules_count;
-READONLY_AFTER_INIT PhysicalAddress multiboot_framebuffer_addr;
-READONLY_AFTER_INIT u32 multiboot_framebuffer_pitch;
-READONLY_AFTER_INIT u32 multiboot_framebuffer_width;
-READONLY_AFTER_INIT u32 multiboot_framebuffer_height;
-READONLY_AFTER_INIT u8 multiboot_framebuffer_bpp;
-READONLY_AFTER_INIT u8 multiboot_framebuffer_type;
 }
 
-extern "C" {
-FlatPtr kernel_mapping_base;
+// kprintf.cpp
+void set_serial_debug_enabled(bool)
+{
+    dbgln("FIXME: Add support for changing state of serial debugging");
 }

+ 0 - 180
Kernel/Arch/aarch64/init.cpp

@@ -1,180 +0,0 @@
-/*
- * Copyright (c) 2021, Nico Weber <thakis@chromium.org>
- * Copyright (c) 2021, Marcin Undak <mcinek@gmail.com>
- * Copyright (c) 2021, Jesse Buhagiar <jooster669@gmail.com>
- * Copyright (c) 2022, the SerenityOS developers.
- * Copyright (c) 2022, Filiph Sandström <filiph.sandstrom@filfatstudios.com>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
-
-#include <AK/Format.h>
-#include <AK/Types.h>
-
-#include <Kernel/Arch/InterruptManagement.h>
-#include <Kernel/Arch/Interrupts.h>
-#include <Kernel/Arch/Processor.h>
-#include <Kernel/Arch/aarch64/ASM_wrapper.h>
-#include <Kernel/Arch/aarch64/BootPPMParser.h>
-#include <Kernel/Arch/aarch64/CPU.h>
-#include <Kernel/Arch/aarch64/RPi/Framebuffer.h>
-#include <Kernel/Arch/aarch64/RPi/Mailbox.h>
-#include <Kernel/Arch/aarch64/RPi/UART.h>
-#include <Kernel/Arch/aarch64/Registers.h>
-#include <Kernel/Arch/aarch64/TrapFrame.h>
-#include <Kernel/CommandLine.h>
-#include <Kernel/Devices/DeviceManagement.h>
-#include <Kernel/FileSystem/VirtualFileSystem.h>
-#include <Kernel/Graphics/Console/BootFramebufferConsole.h>
-#include <Kernel/KSyms.h>
-#include <Kernel/Memory/MemoryManager.h>
-#include <Kernel/Panic.h>
-#include <Kernel/Scheduler.h>
-#include <Kernel/Storage/StorageManagement.h>
-#include <Kernel/TTY/VirtualConsole.h>
-
-typedef void (*ctor_func_t)();
-extern ctor_func_t start_heap_ctors[];
-extern ctor_func_t end_heap_ctors[];
-extern ctor_func_t start_ctors[];
-extern ctor_func_t end_ctors[];
-
-// FIXME: Share this with the Intel Prekernel.
-extern uintptr_t __stack_chk_guard;
-uintptr_t __stack_chk_guard;
-
-READONLY_AFTER_INIT bool g_in_early_boot;
-
-namespace Kernel {
-
-extern "C" [[noreturn]] void halt();
-extern "C" [[noreturn]] void init();
-
-ALWAYS_INLINE static Processor& bootstrap_processor()
-{
-    alignas(Processor) static u8 bootstrap_processor_storage[sizeof(Processor)];
-    return (Processor&)bootstrap_processor_storage;
-}
-
-Atomic<Graphics::Console*> g_boot_console;
-
-VirtualConsole* tty0;
-ProcessID g_init_pid { 0 };
-
-static void init_stage2(void*);
-void init_stage2(void*)
-{
-    Process::register_new(Process::current());
-
-    auto firmware_version = RPi::Mailbox::the().query_firmware_version();
-    dmesgln("RPi: Firmware version: {}", firmware_version);
-
-    VirtualFileSystem::initialize();
-
-    StorageManagement::the().initialize(kernel_command_line().root_device(), kernel_command_line().is_force_pio(), kernel_command_line().is_nvme_polling_enabled());
-    if (VirtualFileSystem::the().mount_root(StorageManagement::the().root_filesystem()).is_error()) {
-        PANIC("VirtualFileSystem::mount_root failed");
-    }
-
-    // Switch out of early boot mode.
-    g_in_early_boot = false;
-
-    LockRefPtr<Thread> thread;
-    auto userspace_init = kernel_command_line().userspace_init();
-    auto init_args = kernel_command_line().userspace_init_args();
-
-    auto init_or_error = Process::try_create_user_process(thread, userspace_init, UserID(0), GroupID(0), move(init_args), {}, tty0);
-    if (init_or_error.is_error())
-        PANIC("init_stage2: Error spawning init process: {}", init_or_error.error());
-
-    g_init_pid = init_or_error.value()->pid();
-
-    thread->set_priority(THREAD_PRIORITY_HIGH);
-
-    Process::current().sys$exit(0);
-    VERIFY_NOT_REACHED();
-}
-
-extern "C" [[noreturn]] void init()
-{
-    g_in_early_boot = true;
-
-    // FIXME: Don't hardcode this
-    multiboot_memory_map_t mmap[] = {
-        { sizeof(struct multiboot_mmap_entry) - sizeof(u32),
-            (u64)0x0,
-            (u64)0x3F000000,
-            MULTIBOOT_MEMORY_AVAILABLE }
-    };
-
-    multiboot_memory_map = mmap;
-    multiboot_memory_map_count = 1;
-
-    dbgln("Welcome to Serenity OS!");
-    dbgln("Imagine this being your ideal operating system.");
-    dbgln("Observed deviations from that ideal are shortcomings of your imagination.");
-    dbgln();
-
-    CommandLine::early_initialize("");
-
-    new (&bootstrap_processor()) Processor();
-    bootstrap_processor().early_initialize(0);
-
-    // We call the constructors of kmalloc.cpp separately, because other constructors in the Kernel
-    // might rely on being able to call new/kmalloc in the constructor. We do have to run the
-    // kmalloc constructors, because kmalloc_init relies on that.
-    for (ctor_func_t* ctor = start_heap_ctors; ctor < end_heap_ctors; ctor++)
-        (*ctor)();
-    kmalloc_init();
-
-    bootstrap_processor().initialize(0);
-
-    load_kernel_symbol_table();
-
-    CommandLine::initialize();
-
-    dmesgln("Starting SerenityOS...");
-
-    Memory::MemoryManager::initialize(0);
-    DeviceManagement::initialize();
-    SysFSComponentRegistry::initialize();
-    DeviceManagement::the().attach_null_device(*NullDevice::must_initialize());
-
-    // Invoke all static global constructors in the kernel.
-    // Note that we want to do this as early as possible.
-    for (ctor_func_t* ctor = start_ctors; ctor < end_ctors; ctor++)
-        (*ctor)();
-
-    RPi::Framebuffer::initialize();
-
-    auto& framebuffer = RPi::Framebuffer::the();
-    if (framebuffer.initialized()) {
-        g_boot_console = &try_make_lock_ref_counted<Graphics::BootFramebufferConsole>(PhysicalAddress((PhysicalPtr)framebuffer.gpu_buffer()), framebuffer.width(), framebuffer.height(), framebuffer.pitch()).value().leak_ref();
-        framebuffer.draw_logo(static_cast<Graphics::BootFramebufferConsole*>(g_boot_console.load())->unsafe_framebuffer_data());
-    }
-
-    initialize_interrupts();
-    InterruptManagement::initialize();
-    Processor::enable_interrupts();
-
-    // Note: We have to disable interrupts otherwise Scheduler::timer_tick might be called before the scheduler is started.
-    Processor::disable_interrupts();
-    TimeManagement::initialize(0);
-
-    Process::initialize();
-    Scheduler::initialize();
-
-    {
-        LockRefPtr<Thread> init_stage2_thread;
-        (void)Process::create_kernel_process(init_stage2_thread, KString::must_create("init_stage2"sv), init_stage2, nullptr, THREAD_AFFINITY_DEFAULT, Process::RegisterProcess::No);
-        // We need to make sure we drop the reference for init_stage2_thread
-        // before calling into Scheduler::start, otherwise we will have a
-        // dangling Thread that never gets cleaned up
-    }
-
-    Scheduler::start();
-
-    VERIFY_NOT_REACHED();
-}
-
-}

+ 52 - 4
Kernel/Arch/x86_64/init.cpp → Kernel/Arch/init.cpp

@@ -7,9 +7,6 @@
 #include <AK/Types.h>
 #include <Kernel/Arch/InterruptManagement.h>
 #include <Kernel/Arch/Processor.h>
-#include <Kernel/Arch/x86_64/Hypervisor/VMWareBackdoor.h>
-#include <Kernel/Arch/x86_64/Interrupts/APIC.h>
-#include <Kernel/Arch/x86_64/Interrupts/PIC.h>
 #include <Kernel/BootInfo.h>
 #include <Kernel/Bus/PCI/Access.h>
 #include <Kernel/Bus/PCI/Initializer.h>
@@ -59,6 +56,15 @@
 #include <Kernel/WorkQueue.h>
 #include <Kernel/kstdio.h>
 
+#if ARCH(X86_64)
+#    include <Kernel/Arch/x86_64/Hypervisor/VMWareBackdoor.h>
+#    include <Kernel/Arch/x86_64/Interrupts/APIC.h>
+#    include <Kernel/Arch/x86_64/Interrupts/PIC.h>
+#elif ARCH(AARCH64)
+#    include <Kernel/Arch/aarch64/RPi/Framebuffer.h>
+#    include <Kernel/Arch/aarch64/RPi/Mailbox.h>
+#endif
+
 // Defined in the linker script
 typedef void (*ctor_func_t)();
 extern ctor_func_t start_heap_ctors[];
@@ -69,10 +75,12 @@ extern ctor_func_t end_ctors[];
 extern uintptr_t __stack_chk_guard;
 READONLY_AFTER_INIT uintptr_t __stack_chk_guard __attribute__((used));
 
+#if ARCH(X86_64)
 extern "C" u8 start_of_safemem_text[];
 extern "C" u8 end_of_safemem_text[];
 extern "C" u8 start_of_safemem_atomic_text[];
 extern "C" u8 end_of_safemem_atomic_text[];
+#endif
 
 extern "C" u8 end_of_kernel_image[];
 
@@ -141,10 +149,11 @@ READONLY_AFTER_INIT u8 multiboot_framebuffer_type;
 
 Atomic<Graphics::Console*> g_boot_console;
 
-extern "C" [[noreturn]] UNMAP_AFTER_INIT void init(BootInfo const& boot_info)
+extern "C" [[noreturn]] UNMAP_AFTER_INIT void init([[maybe_unused]] BootInfo const& boot_info)
 {
     g_in_early_boot = true;
 
+#if ARCH(X86_64)
     start_of_prekernel_image = PhysicalAddress { boot_info.start_of_prekernel_image };
     end_of_prekernel_image = PhysicalAddress { boot_info.end_of_prekernel_image };
     physical_to_virtual_offset = boot_info.physical_to_virtual_offset;
@@ -169,6 +178,22 @@ extern "C" [[noreturn]] UNMAP_AFTER_INIT void init(BootInfo const& boot_info)
     multiboot_framebuffer_height = boot_info.multiboot_framebuffer_height;
     multiboot_framebuffer_bpp = boot_info.multiboot_framebuffer_bpp;
     multiboot_framebuffer_type = boot_info.multiboot_framebuffer_type;
+#elif ARCH(AARCH64)
+    // FIXME: For the aarch64 platforms, we should get the information by parsing a device tree instead of using multiboot.
+    multiboot_memory_map_t mmap[] = {
+        { sizeof(struct multiboot_mmap_entry) - sizeof(u32),
+            (u64)0x0,
+            (u64)0x3F000000,
+            MULTIBOOT_MEMORY_AVAILABLE }
+    };
+    multiboot_memory_map = mmap;
+    multiboot_memory_map_count = 1;
+
+    multiboot_module_entry_t modules[] = {};
+    multiboot_modules = modules;
+    multiboot_modules_count = 0;
+    kernel_cmdline = "";
+#endif
 
     setup_serial_debug();
 
@@ -193,12 +218,22 @@ extern "C" [[noreturn]] UNMAP_AFTER_INIT void init(BootInfo const& boot_info)
     CommandLine::initialize();
     Memory::MemoryManager::initialize(0);
 
+#if ARCH(AARCH64)
+    auto firmware_version = RPi::Mailbox::the().query_firmware_version();
+    dmesgln("RPi: Firmware version: {}", firmware_version);
+
+    RPi::Framebuffer::initialize();
+#endif
+
     // NOTE: If the bootloader provided a framebuffer, then set up an initial console.
     // If the bootloader didn't provide a framebuffer, then set up an initial text console.
     // We do so we can see the output on the screen as soon as possible.
     if (!kernel_command_line().is_early_boot_console_disabled()) {
         if (!multiboot_framebuffer_addr.is_null() && multiboot_framebuffer_type == MULTIBOOT_FRAMEBUFFER_TYPE_RGB) {
             g_boot_console = &try_make_lock_ref_counted<Graphics::BootFramebufferConsole>(multiboot_framebuffer_addr, multiboot_framebuffer_width, multiboot_framebuffer_height, multiboot_framebuffer_pitch).value().leak_ref();
+#if ARCH(AARCH64)
+            RPi::Framebuffer::the().draw_logo(static_cast<Graphics::BootFramebufferConsole*>(g_boot_console.load())->unsafe_framebuffer_data());
+#endif
         } else {
             g_boot_console = &Graphics::VGATextModeConsole::initialize().leak_ref();
         }
@@ -213,9 +248,11 @@ extern "C" [[noreturn]] UNMAP_AFTER_INIT void init(BootInfo const& boot_info)
 
     MM.unmap_prekernel();
 
+#if ARCH(X86_64)
     // Ensure that the safemem sections are not empty. This could happen if the linker accidentally discards the sections.
     VERIFY(+start_of_safemem_text != +end_of_safemem_text);
     VERIFY(+start_of_safemem_atomic_text != +end_of_safemem_atomic_text);
+#endif
 
     // Invoke all static global constructors in the kernel.
     // Note that we want to do this as early as possible.
@@ -234,12 +271,15 @@ extern "C" [[noreturn]] UNMAP_AFTER_INIT void init(BootInfo const& boot_info)
 
     Scheduler::initialize();
 
+#if ARCH(X86_64)
+    // FIXME: Add an abstraction for the smp related functions, instead of using ifdefs in this file.
     if (APIC::initialized() && APIC::the().enabled_processor_count() > 1) {
         // We must set up the AP boot environment before switching to a kernel process,
         // as pages below address USER_RANGE_BASE are only accessible through the kernel
         // page directory.
         APIC::the().setup_ap_boot_environment();
     }
+#endif
 
     {
         LockRefPtr<Thread> init_stage2_thread;
@@ -253,6 +293,7 @@ extern "C" [[noreturn]] UNMAP_AFTER_INIT void init(BootInfo const& boot_info)
     VERIFY_NOT_REACHED();
 }
 
+#if ARCH(X86_64)
 //
 // This is where C++ execution begins for APs, after boot.S transfers control here.
 //
@@ -284,6 +325,7 @@ extern "C" UNMAP_AFTER_INIT void init_finished(u32 cpu)
         TimeManagement::initialize(cpu);
     }
 }
+#endif
 
 void init_stage2(void*)
 {
@@ -294,6 +336,7 @@ void init_stage2(void*)
 
     WorkQueue::initialize();
 
+#if ARCH(X86_64)
     if (kernel_command_line().is_smp_enabled() && APIC::initialized() && APIC::the().enabled_processor_count() > 1) {
         // We can't start the APs until we have a scheduler up and running.
         // We need to be able to process ICI messages, otherwise another
@@ -301,6 +344,7 @@ void init_stage2(void*)
         // exhausted
         APIC::the().boot_aps();
     }
+#endif
 
     // Initialize the PCI Bus as early as possible, for early boot (PCI based) serial logging
     PCI::initialize();
@@ -310,13 +354,17 @@ void init_stage2(void*)
 
     VirtualFileSystem::initialize();
 
+#if ARCH(X86_64)
     if (!is_serial_debug_enabled())
         (void)SerialDevice::must_create(0).leak_ref();
     (void)SerialDevice::must_create(1).leak_ref();
     (void)SerialDevice::must_create(2).leak_ref();
     (void)SerialDevice::must_create(3).leak_ref();
+#endif
 
+#if ARCH(X86_64)
     VMWareBackdoor::the(); // don't wait until first mouse packet
+#endif
     MUST(HIDManagement::initialize());
 
     GraphicsManagement::the().initialize();

+ 1 - 3
Kernel/CMakeLists.txt

@@ -17,6 +17,7 @@ set(KERNEL_HEAP_SOURCES
 
 set(KERNEL_SOURCES
     AddressSanitizer.cpp
+    Arch/init.cpp
     Arch/PageFault.cpp
     Arch/DeferredCallPool.cpp
     Bus/PCI/Controller/HostController.cpp
@@ -361,8 +362,6 @@ set(KERNEL_SOURCES
 if ("${SERENITY_ARCH}" STREQUAL "x86_64")
     set(KERNEL_SOURCES
         ${KERNEL_SOURCES}
-        Arch/x86_64/init.cpp
-
         Arch/Processor.cpp
 
         Arch/x86_64/CMOS.cpp
@@ -462,7 +461,6 @@ elseif("${SERENITY_ARCH}" STREQUAL "aarch64")
         Arch/aarch64/CPUID.cpp
         Arch/aarch64/CurrentTime.cpp
         Arch/aarch64/Dummy.cpp
-        Arch/aarch64/init.cpp
         Arch/aarch64/InterruptManagement.cpp
         Arch/aarch64/Interrupts.cpp
         Arch/aarch64/kprintf.cpp