Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
video-bios.c
Go to the documentation of this file.
1 /* -*- linux-c -*- ------------------------------------------------------- *
2  *
3  * Copyright (C) 1991, 1992 Linus Torvalds
4  * Copyright 2007 rPath, Inc. - All Rights Reserved
5  * Copyright 2009 Intel Corporation; author H. Peter Anvin
6  *
7  * This file is part of the Linux kernel, and is made available under
8  * the terms of the GNU General Public License version 2.
9  *
10  * ----------------------------------------------------------------------- */
11 
12 /*
13  * Standard video BIOS modes
14  *
15  * We have two options for this; silent and scanned.
16  */
17 
18 #include "boot.h"
19 #include "video.h"
20 
21 static __videocard video_bios;
22 
23 /* Set a conventional BIOS mode */
24 static int set_bios_mode(u8 mode);
25 
26 static int bios_set_mode(struct mode_info *mi)
27 {
28  return set_bios_mode(mi->mode - VIDEO_FIRST_BIOS);
29 }
30 
31 static int set_bios_mode(u8 mode)
32 {
33  struct biosregs ireg, oreg;
34  u8 new_mode;
35 
36  initregs(&ireg);
37  ireg.al = mode; /* AH=0x00 Set Video Mode */
38  intcall(0x10, &ireg, NULL);
39 
40  ireg.ah = 0x0f; /* Get Current Video Mode */
41  intcall(0x10, &ireg, &oreg);
42 
43  do_restore = 1; /* Assume video contents were lost */
44 
45  /* Not all BIOSes are clean with the top bit */
46  new_mode = oreg.al & 0x7f;
47 
48  if (new_mode == mode)
49  return 0; /* Mode change OK */
50 
51 #ifndef _WAKEUP
52  if (new_mode != boot_params.screen_info.orig_video_mode) {
53  /* Mode setting failed, but we didn't end up where we
54  started. That's bad. Try to revert to the original
55  video mode. */
56  ireg.ax = boot_params.screen_info.orig_video_mode;
57  intcall(0x10, &ireg, NULL);
58  }
59 #endif
60  return -1;
61 }
62 
63 static int bios_probe(void)
64 {
65  u8 mode;
66 #ifdef _WAKEUP
67  u8 saved_mode = 0x03;
68 #else
69  u8 saved_mode = boot_params.screen_info.orig_video_mode;
70 #endif
71  u16 crtc;
72  struct mode_info *mi;
73  int nmodes = 0;
74 
76  return 0;
77 
78  set_fs(0);
79  crtc = vga_crtc();
80 
81  video_bios.modes = GET_HEAP(struct mode_info, 0);
82 
83  for (mode = 0x14; mode <= 0x7f; mode++) {
84  if (!heap_free(sizeof(struct mode_info)))
85  break;
86 
88  continue;
89 
90  if (set_bios_mode(mode))
91  continue;
92 
93  /* Try to verify that it's a text mode. */
94 
95  /* Attribute Controller: make graphics controller disabled */
96  if (in_idx(0x3c0, 0x10) & 0x01)
97  continue;
98 
99  /* Graphics Controller: verify Alpha addressing enabled */
100  if (in_idx(0x3ce, 0x06) & 0x01)
101  continue;
102 
103  /* CRTC cursor location low should be zero(?) */
104  if (in_idx(crtc, 0x0f))
105  continue;
106 
107  mi = GET_HEAP(struct mode_info, 1);
108  mi->mode = VIDEO_FIRST_BIOS+mode;
109  mi->depth = 0; /* text */
110  mi->x = rdfs16(0x44a);
111  mi->y = rdfs8(0x484)+1;
112  nmodes++;
113  }
114 
115  set_bios_mode(saved_mode);
116 
117  return nmodes;
118 }
119 
120 static __videocard video_bios =
121 {
122  .card_name = "BIOS",
123  .probe = bios_probe,
124  .set_mode = bios_set_mode,
125  .unsafe = 1,
126  .xmode_first = VIDEO_FIRST_BIOS,
127  .xmode_n = 0x80,
128 };