|  | @@ -501,6 +501,150 @@ rm_gdtr:
 | 
		
	
		
			
			| 501 | 501 |  	.word 0 /* Limit */
 | 
		
	
		
			
			| 502 | 502 |  	.long 0 /* Base */
 | 
		
	
		
			
			| 503 | 503 |  
 | 
		
	
		
			
			|  | 504 | +/****************************************************************************
 | 
		
	
		
			
			|  | 505 | + * phys_to_prot (protected-mode near call, 32-bit physical return address)
 | 
		
	
		
			
			|  | 506 | + *
 | 
		
	
		
			
			|  | 507 | + * Switch from 32-bit protected mode with physical addresses to 32-bit
 | 
		
	
		
			
			|  | 508 | + * protected mode with virtual addresses.  %esp is adjusted to a
 | 
		
	
		
			
			|  | 509 | + * virtual address.  All other registers and flags are preserved.
 | 
		
	
		
			
			|  | 510 | + *
 | 
		
	
		
			
			|  | 511 | + * The return address for this function should be a 32-bit physical
 | 
		
	
		
			
			|  | 512 | + * (sic) address.
 | 
		
	
		
			
			|  | 513 | + *
 | 
		
	
		
			
			|  | 514 | + ****************************************************************************
 | 
		
	
		
			
			|  | 515 | + */
 | 
		
	
		
			
			|  | 516 | +	.section ".text.phys_to_prot", "ax", @progbits
 | 
		
	
		
			
			|  | 517 | +	.code32
 | 
		
	
		
			
			|  | 518 | +	.globl phys_to_prot
 | 
		
	
		
			
			|  | 519 | +phys_to_prot:
 | 
		
	
		
			
			|  | 520 | +	/* Preserve registers and flags */
 | 
		
	
		
			
			|  | 521 | +	pushfl
 | 
		
	
		
			
			|  | 522 | +	pushl	%eax
 | 
		
	
		
			
			|  | 523 | +	pushl	%ebp
 | 
		
	
		
			
			|  | 524 | +
 | 
		
	
		
			
			|  | 525 | +	/* Switch to virtual code segment */
 | 
		
	
		
			
			|  | 526 | +	cli
 | 
		
	
		
			
			|  | 527 | +	ljmp	$VIRTUAL_CS, $VIRTUAL(1f)
 | 
		
	
		
			
			|  | 528 | +1:
 | 
		
	
		
			
			|  | 529 | +	/* Switch to virtual data segment and adjust %esp */
 | 
		
	
		
			
			|  | 530 | +	movw	$VIRTUAL_DS, %ax
 | 
		
	
		
			
			|  | 531 | +	movw	%ax, %ds
 | 
		
	
		
			
			|  | 532 | +	movw	%ax, %es
 | 
		
	
		
			
			|  | 533 | +	movw	%ax, %fs
 | 
		
	
		
			
			|  | 534 | +	movw	%ax, %gs
 | 
		
	
		
			
			|  | 535 | +	movw	%ax, %ss
 | 
		
	
		
			
			|  | 536 | +	movl	VIRTUAL(virt_offset), %ebp
 | 
		
	
		
			
			|  | 537 | +	subl	%ebp, %esp
 | 
		
	
		
			
			|  | 538 | +
 | 
		
	
		
			
			|  | 539 | +	/* Adjust return address to a virtual address */
 | 
		
	
		
			
			|  | 540 | +	subl	%ebp, 12(%esp)
 | 
		
	
		
			
			|  | 541 | +
 | 
		
	
		
			
			|  | 542 | +	/* Restore registers and flags, and return */
 | 
		
	
		
			
			|  | 543 | +	popl	%ebp
 | 
		
	
		
			
			|  | 544 | +	popl	%eax
 | 
		
	
		
			
			|  | 545 | +	popfl
 | 
		
	
		
			
			|  | 546 | +	ret
 | 
		
	
		
			
			|  | 547 | +
 | 
		
	
		
			
			|  | 548 | +	/* Expose as _phys_to_virt for use by COMBOOT */
 | 
		
	
		
			
			|  | 549 | +	.globl	_phys_to_virt
 | 
		
	
		
			
			|  | 550 | +	.equ	_phys_to_virt, phys_to_prot
 | 
		
	
		
			
			|  | 551 | +
 | 
		
	
		
			
			|  | 552 | +/****************************************************************************
 | 
		
	
		
			
			|  | 553 | + * prot_to_phys (protected-mode near call, 32-bit virtual return address)
 | 
		
	
		
			
			|  | 554 | + *
 | 
		
	
		
			
			|  | 555 | + * Switch from 32-bit protected mode with virtual addresses to 32-bit
 | 
		
	
		
			
			|  | 556 | + * protected mode with physical addresses.  %esp is adjusted to a
 | 
		
	
		
			
			|  | 557 | + * physical address.  All other registers and flags are preserved.
 | 
		
	
		
			
			|  | 558 | + *
 | 
		
	
		
			
			|  | 559 | + * The return address for this function should be a 32-bit virtual
 | 
		
	
		
			
			|  | 560 | + * (sic) address.
 | 
		
	
		
			
			|  | 561 | + *
 | 
		
	
		
			
			|  | 562 | + ****************************************************************************
 | 
		
	
		
			
			|  | 563 | + */
 | 
		
	
		
			
			|  | 564 | +	.section ".text.prot_to_phys", "ax", @progbits
 | 
		
	
		
			
			|  | 565 | +	.code32
 | 
		
	
		
			
			|  | 566 | +prot_to_phys:
 | 
		
	
		
			
			|  | 567 | +	/* Preserve registers and flags */
 | 
		
	
		
			
			|  | 568 | +	pushfl
 | 
		
	
		
			
			|  | 569 | +	pushl	%eax
 | 
		
	
		
			
			|  | 570 | +	pushl	%ebp
 | 
		
	
		
			
			|  | 571 | +
 | 
		
	
		
			
			|  | 572 | +	/* Adjust return address to a physical address */
 | 
		
	
		
			
			|  | 573 | +	movl	VIRTUAL(virt_offset), %ebp
 | 
		
	
		
			
			|  | 574 | +	addl	%ebp, 12(%esp)
 | 
		
	
		
			
			|  | 575 | +
 | 
		
	
		
			
			|  | 576 | +	/* Switch to physical code segment */
 | 
		
	
		
			
			|  | 577 | +	cli
 | 
		
	
		
			
			|  | 578 | +	pushl	$PHYSICAL_CS
 | 
		
	
		
			
			|  | 579 | +	leal	VIRTUAL(1f)(%ebp), %eax
 | 
		
	
		
			
			|  | 580 | +	pushl	%eax
 | 
		
	
		
			
			|  | 581 | +	lret
 | 
		
	
		
			
			|  | 582 | +1:
 | 
		
	
		
			
			|  | 583 | +	/* Switch to physical data segment and adjust %esp */
 | 
		
	
		
			
			|  | 584 | +	movw	$PHYSICAL_DS, %ax
 | 
		
	
		
			
			|  | 585 | +	movw	%ax, %ds
 | 
		
	
		
			
			|  | 586 | +	movw	%ax, %es
 | 
		
	
		
			
			|  | 587 | +	movw	%ax, %fs
 | 
		
	
		
			
			|  | 588 | +	movw	%ax, %gs
 | 
		
	
		
			
			|  | 589 | +	movw	%ax, %ss
 | 
		
	
		
			
			|  | 590 | +	addl	%ebp, %esp
 | 
		
	
		
			
			|  | 591 | +
 | 
		
	
		
			
			|  | 592 | +	/* Restore registers and flags, and return */
 | 
		
	
		
			
			|  | 593 | +	popl	%ebp
 | 
		
	
		
			
			|  | 594 | +	popl	%eax
 | 
		
	
		
			
			|  | 595 | +	popfl
 | 
		
	
		
			
			|  | 596 | +	ret
 | 
		
	
		
			
			|  | 597 | +
 | 
		
	
		
			
			|  | 598 | +	/* Expose as _virt_to_phys for use by COMBOOT */
 | 
		
	
		
			
			|  | 599 | +	.globl	_virt_to_phys
 | 
		
	
		
			
			|  | 600 | +	.equ	_virt_to_phys, prot_to_phys
 | 
		
	
		
			
			|  | 601 | +
 | 
		
	
		
			
			|  | 602 | +/****************************************************************************
 | 
		
	
		
			
			|  | 603 | + * intr_to_prot (protected-mode near call, 32-bit virtual return address)
 | 
		
	
		
			
			|  | 604 | + *
 | 
		
	
		
			
			|  | 605 | + * Switch from 32-bit protected mode with a virtual code segment and
 | 
		
	
		
			
			|  | 606 | + * either a physical or virtual stack segment to 32-bit protected mode
 | 
		
	
		
			
			|  | 607 | + * with normal virtual addresses.  %esp is adjusted if necessary to a
 | 
		
	
		
			
			|  | 608 | + * virtual address.  All other registers and flags are preserved.
 | 
		
	
		
			
			|  | 609 | + *
 | 
		
	
		
			
			|  | 610 | + * The return address for this function should be a 32-bit virtual
 | 
		
	
		
			
			|  | 611 | + * address.
 | 
		
	
		
			
			|  | 612 | + *
 | 
		
	
		
			
			|  | 613 | + ****************************************************************************
 | 
		
	
		
			
			|  | 614 | + */
 | 
		
	
		
			
			|  | 615 | +	.section ".text.intr_to_prot", "ax", @progbits
 | 
		
	
		
			
			|  | 616 | +	.code32
 | 
		
	
		
			
			|  | 617 | +	.globl intr_to_prot
 | 
		
	
		
			
			|  | 618 | +intr_to_prot:
 | 
		
	
		
			
			|  | 619 | +	/* Preserve registers and flags */
 | 
		
	
		
			
			|  | 620 | +	pushfl
 | 
		
	
		
			
			|  | 621 | +	pushl	%eax
 | 
		
	
		
			
			|  | 622 | +
 | 
		
	
		
			
			|  | 623 | +	/* Check whether stack segment is physical or virtual */
 | 
		
	
		
			
			|  | 624 | +	movw	%ss, %ax
 | 
		
	
		
			
			|  | 625 | +	cmpw	$VIRTUAL_DS, %ax
 | 
		
	
		
			
			|  | 626 | +	movw	$VIRTUAL_DS, %ax
 | 
		
	
		
			
			|  | 627 | +
 | 
		
	
		
			
			|  | 628 | +	/* Reload data segment registers */
 | 
		
	
		
			
			|  | 629 | +	movw	%ax, %ds
 | 
		
	
		
			
			|  | 630 | +	movw	%ax, %es
 | 
		
	
		
			
			|  | 631 | +	movw	%ax, %fs
 | 
		
	
		
			
			|  | 632 | +	movw	%ax, %gs
 | 
		
	
		
			
			|  | 633 | +
 | 
		
	
		
			
			|  | 634 | +	/* Reload stack segment and adjust %esp if necessary */
 | 
		
	
		
			
			|  | 635 | +	je	1f
 | 
		
	
		
			
			|  | 636 | +	movw	%ax, %ss
 | 
		
	
		
			
			|  | 637 | +	subl	VIRTUAL(virt_offset), %esp
 | 
		
	
		
			
			|  | 638 | +1:
 | 
		
	
		
			
			|  | 639 | +	/* Restore registers and flags, and return */
 | 
		
	
		
			
			|  | 640 | +	popl	%eax
 | 
		
	
		
			
			|  | 641 | +	popfl
 | 
		
	
		
			
			|  | 642 | +	ret
 | 
		
	
		
			
			|  | 643 | +
 | 
		
	
		
			
			|  | 644 | +	/* Expose as _intr_to_virt for use by GDB */
 | 
		
	
		
			
			|  | 645 | +	.globl	_intr_to_virt
 | 
		
	
		
			
			|  | 646 | +	.equ	_intr_to_virt, intr_to_prot
 | 
		
	
		
			
			|  | 647 | +
 | 
		
	
		
			
			| 504 | 648 |  /****************************************************************************
 | 
		
	
		
			
			| 505 | 649 |   * prot_call (real-mode near call, 16-bit real-mode near return address)
 | 
		
	
		
			
			| 506 | 650 |   *
 | 
		
	
	
		
			
			|  | @@ -539,6 +683,7 @@ PC_OFFSET_IDT:		.space	6
 | 
		
	
		
			
			| 539 | 683 |  PC_OFFSET_IX86:		.space	SIZEOF_I386_ALL_REGS
 | 
		
	
		
			
			| 540 | 684 |  PC_OFFSET_PADDING:	.space	2 /* for alignment */
 | 
		
	
		
			
			| 541 | 685 |  PC_OFFSET_RETADDR:	.space	2
 | 
		
	
		
			
			|  | 686 | +PC_OFFSET_PARAMS:
 | 
		
	
		
			
			| 542 | 687 |  PC_OFFSET_FUNCTION:	.space	4
 | 
		
	
		
			
			| 543 | 688 |  PC_OFFSET_END:
 | 
		
	
		
			
			| 544 | 689 |  	.previous
 | 
		
	
	
		
			
			|  | @@ -601,7 +746,9 @@ pc_rmode:
 | 
		
	
		
			
			| 601 | 746 |  	addr32 movl -20(%esp), %esp
 | 
		
	
		
			
			| 602 | 747 |  	popfl
 | 
		
	
		
			
			| 603 | 748 |  	popfw	/* padding */
 | 
		
	
		
			
			| 604 |  | -	ret	$4
 | 
		
	
		
			
			|  | 749 | +
 | 
		
	
		
			
			|  | 750 | +	/* Return and discard function parameters */
 | 
		
	
		
			
			|  | 751 | +	ret	$( PC_OFFSET_END - PC_OFFSET_PARAMS )
 | 
		
	
		
			
			| 605 | 752 |  
 | 
		
	
		
			
			| 606 | 753 |  /****************************************************************************
 | 
		
	
		
			
			| 607 | 754 |   * real_call (protected-mode near call, 32-bit virtual return address)
 | 
		
	
	
		
			
			|  | @@ -620,7 +767,7 @@ pc_rmode:
 | 
		
	
		
			
			| 620 | 767 |   * See librm.h and realmode.h for details and examples.
 | 
		
	
		
			
			| 621 | 768 |   *
 | 
		
	
		
			
			| 622 | 769 |   * Parameters:
 | 
		
	
		
			
			| 623 |  | - *   (32-bit) near pointer to real-mode function to call
 | 
		
	
		
			
			|  | 770 | + *   function : offset within .text16 of real-mode function to call
 | 
		
	
		
			
			| 624 | 771 |   *
 | 
		
	
		
			
			| 625 | 772 |   * Returns: none
 | 
		
	
		
			
			| 626 | 773 |   ****************************************************************************
 | 
		
	
	
		
			
			|  | @@ -629,6 +776,7 @@ pc_rmode:
 | 
		
	
		
			
			| 629 | 776 |  RC_OFFSET_REGS:		.space	SIZEOF_I386_REGS
 | 
		
	
		
			
			| 630 | 777 |  RC_OFFSET_REGS_END:
 | 
		
	
		
			
			| 631 | 778 |  RC_OFFSET_RETADDR:	.space	4
 | 
		
	
		
			
			|  | 779 | +RC_OFFSET_PARAMS:
 | 
		
	
		
			
			| 632 | 780 |  RC_OFFSET_FUNCTION:	.space	4
 | 
		
	
		
			
			| 633 | 781 |  RC_OFFSET_END:
 | 
		
	
		
			
			| 634 | 782 |  	.previous
 | 
		
	
	
		
			
			|  | @@ -665,9 +813,11 @@ rc_rmode:
 | 
		
	
		
			
			| 665 | 813 |  	.section ".text.real_call", "ax", @progbits
 | 
		
	
		
			
			| 666 | 814 |  	.code32
 | 
		
	
		
			
			| 667 | 815 |  rc_pmode:
 | 
		
	
		
			
			| 668 |  | -	/* Restore registers and return */
 | 
		
	
		
			
			|  | 816 | +	/* Restore registers */
 | 
		
	
		
			
			| 669 | 817 |  	popal
 | 
		
	
		
			
			| 670 |  | -	ret	$4
 | 
		
	
		
			
			|  | 818 | +
 | 
		
	
		
			
			|  | 819 | +	/* Return and discard function parameters */
 | 
		
	
		
			
			|  | 820 | +	ret	$( RC_OFFSET_END - RC_OFFSET_PARAMS )
 | 
		
	
		
			
			| 671 | 821 |  
 | 
		
	
		
			
			| 672 | 822 |  
 | 
		
	
		
			
			| 673 | 823 |  	/* Function vector, used because "call xx(%sp)" is not a valid
 | 
		
	
	
		
			
			|  | @@ -684,6 +834,55 @@ rm_default_gdtr_idtr:
 | 
		
	
		
			
			| 684 | 834 |  	.word 0x03ff	/* Interrupt descriptor table limit */
 | 
		
	
		
			
			| 685 | 835 |  	.long 0		/* Interrupt descriptor table base */
 | 
		
	
		
			
			| 686 | 836 |  
 | 
		
	
		
			
			|  | 837 | +/****************************************************************************
 | 
		
	
		
			
			|  | 838 | + * phys_call (protected-mode near call, 32-bit virtual return address)
 | 
		
	
		
			
			|  | 839 | + *
 | 
		
	
		
			
			|  | 840 | + * Call a function with flat 32-bit physical addressing
 | 
		
	
		
			
			|  | 841 | + *
 | 
		
	
		
			
			|  | 842 | + * The non-segment register values will be passed directly to the
 | 
		
	
		
			
			|  | 843 | + * function.  The segment registers will be set for flat 32-bit
 | 
		
	
		
			
			|  | 844 | + * physical addressing.  The non-segment register values set by the
 | 
		
	
		
			
			|  | 845 | + * function will be passed back to the caller.
 | 
		
	
		
			
			|  | 846 | + *
 | 
		
	
		
			
			|  | 847 | + * librm.h defines a convenient macro PHYS_CODE() for using phys_call.
 | 
		
	
		
			
			|  | 848 | + *
 | 
		
	
		
			
			|  | 849 | + * Parameters:
 | 
		
	
		
			
			|  | 850 | + *   function : virtual (sic) address of function to call
 | 
		
	
		
			
			|  | 851 | + *
 | 
		
	
		
			
			|  | 852 | + ****************************************************************************
 | 
		
	
		
			
			|  | 853 | + */
 | 
		
	
		
			
			|  | 854 | +	.struct 0
 | 
		
	
		
			
			|  | 855 | +PHC_OFFSET_RETADDR:	.space	4
 | 
		
	
		
			
			|  | 856 | +PHC_OFFSET_PARAMS:
 | 
		
	
		
			
			|  | 857 | +PHC_OFFSET_FUNCTION:	.space	4
 | 
		
	
		
			
			|  | 858 | +PHC_OFFSET_END:
 | 
		
	
		
			
			|  | 859 | +	.previous
 | 
		
	
		
			
			|  | 860 | +
 | 
		
	
		
			
			|  | 861 | +	.section ".text.phys_call", "ax", @progbits
 | 
		
	
		
			
			|  | 862 | +	.code32
 | 
		
	
		
			
			|  | 863 | +	.globl phys_call
 | 
		
	
		
			
			|  | 864 | +phys_call:
 | 
		
	
		
			
			|  | 865 | +	/* Adjust function pointer to a physical address */
 | 
		
	
		
			
			|  | 866 | +	pushl	%ebp
 | 
		
	
		
			
			|  | 867 | +	movl	VIRTUAL(virt_offset), %ebp
 | 
		
	
		
			
			|  | 868 | +	addl	%ebp, ( PHC_OFFSET_FUNCTION + 4 /* saved %ebp */ )(%esp)
 | 
		
	
		
			
			|  | 869 | +	popl	%ebp
 | 
		
	
		
			
			|  | 870 | +
 | 
		
	
		
			
			|  | 871 | +	/* Switch to physical addresses */
 | 
		
	
		
			
			|  | 872 | +	call	prot_to_phys
 | 
		
	
		
			
			|  | 873 | +
 | 
		
	
		
			
			|  | 874 | +	/* Call function */
 | 
		
	
		
			
			|  | 875 | +	call	*PHC_OFFSET_FUNCTION(%esp)
 | 
		
	
		
			
			|  | 876 | +
 | 
		
	
		
			
			|  | 877 | +	/* For sanity's sake, clear the direction flag as soon as possible */
 | 
		
	
		
			
			|  | 878 | +	cld
 | 
		
	
		
			
			|  | 879 | +
 | 
		
	
		
			
			|  | 880 | +	/* Switch to virtual addresses */
 | 
		
	
		
			
			|  | 881 | +	call	phys_to_prot
 | 
		
	
		
			
			|  | 882 | +
 | 
		
	
		
			
			|  | 883 | +	/* Return and discard function parameters */
 | 
		
	
		
			
			|  | 884 | +	ret	$( PHC_OFFSET_END - PHC_OFFSET_PARAMS )
 | 
		
	
		
			
			|  | 885 | +
 | 
		
	
		
			
			| 687 | 886 |  /****************************************************************************
 | 
		
	
		
			
			| 688 | 887 |   * flatten_real_mode (real-mode near call)
 | 
		
	
		
			
			| 689 | 888 |   *
 | 
		
	
	
		
			
			|  | @@ -733,7 +932,7 @@ interrupt_wrapper:
 | 
		
	
		
			
			| 733 | 932 |  	pushl	%esp
 | 
		
	
		
			
			| 734 | 933 |  
 | 
		
	
		
			
			| 735 | 934 |  	/* Switch to virtual addressing */
 | 
		
	
		
			
			| 736 |  | -	call	_intr_to_virt
 | 
		
	
		
			
			|  | 935 | +	call	intr_to_prot
 | 
		
	
		
			
			| 737 | 936 |  
 | 
		
	
		
			
			| 738 | 937 |  	/* Expand IRQ number to whole %eax register */
 | 
		
	
		
			
			| 739 | 938 |  	movzbl	%al, %eax
 |