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:
parent
a5e98d3644
commit
e9b4e07b0a
1 changed files with 45 additions and 13 deletions
|
@ -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 {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue