diff --git a/Kernel/Arch/aarch64/RPi/Timer.cpp b/Kernel/Arch/aarch64/RPi/Timer.cpp index 1649ce9a39..42ed09bd37 100644 --- a/Kernel/Arch/aarch64/RPi/Timer.cpp +++ b/Kernel/Arch/aarch64/RPi/Timer.cpp @@ -54,7 +54,7 @@ u64 Timer::microseconds_since_boot() bool Timer::handle_irq(RegisterState const&) { - dbgln("Timer fired: {} us", m_current_timer_value); + dmesgln("Timer fired: {} us", m_current_timer_value); m_current_timer_value += m_interrupt_interval; set_compare(TimerID::Timer1, m_current_timer_value); diff --git a/Kernel/Arch/aarch64/TrapFrame.h b/Kernel/Arch/aarch64/TrapFrame.h new file mode 100644 index 0000000000..357c4c41f6 --- /dev/null +++ b/Kernel/Arch/aarch64/TrapFrame.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2018-2021, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +#include + +namespace Kernel { + +struct TrapFrame { + u64 x[31]; // Saved general purpose registers + u64 spsr_el1; // Save Processor Status Register, EL1 + u64 elr_el1; // Exception Link Reigster, EL1 + u64 tpidr_el1; // EL0 thread ID + u64 sp_el0; // EL0 stack pointer +}; + +} diff --git a/Kernel/Arch/aarch64/init.cpp b/Kernel/Arch/aarch64/init.cpp index eb16e949e7..0fc521342b 100644 --- a/Kernel/Arch/aarch64/init.cpp +++ b/Kernel/Arch/aarch64/init.cpp @@ -3,6 +3,7 @@ * Copyright (c) 2021, Marcin Undak * Copyright (c) 2021, Jesse Buhagiar * Copyright (c) 2022, the SerenityOS developers. + * Copyright (c) 2022, Filiph Sandström * * SPDX-License-Identifier: BSD-2-Clause */ @@ -20,19 +21,13 @@ #include #include #include +#include +#include #include #include -struct TrapFrame { - u64 x[31]; // Saved general purpose registers - u64 spsr_el1; // Save Processor Status Register, EL1 - u64 elr_el1; // Exception Link Reigster, EL1 - u64 tpidr_el1; // EL0 thread ID - u64 sp_el0; // EL0 stack pointer -}; - -extern "C" void exception_common(TrapFrame const* const trap_frame); -extern "C" void exception_common(TrapFrame const* const trap_frame) +extern "C" void exception_common(Kernel::TrapFrame const* const trap_frame); +extern "C" void exception_common(Kernel::TrapFrame const* const trap_frame) { constexpr bool print_stack_frame = true; @@ -86,6 +81,8 @@ ALWAYS_INLINE static Processor& bootstrap_processor() return (Processor&)bootstrap_processor_storage; } +Atomic g_boot_console; + extern "C" [[noreturn]] void init() { dbgln("Welcome to Serenity OS!"); @@ -108,26 +105,28 @@ extern "C" [[noreturn]] void init() load_kernel_symbol_table(); + auto& framebuffer = RPi::Framebuffer::the(); + if (framebuffer.initialized()) { + g_boot_console = &try_make_ref_counted(framebuffer.gpu_buffer(), framebuffer.width(), framebuffer.width(), framebuffer.pitch()).value().leak_ref(); + draw_logo(); + } + dmesgln("Starting SerenityOS..."); + initialize_interrupts(); InterruptManagement::initialize(); Processor::enable_interrupts(); auto firmware_version = query_firmware_version(); - dbgln("Firmware version: {}", firmware_version); + dmesgln("Firmware version: {}", firmware_version); - dbgln("Initialize MMU"); + dmesgln("Initialize MMU"); init_page_tables(); - auto& framebuffer = RPi::Framebuffer::the(); - if (framebuffer.initialized()) { - draw_logo(); - } - auto& timer = RPi::Timer::the(); timer.set_interrupt_interval_usec(1'000'000); timer.enable_interrupt_mode(); - dbgln("Enter loop"); + dmesgln("Enter loop"); // This will not disable interrupts, so the timer will still fire and show that // interrupts are working! diff --git a/Kernel/Arch/aarch64/kprintf.cpp b/Kernel/Arch/aarch64/kprintf.cpp index 800b56ce67..9da8905bc0 100644 --- a/Kernel/Arch/aarch64/kprintf.cpp +++ b/Kernel/Arch/aarch64/kprintf.cpp @@ -4,11 +4,24 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include +#include #include // FIXME: Merge the code in this file with Kernel/kprintf.cpp once the proper abstractions are in place. +namespace Kernel { +extern Atomic g_boot_console; +} + +static void console_out(char ch) +{ + if (auto* boot_console = g_boot_console.load()) { + boot_console->write(ch, true); + } +} + void kernelputstr(char const* characters, size_t length) { if (!characters) @@ -16,6 +29,9 @@ void kernelputstr(char const* characters, size_t length) auto& uart = Kernel::RPi::UART::the(); uart.print_str(characters, length); + + for (size_t i = 0; i < length; ++i) + console_out(characters[i]); } void kernelcriticalputstr(char const* characters, size_t length) diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt index 6931c5cbb1..4c3faa537c 100644 --- a/Kernel/CMakeLists.txt +++ b/Kernel/CMakeLists.txt @@ -459,6 +459,9 @@ else() MiniStdLib.cpp UBSanitizer.cpp + Graphics/Console/BootFramebufferConsole.cpp + Graphics/Console/GenericFramebufferConsole.cpp + Memory/AddressSpace.cpp Memory/AnonymousVMObject.cpp Memory/InodeVMObject.cpp diff --git a/Kernel/Graphics/Console/BootFramebufferConsole.cpp b/Kernel/Graphics/Console/BootFramebufferConsole.cpp index ac1aeb0d87..111c05e285 100644 --- a/Kernel/Graphics/Console/BootFramebufferConsole.cpp +++ b/Kernel/Graphics/Console/BootFramebufferConsole.cpp @@ -6,18 +6,34 @@ #include #include -#include +// FIXME: Port MemoryManager to aarch64 +#if !ARCH(AARCH64) +# include +#endif namespace Kernel::Graphics { +// FIXME: Port MemoryManager to aarch64 +#if ARCH(AARCH64) +BootFramebufferConsole::BootFramebufferConsole(u8* framebuffer_addr, size_t width, size_t height, size_t pitch) + : GenericFramebufferConsoleImpl(width, height, pitch) + , m_framebuffer(framebuffer_addr) +#else BootFramebufferConsole::BootFramebufferConsole(PhysicalAddress framebuffer_addr, size_t width, size_t height, size_t pitch) : GenericFramebufferConsoleImpl(width, height, pitch) +#endif { +// FIXME: Port MemoryManager to aarch64 +#if ARCH(AARCH64) + m_framebuffer_data = framebuffer_addr; +#else // NOTE: We're very early in the boot process, memory allocations shouldn't really fail auto framebuffer_end = Memory::page_round_up(framebuffer_addr.offset(height * pitch * sizeof(u32)).get()).release_value(); m_framebuffer = MM.allocate_kernel_region(framebuffer_addr.page_base(), framebuffer_end - framebuffer_addr.page_base().get(), "Boot Framebuffer"sv, Memory::Region::Access::ReadWrite).release_value(); + [[maybe_unused]] auto result = m_framebuffer->set_write_combine(true); m_framebuffer_data = m_framebuffer->vaddr().offset(framebuffer_addr.offset_in_page()).as_ptr(); +#endif memset(m_framebuffer_data, 0, height * pitch * sizeof(u32)); } @@ -30,6 +46,7 @@ void BootFramebufferConsole::clear(size_t x, size_t y, size_t length) void BootFramebufferConsole::clear_glyph(size_t x, size_t y) { + VERIFY(m_lock.is_locked()); GenericFramebufferConsoleImpl::clear_glyph(x, y); } diff --git a/Kernel/Graphics/Console/BootFramebufferConsole.h b/Kernel/Graphics/Console/BootFramebufferConsole.h index 434556b28a..86e5bbdb67 100644 --- a/Kernel/Graphics/Console/BootFramebufferConsole.h +++ b/Kernel/Graphics/Console/BootFramebufferConsole.h @@ -23,14 +23,24 @@ public: virtual void flush(size_t, size_t, size_t, size_t) override { } virtual void set_resolution(size_t, size_t, size_t) override { } +// FIXME: Port MemoryManager to aarch64 +#if ARCH(AARCH64) + BootFramebufferConsole(u8* framebuffer_addr, size_t width, size_t height, size_t pitch); +#else BootFramebufferConsole(PhysicalAddress framebuffer_addr, size_t width, size_t height, size_t pitch); +#endif protected: virtual void clear_glyph(size_t x, size_t y) override; virtual u8* framebuffer_data() override; +// FIXME: Port MemoryManager to aarch64 +#if ARCH(AARCH64) + u8* m_framebuffer; +#else OwnPtr m_framebuffer; +#endif u8* m_framebuffer_data {}; mutable Spinlock m_lock; };