This source file includes following definitions.
- uperf_sbus_match
- uperf_sbus_attach
- uperf_sbus_read_reg
- uperf_sbus_write_reg
- uperf_sbus_clrcnt
- uperf_sbus_setcntsrc
- uperf_sbus_getcntsrc
- uperf_sbus_getcnt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 #include <sys/types.h>
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
38 #include <sys/errno.h>
39 #include <sys/device.h>
40 #include <sys/malloc.h>
41
42 #include <machine/bus.h>
43 #include <machine/intr.h>
44 #include <machine/autoconf.h>
45
46 #include <arch/sparc64/dev/uperfvar.h>
47 #include <dev/sun/uperfio.h>
48 #include <dev/sbus/sbusvar.h>
49 #include <dev/sbus/uperf_sbusreg.h>
50
51 int uperf_sbus_match(struct device *, void *, void *);
52 void uperf_sbus_attach(struct device *, struct device *, void *);
53
54 struct uperf_sbus_softc {
55 struct uperf_softc sc_usc;
56 bus_space_tag_t sc_bus_t;
57 bus_space_handle_t sc_bus_h;
58 };
59
60 struct cfattach uperf_sbus_ca = {
61 sizeof(struct uperf_sbus_softc), uperf_sbus_match, uperf_sbus_attach
62 };
63
64 u_int32_t uperf_sbus_read_reg(struct uperf_sbus_softc *, bus_size_t);
65 void uperf_sbus_write_reg(struct uperf_sbus_softc *,
66 bus_size_t, u_int32_t);
67
68 int uperf_sbus_getcnt(void *, int, u_int32_t *, u_int32_t *);
69 int uperf_sbus_clrcnt(void *, int);
70 int uperf_sbus_getcntsrc(void *, int, u_int *, u_int *);
71 int uperf_sbus_setcntsrc(void *, int, u_int, u_int);
72
73 struct uperf_src uperf_sbus_srcs[] = {
74 { UPERFSRC_SYSCK, UPERF_CNT0|UPERF_CNT1, SEL0_SYSCK },
75 { UPERFSRC_PRALL, UPERF_CNT0|UPERF_CNT1, SEL0_PRALL },
76 { UPERFSRC_PRP0, UPERF_CNT0|UPERF_CNT1, SEL0_PRP0 },
77 { UPERFSRC_PRU2S, UPERF_CNT0|UPERF_CNT1, SEL0_PRUS },
78 { UPERFSRC_UPA128, UPERF_CNT0, SEL0_128BUSY },
79 { UPERFSRC_RP0, UPERF_CNT1, SEL1_RDP0 },
80 { UPERFSRC_UPA64, UPERF_CNT0, SEL0_64BUSY },
81 { UPERFSRC_P0CRMR, UPERF_CNT1, SEL1_CRMP0 },
82 { UPERFSRC_PIOS, UPERF_CNT0, SEL0_PIOSTALL },
83 { UPERFSRC_P0PIO, UPERF_CNT1, SEL1_PIOP0 },
84 { UPERFSRC_MEMRI, UPERF_CNT0|UPERF_CNT0, SEL0_MEMREQ },
85 { UPERFSRC_MCBUSY, UPERF_CNT0, SEL0_MCBUSY },
86 { UPERFSRC_MEMRC, UPERF_CNT1, SEL1_MRC},
87 { UPERFSRC_PXSH, UPERF_CNT0, SEL0_PENDSTALL },
88 { UPERFSRC_RDP0, UPERF_CNT0, SEL1_RDP1 },
89 { UPERFSRC_P0CWMR, UPERF_CNT0, SEL0_CWMRP0 },
90 { UPERFSRC_CRMP1, UPERF_CNT1, SEL1_CRMP1 },
91 { UPERFSRC_P1CWMR, UPERF_CNT0, SEL0_CWMRP1 },
92 { UPERFSRC_PIOP1, UPERF_CNT1, SEL1_PIOP1 },
93 { UPERFSRC_CIT, UPERF_CNT0, SEL0_CIT },
94 { UPERFSRC_CWXI, UPERF_CNT1, SEL1_CWXI },
95 { UPERFSRC_U2SDAT, UPERF_CNT0|UPERF_CNT1, SEL0_DACT },
96 { UPERFSRC_CRXI, UPERF_CNT0, SEL0_CRXI },
97 { -1, -1, 0 }
98 };
99
100 int
101 uperf_sbus_match(struct device *parent, void *vcf, void *aux)
102 {
103 struct sbus_attach_args *sa = aux;
104
105 return (strcmp(sa->sa_name, "sc") == 0);
106 }
107
108 void
109 uperf_sbus_attach(struct device *parent, struct device *self, void *aux)
110 {
111 struct sbus_attach_args *sa = aux;
112 struct uperf_sbus_softc *sc = (struct uperf_sbus_softc *)self;
113 char *model;
114 u_int32_t id;
115
116 sc->sc_bus_t = sa->sa_bustag;
117 sc->sc_usc.usc_cookie = sc;
118 sc->sc_usc.usc_getcntsrc = uperf_sbus_getcntsrc;
119 sc->sc_usc.usc_setcntsrc = uperf_sbus_setcntsrc;
120 sc->sc_usc.usc_clrcnt = uperf_sbus_clrcnt;
121 sc->sc_usc.usc_getcnt = uperf_sbus_getcnt;
122 sc->sc_usc.usc_srcs = uperf_sbus_srcs;
123
124 if (sa->sa_nreg != 1) {
125 printf(": expected 1 register, got %d\n", sa->sa_nreg);
126 return;
127 }
128
129 if (sbus_bus_map(sc->sc_bus_t, sa->sa_reg[0].sbr_slot,
130 sa->sa_reg[0].sbr_offset, sa->sa_reg[0].sbr_size, 0, 0,
131 &sc->sc_bus_h) != 0) {
132 printf(": couldn't map registers\n");
133 return;
134 }
135
136 id = uperf_sbus_read_reg(sc, USC_ID);
137 model = getpropstring(sa->sa_node, "model");
138 if (model == NULL || strlen(model) == 0)
139 model = "unknown";
140
141 printf(": model %s (%x/%x) ports %d\n", model,
142 (id & USC_ID_IMPL_M) >> USC_ID_IMPL_S,
143 (id & USC_ID_VERS_M) >> USC_ID_VERS_S,
144 (id & USC_ID_UPANUM_M) >> USC_ID_UPANUM_S);
145 }
146
147
148
149
150 u_int32_t
151 uperf_sbus_read_reg(struct uperf_sbus_softc *sc, bus_size_t r)
152 {
153 u_int32_t v;
154 int s;
155
156 s = splhigh();
157 bus_space_write_1(sc->sc_bus_t, sc->sc_bus_h, USC_ADDR, r);
158 bus_space_barrier(sc->sc_bus_t, sc->sc_bus_h, USC_ADDR, 1,
159 BUS_SPACE_BARRIER_WRITE);
160
161
162
163 v = bus_space_read_1(sc->sc_bus_t, sc->sc_bus_h, USC_DATA + 0);
164 bus_space_barrier(sc->sc_bus_t, sc->sc_bus_h, USC_DATA + 0, 1,
165 BUS_SPACE_BARRIER_READ);
166
167 v <<= 8;
168 v |= bus_space_read_1(sc->sc_bus_t, sc->sc_bus_h, USC_DATA + 1);
169 bus_space_barrier(sc->sc_bus_t, sc->sc_bus_h, USC_DATA + 1, 1,
170 BUS_SPACE_BARRIER_READ);
171
172 v <<= 8;
173 v |= bus_space_read_1(sc->sc_bus_t, sc->sc_bus_h, USC_DATA + 2);
174 bus_space_barrier(sc->sc_bus_t, sc->sc_bus_h, USC_DATA + 2, 1,
175 BUS_SPACE_BARRIER_READ);
176
177 v <<= 8;
178 v |= bus_space_read_1(sc->sc_bus_t, sc->sc_bus_h, USC_DATA + 3);
179 bus_space_barrier(sc->sc_bus_t, sc->sc_bus_h, USC_DATA + 3, 1,
180 BUS_SPACE_BARRIER_READ);
181
182 splx(s);
183 return (v);
184 }
185
186
187
188
189 void
190 uperf_sbus_write_reg(struct uperf_sbus_softc *sc, bus_size_t r, u_int32_t v)
191 {
192 int s;
193
194 s = splhigh();
195 bus_space_write_1(sc->sc_bus_t, sc->sc_bus_h, USC_ADDR, r);
196 bus_space_barrier(sc->sc_bus_t, sc->sc_bus_h, USC_ADDR, 1,
197 BUS_SPACE_BARRIER_WRITE);
198
199
200
201 bus_space_write_1(sc->sc_bus_t, sc->sc_bus_h, USC_DATA + 0,
202 (v >> 24) & 0xff);
203 bus_space_barrier(sc->sc_bus_t, sc->sc_bus_h, USC_DATA + 0, 1,
204 BUS_SPACE_BARRIER_WRITE);
205
206 bus_space_write_1(sc->sc_bus_t, sc->sc_bus_h, USC_DATA + 1,
207 (v >> 16) & 0xff);
208 bus_space_barrier(sc->sc_bus_t, sc->sc_bus_h, USC_DATA + 1, 1,
209 BUS_SPACE_BARRIER_WRITE);
210
211 bus_space_write_1(sc->sc_bus_t, sc->sc_bus_h, USC_DATA + 2,
212 (v >> 8) & 0xff);
213 bus_space_barrier(sc->sc_bus_t, sc->sc_bus_h, USC_DATA + 2, 1,
214 BUS_SPACE_BARRIER_WRITE);
215
216 bus_space_write_1(sc->sc_bus_t, sc->sc_bus_h, USC_DATA + 3,
217 (v >> 0) & 0xff);
218 bus_space_barrier(sc->sc_bus_t, sc->sc_bus_h, USC_DATA + 3, 1,
219 BUS_SPACE_BARRIER_WRITE);
220 splx(s);
221 }
222
223 int
224 uperf_sbus_clrcnt(void *vsc, int flags)
225 {
226 struct uperf_sbus_softc *sc = vsc;
227 u_int32_t clr = 0, oldsrc;
228
229 if (flags & UPERF_CNT0)
230 clr |= USC_PCTRL_CLR0;
231 if (flags & UPERF_CNT1)
232 clr |= USC_PCTRL_CLR1;
233 if (clr) {
234 oldsrc = uperf_sbus_read_reg(sc, USC_PERFCTRL);
235 uperf_sbus_write_reg(sc, USC_PERFCTRL, clr | oldsrc);
236 }
237 return (0);
238 }
239
240 int
241 uperf_sbus_setcntsrc(void *vsc, int flags, u_int src0, u_int src1)
242 {
243 struct uperf_sbus_softc *sc = vsc;
244 u_int32_t src;
245
246 src = uperf_sbus_read_reg(sc, USC_PERFCTRL);
247 if (flags & UPERF_CNT0) {
248 src &= ~USC_PCTRL_SEL0;
249 src |= ((src0 << 0) & USC_PCTRL_SEL0) | USC_PCTRL_CLR0;
250 }
251 if (flags & UPERF_CNT1) {
252 src &= ~USC_PCTRL_SEL1;
253 src |= ((src1 << 8) & USC_PCTRL_SEL1) | USC_PCTRL_CLR1;
254 }
255 uperf_sbus_write_reg(sc, USC_PERFCTRL, src);
256 return (0);
257 }
258
259 int
260 uperf_sbus_getcntsrc(void *vsc, int flags, u_int *srcp0, u_int *srcp1)
261 {
262 struct uperf_sbus_softc *sc = vsc;
263 u_int32_t src;
264
265 src = uperf_sbus_read_reg(sc, USC_PERFCTRL);
266 if (flags & UPERF_CNT0)
267 *srcp0 = (src & USC_PCTRL_SEL0) >> 0;
268 if (flags & UPERF_CNT1)
269 *srcp1 = (src & USC_PCTRL_SEL1) >> 8;
270 return (0);
271 }
272
273 int
274 uperf_sbus_getcnt(void *vsc, int flags, u_int32_t *cntp0, u_int32_t *cntp1)
275 {
276 struct uperf_sbus_softc *sc = vsc;
277 u_int32_t c0, c1;
278
279 c0 = uperf_sbus_read_reg(sc, USC_PERF0);
280 c1 = uperf_sbus_read_reg(sc, USC_PERFSHAD);
281 if (flags & UPERF_CNT0)
282 *cntp0 = c0;
283 if (flags & UPERF_CNT1)
284 *cntp1 = c1;
285 return (0);
286 }