diff options
Diffstat (limited to 'rt')
| -rw-r--r-- | rt/+x86_64/realcall.S | 81 | ||||
| -rw-r--r-- | rt/+x86_64/stage0.s | 1 |
2 files changed, 39 insertions, 43 deletions
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" |
