1 /*        $NetBSD: zbus.c,v 1.78 2023/05/03 13:49:30 phx Exp $ */
2 
3 /*
4  * Copyright (c) 1994 Christian E. Hopps
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *      This product includes software developed by Christian E. Hopps.
18  * 4. The name of the author may not be used to endorse or promote products
19  *    derived from this software without specific prior written permission
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #include <sys/cdefs.h>
34 __KERNEL_RCSID(0, "$NetBSD: zbus.c,v 1.78 2023/05/03 13:49:30 phx Exp $");
35 
36 #include <sys/param.h>
37 #include <sys/device.h>
38 #include <sys/systm.h>
39 #include <sys/bus.h>
40 
41 #include <machine/cpu.h>
42 #include <machine/pte.h>
43 #include <amiga/amiga/cfdev.h>
44 #include <amiga/amiga/device.h>
45 #include <amiga/dev/zbusvar.h>
46 #include <amiga/dev/z3rambdvar.h>
47 
48 #include "z3rambd.h"
49 
50 struct aconfdata {
51           const char *name;
52           int manid;
53           int prodid;
54 };
55 
56 struct preconfdata {
57           int manid;
58           int prodid;
59           void *vaddr;
60 };
61 
62 struct quirksdata {
63           int manid;
64           int prodid;
65           uint8_t quirks;
66 };
67 
68 vaddr_t             ZTWOROMADDR;
69 vaddr_t             ZTWOMEMADDR;
70 u_int               NZTWOMEMPG;
71 vaddr_t             ZBUSADDR; /* kva of Zorro bus I/O pages */
72 u_int               ZBUSAVAIL;          /* bytes of Zorro bus I/O space left */
73 
74 /*
75  * explain the names.. 0123456789 => zothfisven
76  */
77 static const struct aconfdata aconftab[] = {
78           /* Commodore Amiga */
79           { "atzee",          513,      1 },
80           { "atzsc",          514,      2 },
81           { "atzsc",          514,      3 },
82           { "bah",  514,      9 },      /* A2060 */
83           { "ql",             514,      69 },
84           { "ql",             514,      70 },
85           { "atfsc",          514,      84 },
86           { "le",             514,      112 },
87           /* Ameristar */
88           { "le",             1053,     1 },
89           { "bah",  1053,     9 },      /* A2060 */
90           { "es",             1053,     10 },
91           /* University of Lowell */
92           { "grful",          1030,     0 },
93           /* DMI */
94           { "grfrs",          2129,     1 },      /* Resolver graphics board */
95           /* Macrosystems */
96           { "grfrt",          18260,    6 },
97           { "grfrh",          18260,    16},      /* Retina BLT Z3 */
98           { "grfrh",          18260,    19},      /* Altais */
99           /* Greater valley products */
100           { "gvpbus",         2017,     2 },
101           { "gvpbus",         2017,     11 },
102           { "giv",  2017,     32 },
103           { "gio",  2017,     255 },
104           /* progressive perhiperals */
105           { "zssc", 2026,     150 },
106           { "ppia", 2026,     187 },
107           { "ppta", 2026,     105 },
108           { "ppha", 2026,     1 },
109           { "mrsc", 2026,     0 },
110           /* CSA */
111           { "mgnsc",          1058,     17 },
112           { "otgsc",          1058,     21 },
113           /* Microbotics */
114           { "vhzsc",          1010,     69 },
115           /* Supra */
116           { "wstsc",          1056,     12 },
117           { "wstsc",          1056,     13 },
118           /* IVS */
119           { "itrmp",          2112,     48 },
120           { "itrmp",          2112,     52 },
121           { "ivasc",          2112,     242 },
122           { "ivsc", 2112,     243 },
123           /* Hydra */
124           { "ed",             2121,     1 },
125           /* ASDG */
126           { "ed",             1023,     254 },
127           /* Village Tronic Ariadne */
128           { "le",             2167,     201},
129           /* Village Tronic Ariadne II */
130           { "ne",             2167,     202},
131           /* bsc/Alf Data */
132           { "Tandem", 2092,    6 },     /* Tandem AT disk controller */
133           { "mfc",  2092,     16 },
134           { "mfc",  2092,     17 },
135           { "mfc",  2092,     18 },
136           /* Cirrus CL GD 5426 -> Picasso, Piccolo, EGS Spectrum */
137           { "grfcl",          2167,     11},      /* PicassoII mem */
138           { "grfcl",          2167,     12},      /* PicassoII regs */
139           { "grfcl",          2167,     21},      /* PicassoIV Z2 mem1 */
140           { "grfcl",          2167,     22},      /* PicassoIV Z2 mem2 */
141           { "grfcl",          2167,     23},      /* PicassoIV Z2 regs */
142           { "grfcl",          2167,     24},      /* PicassoIV Z3 */
143           { "grfcl",          2193,     2},       /* Spectrum mem */
144           { "grfcl",          2193,     1},       /* Spectrum regs */
145           { "grfcl",          2195,     5},       /* Piccolo mem */
146           { "grfcl",          2195,     6},       /* Piccolo regs */
147           { "grfcl",          2195,     10},      /* Piccolo SD64 mem */
148           { "grfcl",          2195,     11},      /* Piccolo SD64 regs */
149           /* MacroSystemsUS */
150           { "wesc", 2203,     19},      /* Warp engine */
151           /* phase 5 digital products */
152           { "flmem",          8512,     10},      /* FastlaneZ3 memory */
153           { "flsc", 8512,     11},      /* FastlaneZ3 */
154           { "cbsc", 8512,     12},      /* Cyberstorm Mk I SCSI */
155           { "bzivsc",         8512,     17},      /* Blizzard IV SCSI */
156           { "bztzsc",         8512,     24},      /* Blizzard 2060 SCSI */
157           { "cbiisc",         8512,     25},      /* Cyberstorm Mk II SCSI */
158           { "grfcv",          8512,     34},      /* CyberVison 64 */
159           { "grfcv3d",        8512,     67},      /* CyberVison 64/3D */
160           { "cbiiisc",        8512,     100},     /* Cyberstorm Mk III SCSI */
161           { "p5pb",           8512,     101},     /* CyberVisionPPC / BlizzardVisionPPC */
162           { "bppcsc",         8512,     110},     /* Blizzard 603e+ SCSI */
163           /* Hacker Inc. */
164           { "mlhsc",          2011,     1 },
165           /* Resource Management Force */
166           { "qn",             2011,     2 },      /* QuickNet Ethernet */
167           /* ??? */
168           { "empsc",          2171,     21 },     /* Emplant SCSI */
169           { "empsc",          2171,     32 },     /* Emplant SCSI */
170           /* Tseng ET4000 boards */
171           { "grfet",          2117,     3 },      /* Merlin mem */
172           { "grfet",          2117,     4 },      /* Merlin regs */
173           { "grfet",          2167,     1 },      /* Domino mem */
174           { "grfet",          2167,     2 },      /* Domino regs */
175           { "grfet",          2167,     3 },      /* Domino regs (proto 16M) */
176           { "grfet",          2181,     0 },      /* oMniBus */
177           /* Advanced Systems */
178           { "nxsc", 2102,     1 },      /* Nexus SCSI board */
179           /* Masoboshi */
180           { "mcsc", 8535,     4 },      /* Masoboshi Mastercard 702 */
181           /* Apollo */
182           { "apssc",          8738,     35 },     /* Apollo '060 scsi */
183           /* KATO development */
184           { "aumld",          2145,     128 },    /* Melody MPEG layer 2 audio board */
185           /* Individual Computers Jens Schoenfeld */
186           { "buddha",         4626,     0 },
187           { "xsurf",          4626,     23 },     /* X-Surf Ethernet */
188           /* VMC Harald Frank */
189           { "blst", 5001,     1},       /* ISDN Blaster */
190           { "hyper4",         5001,     2},       /* Hypercom4-Zbus */
191           { "hyper3Z",        5001,     3},       /* Hypercom3-Zbus */
192           { "hyper4+",        5001,     6},       /* Hypercom4+ */
193           { "hyper3+",        5001,     7},       /* Hypercom3+ */
194           /* Matay Grzegorz Kraszewski */
195           { "mppb", 44359,    1},       /* Prometheus PCI bridge */
196           /* MNT */
197           { "mntva",          28014,    1},       /* MNT VA2000 */
198           { "zz9k", 28014,    3},       /* MNT ZZ9000 Z2 */
199           { "zz9k", 28014,    4},       /* MNT ZZ9000 Z3 */
200           { "zz9k", 28014,    5}        /* MNT ZZ9000 Z3 256MB */
201 };
202 static int naconfent = sizeof(aconftab) / sizeof(struct aconfdata);
203 
204 /*
205  * Anything listed in this table is subject to pre-configuration,
206  * if autoconf.c:config_console() calls amiga_config_found() on
207  * the Zorro III device.
208  */
209 static struct preconfdata preconftab[] = {
210           {18260, 6, 0 },     /* Retina Z2 */                         /* grf1 */
211           {18260, 16, 0}, /* Retina BLT Z3 */               /* grf2 */
212           {18260, 19, 0}, /* Altais */
213           {2167,    11, 0},   /* PicassoII mem */           /* grf3 */
214           {2167,    12, 0},   /* PicassoII regs */
215           {2167,    21, 0},   /* PicassoIV Z2 mem1 */
216           {2167,    22, 0},   /* PicassoIV Z2 mem2 */
217           {2167,    23, 0},   /* PicassoIV Z2 regs */
218           {2167,    24, 0},   /* PicassoIV Z3 */
219           {2193,    2, 0},    /* Spectrum mem */
220           {2193,    1, 0},    /* Spectrum regs */
221           {2195,    5, 0},    /* Piccolo mem */
222           {2195,    6, 0},    /* Piccolo regs */
223           {2195,    10, 0},   /* Piccolo SD64 mem */
224           {2195,    11, 0},   /* Piccolo SD64 regs */
225           {1030,    0, 0},    /* Ulwl board */              /* grf4 */
226           {8512,    34, 0},   /* Cybervison 64 */           /* grf5 */
227           {2117,    3, 0},    /* Merlin mem */              /* grf6 */
228           {2117,    4, 0},    /* Merlin regs */
229           {2167,    1, 0},    /* Domino mem */
230           {2167,    2, 0},    /* Domino regs */
231           {2167,    3, 0},    /* Domino regs (proto 16M) */
232           {2181,    0, 0},    /* oMniBus mem or regs */
233           {8512,    67, 0},   /* Cybervison 64/3D */                  /* grf7 */
234 /*        {28014,   1, 0},    // MNTMN VA2000 */
235           {28014,   3, 0},    /* MNT ZZ9000 Z2 */
236           {28014,   4, 0}     /* MNT ZZ9000 Z3 */
237 };
238 static int npreconfent = sizeof(preconftab) / sizeof(struct preconfdata);
239 
240 /*
241  * Quirks table.
242  */
243 #define ZORRO_QUIRK_NO_ZBUSMAP 1        /* Don't map VA=PA in zbusattach. */
244 static struct quirksdata quirkstab[] = {
245           {8512, 101, ZORRO_QUIRK_NO_ZBUSMAP}
246 };
247 static int nquirksent = sizeof(quirkstab) / sizeof(struct quirksdata);
248 
249 void zbusattach(device_t, device_t, void *);
250 int zbusprint(void *, const char *);
251 int zbusmatch(device_t, cfdata_t, void *);
252 static const char *aconflookup(int, int);
253 
254 /*
255  * given a manufacturer id and product id, find quirks
256  * for this board.
257  */
258 
259 static uint8_t
quirkslookup(int mid,int pid)260 quirkslookup(int mid, int pid)
261 {
262           const struct quirksdata *qdp, *eqdp;
263 
264           eqdp = &quirkstab[nquirksent];
265           for (qdp = quirkstab; qdp < eqdp; qdp++)
266                     if (qdp->manid == mid && qdp->prodid == pid)
267                               return(qdp->quirks);
268           return(0);
269 }
270 
271 /*
272  * given a manufacturer id and product id, find the name
273  * that describes this board.
274  */
275 static const char *
aconflookup(int mid,int pid)276 aconflookup(int mid, int pid)
277 {
278           const struct aconfdata *adp, *eadp;
279 
280           eadp = &aconftab[naconfent];
281           for (adp = aconftab; adp < eadp; adp++)
282                     if (adp->manid == mid && adp->prodid == pid)
283                               return(adp->name);
284           return("board");
285 }
286 
287 /*
288  * mainbus driver
289  */
290 
291 CFATTACH_DECL_NEW(zbus, 0,
292     zbusmatch, zbusattach, NULL, NULL);
293 
294 static cfdata_t early_cfdata;
295 
296 /*ARGSUSED*/
297 int
zbusmatch(device_t parent,cfdata_t cf,void * aux)298 zbusmatch(device_t parent, cfdata_t cf, void *aux)
299 {
300 
301           if (matchname(aux, "zbus") == 0)
302                     return(0);
303           if (amiga_realconfig == 0)
304                     early_cfdata = cf;
305           return(1);
306 }
307 
308 /*
309  * called to attach bus, we probe, i.e., scan configdev structs passed
310  * in, for each found name call config_found() which will do this again
311  * with that driver if matched else print a diag.
312  */
313 void
zbusattach(device_t parent,device_t self,void * aux)314 zbusattach(device_t parent, device_t self, void *aux)
315 {
316           struct zbus_args za;
317           struct preconfdata *pcp, *epcp;
318           struct cfdev *cdp, *ecdp;
319 
320           epcp = &preconftab[npreconfent];
321           ecdp = &cfdev[ncfdev];
322           if (amiga_realconfig) {
323                     if (ZTWOMEMADDR)
324                               printf(": mem 0x%08lx-0x%08lx",
325                                   ZTWOMEMADDR,
326                                   ZTWOMEMADDR + PAGE_SIZE * NZTWOMEMPG - 1);
327                     if (ZBUSAVAIL)
328                               printf (": i/o size 0x%08x", ZBUSAVAIL);
329                     printf("\n");
330           }
331           for (cdp = cfdev; cdp < ecdp; cdp++) {
332                     for (pcp = preconftab; pcp < epcp; pcp++) {
333                               if (pcp->manid == cdp->rom.manid &&
334                                   pcp->prodid == cdp->rom.prodid)
335                                         break;
336                     }
337                     if (amiga_realconfig == 0 && pcp >= epcp)
338                               continue;
339 
340 #if NZ3RAMBD > 0
341                     if (z3rambd_match_id(cdp->rom.manid, cdp->rom.prodid) > 0)
342                     { }
343                     else
344 #endif /* NZ3RAMBD */
345                     /*
346                      * check if it's a Zorro II or III board and not linked into
347                      * MemList (i.e. not a memory board)
348                      */
349                     switch (cdp->rom.type & (ERT_TYPEMASK | ERTF_MEMLIST)) {
350                     case ERT_ZORROII:
351                     case ERT_ZORROIII:
352                               break;
353                     default:
354                               continue;
355                     }
356 
357                     za.pa = cdp->addr;
358                     za.size = cdp->size;
359                     za.manid = cdp->rom.manid;
360                     za.prodid = cdp->rom.prodid;
361                     za.serno = cdp->rom.serno;
362                     za.slot = (((u_long)za.pa >> 16) & 0xF) - 0x9;
363 
364                     if (amiga_realconfig && pcp < epcp && pcp->vaddr)
365                               za.va = pcp->vaddr;
366                     else {
367                               if(quirkslookup(za.manid, za.prodid) !=
368                                   ZORRO_QUIRK_NO_ZBUSMAP)
369                                         za.va = (void *) (isztwopa(za.pa) ?
370                                             __UNVOLATILE(ztwomap(za.pa)) :
371                                             zbusmap(za.pa, za.size));
372                               /*
373                                * save value if early console init
374                                */
375                               if (amiga_realconfig == 0)
376                                         pcp->vaddr = za.va;
377                     }
378                     amiga_config_found(early_cfdata, self, &za, zbusprint,
379                                            CFARGS_NONE);
380           }
381 }
382 
383 /*
384  * print configuration info.
385  */
386 int
zbusprint(void * aux,const char * pnp)387 zbusprint(void *aux, const char *pnp)
388 {
389           struct zbus_args *zap;
390           int rv;
391 
392           rv = UNCONF;
393           zap = aux;
394 
395           if (pnp) {
396                     aprint_normal("%s at %s:",
397                         aconflookup(zap->manid, zap->prodid), pnp);
398                     if (zap->manid == -1)
399                               rv = UNSUPP;
400           }
401           aprint_normal(" pa %8p man/pro %d/%d", zap->pa, zap->manid,
402               zap->prodid);
403           return(rv);
404 }
405 
406 /*
407  * this function is used to map Zorro physical I/O addresses into kernel
408  * virtual addresses. We don't keep track which address we map where, we don't
409  * NEED to know this. We made sure in amiga_init.c (by scanning all available
410  * Zorro devices) to have enough kva-space available, so there is no extra
411  * range check done here.
412  */
413 void *
zbusmap(void * pa,u_int size)414 zbusmap(void *pa, u_int size)
415 {
416 #if defined(__m68k__)
417           static vaddr_t nextkva = 0;
418           vaddr_t kva;
419 
420           if (nextkva == 0)
421                     nextkva = ZBUSADDR;
422 
423           if (nextkva > ZBUSADDR + ZBUSAVAIL)
424                     return 0;
425 
426           /* size better be an integral multiple of the page size... */
427           kva = nextkva;
428           nextkva += size;
429           if (nextkva > ZBUSADDR + ZBUSAVAIL)
430                     panic("allocating too much Zorro I/O address space");
431           physaccess((void *)kva, (void *)pa, size, PG_RW|PG_CI);
432           return((void *)kva);
433 #else
434 /*
435  * XXX we use direct constant mapping
436  */
437           return(pa);
438 #endif
439 }
440