Annotation of src/sys/arch/prep/stand/boot/vreset.c, Revision 1.3
1.3 ! dsl 1: /* $NetBSD: vreset.c,v 1.2 2005/12/24 23:24:02 perry Exp $ */
1.1 nonaka 2:
3: /*
4: * Copyright (C) 1995-1997 Gary Thomas (gdt@linuxppc.org)
5: * All rights reserved.
6: *
7: * Initialize the VGA control registers to 80x25 text mode.
8: *
9: * Adapted from a program by:
10: * Steve Sellgren
11: * San Francisco Indigo Company
12: * sfindigo!sellgren@uunet.uu.net
13: * Adapted for Moto boxes by:
14: * Pat Kane & Mark Scott, 1996
15: * Fixed for IBM/PowerStack II Pat Kane 1997
16: *
17: * Redistribution and use in source and binary forms, with or without
18: * modification, are permitted provided that the following conditions
19: * are met:
20: * 1. Redistributions of source code must retain the above copyright
21: * notice, this list of conditions and the following disclaimer.
22: * 2. Redistributions in binary form must reproduce the above copyright
23: * notice, this list of conditions and the following disclaimer in the
24: * documentation and/or other materials provided with the distribution.
25: * 3. All advertising materials mentioning features or use of this software
26: * must display the following acknowledgement:
27: * This product includes software developed by Gary Thomas.
28: * 4. The name of the author may not be used to endorse or promote products
29: * derived from this software without specific prior written permission.
30: *
31: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
32: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
33: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
34: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
35: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
40: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41: */
42:
43: #ifdef CONS_VGA
44: #include <lib/libsa/stand.h>
1.3 ! dsl 45: #include <sys/bswap.h>
1.1 nonaka 46: #include "boot.h"
47: #include "iso_font.h"
48:
49: static inline void outw __P((int, u_short));
50: void writeAttr __P((u_char, u_char, u_char));
51:
52:
53: #if 0
54: static char rcsid[] = "vreset.c 2.0 1997 kane PEK'97 Exp $";
55: #endif
56:
57: /*
58: * VGA Register
59: */
60: struct VgaRegs
61: {
62: u_short io_port;
63: u_char io_index;
64: u_char io_value;
65: };
66:
67: /*
68: * Default console text mode registers used to reset
69: * graphics adapter.
70: */
71: #define NREGS 54
72: #define ENDMK 0xFFFF /* End marker */
73:
74: #define S3Vendor 0x5333
75: #define CirrusVendor 0x1013
76: #define DiamondVendor 0x100E
77: #define MatroxVendor 0x102B
78:
79: struct VgaRegs GenVgaTextRegs[NREGS+1] = {
80: /* port index value */
81: /* SR Regs */
82: { 0x3c4, 0x1, 0x0 },
83: { 0x3c4, 0x2, 0x3 },
84: { 0x3c4, 0x3, 0x0 },
85: { 0x3c4, 0x4, 0x2 },
86: /* CR Regs */
87: { 0x3d4, 0x0, 0x5f },
88: { 0x3d4, 0x1, 0x4f },
89: { 0x3d4, 0x2, 0x50 },
90: { 0x3d4, 0x3, 0x82 },
91: { 0x3d4, 0x4, 0x55 },
92: { 0x3d4, 0x5, 0x81 },
93: { 0x3d4, 0x6, 0xbf },
94: { 0x3d4, 0x7, 0x1f },
95: { 0x3d4, 0x8, 0x00 },
96: { 0x3d4, 0x9, 0x4f },
97: { 0x3d4, 0xa, 0x0d },
98: { 0x3d4, 0xb, 0x0e },
99: { 0x3d4, 0xc, 0x00 },
100: { 0x3d4, 0xd, 0x00 },
101: { 0x3d4, 0xe, 0x00 },
102: { 0x3d4, 0xf, 0x00 },
103: { 0x3d4, 0x10, 0x9c },
104: { 0x3d4, 0x11, 0x8e },
105: { 0x3d4, 0x12, 0x8f },
106: { 0x3d4, 0x13, 0x28 },
107: { 0x3d4, 0x14, 0x1f },
108: { 0x3d4, 0x15, 0x96 },
109: { 0x3d4, 0x16, 0xb9 },
110: { 0x3d4, 0x17, 0xa3 },
111: /* GR Regs */
112: { 0x3ce, 0x0, 0x0 },
113: { 0x3ce, 0x1, 0x0 },
114: { 0x3ce, 0x2, 0x0 },
115: { 0x3ce, 0x3, 0x0 },
116: { 0x3ce, 0x4, 0x0 },
117: { 0x3ce, 0x5, 0x10 },
118: { 0x3ce, 0x6, 0xe },
119: { 0x3ce, 0x7, 0x0 },
120: { 0x3ce, 0x8, 0xff },
121: { ENDMK },
122: };
123:
124: struct VgaRegs S3TextRegs[NREGS+1] = {
125: /* port index value */
126: /* SR Regs */
127: { 0x3c4, 0x1, 0x0 },
128: { 0x3c4, 0x2, 0x3 },
129: { 0x3c4, 0x3, 0x0 },
130: { 0x3c4, 0x4, 0x2 },
131: /* CR Regs */
132: { 0x3d4, 0x0, 0x5f },
133: { 0x3d4, 0x1, 0x4f },
134: { 0x3d4, 0x2, 0x50 },
135: { 0x3d4, 0x3, 0x82 },
136: { 0x3d4, 0x4, 0x55 },
137: { 0x3d4, 0x5, 0x81 },
138: { 0x3d4, 0x6, 0xbf },
139: { 0x3d4, 0x7, 0x1f },
140: { 0x3d4, 0x8, 0x00 },
141: { 0x3d4, 0x9, 0x4f },
142: { 0x3d4, 0xa, 0x0d },
143: { 0x3d4, 0xb, 0x0e },
144: { 0x3d4, 0xc, 0x00 },
145: { 0x3d4, 0xd, 0x00 },
146: { 0x3d4, 0xe, 0x00 },
147: { 0x3d4, 0xf, 0x00 },
148: { 0x3d4, 0x10, 0x9c },
149: { 0x3d4, 0x11, 0x8e },
150: { 0x3d4, 0x12, 0x8f },
151: { 0x3d4, 0x13, 0x28 },
152: { 0x3d4, 0x14, 0x1f },
153: { 0x3d4, 0x15, 0x96 },
154: { 0x3d4, 0x16, 0xb9 },
155: { 0x3d4, 0x17, 0xa3 },
156: /* GR Regs */
157: { 0x3ce, 0x0, 0x0 },
158: { 0x3ce, 0x1, 0x0 },
159: { 0x3ce, 0x2, 0x0 },
160: { 0x3ce, 0x3, 0x0 },
161: { 0x3ce, 0x4, 0x0 },
162: { 0x3ce, 0x5, 0x10 },
163: { 0x3ce, 0x6, 0xe },
164: { 0x3ce, 0x7, 0x0 },
165: { 0x3ce, 0x8, 0xff },
166: { ENDMK }
167: };
168:
169: struct RGBColors
170: {
171: u_char r, g, b;
172: };
173:
174: /*
175: * Default console text mode color table.
176: * These values were obtained by booting Linux with
177: * text mode firmware & then dumping the registers.
178: */
179: struct RGBColors TextCLUT[256] =
180: {
181: /* red green blue */
182: { 0x0, 0x0, 0x0 },
183: { 0x0, 0x0, 0x2a },
184: { 0x0, 0x2a, 0x0 },
185: { 0x0, 0x2a, 0x2a },
186: { 0x2a, 0x0, 0x0 },
187: { 0x2a, 0x0, 0x2a },
188: { 0x2a, 0x2a, 0x0 },
189: { 0x2a, 0x2a, 0x2a },
190: { 0x0, 0x0, 0x15 },
191: { 0x0, 0x0, 0x3f },
192: { 0x0, 0x2a, 0x15 },
193: { 0x0, 0x2a, 0x3f },
194: { 0x2a, 0x0, 0x15 },
195: { 0x2a, 0x0, 0x3f },
196: { 0x2a, 0x2a, 0x15 },
197: { 0x2a, 0x2a, 0x3f },
198: { 0x0, 0x15, 0x0 },
199: { 0x0, 0x15, 0x2a },
200: { 0x0, 0x3f, 0x0 },
201: { 0x0, 0x3f, 0x2a },
202: { 0x2a, 0x15, 0x0 },
203: { 0x2a, 0x15, 0x2a },
204: { 0x2a, 0x3f, 0x0 },
205: { 0x2a, 0x3f, 0x2a },
206: { 0x0, 0x15, 0x15 },
207: { 0x0, 0x15, 0x3f },
208: { 0x0, 0x3f, 0x15 },
209: { 0x0, 0x3f, 0x3f },
210: { 0x2a, 0x15, 0x15 },
211: { 0x2a, 0x15, 0x3f },
212: { 0x2a, 0x3f, 0x15 },
213: { 0x2a, 0x3f, 0x3f },
214: { 0x15, 0x0, 0x0 },
215: { 0x15, 0x0, 0x2a },
216: { 0x15, 0x2a, 0x0 },
217: { 0x15, 0x2a, 0x2a },
218: { 0x3f, 0x0, 0x0 },
219: { 0x3f, 0x0, 0x2a },
220: { 0x3f, 0x2a, 0x0 },
221: { 0x3f, 0x2a, 0x2a },
222: { 0x15, 0x0, 0x15 },
223: { 0x15, 0x0, 0x3f },
224: { 0x15, 0x2a, 0x15 },
225: { 0x15, 0x2a, 0x3f },
226: { 0x3f, 0x0, 0x15 },
227: { 0x3f, 0x0, 0x3f },
228: { 0x3f, 0x2a, 0x15 },
229: { 0x3f, 0x2a, 0x3f },
230: { 0x15, 0x15, 0x0 },
231: { 0x15, 0x15, 0x2a },
232: { 0x15, 0x3f, 0x0 },
233: { 0x15, 0x3f, 0x2a },
234: { 0x3f, 0x15, 0x0 },
235: { 0x3f, 0x15, 0x2a },
236: { 0x3f, 0x3f, 0x0 },
237: { 0x3f, 0x3f, 0x2a },
238: { 0x15, 0x15, 0x15 },
239: { 0x15, 0x15, 0x3f },
240: { 0x15, 0x3f, 0x15 },
241: { 0x15, 0x3f, 0x3f },
242: { 0x3f, 0x15, 0x15 },
243: { 0x3f, 0x15, 0x3f },
244: { 0x3f, 0x3f, 0x15 },
245: { 0x3f, 0x3f, 0x3f },
246: { 0x39, 0xc, 0x5 },
247: { 0x15, 0x2c, 0xf },
248: { 0x26, 0x10, 0x3d },
249: { 0x29, 0x29, 0x38 },
250: { 0x4, 0x1a, 0xe },
251: { 0x2, 0x1e, 0x3a },
252: { 0x3c, 0x25, 0x33 },
253: { 0x3c, 0xc, 0x2c },
254: { 0x3f, 0x3, 0x2b },
255: { 0x1c, 0x9, 0x13 },
256: { 0x25, 0x2a, 0x35 },
257: { 0x1e, 0xa, 0x38 },
258: { 0x24, 0x8, 0x3 },
259: { 0x3, 0xe, 0x36 },
260: { 0xc, 0x6, 0x2a },
261: { 0x26, 0x3, 0x32 },
262: { 0x5, 0x2f, 0x33 },
263: { 0x3c, 0x35, 0x2f },
264: { 0x2d, 0x26, 0x3e },
265: { 0xd, 0xa, 0x10 },
266: { 0x25, 0x3c, 0x11 },
267: { 0xd, 0x4, 0x2e },
268: { 0x5, 0x19, 0x3e },
269: { 0xc, 0x13, 0x34 },
270: { 0x2b, 0x6, 0x24 },
271: { 0x4, 0x3, 0xd },
272: { 0x2f, 0x3c, 0xc },
273: { 0x2a, 0x37, 0x1f },
274: { 0xf, 0x12, 0x38 },
275: { 0x38, 0xe, 0x2a },
276: { 0x12, 0x2f, 0x19 },
277: { 0x29, 0x2e, 0x31 },
278: { 0x25, 0x13, 0x3e },
279: { 0x33, 0x3e, 0x33 },
280: { 0x1d, 0x2c, 0x25 },
281: { 0x15, 0x15, 0x5 },
282: { 0x32, 0x25, 0x39 },
283: { 0x1a, 0x7, 0x1f },
284: { 0x13, 0xe, 0x1d },
285: { 0x36, 0x17, 0x34 },
286: { 0xf, 0x15, 0x23 },
287: { 0x2, 0x35, 0xd },
288: { 0x15, 0x3f, 0xc },
289: { 0x14, 0x2f, 0xf },
290: { 0x19, 0x21, 0x3e },
291: { 0x27, 0x11, 0x2f },
292: { 0x38, 0x3f, 0x3c },
293: { 0x36, 0x2d, 0x15 },
294: { 0x16, 0x17, 0x2 },
295: { 0x1, 0xa, 0x3d },
296: { 0x1b, 0x11, 0x3f },
297: { 0x21, 0x3c, 0xd },
298: { 0x1a, 0x39, 0x3d },
299: { 0x8, 0xe, 0xe },
300: { 0x22, 0x21, 0x23 },
301: { 0x1e, 0x30, 0x5 },
302: { 0x1f, 0x22, 0x3d },
303: { 0x1e, 0x2f, 0xa },
304: { 0x0, 0x1c, 0xe },
305: { 0x0, 0x1c, 0x15 },
306: { 0x0, 0x1c, 0x1c },
307: { 0x0, 0x15, 0x1c },
308: { 0x0, 0xe, 0x1c },
309: { 0x0, 0x7, 0x1c },
310: { 0xe, 0xe, 0x1c },
311: { 0x11, 0xe, 0x1c },
312: { 0x15, 0xe, 0x1c },
313: { 0x18, 0xe, 0x1c },
314: { 0x1c, 0xe, 0x1c },
315: { 0x1c, 0xe, 0x18 },
316: { 0x1c, 0xe, 0x15 },
317: { 0x1c, 0xe, 0x11 },
318: { 0x1c, 0xe, 0xe },
319: { 0x1c, 0x11, 0xe },
320: { 0x1c, 0x15, 0xe },
321: { 0x1c, 0x18, 0xe },
322: { 0x1c, 0x1c, 0xe },
323: { 0x18, 0x1c, 0xe },
324: { 0x15, 0x1c, 0xe },
325: { 0x11, 0x1c, 0xe },
326: { 0xe, 0x1c, 0xe },
327: { 0xe, 0x1c, 0x11 },
328: { 0xe, 0x1c, 0x15 },
329: { 0xe, 0x1c, 0x18 },
330: { 0xe, 0x1c, 0x1c },
331: { 0xe, 0x18, 0x1c },
332: { 0xe, 0x15, 0x1c },
333: { 0xe, 0x11, 0x1c },
334: { 0x14, 0x14, 0x1c },
335: { 0x16, 0x14, 0x1c },
336: { 0x18, 0x14, 0x1c },
337: { 0x1a, 0x14, 0x1c },
338: { 0x1c, 0x14, 0x1c },
339: { 0x1c, 0x14, 0x1a },
340: { 0x1c, 0x14, 0x18 },
341: { 0x1c, 0x14, 0x16 },
342: { 0x1c, 0x14, 0x14 },
343: { 0x1c, 0x16, 0x14 },
344: { 0x1c, 0x18, 0x14 },
345: { 0x1c, 0x1a, 0x14 },
346: { 0x1c, 0x1c, 0x14 },
347: { 0x1a, 0x1c, 0x14 },
348: { 0x18, 0x1c, 0x14 },
349: { 0x16, 0x1c, 0x14 },
350: { 0x14, 0x1c, 0x14 },
351: { 0x14, 0x1c, 0x16 },
352: { 0x14, 0x1c, 0x18 },
353: { 0x14, 0x1c, 0x1a },
354: { 0x14, 0x1c, 0x1c },
355: { 0x14, 0x1a, 0x1c },
356: { 0x14, 0x18, 0x1c },
357: { 0x14, 0x16, 0x1c },
358: { 0x0, 0x0, 0x10 },
359: { 0x4, 0x0, 0x10 },
360: { 0x8, 0x0, 0x10 },
361: { 0xc, 0x0, 0x10 },
362: { 0x10, 0x0, 0x10 },
363: { 0x10, 0x0, 0xc },
364: { 0x10, 0x0, 0x8 },
365: { 0x10, 0x0, 0x4 },
366: { 0x10, 0x0, 0x0 },
367: { 0x10, 0x4, 0x0 },
368: { 0x10, 0x8, 0x0 },
369: { 0x10, 0xc, 0x0 },
370: { 0x10, 0x10, 0x0 },
371: { 0xc, 0x10, 0x0 },
372: { 0x8, 0x10, 0x0 },
373: { 0x4, 0x10, 0x0 },
374: { 0x0, 0x10, 0x0 },
375: { 0x0, 0x10, 0x4 },
376: { 0x0, 0x10, 0x8 },
377: { 0x0, 0x10, 0xc },
378: { 0x0, 0x10, 0x10 },
379: { 0x0, 0xc, 0x10 },
380: { 0x0, 0x8, 0x10 },
381: { 0x0, 0x4, 0x10 },
382: { 0x8, 0x8, 0x10 },
383: { 0xa, 0x8, 0x10 },
384: { 0xc, 0x8, 0x10 },
385: { 0xe, 0x8, 0x10 },
386: { 0x10, 0x8, 0x10 },
387: { 0x10, 0x8, 0xe },
388: { 0x10, 0x8, 0xc },
389: { 0x10, 0x8, 0xa },
390: { 0x10, 0x8, 0x8 },
391: { 0x10, 0xa, 0x8 },
392: { 0x10, 0xc, 0x8 },
393: { 0x10, 0xe, 0x8 },
394: { 0x10, 0x10, 0x8 },
395: { 0xe, 0x10, 0x8 },
396: { 0xc, 0x10, 0x8 },
397: { 0xa, 0x10, 0x8 },
398: { 0x8, 0x10, 0x8 },
399: { 0x8, 0x10, 0xa },
400: { 0x8, 0x10, 0xc },
401: { 0x8, 0x10, 0xe },
402: { 0x8, 0x10, 0x10 },
403: { 0x8, 0xe, 0x10 },
404: { 0x8, 0xc, 0x10 },
405: { 0x8, 0xa, 0x10 },
406: { 0xb, 0xb, 0x10 },
407: { 0xc, 0xb, 0x10 },
408: { 0xd, 0xb, 0x10 },
409: { 0xf, 0xb, 0x10 },
410: { 0x10, 0xb, 0x10 },
411: { 0x10, 0xb, 0xf },
412: { 0x10, 0xb, 0xd },
413: { 0x10, 0xb, 0xc },
414: { 0x10, 0xb, 0xb },
415: { 0x10, 0xc, 0xb },
416: { 0x10, 0xd, 0xb },
417: { 0x10, 0xf, 0xb },
418: { 0x10, 0x10, 0xb },
419: { 0xf, 0x10, 0xb },
420: { 0xd, 0x10, 0xb },
421: { 0xc, 0x10, 0xb },
422: { 0xb, 0x10, 0xb },
423: { 0xb, 0x10, 0xc },
424: { 0xb, 0x10, 0xd },
425: { 0xb, 0x10, 0xf },
426: { 0xb, 0x10, 0x10 },
427: { 0xb, 0xf, 0x10 },
428: { 0xb, 0xd, 0x10 },
429: { 0xb, 0xc, 0x10 },
430: { 0x0, 0x0, 0x0 },
431: { 0x0, 0x0, 0x0 },
432: { 0x0, 0x0, 0x0 },
433: { 0x0, 0x0, 0x0 },
434: { 0x0, 0x0, 0x0 },
435: { 0x0, 0x0, 0x0 },
436: { 0x0, 0x0, 0x0 },
437: };
438:
439: u_char AC[21] = {
440: 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
441: 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
442: 0x0C, 0x00, 0x0F, 0x08, 0x00
443: };
444:
445: void enablePCIvideo __P((int));
446: static int scanPCI __P((void));
447: static int PCIVendor __P((int));
448: int delayLoop __P((int));
449: void setTextRegs __P((struct VgaRegs *));
450: void setTextCLUT __P((void));
451: void loadFont __P((u_char *));
452: void unlockS3 __P((void));
453: #ifdef DEBUG
454: static void printslots __P((void));
455: #endif
456:
457: static inline void
458: outw(port, val)
459: int port;
460: u_short val;
461: {
462: outb(port, val >> 8);
463: outb(port+1, val);
464: }
465:
466: void
467: vga_reset(ISA_mem)
468: u_char *ISA_mem;
469: {
470: int slot;
471: struct VgaRegs *VgaTextRegs;
472:
473: /* See if VGA already in TEXT mode - exit if so! */
474: outb(0x3CE, 0x06);
475: if ((inb(0x3CF) & 0x01) == 0) return;
476:
477: /* If no VGA responding in text mode, then we have some work to do... */
478: slot = scanPCI(); /* find video card in use */
479: enablePCIvideo(slot); /* enable I/O to card */
480:
481: /*
482: * Note: the PCI scanning code does not yet work correctly
483: * for non-Moto boxes, so the switch below only
484: * defaults to using an S3 card if it does not
485: * find a Cirrus card.
486: *
487: * The only reason we need to scan the bus looking for
488: * a graphics card is so we could do the "enablePCIvideo(slot)"
489: * call above; it is needed because Moto's OpenFirmware
490: * disables I/O to the graphics adapter before it gives
491: * us control. PEK'97
492: */
493:
494: switch (PCIVendor(slot)) {
495: default: /* Assume S3 */
496: /* case(S3Vendor): */
497: unlockS3();
498: VgaTextRegs = S3TextRegs;
499: outw(0x3C4, 0x0120); /* disable video */
500: setTextRegs(VgaTextRegs); /* initial register setup */
501: setTextCLUT(); /* load color lookup table */
502: loadFont(ISA_mem); /* load font */
503: setTextRegs(VgaTextRegs); /* reload registers */
504: outw(0x3C4, 0x0100); /* re-enable video */
505: outb(0x3c2, 0x63); /* MISC */
506: outb(0x3c2, 0x67); /* MISC */
507: break;
508:
509: case(CirrusVendor):
510: VgaTextRegs = GenVgaTextRegs;
511: outw(0x3C4, 0x0612); /* unlock ext regs */
512: outw(0x3C4, 0x0700); /* reset ext sequence mode */
513: outw(0x3C4, 0x0120); /* disable video */
514: setTextRegs(VgaTextRegs); /* initial register setup */
515: setTextCLUT(); /* load color lookup table */
516: loadFont(ISA_mem); /* load font */
517: setTextRegs(VgaTextRegs); /* reload registers */
518: outw(0x3C4, 0x0100); /* re-enable video */
519: outb(0x3c2, 0x63); /* MISC */
520: break;
521:
522: case (DiamondVendor):
523: case (MatroxVendor):
524: /*
525: * The following code is almost enuf to get the Matrox
526: * working (on a Moto box) but the video is not stable.
527: * We probably need to tweak the TVP3026 Video PLL regs. PEK'97
528: */
529: VgaTextRegs = GenVgaTextRegs;
530: outw(0x3C4, 0x0120); /* disable video */
531: setTextRegs(VgaTextRegs); /* initial register setup */
532: setTextCLUT(); /* load color lookup table */
533: loadFont(ISA_mem); /* load font */
534: setTextRegs(VgaTextRegs); /* reload registers */
535: outw(0x3C4, 0x0100); /* re-enable video */
536: outb(0x3c2, 0x63); /* MISC */
537: printf("VGA Chip Vendor ID: 0x%08x\n", PCIVendor(slot));
538: delayLoop(1);
539: break;
540: };
541:
542:
543: #ifdef DEBUG
544: printslots();
545: delayLoop(5);
546: #endif
547:
548: delayLoop(2); /* give time for the video monitor to come up */
549: }
550:
551: /*
552: * Write to VGA Attribute registers.
553: */
554: void
555: writeAttr(index, data, videoOn)
556: u_char index;
557: u_char data;
558: u_char videoOn; /* video on flag */
559: {
560: u_char v;
561: v = inb(0x3da); /* reset attr. address toggle */
562: if (videoOn)
563: outb(0x3c0, (index & 0x1F) | 0x20);
564: else
565: outb(0x3c0, (index & 0x1F));
566: outb(0x3c0, data);
567: }
568:
569: void
570: setTextRegs(svp)
571: struct VgaRegs *svp;
572: {
573: int i;
574:
575: /*
576: * saved settings
577: */
578: while (svp->io_port != ENDMK) {
579: outb(svp->io_port, svp->io_index);
580: outb(svp->io_port+1, svp->io_value);
581: svp++;
582: }
583:
584: outb(0x3c2, 0x67); /* MISC */
585: outb(0x3c6, 0xff); /* MASK */
586:
587: for (i = 0; i < 0x10; i++)
588: writeAttr(i, AC[i], 0); /* pallete */
589: writeAttr(0x10, 0x0c, 0); /* text mode */
590: writeAttr(0x11, 0x00, 0); /* overscan color (border) */
591: writeAttr(0x12, 0x0f, 0); /* plane enable */
592: writeAttr(0x13, 0x08, 0); /* pixel panning */
593: writeAttr(0x14, 0x00, 1); /* color select; video on */
594: }
595:
596: void
597: setTextCLUT()
598: {
599: int i;
600:
601: outb(0x3C6, 0xFF);
602: i = inb(0x3C7);
603: outb(0x3C8, 0);
604: i = inb(0x3C7);
605:
606: for (i = 0; i < 256; i++) {
607: outb(0x3C9, TextCLUT[i].r);
608: outb(0x3C9, TextCLUT[i].g);
609: outb(0x3C9, TextCLUT[i].b);
610: }
611: }
612:
613: void
614: loadFont(ISA_mem)
615: u_char *ISA_mem;
616: {
617: int i, j;
618: u_char *font_page = (u_char *)&ISA_mem[0xA0000];
619:
620: outb(0x3C2, 0x67);
621: /*
622: * Load font
623: */
624: i = inb(0x3DA); /* Reset Attr toggle */
625:
626: outb(0x3C0,0x30);
627: outb(0x3C0, 0x01); /* graphics mode */
628:
629: outw(0x3C4, 0x0001); /* reset sequencer */
630: outw(0x3C4, 0x0204); /* write to plane 2 */
631: outw(0x3C4, 0x0406); /* enable plane graphics */
632: outw(0x3C4, 0x0003); /* reset sequencer */
633: outw(0x3CE, 0x0402); /* read plane 2 */
634: outw(0x3CE, 0x0500); /* write mode 0, read mode 0 */
635: outw(0x3CE, 0x0605); /* set graphics mode */
636:
637: for (i = 0; i < sizeof(font); i += 16) {
638: for (j = 0; j < 16; j++) {
1.2 perry 639: __asm volatile("eieio");
1.1 nonaka 640: font_page[(2*i)+j] = font[i+j];
641: }
642: }
643: }
644:
645: void
646: unlockS3()
647: {
648: /* From the S3 manual */
649: outb(0x46E8, 0x10); /* Put into setup mode */
650: outb(0x3C3, 0x10);
651: outb(0x102, 0x01); /* Enable registers */
652: outb(0x46E8, 0x08); /* Enable video */
653: outb(0x3C3, 0x08);
654: outb(0x4AE8, 0x00);
655:
656: outb(0x42E8, 0x80); /* Reset graphics engine? */
657:
658: outb(0x3D4, 0x38); /* Unlock all registers */
659: outb(0x3D5, 0x48);
660: outb(0x3D4, 0x39);
661: outb(0x3D5, 0xA5);
662: outb(0x3D4, 0x40);
663: outb(0x3D5, inb(0x3D5)|0x01);
664: outb(0x3D4, 0x33);
665: outb(0x3D5, inb(0x3D5)&~0x52);
666: outb(0x3D4, 0x35);
667: outb(0x3D5, inb(0x3D5)&~0x30);
668: outb(0x3D4, 0x3A);
669: outb(0x3D5, 0x00);
670: outb(0x3D4, 0x53);
671: outb(0x3D5, 0x00);
672: outb(0x3D4, 0x31);
673: outb(0x3D5, inb(0x3D5)&~0x4B);
674: outb(0x3D4, 0x58);
675:
676: outb(0x3D5, 0);
677:
678: outb(0x3D4, 0x54);
679: outb(0x3D5, 0x38);
680: outb(0x3D4, 0x60);
681: outb(0x3D5, 0x07);
682: outb(0x3D4, 0x61);
683: outb(0x3D5, 0x80);
684: outb(0x3D4, 0x62);
685: outb(0x3D5, 0xA1);
686: outb(0x3D4, 0x69); /* High order bits for cursor address */
687: outb(0x3D5, 0);
688:
689: outb(0x3D4, 0x32);
690: outb(0x3D5, inb(0x3D5)&~0x10);
691: }
692:
693: /* ============ */
694:
695:
696: #define NSLOTS 8
697: #define NPCIREGS 5
698:
699: /*
700: * should use devfunc number/indirect method to be totally safe on
701: * all machines, this works for now on 3 slot Moto boxes
702: */
703:
704: struct PCI_ConfigInfo {
705: u_long * config_addr;
706: u_long regs[NPCIREGS];
707: } PCI_slots [NSLOTS] = {
708: { (u_long *)0x80808000, { 0xDE, 0xAD, 0xBE, 0xEF } },
709: { (u_long *)0x80800800, { 0xDE, 0xAD, 0xBE, 0xEF } },
710: { (u_long *)0x80801000, { 0xDE, 0xAD, 0xBE, 0xEF } },
711: { (u_long *)0x80802000, { 0xDE, 0xAD, 0xBE, 0xEF } },
712: { (u_long *)0x80804000, { 0xDE, 0xAD, 0xBE, 0xEF } },
713: { (u_long *)0x80810000, { 0xDE, 0xAD, 0xBE, 0xEF } },
714: { (u_long *)0x80820000, { 0xDE, 0xAD, 0xBE, 0xEF } },
715: { (u_long *)0x80840000, { 0xDE, 0xAD, 0xBE, 0xEF } }
716: };
717:
718:
719: /*
720: * The following code modifies the PCI Command register
721: * to enable memory and I/O accesses.
722: */
723: void
724: enablePCIvideo(slot)
725: int slot;
726: {
727: volatile u_char * ppci;
728:
729: ppci = (u_char *)PCI_slots[slot].config_addr;
730: ppci[4] = 0x0003; /* enable memory and I/O accesses */
1.2 perry 731: __asm volatile("eieio");
1.1 nonaka 732:
733: outb(0x3d4, 0x11);
734: outb(0x3d5, 0x0e); /* unlock CR0-CR7 */
735: }
736:
737: #define DEVID 0
738: #define CMD 1
739: #define CLASS 2
740: #define MEMBASE 4
741:
742: int
743: scanPCI()
744: {
745: int slt, r;
746: struct PCI_ConfigInfo *pslot;
747: int theSlot = -1;
748: int highVgaSlot = -1;
749:
750: for (slt = 0; slt < NSLOTS; slt++) {
751: pslot = &PCI_slots[slt];
752: for (r = 0; r < NPCIREGS; r++) {
753: pslot->regs[r] = bswap32(pslot->config_addr[r]);
754: }
755:
756: if (pslot->regs[DEVID] != 0xFFFFFFFF) { /* card in slot ? */
757: if ((pslot->regs[CLASS] & 0xFFFFFF00) == 0x03000000) { /* VGA ? */
758: highVgaSlot = slt;
759: if ((pslot->regs[CMD] & 0x03)) { /* did firmware enable it ? */
760: theSlot = slt;
761: }
762: }
763: }
764: }
765:
766: if (theSlot == -1)
767: theSlot = highVgaSlot;
768:
769: return (theSlot);
770: }
771:
772: int
773: delayLoop(k)
774: int k;
775: {
776: volatile int a, b;
777: volatile int i, j;
778: a = 0;
779: do {
780: for (i = 0; i < 500; i++) {
781: b = i;
782: for (j = 0; j < 200; j++) {
783: a = b+j;
784: }
785: }
786: } while (k--);
787: return(a);
788: }
789:
790: /* return Vendor ID of card in the slot */
791: static
792: int PCIVendor(slotnum)
793: int slotnum;
794: {
795: struct PCI_ConfigInfo *pslot;
796:
797: pslot = &PCI_slots[slotnum];
798:
799: return (pslot->regs[DEVID] & 0xFFFF);
800: }
801:
802: #ifdef DEBUG
803: static
804: void
805: printslots()
806: {
807: int i;
808: for (i = 0; i < NSLOTS; i++) {
809:
810: printf("PCI Slot number: %d", i);
811: printf(" Vendor ID: 0x%08x\n", PCIVendor(i));
812: }
813: }
814: #endif /* DEBUG */
815: #endif /* CONS_VGA */
CVSweb <webmaster@jp.NetBSD.org>