Browse Source

[libflat] Test A20 gate without switching to flat real mode

Use the real-mode address ffff:0010 to access the linear address
0x100000, and so test whether or not the A20 gate is enabled without
requiring a switch into flat real mode (or some other addressing
mode).

This speeds up CPU mode transitions, and also avoids breaking the NBP
from IBM's Tivoli Provisioning Manager for Operating System
Deployment.  This NBP makes some calls to iPXE in VM86 mode rather
than true real mode and does not correctly emulate our transition into
flat real mode.

Interestingly, Tivoli's VMM *does* allow us to switch into protected
mode (though it patches our GDT so that we execute in ring 1 rather
than ring 0).  However, paging is still disabled and we have a 4GB
segment limit.  Being in ring 1 does not, therefore, restrict us in
any meaningful way; this has been verified by deliberately writing
garbage over Tivoli's own GDT (at address 0x02201010) during a
nominally VM86-mode PXE API call.  It's unclear precisely what
protection this VMM is supposed to be offering.

Suggested-by: Joshua Oreman <oremanj@rwcr.net>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 13 years ago
parent
commit
87723a0f11
1 changed files with 18 additions and 12 deletions
  1. 18
    12
      src/arch/i386/transitions/libflat.S

+ 18
- 12
src/arch/i386/transitions/libflat.S View File

@@ -165,14 +165,23 @@ test_a20_long:
165 165
 	pushl	%ecx
166 166
 	movl	$TEST_A20_LONG_MAX_RETRIES, %ecx
167 167
 1:	pushw	%ax
168
+	pushw	%ds
169
+	pushw	%es
168 170
 
169
-	/* Flatten real mode so we can access the test pattern's 1MB offset */
170
-	call	flatten_real_mode
171
+	/* Set up segment registers for access across the 1MB boundary */
172
+	xorw	%ax, %ax
173
+	movw	%ax, %ds
174
+	decw	%ax
175
+	movw	%ax, %es
171 176
 
172 177
 2:	/* Modify and check test pattern; succeed if we see a difference */
173
-	incw	%cs:test_a20_data
174
-	addr32 movw %cs:(test_a20_data + 0x100000 ), %ax
175
-	cmpw	%cs:test_a20_data, %ax
178
+	pushfw
179
+	cli
180
+	xchgw	%ds:0, %cx
181
+	movw	%es:0x10, %ax
182
+	xchgw	%ds:0, %cx
183
+	popfw
184
+	cmpw	%ax, %cx
176 185
 	clc
177 186
 	jnz	99f
178 187
 
@@ -182,17 +191,13 @@ test_a20_long:
182 191
 	stc
183 192
 
184 193
 99:	/* Restore registers and return */
194
+	popw	%es
195
+	popw	%ds
185 196
 	popw	%ax
186 197
 	popl	%ecx
187 198
 	ret
188 199
 	.size	test_a20_long, . - test_a20_long
189 200
 
190
-	.section ".text16.early.data", "aw", @progbits
191
-	.align	2
192
-test_a20_data:
193
-	.word	0xdead
194
-	.size	test_a20_data, . - test_a20_data
195
-
196 201
 /****************************************************************************
197 202
  * enable_a20_bios
198 203
  *
@@ -414,6 +419,7 @@ enable_a20_method:
414 419
 access_highmem:
415 420
 	/* Enable A20 line */
416 421
 	call	enable_a20
417
-	/* CPU will be in flat real mode as a result of this call */
422
+	/* Set up 4GB limits */
423
+	call	flatten_real_mode
418 424
 	lret
419 425
 	.size	access_highmem, . - access_highmem

Loading…
Cancel
Save