Use .code16gcc to compile arch/x86/boot/bioscall.S rather than .code16, since some older versions of binutils can't generate 32-bit addressing expressions (67 prefixes) in .code16 mode, only in .code16gcc mode. Reported-by: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
		
			
				
	
	
		
			82 lines
		
	
	
	
		
			1.5 KiB
			
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			82 lines
		
	
	
	
		
			1.5 KiB
			
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
/* -----------------------------------------------------------------------
 | 
						|
 *
 | 
						|
 *   Copyright 2009 Intel Corporation; author H. Peter Anvin
 | 
						|
 *
 | 
						|
 *   This file is part of the Linux kernel, and is made available under
 | 
						|
 *   the terms of the GNU General Public License version 2 or (at your
 | 
						|
 *   option) any later version; incorporated herein by reference.
 | 
						|
 *
 | 
						|
 * ----------------------------------------------------------------------- */
 | 
						|
 | 
						|
/*
 | 
						|
 * "Glove box" for BIOS calls.  Avoids the constant problems with BIOSes
 | 
						|
 * touching registers they shouldn't be.
 | 
						|
 */
 | 
						|
 | 
						|
	.code16gcc
 | 
						|
	.text
 | 
						|
	.globl	intcall
 | 
						|
	.type	intcall, @function
 | 
						|
intcall:
 | 
						|
	/* Self-modify the INT instruction.  Ugly, but works. */
 | 
						|
	cmpb	%al, 3f
 | 
						|
	je	1f
 | 
						|
	movb	%al, 3f
 | 
						|
	jmp	1f		/* Synchronize pipeline */
 | 
						|
1:
 | 
						|
	/* Save state */
 | 
						|
	pushfl
 | 
						|
	pushw	%fs
 | 
						|
	pushw	%gs
 | 
						|
	pushal
 | 
						|
 | 
						|
	/* Copy input state to stack frame */
 | 
						|
	subw	$44, %sp
 | 
						|
	movw	%dx, %si
 | 
						|
	movw	%sp, %di
 | 
						|
	movw	$11, %cx
 | 
						|
	rep; movsd
 | 
						|
 | 
						|
	/* Pop full state from the stack */
 | 
						|
	popal
 | 
						|
	popw	%gs
 | 
						|
	popw	%fs
 | 
						|
	popw	%es
 | 
						|
	popw	%ds
 | 
						|
	popfl
 | 
						|
 | 
						|
	/* Actual INT */
 | 
						|
	.byte	0xcd		/* INT opcode */
 | 
						|
3:	.byte	0
 | 
						|
 | 
						|
	/* Push full state to the stack */
 | 
						|
	pushfl
 | 
						|
	pushw	%ds
 | 
						|
	pushw	%es
 | 
						|
	pushw	%fs
 | 
						|
	pushw	%gs
 | 
						|
	pushal
 | 
						|
 | 
						|
	/* Re-establish C environment invariants */
 | 
						|
	cld
 | 
						|
	movzwl	%sp, %esp
 | 
						|
	movw	%cs, %ax
 | 
						|
	movw	%ax, %ds
 | 
						|
	movw	%ax, %es
 | 
						|
 | 
						|
	/* Copy output state from stack frame */
 | 
						|
	movw	68(%esp), %di	/* Original %cx == 3rd argument */
 | 
						|
	andw	%di, %di
 | 
						|
	jz	4f
 | 
						|
	movw	%sp, %si
 | 
						|
	movw	$11, %cx
 | 
						|
	rep; movsd
 | 
						|
4:	addw	$44, %sp
 | 
						|
 | 
						|
	/* Restore state and return */
 | 
						|
	popal
 | 
						|
	popw	%gs
 | 
						|
	popw	%fs
 | 
						|
	popfl
 | 
						|
	retl
 | 
						|
	.size	intcall, .-intcall
 |