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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
|
#include <sys/param.h>
#include <sys/uio.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <machine/cpu.h>
#include <machine/autoconf.h>
#include <mvme88k/dev/pcctworeg.h>
struct pcctwosoftc {
struct device sc_dev;
volatile struct pcc2reg *sc_pcc2reg;
};
int pcctwomatch __P((struct device *, void *, void *));
int pcctwoscan __P((struct device *, void *, void *));
void pcctwoattach __P((struct device *, struct device *, void *));
#ifdef MVME187
void setupiackvectors __P((void));
#endif /* MVME187 */
struct cfattach pcctwo_ca = {
sizeof(struct pcctwosoftc), pcctwomatch, pcctwoattach
};
struct cfdriver pcctwo_cd = {
NULL, "pcctwo", DV_DULL, 0
};
/*ARGSUSED*/
int
pcctwomatch(struct device *parent, void *self, void *aux)
{
int ret;
u_char id, rev;
caddr_t base;
struct confargs *ca = aux;
struct cfdata *cf = self;
#if 0
if (cputyp != CPU_167 && cputyp != CPU_166
#ifdef MVME187
&& cputyp != CPU_187
#endif
)
{
return 0;
}
#endif /* 0 */
if (cputyp != CPU_187) {
return 0;
}
/*
* If bus or name do not match, fail.
*/
if (ca->ca_bustype != BUS_MAIN ||
strcmp(cf->cf_driver->cd_name, "pcctwo")) {
return 0;
}
if ((base = (caddr_t)cf->cf_loc[0]) == (caddr_t)-1) {
return 0;
}
id = badpaddr(base, 1);
rev = badpaddr(base + 1, 1);
if (id != PCC2_CHIP_ID || rev != PCC2_CHIP_REV) {
return 0;
}
ca->ca_size = PCC2_SIZE;
ca->ca_paddr = base;
return 1;
}
int
pcctwoprint(void *aux, char *parent)
{
struct confargs *ca = aux;
/*
* We call pcctwoprint() via config_attach(). Parent
* will always be null and config_attach() would have already
* printed "nvram0 at pcctwo0".
*/
printf(" addr %x size %x", ca->ca_paddr, ca->ca_size);
if (ca->ca_ipl != -1) {
printf(" ipl %x", ca->ca_ipl);
}
return (UNCONF);
}
/*ARGSUSED*/
int
pcctwoscan(struct device *parent, void *self, void *aux)
{
struct confargs ca;
struct cfdata *cf = self;
struct pcctwosoftc *sc = (struct pcctwosoftc *)parent;
/*
* Pcctwoscan gets called by config_search() for each
* child of parent (pcctwo) specified in ioconf.c.
* Fill in the bus type to be PCCTWO and call the child's
* match routine. If the child's match returns 1, then
* we need to allocate device memory, set it in confargs
* and call config_attach(). This, in turn, will call the
* child's attach.
*/
ca.ca_bustype = BUS_PCCTWO;
if ((*cf->cf_attach->ca_match)(parent, cf, &ca) == 0)
return 0;
/*
* The child would have fixed up ca to reflect what its
* requirements are.
*/
if (cf->cf_loc[2] != ca.ca_ipl) {
printf("Changing ipl %x specified in ioconf.c to %x for %s\n",
cf->cf_loc[2], ca.ca_ipl, cf->cf_driver->cd_name);
}
/*
* If the size specified by the child is 0, don't map
* any IO space, but pass in the address of pcc2reg as vaddr.
* This is for clock and parallel port which don't have a
* separate address space by themselves but use pcc2's register
* block.
*/
if (ca.ca_size == 0) {
/*
* pcc2regs addr
*/
#if 0
ca.ca_vaddr = ((struct confargs *)aux)->ca_vaddr;
#endif /* 0 */
ca.ca_vaddr = (caddr_t)sc->sc_pcc2reg;
} else {
ca.ca_vaddr = ca.ca_paddr;
}
#if 0
ca.ca_parent = ((struct confargs *)aux)->ca_vaddr;
#endif /* 0 */
ca.ca_parent = (caddr_t)sc->sc_pcc2reg;
/*
* Call child's attach using config_attach().
*/
config_attach(parent, cf, &ca, pcctwoprint);
return 1;
}
/*
* This function calls the match routine of the configured children
* in turn. For each configured child, map the device address into
* iomap space and then call config_attach() to attach the child.
*/
/* ARGSUSED */
void
pcctwoattach(struct device *parent, struct device *self, void *aux)
{
struct pcctwosoftc *sc = (struct pcctwosoftc *)self;
struct confargs *ca = aux;
caddr_t base;
if (self->dv_unit > 0) {
printf(" unsupported\n");
return;
}
base = ca->ca_vaddr;
printf(": PCCTWO id 0x%2x rev 0x%2x\n",
*(u_char *)base, *((u_char *)base + 1));
/*
* mainbus driver would have mapped Pcc2 at base. Save
* the address in pcctwosoftc.
*/
sc->sc_pcc2reg = (struct pcc2reg *)base;
/*
* Set pcc2intr_mask and pcc2intr_ipl.
*/
pcc2intr_ipl = (u_char *)&(sc->sc_pcc2reg->pcc2_ipl);
pcc2intr_mask = (u_char *)&(sc->sc_pcc2reg->pcc2_imask);
#ifdef MVME187
/*
* Get mappings for iack vectors. This doesn't belong here
* but is more closely related to pcc than anything I can
* think of. (could probably do it in locore.s).
*/
setupiackvectors();
#endif /* MVME187 */
(void)config_search(pcctwoscan, self, aux);
}
|