This source file includes following definitions.
- vesafb_get_ddc_version
- vesafb_get_ddc_info
- vesafb_get_mode
- vesafb_get_mode_info
- vesafb_set_palette
- vesafb_set_mode
- vesafb_find_mode
- vesafb_putcmap
- vesafb_getcmap
- vesafb_getdepthflag
- vesafb_get_supported_depth
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 #include <sys/param.h>
52 #include <sys/systm.h>
53 #include <sys/kernel.h>
54 #include <sys/device.h>
55
56 #include <machine/bus.h>
57
58 #include <dev/pci/pcireg.h>
59 #include <dev/pci/pcivar.h>
60 #include <dev/pci/pcidevs.h>
61
62 #include <dev/ic/mc6845reg.h>
63 #include <dev/ic/pcdisplayvar.h>
64 #include <dev/ic/vgareg.h>
65 #include <dev/ic/vgavar.h>
66 #include <dev/pci/vga_pcivar.h>
67
68 #include <dev/vesa/vesabiosreg.h>
69 #include <dev/vesa/vesabiosvar.h>
70 #include <dev/vesa/vbe.h>
71
72 #include <machine/frame.h>
73 #include <machine/kvm86.h>
74
75 #include <dev/wscons/wsconsio.h>
76 #include <dev/wscons/wsdisplayvar.h>
77
78 #include <uvm/uvm_extern.h>
79
80
81 void vesafb_set_mode(struct vga_pci_softc *, int);
82 int vesafb_get_mode(struct vga_pci_softc *);
83 void vesafb_get_mode_info(struct vga_pci_softc *, int, struct modeinfoblock *);
84 void vesafb_set_palette(struct vga_pci_softc *, int, struct paletteentry);
85 int vesafb_putcmap(struct vga_pci_softc *, struct wsdisplay_cmap *);
86 int vesafb_getcmap(struct vga_pci_softc *, struct wsdisplay_cmap *);
87 int vesafb_get_ddc_version(struct vga_pci_softc *);
88 int vesafb_get_ddc_info(struct vga_pci_softc *, struct edid *);
89
90 int
91 vesafb_get_ddc_version(struct vga_pci_softc *sc)
92 {
93 struct trapframe tf;
94 int res;
95
96 bzero(&tf, sizeof(struct trapframe));
97 tf.tf_eax = VBE_FUNC_DDC;
98
99 res = kvm86_bioscall(BIOS_VIDEO_INTR, &tf);
100 if (res || VBECALL_SUPPORT(tf.tf_eax) != VBECALL_SUPPORTED)
101 return 0;
102
103 return VBECALL_SUCESS(tf.tf_eax);
104 }
105
106
107 int
108 vesafb_get_ddc_info(struct vga_pci_softc *sc, struct edid *info)
109 {
110 struct trapframe tf;
111 unsigned char *buf;
112 int res;
113
114 if ((buf = kvm86_bios_addpage(KVM86_CALL_TASKVA)) == NULL) {
115 printf("%s: kvm86_bios_addpage failed.\n",
116 sc->sc_dev.dv_xname);
117 return 1;
118 }
119
120 bzero(&tf, sizeof(struct trapframe));
121 tf.tf_eax = VBE_FUNC_DDC;
122 tf.tf_ebx = VBE_DDC_GET;
123 tf.tf_vm86_es = 0;
124 tf.tf_edi = KVM86_CALL_TASKVA;
125
126 res = kvm86_bioscall(BIOS_VIDEO_INTR, &tf);
127 if (res || VBECALL_SUPPORT(tf.tf_eax) != VBECALL_SUPPORTED) {
128 kvm86_bios_delpage(KVM86_CALL_TASKVA, buf);
129 return 1;
130 }
131
132 memcpy(info, buf, sizeof(struct edid));
133 kvm86_bios_delpage(KVM86_CALL_TASKVA, buf);
134 return VBECALL_SUCESS(tf.tf_eax);
135 }
136
137 int
138 vesafb_get_mode(struct vga_pci_softc *sc)
139 {
140 struct trapframe tf;
141 int res;
142
143 bzero(&tf, sizeof(struct trapframe));
144 tf.tf_eax = VBE_FUNC_GETMODE;
145
146 res = kvm86_bioscall(BIOS_VIDEO_INTR, &tf);
147 if (res || VBECALL_SUPPORT(tf.tf_eax) != VBECALL_SUPPORTED) {
148 printf("%s: vbecall: res=%d, ax=%x\n",
149 sc->sc_dev.dv_xname, res, tf.tf_eax);
150 }
151 return tf.tf_ebx & 0xffff;
152 }
153
154 void
155 vesafb_get_mode_info(struct vga_pci_softc *sc, int mode,
156 struct modeinfoblock *mi)
157 {
158 struct trapframe tf;
159 unsigned char *buf;
160 int res;
161
162 if ((buf = kvm86_bios_addpage(KVM86_CALL_TASKVA)) == NULL) {
163 printf("%s: kvm86_bios_addpage failed.\n",
164 sc->sc_dev.dv_xname);
165 return;
166 }
167 memset(&tf, 0, sizeof(struct trapframe));
168 tf.tf_eax = VBE_FUNC_MODEINFO;
169 tf.tf_ecx = mode;
170 tf.tf_vm86_es = 0;
171 tf.tf_edi = KVM86_CALL_TASKVA;
172
173 res = kvm86_bioscall(BIOS_VIDEO_INTR, &tf);
174 if (res || VBECALL_SUPPORT(tf.tf_eax) != VBECALL_SUPPORTED) {
175 printf("%s: vbecall: res=%d, ax=%x\n",
176 sc->sc_dev.dv_xname, res, tf.tf_eax);
177 printf("%s: error getting info for mode %05x\n",
178 sc->sc_dev.dv_xname, mode);
179 kvm86_bios_delpage(KVM86_CALL_TASKVA, buf);
180 return;
181 }
182 memcpy(mi, buf, sizeof(struct modeinfoblock));
183 kvm86_bios_delpage(KVM86_CALL_TASKVA, buf);
184 }
185
186 void
187 vesafb_set_palette(struct vga_pci_softc *sc, int reg, struct paletteentry pe)
188 {
189 struct trapframe tf;
190 int res;
191 char *buf;
192
193 if ((buf = kvm86_bios_addpage(KVM86_CALL_TASKVA)) == NULL) {
194 printf("%s: kvm86_bios_addpage failed.\n",
195 sc->sc_dev.dv_xname);
196 return;
197 }
198
199
200
201
202 pe.Red >>= 2;
203 pe.Green >>= 2;
204 pe.Blue >>= 2;
205
206 memcpy(buf, &pe, sizeof(struct paletteentry));
207
208
209 memset(&tf, 0, sizeof(struct trapframe));
210 tf.tf_eax = VBE_FUNC_PALETTE;
211 tf.tf_ebx = 0x0600;
212 tf.tf_ecx = 1;
213 tf.tf_edx = reg;
214 tf.tf_vm86_es = 0;
215 tf.tf_edi = KVM86_CALL_TASKVA;
216
217 res = kvm86_bioscall(BIOS_VIDEO_INTR, &tf);
218 if (res || VBECALL_SUPPORT(tf.tf_eax) != VBECALL_SUPPORTED)
219 printf("%s: vbecall: res=%d, ax=%x\n",
220 sc->sc_dev.dv_xname, res, tf.tf_eax);
221
222 kvm86_bios_delpage(KVM86_CALL_TASKVA, buf);
223 return;
224 }
225
226 void
227 vesafb_set_mode(struct vga_pci_softc *sc, int mode)
228 {
229 struct trapframe tf;
230 int res;
231
232 bzero(&tf, sizeof(struct trapframe));
233 tf.tf_eax = VBE_FUNC_SETMODE;
234 tf.tf_ebx = mode | 0x4000;
235
236 res = kvm86_bioscall(BIOS_VIDEO_INTR, &tf);
237 if (res || VBECALL_SUPPORT(tf.tf_eax) != VBECALL_SUPPORTED) {
238 printf("%s: vbecall: res=%d, ax=%x\n",
239 sc->sc_dev.dv_xname, res, tf.tf_eax);
240 return;
241 }
242 }
243
244 int
245 vesafb_find_mode(struct vga_pci_softc *sc, int width, int height, int bpp)
246 {
247 struct modeinfoblock mi;
248 int i;
249
250 if (vesabios_softc == NULL || vesabios_softc->sc_nmodes == 0)
251 return -1;
252 #ifdef VESABIOSVERBOSE
253 printf("vesafb_find_mode %d %d %d\n", width, height, bpp);
254 #endif
255
256 for (i = 0; i < vesabios_softc->sc_nmodes; i++) {
257 vesafb_get_mode_info(sc, vesabios_softc->sc_modes[i], &mi);
258 if (mi.XResolution == width &&
259 mi.YResolution == height &&
260 mi.BitsPerPixel == bpp) {
261 sc->sc_width = mi.XResolution;
262 sc->sc_height = mi.YResolution;
263 sc->sc_depth = mi.BitsPerPixel;
264 sc->sc_linebytes = mi.BytesPerScanLine;
265 sc->sc_base = mi.PhysBasePtr;
266 break;
267 }
268 }
269 if (i == vesabios_softc->sc_nmodes)
270 return -1;
271 else
272 return vesabios_softc->sc_modes[i];
273 }
274
275 int
276 vesafb_putcmap(struct vga_pci_softc *sc, struct wsdisplay_cmap *cm)
277 {
278 struct paletteentry pe;
279 u_int idx, cnt;
280 u_char r[256], g[256], b[256];
281 u_char *rp, *gp, *bp;
282 int rv, i;
283
284 idx = cm->index;
285 cnt = cm->count;
286
287 if (idx >= 256 || cnt > 256 - idx)
288 return EINVAL;
289
290 rv = copyin(cm->red, &r[idx], cnt);
291 if (rv)
292 return rv;
293 rv = copyin(cm->green, &g[idx], cnt);
294 if (rv)
295 return rv;
296 rv = copyin(cm->blue, &b[idx], cnt);
297 if (rv)
298 return rv;
299
300 memcpy(&sc->sc_cmap_red[idx], &r[idx], cnt);
301 memcpy(&sc->sc_cmap_green[idx], &g[idx], cnt);
302 memcpy(&sc->sc_cmap_blue[idx], &b[idx], cnt);
303
304 rp = &sc->sc_cmap_red[idx];
305 gp = &sc->sc_cmap_green[idx];
306 bp = &sc->sc_cmap_blue[idx];
307
308 for (i = 0; i < cnt; i++) {
309 pe.Blue = *bp;
310 pe.Green = *gp;
311 pe.Red = *rp;
312 pe.Alignment = 0;
313 vesafb_set_palette(sc, idx, pe);
314 idx++;
315 rp++, gp++, bp++;
316 }
317
318 return 0;
319 }
320
321 int
322 vesafb_getcmap(struct vga_pci_softc *sc, struct wsdisplay_cmap *cm)
323 {
324 u_int idx, cnt;
325 int rv;
326
327 idx = cm->index;
328 cnt = cm->count;
329
330 if (idx >= 256 || cnt > 256 - idx)
331 return EINVAL;
332
333 rv = copyout(&sc->sc_cmap_red[idx], cm->red, cnt);
334 if (rv)
335 return rv;
336 rv = copyout(&sc->sc_cmap_green[idx], cm->green, cnt);
337 if (rv)
338 return rv;
339 rv = copyout(&sc->sc_cmap_blue[idx], cm->blue, cnt);
340 if (rv)
341 return rv;
342
343 return 0;
344 }
345
346 static int
347 vesafb_getdepthflag(struct modeinfoblock *mi)
348 {
349 int bpp, depth;
350
351 depth = mi->RedMaskSize + mi->GreenMaskSize + mi->BlueMaskSize;
352 bpp = mi->BitsPerPixel;
353 switch (depth) {
354 case 1:
355 return WSDISPLAYIO_DEPTH_1;
356 case 4:
357 return WSDISPLAYIO_DEPTH_4;
358 case 8:
359 return WSDISPLAYIO_DEPTH_8;
360 case 15:
361 return WSDISPLAYIO_DEPTH_15;
362 case 16:
363 return WSDISPLAYIO_DEPTH_16;
364 case 24:
365 switch (bpp) {
366 case 24:
367 return WSDISPLAYIO_DEPTH_24_24;
368 case 32:
369 return WSDISPLAYIO_DEPTH_24_32;
370 }
371 }
372 return 0;
373 }
374
375
376 int
377 vesafb_get_supported_depth(struct vga_pci_softc *sc)
378 {
379 int i, depths;
380 struct modeinfoblock mi;
381
382 depths = 0;
383
384 if (vesabios_softc == NULL || vesabios_softc->sc_nmodes == 0)
385 return 0;
386
387 for (i = 0; i < vesabios_softc->sc_nmodes; i++) {
388 vesafb_get_mode_info(sc, vesabios_softc->sc_modes[i], &mi);
389 depths |= vesafb_getdepthflag(&mi);
390 }
391 return depths;
392 }