diff options
Diffstat (limited to 'arch/x86/boot/video-vesa.c')
| -rw-r--r-- | arch/x86/boot/video-vesa.c | 137 | 
1 files changed, 60 insertions, 77 deletions
diff --git a/arch/x86/boot/video-vesa.c b/arch/x86/boot/video-vesa.c index 4a58c8ce3f6..c700147d6ff 100644 --- a/arch/x86/boot/video-vesa.c +++ b/arch/x86/boot/video-vesa.c @@ -2,6 +2,7 @@   *   *   Copyright (C) 1991, 1992 Linus Torvalds   *   Copyright 2007 rPath, Inc. - All Rights Reserved + *   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. @@ -31,7 +32,7 @@ static inline void vesa_store_mode_params_graphics(void) {}  static int vesa_probe(void)  {  #if defined(CONFIG_VIDEO_VESA) || defined(CONFIG_FIRMWARE_EDID) -	u16 ax, cx, di; +	struct biosregs ireg, oreg;  	u16 mode;  	addr_t mode_ptr;  	struct mode_info *mi; @@ -39,13 +40,12 @@ static int vesa_probe(void)  	video_vesa.modes = GET_HEAP(struct mode_info, 0); -	ax = 0x4f00; -	di = (size_t)&vginfo; -	asm(INT10 -	    : "+a" (ax), "+D" (di), "=m" (vginfo) -	    : : "ebx", "ecx", "edx", "esi"); +	initregs(&ireg); +	ireg.ax = 0x4f00; +	ireg.di = (size_t)&vginfo; +	intcall(0x10, &ireg, &oreg); -	if (ax != 0x004f || +	if (ireg.ax != 0x004f ||  	    vginfo.signature != VESA_MAGIC ||  	    vginfo.version < 0x0102)  		return 0;	/* Not present */ @@ -65,14 +65,12 @@ static int vesa_probe(void)  		memset(&vminfo, 0, sizeof vminfo); /* Just in case... */ -		ax = 0x4f01; -		cx = mode; -		di = (size_t)&vminfo; -		asm(INT10 -		    : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo) -		    : : "ebx", "edx", "esi"); +		ireg.ax = 0x4f01; +		ireg.cx = mode; +		ireg.di = (size_t)&vminfo; +		intcall(0x10, &ireg, &oreg); -		if (ax != 0x004f) +		if (ireg.ax != 0x004f)  			continue;  		if ((vminfo.mode_attr & 0x15) == 0x05) { @@ -111,20 +109,19 @@ static int vesa_probe(void)  static int vesa_set_mode(struct mode_info *mode)  { -	u16 ax, bx, cx, di; +	struct biosregs ireg, oreg;  	int is_graphic;  	u16 vesa_mode = mode->mode - VIDEO_FIRST_VESA;  	memset(&vminfo, 0, sizeof vminfo); /* Just in case... */ -	ax = 0x4f01; -	cx = vesa_mode; -	di = (size_t)&vminfo; -	asm(INT10 -	    : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo) -	    : : "ebx", "edx", "esi"); +	initregs(&ireg); +	ireg.ax = 0x4f01; +	ireg.cx = vesa_mode; +	ireg.di = (size_t)&vminfo; +	intcall(0x10, &ireg, &oreg); -	if (ax != 0x004f) +	if (oreg.ax != 0x004f)  		return -1;  	if ((vminfo.mode_attr & 0x15) == 0x05) { @@ -141,14 +138,12 @@ static int vesa_set_mode(struct mode_info *mode)  	} -	ax = 0x4f02; -	bx = vesa_mode; -	di = 0; -	asm volatile(INT10 -		     : "+a" (ax), "+b" (bx), "+D" (di) -		     : : "ecx", "edx", "esi"); +	initregs(&ireg); +	ireg.ax = 0x4f02; +	ireg.bx = vesa_mode; +	intcall(0x10, &ireg, &oreg); -	if (ax != 0x004f) +	if (oreg.ax != 0x004f)  		return -1;  	graphic_mode = is_graphic; @@ -171,50 +166,45 @@ static int vesa_set_mode(struct mode_info *mode)  /* Switch DAC to 8-bit mode */  static void vesa_dac_set_8bits(void)  { +	struct biosregs ireg, oreg;  	u8 dac_size = 6;  	/* If possible, switch the DAC to 8-bit mode */  	if (vginfo.capabilities & 1) { -		u16 ax, bx; - -		ax = 0x4f08; -		bx = 0x0800; -		asm volatile(INT10 -			     : "+a" (ax), "+b" (bx) -			     : : "ecx", "edx", "esi", "edi"); - -		if (ax == 0x004f) -			dac_size = bx >> 8; +		initregs(&ireg); +		ireg.ax = 0x4f08; +		ireg.bh = 0x08; +		intcall(0x10, &ireg, &oreg); +		if (oreg.ax == 0x004f) +			dac_size = oreg.bh;  	}  	/* Set the color sizes to the DAC size, and offsets to 0 */ -	boot_params.screen_info.red_size = dac_size; +	boot_params.screen_info.red_size   = dac_size;  	boot_params.screen_info.green_size = dac_size; -	boot_params.screen_info.blue_size = dac_size; -	boot_params.screen_info.rsvd_size = dac_size; +	boot_params.screen_info.blue_size  = dac_size; +	boot_params.screen_info.rsvd_size  = dac_size; -	boot_params.screen_info.red_pos = 0; -	boot_params.screen_info.green_pos = 0; -	boot_params.screen_info.blue_pos = 0; -	boot_params.screen_info.rsvd_pos = 0; +	boot_params.screen_info.red_pos    = 0; +	boot_params.screen_info.green_pos  = 0; +	boot_params.screen_info.blue_pos   = 0; +	boot_params.screen_info.rsvd_pos   = 0;  }  /* Save the VESA protected mode info */  static void vesa_store_pm_info(void)  { -	u16 ax, bx, di, es; +	struct biosregs ireg, oreg; -	ax = 0x4f0a; -	bx = di = 0; -	asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es" -	    : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di) -	    : : "ecx", "esi"); +	initregs(&ireg); +	ireg.ax = 0x4f0a; +	intcall(0x10, &ireg, &oreg); -	if (ax != 0x004f) +	if (oreg.ax != 0x004f)  		return; -	boot_params.screen_info.vesapm_seg = es; -	boot_params.screen_info.vesapm_off = di; +	boot_params.screen_info.vesapm_seg = oreg.es; +	boot_params.screen_info.vesapm_off = oreg.di;  }  /* @@ -252,7 +242,7 @@ static void vesa_store_mode_params_graphics(void)  void vesa_store_edid(void)  {  #ifdef CONFIG_FIRMWARE_EDID -	u16 ax, bx, cx, dx, di; +	struct biosregs ireg, oreg;  	/* Apparently used as a nonsense token... */  	memset(&boot_params.edid_info, 0x13, sizeof boot_params.edid_info); @@ -260,33 +250,26 @@ void vesa_store_edid(void)  	if (vginfo.version < 0x0200)  		return;		/* EDID requires VBE 2.0+ */ -	ax = 0x4f15;		/* VBE DDC */ -	bx = 0x0000;		/* Report DDC capabilities */ -	cx = 0;			/* Controller 0 */ -	di = 0;			/* ES:DI must be 0 by spec */ - -	/* Note: The VBE DDC spec is different from the main VESA spec; -	   we genuinely have to assume all registers are destroyed here. */ - -	asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es" -	    : "+a" (ax), "+b" (bx), "+c" (cx), "+D" (di) -	    : : "esi", "edx"); +	initregs(&ireg); +	ireg.ax = 0x4f15;		/* VBE DDC */ +	/* ireg.bx = 0x0000; */		/* Report DDC capabilities */ +	/* ireg.cx = 0;	*/		/* Controller 0 */ +	ireg.es = 0;			/* ES:DI must be 0 by spec */ +	intcall(0x10, &ireg, &oreg); -	if (ax != 0x004f) +	if (oreg.ax != 0x004f)  		return;		/* No EDID */  	/* BH = time in seconds to transfer EDD information */  	/* BL = DDC level supported */ -	ax = 0x4f15;		/* VBE DDC */ -	bx = 0x0001;		/* Read EDID */ -	cx = 0;			/* Controller 0 */ -	dx = 0;			/* EDID block number */ -	di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */ -	asm(INT10 -	    : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info), -	      "+c" (cx), "+D" (di) -	    : : "esi"); +	ireg.ax = 0x4f15;		/* VBE DDC */ +	ireg.bx = 0x0001;		/* Read EDID */ +	/* ireg.cx = 0; */		/* Controller 0 */ +	/* ireg.dx = 0;	*/		/* EDID block number */ +	ireg.es = ds(); +	ireg.di =(size_t)&boot_params.edid_info; /* (ES:)Pointer to block */ +	intcall(0x10, &ireg, &oreg);  #endif /* CONFIG_FIRMWARE_EDID */  }  |