write kernel sp to tss in dispatcher
This commit is contained in:
@@ -17,6 +17,10 @@ void switchToUsermode(void *stackpointer, void *kickoff,
|
|||||||
constexpr uint16_t user_ds = 4 << 3 | 3;
|
constexpr uint16_t user_ds = 4 << 3 | 3;
|
||||||
|
|
||||||
asm volatile ( \
|
asm volatile ( \
|
||||||
|
"mov %[user_data], %%ds \n" \
|
||||||
|
"mov %[user_data], %%es \n" \
|
||||||
|
"mov %[user_data], %%fs \n" \
|
||||||
|
"mov %[user_data], %%gs \n" \
|
||||||
"pushq %[user_data] \n" \
|
"pushq %[user_data] \n" \
|
||||||
"pushq %[user_stack] \n" \
|
"pushq %[user_stack] \n" \
|
||||||
"pushq %[user_eflags] \n" \
|
"pushq %[user_eflags] \n" \
|
||||||
|
|||||||
@@ -3,8 +3,6 @@
|
|||||||
#include "core.h"
|
#include "core.h"
|
||||||
#include "tss.h"
|
#include "tss.h"
|
||||||
|
|
||||||
TSS::Entry mytss;
|
|
||||||
|
|
||||||
namespace GDT {
|
namespace GDT {
|
||||||
|
|
||||||
// The static 32-bit Global Descriptor Table (GDT)
|
// The static 32-bit Global Descriptor Table (GDT)
|
||||||
|
|||||||
@@ -47,3 +47,5 @@ void init();
|
|||||||
void setStackpointer(void* ptr);
|
void setStackpointer(void* ptr);
|
||||||
|
|
||||||
} // namespace TSS
|
} // namespace TSS
|
||||||
|
extern TSS::Entry mytss;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
// vim: set noet ts=4 sw=4:
|
// vim: set noet ts=4 sw=4:
|
||||||
|
|
||||||
#include "dispatcher.h"
|
#include "dispatcher.h"
|
||||||
|
#include "../arch/tss.h"
|
||||||
|
#include "thread.h"
|
||||||
|
|
||||||
#include "../arch/core.h"
|
#include "../arch/core.h"
|
||||||
#include "../debug/output.h" // IWYU pragma: keep
|
#include "../debug/output.h" // IWYU pragma: keep
|
||||||
@@ -12,6 +14,7 @@ Thread *Dispatcher::active() const { return life; }
|
|||||||
void Dispatcher::go(Thread *first) {
|
void Dispatcher::go(Thread *first) {
|
||||||
assert(active() == nullptr);
|
assert(active() == nullptr);
|
||||||
setActive(first);
|
setActive(first);
|
||||||
|
mytss.sp0 = first->StackPointer.isr;
|
||||||
first->go();
|
first->go();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,7 +23,7 @@ void Dispatcher::dispatch(Thread *next) {
|
|||||||
assert(current != nullptr);
|
assert(current != nullptr);
|
||||||
if (current != next) {
|
if (current != next) {
|
||||||
setActive(next);
|
setActive(next);
|
||||||
|
mytss.sp0 = next->StackPointer.isr;
|
||||||
current->resume(next);
|
current->resume(next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,10 +41,11 @@ Thread::Thread (bool kernel, void * start): queue_link(nullptr), isKernel(kerne
|
|||||||
prepareContext(StackPointer.isr, context, kickoff, reinterpret_cast<uintptr_t>(this), 0, 0);
|
prepareContext(StackPointer.isr, context, kickoff, reinterpret_cast<uintptr_t>(this), 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread::Thread() : queue_link(nullptr), id(idCounter++), kill_flag(false) {
|
Thread::Thread() : Thread(false, 0) {}
|
||||||
void *tos = reinterpret_cast<void *>(reserved_stack_space_isr + STACK_SIZE);
|
//Thread::Thread() : queue_link(nullptr), id(idCounter++), kill_flag(false) {
|
||||||
prepareContext(tos, context, kickoff, reinterpret_cast<uintptr_t>(this), 0, 0);
|
// void *tos = reinterpret_cast<void *>(reserved_stack_space_isr + STACK_SIZE);
|
||||||
}
|
// prepareContext(tos, context, kickoff, reinterpret_cast<uintptr_t>(this), 0, 0);
|
||||||
|
//}
|
||||||
|
|
||||||
void Thread::resume(Thread *next) {
|
void Thread::resume(Thread *next) {
|
||||||
assert(next != nullptr && "Pointer to next Thread must not be nullptr!");
|
assert(next != nullptr && "Pointer to next Thread must not be nullptr!");
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class Thread {
|
|||||||
/*! \brief pointer to the next element of the readylist
|
/*! \brief pointer to the next element of the readylist
|
||||||
*/
|
*/
|
||||||
Thread* queue_link;
|
Thread* queue_link;
|
||||||
bool isKernel = true;
|
bool isKernel;
|
||||||
void* start;
|
void* start;
|
||||||
|
|
||||||
friend class Queue<Thread>;
|
friend class Queue<Thread>;
|
||||||
@@ -38,11 +38,6 @@ class Thread {
|
|||||||
alignas(16) char reserved_stack_space_user[STACK_SIZE];
|
alignas(16) char reserved_stack_space_user[STACK_SIZE];
|
||||||
alignas(16) char reserved_stack_space_isr[STACK_SIZE];
|
alignas(16) char reserved_stack_space_isr[STACK_SIZE];
|
||||||
|
|
||||||
struct{
|
|
||||||
void* user;
|
|
||||||
void* isr;
|
|
||||||
} StackPointer;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/*! \brief Context of the thread, used for saving and restoring the register
|
/*! \brief Context of the thread, used for saving and restoring the register
|
||||||
* values when context switching.
|
* values when context switching.
|
||||||
@@ -70,6 +65,11 @@ class Thread {
|
|||||||
static void kickoffUsermode (Thread *object);
|
static void kickoffUsermode (Thread *object);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
struct{
|
||||||
|
void* user;
|
||||||
|
void* isr;
|
||||||
|
} StackPointer;
|
||||||
|
|
||||||
/*! \brief Unique thread id */
|
/*! \brief Unique thread id */
|
||||||
const size_t id;
|
const size_t id;
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ extern TextStream kout;
|
|||||||
extern Application apps[];
|
extern Application apps[];
|
||||||
|
|
||||||
void Application::action() { // NOLINT
|
void Application::action() { // NOLINT
|
||||||
|
|
||||||
// Thread 1 may be an auxiliary thread
|
// Thread 1 may be an auxiliary thread
|
||||||
unsigned id = 0;
|
unsigned id = 0;
|
||||||
while (&apps[id++] != this);
|
while (&apps[id++] != this);
|
||||||
|
|||||||
Reference in New Issue
Block a user