Browse Source

Add infrastructure to support access to .data16 (and .text16) variables

from protected-mode code.

Set up %ds to point to .data16 in prot_to_real, so that code specified
via REAL_EXEC() and friends can access variables in .data16.

Move most real-mode librm variables from .text16 to .data16.
tags/v0.9.3
Michael Brown 19 years ago
parent
commit
832807726a
2 changed files with 125 additions and 76 deletions
  1. 3
    2
      src/arch/i386/prefix/libprefix.S
  2. 122
    74
      src/arch/i386/transitions/librm.S

+ 3
- 2
src/arch/i386/prefix/libprefix.S View File

336
 	call	install_highmem
336
 	call	install_highmem
337
 
337
 
338
 	/* Continue executing in .text16 segment */
338
 	/* Continue executing in .text16 segment */
339
+	movw	%bx, %ds
339
 	pushw	%cs
340
 	pushw	%cs
340
 	pushw	$2f
341
 	pushw	$2f
341
 	pushw	%ax
342
 	pushw	%ax
344
 	.section ".text16", "awx", @progbits
345
 	.section ".text16", "awx", @progbits
345
 1:
346
 1:
346
 	/* Set up protected-mode GDT, call relocate(), reset GDT */
347
 	/* Set up protected-mode GDT, call relocate(), reset GDT */
347
-	call	init_gdt
348
+	call	init_librm
348
 	pushl	$relocate
349
 	pushl	$relocate
349
 	data32 call	prot_call
350
 	data32 call	prot_call
350
 	addw	$4, %sp
351
 	addw	$4, %sp
351
-	call	init_gdt
352
+	call	init_librm
352
 
353
 
353
 	/* Return to executing in .prefix section */
354
 	/* Return to executing in .prefix section */
354
 	lret
355
 	lret

+ 122
- 74
src/arch/i386/transitions/librm.S View File

24
 /****************************************************************************
24
 /****************************************************************************
25
  * Global descriptor table
25
  * Global descriptor table
26
  *
26
  *
27
- * Call init_gdt to set up the GDT before attempting to use any
27
+ * Call init_librm to set up the GDT before attempting to use any
28
  * protected-mode code.
28
  * protected-mode code.
29
  *
29
  *
30
  * Define FLATTEN_REAL_MODE if you want to use so-called "flat real
30
  * Define FLATTEN_REAL_MODE if you want to use so-called "flat real
45
 #else
45
 #else
46
 #define RM_LIMIT_16_19__AVL__SIZE__GRANULARITY 0x00
46
 #define RM_LIMIT_16_19__AVL__SIZE__GRANULARITY 0x00
47
 #endif
47
 #endif
48
-	.section ".text16"
48
+	.section ".data16", "aw", @progbits
49
 	.align 16
49
 	.align 16
50
 gdt:
50
 gdt:
51
 gdt_limit:		.word gdt_length - 1
51
 gdt_limit:		.word gdt_length - 1
86
 	.equ	gdt_length, gdt_end - gdt
86
 	.equ	gdt_length, gdt_end - gdt
87
 
87
 
88
 /****************************************************************************
88
 /****************************************************************************
89
- * init_gdt (real-mode near call, 16-bit real-mode return address)
89
+ * init_librm (real-mode near call, 16-bit real-mode return address)
90
  *
90
  *
91
  * Initialise the GDT ready for transitions to protected mode.
91
  * Initialise the GDT ready for transitions to protected mode.
92
  *
92
  *
93
- * Parameters: 
94
- *   %edi : Physical base of protected-mode code
93
+ * Parameters:
94
+ *   %cs : .text16 segment
95
+ *   %ds : .data16 segment
96
+ *   %edi : Physical base of protected-mode code (virt_offset)
95
  ****************************************************************************
97
  ****************************************************************************
96
  */
98
  */
97
 	.section ".text16"
99
 	.section ".text16"
98
 	.code16
100
 	.code16
99
-	.globl init_gdt
100
-init_gdt:
101
+	.globl init_librm
102
+init_librm:
101
 	/* Preserve registers */
103
 	/* Preserve registers */
102
 	pushl	%eax
104
 	pushl	%eax
103
-	pushw	%bx
104
-
105
-	/* Record virt_offset */
106
-	movl	%edi, %cs:virt_offset_rm_copy
105
+	pushl	%ebx
107
 
106
 
108
-	/* Set virtual_cs and virtual_ds base */
107
+	/* Store _virt_offset and set up virtual_cs and virtual_ds segments */
109
 	movl	%edi, %eax
108
 	movl	%edi, %eax
110
 	movw	$virtual_cs, %bx
109
 	movw	$virtual_cs, %bx
111
 	call	set_seg_base
110
 	call	set_seg_base
