feat: introduced tasking, added paging (no vm), moved malloc, added
syscalls, other stuff
This commit is contained in:
20
kernel/cpu/cpu.h
Normal file
20
kernel/cpu/cpu.h
Normal file
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// Created by rick on 22-02-21.
|
||||
//
|
||||
|
||||
#ifndef NEW_KERNEL_CPU_H
|
||||
#define NEW_KERNEL_CPU_H
|
||||
#include <types.h>
|
||||
|
||||
typedef struct {
|
||||
uint32_t edi, esi, ebx, ebp, eip;
|
||||
} task_registers_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t ds; // pushed in common handler
|
||||
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; // pusha/popa
|
||||
uint32_t int_no, err_code; // pushed by handlers
|
||||
uint32_t eip, cs, eflags, useresp, ss; // isr/iret
|
||||
} isr_registers_t;
|
||||
|
||||
#endif //NEW_KERNEL_CPU_H
|
||||
@@ -4,3 +4,30 @@
|
||||
|
||||
#include "cpuidx.h"
|
||||
|
||||
#include <types.h>
|
||||
#include <cpuid.h>
|
||||
#include <libc/kprintf.h>
|
||||
|
||||
union cpu_name {
|
||||
uint32_t parts[3];
|
||||
struct {
|
||||
char name[12];
|
||||
char end;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
void cpuidx_print_info() {
|
||||
union cpu_name name;
|
||||
__get_cpuid(0, NULL, &name.parts[0], &name.parts[2], &name.parts[1]);
|
||||
name.end = 0;
|
||||
printf("CPU: %s\n", &name.name);
|
||||
|
||||
cpu_features_ecx features_ecx;
|
||||
cpu_features_edx features_edx;
|
||||
__get_cpuid(1, NULL, NULL, (uint32_t *) &features_ecx, (uint32_t *) &features_edx);
|
||||
|
||||
printf("");
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -5,10 +5,76 @@
|
||||
#ifndef NEW_KERNEL_CPUIDX_H
|
||||
#define NEW_KERNEL_CPUIDX_H
|
||||
|
||||
#include <cpuid.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
enum {
|
||||
typedef struct {
|
||||
bool sse3: 1;
|
||||
bool pclmul: 1;
|
||||
bool dtes64: 1;
|
||||
bool monitor: 1;
|
||||
bool ds_cpl: 1;
|
||||
bool vmx: 1;
|
||||
bool smx: 1;
|
||||
bool est: 1;
|
||||
bool tm2: 1;
|
||||
bool ssse3: 1;
|
||||
bool cid: 1;
|
||||
bool reserved: 1;
|
||||
bool fma: 1;
|
||||
bool cx16: 1;
|
||||
bool etprd: 1;
|
||||
bool pdcm: 1;
|
||||
bool pcide: 1;
|
||||
bool dca: 1;
|
||||
bool sse4_1: 1;
|
||||
bool sse4_2: 1;
|
||||
bool x2APIC: 1;
|
||||
bool movbe: 1;
|
||||
bool popcnt: 1;
|
||||
bool reserved2: 1;
|
||||
bool aes: 1;
|
||||
bool xsave: 1;
|
||||
bool osxsave: 1;
|
||||
bool avx: 1;
|
||||
} cpu_features_ecx ;
|
||||
|
||||
typedef struct {
|
||||
bool fpu: 1;
|
||||
bool vme: 1;
|
||||
bool de: 1;
|
||||
bool pse: 1;
|
||||
bool tsc: 1;
|
||||
bool msr: 1;
|
||||
bool pae: 1;
|
||||
bool mce: 1;
|
||||
bool cx8: 1;
|
||||
bool apic: 1;
|
||||
bool reserved: 1;
|
||||
bool sep: 1;
|
||||
bool mtrr: 1;
|
||||
bool pge: 1;
|
||||
bool mca: 1;
|
||||
bool cmov: 1;
|
||||
bool pat: 1;
|
||||
bool pse36: 1;
|
||||
bool psn: 1;
|
||||
bool clf: 1;
|
||||
bool reserved2: 1;
|
||||
bool dtes: 1;
|
||||
bool acpi: 1;
|
||||
bool mmx: 1;
|
||||
bool fxsr: 1;
|
||||
bool sse: 1;
|
||||
bool sse2: 1;
|
||||
bool ss: 1;
|
||||
bool htt: 1;
|
||||
bool tm1: 1;
|
||||
bool ia64: 1;
|
||||
bool pbe: 1;
|
||||
|
||||
} cpu_features_edx ;
|
||||
|
||||
enum cpu_features {
|
||||
CPUID_FEAT_ECX_SSE3 = 1 << 0,
|
||||
CPUID_FEAT_ECX_PCLMUL = 1 << 1,
|
||||
CPUID_FEAT_ECX_DTES64 = 1 << 2,
|
||||
@@ -68,16 +134,6 @@ enum {
|
||||
CPUID_FEAT_EDX_PBE = 1 << 31
|
||||
};
|
||||
|
||||
static inline void cpuid(int code, uint32_t *a, uint32_t *d) {
|
||||
asm volatile("cpuid":"=a"(*a), "=d"(*d):"a"(code):"ecx", "ebx");
|
||||
}
|
||||
|
||||
/** issue a complete request, storing general registers output as a string
|
||||
*/
|
||||
static inline int cpuid_string(int code, uint32_t where[4]) {
|
||||
asm volatile("cpuid":"=a"(*where), "=b"(*(where + 1)),
|
||||
"=c"(*(where + 2)), "=d"(*(where + 3)):"a"(code));
|
||||
return (int) where[0];
|
||||
}
|
||||
void cpuidx_print_info();
|
||||
|
||||
#endif //NEW_KERNEL_CPUIDX_H
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#ifndef MY_KERNEL_IDT_H
|
||||
#define MY_KERNEL_IDT_H
|
||||
#include <attributes.h>
|
||||
|
||||
#define KERNEL_CS 0x08
|
||||
|
||||
/* How every interrupt gate (handler) is defined */
|
||||
@@ -19,12 +21,12 @@ typedef struct {
|
||||
* Bits 3-0: bits 1110 = decimal 14 = "32 bit interrupt gate" */
|
||||
uint8_t flags;
|
||||
uint16_t high_offset; /* Higher 16 bits of handler function address */
|
||||
} __attribute__((packed)) idt_gate_t;
|
||||
} packed idt_gate_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t limit;
|
||||
uint32_t base;
|
||||
} __attribute__((packed)) idt_register_t;
|
||||
} packed idt_register_t;
|
||||
|
||||
#define IDT_REGISTERS 256
|
||||
|
||||
|
||||
@@ -109,6 +109,8 @@ irq_common_stub:
|
||||
.global irq14
|
||||
.global irq15
|
||||
|
||||
.global isr128
|
||||
|
||||
# 0: Divide By Zero Exception
|
||||
isr0:
|
||||
cli
|
||||
@@ -424,3 +426,9 @@ irq15:
|
||||
push $47
|
||||
jmp irq_common_stub
|
||||
|
||||
# Syscall
|
||||
isr128:
|
||||
cli
|
||||
push $0
|
||||
push $128
|
||||
jmp isr_common_stub
|
||||
|
||||
@@ -5,9 +5,11 @@
|
||||
#include "isr.h"
|
||||
|
||||
#include <cpu/idt.h>
|
||||
#include <cpu/syscall_handler.h>
|
||||
#include <libc/libc.h>
|
||||
#include <drivers/ports.h>
|
||||
#include <libc/kprintf.h>
|
||||
#include <libk.h>
|
||||
|
||||
#define PIC_END_OF_INTERRUPT 0x20
|
||||
|
||||
@@ -48,6 +50,7 @@ void isr_install() {
|
||||
set_idt_gate(31, (uint32_t) isr31);
|
||||
|
||||
// Remap the PIC
|
||||
// todo make readable
|
||||
port_byte_out(0x20, 0x11);
|
||||
port_byte_out(0xA0, 0x11);
|
||||
port_byte_out(0x21, 0x20);
|
||||
@@ -77,6 +80,8 @@ void isr_install() {
|
||||
set_idt_gate(46, (uint32_t) irq14);
|
||||
set_idt_gate(47, (uint32_t) irq15);
|
||||
|
||||
set_idt_gate(128, (uint32_t) isr128);
|
||||
|
||||
set_idt(); // Load with ASM
|
||||
}
|
||||
|
||||
@@ -118,15 +123,20 @@ char *exception_messages[] = {
|
||||
"Reserved"
|
||||
};
|
||||
|
||||
void isr_handler(registers_t r) {
|
||||
void isr_handler(isr_registers_t r) {
|
||||
if (r.int_no == 128) {
|
||||
syscall_handle(&r);
|
||||
return;
|
||||
}
|
||||
printf("Received interrupt: %d - %s\n", r.int_no, exception_messages[r.int_no]);
|
||||
k_panic();
|
||||
}
|
||||
|
||||
void register_interrupt_handler(uint8_t n, isr_t handler) {
|
||||
interrupt_handlers[n] = handler;
|
||||
}
|
||||
|
||||
void irq_handler(registers_t r) {
|
||||
void irq_handler(isr_registers_t r) {
|
||||
/* After every interrupt we need to send an EOI to the PICs
|
||||
* or they will not send another interrupt again */
|
||||
if (r.int_no >= 40) port_byte_out(PORT_PIC_SLAVE_COMMAND, PIC_END_OF_INTERRUPT); /* slave */
|
||||
@@ -135,6 +145,6 @@ void irq_handler(registers_t r) {
|
||||
/* Handle the interrupt in a more modular way */
|
||||
if (interrupt_handlers[r.int_no] != NULL) {
|
||||
isr_t handler = interrupt_handlers[r.int_no];
|
||||
handler(r);
|
||||
handler(&r);
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,8 @@
|
||||
#ifndef MY_KERNEL_ISR_H
|
||||
#define MY_KERNEL_ISR_H
|
||||
|
||||
#include <cpu/cpu.h>
|
||||
|
||||
/* ISRs reserved for CPU exceptions */
|
||||
extern void isr0();
|
||||
|
||||
@@ -105,6 +107,8 @@ extern void irq14();
|
||||
|
||||
extern void irq15();
|
||||
|
||||
extern void isr128();
|
||||
|
||||
#define IRQ0 32
|
||||
#define IRQ1 33
|
||||
#define IRQ2 34
|
||||
@@ -122,19 +126,12 @@ extern void irq15();
|
||||
#define IRQ14 46
|
||||
#define IRQ15 47
|
||||
|
||||
typedef struct {
|
||||
uint32_t ds;
|
||||
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax;
|
||||
uint32_t int_no, err_code;
|
||||
uint32_t eip, cs, eflags, useresp, ss;
|
||||
} registers_t;
|
||||
|
||||
typedef void (*isr_t)(registers_t);
|
||||
typedef void (*isr_t)(isr_registers_t*);
|
||||
|
||||
void register_interrupt_handler(uint8_t n, isr_t handler);
|
||||
|
||||
void isr_install();
|
||||
|
||||
void isr_handler(registers_t r);
|
||||
void isr_handler(isr_registers_t r);
|
||||
|
||||
#endif //MY_KERNEL_ISR_H
|
||||
|
||||
20
kernel/cpu/syscall_handler.c
Normal file
20
kernel/cpu/syscall_handler.c
Normal file
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// Created by rick on 24-02-21.
|
||||
//
|
||||
|
||||
#include "syscall_handler.h"
|
||||
#include <syscall.h>
|
||||
#include <tasks/task.h>
|
||||
|
||||
void syscall_handle(isr_registers_t *registers) {
|
||||
switch (registers->eax) {
|
||||
case SYSCALL_START_SCHEDULER:
|
||||
task_start_first();
|
||||
break;
|
||||
case SYSCALL_YIELD_JOB:
|
||||
task_switch_next();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
11
kernel/cpu/syscall_handler.h
Normal file
11
kernel/cpu/syscall_handler.h
Normal file
@@ -0,0 +1,11 @@
|
||||
//
|
||||
// Created by rick on 24-02-21.
|
||||
//
|
||||
|
||||
#ifndef NEW_KERNEL_SYSCALL_HANDLER_H
|
||||
#define NEW_KERNEL_SYSCALL_HANDLER_H
|
||||
#include <cpu/cpu.h>
|
||||
|
||||
void syscall_handle(isr_registers_t *registers);
|
||||
|
||||
#endif //NEW_KERNEL_SYSCALL_HANDLER_H
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <libc/libc.h>
|
||||
#include <libk.h>
|
||||
#include <kprint.h>
|
||||
#include <tasks/task.h>
|
||||
|
||||
// https://wiki.osdev.org/PIT
|
||||
#define PIT_MODE_BIN_BCD (1 << 0)
|
||||
@@ -34,8 +35,13 @@
|
||||
|
||||
uint32_t tick = 0;
|
||||
|
||||
static void timer_callback(registers_t regs) {
|
||||
static void timer_callback(isr_registers_t *regs) {
|
||||
tick++;
|
||||
task_switch_next();
|
||||
}
|
||||
|
||||
uint32_t timer_get_tick() {
|
||||
return tick;
|
||||
}
|
||||
|
||||
void sleep(uint32_t milliseconds) {
|
||||
|
||||
@@ -11,6 +11,8 @@ int init_timer(uint32_t freq);
|
||||
|
||||
void print_current_tick();
|
||||
|
||||
uint32_t timer_get_tick();
|
||||
|
||||
void sleep(uint32_t milliseconds);
|
||||
|
||||
#endif //MY_KERNEL_TIMER_H
|
||||
|
||||
Reference in New Issue
Block a user