interrupt, smp: fix GDT code/data segment order, fix GDT size

This commit is contained in:
Edgaru089 2021-11-14 17:31:11 +08:00
parent db6959a932
commit 54f8aa54c1
6 changed files with 27 additions and 21 deletions

View File

@ -5,6 +5,7 @@
#include "../runtime/stdio.h" #include "../runtime/stdio.h"
#include "../runtime/panic_assert.h" #include "../runtime/panic_assert.h"
#include "testcode.h" #include "testcode.h"
#include "string.h"
bool interrupt_Enabled; bool interrupt_Enabled;
@ -28,7 +29,7 @@ SYSV_ABI void interrupt_MapHandler(void *handler, int interrupt) {
*/ */
// defined in assembly // defined in assembly
SYSV_ABI void interrupt_MapHandler(void *handler, int interrupt); //SYSV_ABI void interrupt_MapHandler(void *handler, int interrupt);
void interrupt_Init() { void interrupt_Init() {
@ -40,21 +41,21 @@ void interrupt_Init() {
io_WriteConsoleASCII("interrupt_Init() calling\n"); io_WriteConsoleASCII("interrupt_Init() calling\n");
// set the 2 dummy gdts // set the 2 dummy gdts
uint64_t *gdt = (uint64_t *)KERNEL_GDT_MAPPING; uint64_t *gdt = (uint64_t *)KERNEL_GDT_MAPPING;
gdt[0] = 0; gdt[0] = 0;
gdt[1] = GDT_EXEC; gdt[GDT_DATA_SELECTOR >> 3] = GDT_DATA;
gdt[2] = GDT_DATA; gdt[GDT_EXEC_SELECTOR >> 3] = GDT_EXEC;
gdt[3] = GDT_EXEC_RING3; gdt[GDT_DATA_RING3_SELECTOR >> 3] = GDT_DATA_RING3;
gdt[4] = GDT_DATA_RING3; gdt[GDT_EXEC_RING3_SELECTOR >> 3] = GDT_EXEC_RING3;
io_WriteConsoleASCII("GDT Installed\n"); io_WriteConsoleASCII("GDT Installed\n");
interrupt_LoadGDT(4 * GDT_SIZE_BYTES - 1, (void *)KERNEL_GDT_MAPPING); // set it! interrupt_LoadGDT(5 * GDT_SIZE_BYTES - 1, (void *)KERNEL_GDT_MAPPING); // set it!
io_WriteConsoleASCII("GDT OK\n"); io_WriteConsoleASCII("GDT OK\n");
//interrupt_Testcode(); //interrupt_Testcode();
io_WriteConsoleASCII("Testcode OK\n"); io_WriteConsoleASCII("Testcode OK\n");
memset((void *)KERNEL_IDT_MAPPING, 0, KERNEL_IDT_SIZE);
interrupt_MapHandler(interrupt_Int0, 0); interrupt_MapHandler(interrupt_Int0, 0);
interrupt_MapHandler(interrupt_Int1, 1); interrupt_MapHandler(interrupt_Int1, 1);
interrupt_MapHandler(interrupt_Int2, 2); interrupt_MapHandler(interrupt_Int2, 2);

View File

@ -8,16 +8,16 @@ extern "C" {
#endif #endif
#define GDT_SIZE_BYTES 4 #define GDT_SIZE_BYTES 8
#define GDT_EXEC 0x00AF9A000000FFFFull // Base=0, Limit=max, Access=Present|Ring0|TypeUser|Exec|Readable, Flag=GranularityPage|Long #define GDT_EXEC 0x00AF9A000000FFFFull // Base=0, Limit=max, Access=Present|Ring0|TypeUser|Exec|Readable, Flag=GranularityPage|Long
#define GDT_DATA 0x00EF92000000FFFFull // Base=0, Limit=max, Access=Present|Ring0|TypeUser|Writable, Flag=GranularityPage|Size #define GDT_DATA 0x00EF92000000FFFFull // Base=0, Limit=max, Access=Present|Ring0|TypeUser|Writable, Flag=GranularityPage|Size
#define GDT_EXEC_RING3 0x00AFFA000000FFFFull // Base=0, Limit=max, Access=Present|Ring3|TypeUser|Exec|Readable, Flag=GranularityPage|Long #define GDT_EXEC_RING3 0x00AFFA000000FFFFull // Base=0, Limit=max, Access=Present|Ring3|TypeUser|Exec|Readable, Flag=GranularityPage|Long
#define GDT_DATA_RING3 0x00EFF2000000FFFFull // Base=0, Limit=max, Access=Present|Ring3|TypeUser|Writable, Flag=GranularityPage|Size #define GDT_DATA_RING3 0x00EFF2000000FFFFull // Base=0, Limit=max, Access=Present|Ring3|TypeUser|Writable, Flag=GranularityPage|Size
#define GDT_EXEC_SELECTOR 0x08 // SelectorIndex=1, TableIndicator=GDT(0), Privilege=Ring0 #define GDT_DATA_SELECTOR 0x08 // SelectorIndex=1, TableIndicator=GDT(0), Privilege=Ring0
#define GDT_DATA_SELECTOR 0x10 // SelectorIndex=2, TableIndicator=GDT(0), Privilege=Ring0 #define GDT_EXEC_SELECTOR 0x10 // SelectorIndex=2, TableIndicator=GDT(0), Privilege=Ring0
#define GDT_EXEC_RING3_SELECTOR 0x1B // SelectorIndex=3, TableIndicator=GDT(0), Privilege=Ring3 #define GDT_DATA_RING3_SELECTOR 0x1B // SelectorIndex=3, TableIndicator=GDT(0), Privilege=Ring3
#define GDT_DATA_RING3_SELECTOR 0x23 // SelectorIndex=4, TableIndicator=GDT(0), Privilege=Ring3 #define GDT_EXEC_RING3_SELECTOR 0x23 // SelectorIndex=4, TableIndicator=GDT(0), Privilege=Ring3
#define IDT_PRESENT (1ull << 47) #define IDT_PRESENT (1ull << 47)
#define IDT_RING0 0 #define IDT_RING0 0

View File

@ -46,12 +46,18 @@ interrupt_Testcode:
lidt [idtr] lidt [idtr]
mov rax, int_handler mov rax, int_handler
mov [idt+49*16], ax mov [idt+49*16], ax
mov word [idt+49*16+2], 0x08 mov word [idt+49*16+2], 0x10
mov word [idt+49*16+4], 0x8e00 mov word [idt+49*16+4], 0x8e00
shr rax, 16 shr rax, 16
mov [idt+49*16+6], ax mov [idt+49*16+6], ax
shr rax, 16 shr rax, 16
mov [idt+49*16+8], rax mov [idt+49*16+8], rax
; load the CS segment reg with 0x10
lea rax, [.realint]
push qword 0x10
push rax
retfq
.realint:
int 49 int 49
ret ret

View File

@ -11,19 +11,18 @@ section '.text' executable
; ;
; Clobbers: rax ; Clobbers: rax
interrupt_ReloadSegments: interrupt_ReloadSegments:
;mov eax, 0x10 ; my data segment mov ax, 0x08 ; my data segment
xor ax, ax
mov ds, ax mov ds, ax
mov es, ax mov es, ax
mov fs, ax mov fs, ax
mov gs, ax mov gs, ax
mov ss, ax mov ss, ax
;jmp 0x08:.flush ;jmp 0x10:.flush
; as in https://forum.osdev.org/viewtopic.php?f=1&t=30739 ; as in https://forum.osdev.org/viewtopic.php?f=1&t=30739
; farjump does not work in long mode, you need to do a far return: ; farjump does not work in long mode, you need to do a far return:
pop rax pop rax
push qword 0x08 ; my code segment push qword 0x10 ; my code segment
push rax push rax
retfq retfq

View File

@ -16,7 +16,7 @@ interrupt_MapHandler:
shl rsi, 4 ; rsi *= 16 shl rsi, 4 ; rsi *= 16
add rsi, rax ; rsi += KERNEL_IDT_MAPPING add rsi, rax ; rsi += KERNEL_IDT_MAPPING
mov [rsi], di mov [rsi], di
mov word [rsi+2], 0x08 ; GDT_EXEC_SELECTOR (index=1) mov word [rsi+2], 0x10 ; GDT_EXEC_SELECTOR (index=2)
mov word [rsi+4], 0x8e00 mov word [rsi+4], 0x8e00
shr rdi, 16 shr rdi, 16
mov [rsi+6], di mov [rsi+6], di

View File

@ -72,7 +72,7 @@ smp_thread_ID smp_thread_Start(void *entry, const smp_thread_Arguments *args, un
t->waitCondition = NULL; t->waitCondition = NULL;
t->state.cs = GDT_EXEC_SELECTOR; t->state.cs = GDT_EXEC_SELECTOR;
t->state.ss = 0; t->state.ss = GDT_DATA_SELECTOR;
t->state.rip = (uint64_t)__smp_thread_EntryPoint; t->state.rip = (uint64_t)__smp_thread_EntryPoint;
t->state.rax = (uint64_t)entry; t->state.rax = (uint64_t)entry;