112
-
113
-	/* Set real_cs and real_ds base, and GDT base */
114
-	movw	$real_cs, %bx
111
+	movw	$virtual_ds, %bx
112
+	call	set_seg_base	
113
+	movl	%edi, _virt_offset
114
+
115
+	/* Negate virt_offset */
116
+	negl	%edi
117
+		
118
+	/* Store rm_cs and _text16, set up real_cs segment */
115
 	xorl	%eax, %eax
119
 	xorl	%eax, %eax
116
 	movw	%cs, %ax
120
 	movw	%cs, %ax
121
+	movw	%ax, rm_cs
117
 	shll	$4, %eax
122
 	shll	$4, %eax
123
+	movw	$real_cs, %bx
118
 	call	set_seg_base
124
 	call	set_seg_base
119
-	addl	$gdt, %eax
120
-	movl	%eax, %cs:gdt_base
125
+	leal	(%eax, %edi), %ebx
126
+	movl	%ebx, _text16
121
 
127
 
128
+	/* Store rm_ds and _data16, set up real_ds segment and set GDT base */
129
+	xorl	%eax, %eax
130
+	movw	%ds, %ax
131
+	movw	%ax, %cs:rm_ds
132
+	shll	$4, %eax
133
+	movw	$real_ds, %bx
134
+	call	set_seg_base
135
+	leal	(%eax, %edi), %ebx
136
+	movl	%ebx, _data16
137
+	addl	$gdt, %eax
138
+	movl	%eax, gdt_base
139
+		
122
 	/* Restore registers */
140
 	/* Restore registers */
123
-	popw	%bx
141
+	negl	%edi
142
+	popl	%ebx
124
 	popl	%eax
143
 	popl	%eax
125
 	ret
144
 	ret
126
 
145
 
127
 	.section ".text16"
146
 	.section ".text16"
128
 	.code16
147
 	.code16
129
 set_seg_base:
148
 set_seg_base:
130
-	pushl	%eax
131
-	movw	%ax, %cs:(0+2)(%bx)
132
-	movw	%ax, %cs:(8+2)(%bx)
133
-	shrl	$16, %eax
134
-	movb	%al, %cs:(0+4)(%bx)
135
-	movb	%al, %cs:(8+4)(%bx)
136
-	movb	%ah, %cs:(0+7)(%bx)
137
-	movb	%ah, %cs:(8+7)(%bx)
138
-	popl	%eax
149
+1:	movw	%ax, 2(%bx)
150
+	rorl	$16, %eax
151
+	movb	%al, 4(%bx)
152
+	movb	%ah, 7(%bx)
153
+	roll	$16, %eax
139
 	ret
154
 	ret
140
 	
155
 	
141
 /****************************************************************************
156
 /****************************************************************************
157
 	.section ".text16"
172
 	.section ".text16"
158
 	.code16
173
 	.code16
159
 real_to_prot:
174
 real_to_prot:
160
-	/* Protected-mode return address => %ebx */
161
-	popl	%ebx
162
-
163
-	/* Real-mode %cs => %dx, %ss => %bp */
164
-	movw	%cs, %dx
175
+	/* Make sure we have our data segment available */
176
+	movw	%cs:rm_ds, %ax
177
+	movw	%ax, %ds
178
+	
179
+	/* Add _virt_offset, _text16 and _data16 to stack to be
180
+	 * copied, and also copy the return address.
181
+	 */
182
+	pushl	_virt_offset
183
+	pushl	_text16
184
+	pushl	_data16
185
+	addw	$16, %cx /* %ecx must be less than 64kB anyway */
186
+	
187
+	/* Real-mode %ss:%sp => %bp:%esi */
165
 	movw	%ss, %bp
188
 	movw	%ss, %bp
166
-
167
-	/* virt_offset => %edi */
168
-	movl	%cs:virt_offset_rm_copy, %edi
189
+	movzwl	%sp, %esi
169
 
190
 
170
 	/* Switch to protected mode */
191
 	/* Switch to protected mode */
171
 	cli
192
 	cli
172
-	data32 lgdt	%cs:gdt
193
+	data32 lgdt	gdt
173
 	movl	%cr0, %eax
194
 	movl	%cr0, %eax
174
 	orb	$CR0_PE, %al
195
 	orb	$CR0_PE, %al
175
 	movl	%eax, %cr0
196
 	movl	%eax, %cr0
184
 	movw	%ax, %fs
205
 	movw	%ax, %fs
185
 	movw	%ax, %gs
206
 	movw	%ax, %gs
186
 
207
 
187
-	/* Record virt_offset */
188
-	movl	%edi, virt_offset
189
-
190
 	/* Move data from RM stack to PM stack and set up PM stack */
208
 	/* Move data from RM stack to PM stack and set up PM stack */
191
-	movzwl	%sp, %esi
192
 	movl	pm_esp, %esp
