1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 06:27:45 +00:00

Kernel/aarch64: Start and initialize Scheduler and run multiple threads

This commit changes the init.cpp file to start and initialize the
Scheduler, and actually runs init_stage2. To show that it actually
works, another thread is spawned and executed simultaneously, by context
switching between the two!
This commit is contained in:
Timon Kruiper 2022-12-22 19:38:51 +01:00 committed by Andrew Kaster
parent a5e98d3644
commit e9b4e07b0a

View file

@ -14,6 +14,7 @@
#include <Kernel/Arch/InterruptManagement.h> #include <Kernel/Arch/InterruptManagement.h>
#include <Kernel/Arch/Interrupts.h> #include <Kernel/Arch/Interrupts.h>
#include <Kernel/Arch/Processor.h> #include <Kernel/Arch/Processor.h>
#include <Kernel/Arch/aarch64/ASM_wrapper.h>
#include <Kernel/Arch/aarch64/BootPPMParser.h> #include <Kernel/Arch/aarch64/BootPPMParser.h>
#include <Kernel/Arch/aarch64/CPU.h> #include <Kernel/Arch/aarch64/CPU.h>
#include <Kernel/Arch/aarch64/RPi/Framebuffer.h> #include <Kernel/Arch/aarch64/RPi/Framebuffer.h>
@ -28,6 +29,7 @@
#include <Kernel/KSyms.h> #include <Kernel/KSyms.h>
#include <Kernel/Memory/MemoryManager.h> #include <Kernel/Memory/MemoryManager.h>
#include <Kernel/Panic.h> #include <Kernel/Panic.h>
#include <Kernel/Scheduler.h>
extern "C" void exception_common(Kernel::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) extern "C" void exception_common(Kernel::TrapFrame const* const trap_frame)
@ -92,6 +94,36 @@ ALWAYS_INLINE static Processor& bootstrap_processor()
Atomic<Graphics::Console*> g_boot_console; Atomic<Graphics::Console*> g_boot_console;
static void init_stage2(void*);
void init_stage2(void*)
{
Process::register_new(Process::current());
// This thread is created to show that kernel scheduling is working!
LockRefPtr<Thread> more_work_thread;
(void)Process::create_kernel_process(more_work_thread, MUST(KString::try_create("More Work Thread"sv)), [] {
dmesgln("Enter loop (more work):");
for (int i = 0; i < 500; i++) {
if (i % 20 == 0)
dmesgln(" Hello from more_work: {}", i);
Aarch64::Asm::wait_cycles(1000000);
}
dmesgln("Finished the work!");
});
auto firmware_version = query_firmware_version();
dmesgln("Firmware version: {}", firmware_version);
dmesgln("Enter loop");
for (int i = 0;; i++) {
if (i % 20 == 0)
dmesgln("Hello from init_stage2: {}", i);
Aarch64::Asm::wait_cycles(1000000);
}
}
extern "C" [[noreturn]] void init() extern "C" [[noreturn]] void init()
{ {
g_in_early_boot = true; g_in_early_boot = true;
@ -154,27 +186,27 @@ extern "C" [[noreturn]] void init()
InterruptManagement::initialize(); InterruptManagement::initialize();
Processor::enable_interrupts(); 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); TimeManagement::initialize(0);
ProcFSComponentRegistry::initialize(); ProcFSComponentRegistry::initialize();
JailManagement::the(); JailManagement::the();
auto firmware_version = query_firmware_version(); Process::initialize();
dmesgln("Firmware version: {}", firmware_version); Scheduler::initialize();
dmesgln("Enter loop"); {
LockRefPtr<Thread> init_stage2_thread;
// This will not disable interrupts, so the timer will still fire and show that (void)Process::create_kernel_process(init_stage2_thread, KString::must_create("init_stage2"sv), init_stage2, nullptr, THREAD_AFFINITY_DEFAULT, Process::RegisterProcess::No);
// interrupts are working! // We need to make sure we drop the reference for init_stage2_thread
for (u32 i = 0;; i++) { // before calling into Scheduler::start, otherwise we will have a
asm volatile("wfi"); // dangling Thread that never gets cleaned up
// NOTE: This shows that dmesgln now outputs the time since boot!
if (i % 250 == 0)
dmesgln("Timer fired!");
} }
TODO_AARCH64(); Scheduler::start();
VERIFY_NOT_REACHED();
} }
class QueryFirmwareVersionMboxMessage : RPi::Mailbox::Message { class QueryFirmwareVersionMboxMessage : RPi::Mailbox::Message {