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