Commit f762a356 authored by Matěj Kafka's avatar Matěj Kafka
Browse files

nova: Remove `Ec::cont` to make thread switching easier to understand

Originally, `Ec::cont` was (afaict) designed to allow switching between threads
in different processes (with different virtual memory space). For switching
between threads inside a single process, it is not needed, but it must be
understood to correctly use `Ec::make_current`, which seems (rightfully)
confusing to many students.

This commit also gets rid of the indirect call of Ec::root_invoke, so now
hopefully it should be easier to understand the program flow during boot.
parent 29e83bc8
......@@ -28,7 +28,6 @@
class Ec
{
private:
void (*cont)();
Exc_regs regs;
/* Minimal and current break address (shared by all execution contexts) */
......@@ -52,20 +51,15 @@ class Ec
static Ec * current; /* Currently running execution context */
Ec * next;
Ec (void (*)(), mword = 0);
Ec (mword start, mword stack);
Ec();
Ec(mword start, mword stack);
/* Switch to this execution context */
ALWAYS_INLINE NORETURN
ALWAYS_INLINE
inline void make_current()
{
current = this;
Tss::run.sp0 = reinterpret_cast<mword>(exc_regs() + 1);
asm volatile ("mov %0, %%esp;"
"jmp *%1"
: : "g" (KSTCK_ADDR + PAGE_SIZE), "rm" (cont) : "memory"); UNREACHED;
}
HOT NORETURN
......@@ -78,7 +72,7 @@ class Ec
static void idle();
NORETURN
static void root_invoke();
static void root_invoke(mword mbi_addr);
HOT NORETURN REGPARM (1)
static void syscall_handler (uint8) asm ("syscall_handler");
......
......@@ -30,10 +30,8 @@ Ec * Ec::current;
mword Ec::break_min;
mword Ec::break_current;
// used for idle() and root_invoke()
Ec::Ec (void (*f)(), mword mbi) : cont (f)
Ec::Ec()
{
regs.eax = mbi; // Store MultiBoot Info to user-space eax register
regs.cs = SEL_USER_CODE;
regs.ds = SEL_USER_DATA;
regs.es = SEL_USER_DATA;
......@@ -74,7 +72,7 @@ void Ec::idle()
UNREACHED;
}
void Ec::root_invoke()
void Ec::root_invoke(mword mbi_addr)
{
// Bootloader passed us the "Multiboot information" data
// structure. Among other things, it contains the physical address
......@@ -83,7 +81,7 @@ void Ec::root_invoke()
// To access the data at physical address, we have to "map" them
// to virtual memory. Ptab::remap() creates a temporary mapping of
// one 4 MB page.
Multiboot * mbi = static_cast<Multiboot *>(Ptab::remap (current->regs.eax));
Multiboot *mbi = static_cast<Multiboot *>(Ptab::remap(mbi_addr));
if (!(mbi->flags & Multiboot::MODULES) || (mbi->mods_count < 1))
panic ("No multiboot modules\n");
......
......@@ -85,9 +85,11 @@ void bootstrap (mword addr)
Cpu::flush();
// Setup execution context for a new "task"
Ec::current = new Ec (Ec::root_invoke, addr);
Ec::current = new Ec();
Ec::current->make_current(); // Switch context to our new "task"
// Setup the root task
Ec::root_invoke(addr);
UNREACHED;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment