| @@ -1,205 +1,212 @@ | | | @@ -1,205 +1,212 @@ |
1 | /* $NetBSD: ioasic.c,v 1.22 2013/11/10 20:09:53 christos Exp $ */ | | 1 | /* $NetBSD: ioasic.c,v 1.23 2020/09/03 06:42:29 simonb Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1994, 1995 Carnegie-Mellon University. | | 4 | * Copyright (c) 1994, 1995 Carnegie-Mellon University. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Author: Keith Bostic, Chris G. Demetriou, Jonathan Stone | | 7 | * Author: Keith Bostic, Chris G. Demetriou, Jonathan Stone |
8 | * | | 8 | * |
9 | * Permission to use, copy, modify and distribute this software and | | 9 | * Permission to use, copy, modify and distribute this software and |
10 | * its documentation is hereby granted, provided that both the copyright | | 10 | * its documentation is hereby granted, provided that both the copyright |
11 | * notice and this permission notice appear in all copies of the | | 11 | * notice and this permission notice appear in all copies of the |
12 | * software, derivative works or modified versions, and any portions | | 12 | * software, derivative works or modified versions, and any portions |
13 | * thereof, and that both notices appear in supporting documentation. | | 13 | * thereof, and that both notices appear in supporting documentation. |
14 | * | | 14 | * |
15 | * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" | | 15 | * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" |
16 | * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND | | 16 | * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND |
17 | * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. | | 17 | * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. |
18 | * | | 18 | * |
19 | * Carnegie Mellon requests users of this software to return to | | 19 | * Carnegie Mellon requests users of this software to return to |
20 | * | | 20 | * |
21 | * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU | | 21 | * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU |
22 | * School of Computer Science | | 22 | * School of Computer Science |
23 | * Carnegie Mellon University | | 23 | * Carnegie Mellon University |
24 | * Pittsburgh PA 15213-3890 | | 24 | * Pittsburgh PA 15213-3890 |
25 | * | | 25 | * |
26 | * any improvements or extensions that they make and grant Carnegie the | | 26 | * any improvements or extensions that they make and grant Carnegie the |
27 | * rights to redistribute these changes. | | 27 | * rights to redistribute these changes. |
28 | */ | | 28 | */ |
29 | | | 29 | |
30 | #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ | | 30 | #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ |
31 | __KERNEL_RCSID(0, "$NetBSD: ioasic.c,v 1.22 2013/11/10 20:09:53 christos Exp $"); | | 31 | __KERNEL_RCSID(0, "$NetBSD: ioasic.c,v 1.23 2020/09/03 06:42:29 simonb Exp $"); |
32 | | | 32 | |
33 | #include <sys/param.h> | | 33 | #include <sys/param.h> |
34 | #include <sys/systm.h> | | 34 | #include <sys/systm.h> |
35 | #include <sys/device.h> | | 35 | #include <sys/device.h> |
36 | | | 36 | |
37 | #include <dev/tc/tcvar.h> | | 37 | #include <dev/tc/tcvar.h> |
38 | #include <dev/tc/ioasicreg.h> | | 38 | #include <dev/tc/ioasicreg.h> |
39 | #include <dev/tc/ioasicvar.h> | | 39 | #include <dev/tc/ioasicvar.h> |
40 | | | 40 | |
41 | #include <pmax/sysconf.h> | | 41 | #include <pmax/sysconf.h> |
42 | | | 42 | |
43 | #include <pmax/pmax/pmaxtype.h> | | 43 | #include <pmax/pmax/pmaxtype.h> |
44 | #include <pmax/pmax/kmin.h> | | 44 | #include <pmax/pmax/kmin.h> |
45 | #include <pmax/pmax/maxine.h> | | 45 | #include <pmax/pmax/maxine.h> |
46 | #include <pmax/pmax/kn03.h> | | 46 | #include <pmax/pmax/kn03.h> |
47 | | | 47 | |
48 | #include "opt_dec_3min.h" | | 48 | #include "opt_dec_3min.h" |
49 | #include "opt_dec_maxine.h" | | 49 | #include "opt_dec_maxine.h" |
50 | #include "opt_dec_3maxplus.h" | | 50 | #include "opt_dec_3maxplus.h" |
51 | | | 51 | |
52 | #define ARRAY_SIZEOF(x) (sizeof((x)) / sizeof((x)[0])) | | 52 | #define ARRAY_SIZEOF(x) (sizeof((x)) / sizeof((x)[0])) |
53 | | | 53 | |
54 | #if defined(DEC_3MIN) | | 54 | #if defined(DEC_3MIN) |
55 | static struct ioasic_dev kmin_ioasic_devs[] = { | | 55 | static struct ioasic_dev kmin_ioasic_devs[] = { |
56 | { "PMAD-BA ", 0x0C0000, C(SYS_DEV_LANCE), }, | | 56 | { "PMAD-BA ", 0x0C0000, C(SYS_DEV_LANCE), }, |
57 | { "scc", 0x100000, C(SYS_DEV_SCC0), }, | | 57 | { "scc", 0x100000, C(SYS_DEV_SCC0), }, |
58 | { "scc", 0x180000, C(SYS_DEV_SCC1), }, | | 58 | { "scc", 0x180000, C(SYS_DEV_SCC1), }, |
59 | { "mc146818", 0x200000, C(SYS_DEV_BOGUS), }, | | 59 | { "mc146818", 0x200000, C(SYS_DEV_BOGUS), }, |
60 | { "asc", 0x300000, C(SYS_DEV_SCSI), }, | | 60 | { "asc", 0x300000, C(SYS_DEV_SCSI), }, |
61 | }; | | 61 | }; |
62 | static int kmin_builtin_ndevs = ARRAY_SIZEOF(kmin_ioasic_devs); | | 62 | static int kmin_builtin_ndevs = ARRAY_SIZEOF(kmin_ioasic_devs); |
63 | static int kmin_ioasic_ndevs = ARRAY_SIZEOF(kmin_ioasic_devs); | | 63 | static int kmin_ioasic_ndevs = ARRAY_SIZEOF(kmin_ioasic_devs); |
64 | #endif | | 64 | #endif |
65 | | | 65 | |
66 | #if defined(DEC_MAXINE) | | 66 | #if defined(DEC_MAXINE) |
67 | static struct ioasic_dev xine_ioasic_devs[] = { | | 67 | static struct ioasic_dev xine_ioasic_devs[] = { |
68 | { "PMAD-BA ", 0x0C0000, C(SYS_DEV_LANCE), }, | | 68 | { "PMAD-BA ", 0x0C0000, C(SYS_DEV_LANCE), }, |
69 | { "scc", 0x100000, C(SYS_DEV_SCC0), }, | | 69 | { "scc", 0x100000, C(SYS_DEV_SCC0), }, |
70 | { "mc146818", 0x200000, C(SYS_DEV_BOGUS), }, | | 70 | { "mc146818", 0x200000, C(SYS_DEV_BOGUS), }, |
71 | { "isdn", 0x240000, C(SYS_DEV_ISDN), }, | | 71 | { "isdn", 0x240000, C(SYS_DEV_ISDN), }, |
72 | { "dtop", 0x280000, C(SYS_DEV_DTOP), }, | | 72 | { "dtop", 0x280000, C(SYS_DEV_DTOP), }, |
73 | { "fdc", 0x2C0000, C(SYS_DEV_FDC), }, | | 73 | { "fdc", 0x2C0000, C(SYS_DEV_FDC), }, |
74 | { "asc", 0x300000, C(SYS_DEV_SCSI), }, | | 74 | { "asc", 0x300000, C(SYS_DEV_SCSI), }, |
75 | { "(TC0)", 0x0, C(SYS_DEV_OPT0), }, | | 75 | { "(TC0)", 0x0, C(SYS_DEV_OPT0), }, |
76 | { "(TC1)", 0x0, C(SYS_DEV_OPT1), }, | | 76 | { "(TC1)", 0x0, C(SYS_DEV_OPT1), }, |
77 | { "(TC2)", 0x0, C(SYS_DEV_OPT2), }, | | 77 | { "(TC2)", 0x0, C(SYS_DEV_OPT2), }, |
78 | }; | | 78 | }; |
79 | static int xine_builtin_ndevs = ARRAY_SIZEOF(xine_ioasic_devs) - 3; | | 79 | static int xine_builtin_ndevs = ARRAY_SIZEOF(xine_ioasic_devs) - 3; |
80 | static int xine_ioasic_ndevs = ARRAY_SIZEOF(xine_ioasic_devs); | | 80 | static int xine_ioasic_ndevs = ARRAY_SIZEOF(xine_ioasic_devs); |
81 | #endif | | 81 | #endif |
82 | | | 82 | |
83 | #if defined(DEC_3MAXPLUS) | | 83 | #if defined(DEC_3MAXPLUS) |
84 | static struct ioasic_dev kn03_ioasic_devs[] = { | | 84 | static struct ioasic_dev kn03_ioasic_devs[] = { |
85 | { "PMAD-BA ", 0x0C0000, C(SYS_DEV_LANCE), }, | | 85 | { "PMAD-BA ", 0x0C0000, C(SYS_DEV_LANCE), }, |
86 | { "z8530 ", 0x100000, C(SYS_DEV_SCC0), }, | | 86 | { "z8530 ", 0x100000, C(SYS_DEV_SCC0), }, |
87 | { "z8530 ", 0x180000, C(SYS_DEV_SCC1), }, | | 87 | { "z8530 ", 0x180000, C(SYS_DEV_SCC1), }, |
88 | { "mc146818", 0x200000, C(SYS_DEV_BOGUS), }, | | 88 | { "mc146818", 0x200000, C(SYS_DEV_BOGUS), }, |
89 | { "asc", 0x300000, C(SYS_DEV_SCSI), }, | | 89 | { "asc", 0x300000, C(SYS_DEV_SCSI), }, |
90 | { "(TC0)", 0x0, C(SYS_DEV_OPT0), }, | | 90 | { "(TC0)", 0x0, C(SYS_DEV_OPT0), }, |
91 | { "(TC1)", 0x0, C(SYS_DEV_OPT1), }, | | 91 | { "(TC1)", 0x0, C(SYS_DEV_OPT1), }, |
92 | { "(TC2)", 0x0, C(SYS_DEV_OPT2), }, | | 92 | { "(TC2)", 0x0, C(SYS_DEV_OPT2), }, |
93 | }; | | 93 | }; |
94 | static int kn03_builtin_ndevs = ARRAY_SIZEOF(kn03_ioasic_devs) - 3; | | 94 | static int kn03_builtin_ndevs = ARRAY_SIZEOF(kn03_ioasic_devs) - 3; |
95 | static int kn03_ioasic_ndevs = ARRAY_SIZEOF(kn03_ioasic_devs); | | 95 | static int kn03_ioasic_ndevs = ARRAY_SIZEOF(kn03_ioasic_devs); |
96 | #endif | | 96 | #endif |
97 | | | 97 | |
98 | static int ioasicmatch(device_t, cfdata_t, void *); | | 98 | static int ioasicmatch(device_t, cfdata_t, void *); |
99 | static void ioasicattach(device_t, device_t, void *); | | 99 | static void ioasicattach(device_t, device_t, void *); |
100 | | | 100 | |
101 | CFATTACH_DECL_NEW(ioasic, sizeof(struct ioasic_softc), | | 101 | CFATTACH_DECL_NEW(ioasic, sizeof(struct ioasic_softc), |
102 | ioasicmatch, ioasicattach, NULL, NULL); | | 102 | ioasicmatch, ioasicattach, NULL, NULL); |
103 | | | 103 | |
104 | tc_addr_t ioasic_base; /* XXX XXX XXX */ | | 104 | tc_addr_t ioasic_base; /* XXX XXX XXX */ |
105 | | | 105 | |
106 | /* There can be only one. */ | | 106 | /* There can be only one. */ |
107 | int ioasicfound; | | 107 | int ioasicfound; |
108 | | | 108 | |
109 | static int | | 109 | static int |
110 | ioasicmatch(device_t parent, cfdata_t cfdata, void *aux) | | 110 | ioasicmatch(device_t parent, cfdata_t cfdata, void *aux) |
111 | { | | 111 | { |
112 | struct tc_attach_args *ta = aux; | | 112 | struct tc_attach_args *ta = aux; |
113 | | | 113 | |
114 | /* Make sure that we're looking for this type of device. */ | | 114 | /* Make sure that we're looking for this type of device. */ |
115 | if (strncmp("IOCTL ", ta->ta_modname, TC_ROM_LLEN)) | | 115 | if (strncmp("IOCTL ", ta->ta_modname, TC_ROM_LLEN)) |
116 | return (0); | | 116 | return (0); |
117 | | | 117 | |
118 | if (ioasicfound) | | 118 | if (ioasicfound) |
119 | return (0); | | 119 | return (0); |
120 | | | 120 | |
121 | return (1); | | 121 | return (1); |
122 | } | | 122 | } |
123 | | | 123 | |
124 | static void | | 124 | static void |
125 | ioasicattach(device_t parent, device_t self, void *aux) | | 125 | ioasicattach(device_t parent, device_t self, void *aux) |
126 | { | | 126 | { |
127 | struct ioasic_softc *sc = device_private(self); | | 127 | struct ioasic_softc *sc = device_private(self); |
128 | struct tc_attach_args *ta = aux; | | 128 | struct tc_attach_args *ta = aux; |
129 | struct ioasic_dev *ioasic_devs; | | 129 | struct ioasic_dev *ioasic_devs; |
130 | int ioasic_ndevs, builtin_ndevs; | | 130 | int ioasic_ndevs, builtin_ndevs; |
131 | | | 131 | |
132 | ioasicfound = 1; | | 132 | ioasicfound = 1; |
133 | | | 133 | |
134 | sc->sc_dev = self; | | 134 | sc->sc_dev = self; |
135 | sc->sc_bst = ta->ta_memt; | | 135 | sc->sc_bst = ta->ta_memt; |
136 | if (bus_space_map(ta->ta_memt, ta->ta_addr, | | 136 | /* |
| | | 137 | * XXX |
| | | 138 | * The TC device addresses are defined in KSEG1, but this |
| | | 139 | * confuses bus_space(9) which expects bus addresses and |
| | | 140 | * not kernel virtual addresses. Pull the addresses back |
| | | 141 | * to bus addresses with MIPS_KSEG1_TO_PHYS(). |
| | | 142 | */ |
| | | 143 | if (bus_space_map(ta->ta_memt, MIPS_KSEG1_TO_PHYS(ta->ta_addr), |
137 | 0x400000, 0, &sc->sc_bsh)) { | | 144 | 0x400000, 0, &sc->sc_bsh)) { |
138 | printf("%s: unable to map device\n", device_xname(self)); | | 145 | printf("%s: unable to map device\n", device_xname(self)); |
139 | return; | | 146 | return; |
140 | } | | 147 | } |
141 | sc->sc_dmat = ta->ta_dmat; | | 148 | sc->sc_dmat = ta->ta_dmat; |
142 | | | 149 | |
143 | sc->sc_base = ta->ta_addr; /* XXX XXX XXX */ | | 150 | sc->sc_base = ta->ta_addr; /* XXX XXX XXX */ |
144 | | | 151 | |
145 | printf("\n"); | | 152 | printf("\n"); |
146 | | | 153 | |
147 | switch (systype) { | | 154 | switch (systype) { |
148 | #if defined(DEC_3MIN) | | 155 | #if defined(DEC_3MIN) |
149 | case DS_3MIN: | | 156 | case DS_3MIN: |
150 | ioasic_devs = kmin_ioasic_devs; | | 157 | ioasic_devs = kmin_ioasic_devs; |
151 | ioasic_ndevs = kmin_ioasic_ndevs; | | 158 | ioasic_ndevs = kmin_ioasic_ndevs; |
152 | builtin_ndevs = kmin_builtin_ndevs; | | 159 | builtin_ndevs = kmin_builtin_ndevs; |
153 | break; | | 160 | break; |
154 | #endif | | 161 | #endif |
155 | #if defined(DEC_MAXINE) | | 162 | #if defined(DEC_MAXINE) |
156 | case DS_MAXINE: | | 163 | case DS_MAXINE: |
157 | ioasic_devs = xine_ioasic_devs; | | 164 | ioasic_devs = xine_ioasic_devs; |
158 | ioasic_ndevs = xine_ioasic_ndevs; | | 165 | ioasic_ndevs = xine_ioasic_ndevs; |
159 | builtin_ndevs = xine_builtin_ndevs; | | 166 | builtin_ndevs = xine_builtin_ndevs; |
160 | break; | | 167 | break; |
161 | #endif | | 168 | #endif |
162 | #if defined(DEC_3MAXPLUS) | | 169 | #if defined(DEC_3MAXPLUS) |
163 | case DS_3MAXPLUS: | | 170 | case DS_3MAXPLUS: |
164 | ioasic_devs = kn03_ioasic_devs; | | 171 | ioasic_devs = kn03_ioasic_devs; |
165 | ioasic_ndevs = kn03_ioasic_ndevs; | | 172 | ioasic_ndevs = kn03_ioasic_ndevs; |
166 | builtin_ndevs = kn03_builtin_ndevs; | | 173 | builtin_ndevs = kn03_builtin_ndevs; |
167 | break; | | 174 | break; |
168 | #endif | | 175 | #endif |
169 | default: | | 176 | default: |
170 | panic("ioasicmatch: how did we get here?"); | | 177 | panic("ioasicmatch: how did we get here?"); |
171 | } | | 178 | } |
172 | | | 179 | |
173 | #if 0 /* IMSK has been sanitized */ | | 180 | #if 0 /* IMSK has been sanitized */ |
174 | /* | | 181 | /* |
175 | * Turn off all device interrupt bits. | | 182 | * Turn off all device interrupt bits. |
176 | * (This _does_ include TC option slot bits.) | | 183 | * (This _does_ include TC option slot bits.) |
177 | */ | | 184 | */ |
178 | imsk = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_IMSK); | | 185 | imsk = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_IMSK); |
179 | for (i = 0; i < ioasic_ndevs; i++) | | 186 | for (i = 0; i < ioasic_ndevs; i++) |
180 | imsk &= ~ioasic_devs[i].iad_intrbits; | | 187 | imsk &= ~ioasic_devs[i].iad_intrbits; |
181 | bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_IMSK, imsk); | | 188 | bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_IMSK, imsk); |
182 | #else | | 189 | #else |
183 | __USE(ioasic_ndevs); | | 190 | __USE(ioasic_ndevs); |
184 | #endif | | 191 | #endif |
185 | | | 192 | |
186 | /* | | 193 | /* |
187 | * Try to configure each device. | | 194 | * Try to configure each device. |
188 | */ | | 195 | */ |
189 | ioasic_attach_devs(sc, ioasic_devs, builtin_ndevs); | | 196 | ioasic_attach_devs(sc, ioasic_devs, builtin_ndevs); |
190 | } | | 197 | } |
191 | | | 198 | |
192 | const struct evcnt * | | 199 | const struct evcnt * |
193 | ioasic_intr_evcnt(device_t dev, void *cookie) | | 200 | ioasic_intr_evcnt(device_t dev, void *cookie) |
194 | { | | 201 | { |
195 | | | 202 | |
196 | /* XXX for now, no evcnt parent reported */ | | 203 | /* XXX for now, no evcnt parent reported */ |
197 | return NULL; | | 204 | return NULL; |
198 | } | | 205 | } |
199 | | | 206 | |
200 | void | | 207 | void |
201 | ioasic_intr_establish(device_t dev, void *cookie, int level, | | 208 | ioasic_intr_establish(device_t dev, void *cookie, int level, |
202 | int (*handler)(void *), void *val) | | 209 | int (*handler)(void *), void *val) |
203 | { | | 210 | { |
204 | (*platform.intr_establish)(dev, cookie, level, handler, val); | | 211 | (*platform.intr_establish)(dev, cookie, level, handler, val); |
205 | } | | 212 | } |