interrupt, smp: fix GDT code/data segment order, fix GDT size
This commit is contained in:
		| @@ -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; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user