diff options
author | Freya Murphy <freya@freyacat.org> | 2025-04-24 11:30:07 -0400 |
---|---|---|
committer | Freya Murphy <freya@freyacat.org> | 2025-04-24 11:30:07 -0400 |
commit | a6a8129c151dc0e3a070c74161e117ec1365c099 (patch) | |
tree | 079531134ee3f685d861f4c55e8e15f70fe09905 | |
parent | update paging code (diff) | |
download | comus-a6a8129c151dc0e3a070c74161e117ec1365c099.tar.gz comus-a6a8129c151dc0e3a070c74161e117ec1365c099.tar.bz2 comus-a6a8129c151dc0e3a070c74161e117ec1365c099.zip |
add tss
-rw-r--r-- | kernel/cpu/cpu.c | 3 | ||||
-rw-r--r-- | kernel/cpu/tss.S | 6 | ||||
-rw-r--r-- | kernel/cpu/tss.c | 80 | ||||
-rw-r--r-- | kernel/cpu/tss.h | 31 | ||||
-rw-r--r-- | kernel/entry.S | 5 |
5 files changed, 124 insertions, 1 deletions
diff --git a/kernel/cpu/cpu.c b/kernel/cpu/cpu.c index 136a1d8..6ef5ef5 100644 --- a/kernel/cpu/cpu.c +++ b/kernel/cpu/cpu.c @@ -3,6 +3,7 @@ #include "pic.h" #include "idt.h" +#include "tss.h" static inline void fpu_init(void) { @@ -73,6 +74,8 @@ void cpu_init(void) if (feats.avx) avx_init(); } + + tss_init(); } void cpu_report(void) diff --git a/kernel/cpu/tss.S b/kernel/cpu/tss.S new file mode 100644 index 0000000..27f2955 --- /dev/null +++ b/kernel/cpu/tss.S @@ -0,0 +1,6 @@ + .globl tss_flush + +tss_flush: + movw $0x28, %ax + ltr %ax + ret diff --git a/kernel/cpu/tss.c b/kernel/cpu/tss.c new file mode 100644 index 0000000..bda713b --- /dev/null +++ b/kernel/cpu/tss.c @@ -0,0 +1,80 @@ +#include "lib/kstring.h" +#include <stdint.h> + +#include "tss.h" + +struct sys_seg_descriptor { + uint64_t limit0_15 : 16; + uint64_t base0_15 : 16; + uint64_t base16_23 : 8; + uint64_t type : 4; + uint64_t : 1; + uint64_t DPL : 2; + uint64_t present : 1; + uint64_t limit16_19: 4; + uint64_t available : 1; + uint64_t : 1; + uint64_t : 1; + uint64_t gran : 1; + uint64_t base24_31 : 8; + uint64_t base32_63 : 32; + uint64_t : 32; +} __attribute__((packed)); + +struct tss { + uint64_t : 32; + uint64_t rsp0 : 64; + uint64_t rsp1 : 64; + uint64_t rsp2 : 64; + uint64_t : 64; + uint64_t ist1 : 64; + uint64_t ist2 : 64; + uint64_t ist3 : 64; + uint64_t ist4 : 64; + uint64_t ist5 : 64; + uint64_t ist6 : 64; + uint64_t ist7 : 64; + uint64_t : 64; + uint64_t : 16; + uint64_t iopb : 16; +} __attribute__((packed)); + +// tss entry +static volatile struct tss tss; + +// gdt entries +extern volatile uint8_t GDT[]; +static volatile struct sys_seg_descriptor *GDT_TSS; + +// kernel stack pointer +extern char kern_stack_end[]; + +void tss_init(void) { + uint64_t base = (uint64_t) &tss; + uint64_t limit = sizeof tss - 1; + + // setup tss entry + memsetv(&tss, 0, sizeof(struct tss)); + tss.rsp0 = (uint64_t) kern_stack_end; + + // map tss into gdt + GDT_TSS = (volatile struct sys_seg_descriptor *) (GDT + 0x28); + memsetv(GDT_TSS, 0, sizeof(struct sys_seg_descriptor)); + GDT_TSS->limit0_15 = limit & 0xFFFF; + GDT_TSS->base0_15 = base & 0xFFFF; + GDT_TSS->base16_23 = (base >> 16) & 0xFF; + GDT_TSS->type = 0x9; + GDT_TSS->DPL = 0; + GDT_TSS->present = 1; + GDT_TSS->limit16_19 = (limit >> 16) & 0xF; + GDT_TSS->available = 0; + GDT_TSS->gran = 0; + GDT_TSS->base24_31 = (base >> 24) & 0xFF; + GDT_TSS->base32_63 = (base >> 32) & 0xFFFFFFFF; + + tss_flush(); +} + +void tss_set_stack(uint64_t stack) { + tss.rsp0 = stack; +} diff --git a/kernel/cpu/tss.h b/kernel/cpu/tss.h new file mode 100644 index 0000000..f17b619 --- /dev/null +++ b/kernel/cpu/tss.h @@ -0,0 +1,31 @@ +/** + * @file tss.h + * + * @author Freya Murphy <freya@freyacat.org> + * + * TSS functions + */ + +#ifndef TSS_H_ +#define TSS_H_ + +#define TSS_REMAP_OFFSET 0x20 + +#include <stdint.h> + +/** + * Load the TSS selector + */ +void tss_init(void); + +/** + * Flush the tss + */ +void tss_flush(void); + +/** + * Set the kernel stack pointer in the tss + */ +void tss_set_stack(uint64_t stack); + +#endif /* tss.h */ diff --git a/kernel/entry.S b/kernel/entry.S index aa4c38d..4b5415b 100644 --- a/kernel/entry.S +++ b/kernel/entry.S @@ -7,8 +7,10 @@ .globl kernel_pd_0_ents .globl kernel_pd_1 .globl paging_pt + .globl GDT + .globl kern_stack_end + .globl kern_stack_start .extern main - .extern GDT .section .multiboot @@ -155,6 +157,7 @@ GDT: # TSS segment (0x28) .equ GDT.TSS, . - GDT + .quad 0 .quad 0 # to be modified in kernel # GDT Pointer |