apbus.c revision 1.1 1 /* $NetBSD: apbus.c,v 1.1 1999/12/22 05:55:24 tsubai Exp $ */
2
3 /*-
4 * Copyright (C) 1999 SHIMIZU Ryo. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/device.h>
32
33 #include <machine/adrsmap.h>
34 #include <machine/autoconf.h>
35 #include <newsmips/apbus/apbusvar.h>
36
37 static int apbusmatch __P((struct device *, struct cfdata *, void *));
38 static void apbusattach __P((struct device *, struct device *, void *));
39 static int apbusprint __P((void *, const char *));
40 /* static void *aptokseg0 __P((void *)); */
41
42 #define MAXAPDEVNUM 32
43
44 struct apbus_softc {
45 struct device apbs_dev;
46 };
47
48 struct cfattach ap_ca = {
49 sizeof(struct apbus_softc), apbusmatch, apbusattach
50 };
51
52 #define APBUS_DEVNAMELEN 16
53
54 struct ap_intrhand {
55 int ai_mask;
56 int ai_priority;
57 void (*ai_func) __P((void*)); /* function */
58 void *ai_aux; /* softc */
59 char ai_name[APBUS_DEVNAMELEN];
60 int ai_ctlno;
61 };
62
63 #define NLEVEL 2
64 #define NBIT 16
65
66 static struct ap_intrhand apintr[NLEVEL][NBIT];
67
68 static int
69 apbusmatch(parent, cfdata, aux)
70 struct device *parent;
71 struct cfdata *cfdata;
72 void *aux;
73 {
74 struct confargs *ca = aux;
75
76 if (strcmp(ca->ca_name, "ap") != 0)
77 return 0;
78
79 return 1;
80 }
81
82
83 static void
84 apbusattach(parent, self, aux)
85 struct device *parent;
86 struct device *self;
87 void *aux;
88 {
89 struct apbus_attach_args child;
90 struct apbus_device *apdev;
91 struct apbus_ctl *apctl;
92
93 *(volatile u_int*)(NEWS5000_APBUS_INTSTAT) = 0xffffffff;
94 *(volatile u_int*)(NEWS5000_APBUS_INTMASK) = NEWS5000_INTAPBUS_ALL;
95
96 *(volatile u_int*)(NEWS5000_APBUS_CONFIG) = 0x04;
97 *(volatile u_int *)(NEWS5000_APBUS_DUMCOH) =
98 NEWS5000_APBUS_DEVICE_DMAC3 |
99 NEWS5000_APBUS_DEVICE_SONIC |
100 NEWS5000_APBUS_DEVICE_ALLSLOT;
101
102 *(volatile u_int*)NEWS5000_INTMASK0 = NEWS5000_INT0_ALL;
103 *(volatile u_int*)NEWS5000_INTMASK1 = NEWS5000_INT1_ALL;
104
105 printf("\n");
106
107 /*
108 * get first ap-device
109 */
110 apdev = apbus_lookupdev(NULL);
111
112 /*
113 * trace device chain
114 */
115 while (apdev) {
116 apctl = apdev->apbd_ctl;
117
118 /*
119 * probe physical device only
120 * (no pseudo device)
121 */
122 if (apctl && apctl->apbc_hwbase) {
123 /*
124 * ... and, all units
125 */
126 while (apctl) {
127 /* make apbus_attach_args for devices */
128 child.apa_name = apdev->apbd_name;
129 child.apa_ctlnum = apctl->apbc_ctlno;
130 child.apa_slotno = apctl->apbc_sl;
131 child.apa_hwbase = apctl->apbc_hwbase;
132
133 #if 0
134 printf("config_found: name = %s\n", child.apa_name);
135 printf(" : unit = %d\n", child.apa_ctlnum);
136 printf(" : slot = %d\n", child.apa_slotno);
137 printf(" : unit = 0x%08lx\n", child.apa_hwbase);
138 #endif
139
140 config_found(self, &child, apbusprint);
141
142 apctl = apctl->apbc_link;
143 }
144 }
145
146 apdev = apdev->apbd_link;
147 }
148 }
149
150 int
151 apbusprint(aux, pnp)
152 void *aux;
153 const char *pnp;
154 {
155 struct apbus_attach_args *a = aux;
156
157 if (pnp)
158 printf("%s at %s slot%d addr 0x%lx",
159 a->apa_name, pnp, a->apa_slotno, a->apa_hwbase);
160
161 return UNCONF;
162 }
163
164 #if 0
165 void *
166 aptokseg0(va)
167 void *va;
168 {
169 vaddr_t addr = (vaddr_t)va;
170
171 if (addr >= 0xfff00000) {
172 addr -= 0xfff00000;
173 addr += physmem << PGSHIFT;
174 addr += 0x80000000;
175 va = (void *)addr;
176 }
177 return va;
178 }
179 #endif
180
181 void
182 apbus_wbflush()
183 {
184 volatile int *wbflush = (int *)NEWS5000_WB;
185
186 (void)*wbflush;
187 }
188
189 void
190 apbus_intr_init()
191 {
192 bzero(&apintr[0][0],sizeof(apintr));
193 }
194
195 /*
196 * called by hardware interrupt routine
197 */
198 int
199 apbus_intr_call(level, stat)
200 int level;
201 int stat;
202 {
203 int i;
204 int nintr = 0;
205 struct ap_intrhand *aip = &apintr[level][0];
206
207 for(i = 0; i < NBIT; i++) {
208 if (aip->ai_mask & stat) {
209 (*aip->ai_func)(aip->ai_aux);
210 nintr++;
211 }
212 aip++;
213 }
214 return nintr;
215 }
216
217 /*
218 * register device interrupt routine
219 */
220 void *
221 apbus_intr_establish(level, mask, priority, func, aux, name, ctlno)
222 int level;
223 int mask;
224 int priority;
225 void (*func) __P((void *));
226 void *aux;
227 char *name;
228 int ctlno;
229 {
230 int i;
231 int nbit = -1;
232 struct ap_intrhand *aip;
233
234 for (i = 0; i < NBIT; i++) {
235 if (mask & (1 << i)) {
236 nbit = i;
237 break;
238 }
239 }
240
241 if (nbit == -1)
242 panic("apbus_intr_establish");
243
244 aip = &apintr[level][nbit];
245 aip->ai_mask = 1 << nbit;
246 aip->ai_priority = priority;
247 aip->ai_func = func;
248 aip->ai_aux = aux;
249 strncpy(aip->ai_name, name, APBUS_DEVNAMELEN-1);
250 aip->ai_ctlno = ctlno;
251
252 return (void *)aip;
253 }
254