This source file includes following definitions.
- vesabios_match
- vbegetinfo
- vbefreeinfo
- vbeprobe
- mm2txt
- vesabios_attach
- vesabios_print
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 #include <sys/cdefs.h>
30
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/device.h>
34 #include <sys/malloc.h>
35 #include <machine/frame.h>
36 #include <machine/kvm86.h>
37
38 #include <dev/vesa/vesabiosvar.h>
39 #include <dev/vesa/vesabiosreg.h>
40 #include <dev/vesa/vbe.h>
41
42 struct vbeinfoblock
43 {
44 char VbeSignature[4];
45 uint16_t VbeVersion;
46 uint32_t OemStringPtr;
47 uint32_t Capabilities;
48 uint32_t VideoModePtr;
49 uint16_t TotalMemory;
50 uint16_t OemSoftwareRev;
51 uint32_t OemVendorNamePtr, OemProductNamePtr, OemProductRevPtr;
52
53 } __packed;
54
55 #define FAR2FLATPTR(p) ((p & 0xffff) + ((p >> 12) & 0xffff0))
56
57 int vesabios_match(struct device *, void *, void *);
58 void vesabios_attach(struct device *, struct device *, void *);
59 int vesabios_print(void *, const char *);
60
61 int vbegetinfo(struct vbeinfoblock **);
62 void vbefreeinfo(struct vbeinfoblock *);
63 #ifdef VESABIOSVERBOSE
64 const char *mm2txt(unsigned int);
65 #endif
66
67 struct vesabios_softc *vesabios_softc;
68
69 struct cfattach vesabios_ca = {
70 sizeof(struct vesabios_softc), vesabios_match, vesabios_attach
71 };
72
73 struct cfdriver vesabios_cd = {
74 NULL, "vesabios", DV_DULL
75 };
76
77 int
78 vesabios_match(struct device *parent, void *match, void *aux)
79 {
80
81 return (1);
82 }
83
84 int
85 vbegetinfo(struct vbeinfoblock **vip)
86 {
87 unsigned char *buf;
88 struct trapframe tf;
89 int res, error;
90
91 if ((buf = kvm86_bios_addpage(KVM86_CALL_TASKVA)) == NULL) {
92 printf("vbegetinfo: kvm86_bios_addpage failed\n");
93 return (ENOMEM);
94 }
95
96 memcpy(buf, "VBE2", 4);
97
98 memset(&tf, 0, sizeof(struct trapframe));
99 tf.tf_eax = VBE_FUNC_CTRLINFO;
100 tf.tf_vm86_es = 0;
101 tf.tf_edi = KVM86_CALL_TASKVA;
102
103 res = kvm86_bioscall(BIOS_VIDEO_INTR, &tf);
104 if (res || VBECALL_SUPPORT(tf.tf_eax) != VBECALL_SUPPORTED) {
105 printf("vbecall: res=%d, ax=%x\n", res, tf.tf_eax);
106 error = ENXIO;
107 goto out;
108 }
109
110 if (memcmp(((struct vbeinfoblock *)buf)->VbeSignature, "VESA", 4)) {
111 error = EIO;
112 goto out;
113 }
114
115 if (vip)
116 *vip = (struct vbeinfoblock *)buf;
117 return (0);
118
119 out:
120 kvm86_bios_delpage(KVM86_CALL_TASKVA, buf);
121 return (error);
122 }
123
124 void
125 vbefreeinfo(struct vbeinfoblock *vip)
126 {
127
128 kvm86_bios_delpage(KVM86_CALL_TASKVA, vip);
129 }
130
131 int
132 vbeprobe(void)
133 {
134 struct vbeinfoblock *vi;
135 int found = 0;
136
137 if (vbegetinfo(&vi))
138 return (0);
139 if (VBE_CTRLINFO_VERSION(vi->VbeVersion) > 1) {
140
141 found = 1;
142 }
143 vbefreeinfo(vi);
144 return (found);
145 }
146
147 #ifdef VESABIOSVERBOSE
148 const char *
149 mm2txt(unsigned int mm)
150 {
151 static char buf[30];
152 static const char *names[] = {
153 "Text mode",
154 "CGA graphics",
155 "Hercules graphics",
156 "Planar",
157 "Packed pixel",
158 "Non-chain 4, 256 color",
159 "Direct Color",
160 "YUV"
161 };
162
163 if (mm < sizeof(names)/sizeof(names[0]))
164 return (names[mm]);
165 snprintf(buf, sizeof(buf), "unknown memory model %d", mm);
166 return (buf);
167 }
168 #endif
169
170 void
171 vesabios_attach(struct device *parent, struct device *self, void *aux)
172 {
173 struct vesabios_softc *sc = (struct vesabios_softc *)self;
174 struct vbeinfoblock *vi;
175 unsigned char *buf;
176 struct trapframe tf;
177 int res;
178 char name[256];
179 #define MAXMODES 60
180 uint16_t modes[MAXMODES];
181 int rastermodes[MAXMODES];
182 int textmodes[MAXMODES];
183 int nmodes, nrastermodes, ntextmodes, i;
184 uint32_t modeptr;
185 struct modeinfoblock *mi;
186
187 if (vbegetinfo(&vi)) {
188 printf("\n");
189 panic("vesabios_attach: disappeared");
190 }
191
192 printf(": version %d.%d",
193 VBE_CTRLINFO_VERSION(vi->VbeVersion),
194 VBE_CTRLINFO_REVISION(vi->VbeVersion));
195
196
197 res = kvm86_bios_read(FAR2FLATPTR(vi->OemVendorNamePtr),
198 name, sizeof(name));
199
200 sc->sc_size = vi->TotalMemory * 65536;
201 if (res > 0) {
202 name[res - 1] = 0;
203 printf(", %s", name);
204 res = kvm86_bios_read(FAR2FLATPTR(vi->OemProductNamePtr),
205 name, sizeof(name));
206 if (res > 0) {
207 name[res - 1] = 0;
208 printf(" %s", name);
209 }
210 }
211 printf("\n");
212
213 nmodes = 0;
214 modeptr = FAR2FLATPTR(vi->VideoModePtr);
215 while (nmodes < MAXMODES) {
216 res = kvm86_bios_read(modeptr, (char *)&modes[nmodes], 2);
217 if (res != 2 || modes[nmodes] == 0xffff)
218 break;
219 nmodes++;
220 modeptr += 2;
221 }
222
223 vbefreeinfo(vi);
224 if (nmodes == 0)
225 return;
226
227 nrastermodes = ntextmodes = 0;
228
229 buf = kvm86_bios_addpage(KVM86_CALL_TASKVA);
230 if (!buf) {
231 printf("%s: kvm86_bios_addpage failed\n",
232 self->dv_xname);
233 return;
234 }
235 for (i = 0; i < nmodes; i++) {
236
237 memset(&tf, 0, sizeof(struct trapframe));
238 tf.tf_eax = VBE_FUNC_MODEINFO;
239 tf.tf_ecx = modes[i];
240 tf.tf_vm86_es = 0;
241 tf.tf_edi = KVM86_CALL_TASKVA;
242
243 res = kvm86_bioscall(BIOS_VIDEO_INTR, &tf);
244 if (res || VBECALL_SUPPORT(tf.tf_eax) != VBECALL_SUPPORTED) {
245 printf("%s: vbecall: res=%d, ax=%x\n",
246 self->dv_xname, res, tf.tf_eax);
247 printf("%s: error getting info for mode %04x\n",
248 self->dv_xname, modes[i]);
249 continue;
250 }
251 mi = (struct modeinfoblock *)buf;
252 #ifdef VESABIOSVERBOSE
253 printf("%s: VESA mode %04x: attributes %04x",
254 self->dv_xname, modes[i], mi->ModeAttributes);
255 #endif
256 if (!(mi->ModeAttributes & 1)) {
257 #ifdef VESABIOSVERBOSE
258 printf("\n");
259 #endif
260 continue;
261 }
262 if (mi->ModeAttributes & 0x10) {
263
264 #ifdef VESABIOSVERBOSE
265 printf(", %dx%d %dbbp %s\n",
266 mi->XResolution, mi->YResolution,
267 mi->BitsPerPixel, mm2txt(mi->MemoryModel));
268 #endif
269 if (mi->ModeAttributes & 0x80) {
270
271 rastermodes[nrastermodes++] = modes[i];
272 }
273 } else {
274
275 #ifdef VESABIOSVERBOSE
276 printf(", text %dx%d\n",
277 mi->XResolution, mi->YResolution);
278 #endif
279 if (!(mi->ModeAttributes & 0x20))
280 textmodes[ntextmodes++] = modes[i];
281 }
282 }
283 kvm86_bios_delpage(KVM86_CALL_TASKVA, buf);
284 if (nrastermodes > 0) {
285 sc->sc_modes =
286 (uint16_t *)malloc(sizeof(uint16_t)*nrastermodes,
287 M_DEVBUF, M_NOWAIT);
288 if (sc->sc_modes == NULL) {
289 sc->sc_nmodes = 0;
290 return;
291 }
292 sc->sc_nmodes = nrastermodes;
293 for (i = 0; i < nrastermodes; i++)
294 sc->sc_modes[i] = rastermodes[i];
295 }
296 vesabios_softc = sc;
297 }
298
299 int
300 vesabios_print(aux, pnp)
301 void *aux;
302 const char *pnp;
303 {
304 char *busname = aux;
305
306 if (pnp)
307 printf("%s at %s", busname, pnp);
308 return (UNCONF);
309 }