Browse Source

[vesafb] Return meaningful error when no suitable mode is found

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 11 years ago
parent
commit
00bb19257f
1 changed files with 75 additions and 44 deletions
  1. 75
    44
      src/arch/i386/interface/pcbios/vesafb.c

+ 75
- 44
src/arch/i386/interface/pcbios/vesafb.c View File

70
 struct vesafb {
70
 struct vesafb {
71
 	/** Frame buffer console */
71
 	/** Frame buffer console */
72
 	struct fbcon fbcon;
72
 	struct fbcon fbcon;
73
+	/** Physical start address */
74
+	physaddr_t start;
73
 	/** Pixel geometry */
75
 	/** Pixel geometry */
74
 	struct fbcon_geometry pixel;
76
 	struct fbcon_geometry pixel;
75
 	/** Colour mapping */
77
 	/** Colour mapping */
76
 	struct fbcon_colour_map map;
78
 	struct fbcon_colour_map map;
77
 	/** Font definition */
79
 	/** Font definition */
78
 	struct fbcon_font font;
80
 	struct fbcon_font font;
79
-	/** Total length */
80
-	size_t len;
81
 	/** Saved VGA mode */
81
 	/** Saved VGA mode */
82
 	uint8_t saved_mode;
82
 	uint8_t saved_mode;
83
 };
83
 };
215
  *
215
  *
216
  * @v mode_number	Mode number
216
  * @v mode_number	Mode number
217
  * @v mode		Mode information
217
  * @v mode		Mode information
218
- * @v pixbuf		Background picture (if any)
219
  * @ret rc		Return status code
218
  * @ret rc		Return status code
220
  */
219
  */
221
 static int vesafb_set_mode ( unsigned int mode_number,
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
 	uint16_t status;
222
 	uint16_t status;
225
 	int rc;
223
 	int rc;
226
 
224
 
236
 	}
234
 	}
237
 
235
 
238
 	/* Record mode parameters */
236
 	/* Record mode parameters */
237
+	vesafb.start = mode->phys_base_ptr;
239
 	vesafb.pixel.width = mode->x_resolution;
238
 	vesafb.pixel.width = mode->x_resolution;
240
 	vesafb.pixel.height = mode->y_resolution;
239
 	vesafb.pixel.height = mode->y_resolution;
241
 	vesafb.pixel.len = ( ( mode->bits_per_pixel + 7 ) / 8 );
240
 	vesafb.pixel.len = ( ( mode->bits_per_pixel + 7 ) / 8 );
251
 	vesafb.map.green_lsb = mode->green_field_position;
250
 	vesafb.map.green_lsb = mode->green_field_position;
252
 	vesafb.map.blue_lsb = mode->blue_field_position;
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
 	return 0;
253
 	return 0;
262
 }
254
 }
263
 
255
 
264
 /**
256
 /**
265
  * Select and set video mode
257
  * Select and set video mode
266
  *
258
  *
259
+ * @v mode_numbers	Mode number list (terminated with VBE_MODE_END)
267
  * @v min_width		Minimum required width (in pixels)
260
  * @v min_width		Minimum required width (in pixels)
268
  * @v min_height	Minimum required height (in pixels)
261
  * @v min_height	Minimum required height (in pixels)
269
  * @v min_bpp		Minimum required colour depth (in bits per pixel)
262
  * @v min_bpp		Minimum required colour depth (in bits per pixel)
270
- * @v pixbuf		Background picture (if any)
271
  * @ret rc		Return status code
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
 	struct vbe_mode_info *mode = &vbe_buf.mode;
268
 	struct vbe_mode_info *mode = &vbe_buf.mode;
277
-	uint16_t *mode_numbers;
278
 	uint16_t mode_number;
269
 	uint16_t mode_number;
279
 	uint16_t status;
270
 	uint16_t status;
280
 	int rc;
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
 	/* Find the first suitable mode */
273
 	/* Find the first suitable mode */
287
 	while ( ( mode_number = *(mode_numbers++) ) != VBE_MODE_END ) {
274
 	while ( ( mode_number = *(mode_numbers++) ) != VBE_MODE_END ) {
288
 
275
 
339
 		}
326
 		}
340
 
327
 
341
 		/* Select this mode */
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
 	free ( mode_numbers );
377
 	free ( mode_numbers );
352
  err_mode_list:
378
  err_mode_list:
353
 	return rc;
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
  * Print a character to current cursor position
401
  * Print a character to current cursor position
358
  *
402
  *
370
  * @ret rc		Return status code
414
  * @ret rc		Return status code
371
  */
415
  */
372
 static int vesafb_configure ( struct console_configuration *config ) {
416
 static int vesafb_configure ( struct console_configuration *config ) {
373
-	uint32_t discard_a;
374
-	uint32_t discard_b;
375
 	int rc;
417
 	int rc;
376
 
418
 
377
 	/* Reset console, if applicable */
419
 	/* Reset console, if applicable */
378
 	if ( ! vesafb_console.disabled ) {
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
 		bios_console.disabled &= ~CONSOLE_DISABLED_OUTPUT;
422
 		bios_console.disabled &= ~CONSOLE_DISABLED_OUTPUT;
387
 	}
423
 	}
388
 	vesafb_console.disabled = CONSOLE_DISABLED;
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
 	/* Do nothing more unless we have a usable configuration */
426
 	/* Do nothing more unless we have a usable configuration */
396
 	if ( ( config == NULL ) ||
427
 	if ( ( config == NULL ) ||
397
 	     ( config->width == 0 ) || ( config->height == 0 ) ) {
428
 	     ( config->width == 0 ) || ( config->height == 0 ) ) {
398
 		return 0;
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
 		return rc;
435
 		return rc;
405
 
436
 
406
 	/* Mark console as enabled */
437
 	/* Mark console as enabled */

Loading…
Cancel
Save