• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/arch/x86/boot/
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
21static __videocard video_bios;
22
23/* Set a conventional BIOS mode */
24static int set_bios_mode(u8 mode);
25
26static int bios_set_mode(struct mode_info *mi)
27{
28	return set_bios_mode(mi->mode - VIDEO_FIRST_BIOS);
29}
30
31static 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
63static 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
75	if (adapter != ADAPTER_EGA && adapter != ADAPTER_VGA)
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
87		if (mode_defined(VIDEO_FIRST_BIOS+mode))
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
120static __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};
129