:: limine / common / lib / real.s2.asm_bios_ia32 2.4 KB raw

1
section .realmode
2
3
global rm_hcf
4
rm_hcf:
5
    ; Load BIOS IVT
6
    lidt [.rm_idt]
7
8
    ; Jump to real mode
9
    jmp 0x08:.bits16
10
  .bits16:
11
    bits 16
12
    mov ax, 0x10
13
    mov ds, ax
14
    mov es, ax
15
    mov fs, ax
16
    mov gs, ax
17
    mov ss, ax
18
    mov eax, cr0
19
    btr ax, 0
20
    mov cr0, eax
21
    jmp 0x00:.cszero
22
  .cszero:
23
    xor ax, ax
24
    mov ds, ax
25
    mov es, ax
26
    mov fs, ax
27
    mov gs, ax
28
    mov ss, ax
29
30
    sti
31
  .hang:
32
    hlt
33
    jmp .hang
34
    bits 32
35
36
  .rm_idt:   dw 0x3ff
37
             dd 0
38
39
global rm_int
40
rm_int:
41
    ; Self-modifying code: int $int_no
42
    mov al, byte [esp+4]
43
    mov byte [.int_no], al
44
45
    ; Save out_regs
46
    mov eax, dword [esp+8]
47
    mov dword [.out_regs], eax
48
49
    ; Save in_regs
50
    mov eax, dword [esp+12]
51
    mov dword [.in_regs], eax
52
53
    ; Save GDT in case BIOS overwrites it
54
    sgdt [.gdt]
55
56
    ; Save IDT
57
    sidt [.idt]
58
59
    ; Load BIOS IVT
60
    lidt [.rm_idt]
61
62
    ; Save non-scratch GPRs
63
    push ebx
64
    push esi
65
    push edi
66
    push ebp
67
68
    ; Jump to real mode
69
    jmp 0x08:.bits16
70
  .bits16:
71
    bits 16
72
    mov ax, 0x10
73
    mov ds, ax
74
    mov es, ax
75
    mov fs, ax
76
    mov gs, ax
77
    mov ss, ax
78
    mov eax, cr0
79
    and al, 0xfe
80
    mov cr0, eax
81
    jmp 0x00:.cszero
82
  .cszero:
83
    xor ax, ax
84
    mov ss, ax
85
86
    ; Load in_regs
87
    mov dword [ss:.esp], esp
88
    mov esp, dword [ss:.in_regs]
89
    pop gs
90
    pop fs
91
    pop es
92
    pop ds
93
    popfd
94
    pop ebp
95
    pop edi
96
    pop esi
97
    pop edx
98
    pop ecx
99
    pop ebx
100
    pop eax
101
    mov esp, dword [ss:.esp]
102
103
    sti
104
105
    ; Indirect interrupt call
106
    db 0xcd
107
  .int_no:
108
    db 0
109
110
    cli
111
112
    ; Load out_regs
113
    mov dword [ss:.esp], esp
114
    mov esp, dword [ss:.out_regs]
115
    lea esp, [esp + 10*4]
116
    push eax
117
    push ebx
118
    push ecx
119
    push edx
120
    push esi
121
    push edi
122
    push ebp
123
    pushfd
124
    push ds
125
    push es
126
    push fs
127
    push gs
128
    mov esp, dword [ss:.esp]
129
130
    ; Restore GDT
131
    o32 lgdt [ss:.gdt]
132
133
    ; Restore IDT
134
    o32 lidt [ss:.idt]
135
136
    ; Jump back to pmode
137
    mov eax, cr0
138
    or al, 1
139
    mov cr0, eax
140
    jmp 0x18:.bits32
141
  .bits32:
142
    bits 32
143
    mov ax, 0x20
144
    mov ds, ax
145
    mov es, ax
146
    mov fs, ax
147
    mov gs, ax
148
    mov ss, ax
149
150
    ; Restore non-scratch GPRs
151
    pop ebp
152
    pop edi
153
    pop esi
154
    pop ebx
155
156
    ; Exit
157
    ret
158
159
align 16
160
  .esp:      dd 0
161
  .out_regs: dd 0
162
  .in_regs:  dd 0
163
  .gdt:      dq 0
164
  .idt:      dq 0
165
  .rm_idt:   dw 0x3ff
166
             dd 0
167
168
section .note.GNU-stack noalloc noexec nowrite progbits
tab: 248 wrap: offon