209
 	movl	pm_esp, %esp
193
 	subl	%ecx, %esp
210
 	subl	%ecx, %esp
194
 	movl	%esp, %edi
211
 	movl	%esp, %edi
195
 	rep ss movsb
212
 	rep ss movsb
196
 	movw	%ax, %ss
213
 	movw	%ax, %ss
197
 
214
 
198
-	/* Record real-mode %cs and %ss:sp */
199
-	movw	%dx, rm_cs
215
+	/* Record real-mode %ss:sp (after removal of data) */
200
 	movw	%bp, rm_ss
216
 	movw	%bp, rm_ss
201
 	movw	%si, rm_sp
217
 	movw	%si, rm_sp
202
 
218
 
219
+	/* Publish virt_offset, text16 and data16 for PM code to use */
220
+	popl	data16
221
+	popl	text16
222
+	popl	virt_offset
223
+
203
 	/* Return to virtual address */
224
 	/* Return to virtual address */
204
-	jmp	*%ebx
225
+	ret
205
 
226
 
206
 /****************************************************************************
227
 /****************************************************************************
207
  * prot_to_real (protected-mode near call, 32-bit real-mode return address)
228
  * prot_to_real (protected-mode near call, 32-bit real-mode return address)
209
  * Switch from 32-bit protected mode with virtual addresses to 16-bit
230
  * Switch from 32-bit protected mode with virtual addresses to 16-bit
210
  * real mode.  The protected-mode %esp is stored in pm_esp and the
231
  * real mode.  The protected-mode %esp is stored in pm_esp and the
211
  * real-mode %ss:sp is restored from the saved rm_ss and rm_sp.  All
232
  * real-mode %ss:sp is restored from the saved rm_ss and rm_sp.  All
212
- * real-mode data segment registers are set equal to %ss.  Interrupts
213
- * are *not* enabled, since we want to be able to use prot_to_real in
214
- * an ISR.  All other registers may be destroyed.
233
+ * real-mode data segment registers are loaded from the saved rm_ds.
234
+ * Interrupts are *not* enabled, since we want to be able to use
235
+ * prot_to_real in an ISR.  All other registers may be destroyed.
215
  *
236
  *
216
  * The return address for this function should be a 32-bit (sic)
237
  * The return address for this function should be a 32-bit (sic)
217
  * real-mode offset within .code16.
238
  * real-mode offset within .code16.
224
 	.section ".text"
245
 	.section ".text"
225
 	.code32
246
 	.code32
226
 prot_to_real:
247
 prot_to_real:
227
-	/* Real-mode return address => %ebx */
228
-	popl	%ebx
248
+	/* Add return address to data to be moved to RM stack */
249
+	addl	$4, %ecx
229
 	
250
 	
230
 	/* Real-mode %ss:sp => %ebp:edx */
251
 	/* Real-mode %ss:sp => %ebp:edx */
231
 	movzwl	rm_ss, %ebp
252
 	movzwl	rm_ss, %ebp
232
 	movzwl	rm_sp, %edx
253
 	movzwl	rm_sp, %edx
233
 	subl	%ecx, %edx
254
 	subl	%ecx, %edx
234
 	
255
 	
235
-	/* Copy data from PM stack to RM stack */
256
+	/* Move data from PM stack to RM stack */
236
 	movl	%ebp, %eax
257
 	movl	%ebp, %eax
237
 	shll	$4, %eax
258
 	shll	$4, %eax
238
 	leal	(%eax,%edx), %edi
259
 	leal	(%eax,%edx), %edi
240
 	movl	%esp, %esi
261
 	movl	%esp, %esi
241
 	rep movsb
262
 	rep movsb
242
 	
263
 	
243
-	/* Record protected-mode %esp */
264
+	/* Record protected-mode %esp (after removal of data) */
244
 	movl	%esi, pm_esp
265
 	movl	%esi, pm_esp
245
 
266
 
246
-	/* Real-mode %cs => %di */
247
-	movw	rm_cs, %di
248
-
249
 	/* Load real-mode segment limits */
267
 	/* Load real-mode segment limits */
250
 	movw	$REAL_DS, %ax
268
 	movw	$REAL_DS, %ax
251
 	movw	%ax, %ds
269
 	movw	%ax, %ds
257
 	.section ".text16"
275
 	.section ".text16"
258
 	.code16
276
 	.code16
259
 1:
277
 1:
260
-	/* Set up real-mode ljmp instruction */
261
-	movw	%di, %ds:(p2r_ljmp + 3)
262
-	
263
 	/* Switch to real mode */
278
 	/* Switch to real mode */
264
 	movl	%cr0, %eax
279
 	movl	%cr0, %eax
265
 	andb	$0!CR0_PE, %al
280
 	andb	$0!CR0_PE, %al
266
 	movl	%eax, %cr0
