Annotation of sys/arch/alpha/tc/tc_3000_300.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: tc_3000_300.c,v 1.12 2006/03/04 12:33:17 miod Exp $ */
2: /* $NetBSD: tc_3000_300.c,v 1.26 2001/07/27 00:25:21 thorpej Exp $ */
3:
4: /*
5: * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
6: * All rights reserved.
7: *
8: * Author: Chris G. Demetriou
9: *
10: * Permission to use, copy, modify and distribute this software and
11: * its documentation is hereby granted, provided that both the copyright
12: * notice and this permission notice appear in all copies of the
13: * software, derivative works or modified versions, and any portions
14: * thereof, and that both notices appear in supporting documentation.
15: *
16: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
17: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
18: * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
19: *
20: * Carnegie Mellon requests users of this software to return to
21: *
22: * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
23: * School of Computer Science
24: * Carnegie Mellon University
25: * Pittsburgh PA 15213-3890
26: *
27: * any improvements or extensions that they make and grant Carnegie the
28: * rights to redistribute these changes.
29: */
30:
31: #include <sys/param.h>
32: #include <sys/systm.h>
33: #include <sys/device.h>
34: #include <sys/malloc.h>
35:
36: #include <machine/autoconf.h>
37: #include <machine/pte.h>
38:
39: #include <dev/tc/tcvar.h>
40: #include <dev/tc/ioasicreg.h>
41: #include <alpha/tc/tc_conf.h>
42: #include <alpha/tc/tc_3000_300.h>
43:
44: #include "wsdisplay.h"
45: #include "sfb.h"
46:
47: #if NSFB > 0
48: extern int sfb_cnattach(tc_addr_t);
49: #endif
50:
51: int tc_3000_300_intrnull(void *);
52:
53: #define C(x) ((void *)(u_long)x)
54: #define KV(x) (ALPHA_PHYS_TO_K0SEG(x))
55:
56: /*
57: * We have to read and modify the IOASIC registers directly, because
58: * the TC option slot interrupt request and mask bits are stored there,
59: * and the ioasic code isn't initted when we need to frob some interrupt
60: * bits.
61: */
62: #define DEC_3000_300_IOASIC_ADDR KV(0x1a0000000)
63:
64: struct tc_slotdesc tc_3000_300_slots[] = {
65: { KV(0x100000000), C(TC_3000_300_DEV_OPT0), }, /* 0 - opt slot 0 */
66: { KV(0x120000000), C(TC_3000_300_DEV_OPT1), }, /* 1 - opt slot 1 */
67: { KV(0x140000000), C(TC_3000_300_DEV_BOGUS), }, /* 2 - unused */
68: { KV(0x160000000), C(TC_3000_300_DEV_BOGUS), }, /* 3 - unused */
69: { KV(0x180000000), C(TC_3000_300_DEV_BOGUS), }, /* 4 - TCDS ASIC */
70: { KV(0x1a0000000), C(TC_3000_300_DEV_BOGUS), }, /* 5 - IOCTL ASIC */
71: { KV(0x1c0000000), C(TC_3000_300_DEV_BOGUS), }, /* 6 - CXTurbo */
72: };
73: int tc_3000_300_nslots =
74: sizeof(tc_3000_300_slots) / sizeof(tc_3000_300_slots[0]);
75:
76: struct tc_builtin tc_3000_300_builtins[] = {
77: { "PMAGB-BA", 6, 0x02000000, C(TC_3000_300_DEV_CXTURBO), },
78: { "FLAMG-IO", 5, 0x00000000, C(TC_3000_300_DEV_IOASIC), },
79: { "PMAZ-DS ", 4, 0x00000000, C(TC_3000_300_DEV_TCDS), },
80: };
81: int tc_3000_300_nbuiltins =
82: sizeof(tc_3000_300_builtins) / sizeof(tc_3000_300_builtins[0]);
83:
84: struct tcintr {
85: int (*tci_func)(void *);
86: void *tci_arg;
87: struct evcount tci_count;
88: char tci_name[12];
89: } tc_3000_300_intr[TC_3000_300_NCOOKIES];
90:
91: void
92: tc_3000_300_intr_setup()
93: {
94: volatile u_int32_t *imskp;
95: u_long i;
96:
97: /*
98: * Disable all interrupts that we can (can't disable builtins).
99: */
100: imskp = (volatile u_int32_t *)(DEC_3000_300_IOASIC_ADDR + IOASIC_IMSK);
101: *imskp &= ~(IOASIC_INTR_300_OPT0 | IOASIC_INTR_300_OPT1);
102:
103: /*
104: * Set up interrupt handlers.
105: */
106: for (i = 0; i < TC_3000_300_NCOOKIES; i++) {
107: tc_3000_300_intr[i].tci_func = tc_3000_300_intrnull;
108: tc_3000_300_intr[i].tci_arg = (void *)i;
109: snprintf(tc_3000_300_intr[i].tci_name,
110: sizeof tc_3000_300_intr[i].tci_name, "tc slot %u", i);
111: evcount_attach(&tc_3000_300_intr[i].tci_count,
112: tc_3000_300_intr[i].tci_name, NULL, &evcount_intr);
113: }
114: }
115:
116: void
117: tc_3000_300_intr_establish(tcadev, cookie, level, func, arg)
118: struct device *tcadev;
119: void *cookie, *arg;
120: tc_intrlevel_t level;
121: int (*func)(void *);
122: {
123: volatile u_int32_t *imskp;
124: u_long dev = (u_long)cookie;
125:
126: #ifdef DIAGNOSTIC
127: /* XXX bounds-check cookie. */
128: #endif
129:
130: if (tc_3000_300_intr[dev].tci_func != tc_3000_300_intrnull)
131: panic("tc_3000_300_intr_establish: cookie %lu twice", dev);
132:
133: tc_3000_300_intr[dev].tci_func = func;
134: tc_3000_300_intr[dev].tci_arg = arg;
135:
136: imskp = (volatile u_int32_t *)(DEC_3000_300_IOASIC_ADDR + IOASIC_IMSK);
137: switch (dev) {
138: case TC_3000_300_DEV_OPT0:
139: *imskp |= IOASIC_INTR_300_OPT0;
140: break;
141: case TC_3000_300_DEV_OPT1:
142: *imskp |= IOASIC_INTR_300_OPT1;
143: break;
144: default:
145: /* interrupts for builtins always enabled */
146: break;
147: }
148: }
149:
150: void
151: tc_3000_300_intr_disestablish(tcadev, cookie)
152: struct device *tcadev;
153: void *cookie;
154: {
155: volatile u_int32_t *imskp;
156: u_long dev = (u_long)cookie;
157:
158: #ifdef DIAGNOSTIC
159: /* XXX bounds-check cookie. */
160: #endif
161:
162: if (tc_3000_300_intr[dev].tci_func == tc_3000_300_intrnull)
163: panic("tc_3000_300_intr_disestablish: cookie %lu bad intr",
164: dev);
165:
166: imskp = (volatile u_int32_t *)(DEC_3000_300_IOASIC_ADDR + IOASIC_IMSK);
167: switch (dev) {
168: case TC_3000_300_DEV_OPT0:
169: *imskp &= ~IOASIC_INTR_300_OPT0;
170: break;
171: case TC_3000_300_DEV_OPT1:
172: *imskp &= ~IOASIC_INTR_300_OPT1;
173: break;
174: default:
175: /* interrupts for builtins always enabled */
176: break;
177: }
178:
179: tc_3000_300_intr[dev].tci_func = tc_3000_300_intrnull;
180: tc_3000_300_intr[dev].tci_arg = (void *)dev;
181: }
182:
183: int
184: tc_3000_300_intrnull(val)
185: void *val;
186: {
187:
188: panic("tc_3000_300_intrnull: uncaught TC intr for cookie %ld",
189: (u_long)val);
190: }
191:
192: void
193: tc_3000_300_iointr(arg, vec)
194: void *arg;
195: unsigned long vec;
196: {
197: u_int32_t tcir, ioasicir, ioasicimr;
198: int ifound;
199:
200: #ifdef DIAGNOSTIC
201: int s;
202: if (vec != 0x800)
203: panic("INVALID ASSUMPTION: vec 0x%lx, not 0x800", vec);
204: s = splhigh();
205: if (s != ALPHA_PSL_IPL_IO)
206: panic("INVALID ASSUMPTION: IPL %d, not %d", s,
207: ALPHA_PSL_IPL_IO);
208: splx(s);
209: #endif
210:
211: do {
212: tc_syncbus();
213:
214: /* find out what interrupts/errors occurred */
215: tcir = *(volatile u_int32_t *)TC_3000_300_IR;
216: ioasicir = *(volatile u_int32_t *)
217: (DEC_3000_300_IOASIC_ADDR + IOASIC_INTR);
218: ioasicimr = *(volatile u_int32_t *)
219: (DEC_3000_300_IOASIC_ADDR + IOASIC_IMSK);
220: tc_mb();
221:
222: /* Ignore interrupts that aren't enabled out. */
223: ioasicir &= ioasicimr;
224:
225: /* clear the interrupts/errors we found. */
226: *(volatile u_int32_t *)TC_3000_300_IR = tcir;
227: /* XXX can't clear TC option slot interrupts here? */
228: tc_wmb();
229:
230: ifound = 0;
231:
232: #define CHECKINTR(slot, flag) \
233: if (flag) { \
234: ifound = 1; \
235: tc_3000_300_intr[slot].tci_count.ec_count++; \
236: (*tc_3000_300_intr[slot].tci_func) \
237: (tc_3000_300_intr[slot].tci_arg); \
238: }
239: /* Do them in order of priority; highest slot # first. */
240: CHECKINTR(TC_3000_300_DEV_CXTURBO,
241: tcir & TC_3000_300_IR_CXTURBO);
242: CHECKINTR(TC_3000_300_DEV_IOASIC,
243: (tcir & TC_3000_300_IR_IOASIC) &&
244: (ioasicir & ~(IOASIC_INTR_300_OPT1|IOASIC_INTR_300_OPT0)));
245: CHECKINTR(TC_3000_300_DEV_TCDS, tcir & TC_3000_300_IR_TCDS);
246: CHECKINTR(TC_3000_300_DEV_OPT1,
247: ioasicir & IOASIC_INTR_300_OPT1);
248: CHECKINTR(TC_3000_300_DEV_OPT0,
249: ioasicir & IOASIC_INTR_300_OPT0);
250: #undef CHECKINTR
251:
252: #ifdef DIAGNOSTIC
253: #define PRINTINTR(msg, bits) \
254: if (tcir & bits) \
255: printf(msg);
256: PRINTINTR("BCache tag parity error\n",
257: TC_3000_300_IR_BCTAGPARITY);
258: PRINTINTR("TC overrun error\n", TC_3000_300_IR_TCOVERRUN);
259: PRINTINTR("TC I/O timeout\n", TC_3000_300_IR_TCTIMEOUT);
260: PRINTINTR("Bcache parity error\n",
261: TC_3000_300_IR_BCACHEPARITY);
262: PRINTINTR("Memory parity error\n", TC_3000_300_IR_MEMPARITY);
263: #undef PRINTINTR
264: #endif
265: } while (ifound);
266: }
267:
268: #if NWSDISPLAY > 0
269: /*
270: * tc_3000_300_fb_cnattach --
271: * Attempt to map the CTB output device to a slot and attach the
272: * framebuffer as the output side of the console.
273: */
274: int
275: tc_3000_300_fb_cnattach(turbo_slot)
276: u_int64_t turbo_slot;
277: {
278: u_int32_t output_slot;
279:
280: output_slot = turbo_slot & 0xffffffff;
281:
282: if (output_slot >= tc_3000_300_nslots) {
283: return EINVAL;
284: }
285:
286: if (output_slot == 0) {
287: #if NSFB > 0
288: sfb_cnattach(KV(0x1c0000000) + 0x02000000);
289: return 0;
290: #else
291: return ENXIO;
292: #endif
293: }
294:
295: return tc_fb_cnattach(tc_3000_300_slots[output_slot-1].tcs_addr);
296: }
297: #endif /* NWSDISPLAY */
CVSweb