Преглед на файлове

fix: enable SSE to prevent crashes

greatbridf преди 2 години
родител
ревизия
3e52ddd462
променени са 7 файла, в които са добавени 70 реда и са изтрити 6 реда
  1. 5 1
      Makefile
  2. 1 0
      include/asm/port_io.h
  3. 11 1
      src/asm/interrupt.s
  4. 11 0
      src/asm/port_io.s
  5. 3 1
      src/boot.s
  6. 30 2
      src/kernel/interrupt.c
  7. 9 1
      src/kernel_main.c

+ 5 - 1
Makefile

@@ -1,11 +1,15 @@
 .PHONY: run
 run: build
-	qemu-system-x86_64 -drive file=build/boot.img,format=raw -display curses -no-reboot -no-shutdown -S -s -enable-kvm
+	qemu-system-i386 -drive file=build/boot.img,format=raw -display curses -no-reboot -no-shutdown -S -s -enable-kvm
 
 .PHONY: build
 build:
 	cmake --build build --target boot.img
 
+.PHONY: debug
+debug:
+	gdb --symbols=build/kernel.out --init-eval-command 'target remote:1234' --eval-command 'hbr kernel_main' --eval-command 'c'
+
 build/boot.vdi: build/boot.img
 	-rm build/boot.vdi
 	VBoxManage convertfromraw $< $@ --format VDI

+ 1 - 0
include/asm/port_io.h

@@ -27,6 +27,7 @@ extern uint8_t asm_inb(uint16_t port_number);
 extern void asm_hlt(void);
 extern void asm_cli(void);
 extern void asm_sti(void);
+extern void asm_enable_sse(void);
 
 #ifdef __cplusplus
 }

+ 11 - 1
src/asm/interrupt.s

@@ -2,6 +2,16 @@
 
 .text
 
+.globl int6
+.type  int6 @function
+int6:
+    xchgw %bx, %bx
+    pushal
+    call int6_handler
+    popal
+
+    iret
+
 .globl int13
 .type  int13 @function
 int13:
@@ -43,7 +53,7 @@ irq1:
     call irq1_handler
     popal
     iret
-    
+
 .globl irq2
 .type  irq2 @function
 irq2:

+ 11 - 0
src/asm/port_io.s

@@ -40,3 +40,14 @@ asm_cli:
 asm_sti:
     sti
     ret
+
+.globl asm_enable_sse
+.type  asm_enable_sse @function
+asm_enable_sse:
+	movl %cr0, %eax
+	orl $0b10, %eax
+	movl %eax, %cr0
+	movl %cr4, %eax
+	orl $0b11000000000, %eax
+	movl %eax, %cr4
+	ret

+ 3 - 1
src/boot.s

@@ -39,7 +39,9 @@ string_hello:
 
 read_data_pack:
     .byte 0x10, 0
-    .word 32     # block count (read 16k)
+# TODO!!!
+# read more!
+    .word 64     # block count (read 16k)
     .word 0x0000 # offset address
     .word 0x07e0 # segment address
     .long 1      # LBA to read

+ 30 - 2
src/kernel/interrupt.c

@@ -29,6 +29,7 @@ void init_idt()
     asm_outb(PORT_PIC2_DATA, 0x00);
 
     // handle general protection fault (handle segmentation fault)
+    SET_IDT_ENTRY_FN(6, int6, 0x08);
     SET_IDT_ENTRY_FN(13, int13, 0x08);
     SET_IDT_ENTRY_FN(14, int14, 0x08);
     // SET_IDT_ENTRY(0x0c, /* addr */ 0, 0x08);
@@ -58,6 +59,33 @@ void init_idt()
     asm_load_idt(idt_descriptor);
 }
 
+void int6_handler(
+    struct regs_32 s_regs,
+    uint32_t error_code,
+    ptr_t eip,
+    uint16_t cs)
+{
+    char buf[512];
+
+    vga_printk("---- INVALID OPCODE ----\n", 0x0fu);
+
+    snprintf(
+        buf, 512,
+        "eax: %x, ebx: %x, ecx: %x, edx: %x\n"
+        "esp: %x, ebp: %x, esi: %x, edi: %x\n"
+        "eip: %x, cs: %x, error_code: %x   \n",
+        s_regs.eax, s_regs.ebx, s_regs.ecx,
+        s_regs.edx, s_regs.esp, s_regs.ebp,
+        s_regs.esi, s_regs.edi, eip,
+        cs, error_code);
+    vga_printk(buf, 0x0fu);
+
+    vga_printk("----   HALTING SYSTEM   ----", 0x0fu);
+
+    asm_cli();
+    asm_hlt();
+}
+
 // general protection
 void int13_handler(
     struct regs_32 s_regs,
@@ -66,7 +94,7 @@ void int13_handler(
     uint16_t cs,
     uint32_t eflags)
 {
-    char buf[512] = { 0 };
+    char buf[512];
 
     vga_printk("---- SEGMENTATION FAULT ----\n", 0x0fu);
 
@@ -97,7 +125,7 @@ void int14_handler(
     uint16_t cs,
     uint32_t eflags)
 {
-    char buf[512] = { 0 };
+    char buf[512];
 
     vga_printk("---- PAGE FAULT ----\n", 0x0fu);
 

+ 9 - 1
src/kernel_main.c

@@ -82,13 +82,21 @@ void kernel_main(void)
 {
     MAKE_BREAK_POINT();
 
-    char buf[KERNEL_MAIN_BUF_SIZE] = { 0 };
+    char buf[KERNEL_MAIN_BUF_SIZE];
 
     show_mem_info(buf);
 
     init_paging();
     printkf("Paging enabled\n");
 
+    asm_enable_sse();
+    printkf("SSE enabled\n");
+
+    {
+        char test_sse[KERNEL_MAIN_BUF_SIZE] = { 0 };
+    }
+    printkf("SSE tested\n");
+
     init_idt();
     init_pit();
     printkf("IDT initialized\n");