281
 	movl	%eax, %cr0
282
+	ljmp	*p2r_jump_vector
283
+p2r_jump_target:
267
 
284
 
268
-p2r_ljmp:
269
-	ljmp	$0, $1f /* Segment is filled in by above code */
270
-1:
271
-	/* Set up real-mode stack and data segments, and stack pointer */
272
-	movw	%bp, %ds
273
-	movw	%bp, %es
274
-	movw	%bp, %fs
275
-	movw	%bp, %gs
285
+	/* Set up real-mode stack */
276
 	movw	%bp, %ss
286
 	movw	%bp, %ss
277
 	movw	%dx, %sp
287
 	movw	%dx, %sp
288
+	
289
+	/* Set up real-mode data segments */
290
+	movw	%cs:rm_ds, %ax
291
+	movw	%ax, %ds
292
+	movw	%ax, %es
293
+	movw	%ax, %fs
294
+	movw	%ax, %gs
278
 
295
 
279
 	/* Return to real-mode address */
296
 	/* Return to real-mode address */
280
-	jmp	*%bx
297
+	data32 ret
298
+
299
+
300
+	/* Real-mode code and data segments.  Assigned by the call to
301
+	 * init_librm.  rm_cs doubles as the segment part of the jump
302
+	 * vector used by prot_to_real.  rm_ds is located in .text16
303
+	 * rather than .data16 because code needs to be able to locate
304
+	 * the data segment.
305
+	 */
306
+	.section ".data16"
307
+p2r_jump_vector:
308
+	.word	p2r_jump_target
309
+rm_cs:	.word 0
310
+	.section ".text16"
311
+rm_ds:	.word 0
281
 	
312
 	
282
 /****************************************************************************
313
 /****************************************************************************
283
  * prot_call (real-mode near call, 32-bit real-mode return address)
314
  * prot_call (real-mode near call, 32-bit real-mode return address)
406
 	/* Construct call to real-mode function */
437
 	/* Construct call to real-mode function */
407
 	movw	%sp, %bp
438
 	movw	%sp, %bp
408
 	movw	RC_OFFSET_FUNCTION(%bp), %ax
439
 	movw	RC_OFFSET_FUNCTION(%bp), %ax
409
-	movw	%ax, %cs:rc_function
440
+	movw	%ax, rc_function
410
 
441
 
411
 	/* Call real-mode function */
442
 	/* Call real-mode function */
412
 	popal
443
 	popal
413
-	call	*%cs:rc_function
444
+	call	*RC_OFFSET_FUNCTION(%esp)
445
+	call	*rc_function
414
 	pushal
446
 	pushal
415
 
447
 
416
 	/* Switch to protected mode and move register dump back to PM stack */
448
 	/* Switch to protected mode and move register dump back to PM stack */
427
 	popal
459
 	popal
428
 	ret
460
 	ret
429
 
461
 
430
-	.section ".text16"
462
+
463
+	/* Function vector, used because */
464
+	.section ".data16"
431
 rc_function:	.word 0
465
 rc_function:	.word 0
432
 	
466
 	
433
 /****************************************************************************
467
 /****************************************************************************
464
  * to us.
498
  * to us.
465
  ****************************************************************************
499
  ****************************************************************************
466
  */
500
  */
467
-
468
 	.section ".data"
501
 	.section ".data"
469
 	.globl rm_sp
502
 	.globl rm_sp
470
 rm_sp:	.word 0
503
 rm_sp:	.word 0
471
 	.globl rm_ss
504
 	.globl rm_ss
472
 rm_ss:	.word 0
505
 rm_ss:	.word 0
473
-	.globl rm_cs
474
-rm_cs:	.word 0
475
 	.globl pm_esp
506
 	.globl pm_esp
476
 pm_esp:	.long _estack
507
 pm_esp:	.long _estack
477
 
508
 
478
-	.section ".text16"
479
-virt_offset_rm_copy:	.long 0
509
+/****************************************************************************
510
+ * Virtual address offsets
511
+ *
512
+ * These are used by the protected-mode code to map between virtual
513
+ * and physical addresses, and to access variables in the .text16 or
514
+ * .data16 segments.
515
+ ****************************************************************************
516
+ */
517
+	/* Internal copies, created by init_librm (which runs in real mode) */
518
+	.section ".data16"
519
+_virt_offset:	.long 0
520
+_text16:	.long 0
521
+_data16:	.long 0
522
+
523
+	/* Externally-visible copies, created by real_to_prot */
480
 	.section ".data"
524
 	.section ".data"
481
 	.globl virt_offset
525
 	.globl virt_offset
482
-virt_offset:		.long 0	
526
+virt_offset:	.long 0	
527
+	.globl text16
528
+text16:		.long 0
529
+	.globl data16
530
+data16:		.long 0

Loading…
Cancel
Save