interrupt, smp: fix GDT code/data segment order, fix GDT size
This commit is contained in:
parent
db6959a932
commit
54f8aa54c1
@ -5,6 +5,7 @@
|
||||
#include "../runtime/stdio.h"
|
||||
#include "../runtime/panic_assert.h"
|
||||
#include "testcode.h"
|
||||
#include "string.h"
|
||||
|
||||
bool interrupt_Enabled;
|
||||
|
||||
@ -28,7 +29,7 @@ SYSV_ABI void interrupt_MapHandler(void *handler, int interrupt) {
|
||||
*/
|
||||
|
||||
// defined in assembly
|
||||
SYSV_ABI void interrupt_MapHandler(void *handler, int interrupt);
|
||||
//SYSV_ABI void interrupt_MapHandler(void *handler, int interrupt);
|
||||
|
||||
|
||||
void interrupt_Init() {
|
||||
@ -40,21 +41,21 @@ void interrupt_Init() {
|
||||
io_WriteConsoleASCII("interrupt_Init() calling\n");
|
||||
|
||||
// set the 2 dummy gdts
|
||||
uint64_t *gdt = (uint64_t *)KERNEL_GDT_MAPPING;
|
||||
gdt[0] = 0;
|
||||
gdt[1] = GDT_EXEC;
|
||||
gdt[2] = GDT_DATA;
|
||||
gdt[3] = GDT_EXEC_RING3;
|
||||
gdt[4] = GDT_DATA_RING3;
|
||||
uint64_t *gdt = (uint64_t *)KERNEL_GDT_MAPPING;
|
||||
gdt[0] = 0;
|
||||
gdt[GDT_DATA_SELECTOR >> 3] = GDT_DATA;
|
||||
gdt[GDT_EXEC_SELECTOR >> 3] = GDT_EXEC;
|
||||
gdt[GDT_DATA_RING3_SELECTOR >> 3] = GDT_DATA_RING3;
|
||||
gdt[GDT_EXEC_RING3_SELECTOR >> 3] = GDT_EXEC_RING3;
|
||||
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");
|
||||
|
||||
//interrupt_Testcode();
|
||||
io_WriteConsoleASCII("Testcode OK\n");
|
||||
|
||||
|
||||
memset((void *)KERNEL_IDT_MAPPING, 0, KERNEL_IDT_SIZE);
|
||||
interrupt_MapHandler(interrupt_Int0, 0);
|
||||
interrupt_MapHandler(interrupt_Int1, 1);
|
||||
interrupt_MapHandler(interrupt_Int2, 2);
|
||||
|
@ -8,16 +8,16 @@ extern "C" {
|
||||
#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_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_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 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 0x23 // SelectorIndex=4, TableIndicator=GDT(0), Privilege=Ring3
|
||||
#define GDT_DATA_SELECTOR 0x08 // SelectorIndex=1, TableIndicator=GDT(0), Privilege=Ring0
|
||||
#define GDT_EXEC_SELECTOR 0x10 // SelectorIndex=2, TableIndicator=GDT(0), Privilege=Ring0
|
||||
#define GDT_DATA_RING3_SELECTOR 0x1B // SelectorIndex=3, 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_RING0 0
|
||||
|
@ -46,12 +46,18 @@ interrupt_Testcode:
|
||||
lidt [idtr]
|
||||
mov rax, int_handler
|
||||
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
|
||||
shr rax, 16
|
||||
mov [idt+49*16+6], ax
|
||||
shr rax, 16
|
||||
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
|
||||
ret
|
||||
|
@ -11,19 +11,18 @@ section '.text' executable
|
||||
;
|
||||
; Clobbers: rax
|
||||
interrupt_ReloadSegments:
|
||||
;mov eax, 0x10 ; my data segment
|
||||
xor ax, ax
|
||||
mov ax, 0x08 ; my data segment
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov ss, ax
|
||||
|
||||
;jmp 0x08:.flush
|
||||
;jmp 0x10:.flush
|
||||
; 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:
|
||||
pop rax
|
||||
push qword 0x08 ; my code segment
|
||||
push qword 0x10 ; my code segment
|
||||
push rax
|
||||
retfq
|
||||
|
||||
|
@ -16,7 +16,7 @@ interrupt_MapHandler:
|
||||
shl rsi, 4 ; rsi *= 16
|
||||
add rsi, rax ; rsi += KERNEL_IDT_MAPPING
|
||||
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
|
||||
shr rdi, 16
|
||||
mov [rsi+6], di
|
||||
|
@ -72,7 +72,7 @@ smp_thread_ID smp_thread_Start(void *entry, const smp_thread_Arguments *args, un
|
||||
t->waitCondition = NULL;
|
||||
|
||||
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.rax = (uint64_t)entry;
|
||||
|
Loading…
Reference in New Issue
Block a user