|  | @@ -70,14 +70,14 @@ struct console_driver vesafb_console __console_driver;
 | 
		
	
		
			
			| 70 | 70 |  struct vesafb {
 | 
		
	
		
			
			| 71 | 71 |  	/** Frame buffer console */
 | 
		
	
		
			
			| 72 | 72 |  	struct fbcon fbcon;
 | 
		
	
		
			
			|  | 73 | +	/** Physical start address */
 | 
		
	
		
			
			|  | 74 | +	physaddr_t start;
 | 
		
	
		
			
			| 73 | 75 |  	/** Pixel geometry */
 | 
		
	
		
			
			| 74 | 76 |  	struct fbcon_geometry pixel;
 | 
		
	
		
			
			| 75 | 77 |  	/** Colour mapping */
 | 
		
	
		
			
			| 76 | 78 |  	struct fbcon_colour_map map;
 | 
		
	
		
			
			| 77 | 79 |  	/** Font definition */
 | 
		
	
		
			
			| 78 | 80 |  	struct fbcon_font font;
 | 
		
	
		
			
			| 79 |  | -	/** Total length */
 | 
		
	
		
			
			| 80 |  | -	size_t len;
 | 
		
	
		
			
			| 81 | 81 |  	/** Saved VGA mode */
 | 
		
	
		
			
			| 82 | 82 |  	uint8_t saved_mode;
 | 
		
	
		
			
			| 83 | 83 |  };
 | 
		
	
	
		
			
			|  | @@ -215,12 +215,10 @@ static int vesafb_mode_list ( uint16_t **mode_numbers ) {
 | 
		
	
		
			
			| 215 | 215 |   *
 | 
		
	
		
			
			| 216 | 216 |   * @v mode_number	Mode number
 | 
		
	
		
			
			| 217 | 217 |   * @v mode		Mode information
 | 
		
	
		
			
			| 218 |  | - * @v pixbuf		Background picture (if any)
 | 
		
	
		
			
			| 219 | 218 |   * @ret rc		Return status code
 | 
		
	
		
			
			| 220 | 219 |   */
 | 
		
	
		
			
			| 221 | 220 |  static int vesafb_set_mode ( unsigned int mode_number,
 | 
		
	
		
			
			| 222 |  | -			     struct vbe_mode_info *mode,
 | 
		
	
		
			
			| 223 |  | -			     struct pixel_buffer *pixbuf ) {
 | 
		
	
		
			
			|  | 221 | +			     struct vbe_mode_info *mode ) {
 | 
		
	
		
			
			| 224 | 222 |  	uint16_t status;
 | 
		
	
		
			
			| 225 | 223 |  	int rc;
 | 
		
	
		
			
			| 226 | 224 |  
 | 
		
	
	
		
			
			|  | @@ -236,6 +234,7 @@ static int vesafb_set_mode ( unsigned int mode_number,
 | 
		
	
		
			
			| 236 | 234 |  	}
 | 
		
	
		
			
			| 237 | 235 |  
 | 
		
	
		
			
			| 238 | 236 |  	/* Record mode parameters */
 | 
		
	
		
			
			|  | 237 | +	vesafb.start = mode->phys_base_ptr;
 | 
		
	
		
			
			| 239 | 238 |  	vesafb.pixel.width = mode->x_resolution;
 | 
		
	
		
			
			| 240 | 239 |  	vesafb.pixel.height = mode->y_resolution;
 | 
		
	
		
			
			| 241 | 240 |  	vesafb.pixel.len = ( ( mode->bits_per_pixel + 7 ) / 8 );
 | 
		
	
	
		
			
			|  | @@ -251,38 +250,26 @@ static int vesafb_set_mode ( unsigned int mode_number,
 | 
		
	
		
			
			| 251 | 250 |  	vesafb.map.green_lsb = mode->green_field_position;
 | 
		
	
		
			
			| 252 | 251 |  	vesafb.map.blue_lsb = mode->blue_field_position;
 | 
		
	
		
			
			| 253 | 252 |  
 | 
		
	
		
			
			| 254 |  | -	/* Get font data */
 | 
		
	
		
			
			| 255 |  | -	vesafb_font();
 | 
		
	
		
			
			| 256 |  | -
 | 
		
	
		
			
			| 257 |  | -	/* Initialise frame buffer console */
 | 
		
	
		
			
			| 258 |  | -	fbcon_init ( &vesafb.fbcon, phys_to_user ( mode->phys_base_ptr ),
 | 
		
	
		
			
			| 259 |  | -		     &vesafb.pixel, &vesafb.map, &vesafb.font, pixbuf );
 | 
		
	
		
			
			| 260 |  | -
 | 
		
	
		
			
			| 261 | 253 |  	return 0;
 | 
		
	
		
			
			| 262 | 254 |  }
 | 
		
	
		
			
			| 263 | 255 |  
 | 
		
	
		
			
			| 264 | 256 |  /**
 | 
		
	
		
			
			| 265 | 257 |   * Select and set video mode
 | 
		
	
		
			
			| 266 | 258 |   *
 | 
		
	
		
			
			|  | 259 | + * @v mode_numbers	Mode number list (terminated with VBE_MODE_END)
 | 
		
	
		
			
			| 267 | 260 |   * @v min_width		Minimum required width (in pixels)
 | 
		
	
		
			
			| 268 | 261 |   * @v min_height	Minimum required height (in pixels)
 | 
		
	
		
			
			| 269 | 262 |   * @v min_bpp		Minimum required colour depth (in bits per pixel)
 | 
		
	
		
			
			| 270 |  | - * @v pixbuf		Background picture (if any)
 | 
		
	
		
			
			| 271 | 263 |   * @ret rc		Return status code
 | 
		
	
		
			
			| 272 | 264 |   */
 | 
		
	
		
			
			| 273 |  | -static int vesafb_select_mode ( unsigned int min_width, unsigned int min_height,
 | 
		
	
		
			
			| 274 |  | -				unsigned int min_bpp,
 | 
		
	
		
			
			| 275 |  | -				struct pixel_buffer *pixbuf ) {
 | 
		
	
		
			
			|  | 265 | +static int vesafb_select_mode ( const uint16_t *mode_numbers,
 | 
		
	
		
			
			|  | 266 | +				unsigned int min_width, unsigned int min_height,
 | 
		
	
		
			
			|  | 267 | +				unsigned int min_bpp ) {
 | 
		
	
		
			
			| 276 | 268 |  	struct vbe_mode_info *mode = &vbe_buf.mode;
 | 
		
	
		
			
			| 277 |  | -	uint16_t *mode_numbers;
 | 
		
	
		
			
			| 278 | 269 |  	uint16_t mode_number;
 | 
		
	
		
			
			| 279 | 270 |  	uint16_t status;
 | 
		
	
		
			
			| 280 | 271 |  	int rc;
 | 
		
	
		
			
			| 281 | 272 |  
 | 
		
	
		
			
			| 282 |  | -	/* Get VESA mode list */
 | 
		
	
		
			
			| 283 |  | -	if ( ( rc = vesafb_mode_list ( &mode_numbers ) ) != 0 )
 | 
		
	
		
			
			| 284 |  | -		goto err_mode_list;
 | 
		
	
		
			
			| 285 |  | -
 | 
		
	
		
			
			| 286 | 273 |  	/* Find the first suitable mode */
 | 
		
	
		
			
			| 287 | 274 |  	while ( ( mode_number = *(mode_numbers++) ) != VBE_MODE_END ) {
 | 
		
	
		
			
			| 288 | 275 |  
 | 
		
	
	
		
			
			|  | @@ -339,20 +326,77 @@ static int vesafb_select_mode ( unsigned int min_width, unsigned int min_height,
 | 
		
	
		
			
			| 339 | 326 |  		}
 | 
		
	
		
			
			| 340 | 327 |  
 | 
		
	
		
			
			| 341 | 328 |  		/* Select this mode */
 | 
		
	
		
			
			| 342 |  | -		if ( ( rc = vesafb_set_mode ( mode_number, mode,
 | 
		
	
		
			
			| 343 |  | -					      pixbuf ) ) != 0 ) {
 | 
		
	
		
			
			| 344 |  | -			goto err_set_mode;
 | 
		
	
		
			
			| 345 |  | -		}
 | 
		
	
		
			
			|  | 329 | +		if ( ( rc = vesafb_set_mode ( mode_number, mode ) ) != 0 )
 | 
		
	
		
			
			|  | 330 | +			return rc;
 | 
		
	
		
			
			| 346 | 331 |  
 | 
		
	
		
			
			| 347 |  | -		break;
 | 
		
	
		
			
			|  | 332 | +		return 0;
 | 
		
	
		
			
			| 348 | 333 |  	}
 | 
		
	
		
			
			| 349 | 334 |  
 | 
		
	
		
			
			| 350 |  | - err_set_mode:
 | 
		
	
		
			
			|  | 335 | +	DBGC ( &vbe_buf, "VESAFB found no suitable mode\n" );
 | 
		
	
		
			
			|  | 336 | +	return -ENOENT;
 | 
		
	
		
			
			|  | 337 | +}
 | 
		
	
		
			
			|  | 338 | +
 | 
		
	
		
			
			|  | 339 | +/**
 | 
		
	
		
			
			|  | 340 | + * Initialise VESA frame buffer
 | 
		
	
		
			
			|  | 341 | + *
 | 
		
	
		
			
			|  | 342 | + * @v min_width		Minimum required width (in pixels)
 | 
		
	
		
			
			|  | 343 | + * @v min_height	Minimum required height (in pixels)
 | 
		
	
		
			
			|  | 344 | + * @v min_bpp		Minimum required colour depth (in bits per pixel)
 | 
		
	
		
			
			|  | 345 | + * @v pixbuf		Background picture (if any)
 | 
		
	
		
			
			|  | 346 | + * @ret rc		Return status code
 | 
		
	
		
			
			|  | 347 | + */
 | 
		
	
		
			
			|  | 348 | +static int vesafb_init ( unsigned int min_width, unsigned int min_height,
 | 
		
	
		
			
			|  | 349 | +			 unsigned int min_bpp, struct pixel_buffer *pixbuf ) {
 | 
		
	
		
			
			|  | 350 | +	uint32_t discard_b;
 | 
		
	
		
			
			|  | 351 | +	uint16_t *mode_numbers;
 | 
		
	
		
			
			|  | 352 | +	int rc;
 | 
		
	
		
			
			|  | 353 | +
 | 
		
	
		
			
			|  | 354 | +	/* Record current VGA mode */
 | 
		
	
		
			
			|  | 355 | +	__asm__ __volatile__ ( REAL_CODE ( "int $0x10" )
 | 
		
	
		
			
			|  | 356 | +			       : "=a" ( vesafb.saved_mode ), "=b" ( discard_b )
 | 
		
	
		
			
			|  | 357 | +			       : "a" ( VBE_GET_VGA_MODE ) );
 | 
		
	
		
			
			|  | 358 | +	DBGC ( &vbe_buf, "VESAFB saved VGA mode %#02x\n", vesafb.saved_mode );
 | 
		
	
		
			
			|  | 359 | +
 | 
		
	
		
			
			|  | 360 | +	/* Get VESA mode list */
 | 
		
	
		
			
			|  | 361 | +	if ( ( rc = vesafb_mode_list ( &mode_numbers ) ) != 0 )
 | 
		
	
		
			
			|  | 362 | +		goto err_mode_list;
 | 
		
	
		
			
			|  | 363 | +
 | 
		
	
		
			
			|  | 364 | +	/* Select and set mode */
 | 
		
	
		
			
			|  | 365 | +	if ( ( rc = vesafb_select_mode ( mode_numbers, min_width, min_height,
 | 
		
	
		
			
			|  | 366 | +					 min_bpp ) ) != 0 )
 | 
		
	
		
			
			|  | 367 | +		goto err_select_mode;
 | 
		
	
		
			
			|  | 368 | +
 | 
		
	
		
			
			|  | 369 | +	/* Get font data */
 | 
		
	
		
			
			|  | 370 | +	vesafb_font();
 | 
		
	
		
			
			|  | 371 | +
 | 
		
	
		
			
			|  | 372 | +	/* Initialise frame buffer console */
 | 
		
	
		
			
			|  | 373 | +	fbcon_init ( &vesafb.fbcon, phys_to_user ( vesafb.start ),
 | 
		
	
		
			
			|  | 374 | +		     &vesafb.pixel, &vesafb.map, &vesafb.font, pixbuf );
 | 
		
	
		
			
			|  | 375 | +
 | 
		
	
		
			
			|  | 376 | + err_select_mode:
 | 
		
	
		
			
			| 351 | 377 |  	free ( mode_numbers );
 | 
		
	
		
			
			| 352 | 378 |   err_mode_list:
 | 
		
	
		
			
			| 353 | 379 |  	return rc;
 | 
		
	
		
			
			| 354 | 380 |  }
 | 
		
	
		
			
			| 355 | 381 |  
 | 
		
	
		
			
			|  | 382 | +/**
 | 
		
	
		
			
			|  | 383 | + * Finalise VESA frame buffer
 | 
		
	
		
			
			|  | 384 | + *
 | 
		
	
		
			
			|  | 385 | + */
 | 
		
	
		
			
			|  | 386 | +static void vesafb_fini ( void ) {
 | 
		
	
		
			
			|  | 387 | +	uint32_t discard_a;
 | 
		
	
		
			
			|  | 388 | +
 | 
		
	
		
			
			|  | 389 | +	/* Finalise frame buffer console */
 | 
		
	
		
			
			|  | 390 | +	fbcon_fini ( &vesafb.fbcon );
 | 
		
	
		
			
			|  | 391 | +
 | 
		
	
		
			
			|  | 392 | +	/* Restore VGA mode */
 | 
		
	
		
			
			|  | 393 | +	__asm__ __volatile__ ( REAL_CODE ( "int $0x10" )
 | 
		
	
		
			
			|  | 394 | +			       : "=a" ( discard_a )
 | 
		
	
		
			
			|  | 395 | +			       : "a" ( VBE_SET_VGA_MODE | vesafb.saved_mode ) );
 | 
		
	
		
			
			|  | 396 | +	DBGC ( &vbe_buf, "VESAFB restored VGA mode %#02x\n",
 | 
		
	
		
			
			|  | 397 | +	       vesafb.saved_mode );
 | 
		
	
		
			
			|  | 398 | +}
 | 
		
	
		
			
			|  | 399 | +
 | 
		
	
		
			
			| 356 | 400 |  /**
 | 
		
	
		
			
			| 357 | 401 |   * Print a character to current cursor position
 | 
		
	
		
			
			| 358 | 402 |   *
 | 
		
	
	
		
			
			|  | @@ -370,37 +414,24 @@ static void vesafb_putchar ( int character ) {
 | 
		
	
		
			
			| 370 | 414 |   * @ret rc		Return status code
 | 
		
	
		
			
			| 371 | 415 |   */
 | 
		
	
		
			
			| 372 | 416 |  static int vesafb_configure ( struct console_configuration *config ) {
 | 
		
	
		
			
			| 373 |  | -	uint32_t discard_a;
 | 
		
	
		
			
			| 374 |  | -	uint32_t discard_b;
 | 
		
	
		
			
			| 375 | 417 |  	int rc;
 | 
		
	
		
			
			| 376 | 418 |  
 | 
		
	
		
			
			| 377 | 419 |  	/* Reset console, if applicable */
 | 
		
	
		
			
			| 378 | 420 |  	if ( ! vesafb_console.disabled ) {
 | 
		
	
		
			
			| 379 |  | -		fbcon_fini ( &vesafb.fbcon );
 | 
		
	
		
			
			| 380 |  | -		__asm__ __volatile__ ( REAL_CODE ( "int $0x10" )
 | 
		
	
		
			
			| 381 |  | -				       : "=a" ( discard_a )
 | 
		
	
		
			
			| 382 |  | -				       : "a" ( VBE_SET_VGA_MODE |
 | 
		
	
		
			
			| 383 |  | -					       vesafb.saved_mode ) );
 | 
		
	
		
			
			| 384 |  | -		DBGC ( &vbe_buf, "VESAFB restored VGA mode %#02x\n",
 | 
		
	
		
			
			| 385 |  | -		       vesafb.saved_mode );
 | 
		
	
		
			
			|  | 421 | +		vesafb_fini();
 | 
		
	
		
			
			| 386 | 422 |  		bios_console.disabled &= ~CONSOLE_DISABLED_OUTPUT;
 | 
		
	
		
			
			| 387 | 423 |  	}
 | 
		
	
		
			
			| 388 | 424 |  	vesafb_console.disabled = CONSOLE_DISABLED;
 | 
		
	
		
			
			| 389 | 425 |  
 | 
		
	
		
			
			| 390 |  | -	/* Record current video mode */
 | 
		
	
		
			
			| 391 |  | -	__asm__ __volatile__ ( REAL_CODE ( "int $0x10" )
 | 
		
	
		
			
			| 392 |  | -			       : "=a" ( vesafb.saved_mode ), "=b" ( discard_b )
 | 
		
	
		
			
			| 393 |  | -			       : "a" ( VBE_GET_VGA_MODE ) );
 | 
		
	
		
			
			| 394 |  | -
 | 
		
	
		
			
			| 395 | 426 |  	/* Do nothing more unless we have a usable configuration */
 | 
		
	
		
			
			| 396 | 427 |  	if ( ( config == NULL ) ||
 | 
		
	
		
			
			| 397 | 428 |  	     ( config->width == 0 ) || ( config->height == 0 ) ) {
 | 
		
	
		
			
			| 398 | 429 |  		return 0;
 | 
		
	
		
			
			| 399 | 430 |  	}
 | 
		
	
		
			
			| 400 | 431 |  
 | 
		
	
		
			
			| 401 |  | -	/* Try to select an appropriate mode */
 | 
		
	
		
			
			| 402 |  | -	if ( ( rc = vesafb_select_mode ( config->width, config->height,
 | 
		
	
		
			
			| 403 |  | -					 config->bpp, config->pixbuf ) ) != 0 )
 | 
		
	
		
			
			|  | 432 | +	/* Initialise VESA frame buffer */
 | 
		
	
		
			
			|  | 433 | +	if ( ( rc = vesafb_init ( config->width, config->height, config->bpp,
 | 
		
	
		
			
			|  | 434 | +				  config->pixbuf ) ) != 0 )
 | 
		
	
		
			
			| 404 | 435 |  		return rc;
 | 
		
	
		
			
			| 405 | 436 |  
 | 
		
	
		
			
			| 406 | 437 |  	/* Mark console as enabled */
 |