Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
Kernel: Separate Registers struct into different structs
Browse files Browse the repository at this point in the history
  • Loading branch information
byteduck committed Jan 5, 2024
1 parent ff7fc65 commit 2c38dc2
Show file tree
Hide file tree
Showing 36 changed files with 207 additions and 172 deletions.
6 changes: 5 additions & 1 deletion kernel/KernelMapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,16 @@ KernelMapper::Symbol* KernelMapper::get_symbol(size_t location) {
printf("Add -DADD_KERNEL_DEBUG_SYMBOLS:BOOL=ON to your CMake arguments to compile with debug symbols.\n");

void KernelMapper::print_stacktrace() {
print_stacktrace((size_t) __builtin_frame_address(0));
}

void KernelMapper::print_stacktrace(size_t ebp) {
#ifdef DUCKOS_KERNEL_DEBUG_SYMBOLS
if(!symbols)
printf("[Symbols not available yet]\n");

//Start walking the stack
auto* stk = (uint32_t*) __builtin_frame_address(0);
auto* stk = (uint32_t*) ebp;

for(unsigned int frame = 0; stk && frame < 4096; frame++) {
if(!MM.kernel_page_directory.is_mapped((VirtualAddress) stk, false))
Expand Down
1 change: 1 addition & 0 deletions kernel/KernelMapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class KernelMapper {
static void load_map();
static Symbol* get_symbol(size_t location);
static void print_stacktrace();
static void print_stacktrace(size_t ebp);
static void print_userspace_stacktrace();
};

4 changes: 2 additions & 2 deletions kernel/StackWalker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ StackWalker::Frame* StackWalker::walk_stack(const kstd::Arc<Thread>& thread, uin
else if (thread == TaskManager::current_thread())
cur_frame = (Frame*) __builtin_frame_address(0);
else
cur_frame = ((Frame*) (thread->in_signal_handler() ? thread->signal_registers.esp : thread->registers.esp))->next_frame;
cur_frame = ((Frame*) (thread->in_signal_handler() ? thread->signal_registers.gp.esp : thread->registers.gp.esp))->next_frame;

size_t count = 0;

Expand All @@ -38,4 +38,4 @@ StackWalker::Frame* StackWalker::walk_stack(const kstd::Arc<Thread>& thread, uin
}

return cur_frame;
}
}
38 changes: 38 additions & 0 deletions kernel/arch/i386/registers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/* SPDX-License-Identifier: GPL-3.0-or-later */
/* Copyright © 2016-2023 Byteduck */

#pragma once

#include <kernel/kstd/types.h>

struct GPRegisters {
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax;
};

struct SegmentRegisters {
uint32_t gs, fs, es, ds;
};

struct InterruptFrame {
uint32_t eip, cs, eflags, esp, ss;
};

struct ISRRegisters {
SegmentRegisters segment_registers;
GPRegisters registers;
uint32_t isr_num, err_code;
InterruptFrame interrupt_frame;
};

struct IRQRegisters {
SegmentRegisters segment_registers;
GPRegisters registers;
uint32_t irq_num, err_code;
InterruptFrame interrupt_frame;
};

struct ThreadRegisters {
SegmentRegisters seg;
GPRegisters gp;
InterruptFrame iret;
};
3 changes: 0 additions & 3 deletions kernel/asm/syscall.s
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
[extern syscall_handler]
global asm_syscall_handler
asm_syscall_handler:
push 0 ;fake num and err_code in Registers struct
push 0
pusha
push ds
push es
Expand All @@ -22,5 +20,4 @@ asm_syscall_handler:
pop es
pop ds
popa
add esp, 8
iret
2 changes: 1 addition & 1 deletion kernel/device/AC97Device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ ssize_t AC97Device::write(FileDescriptor& fd, size_t, SafePointer<uint8_t> buffe
return n_written;
}

void AC97Device::handle_irq(Registers *regs) {
void AC97Device::handle_irq(IRQRegisters *regs) {
//Read the status
auto status_byte = IO::inw(m_output_channel + ChannelRegisters::STATUS);
BufferStatus status = {.value = status_byte};
Expand Down
2 changes: 1 addition & 1 deletion kernel/device/AC97Device.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ class AC97Device: public CharacterDevice, public IRQHandler {
ssize_t write(FileDescriptor& fd, size_t offset, SafePointer<uint8_t> buffer, size_t count) override;

//IRQHandler
void handle_irq(Registers* regs) override;
void handle_irq(IRQRegisters* regs) override;

private:
explicit AC97Device(PCI::Address address);
Expand Down
4 changes: 2 additions & 2 deletions kernel/device/KeyboardDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ void KeyboardDevice::set_handler(KeyboardHandler *handler) {
_handler = handler;
}

void KeyboardDevice::handle_irq(Registers *regs) {
void KeyboardDevice::handle_irq(IRQRegisters *regs) {
I8042::inst().handle_irq();
}

Expand Down Expand Up @@ -136,4 +136,4 @@ void KeyboardDevice::set_key_state(uint8_t scancode, bool pressed) {
if(_event_buffer.size() == _event_buffer.capacity())
_event_buffer.pop_front();
_event_buffer.push_back(event);
}
}
2 changes: 1 addition & 1 deletion kernel/device/KeyboardDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class KeyboardDevice: public CharacterDevice, public IRQHandler {

//IRQHandler
void set_handler(KeyboardHandler* handler);
void handle_irq(Registers* regs) override;
void handle_irq(IRQRegisters* regs) override;

//I8042
void handle_byte(uint8_t byte);
Expand Down
2 changes: 1 addition & 1 deletion kernel/device/MouseDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ ssize_t MouseDevice::write(FileDescriptor &fd, size_t offset, SafePointer<uint8_
return 0;
}

void MouseDevice::handle_irq(Registers *regs) {
void MouseDevice::handle_irq(IRQRegisters *regs) {
I8042::inst().handle_irq();
}

Expand Down
2 changes: 1 addition & 1 deletion kernel/device/MouseDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class MouseDevice: public CharacterDevice, public IRQHandler {
bool can_write(const FileDescriptor& fd) override;

//IRQHandler
void handle_irq(Registers* regs) override;
void handle_irq(IRQRegisters* regs) override;

//I8042
void handle_byte(uint8_t byte);
Expand Down
2 changes: 1 addition & 1 deletion kernel/device/PATADevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,7 @@ ssize_t PATADevice::write(FileDescriptor& fd, size_t offset, SafePointer<uint8_t
return count;
}

void PATADevice::handle_irq(Registers *regs) {
void PATADevice::handle_irq(IRQRegisters *regs) {
_post_irq_status = IO::inb(_io_base + ATA_STATUS);
_post_irq_bm_status = IO::inb(_bus_master_base + ATA_BM_STATUS);
if(!(_post_irq_bm_status & 0x4u))
Expand Down
2 changes: 1 addition & 1 deletion kernel/device/PATADevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class PATADevice: public IRQHandler, public DiskDevice {
ssize_t write(FileDescriptor& fd, size_t offset, SafePointer<uint8_t> buffer, size_t count) override;

//IRQHandler
void handle_irq(Registers* regs) override;
void handle_irq(IRQRegisters* regs) override;

private:
PATADevice(PCI::Address addr, Channel channel, DriveType drive, bool use_pio);
Expand Down
2 changes: 1 addition & 1 deletion kernel/interrupt/IRQHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ IRQHandler::IRQHandler() {

}

void IRQHandler::handle(Registers* regs) {
void IRQHandler::handle(IRQRegisters* regs) {
_sent_eoi = false;
handle_irq(regs);
}
Expand Down
5 changes: 3 additions & 2 deletions kernel/interrupt/IRQHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,16 @@
#pragma once

#include <kernel/kstd/kstddef.h>
#include <kernel/arch/i386/registers.h>

class IRQHandler {
public:
void handle(Registers* regs);
void handle(IRQRegisters* regs);
bool sent_eoi();
virtual bool mark_in_irq();

protected:
virtual void handle_irq(Registers* regs) = 0;
virtual void handle_irq(IRQRegisters* regs) = 0;
explicit IRQHandler();
IRQHandler(int irq);
void set_irq(int irq);
Expand Down
11 changes: 7 additions & 4 deletions kernel/interrupt/irq.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,19 +80,22 @@ namespace Interrupt {
idt_set_gate(47, (unsigned)irq15, 0x08, 0x8E);
}

void irq_handler(struct Registers *r){
auto handler = handlers[r->num - 0x20];
void irq_handler(IRQRegisters* regs){
regs->irq_num -= 0x20;
if (regs->irq_num >= (sizeof(handlers) / sizeof(handlers[0])))
PANIC("INVALID_IRQ", "Attempted to handle invalid IRQ %d", regs->irq_num);
auto handler = handlers[regs->irq_num];
if(handler) {
//Mark that we're in an interrupt so that yield will be async if it occurs
_in_interrupt = handler->mark_in_irq();

//Handle the IRQ
handler->handle(r);
handler->handle(regs);
}

//Send EOI if we haven't already
if(!handler || !handler->sent_eoi())
send_eoi(r->num - 0x20);
send_eoi(regs->irq_num);

//If we need to yield asynchronously after the interrupt because we called TaskManager::yield() during it, do so
TaskManager::do_yield_async();
Expand Down
4 changes: 3 additions & 1 deletion kernel/interrupt/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

#pragma once

#include <kernel/arch/i386/registers.h>

#define PIC1 0x20
#define PIC2 0xA0
#define PIC1_COMMAND PIC1
Expand All @@ -45,7 +47,7 @@ namespace Interrupt {
extern "C" void irq13();
extern "C" void irq14();
extern "C" void irq15();
extern "C" void irq_handler(struct Registers *r);
extern "C" void irq_handler(IRQRegisters* regs);

void irq_set_handler(int irq, IRQHandler* handler);
void irq_remove_handler(int irq);
Expand Down
37 changes: 15 additions & 22 deletions kernel/interrupt/isr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
#include <kernel/tasking/Signal.h>
#include <kernel/tasking/Thread.h>
#include <kernel/tasking/Process.h>
#include <kernel/KernelMapper.h>
#include <kernel/arch/i386/registers.h>

namespace Interrupt {
void isr_init(){
Expand Down Expand Up @@ -64,57 +66,48 @@ namespace Interrupt {
idt_set_gate(31, (unsigned)isr31, 0x08, 0x8E);
}

void handle_fault(const char* err, const char* panic_msg, uint32_t sig){
if(!TaskManager::enabled() || TaskManager::current_thread()->is_kernel_mode() || TaskManager::is_preempting()){
PANIC(err, panic_msg);
void handle_fault(const char* err, const char* panic_msg, uint32_t sig, ISRRegisters* regs) {
if(!TaskManager::enabled() || TaskManager::current_thread()->is_kernel_mode() || TaskManager::is_preempting()) {
PANIC(err, "%s\nFault %d at 0x%x", panic_msg, regs->isr_num, regs->interrupt_frame.eip);
} else {
TaskManager::current_process()->kill(sig);
}
}

void fault_handler(struct Registers *r){
if(r->num < 32){
switch(r->num){
void fault_handler(ISRRegisters* regs){
if(regs->isr_num < 32){
switch(regs->isr_num){
case 0:
handle_fault("DIVIDE_BY_ZERO", "Please don't do that.", SIGILL);
handle_fault("DIVIDE_BY_ZERO", "Please don't do that.", SIGILL, regs);
break;

case 13: //GPF
handle_fault("GENERAL_PROTECTION_FAULT", "How did you manage to do that?", SIGILL);
handle_fault("GENERAL_PROTECTION_FAULT", "How did you manage to do that?", SIGILL, regs);
break;

case 14: //Page fault
if(!TaskManager::current_thread() || TaskManager::current_thread()->is_kernel_mode() || TaskManager::is_preempting()) {
MemoryManager::inst().page_fault_handler(r);
MemoryManager::inst().page_fault_handler(regs);
} else {
size_t err_pos;
asm volatile ("mov %%cr2, %0" : "=r" (err_pos));
PageFault::Type type;
if(r->err_code == FAULT_USER_READ)
if(regs->err_code == FAULT_USER_READ)
type = PageFault::Type::Read;
else if(r->err_code == FAULT_USER_WRITE)
else if(regs->err_code == FAULT_USER_WRITE)
type = PageFault::Type::Write;
else
type = PageFault::Type::Unknown;
TaskManager::current_thread()->handle_pagefault({
err_pos,
r->eip,
regs,
});
}
break;

default:
handle_fault("UNKNOWN_FAULT", "What did you do?", SIGILL);
handle_fault("UNKNOWN_FAULT", "What did you do?", SIGILL, regs);
}
}
}
}

void print_regs(struct Registers *r){
asm volatile("mov %%ss, %%eax":"=a"(r->ss));
printf("eip:0x%X err:%d\n", r->eip, r->err_code);
printf("cs:0x%X ds:0x%X es:0x%X gs:0x%X fs:0x%X ss:0x%X\n",r->cs,r->ds,r->es,r->gs,r->fs,r->ss);
printf("eax:0x%X ebx:0x%X ecx:0x%X edx:0x%X\n",r->eax,r->ebx,r->ecx,r->edx);
printf("edi: 0x%X esi: 0x%X ebp: 0x%X esp:0x%X\n",r->edi,r->esi,r->ebp,r->esp);
printf("EFLAGS: 0x%X",r->eflags);
}
5 changes: 2 additions & 3 deletions kernel/interrupt/isr.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#pragma once

#include <kernel/kstd/kstddef.h>
#include <kernel/arch/i386/registers.h>

#define FAULT_KERNEL_READ 0
#define FAULT_KERNEL_READ_GPF 1
Expand Down Expand Up @@ -66,7 +67,5 @@ namespace Interrupt {

void isr_init();

extern "C" void fault_handler(struct Registers *r);
extern "C" void fault_handler(ISRRegisters *r);
}

void print_regs(struct Registers *r);
7 changes: 0 additions & 7 deletions kernel/kstd/kstddef.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,6 @@
#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)

struct Registers {
unsigned int gs, fs, es, ds;
unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax;
unsigned int num, err_code;
unsigned int eip, cs, eflags, useresp, ss;
};

void *operator new(size_t size);
void *operator new(size_t size, void* ptr);
void *operator new[](size_t size);
Expand Down
5 changes: 3 additions & 2 deletions kernel/memory/Memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include "../kstd/kstddef.h"
#include "../api/page_size.h"
#include <kernel/arch/i386/registers.h>

#define PAGING_4KiB 0
#define PAGING_4MiB 1
Expand Down Expand Up @@ -46,8 +47,8 @@ struct VirtualRange {
struct PageFault {
public:
VirtualAddress address;
VirtualAddress instruction_pointer;
ISRRegisters* registers;
enum class Type {
Read, Write, Execute, Unknown
} type;
};
};
4 changes: 2 additions & 2 deletions kernel/memory/MemoryManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,11 @@ void MemoryManager::load_page_directory(PageDirectory& page_directory) {
asm volatile("movl %0, %%cr3" :: "r"(page_directory.entries_physaddr()));
}

void MemoryManager::page_fault_handler(struct Registers *r) {
void MemoryManager::page_fault_handler(ISRRegisters* regs) {
TaskManager::ScopedCritical critical;
uint32_t err_pos;
asm volatile ("mov %%cr2, %0" : "=r" (err_pos));
switch (r->err_code) {
switch (regs->err_code) {
case FAULT_KERNEL_READ:
PANIC("KRNL_READ_NONPAGED_AREA", "0x%x", err_pos);
case FAULT_KERNEL_READ_GPF:
Expand Down
Loading

0 comments on commit 2c38dc2

Please sign in to comment.