-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Video mode probing support for the new x86 setup code
Video mode probing for the new x86 setup code. This code breaks down different drivers into modules. This code deliberately drops support for a lot of the vendor-specific mode probing present in the assembly version, since a lot of those probes have been found to be stale in current versions of those chips -- frequently, support for those modes have been dropped from recent video BIOSes due to space constraints, but the video BIOS signatures are still the same. However, additional drivers should be extremely straightforward to plug in, if desirable. Signed-off-by: H. Peter Anvin <hpa@zytor.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
- Loading branch information
H. Peter Anvin
authored and
Linus Torvalds
committed
Jul 12, 2007
1 parent
337496e
commit 5e8ddcb
Showing
6 changed files
with
1,349 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
/* ----------------------------------------------------------------------- * | ||
* | ||
* Copyright 1999-2007 H. Peter Anvin - All Rights Reserved | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, Inc., 53 Temple Place Ste 330, | ||
* Boston MA 02111-1307, USA; either version 2 of the License, or | ||
* (at your option) any later version; incorporated herein by reference. | ||
* | ||
* ----------------------------------------------------------------------- */ | ||
|
||
#ifndef BOOT_VESA_H | ||
#define BOOT_VESA_H | ||
|
||
typedef struct { | ||
u16 off, seg; | ||
} far_ptr; | ||
|
||
/* VESA General Information table */ | ||
struct vesa_general_info { | ||
u32 signature; /* 0 Magic number = "VESA" */ | ||
u16 version; /* 4 */ | ||
far_ptr vendor_string; /* 6 */ | ||
u32 capabilities; /* 10 */ | ||
far_ptr video_mode_ptr; /* 14 */ | ||
u16 total_memory; /* 18 */ | ||
|
||
u16 oem_software_rev; /* 20 */ | ||
far_ptr oem_vendor_name_ptr; /* 22 */ | ||
far_ptr oem_product_name_ptr; /* 26 */ | ||
far_ptr oem_product_rev_ptr; /* 30 */ | ||
|
||
u8 reserved[222]; /* 34 */ | ||
u8 oem_data[256]; /* 256 */ | ||
} __attribute__ ((packed)); | ||
|
||
#define VESA_MAGIC ('V' + ('E' << 8) + ('S' << 16) + ('A' << 24)) | ||
#define VBE2_MAGIC ('V' + ('B' << 8) + ('E' << 16) + ('2' << 24)) | ||
|
||
struct vesa_mode_info { | ||
u16 mode_attr; /* 0 */ | ||
u8 win_attr[2]; /* 2 */ | ||
u16 win_grain; /* 4 */ | ||
u16 win_size; /* 6 */ | ||
u16 win_seg[2]; /* 8 */ | ||
far_ptr win_scheme; /* 12 */ | ||
u16 logical_scan; /* 16 */ | ||
|
||
u16 h_res; /* 18 */ | ||
u16 v_res; /* 20 */ | ||
u8 char_width; /* 22 */ | ||
u8 char_height; /* 23 */ | ||
u8 memory_planes; /* 24 */ | ||
u8 bpp; /* 25 */ | ||
u8 banks; /* 26 */ | ||
u8 memory_layout; /* 27 */ | ||
u8 bank_size; /* 28 */ | ||
u8 image_planes; /* 29 */ | ||
u8 page_function; /* 30 */ | ||
|
||
u8 rmask; /* 31 */ | ||
u8 rpos; /* 32 */ | ||
u8 gmask; /* 33 */ | ||
u8 gpos; /* 34 */ | ||
u8 bmask; /* 35 */ | ||
u8 bpos; /* 36 */ | ||
u8 resv_mask; /* 37 */ | ||
u8 resv_pos; /* 38 */ | ||
u8 dcm_info; /* 39 */ | ||
|
||
u32 lfb_ptr; /* 40 Linear frame buffer address */ | ||
u32 offscreen_ptr; /* 44 Offscreen memory address */ | ||
u16 offscreen_size; /* 48 */ | ||
|
||
u8 reserved[206]; /* 50 */ | ||
} __attribute__ ((packed)); | ||
|
||
#endif /* LIB_SYS_VESA_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
/* -*- linux-c -*- ------------------------------------------------------- * | ||
* | ||
* Copyright (C) 1991, 1992 Linus Torvalds | ||
* Copyright 2007 rPath, Inc. - All Rights Reserved | ||
* | ||
* This file is part of the Linux kernel, and is made available under | ||
* the terms of the GNU General Public License version 2. | ||
* | ||
* ----------------------------------------------------------------------- */ | ||
|
||
/* | ||
* arch/i386/boot/video-bios.c | ||
* | ||
* Standard video BIOS modes | ||
* | ||
* We have two options for this; silent and scanned. | ||
*/ | ||
|
||
#include "boot.h" | ||
#include "video.h" | ||
|
||
__videocard video_bios; | ||
|
||
/* Set a conventional BIOS mode */ | ||
static int set_bios_mode(u8 mode); | ||
|
||
static int bios_set_mode(struct mode_info *mi) | ||
{ | ||
return set_bios_mode(mi->mode - VIDEO_FIRST_BIOS); | ||
} | ||
|
||
static int set_bios_mode(u8 mode) | ||
{ | ||
u16 ax; | ||
u8 new_mode; | ||
|
||
ax = mode; /* AH=0x00 Set Video Mode */ | ||
asm volatile(INT10 | ||
: "+a" (ax) | ||
: : "ebx", "ecx", "edx", "esi", "edi"); | ||
|
||
ax = 0x0f00; /* Get Current Video Mode */ | ||
asm volatile(INT10 | ||
: "+a" (ax) | ||
: : "ebx", "ecx", "edx", "esi", "edi"); | ||
|
||
do_restore = 1; /* Assume video contents was lost */ | ||
new_mode = ax & 0x7f; /* Not all BIOSes are clean with the top bit */ | ||
|
||
if (new_mode == mode) | ||
return 0; /* Mode change OK */ | ||
|
||
if (new_mode != boot_params.screen_info.orig_video_mode) { | ||
/* Mode setting failed, but we didn't end up where we | ||
started. That's bad. Try to revert to the original | ||
video mode. */ | ||
ax = boot_params.screen_info.orig_video_mode; | ||
asm volatile(INT10 | ||
: "+a" (ax) | ||
: : "ebx", "ecx", "edx", "esi", "edi"); | ||
} | ||
return -1; | ||
} | ||
|
||
static int bios_probe(void) | ||
{ | ||
u8 mode; | ||
u8 saved_mode = boot_params.screen_info.orig_video_mode; | ||
u16 crtc; | ||
struct mode_info *mi; | ||
int nmodes = 0; | ||
|
||
if (adapter != ADAPTER_EGA && adapter != ADAPTER_VGA) | ||
return 0; | ||
|
||
set_fs(0); | ||
crtc = vga_crtc(); | ||
|
||
video_bios.modes = GET_HEAP(struct mode_info, 0); | ||
|
||
for (mode = 0x14; mode <= 0x7f; mode++) { | ||
if (heap_free() < sizeof(struct mode_info)) | ||
break; | ||
|
||
if (mode_defined(VIDEO_FIRST_BIOS+mode)) | ||
continue; | ||
|
||
if (set_bios_mode(mode)) | ||
continue; | ||
|
||
/* Try to verify that it's a text mode. */ | ||
|
||
/* Attribute Controller: make graphics controller disabled */ | ||
if (in_idx(0x3c0, 0x10) & 0x01) | ||
continue; | ||
|
||
/* Graphics Controller: verify Alpha addressing enabled */ | ||
if (in_idx(0x3ce, 0x06) & 0x01) | ||
continue; | ||
|
||
/* CRTC cursor location low should be zero(?) */ | ||
if (in_idx(crtc, 0x0f)) | ||
continue; | ||
|
||
mi = GET_HEAP(struct mode_info, 1); | ||
mi->mode = VIDEO_FIRST_BIOS+mode; | ||
mi->x = rdfs16(0x44a); | ||
mi->y = rdfs8(0x484)+1; | ||
nmodes++; | ||
} | ||
|
||
set_bios_mode(saved_mode); | ||
|
||
return nmodes; | ||
} | ||
|
||
__videocard video_bios = | ||
{ | ||
.card_name = "BIOS (scanned)", | ||
.probe = bios_probe, | ||
.set_mode = bios_set_mode, | ||
.unsafe = 1, | ||
.xmode_first = VIDEO_FIRST_BIOS, | ||
.xmode_n = 0x80, | ||
}; |
Oops, something went wrong.