|  | @@ -253,12 +253,6 @@ r2p_pmode:
 | 
		
	
		
			
			| 253 | 253 |  	/* Return to virtual address */
 | 
		
	
		
			
			| 254 | 254 |  	ret
 | 
		
	
		
			
			| 255 | 255 |  
 | 
		
	
		
			
			| 256 |  | -	/* Default real-mode interrupt descriptor table */
 | 
		
	
		
			
			| 257 |  | -	.section ".data", "aw", @progbits
 | 
		
	
		
			
			| 258 |  | -rm_idtr:
 | 
		
	
		
			
			| 259 |  | -	.word 0xffff /* limit */
 | 
		
	
		
			
			| 260 |  | -	.long 0 /* base */
 | 
		
	
		
			
			| 261 |  | -
 | 
		
	
		
			
			| 262 | 256 |  /****************************************************************************
 | 
		
	
		
			
			| 263 | 257 |   * prot_to_real (protected-mode near call, 32-bit real-mode return address)
 | 
		
	
		
			
			| 264 | 258 |   *
 | 
		
	
	
		
			
			|  | @@ -275,12 +269,22 @@ rm_idtr:
 | 
		
	
		
			
			| 275 | 269 |   *
 | 
		
	
		
			
			| 276 | 270 |   * Parameters: 
 | 
		
	
		
			
			| 277 | 271 |   *   %ecx : number of bytes to move from PM stack to RM stack
 | 
		
	
		
			
			|  | 272 | + *   %esi : real-mode global and interrupt descriptor table registers
 | 
		
	
		
			
			| 278 | 273 |   *
 | 
		
	
		
			
			| 279 | 274 |   ****************************************************************************
 | 
		
	
		
			
			| 280 | 275 |   */
 | 
		
	
		
			
			| 281 | 276 |  	.section ".text", "ax", @progbits
 | 
		
	
		
			
			| 282 | 277 |  	.code32
 | 
		
	
		
			
			| 283 | 278 |  prot_to_real:
 | 
		
	
		
			
			|  | 279 | +	/* Copy real-mode global descriptor table register to RM code segment */
 | 
		
	
		
			
			|  | 280 | +	movl	text16, %edi
 | 
		
	
		
			
			|  | 281 | +	leal	rm_gdtr(%edi), %edi
 | 
		
	
		
			
			|  | 282 | +	movsw
 | 
		
	
		
			
			|  | 283 | +	movsl
 | 
		
	
		
			
			|  | 284 | +
 | 
		
	
		
			
			|  | 285 | +	/* Load real-mode interrupt descriptor table register */
 | 
		
	
		
			
			|  | 286 | +	lidt	(%esi)
 | 
		
	
		
			
			|  | 287 | +
 | 
		
	
		
			
			| 284 | 288 |  	/* Add return address to data to be moved to RM stack */
 | 
		
	
		
			
			| 285 | 289 |  	addl	$4, %ecx
 | 
		
	
		
			
			| 286 | 290 |  	
 | 
		
	
	
		
			
			|  | @@ -300,9 +304,6 @@ prot_to_real:
 | 
		
	
		
			
			| 300 | 304 |  	/* Record protected-mode %esp (after removal of data) */
 | 
		
	
		
			
			| 301 | 305 |  	movl	%esi, pm_esp
 | 
		
	
		
			
			| 302 | 306 |  
 | 
		
	
		
			
			| 303 |  | -	/* Reset IDTR to the real-mode defaults */
 | 
		
	
		
			
			| 304 |  | -	lidt	rm_idtr
 | 
		
	
		
			
			| 305 |  | -
 | 
		
	
		
			
			| 306 | 307 |  	/* Load real-mode segment limits */
 | 
		
	
		
			
			| 307 | 308 |  	movw	$REAL_DS, %ax
 | 
		
	
		
			
			| 308 | 309 |  	movw	%ax, %ds
 | 
		
	
	
		
			
			|  | @@ -314,6 +315,8 @@ prot_to_real:
 | 
		
	
		
			
			| 314 | 315 |  	.section ".text16", "ax", @progbits
 | 
		
	
		
			
			| 315 | 316 |  	.code16
 | 
		
	
		
			
			| 316 | 317 |  p2r_rmode:
 | 
		
	
		
			
			|  | 318 | +	/* Load real-mode GDT */
 | 
		
	
		
			
			|  | 319 | +	data32 lgdt %cs:rm_gdtr
 | 
		
	
		
			
			| 317 | 320 |  	/* Switch to real mode */
 | 
		
	
		
			
			| 318 | 321 |  	movl	%cr0, %eax
 | 
		
	
		
			
			| 319 | 322 |  	andb	$0!CR0_PE, %al
 | 
		
	
	
		
			
			|  | @@ -349,6 +352,12 @@ p2r_ljmp_rm_cs:
 | 
		
	
		
			
			| 349 | 352 |  	.globl rm_ds
 | 
		
	
		
			
			| 350 | 353 |  rm_ds:	.word 0
 | 
		
	
		
			
			| 351 | 354 |  
 | 
		
	
		
			
			|  | 355 | +	/* Real-mode global and interrupt descriptor table registers */
 | 
		
	
		
			
			|  | 356 | +	.section ".text16.data", "aw", @progbits
 | 
		
	
		
			
			|  | 357 | +rm_gdtr:
 | 
		
	
		
			
			|  | 358 | +	.word 0 /* Limit */
 | 
		
	
		
			
			|  | 359 | +	.long 0 /* Base */
 | 
		
	
		
			
			|  | 360 | +
 | 
		
	
		
			
			| 352 | 361 |  /****************************************************************************
 | 
		
	
		
			
			| 353 | 362 |   * prot_call (real-mode far call, 16-bit real-mode far return address)
 | 
		
	
		
			
			| 354 | 363 |   *
 | 
		
	
	
		
			
			|  | @@ -384,8 +393,8 @@ rm_ds:	.word 0
 | 
		
	
		
			
			| 384 | 393 |   */
 | 
		
	
		
			
			| 385 | 394 |  
 | 
		
	
		
			
			| 386 | 395 |  #define PC_OFFSET_GDT ( 0 )
 | 
		
	
		
			
			| 387 |  | -#define PC_OFFSET_IDT ( PC_OFFSET_GDT + 8 /* pad to 8 to keep alignment */ )
 | 
		
	
		
			
			| 388 |  | -#define PC_OFFSET_IX86 ( PC_OFFSET_IDT + 8 /* pad to 8 to keep alignment */ )
 | 
		
	
		
			
			|  | 396 | +#define PC_OFFSET_IDT ( PC_OFFSET_GDT + 6 )
 | 
		
	
		
			
			|  | 397 | +#define PC_OFFSET_IX86 ( PC_OFFSET_IDT + 6 )
 | 
		
	
		
			
			| 389 | 398 |  #define PC_OFFSET_RETADDR ( PC_OFFSET_IX86 + SIZEOF_I386_ALL_REGS )
 | 
		
	
		
			
			| 390 | 399 |  #define PC_OFFSET_FUNCTION ( PC_OFFSET_RETADDR + 4 )
 | 
		
	
		
			
			| 391 | 400 |  #define PC_OFFSET_END ( PC_OFFSET_FUNCTION + 4 )
 | 
		
	
	
		
			
			|  | @@ -403,10 +412,10 @@ prot_call:
 | 
		
	
		
			
			| 403 | 412 |  	pushw	%ds
 | 
		
	
		
			
			| 404 | 413 |  	pushw	%ss
 | 
		
	
		
			
			| 405 | 414 |  	pushw	%cs
 | 
		
	
		
			
			| 406 |  | -	subw	$16, %sp
 | 
		
	
		
			
			|  | 415 | +	subw	$PC_OFFSET_IX86, %sp
 | 
		
	
		
			
			| 407 | 416 |  	movw	%sp, %bp
 | 
		
	
		
			
			| 408 |  | -	sidt	8(%bp)
 | 
		
	
		
			
			| 409 |  | -	sgdt	(%bp)
 | 
		
	
		
			
			|  | 417 | +	sidt	PC_OFFSET_IDT(%bp)
 | 
		
	
		
			
			|  | 418 | +	sgdt	PC_OFFSET_GDT(%bp)
 | 
		
	
		
			
			| 410 | 419 |  
 | 
		
	
		
			
			| 411 | 420 |  	/* For sanity's sake, clear the direction flag as soon as possible */
 | 
		
	
		
			
			| 412 | 421 |  	cld
 | 
		
	
	
		
			
			|  | @@ -426,16 +435,14 @@ pc_pmode:
 | 
		
	
		
			
			| 426 | 435 |  
 | 
		
	
		
			
			| 427 | 436 |  	/* Switch to real mode and move register dump back to RM stack */
 | 
		
	
		
			
			| 428 | 437 |  	movl	$PC_OFFSET_END, %ecx
 | 
		
	
		
			
			|  | 438 | +	movl	%esp, %esi
 | 
		
	
		
			
			| 429 | 439 |  	pushl	$pc_rmode
 | 
		
	
		
			
			| 430 | 440 |  	jmp	prot_to_real
 | 
		
	
		
			
			| 431 | 441 |  	.section ".text16", "ax", @progbits
 | 
		
	
		
			
			| 432 | 442 |  	.code16
 | 
		
	
		
			
			| 433 | 443 |  pc_rmode:
 | 
		
	
		
			
			| 434 |  | -	/* Reload GDT and IDT, restore registers and flags and return */
 | 
		
	
		
			
			| 435 |  | -	movw	%sp, %bp
 | 
		
	
		
			
			| 436 |  | -	data32 lgdt (%bp)
 | 
		
	
		
			
			| 437 |  | -	data32 lidt 8(%bp)
 | 
		
	
		
			
			| 438 |  | -	addw	$20, %sp /* also skip %cs and %ss */
 | 
		
	
		
			
			|  | 444 | +	/* Restore registers and flags and return */
 | 
		
	
		
			
			|  | 445 | +	addw	$( PC_OFFSET_IX86 + 4 /* also skip %cs and %ss */ ), %sp
 | 
		
	
		
			
			| 439 | 446 |  	popw	%ds
 | 
		
	
		
			
			| 440 | 447 |  	popw	%es
 | 
		
	
		
			
			| 441 | 448 |  	popw	%fs
 | 
		
	
	
		
			
			|  | @@ -489,6 +496,7 @@ real_call:
 | 
		
	
		
			
			| 489 | 496 |  	/* Switch to real mode and move register dump to RM stack  */
 | 
		
	
		
			
			| 490 | 497 |  	movl	$( RC_OFFSET_RETADDR + 4 /* function pointer copy */ ), %ecx
 | 
		
	
		
			
			| 491 | 498 |  	pushl	$rc_rmode
 | 
		
	
		
			
			|  | 499 | +	movl	$rm_default_gdtr_idtr, %esi
 | 
		
	
		
			
			| 492 | 500 |  	jmp	prot_to_real
 | 
		
	
		
			
			| 493 | 501 |  	.section ".text16", "ax", @progbits
 | 
		
	
		
			
			| 494 | 502 |  	.code16
 | 
		
	
	
		
			
			|  | @@ -520,6 +528,14 @@ rc_pmode:
 | 
		
	
		
			
			| 520 | 528 |  	.section ".data16", "aw", @progbits
 | 
		
	
		
			
			| 521 | 529 |  rc_function:	.word 0, 0
 | 
		
	
		
			
			| 522 | 530 |  
 | 
		
	
		
			
			|  | 531 | +	/* Default real-mode global and interrupt descriptor table registers */
 | 
		
	
		
			
			|  | 532 | +	.section ".data", "aw", @progbits
 | 
		
	
		
			
			|  | 533 | +rm_default_gdtr_idtr:
 | 
		
	
		
			
			|  | 534 | +	.word 0		/* Global descriptor table limit */
 | 
		
	
		
			
			|  | 535 | +	.long 0		/* Global descriptor table base */
 | 
		
	
		
			
			|  | 536 | +	.word 0x03ff	/* Interrupt descriptor table limit */
 | 
		
	
		
			
			|  | 537 | +	.long 0		/* Interrupt descriptor table base */
 | 
		
	
		
			
			|  | 538 | +
 | 
		
	
		
			
			| 523 | 539 |  /****************************************************************************
 | 
		
	
		
			
			| 524 | 540 |   * flatten_real_mode (real-mode near call)
 | 
		
	
		
			
			| 525 | 541 |   *
 |