xel.c revision 1.7 1 /* $NetBSD: xel.c,v 1.7 2003/07/15 01:44:52 lukem Exp $ */
2
3 /*
4 * Copyright (c) 1998 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Minoura Makoto.
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 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39 /*
40 * TSR Xellent30 driver.
41 * Detect Xellent30, and reserve its I/O area.
42 */
43
44 #include <sys/cdefs.h>
45 __KERNEL_RCSID(0, "$NetBSD: xel.c,v 1.7 2003/07/15 01:44:52 lukem Exp $");
46
47 #include <sys/param.h>
48 #include <sys/systm.h>
49 #include <sys/kernel.h>
50 #include <sys/device.h>
51
52 #include <machine/cpu.h>
53 #include <machine/bus.h>
54
55 #include <arch/x68k/dev/intiovar.h>
56
57 static paddr_t xel_addr __P((struct device *, struct cfdata *,
58 struct intio_attach_args *));
59 static int xel_probe __P((paddr_t));
60 static int xel_match __P((struct device *, struct cfdata *, void *));
61 static void xel_attach __P((struct device *, struct device *, void *));
62
63 struct xel_softc {
64 struct device dev;
65
66 bus_space_tag_t sc_bst;
67 bus_space_handle_t sc_bh;
68 };
69
70 CFATTACH_DECL(xel, sizeof (struct xel_softc),
71 xel_match, xel_attach, NULL, NULL);
72
73 static paddr_t xel_addrs[] = { 0xec0000, 0xec4000, 0xec8000, 0xecc000 };
74
75 #define XEL_MODE_RAM_LOWER 0x00
76 #define XEL_MODE_RAM_HIGHER 0x01
77 #define XEL_MODE_UNMAP_RAM 0x00
78 #define XEL_MODE_MAP_RAM 0x02
79 #define XEL_MODE_MPU_000 0x00
80 #define XEL_MODE_MPU_030 0x04
81
82 #define XEL_RAM_ADDR_LOWER 0xbc0000
83 #define XEL_RAM_ADDR_HIGHER 0xfc0000
84
85
86 static paddr_t
87 xel_addr (parent, match, ia)
88 struct device *parent;
89 struct cfdata *match;
90 struct intio_attach_args *ia;
91 {
92 paddr_t addr = 0;
93
94 if (match->cf_addr == INTIOCF_ADDR_DEFAULT) {
95 int i;
96
97 for (i=0; i<sizeof(xel_addrs)/sizeof(xel_addrs[0]); i++) {
98 if (xel_probe(xel_addrs[i])) {
99 addr = xel_addrs[i];
100 break;
101 }
102 }
103 } else {
104 if (xel_probe((paddr_t) match->cf_addr))
105 addr = (paddr_t) match->cf_addr;
106 }
107
108 if (addr) {
109 /* found! */
110 ia->ia_addr = (int) addr;
111 ia->ia_size = 0x4000;
112 if (intio_map_allocate_region (parent, ia, INTIO_MAP_TESTONLY)
113 < 0)
114 return 0;
115 else
116 return addr;
117 }
118
119 return 0;
120 }
121
122 extern int *nofault;
123
124 static int
125 xel_probe(addr)
126 paddr_t addr;
127 {
128 u_int32_t b1, b2;
129 u_int16_t *start = (void*) INTIO_ADDR(addr);
130 label_t faultbuf;
131 volatile u_int32_t *sram = (void*) INTIO_ADDR(XEL_RAM_ADDR_HIGHER);
132
133 if (badaddr((caddr_t)start))
134 return 0;
135
136 nofault = (int *) &faultbuf;
137 if (setjmp(&faultbuf)) {
138 nofault = (int *) 0;
139 return 0;
140 }
141
142 b1 = sram[0];
143 b2 = sram[1];
144 /* Try to map the Xellent local memory. */
145 start[0] = XEL_MODE_RAM_HIGHER | XEL_MODE_MAP_RAM | XEL_MODE_MPU_030;
146
147 #if 0
148 /* the contents should be deferent. */
149 if (b1 == sram[0] && b2 == sram[1]) {
150 nofault = (int *) 0;
151 return 0;
152 }
153 #else
154 /* Try to write to the local memory. */
155 sram[0] = 0x55555555;
156 sram[1] = 0xaaaaaaaa;
157 if (sram[0] != 0x55555555 || sram[1] != 0xaaaaaaaa) {
158 sram[0] = b1;
159 sram[1] = b2;
160 nofault = (int *) 0;
161 return 0;
162 }
163 sram[0] = 0xaaaaaaaa;
164 sram[1] = 0x55555555;
165 if (sram[0] != 0xaaaaaaaa || sram[1] != 0x55555555) {
166 sram[0] = b1;
167 sram[1] = b2;
168 nofault = (int *) 0;
169 return 0;
170 }
171 sram[0] = b1;
172 sram[1] = b2;
173 #endif
174
175 /* Unmap. */
176 start[0] = XEL_MODE_UNMAP_RAM | XEL_MODE_MPU_030;
177
178 nofault = (int *) 0;
179 return 1;
180 }
181
182 static int
183 xel_match (parent, match, aux)
184 struct device *parent;
185 struct cfdata *match;
186 void *aux;
187 {
188 struct intio_attach_args *ia = aux;
189
190 if (strcmp (ia->ia_name, "xel") != 0)
191 return 0;
192
193 if (xel_addr(parent, match, ia)) {
194 #ifdef DIAGNOSTIC
195 if (cputype != CPU_68030)
196 panic ("Non-030 Xellent???");
197 #endif
198 return 1;
199 }
200 return 0;
201 }
202
203 static void
204 xel_attach (parent, self, aux)
205 struct device *parent, *self;
206 void *aux;
207 {
208 struct xel_softc *sc = (void*)self;
209 struct intio_attach_args *ia = aux;
210 struct cfdata *cf = self->dv_cfdata;
211 paddr_t addr;
212 int r;
213
214 addr = xel_addr(parent, cf, aux);
215 sc->sc_bst = ia->ia_bst;
216 ia->ia_addr = (int) addr;
217 ia->ia_size = 0x4000;
218 r = intio_map_allocate_region (parent, ia, INTIO_MAP_ALLOCATE);
219 #ifdef DIAGNOSTIC
220 if (r)
221 panic ("IO map for Xellent30 corruption??");
222 #endif
223 printf (": Xellent30 MPU Accelerator.\n");
224
225 return;
226 }
227