Compare commits
2 Commits
83e5cb81e8
...
4af9699b22
| Author | SHA1 | Date |
|---|---|---|
|
|
4af9699b22 | |
|
|
35c97e2ff8 |
|
|
@ -137,6 +137,7 @@ if("${BANAN_ARCH}" STREQUAL "x86_64")
|
|||
arch/x86_64/Signal.S
|
||||
arch/x86_64/Syscall.S
|
||||
arch/x86_64/Thread.S
|
||||
arch/x86_64/Yield.S
|
||||
)
|
||||
elseif("${BANAN_ARCH}" STREQUAL "i686")
|
||||
set(KERNEL_SOURCES
|
||||
|
|
@ -147,6 +148,7 @@ elseif("${BANAN_ARCH}" STREQUAL "i686")
|
|||
arch/i686/Signal.S
|
||||
arch/i686/Syscall.S
|
||||
arch/i686/Thread.S
|
||||
arch/i686/Yield.S
|
||||
)
|
||||
else()
|
||||
message(FATAL_ERROR "unsupported architecure ${BANAN_ARCH}")
|
||||
|
|
|
|||
|
|
@ -34,8 +34,6 @@ start_kernel_thread:
|
|||
|
||||
.global start_userspace_thread
|
||||
start_userspace_thread:
|
||||
call load_thread_sse
|
||||
|
||||
call get_thread_start_sp
|
||||
movl %eax, %esp
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
.global asm_yield_trampoline
|
||||
asm_yield_trampoline:
|
||||
movl %esp, %ecx
|
||||
movl 4(%esp), %esp
|
||||
|
||||
pushl (%ecx)
|
||||
pushl %ecx
|
||||
pushl %eax
|
||||
pushl %ebx
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
pushl %ebp
|
||||
|
||||
pushl %esp
|
||||
call scheduler_on_yield
|
||||
addl $4, %esp
|
||||
|
||||
popl %ebp
|
||||
popl %edi
|
||||
popl %esi
|
||||
popl %ebx
|
||||
popl %eax
|
||||
movl 4(%esp), %ecx
|
||||
movl 0(%esp), %esp
|
||||
jmp *%ecx
|
||||
|
|
@ -83,28 +83,6 @@ irq_stub:
|
|||
addl $8, %esp
|
||||
iret
|
||||
|
||||
.global asm_yield_handler
|
||||
asm_yield_handler:
|
||||
# This can only be called from kernel, so no segment saving is needed
|
||||
pushal
|
||||
cld
|
||||
|
||||
leal 32(%esp), %edi # interrupt stack ptr
|
||||
movl %esp, %esi # interrupt registers ptr
|
||||
|
||||
movl %esp, %ebp
|
||||
andl $-16, %esp
|
||||
|
||||
subl $8, %esp
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
call cpp_yield_handler
|
||||
|
||||
movl %ebp, %esp
|
||||
|
||||
popal
|
||||
iret
|
||||
|
||||
.global asm_ipi_handler
|
||||
asm_ipi_handler:
|
||||
pushal
|
||||
|
|
|
|||
|
|
@ -27,8 +27,6 @@ start_kernel_thread:
|
|||
|
||||
.global start_userspace_thread
|
||||
start_userspace_thread:
|
||||
call load_thread_sse
|
||||
|
||||
call get_thread_start_sp
|
||||
movq %rax, %rsp
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
.global asm_yield_trampoline
|
||||
asm_yield_trampoline:
|
||||
movq %rsp, %rcx
|
||||
movq %rdi, %rsp
|
||||
|
||||
subq $8, %rsp
|
||||
pushq (%rcx)
|
||||
pushq %rcx
|
||||
pushq %rax
|
||||
pushq %rbx
|
||||
pushq %rbp
|
||||
pushq %r12
|
||||
pushq %r13
|
||||
pushq %r14
|
||||
pushq %r15
|
||||
|
||||
movq %rsp, %rdi
|
||||
call scheduler_on_yield
|
||||
|
||||
popq %r15
|
||||
popq %r14
|
||||
popq %r13
|
||||
popq %r12
|
||||
popq %rbp
|
||||
popq %rbx
|
||||
popq %rax
|
||||
movq 8(%rsp), %rcx
|
||||
movq 0(%rsp), %rsp
|
||||
jmp *%rcx
|
||||
|
|
@ -71,16 +71,6 @@ irq_stub:
|
|||
addq $16, %rsp
|
||||
iretq
|
||||
|
||||
.global asm_yield_handler
|
||||
asm_yield_handler:
|
||||
pushaq 8
|
||||
cld
|
||||
leaq 120(%rsp), %rdi # interrupt stack ptr
|
||||
movq %rsp, %rsi # interrupt register ptr
|
||||
call cpp_yield_handler
|
||||
popaq 8
|
||||
iretq
|
||||
|
||||
.global asm_ipi_handler
|
||||
asm_ipi_handler:
|
||||
pushaq 8
|
||||
|
|
|
|||
|
|
@ -22,9 +22,8 @@ namespace Kernel
|
|||
#if ARCH(i686)
|
||||
constexpr uint8_t IRQ_SYSCALL = 0xF0;
|
||||
#endif
|
||||
constexpr uint8_t IRQ_YIELD = 0xF1;
|
||||
constexpr uint8_t IRQ_IPI = 0xF2;
|
||||
constexpr uint8_t IRQ_TIMER = 0xF3;
|
||||
constexpr uint8_t IRQ_IPI = 0xF1;
|
||||
constexpr uint8_t IRQ_TIMER = 0xF2;
|
||||
|
||||
#if ARCH(x86_64)
|
||||
struct GateDescriptor
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ namespace Kernel
|
|||
uintptr_t r10;
|
||||
uintptr_t r9;
|
||||
uintptr_t r8;
|
||||
|
||||
uintptr_t rdi;
|
||||
uintptr_t rsi;
|
||||
uintptr_t rbp;
|
||||
|
|
@ -36,6 +35,18 @@ namespace Kernel
|
|||
uintptr_t rcx;
|
||||
uintptr_t rax;
|
||||
};
|
||||
struct YieldRegisters
|
||||
{
|
||||
uintptr_t r15;
|
||||
uintptr_t r14;
|
||||
uintptr_t r13;
|
||||
uintptr_t r12;
|
||||
uintptr_t rbp;
|
||||
uintptr_t rbx;
|
||||
uintptr_t ret;
|
||||
uintptr_t sp;
|
||||
uintptr_t ip;
|
||||
};
|
||||
#elif ARCH(i686)
|
||||
struct InterruptRegisters
|
||||
{
|
||||
|
|
@ -48,6 +59,16 @@ namespace Kernel
|
|||
uintptr_t ecx;
|
||||
uintptr_t eax;
|
||||
};
|
||||
struct YieldRegisters
|
||||
{
|
||||
uintptr_t ebp;
|
||||
uintptr_t edi;
|
||||
uintptr_t esi;
|
||||
uintptr_t ebx;
|
||||
uintptr_t ret;
|
||||
uintptr_t sp;
|
||||
uintptr_t ip;
|
||||
};
|
||||
#endif
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,6 +120,9 @@ namespace Kernel
|
|||
static void update_tsc();
|
||||
static uint64_t ns_since_boot_tsc();
|
||||
|
||||
static Thread* get_current_sse_thread() { return read_gs_sized<Thread*>(offsetof(Processor, m_sse_thread)); };
|
||||
static void set_current_sse_thread(Thread* thread) { write_gs_sized<Thread*>(offsetof(Processor, m_sse_thread), thread); };
|
||||
|
||||
static paddr_t shared_page_paddr() { return s_shared_page_paddr; }
|
||||
static volatile API::SharedPage& shared_page() { return *reinterpret_cast<API::SharedPage*>(s_shared_page_vaddr); }
|
||||
|
||||
|
|
@ -133,6 +136,21 @@ namespace Kernel
|
|||
static void load_fsbase();
|
||||
static void load_gsbase();
|
||||
|
||||
static void disable_sse()
|
||||
{
|
||||
uintptr_t dummy;
|
||||
#if ARCH(x86_64)
|
||||
asm volatile("movq %%cr0, %0; orq $0x08, %0; movq %0, %%cr0" : "=r"(dummy));
|
||||
#elif ARCH(i686)
|
||||
asm volatile("movl %%cr0, %0; orl $0x08, %0; movl %0, %%cr0" : "=r"(dummy));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void enable_sse()
|
||||
{
|
||||
asm volatile("clts");
|
||||
}
|
||||
|
||||
private:
|
||||
Processor() = default;
|
||||
~Processor() { ASSERT_NOT_REACHED(); }
|
||||
|
|
@ -194,6 +212,8 @@ namespace Kernel
|
|||
|
||||
vaddr_t m_thread_syscall_stack;
|
||||
|
||||
Thread* m_sse_thread { nullptr };
|
||||
|
||||
static constexpr size_t s_stack_size { 4096 };
|
||||
void* m_stack { nullptr };
|
||||
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ namespace Kernel
|
|||
static BAN::ErrorOr<Scheduler*> create();
|
||||
BAN::ErrorOr<void> initialize();
|
||||
|
||||
void reschedule(InterruptStack*, InterruptRegisters*);
|
||||
void reschedule(YieldRegisters*);
|
||||
void reschedule_if_idle();
|
||||
|
||||
void timer_interrupt();
|
||||
|
|
|
|||
|
|
@ -132,8 +132,7 @@ namespace Kernel
|
|||
size_t virtual_page_count() const { return (m_kernel_stack ? (m_kernel_stack->size() / PAGE_SIZE) : 0) + (m_userspace_stack ? (m_userspace_stack->size() / PAGE_SIZE) : 0); }
|
||||
size_t physical_page_count() const { return virtual_page_count(); }
|
||||
|
||||
InterruptStack& interrupt_stack() { return m_interrupt_stack; }
|
||||
InterruptRegisters& interrupt_registers() { return m_interrupt_registers; }
|
||||
YieldRegisters& yield_registers() { return m_yield_registers; }
|
||||
|
||||
void save_sse();
|
||||
void load_sse();
|
||||
|
|
@ -173,8 +172,7 @@ namespace Kernel
|
|||
|
||||
SchedulerQueue::Node* m_scheduler_node { nullptr };
|
||||
|
||||
InterruptStack m_interrupt_stack { };
|
||||
InterruptRegisters m_interrupt_registers { };
|
||||
YieldRegisters m_yield_registers { };
|
||||
|
||||
siginfo_t m_signal_infos[_SIGMAX + 1] { };
|
||||
uint64_t m_signal_pending_mask { 0 };
|
||||
|
|
|
|||
|
|
@ -177,34 +177,47 @@ namespace Kernel
|
|||
const pid_t tid = Thread::current_tid();
|
||||
const pid_t pid = (tid && Thread::current().has_process()) ? Process::current().pid() : 0;
|
||||
|
||||
const char* process_name = "";
|
||||
|
||||
if (tid)
|
||||
switch (isr)
|
||||
{
|
||||
auto& thread = Thread::current();
|
||||
thread.save_sse();
|
||||
|
||||
if (isr == ISR::PageFault && Thread::current().is_userspace())
|
||||
case ISR::PageFault:
|
||||
{
|
||||
if (pid)
|
||||
if (pid == 0 || !Thread::current().is_userspace())
|
||||
break;
|
||||
|
||||
PageFaultError page_fault_error;
|
||||
page_fault_error.raw = error;
|
||||
|
||||
Processor::set_interrupt_state(InterruptState::Enabled);
|
||||
auto result = Process::current().allocate_page_for_demand_paging(regs->cr2, page_fault_error.write, page_fault_error.instruction);
|
||||
Processor::set_interrupt_state(InterruptState::Disabled);
|
||||
|
||||
if (result.is_error())
|
||||
{
|
||||
PageFaultError page_fault_error;
|
||||
page_fault_error.raw = error;
|
||||
|
||||
Processor::set_interrupt_state(InterruptState::Enabled);
|
||||
auto result = Process::current().allocate_page_for_demand_paging(regs->cr2, page_fault_error.write, page_fault_error.instruction);
|
||||
Processor::set_interrupt_state(InterruptState::Disabled);
|
||||
|
||||
if (!result.is_error() && result.value())
|
||||
goto done;
|
||||
|
||||
if (result.is_error())
|
||||
{
|
||||
dwarnln("Demand paging: {}", result.error());
|
||||
Thread::current().handle_signal(SIGKILL, {});
|
||||
goto done;
|
||||
}
|
||||
dwarnln("Demand paging: {}", result.error());
|
||||
Thread::current().handle_signal(SIGKILL, {});
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.value())
|
||||
return;
|
||||
|
||||
break;
|
||||
}
|
||||
case ISR::DeviceNotAvailable:
|
||||
{
|
||||
if (pid == 0 || !Thread::current().is_userspace())
|
||||
break;
|
||||
|
||||
Processor::enable_sse();
|
||||
|
||||
if (auto* sse_thread = Processor::get_current_sse_thread())
|
||||
sse_thread->save_sse();
|
||||
|
||||
auto* current_thread = &Thread::current();
|
||||
current_thread->load_sse();
|
||||
Processor::set_current_sse_thread(current_thread);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -225,8 +238,9 @@ namespace Kernel
|
|||
);
|
||||
}
|
||||
|
||||
if (Thread::current().has_process())
|
||||
process_name = Process::current().name();
|
||||
const char* process_name = (tid && Thread::current().has_process())
|
||||
? Process::current().name()
|
||||
: nullptr;
|
||||
|
||||
#if ARCH(x86_64)
|
||||
dwarnln(
|
||||
|
|
@ -320,17 +334,6 @@ namespace Kernel
|
|||
}
|
||||
|
||||
ASSERT(Thread::current().state() != Thread::State::Terminated);
|
||||
|
||||
done:
|
||||
Thread::current().load_sse();
|
||||
}
|
||||
|
||||
extern "C" void cpp_yield_handler(InterruptStack* interrupt_stack, InterruptRegisters* interrupt_registers)
|
||||
{
|
||||
// yield is raised through kernel software interrupt
|
||||
ASSERT(!InterruptController::get().is_in_service(IRQ_YIELD - IRQ_VECTOR_BASE));
|
||||
ASSERT(!GDT::is_user_segment(interrupt_stack->cs));
|
||||
Processor::scheduler().reschedule(interrupt_stack, interrupt_registers);
|
||||
}
|
||||
|
||||
extern "C" void cpp_ipi_handler()
|
||||
|
|
@ -351,8 +354,6 @@ namespace Kernel
|
|||
asm volatile("cli; 1: hlt; jmp 1b");
|
||||
}
|
||||
|
||||
Thread::current().save_sse();
|
||||
|
||||
ASSERT(InterruptController::get().is_in_service(IRQ_TIMER - IRQ_VECTOR_BASE));
|
||||
InterruptController::get().eoi(IRQ_TIMER - IRQ_VECTOR_BASE);
|
||||
|
||||
|
|
@ -364,8 +365,6 @@ namespace Kernel
|
|||
auto& current_thread = Thread::current();
|
||||
if (current_thread.can_add_signal_to_execute())
|
||||
current_thread.handle_signal();
|
||||
|
||||
Thread::current().load_sse();
|
||||
}
|
||||
|
||||
extern "C" void cpp_irq_handler(uint32_t irq)
|
||||
|
|
@ -383,8 +382,6 @@ namespace Kernel
|
|||
if (!InterruptController::get().is_in_service(irq))
|
||||
return;
|
||||
|
||||
Thread::current().save_sse();
|
||||
|
||||
InterruptController::get().eoi(irq);
|
||||
if (auto* handler = s_interruptables[irq])
|
||||
handler->handle_irq();
|
||||
|
|
@ -398,8 +395,6 @@ namespace Kernel
|
|||
Processor::scheduler().reschedule_if_idle();
|
||||
|
||||
ASSERT(Thread::current().state() != Thread::State::Terminated);
|
||||
|
||||
Thread::current().load_sse();
|
||||
}
|
||||
|
||||
void IDT::register_interrupt_handler(uint8_t index, void (*handler)(), uint8_t ist)
|
||||
|
|
@ -477,7 +472,6 @@ namespace Kernel
|
|||
static_assert(DoubleFault == 8);
|
||||
#endif
|
||||
|
||||
idt->register_interrupt_handler(IRQ_YIELD, asm_yield_handler);
|
||||
idt->register_interrupt_handler(IRQ_IPI, asm_ipi_handler);
|
||||
idt->register_interrupt_handler(IRQ_TIMER, asm_timer_handler);
|
||||
#if ARCH(i686)
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ namespace Kernel
|
|||
static BAN::Array<ProcessorID, 0xFF> s_processor_ids { PROCESSOR_NONE };
|
||||
|
||||
extern "C" void asm_syscall_handler();
|
||||
extern "C" void asm_yield_trampoline(uintptr_t);
|
||||
|
||||
ProcessorID Processor::read_processor_id()
|
||||
{
|
||||
|
|
@ -146,6 +147,8 @@ namespace Kernel
|
|||
ASSERT(processor.m_idt);
|
||||
processor.idt().load();
|
||||
|
||||
disable_sse();
|
||||
|
||||
return processor;
|
||||
}
|
||||
|
||||
|
|
@ -556,33 +559,7 @@ namespace Kernel
|
|||
if (!scheduler().is_idle())
|
||||
Thread::current().set_cpu_time_stop();
|
||||
|
||||
#if ARCH(x86_64)
|
||||
asm volatile(
|
||||
"movq %%rsp, %%rcx;"
|
||||
"movq %[load_sp], %%rsp;"
|
||||
"int %[yield];"
|
||||
"movq %%rcx, %%rsp;"
|
||||
// NOTE: This is offset by 2 pointers since interrupt without PL change
|
||||
// does not push SP and SS. This allows accessing "whole" interrupt stack.
|
||||
:: [load_sp]"r"(Processor::current_stack_top() - 2 * sizeof(uintptr_t)),
|
||||
[yield]"i"(static_cast<int>(IRQ_YIELD)) // WTF GCC 15
|
||||
: "memory", "rcx"
|
||||
);
|
||||
#elif ARCH(i686)
|
||||
asm volatile(
|
||||
"movl %%esp, %%ecx;"
|
||||
"movl %[load_sp], %%esp;"
|
||||
"int %[yield];"
|
||||
"movl %%ecx, %%esp;"
|
||||
// NOTE: This is offset by 2 pointers since interrupt without PL change
|
||||
// does not push SP and SS. This allows accessing "whole" interrupt stack.
|
||||
:: [load_sp]"r"(Processor::current_stack_top() - 2 * sizeof(uintptr_t)),
|
||||
[yield]"i"(static_cast<int>(IRQ_YIELD)) // WTF GCC 15
|
||||
: "memory", "ecx"
|
||||
);
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
asm_yield_trampoline(Processor::current_stack_top());
|
||||
|
||||
processor_info.m_start_ns = SystemTimer::get().ns_since_boot();
|
||||
|
||||
|
|
|
|||
|
|
@ -207,7 +207,7 @@ namespace Kernel
|
|||
m_most_loaded_threads.back().queue = nullptr;
|
||||
}
|
||||
|
||||
void Scheduler::reschedule(InterruptStack* interrupt_stack, InterruptRegisters* interrupt_registers)
|
||||
void Scheduler::reschedule(YieldRegisters* yield_registers)
|
||||
{
|
||||
ASSERT(Processor::get_interrupt_state() == InterruptState::Disabled);
|
||||
|
||||
|
|
@ -232,8 +232,7 @@ namespace Kernel
|
|||
case Thread::State::Executing:
|
||||
{
|
||||
const uint64_t current_ns = SystemTimer::get().ns_since_boot();
|
||||
m_current->thread->interrupt_stack() = *interrupt_stack;
|
||||
m_current->thread->interrupt_registers() = *interrupt_registers;
|
||||
m_current->thread->yield_registers() = *yield_registers;
|
||||
m_current->time_used_ns += current_ns - m_current->last_start_ns;
|
||||
add_current_to_most_loaded(m_current->blocked ? &m_block_queue : &m_run_queue);
|
||||
if (!m_current->blocked)
|
||||
|
|
@ -267,8 +266,7 @@ namespace Kernel
|
|||
{
|
||||
if (&PageTable::current() != &PageTable::kernel())
|
||||
PageTable::kernel().load();
|
||||
*interrupt_stack = m_idle_thread->interrupt_stack();
|
||||
*interrupt_registers = m_idle_thread->interrupt_registers();
|
||||
*yield_registers = m_idle_thread->yield_registers();
|
||||
m_idle_thread->m_state = Thread::State::Executing;
|
||||
m_idle_start_ns = SystemTimer::get().ns_since_boot();
|
||||
return;
|
||||
|
|
@ -296,8 +294,11 @@ namespace Kernel
|
|||
Processor::load_segments();
|
||||
}
|
||||
|
||||
*interrupt_stack = thread->interrupt_stack();
|
||||
*interrupt_registers = thread->interrupt_registers();
|
||||
(Processor::get_current_sse_thread() == thread)
|
||||
? Processor::enable_sse()
|
||||
: Processor::disable_sse();
|
||||
|
||||
*yield_registers = thread->yield_registers();
|
||||
|
||||
m_current->last_start_ns = SystemTimer::get().ns_since_boot();
|
||||
}
|
||||
|
|
@ -333,6 +334,11 @@ namespace Kernel
|
|||
Processor::yield();
|
||||
}
|
||||
|
||||
extern "C" void scheduler_on_yield(YieldRegisters* yield_registers)
|
||||
{
|
||||
Processor::scheduler().reschedule(yield_registers);
|
||||
}
|
||||
|
||||
void Scheduler::timer_interrupt()
|
||||
{
|
||||
ASSERT(Processor::get_interrupt_state() == InterruptState::Disabled);
|
||||
|
|
@ -566,6 +572,14 @@ namespace Kernel
|
|||
dprintln_if(DEBUG_SCHEDULER, "CPU {}: sending tid {} to CPU {}", Processor::current_id(), thread_info.node->thread->tid(), least_loaded_id);
|
||||
}
|
||||
|
||||
if (auto* thread = thread_info.node->thread; thread == Processor::get_current_sse_thread())
|
||||
{
|
||||
Processor::enable_sse();
|
||||
thread->save_sse();
|
||||
Processor::set_current_sse_thread(nullptr);
|
||||
Processor::disable_sse();
|
||||
}
|
||||
|
||||
thread_info.node->time_used_ns = 0;
|
||||
|
||||
{
|
||||
|
|
|
|||
|
|
@ -26,12 +26,7 @@ namespace Kernel
|
|||
|
||||
extern "C" uintptr_t get_thread_start_sp()
|
||||
{
|
||||
return Thread::current().interrupt_stack().sp;
|
||||
}
|
||||
|
||||
extern "C" void load_thread_sse()
|
||||
{
|
||||
Thread::current().load_sse();
|
||||
return Thread::current().yield_registers().sp;
|
||||
}
|
||||
|
||||
static pid_t s_next_tid = 1;
|
||||
|
|
@ -51,6 +46,11 @@ namespace Kernel
|
|||
return;
|
||||
}
|
||||
|
||||
const auto state = Processor::get_interrupt_state();
|
||||
Processor::set_interrupt_state(InterruptState::Disabled);
|
||||
|
||||
Processor::enable_sse();
|
||||
|
||||
const uint32_t mxcsr = 0x1F80;
|
||||
asm volatile(
|
||||
"finit;"
|
||||
|
|
@ -66,6 +66,10 @@ namespace Kernel
|
|||
: [mxcsr]"m"(mxcsr)
|
||||
);
|
||||
|
||||
Processor::disable_sse();
|
||||
|
||||
Processor::set_interrupt_state(state);
|
||||
|
||||
s_default_sse_storage_initialized = true;
|
||||
}
|
||||
|
||||
|
|
@ -179,13 +183,9 @@ namespace Kernel
|
|||
write_to_stack(sp, data);
|
||||
write_to_stack(sp, entry);
|
||||
|
||||
thread->m_interrupt_stack.ip = reinterpret_cast<vaddr_t>(start_kernel_thread);
|
||||
thread->m_interrupt_stack.cs = 0x08;
|
||||
thread->m_interrupt_stack.flags = 0x002;
|
||||
thread->m_interrupt_stack.sp = sp;
|
||||
thread->m_interrupt_stack.ss = 0x10;
|
||||
|
||||
memset(&thread->m_interrupt_registers, 0, sizeof(InterruptRegisters));
|
||||
thread->m_yield_registers = {};
|
||||
thread->m_yield_registers.ip = reinterpret_cast<vaddr_t>(start_kernel_thread);
|
||||
thread->m_yield_registers.sp = sp;
|
||||
|
||||
thread_deleter.disable();
|
||||
|
||||
|
|
@ -265,6 +265,12 @@ namespace Kernel
|
|||
|
||||
Thread::~Thread()
|
||||
{
|
||||
if (Processor::get_current_sse_thread() == this)
|
||||
{
|
||||
Processor::set_current_sse_thread(nullptr);
|
||||
Processor::disable_sse();
|
||||
}
|
||||
|
||||
if (m_delete_process)
|
||||
{
|
||||
ASSERT(m_process);
|
||||
|
|
@ -347,20 +353,13 @@ namespace Kernel
|
|||
|
||||
thread->m_state = State::NotStarted;
|
||||
|
||||
thread->m_interrupt_stack.ip = ip;
|
||||
thread->m_interrupt_stack.cs = 0x08;
|
||||
thread->m_interrupt_stack.flags = 0x002;
|
||||
thread->m_interrupt_stack.sp = sp;
|
||||
thread->m_interrupt_stack.ss = 0x10;
|
||||
|
||||
save_sse();
|
||||
memcpy(thread->m_sse_storage, m_sse_storage, sizeof(m_sse_storage));
|
||||
|
||||
#if ARCH(x86_64)
|
||||
thread->m_interrupt_registers.rax = 0;
|
||||
#elif ARCH(i686)
|
||||
thread->m_interrupt_registers.eax = 0;
|
||||
#endif
|
||||
thread->m_yield_registers = {};
|
||||
thread->m_yield_registers.ip = ip;
|
||||
thread->m_yield_registers.sp = sp;
|
||||
thread->m_yield_registers.ret = 0;
|
||||
|
||||
thread_deleter.disable();
|
||||
|
||||
|
|
@ -498,13 +497,9 @@ namespace Kernel
|
|||
write_to_stack(cur_sp, ip);
|
||||
});
|
||||
|
||||
m_interrupt_stack.ip = reinterpret_cast<vaddr_t>(start_userspace_thread);
|
||||
m_interrupt_stack.cs = 0x08;
|
||||
m_interrupt_stack.flags = 0x002;
|
||||
m_interrupt_stack.sp = kernel_stack_top() - 5 * sizeof(uintptr_t);
|
||||
m_interrupt_stack.ss = 0x10;
|
||||
|
||||
memset(&m_interrupt_registers, 0, sizeof(InterruptRegisters));
|
||||
m_yield_registers = {};
|
||||
m_yield_registers.ip = reinterpret_cast<vaddr_t>(start_userspace_thread);
|
||||
m_yield_registers.sp = kernel_stack_top() - 5 * sizeof(uintptr_t);
|
||||
}
|
||||
|
||||
void Thread::setup_process_cleanup()
|
||||
|
|
@ -539,13 +534,9 @@ namespace Kernel
|
|||
write_to_stack(sp, entry);
|
||||
});
|
||||
|
||||
m_interrupt_stack.ip = reinterpret_cast<vaddr_t>(start_kernel_thread);
|
||||
m_interrupt_stack.cs = 0x08;
|
||||
m_interrupt_stack.flags = 0x002;
|
||||
m_interrupt_stack.sp = kernel_stack_top() - 4 * sizeof(uintptr_t);
|
||||
m_interrupt_stack.ss = 0x10;
|
||||
|
||||
memset(&m_interrupt_registers, 0, sizeof(InterruptRegisters));
|
||||
m_yield_registers = {};
|
||||
m_yield_registers.ip = reinterpret_cast<vaddr_t>(start_kernel_thread);
|
||||
m_yield_registers.sp = kernel_stack_top() - 4 * sizeof(uintptr_t);
|
||||
}
|
||||
|
||||
bool Thread::is_interrupted_by_signal(bool skip_stop_and_cont) const
|
||||
|
|
@ -811,7 +802,7 @@ namespace Kernel
|
|||
|
||||
const vaddr_t stack_bottom = reinterpret_cast<vaddr_t>(m_signal_alt_stack.ss_sp);
|
||||
const vaddr_t stack_top = stack_bottom + m_signal_alt_stack.ss_size;
|
||||
const vaddr_t sp = m_interrupt_stack.sp;
|
||||
const vaddr_t sp = m_yield_registers.sp;
|
||||
return stack_bottom <= sp && sp <= stack_top;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue