|
|
1.1 root 1: /*
2: * KMC11 microprocessor driver
3: */
4: #include "kmc.h"
5: #if NKMC > 0
6: /* this driver supports ONE kmc ONLY */
7: /* it should be modified to support only kmc11b's too */
8:
9: /* nonstandard crap */
10: typedef unsigned short ushort;
11: #define lobyte(X) (((unsigned char *)&X)[0])
12: #define hibyte(X) (((unsigned char *)&X)[1])
13:
14: #include "../h/param.h"
15: #include "../h/systm.h"
16: #include "../h/kmc.h"
17: #include "../h/pte.h"
18: #include "../h/map.h"
19: #include "../h/buf.h"
20: #include "../h/ubareg.h"
21: #include "../h/ubavar.h"
22: #include "../h/conf.h"
23: #include "../h/dir.h"
24: #include "../h/user.h"
25:
26: struct kmc {
27: char k_stat;
28: char k_type;
29: } kmc[NKMC];
30:
31: #define KMC11A 1
32: #define KMC11B 2
33: #define KASIZE 1024
34: #define KBSIZE 4096
35:
36: #define RUN (1<<7)
37: #define MCLR (1<<6)
38: #define CWRT (1<<5)
39: #define LUB (1<<4)
40: #define LUA (1<<3)
41: #define ROMO (1<<2)
42: #define ROMI (1<<1)
43: #define STEP (1<<0)
44:
45: #define RDYO 0200
46: #define RDYI 020
47: #define RQI 0200
48: #define IEI 01
49: #define IEO 020
50:
51: #define STYPE 017
52: #define SRUN 020
53: #define SRINT 040
54: #define SOPEN 0100
55:
56: struct device {
57: union {
58: char b[8];
59: ushort w[4];
60: } un;
61: };
62:
63: #define bsel0 un.b[0]
64: #define bsel1 un.b[1]
65: #define bsel2 un.b[2]
66: #define bsel3 un.b[3]
67: #define bsel4 un.b[4]
68: #define bsel5 un.b[5]
69: #define bsel6 un.b[6]
70: #define bsel7 un.b[7]
71: #define sel0 un.w[0]
72: #define sel2 un.w[1]
73: #define sel4 un.w[2]
74: #define sel6 un.w[3]
75:
76: int kmcwritten;
77: int kmcprobe(), kmcattach(), kmcxint();
78: struct uba_device *kmcdinfo[NKMC];
79: unsigned short kmcstd[] = { 0};
80: struct uba_driver kmcdriver = {
81: kmcprobe, 0, kmcattach, 0, kmcstd, "kmc", kmcdinfo
82: };
83:
84: int (*kdirint)();
85: int (*kdixint)();
86:
87: kmcprobe(reg)
88: caddr_t reg;
89: { register int br, cvec; /* don't touch */
90: register struct device *kp = (struct device *)reg;
91: register s;
92:
93: #ifdef lint
94: br = 0; cvec = br; br = cvec;
95: #endif
96: s = spl7();
97: kp->bsel1 = MCLR;
98: splx(s);
99: kp->bsel1 = ROMI;
100: kp->sel4 = 0200; /* bus request */
101: kp->sel6 = 0121111; /* mov csr4,obr */
102: kp->bsel1 = ROMI|STEP;
103: DELAY(50);
104: kp->bsel1 = 0;
105: return(1);
106: }
107:
108: kmcattach(ui)
109: register struct uba_device *ui;
110: {}
111:
112: kmcopen(dev, flag)
113: dev_t dev;
114: { register struct device *kp;
115: register struct kmc *tp;
116: register sav;
117:
118: dev = minor(dev);
119: if (dev>=NKMC || (tp = &kmc[dev])->k_stat&SOPEN) {
120: u.u_error = ENXIO;
121: return;
122: }
123: kmcwritten = 0;
124: tp->k_stat |= SOPEN;
125: if (tp->k_type==0) {
126: kp = ((struct device *)kmcdinfo[dev]->ui_addr);
127: kp->bsel1 = ROMO;
128: kp->sel4 = 0;
129: sav = kp->sel6;
130: kp->sel6 = ~sav;
131: if (kp->sel6 != sav) {
132: tp->k_type = KMC11B;
133: kp->sel6 = sav;
134: } else
135: tp->k_type = KMC11A;
136: kp->bsel1 = 0;
137: }
138: }
139:
140: kmcclose(dev)
141: dev_t dev;
142: {
143: dev = minor(dev);
144: if(dev >= NKMC)
145: return;
146: kmc[dev].k_stat &= ~SOPEN;
147: if (kmcwritten)
148: kdireload();
149: }
150:
151: kmcread(dev)
152: dev_t dev;
153: { register struct device *kp;
154: register ad;
155: int dsize;
156: ushort sav;
157:
158: dev = minor(dev);
159: if(dev >= NKMC) {
160: u.u_error = ENXIO;
161: return;
162: }
163: if (kmc[dev].k_stat&SRUN)
164: return;
165: dsize = (kmc[dev].k_type==KMC11A)?KASIZE:KBSIZE;
166: kp = ((struct device *)kmcdinfo[dev]->ui_addr);
167: kp->bsel1 = 0;
168: do {
169: ad = u.u_offset;
170: if (ad<dsize*2) {
171: if (ad&1) {
172: u.u_error = ENXIO;
173: break;
174: }
175: ad >>= 1;
176: kp->bsel1 = ROMO;
177: kp->sel4 = ad;
178: passc(kp->bsel6);
179: passc(kp->bsel7);
180: kp->bsel1 = 0;
181: } else if (ad -= dsize*2, ad<dsize) {
182: kp->bsel1 = ROMO;
183: kp->sel4 = 0;
184: sav = kp->sel6;
185: kp->bsel1 = ROMI;
186: kp->sel6 = 010000|(ad&0377); /* mov ad,mar */
187: kp->bsel1 = ROMI|STEP;
188: kp->bsel1 = ROMI;
189: kp->sel6 = 04000|((ad>>8)&0377); /* mov %ad,%mar */
190: kp->bsel1 = ROMI|STEP;
191: kp->bsel1 = ROMI;
192: kp->sel6 = 055222; /* mov mem,csr2|mar++ */
193: kp->bsel1 = ROMI|STEP;
194: passc(kp->bsel2);
195: kp->bsel1 = ROMI;
196: kp->sel6 = sav;
197: kp->bsel1 = 0;
198: } else
199: break;
200: } while (u.u_error==0 && u.u_count);
201: }
202:
203: kmcwrite(dev)
204: dev_t dev;
205: { register struct device *kp;
206: register ad;
207: int dsize;
208: short ins;
209: ushort sav;
210:
211: dev = minor(dev);
212: if(dev >= NKMC) {
213: u.u_error = ENXIO;
214: return;
215: }
216: if (kmc[dev].k_stat&SRUN)
217: return;
218: dsize = (kmc[dev].k_type==KMC11A)?KASIZE:KBSIZE;
219: kp = ((struct device *)kmcdinfo[dev]->ui_addr);
220: kp->bsel1 = 0;
221: kmcwritten = 1;
222: while (u.u_error==0 && u.u_count) {
223: ad = u.u_offset;
224: if (ad<dsize*2) {
225: if (ad&1) {
226: u.u_error = ENXIO;
227: break;
228: }
229: kp->bsel1 = ROMO;
230: kp->sel4 = ad>>1;
231: lobyte(ins) = cpass();
232: hibyte(ins) = cpass();
233: kp->sel6 = ins;
234: kp->bsel1 |= CWRT;
235: kp->bsel1 = 0;
236: } else if (ad -= dsize*2, ad<dsize) {
237: kp->bsel1 = ROMO;
238: kp->sel4 = 0;
239: sav = kp->sel6;
240: kp->bsel1 = ROMI;
241: kp->sel6 = 010000|(ad&0377); /* mov ad,mar */
242: kp->bsel1 = ROMI|STEP;
243: kp->bsel1 = ROMI;
244: kp->sel6 = 04000|((ad>>8)&0377); /* mov %ad,%mar */
245: kp->bsel1 = ROMI|STEP;
246: kp->bsel1 = ROMI;
247: kp->bsel2 = cpass();
248: kp->sel6 = 0136440; /* mov csr2,mem|mar++ */
249: kp->bsel1 = ROMI|STEP;
250: kp->bsel1 = ROMI;
251: kp->sel6 = sav;
252: kp->bsel1 = 0;
253: } else
254: break;
255: }
256: }
257:
258: kmcioctl(dev, cmd, arg, mode)
259: caddr_t arg;
260: dev_t dev;
261: { register struct device *kp;
262: register struct kmc *tp;
263: struct kmcntl kk;
264: short csr[4];
265: ushort sav;
266:
267: dev = minor(dev);
268: if (cmd != KCSETA) {
269: u.u_error = EINVAL;
270: return;
271: }
272: if(dev >= NKMC) {
273: u.u_error = ENXIO;
274: return;
275: }
276: if (copyin(arg, &kk, sizeof(kk))) {
277: u.u_error = EFAULT;
278: return;
279: }
280: kp = ((struct device *)kmcdinfo[dev]->ui_addr);
281: tp = &kmc[dev];
282: switch (kk.kmd) {
283: case KMCLR:
284: case KRESET:
285: spl7();
286: kp->bsel1 = MCLR;
287: spl0();
288: case KSTOP:
289: tp->k_stat &= ~SRUN;
290: kp->bsel1 = 0;
291: if (kk.kmd == KRESET) {
292: tp->k_stat = 0;
293: /* flush here */
294: }
295: return;
296: case KMS:
297: if (tp->k_stat&SRUN)
298: break;
299: kp->bsel1 = ROMI|ROMO;
300: sav = kp->sel6;
301: kp->bsel1 = ROMI;
302: kp->sel6 = kk.kval;
303: kp->bsel1 = ROMI|STEP;
304: kp->bsel1 = ROMI;
305: kp->sel6 = sav;
306: kp->bsel1 = 0;
307: goto lcsr;
308: case KSTEP:
309: if (tp->k_stat&SRUN)
310: break;
311: kp->bsel1 |= STEP;
312: kp->bsel1 = 0;
313: case KCSR:
314: lcsr:
315: csr[0] = kp->sel0;
316: csr[1] = kp->sel2;
317: csr[2] = kp->sel4;
318: csr[3] = kp->sel6;
319: if (copyout(csr, kk.kcsr, sizeof csr))
320: u.u_error = EFAULT;
321: return;
322: case KWRCR:
323: if (tp->k_stat&SRINT)
324: break;
325: kp->sel6 = kk.kval;
326: return;
327: case KRUN:
328: if (tp->k_stat&SRUN)
329: break;
330: tp->k_stat &= ~STYPE;
331: tp->k_stat |= (kk.kval&STYPE)|SRUN;
332: kp->bsel1 |= RUN;
333: if (tp->k_stat&SRINT) {
334: spl5();
335: kmcrint(dev);
336: spl0();
337: }
338: return;
339: case KLU:
340: kp->bsel1 = kk.kval&(LUA|LUB);
341: return;
342: }
343: u.u_error = EIO;
344: }
345:
346: kmcrint(dev)
347: dev_t dev;
348: {
349: if (kdirint)
350: (*kdirint)();
351: }
352:
353: kmcxint(dev)
354: {
355: if (kdixint)
356: (*kdixint)();
357: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.