Przeglądaj źródła

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

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 10 lat temu
rodzic
commit
00bb19257f
1 zmienionych plików z 75 dodań i 44 usunięć
  1. 75
    44
      src/arch/i386/interface/pcbios/vesafb.c

+ 75
- 44
src/arch/i386/interface/pcbios/vesafb.c Wyświetl plik

@@ -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 */

Ładowanie…
Anuluj
Zapisz