1 /* $NetBSD: p5bus.c,v 1.6 2021/08/07 16:18:41 thorpej Exp $ */
2
3 /*-
4 * Copyright (c) 2011, 2012 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Radoslaw Kujawa.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 /* Driver for internal BlizzardPPC, CyberStorm Mk-III/PPC bus. */
33
34 #include <sys/cdefs.h>
35
36 #include <sys/systm.h>
37 #include <sys/types.h>
38 #include <sys/device.h>
39 #include <sys/kmem.h>
40
41 #include <amiga/dev/zbusvar.h>
42 #include <amiga/dev/p5busvar.h>
43
44 #define ZORRO_MANID_P5 8512
45 #define ZORRO_PRODID_CSPPC 100
46 #define ZORRO_PRODID_BPPC 110
47
48 #define P5_ROM_OFF 0xF00010
49 #define P5_SN_LEN 7
50
51 static int p5bus_match(device_t, cfdata_t, void *);
52 static void p5bus_attach(device_t, device_t, void *);
53 static char* p5bus_cardsn(void);
54 static int p5bus_print(void *aux, const char *str);
55 static void p5bus_callback(device_t self);
56
57 struct p5bus_softc {
58 device_t sc_dev;
59 uint8_t sc_cardtype;
60 uint8_t sc_has_scsi;
61 #define P5BUS_SCSI_NONE 0
62 #define P5BUS_SCSI_710 1 /* NCR 53C710 */
63 #define P5BUS_SCSI_770 2 /* NCR 53C770 */
64 uint8_t sc_has_ppc;
65 #define P5BUS_PPC_NONE 0 /* CS Mk-III only */
66 #define P5BUS_PPC_OK 1 /* has working PPC CPU */
67 };
68
69 CFATTACH_DECL_NEW(p5bus, sizeof(struct p5bus_softc),
70 p5bus_match, p5bus_attach, NULL, NULL);
71
72 static int
p5bus_match(device_t parent,cfdata_t cf,void * aux)73 p5bus_match(device_t parent, cfdata_t cf, void *aux)
74 {
75 struct zbus_args *zap;
76
77 zap = aux;
78
79 if (zap->manid != ZORRO_MANID_P5)
80 return 0;
81
82
83 if ((zap->prodid != ZORRO_PRODID_BPPC) &&
84 (zap->prodid != ZORRO_PRODID_CSPPC))
85 return 0;
86
87 return 1;
88 }
89
90 static void
p5bus_attach(device_t parent,device_t self,void * aux)91 p5bus_attach(device_t parent, device_t self, void *aux)
92 {
93 struct p5bus_softc *sc;
94 struct zbus_args *zap;
95 struct p5bus_attach_args p5baa;
96 char *sn;
97
98 zap = aux;
99 sc = device_private(self);
100 sc->sc_dev = self;
101
102 sn = p5bus_cardsn();
103
104 aprint_normal(": Phase5 PowerUP on-board bus\n");
105
106 /* "Detect" what devices are present and attach the right drivers. */
107
108 if (zap->prodid == ZORRO_PRODID_CSPPC) {
109
110 if (sn[0] == 'F') {
111 aprint_normal_dev(sc->sc_dev,
112 "CyberStorm Mk-III (sn %s)\n", sn);
113 sc->sc_has_ppc = P5BUS_PPC_NONE;
114 } else {
115 aprint_normal_dev(sc->sc_dev,
116 "CyberStorm PPC 604e (sn %s)\n", sn);
117 sc->sc_has_ppc = P5BUS_PPC_OK;
118 }
119
120 sc->sc_cardtype = P5_CARDTYPE_CS;
121 sc->sc_has_scsi = P5BUS_SCSI_770;
122
123 } else if (zap->prodid == ZORRO_PRODID_BPPC) {
124
125 if (sn[0] != 'I') { /* only "+" model has SCSI */
126 aprint_normal_dev(sc->sc_dev,
127 "BlizzardPPC 603e (sn %s)\n", sn);
128 sc->sc_has_scsi = P5BUS_SCSI_NONE;
129 } else {
130 aprint_normal_dev(sc->sc_dev,
131 "BlizzardPPC 603e+ (sn %s)\n", sn);
132 sc->sc_has_scsi = P5BUS_SCSI_710;
133 }
134
135 sc->sc_cardtype = P5_CARDTYPE_BPPC;
136 sc->sc_has_ppc = P5BUS_PPC_OK;
137
138 }
139
140 p5baa.p5baa_cardtype = sc->sc_cardtype;
141
142 /* Attach the SCSI host adapters. */
143 switch (sc->sc_has_scsi) {
144 case P5BUS_SCSI_710:
145 strcpy(p5baa.p5baa_name, "bppcsc");
146 config_found(sc->sc_dev, &p5baa, p5bus_print, CFARGS_NONE);
147 break;
148 case P5BUS_SCSI_770:
149 strcpy(p5baa.p5baa_name, "cbiiisc");
150 config_found(sc->sc_dev, &p5baa, p5bus_print, CFARGS_NONE);
151 break;
152 default:
153 break;
154 }
155
156 /*
157 * We need to wait for possible p5membar attachments. Defer the rest
158 * until parent (zbus) is completely configured.
159 */
160 config_defer(self, p5bus_callback);
161
162 }
163
164 /* Continue the attachment. */
165 static void
p5bus_callback(device_t self)166 p5bus_callback(device_t self) {
167
168 struct p5bus_attach_args p5baa;
169 struct p5bus_softc *sc;
170
171 sc = device_private(self);
172 p5baa.p5baa_cardtype = sc->sc_cardtype;
173
174 /* p5pb is always found, probe is inside of p5pb driver */
175 strcpy(p5baa.p5baa_name, "p5pb");
176 config_found(sc->sc_dev, &p5baa, p5bus_print, CFARGS_NONE);
177 }
178
179 /* Get serial number of the card. */
180 static char *
p5bus_cardsn(void)181 p5bus_cardsn(void)
182 {
183 char *snr, *sn;
184
185 sn = kmem_zalloc(P5_SN_LEN + 1, KM_SLEEP);
186 snr = (char *)__UNVOLATILE(ztwomap(P5_ROM_OFF));
187
188 memcpy(sn, snr, P5_SN_LEN);
189 return sn;
190 }
191
192 static int
p5bus_print(void * aux,const char * str)193 p5bus_print(void *aux, const char *str)
194 {
195 if (str == NULL)
196 return 0;
197
198 printf("%s ", str);
199
200 return 0;
201 }
202