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