|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)bwtwo.c 1.1 86/02/03 Copyr 1985 Sun Micro";
3: #endif
4:
5: /*
6: * Copyright (c) 1986 by Sun Microsystems, Inc.
7: */
8:
9: /*
10: * Sun Two Black & White Board(s) Driver
11: */
12:
13: #include "bwtwo.h"
14:
15: #include "../h/param.h"
16: #include "../h/systm.h"
17: #include "../h/dir.h"
18: #include "../h/user.h"
19: #include "../h/proc.h"
20: #include "../h/buf.h"
21: #include "../h/conf.h"
22: #include "../h/file.h"
23: #include "../h/map.h"
24: #include "../h/vmmac.h"
25:
26: #include "../sun/fbio.h"
27:
28: #include "../machine/pte.h"
29: #include "../machine/mmu.h"
30: #include "../machine/cpu.h"
31:
32: #include "../sundev/mbvar.h"
33: #include "../sundev/bw2reg.h"
34:
35: #ifdef sun3
36: #include "../sun3/eeprom.h"
37: #endif sun3
38:
39: extern char CADDR1[];
40:
41: int copyenpfnum; /* pfnum before shadow memory mapped in */
42: caddr_t copyenvirt = 0; /* virtual address mapped to shadow memory */
43:
44: struct bw2_softc {
45: caddr_t image;
46: } bw2_softc[NBWTWO];
47:
48: #define BW2SIZEX 1152
49: #define BW2SIZEY 900
50: #define BW2SQUARESIZEX 1024
51: #define BW2SQUARESIZEY 1024
52:
53: /*
54: * Driver information for auto-configuration stuff.
55: */
56: int bwtwoprobe(), bwtwoattach(), bwtwointr();
57: struct mb_device *bwtwoinfo[NBWTWO];
58: struct mb_driver bwtwodriver = {
59: bwtwoprobe, 0, bwtwoattach, 0, 0, bwtwointr,
60: sizeof (struct bw2dev) + CLBYTES /* XXX */, "bwtwo", bwtwoinfo, 0, 0, 0,
61: };
62:
63: /*
64: * Only allow opens for writing or reading and writing
65: * because reading is nonsensical.
66: */
67: bwtwoopen(dev, flag)
68: dev_t dev;
69: {
70:
71: fbopen(dev, flag, NBWTWO, bwtwoinfo);
72: }
73:
74: bwtwoclose(dev, flag)
75: dev_t dev;
76: {
77: }
78:
79: /*ARGSUSED*/
80: bwtwommap(dev, off, prot)
81: dev_t dev;
82: off_t off;
83: int prot;
84: {
85: register caddr_t hold;
86: register int unit = minor(dev);
87: int page;
88:
89: hold = bwtwoinfo[unit]->md_addr;
90: bwtwoinfo[unit]->md_addr = bw2_softc[unit].image;
91: page = fbmmap(dev, off, prot, NBWTWO, bwtwoinfo, BW2_FBSIZE);
92: bwtwoinfo[unit]->md_addr = hold;
93: return (page);
94: }
95:
96: /*
97: * Determine if a bwtwo exists at the given address.
98: */
99: /*ARGSUSED*/
100: bwtwoprobe(reg, unit)
101: caddr_t reg;
102: int unit;
103: {
104: #ifdef sun3
105: /*
106: * For the sun3 we have to rely on the machine type since the bits
107: * in the enable register may not be reliable.
108: */
109: int result;
110:
111: /*
112: * XXX - kludge used to get around current mem_rop bug.
113: * We need to have the page before the frame buffer to not have
114: * have any "holes" in them as the mem_rop code will sometimes
115: * access this page. We kludge here to avoid this problem by
116: * increasing the size of area to be mapped by adding CLBYTES
117: * to the device size mapped by the autoconfig code. Here
118: * we remap all but the first page so that the first page map
119: * entry is duplicated and then we bump the virtual address
120: * up by CLBYTES in bwtwoattach().
121: */
122: mapin(&Sysmap[btoc(reg + CLBYTES - KERNELBASE)],
123: (u_int)btoc(reg + CLBYTES),
124: ((*(u_int *)&Sysmap[btoc(reg - KERNELBASE)]) & PG_PFNUM),
125: btoc(BW2_FBSIZE), PG_V | PG_KW);
126:
127: switch (cpu) {
128: case CPU_SUN3_160:
129: result = BW2_FBSIZE;
130: break;
131: case CPU_SUN3_50:
132: result = BW2_FBSIZE;
133: break;
134: case CPU_SUN3_260:
135: result = 0;
136: break;
137: default:
138: result = 0;
139: break;
140: }
141: return (result);
142: #endif sun3
143: #ifdef sun2
144: struct bw2dev *bw2dev = (struct bw2dev *)(reg + CLBYTES); /* XXX */
145: register struct bw2cr *alias1;
146: register struct bw2cr *alias2;
147: short w1;
148: register short w2, wrestore;
149: int result = 0;
150:
151: /*
152: * XXX - kludge used to get around current mem_rop bug.
153: * We need to have the page before the frame buffer to not have
154: * have any "holes" in them as the mem_rop code will sometimes
155: * access this page. We kludge here to avoid this problem by
156: * increasing the size of area to be mapped by adding CLBYTES
157: * to the device size mapped by the autoconfig code. Here
158: * we remap all but the first page so that the first page map
159: * entry is duplicated and then we bump the virtual address
160: * up by CLBYTES above for bw2dev and in bwtwoattach().
161: */
162: mapin(&Sysmap[btoc(reg + CLBYTES - KERNELBASE)],
163: (u_int)btoc(reg + CLBYTES),
164: ((*(u_int *)&Sysmap[btoc(reg - KERNELBASE)]) & PG_PFNUM),
165: btoc(BW2_FBSIZE), PG_V | PG_KW);
166:
167: bw2crmapin(bw2dev);
168: alias1 = &bw2dev->bw2cr;
169: alias2 = alias1 + 1;
170:
171: /*
172: * Two adjacent shorts should be the same because
173: * the control register is replicated every 2 bytes
174: * throughout the control page.
175: */
176: if ((w1 = peek((short *)alias1)) == -1)
177: return (0);
178: wrestore = w1;
179: ((struct bw2cr *)&w1)->vc_copybase = 0xAA & BW2_COPYBASEMASK;
180: if (poke((short *)alias1, w1))
181: return (0);
182: if ((w2 = peek((short *)alias2)) == -1)
183: goto restore;
184: if (w1 != w2)
185: goto restore;
186: ((struct bw2cr *)&w1)->vc_copybase = ~0xAA & BW2_COPYBASEMASK;
187: if (poke((short *)alias1, w1))
188: goto restore;
189: if ((w2 = peek((short *)alias2)) == -1)
190: goto restore;
191: if (w1 != w2)
192: goto restore;
193: result = BW2_FBSIZE;
194: restore:
195: if (poke((short *)alias1, wrestore))
196: panic("bwtwoprobe");
197: return (result);
198: #endif sun2
199: }
200:
201: /*
202: * Set up the softc structure
203: */
204: bwtwoattach(md)
205: register struct mb_device *md;
206: {
207: #ifdef sun2
208: register struct bw2dev *bw2dev;
209: #endif
210: int pfnum;
211: caddr_t fbvirtaddr;
212: caddr_t v;
213: int i;
214:
215: /*
216: * XXX - Last part of mem_rop bug kludge, increase the virtual
217: * address set up by autoconfig by CLBYTES as we have remapped
218: * the first page to be a duplicate in bwtwoprobe().
219: */
220: md->md_addr += CLBYTES;
221:
222: pfnum = getkpgmap(md->md_addr) & PG_PFNUM;
223: #ifdef sun3
224: /*
225: * If we are on a SUN3_50 (Model 25), then we must
226: * reserve the on board memory for the frame buffer.
227: */
228: if (cpu == CPU_SUN3_50) {
229: if (fbobmemavail == 0)
230: panic("No video memory");
231: else
232: fbobmemavail = 0;
233: }
234: #endif sun3
235:
236: /*
237: * Have we passed this way before?
238: */
239: if (fbobmemavail == 0) {
240: if (copyenvirt == 0) {
241: copyenvirt = (caddr_t)(*romp->v_fbaddr);
242: if (pfnum == copyenpfnum)
243: bw2_softc[md->md_unit].image = copyenvirt;
244: else
245: bw2_softc[md->md_unit].image = md->md_addr;
246: }
247: return;
248: }
249:
250: /*
251: * We know that the copy memory can be used. Use the
252: * shadow memory if the config flags say to use it.
253: */
254: if ((md->md_flags & BW2_USECOPYMEM) == 0) {
255: /* don't bother using reserved shadow memory */
256: copyenvirt = md->md_addr;
257: bw2_softc[md->md_unit].image = md->md_addr;
258: return;
259: }
260:
261: /*
262: * Mark the onboard frame buffer memory as not available
263: * anymore as we are going to use it for copy memory.
264: */
265: fbobmemavail = 0;
266:
267: if (*romp->v_outsink != OUTSCREEN || *romp->v_fbtype != FBTYPE_SUN2BW)
268: fbvirtaddr = (caddr_t)md->md_addr;
269: else {
270: rmfree(kernelmap, (long)btoc(BW2_FBSIZE),
271: btokmx((struct pte *)(md->md_addr)));
272: mapout(&Usrptmap[btokmx((struct pte *)(md->md_addr))],
273: btoc(BW2_FBSIZE));
274: fbvirtaddr = (caddr_t)(*romp->v_fbaddr);
275: }
276: copyenvirt = fbvirtaddr;
277: copyenpfnum = getkpgmap(fbvirtaddr) & PG_PFNUM;
278:
279: /*
280: * Copy the current frame buffer memory
281: * to the copy memory as we map it in.
282: */
283: for (v = (caddr_t)fbvirtaddr, i = btop(OBFBADDR);
284: i < btop(OBFBADDR + BW2_FBSIZE); v += NBPG, i++) {
285: mapin(CMAP1, btop(CADDR1),
286: (u_int)(i | PGT_OBMEM), 1, PG_V | PG_KW);
287: bcopy(v, CADDR1, NBPG);
288: setpgmap(v, (long)(PG_V|PG_KW|PGT_OBMEM|i));
289: }
290:
291: #ifdef sun2
292: bw2dev = (struct bw2dev *)md->md_addr;
293: i = (OBFBADDR>>BW2_COPYSHIFT) | BW2_COPYENABLEMASK;
294: (void) bwtwosetcr(&bw2dev->bw2cr, i, 1);
295: #endif sun2
296: #ifdef sun3
297: setcopyenable();
298: #endif
299: if (pfnum == copyenpfnum)
300: bw2_softc[md->md_unit].image = copyenvirt;
301: else
302: bw2_softc[md->md_unit].image = md->md_addr;
303: }
304:
305: /*ARGSUSED*/
306: bwtwoioctl(dev, cmd, data, flag)
307: dev_t dev;
308: caddr_t data;
309: {
310: register int unit = minor(dev);
311:
312: switch (cmd) {
313:
314: case FBIOGTYPE: {
315: register struct fbtype *fb = (struct fbtype *)data;
316: #ifdef sun2
317: register struct bw2dev *bw2dev =
318: (struct bw2dev *)bwtwoinfo[unit]->md_addr;
319: #endif
320: fb->fb_type = FBTYPE_SUN2BW;
321: fb->fb_depth = 1;
322: fb->fb_cmsize = 2;
323: fb->fb_size = BW2_FBSIZE;
324: #ifdef sun3
325: /*
326: * Look at the eeprom for screen configuration,
327: * if unknown default to standard sizes.
328: */
329: switch (EEPROM->ee_diag.eed_scrsize) {
330: case EED_SCR_1024X1024:
331: fb->fb_height = BW2SQUARESIZEY;
332: fb->fb_width = BW2SQUARESIZEX;
333: break;
334:
335: case EED_SCR_1152X900:
336: default:
337: fb->fb_height = BW2SIZEY;
338: fb->fb_width = BW2SIZEX;
339: break;
340: }
341: #endif sun3
342: #ifdef sun2
343: /*
344: * Check for "square screen" jumper
345: */
346: if (cpu != CPU_SUN2_120 && bwtwoinfo[unit]->md_unit == 0 &&
347: bw2dev->bw2cr.vc_1024_jumper) {
348: fb->fb_height = BW2SQUARESIZEY;
349: fb->fb_width = BW2SQUARESIZEX;
350: } else {
351: fb->fb_height = BW2SIZEY;
352: fb->fb_width = BW2SIZEX;
353: }
354: #endif sun2
355: break;
356: }
357:
358: default:
359: u.u_error = ENOTTY;
360: }
361: }
362:
363: bwtwointr()
364: {
365: int bwtwointclear();
366:
367: return (fbintr(NBWTWO, bwtwoinfo, bwtwointclear));
368: }
369:
370: /*
371: * Turn off interrupts on bwtwo board.
372: */
373: #ifdef sun3
374: /*ARGSUSED*/
375: bwtwointclear(bw2dev)
376: struct bw2dev *bw2dev;
377: {
378:
379: (void) setintrenable(0);
380: return (0);
381: }
382: #endif sun3
383:
384: #ifdef sun2
385: bwtwointclear(bw2dev)
386: struct bw2dev *bw2dev;
387: {
388: int int_active;
389:
390: int_active = bw2dev->bw2cr.vc_int;
391: (void) setintrenable(&bw2dev->bw2cr);
392: return (int_active);
393: }
394:
395: setvideoenable(bw2cr)
396: struct bw2cr *bw2cr;
397: {
398:
399: bwtwosetcr(bw2cr, BW2_VIDEOENABLEMASK, 1);
400: }
401:
402: setintrenable(bw2cr)
403: struct bw2cr *bw2cr;
404: {
405:
406: bwtwosetcr(bw2cr, BW2_INTENABLEMASK, 0);
407: }
408:
409: /*
410: * Special access approach to video ctrl register needed because byte writes,
411: * generated when do bit writes, replicates itself on the subsequent byte as
412: * well (this is a hardware bug). Thus, we need to access the register as a
413: * word. Also these routines assume that only one bit changes at a time.
414: */
415: bwtwosetcr(bw2cr, mask, value)
416: struct bw2cr *bw2cr;
417: short mask;
418: int value;
419: {
420: register short w;
421:
422: /*
423: * Read word from video control register.
424: */
425: w = *((short *)bw2cr);
426: /*
427: * Modify bit as requested.
428: */
429: if (value)
430: w |= mask;
431: else
432: w &= ~mask;
433: /*
434: * Write word back to video control register.
435: */
436: *((short *)bw2cr) = w;
437: return;
438: }
439: #endif sun2
440:
441: #ifndef sun3
442: /*
443: * Given the video base virtual address,
444: * map in the control register address.
445: * This lets us handle minor implementation differences.
446: */
447: bw2crmapin(bw2dev)
448: struct bw2dev *bw2dev;
449: {
450: struct bw2cr *bw2cr = &bw2dev->bw2cr;
451: int pte = getkpgmap((caddr_t)bw2dev);
452: int page, delta;
453:
454: page = pte & PGT_MASK;
455:
456: if (page == PGT_OBMEM)
457: delta = (int)BW2MB_CR - (int)BW2MB_FB;
458: else if (page == PGT_OBIO)
459: delta = (int)BW2VME_CR - (int)BW2VME_FB;
460: else
461: panic("bwtwocraddr");
462:
463: mapin(&Sysmap[btoc((u_int)bw2cr - KERNELBASE)], btoc(bw2cr),
464: pte + btoc(delta), 1, PG_V | (pte & PG_PROT));
465: }
466: #endif !sun3
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.