summaryrefslogtreecommitdiff
path: root/rt
diff options
context:
space:
mode:
Diffstat (limited to 'rt')
-rw-r--r--rt/+x86_64/realcall.S81
-rw-r--r--rt/+x86_64/stage0.s1
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"