|
|
1.1 root 1: /*
2: * KMC11 microprocessor driver
3: * quasi-general-purpose:
4: * the code here is for downloading and controlling the kmc
5: * dealing with particular downloaded code
6: * will usually mean writing another driver
7: * which, alas, must generally have magic knowledge of
8: * struct kmc and the device registers
9: *
10: * the caller is expected to fill in
11: * k_rint, k_xint, k_reset if it cares
12: */
13:
14: #define lobyte(X) (((unsigned char *)&X)[0])
15: #define hibyte(X) (((unsigned char *)&X)[1])
16:
17: #include "sys/param.h"
18: #include "sys/kmc.h"
19: #include "sys/ubaddr.h"
20: #include "sys/conf.h"
21: #include "sys/user.h"
22:
23: extern struct kmc kmc[];
24: extern struct ubaddr kmcaddr[];
25: extern int kmccnt;
26:
27: #define KMC11A 1
28: #define KMC11B 2
29: #define KASIZE 1024
30: #define KBSIZE 4096
31:
32: #define RUN (1<<7)
33: #define MCLR (1<<6)
34: #define CWRT (1<<5)
35: #define LUB (1<<4)
36: #define LUA (1<<3)
37: #define ROMO (1<<2)
38: #define ROMI (1<<1)
39: #define STEP (1<<0)
40:
41: #define RDYO 0200
42: #define RDYI 020
43: #define RQI 0200
44: #define IEI 01
45: #define IEO 020
46:
47: #define STYPE 017
48: #define SRUN 020
49: #define SRINT 040
50: #define SOPEN 0100
51:
52: struct device {
53: union {
54: char b[8];
55: u_short w[4];
56: } un;
57: };
58:
59: #define bsel0 un.b[0]
60: #define bsel1 un.b[1]
61: #define bsel2 un.b[2]
62: #define bsel3 un.b[3]
63: #define bsel4 un.b[4]
64: #define bsel5 un.b[5]
65: #define bsel6 un.b[6]
66: #define bsel7 un.b[7]
67: #define sel0 un.w[0]
68: #define sel2 un.w[1]
69: #define sel4 un.w[2]
70: #define sel6 un.w[3]
71:
72: int kmcopen(), kmcclose(), kmcread(), kmcwrite(), kmcioctl();
73: struct cdevsw kmccdev = cdinit(kmcopen, kmcclose, kmcread, kmcwrite, kmcioctl);
74:
75: kmcopen(dev, flag)
76: dev_t dev;
77: { register struct device *kp;
78: register struct kmc *tp;
79: register sav;
80:
81: dev = minor(dev);
82: if (dev>=kmccnt || (tp = &kmc[dev])->k_stat&SOPEN) {
83: u.u_error = ENXIO;
84: return;
85: }
86: if ((kp = (struct device *)ubaddr(&kmcaddr[dev])) == 0
87: || ubbadaddr(kmcaddr[dev].ubno, kp, sizeof(short))) {
88: printf("kmc%d absent\n", dev);
89: u.u_error = ENXIO;
90: return;
91: }
92: tp->k_addr = kp;
93: tp->k_written = 0;
94: tp->k_stat |= SOPEN;
95: if (tp->k_type==0) {
96: kp->bsel1 = ROMO;
97: kp->sel4 = 0;
98: sav = kp->sel6;
99: kp->sel6 = ~sav;
100: if (kp->sel6 != sav) {
101: tp->k_type = KMC11B;
102: kp->sel6 = sav;
103: } else
104: tp->k_type = KMC11A;
105: kp->bsel1 = 0;
106: }
107: }
108:
109: kmcclose(dev)
110: dev_t dev;
111: {
112: register struct kmc *tp;
113:
114: tp = &kmc[minor(dev)];
115: tp->k_stat &= ~SOPEN;
116: if (tp->k_written && tp->k_reset)
117: (*tp->k_reset)(minor(dev));
118: }
119:
120: kmcread(dev)
121: register dev_t dev;
122: { register struct device *kp;
123: register ad;
124: int dsize;
125: u_short sav;
126:
127: dev = minor(dev);
128: if (kmc[dev].k_stat&SRUN)
129: return;
130: dsize = (kmc[dev].k_type==KMC11A)?KASIZE:KBSIZE;
131: kp = kmc[dev].k_addr;
132: kp->bsel1 = 0;
133: do {
134: ad = Ltol(u.u_offset);
135: if (ad<dsize*2) {
136: if (ad&1) {
137: u.u_error = ENXIO;
138: break;
139: }
140: ad >>= 1;
141: kp->bsel1 = ROMO;
142: kp->sel4 = ad;
143: passc(kp->bsel6);
144: passc(kp->bsel7);
145: kp->bsel1 = 0;
146: } else if (ad -= dsize*2, ad<dsize) {
147: kp->bsel1 = ROMO;
148: kp->sel4 = 0;
149: sav = kp->sel6;
150: kp->bsel1 = ROMI;
151: kp->sel6 = 010000|(ad&0377); /* mov ad,mar */
152: kp->bsel1 = ROMI|STEP;
153: kp->bsel1 = ROMI;
154: kp->sel6 = 04000|((ad>>8)&0377); /* mov %ad,%mar */
155: kp->bsel1 = ROMI|STEP;
156: kp->bsel1 = ROMI;
157: kp->sel6 = 055222; /* mov mem,csr2|mar++ */
158: kp->bsel1 = ROMI|STEP;
159: passc(kp->bsel2);
160: kp->bsel1 = ROMI;
161: kp->sel6 = sav;
162: kp->bsel1 = 0;
163: } else
164: break;
165: } while (u.u_error==0 && u.u_count);
166: }
167:
168: kmcwrite(dev)
169: register dev_t dev;
170: { register struct device *kp;
171: register ad;
172: int dsize;
173: short ins;
174: u_short sav;
175:
176: dev = minor(dev);
177: if (kmc[dev].k_stat&SRUN)
178: return;
179: dsize = (kmc[dev].k_type==KMC11A)?KASIZE:KBSIZE;
180: kp = kmc[dev].k_addr;
181: kp->bsel1 = 0;
182: kmc[dev].k_written = 1;
183: while (u.u_error==0 && u.u_count) {
184: ad = Ltol(u.u_offset);
185: if (ad<dsize*2) {
186: if (ad&1) {
187: u.u_error = ENXIO;
188: break;
189: }
190: kp->bsel1 = ROMO;
191: kp->sel4 = ad>>1;
192: lobyte(ins) = cpass();
193: hibyte(ins) = cpass();
194: kp->sel6 = ins;
195: kp->bsel1 |= CWRT;
196: kp->bsel1 = 0;
197: } else if (ad -= dsize*2, ad<dsize) {
198: kp->bsel1 = ROMO;
199: kp->sel4 = 0;
200: sav = kp->sel6;
201: kp->bsel1 = ROMI;
202: kp->sel6 = 010000|(ad&0377); /* mov ad,mar */
203: kp->bsel1 = ROMI|STEP;
204: kp->bsel1 = ROMI;
205: kp->sel6 = 04000|((ad>>8)&0377); /* mov %ad,%mar */
206: kp->bsel1 = ROMI|STEP;
207: kp->bsel1 = ROMI;
208: kp->bsel2 = cpass();
209: kp->sel6 = 0136440; /* mov csr2,mem|mar++ */
210: kp->bsel1 = ROMI|STEP;
211: kp->bsel1 = ROMI;
212: kp->sel6 = sav;
213: kp->bsel1 = 0;
214: } else
215: break;
216: }
217: }
218:
219: kmcioctl(dev, cmd, arg, mode)
220: caddr_t arg;
221: register dev_t dev;
222: { register struct device *kp;
223: register struct kmc *tp;
224: struct kmcntl kk;
225: short csr[4];
226: u_short sav;
227:
228: dev = minor(dev);
229: if (cmd != KCSETA) {
230: u.u_error = EINVAL;
231: return;
232: }
233: if (copyin(arg, &kk, sizeof(kk))) {
234: u.u_error = EFAULT;
235: return;
236: }
237: tp = &kmc[dev];
238: kp = tp->k_addr;
239: switch (kk.kmd) {
240: case KMCLR:
241: case KRESET:
242: spl7();
243: kp->bsel1 = MCLR;
244: spl0();
245: case KSTOP:
246: tp->k_stat &= ~SRUN;
247: kp->bsel1 = 0;
248: if (kk.kmd == KRESET) {
249: tp->k_stat = 0;
250: /* flush here */
251: }
252: return;
253: case KMS:
254: if (tp->k_stat&SRUN)
255: break;
256: kp->bsel1 = ROMI|ROMO;
257: sav = kp->sel6;
258: kp->bsel1 = ROMI;
259: kp->sel6 = kk.kval;
260: kp->bsel1 = ROMI|STEP;
261: kp->bsel1 = ROMI;
262: kp->sel6 = sav;
263: kp->bsel1 = 0;
264: goto lcsr;
265: case KSTEP:
266: if (tp->k_stat&SRUN)
267: break;
268: kp->bsel1 |= STEP;
269: kp->bsel1 = 0;
270: case KCSR:
271: lcsr:
272: csr[0] = kp->sel0;
273: csr[1] = kp->sel2;
274: csr[2] = kp->sel4;
275: csr[3] = kp->sel6;
276: if (copyout(csr, kk.kcsr, sizeof csr))
277: u.u_error = EFAULT;
278: return;
279: case KWRCR:
280: if (tp->k_stat&SRINT)
281: break;
282: kp->sel6 = kk.kval;
283: return;
284: case KRUN:
285: if (tp->k_stat&SRUN)
286: break;
287: tp->k_stat &= ~STYPE;
288: tp->k_stat |= (kk.kval&STYPE)|SRUN;
289: kp->bsel1 |= RUN;
290: if (tp->k_stat&SRINT) {
291: spl5();
292: kmc0int(dev);
293: spl0();
294: }
295: return;
296: case KLU:
297: kp->bsel1 = kk.kval&(LUA|LUB);
298: return;
299: }
300: u.u_error = EIO;
301: }
302:
303: kmc0int(dev)
304: {
305: register int (*p)();
306:
307: if ((p = kmc[dev].k_rint) != 0)
308: (*p)(dev);
309: }
310:
311: kmc1int(dev)
312: {
313: register int (*p)();
314:
315: if ((p = kmc[dev].k_xint) != 0)
316: (*p)(dev);
317: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.