|
@@ -19,8 +19,22 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
19
|
19
|
#define SIZEOF_REAL_MODE_REGS ( SIZEOF_I386_SEG_REGS + SIZEOF_I386_REGS )
|
20
|
20
|
#define SIZEOF_I386_FLAGS 4
|
21
|
21
|
#define SIZEOF_I386_ALL_REGS ( SIZEOF_REAL_MODE_REGS + SIZEOF_I386_FLAGS )
|
22
|
|
-
|
23
|
|
- .arch i386
|
|
22
|
+
|
|
23
|
+/* Size of an address */
|
|
24
|
+#ifdef __x86_64__
|
|
25
|
+#define SIZEOF_ADDR 8
|
|
26
|
+#else
|
|
27
|
+#define SIZEOF_ADDR 4
|
|
28
|
+#endif
|
|
29
|
+
|
|
30
|
+/* Selectively assemble code for 32-bit/64-bit builds */
|
|
31
|
+#ifdef __x86_64__
|
|
32
|
+#define if32 if 0
|
|
33
|
+#define if64 if 1
|
|
34
|
+#else
|
|
35
|
+#define if32 if 1
|
|
36
|
+#define if64 if 0
|
|
37
|
+#endif
|
24
|
38
|
|
25
|
39
|
/****************************************************************************
|
26
|
40
|
* Global descriptor table
|
|
@@ -126,7 +140,7 @@ rm_sp: .word 0
|
126
|
140
|
rm_ss: .word 0
|
127
|
141
|
|
128
|
142
|
.section ".data.pm_esp", "aw", @progbits
|
129
|
|
-pm_esp: .long _estack
|
|
143
|
+pm_esp: .long VIRTUAL(_estack)
|
130
|
144
|
|
131
|
145
|
/****************************************************************************
|
132
|
146
|
* Virtual address offsets
|
|
@@ -137,9 +151,9 @@ pm_esp: .long _estack
|
137
|
151
|
****************************************************************************
|
138
|
152
|
*/
|
139
|
153
|
.struct 0
|
140
|
|
-VA_VIRT_OFFSET: .space 4
|
141
|
|
-VA_TEXT16: .space 4
|
142
|
|
-VA_DATA16: .space 4
|
|
154
|
+VA_VIRT_OFFSET: .space SIZEOF_ADDR
|
|
155
|
+VA_TEXT16: .space SIZEOF_ADDR
|
|
156
|
+VA_DATA16: .space SIZEOF_ADDR
|
143
|
157
|
VA_SIZE:
|
144
|
158
|
.previous
|
145
|
159
|
|
|
@@ -168,7 +182,7 @@ virt_addrs: .space VA_SIZE
|
168
|
182
|
* Parameters:
|
169
|
183
|
* %cs : .text16 segment
|
170
|
184
|
* %ds : .data16 segment
|
171
|
|
- * %edi : Physical base of protected-mode code (virt_offset)
|
|
185
|
+ * %edi : Physical base of protected-mode code
|
172
|
186
|
****************************************************************************
|
173
|
187
|
*/
|
174
|
188
|
.section ".text16.init_librm", "ax", @progbits
|
|
@@ -181,7 +195,9 @@ init_librm:
|
181
|
195
|
pushl %edi
|
182
|
196
|
|
183
|
197
|
/* Store rm_virt_offset and set up virtual_cs and virtual_ds segments */
|
|
198
|
+ subl $VIRTUAL(_textdata), %edi
|
184
|
199
|
movl %edi, rm_virt_offset
|
|
200
|
+.if64 ; setae (rm_virt_offset+4) ; .endif
|
185
|
201
|
movl %edi, %eax
|
186
|
202
|
movw $virtual_cs, %bx
|
187
|
203
|
call set_seg_base
|
|
@@ -195,7 +211,7 @@ init_librm:
|
195
|
211
|
shll $4, %eax
|
196
|
212
|
movw $real_cs, %bx
|
197
|
213
|
call set_seg_base
|
198
|
|
- subl %edi, %eax
|
|
214
|
+.if32 ; subl %edi, %eax ; .endif
|
199
|
215
|
movl %eax, rm_text16
|
200
|
216
|
|
201
|
217
|
/* Store rm_ds and rm_data16, set up real_ds segment and GDT base */
|
|
@@ -207,7 +223,7 @@ init_librm:
|
207
|
223
|
call set_seg_base
|
208
|
224
|
movl %eax, gdt_base
|
209
|
225
|
addl $gdt, gdt_base
|
210
|
|
- subl %edi, %eax
|
|
226
|
+.if32 ; subl %edi, %eax ; .endif
|
211
|
227
|
movl %eax, rm_data16
|
212
|
228
|
|
213
|
229
|
/* Switch to protected mode */
|
|
@@ -221,7 +237,7 @@ init_librm_pmode:
|
221
|
237
|
movw $REAL_DS, %ax
|
222
|
238
|
movw %ax, %ds
|
223
|
239
|
movl $rm_virt_addrs, %esi
|
224
|
|
- movl $virt_addrs, %edi
|
|
240
|
+ movl $VIRTUAL(virt_addrs), %edi
|
225
|
241
|
movl $( VA_SIZE / 4 ), %ecx
|
226
|
242
|
rep movsl
|
227
|
243
|
popw %ds
|
|
@@ -312,7 +328,7 @@ real_to_prot:
|
312
|
328
|
movl %cr0, %eax
|
313
|
329
|
orb $CR0_PE, %al
|
314
|
330
|
movl %eax, %cr0
|
315
|
|
- data32 ljmp $VIRTUAL_CS, $r2p_pmode
|
|
331
|
+ data32 ljmp $VIRTUAL_CS, $VIRTUAL(r2p_pmode)
|
316
|
332
|
.section ".text.real_to_prot", "ax", @progbits
|
317
|
333
|
.code32
|
318
|
334
|
r2p_pmode:
|
|
@@ -323,15 +339,15 @@ r2p_pmode:
|
323
|
339
|
movw %ax, %fs
|
324
|
340
|
movw %ax, %gs
|
325
|
341
|
movw %ax, %ss
|
326
|
|
- movl pm_esp, %esp
|
|
342
|
+ movl VIRTUAL(pm_esp), %esp
|
327
|
343
|
|
328
|
344
|
/* Load protected-mode interrupt descriptor table */
|
329
|
|
- lidt idtr
|
|
345
|
+ lidt VIRTUAL(idtr)
|
330
|
346
|
|
331
|
347
|
/* Record real-mode %ss:sp (after removal of data) */
|
332
|
|
- movw %bp, rm_ss
|
|
348
|
+ movw %bp, VIRTUAL(rm_ss)
|
333
|
349
|
addl %ecx, %edx
|
334
|
|
- movw %dx, rm_sp
|
|
350
|
+ movw %dx, VIRTUAL(rm_sp)
|
335
|
351
|
|
336
|
352
|
/* Move data from RM stack to PM stack */
|
337
|
353
|
subl %ecx, %esp
|
|
@@ -365,7 +381,8 @@ r2p_pmode:
|
365
|
381
|
.code32
|
366
|
382
|
prot_to_real:
|
367
|
383
|
/* Copy real-mode global descriptor table register to RM code segment */
|
368
|
|
- movl text16, %edi
|
|
384
|
+ movl VIRTUAL(text16), %edi
|
|
385
|
+.if64 ; subl VIRTUAL(virt_offset), %edi ; .endif
|
369
|
386
|
leal rm_gdtr(%edi), %edi
|
370
|
387
|
movsw
|
371
|
388
|
movsl
|
|
@@ -377,20 +394,20 @@ prot_to_real:
|
377
|
394
|
addl $4, %ecx
|
378
|
395
|
|
379
|
396
|
/* Real-mode %ss:sp => %ebp:edx and virtual address => %edi */
|
380
|
|
- movzwl rm_ss, %ebp
|
381
|
|
- movzwl rm_sp, %edx
|
|
397
|
+ movzwl VIRTUAL(rm_ss), %ebp
|
|
398
|
+ movzwl VIRTUAL(rm_sp), %edx
|
382
|
399
|
subl %ecx, %edx
|
383
|
400
|
movl %ebp, %eax
|
384
|
401
|
shll $4, %eax
|
385
|
402
|
leal (%eax,%edx), %edi
|
386
|
|
- subl virt_offset, %edi
|
|
403
|
+ subl VIRTUAL(virt_offset), %edi
|
387
|
404
|
|
388
|
405
|
/* Move data from PM stack to RM stack */
|
389
|
406
|
movl %esp, %esi
|
390
|
407
|
rep movsb
|
391
|
408
|
|
392
|
409
|
/* Record protected-mode %esp (after removal of data) */
|
393
|
|
- movl %esi, pm_esp
|
|
410
|
+ movl %esi, VIRTUAL(pm_esp)
|
394
|
411
|
|
395
|
412
|
/* Load real-mode segment limits */
|
396
|
413
|
movw $P2R_DS, %ax
|
|
@@ -512,7 +529,7 @@ prot_call:
|
512
|
529
|
|
513
|
530
|
/* Switch to protected mode and move register dump to PM stack */
|
514
|
531
|
movl $PC_OFFSET_END, %ecx
|
515
|
|
- pushl $pc_pmode
|
|
532
|
+ pushl $VIRTUAL(pc_pmode)
|
516
|
533
|
jmp real_to_prot
|
517
|
534
|
.section ".text.prot_call", "ax", @progbits
|
518
|
535
|
.code32
|
|
@@ -589,7 +606,7 @@ real_call:
|
589
|
606
|
/* Switch to real mode and move register dump to RM stack */
|
590
|
607
|
movl $( RC_OFFSET_REGS_END + 4 /* function pointer copy */ ), %ecx
|
591
|
608
|
pushl $rc_rmode
|
592
|
|
- movl $rm_default_gdtr_idtr, %esi
|
|
609
|
+ movl $VIRTUAL(rm_default_gdtr_idtr), %esi
|
593
|
610
|
jmp prot_to_real
|
594
|
611
|
.section ".text16.real_call", "ax", @progbits
|
595
|
612
|
.code16
|
|
@@ -605,7 +622,7 @@ rc_rmode:
|
605
|
622
|
|
606
|
623
|
/* Switch to protected mode and move register dump back to PM stack */
|
607
|
624
|
movl $RC_OFFSET_REGS_END, %ecx
|
608
|
|
- pushl $rc_pmode
|
|
625
|
+ pushl $VIRTUAL(rc_pmode)
|
609
|
626
|
jmp real_to_prot
|
610
|
627
|
.section ".text.real_call", "ax", @progbits
|
611
|
628
|
.code32
|
|
@@ -665,6 +682,8 @@ flatten_dummy:
|
665
|
682
|
* May be entered with either physical or virtual stack segment.
|
666
|
683
|
****************************************************************************
|
667
|
684
|
*/
|
|
685
|
+ .section ".text.interrupt_wrapper", "ax", @progbits
|
|
686
|
+ .code32
|
668
|
687
|
.globl interrupt_wrapper
|
669
|
688
|
interrupt_wrapper:
|
670
|
689
|
/* Preserve segment registers and original %esp */
|