diff options
| -rw-r--r-- | bios/bios.ha | 6 | ||||
| -rw-r--r-- | drive/drive.ha | 19 | ||||
| -rw-r--r-- | rt/+x86_64/realcall.S | 81 | ||||
| -rw-r--r-- | rt/+x86_64/stage0.s | 1 |
4 files changed, 50 insertions, 57 deletions
diff --git a/bios/bios.ha b/bios/bios.ha index afae0f6..aa69f8a 100644 --- a/bios/bios.ha +++ b/bios/bios.ha @@ -7,11 +7,7 @@ export type state = struct { @offset(12) edx: u32, @offset(16) edi: u32, @offset(20) esi: u32, - @offset(24) ds: u16, - @offset(26) es: u16, - @offset(28) ss: u16, - @offset(30) gs: u16, - @offset(32) fs: u16 + @offset(24) es: u16, }; // The set real mode registers diff --git a/drive/drive.ha b/drive/drive.ha index 42cef43..259e7f5 100644 --- a/drive/drive.ha +++ b/drive/drive.ha @@ -2,19 +2,20 @@ use bios; use bios::drive; fn lba_to_chs(lba: u16) (u16, u16, u16) = { - let temp = lba / bios::drive::drive_spt; - let sector = (lba % bios::drive::drive_spt) + 1; - let head = temp % bios::drive::drive_heads; - let cylinder = temp / bios::drive::drive_heads; + //let temp = lba / bios::drive::drive_spt; + //let sector = (lba % bios::drive::drive_spt) + 1; + //let head = temp % bios::drive::drive_heads; + //let cylinder = temp / bios::drive::drive_heads; - return (cylinder, head, sector); + //return (cylinder, head, sector); + return (0, 0, 0); }; export fn read(sector: u16, dest: uintptr) void = { let chs = lba_to_chs(sector); - bios::regs.eax = 1 | 0x2 << 8; - bios::regs.ebx = ws; - bios::regs.ecx = chs.2 | chs.0 << 8; - bios::regs.edx = bios::drive::drive_no | chs.1 << 8; + //bios::regs.eax = 1 | 0x2 << 8; + //bios::regs.ebx = ws; + //bios::regs.ecx = chs.2 | chs.0 << 8; + //bios::regs.edx = bios::drive::drive_no | chs.1 << 8; }; diff --git a/rt/+x86_64/realcall.S b/rt/+x86_64/realcall.S index 9e9afb4..ffbc0a9 100644 --- a/rt/+x86_64/realcall.S +++ b/rt/+x86_64/realcall.S @@ -14,18 +14,13 @@ redi: .int 0x0 resi: .int 0x0 -rds: - .short 0x0 res: .short 0x0 -rss: - .short 0x0 -rgs: - .short 0x0 -rfs: - .short 0x0 - +prev_idt: + .quad 0x0 +prev_gdt: + .quad 0x0 # :real_call # This function is intended to be called from long mode @@ -45,12 +40,25 @@ bios.call: push %r13 push %r14 push %r15 + pushf + + # :Save code segment (and second push to prepare for far return) + mov %cs, %ax + push %ax + push %ax + + # :Save data segment + mov %ds, %ax + push %ax + # :Save the interrupt number push %di cli + sidt (prev_idt) + sgdt (prev_gdt) - lgdt gdtr32 + lgdt (gdtr32) pushq $(gdt32_code - gdt32) pushq $real_call_to_pmode_down retfq @@ -92,15 +100,12 @@ real_call_to_16bits_rmode_down: mov %ax, %fs lidt bios_idtr - sti # :Self modifying code to call arbitrary interrupts pop %ax mov $real_call_int, %bx mov %al, 1(%bx) - push %ds - # :Load registers mov (reax), %eax mov (rebx), %ebx @@ -108,29 +113,22 @@ real_call_to_16bits_rmode_down: mov (redx), %edx mov (redi), %edi mov (resi), %esi - mov %ds:(res), %es - mov %ds:(rss), %ss - mov %ds:(rgs), %gs - mov %ds:(rfs), %fs - mov %ds:(rds), %ds - xchg %bx, %bx + mov (res), %es + + sti real_call_int: int $0x0 - - pop %ds - mov %ds:(rfs), %fs - mov %ds:(rgs), %gs - mov %ds:(rss), %ss - mov %ds:(res), %es + + cli + + mov %es, (res) mov %eax, (reax) mov %ebx, (rebx) mov %ecx, (recx) mov %edx, (redx) mov %edi, (redi) mov %esi, (resi) - - cli # :Restore protected mode mov %cr0, %eax @@ -157,33 +155,32 @@ real_call_to_pmode_up: or $1 << 31, %eax mov %eax, %cr0 - lgdt gdtr64 - ljmp $(gdt64_code - gdt64), $real_call_to_longmode_up + lgdt (prev_gdt) + + # :At this point %ds is latest in stack + pop %ax + + # :At this point %cs is latest in stack + # Do a long jump + push $real_call_to_longmode_up + retf .code64 real_call_to_longmode_up: - mov $(gdt64_data - gdt64), %ax mov %ax, %fs mov %ax, %gs mov %ax, %ss mov %ax, %es mov %ax, %ds + # :Avoid doing this until the bootloader loads a 64 bits IDT + # XXX + #idt (prev_idt) + real_call_end: + popf pop %r15 pop %r14 pop %r13 pop %r12 pop %rbx ret - -.globl testt -testt: - mov $1, %al - mov $0x43, %bh - mov $0x6, %ah - mov $0, %ch - mov $0, %cl - mov $5, %dh - mov $5, %dl - int $0x10 - ret diff --git a/rt/+x86_64/stage0.s b/rt/+x86_64/stage0.s index e17c06b..2961a10 100644 --- a/rt/+x86_64/stage0.s +++ b/rt/+x86_64/stage0.s @@ -89,5 +89,4 @@ bios_idtr: .org 510 .word 0xaa55 - .include "rt/+x86_64/stage1.S" |
