1 /* $NetBSD: g2bus_bus_mem.c,v 1.3 2001/02/01 01:01:50 thorpej Exp $ */ 2 3 /*- 4 * Copyright (c) 2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe. 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 * Bus space implementation for the SEGA G2 bus. 41 * 42 * NOTE: We only implement a small subset of what the bus_space(9) 43 * API specifies. Right now, the GAPS PCI bridge is only used for 44 * the Dreamcast Broadband Adatper, so we only provide what the 45 * pci(4) and rtk(4) drivers need. 46 */ 47 48 #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 49 50 #include <sys/param.h> 51 #include <sys/systm.h> 52 #include <sys/device.h> 53 54 #include <machine/cpu.h> 55 #include <machine/bus.h> 56 #include <machine/cpufunc.h> 57 58 #include <dreamcast/dev/g2/g2busvar.h> 59 60 int g2bus_bus_mem_map(void *, bus_addr_t, bus_size_t, int, 61 bus_space_handle_t *); 62 void g2bus_bus_mem_unmap(void *, bus_space_handle_t, bus_size_t); 63 64 u_int8_t g2bus_bus_mem_read_1(void *, bus_space_handle_t, bus_size_t); 65 u_int16_t g2bus_bus_mem_read_2(void *, bus_space_handle_t, bus_size_t); 66 u_int32_t g2bus_bus_mem_read_4(void *, bus_space_handle_t, bus_size_t); 67 68 void g2bus_bus_mem_write_1(void *, bus_space_handle_t, bus_size_t, 69 u_int8_t); 70 void g2bus_bus_mem_write_2(void *, bus_space_handle_t, bus_size_t, 71 u_int16_t); 72 void g2bus_bus_mem_write_4(void *, bus_space_handle_t, bus_size_t, 73 u_int32_t); 74 75 void g2bus_bus_mem_read_region_1(void *, bus_space_handle_t, bus_size_t, 76 u_int8_t *, bus_size_t); 77 78 void g2bus_bus_mem_write_region_1(void *, bus_space_handle_t, bus_size_t, 79 const u_int8_t *, bus_size_t); 80 81 void 82 g2bus_bus_mem_init(struct g2bus_softc *sc) 83 { 84 bus_space_tag_t t = &sc->sc_memt; 85 86 memset(t, 0, sizeof(*t)); 87 88 t->dbs_map = g2bus_bus_mem_map; 89 t->dbs_unmap = g2bus_bus_mem_unmap; 90 91 t->dbs_r_1 = g2bus_bus_mem_read_1; 92 t->dbs_r_2 = g2bus_bus_mem_read_2; 93 t->dbs_r_4 = g2bus_bus_mem_read_4; 94 95 t->dbs_w_1 = g2bus_bus_mem_write_1; 96 t->dbs_w_2 = g2bus_bus_mem_write_2; 97 t->dbs_w_4 = g2bus_bus_mem_write_4; 98 99 t->dbs_rr_1 = g2bus_bus_mem_read_region_1; 100 101 t->dbs_wr_1 = g2bus_bus_mem_write_region_1; 102 } 103 104 int 105 g2bus_bus_mem_map(void *v, bus_addr_t addr, bus_size_t size, int flags, 106 bus_space_handle_t *shp) 107 { 108 109 KASSERT((addr & SH3_PHYS_MASK) == addr); 110 *shp = SH3_PHYS_TO_P2SEG(addr); 111 112 return (0); 113 } 114 115 void 116 g2bus_bus_mem_unmap(void *v, bus_space_handle_t sh, bus_size_t size) 117 { 118 119 KASSERT(sh >= SH3_P2SEG_BASE && sh <= SH3_P2SEG_END); 120 /* Nothing to do. */ 121 } 122 123 /* 124 * G2 bus cycles must not be interrupted by IRQs or G2 DMA. 125 * The following paired macros will take the necessary precautions. 126 */ 127 128 #define G2_LOCK \ 129 do { \ 130 disable_intr(); \ 131 /* suspend any G2 DMA here... */ \ 132 while((*(volatile unsigned int *)0xa05f688c) & 32); \ 133 } while(0) 134 135 #define G2_UNLOCK \ 136 do { \ 137 /* resume any G2 DMA here... */ \ 138 enable_intr(); \ 139 } while(0) 140 141 142 u_int8_t 143 g2bus_bus_mem_read_1(void *v, bus_space_handle_t sh, bus_size_t off) 144 { 145 u_int8_t rv; 146 147 G2_LOCK; 148 149 rv = *(__volatile u_int8_t *)(sh + off); 150 151 G2_UNLOCK; 152 153 return (rv); 154 } 155 156 u_int16_t 157 g2bus_bus_mem_read_2(void *v, bus_space_handle_t sh, bus_size_t off) 158 { 159 u_int16_t rv; 160 161 G2_LOCK; 162 163 rv = *(__volatile u_int16_t *)(sh + off); 164 165 G2_UNLOCK; 166 167 return (rv); 168 } 169 170 u_int32_t 171 g2bus_bus_mem_read_4(void *v, bus_space_handle_t sh, bus_size_t off) 172 { 173 u_int32_t rv; 174 175 G2_LOCK; 176 177 rv = *(__volatile u_int32_t *)(sh + off); 178 179 G2_UNLOCK; 180 181 return (rv); 182 } 183 184 void 185 g2bus_bus_mem_write_1(void *v, bus_space_handle_t sh, bus_size_t off, 186 u_int8_t val) 187 { 188 189 G2_LOCK; 190 191 *(__volatile u_int8_t *)(sh + off) = val; 192 193 G2_UNLOCK; 194 } 195 196 void 197 g2bus_bus_mem_write_2(void *v, bus_space_handle_t sh, bus_size_t off, 198 u_int16_t val) 199 { 200 201 G2_LOCK; 202 203 *(__volatile u_int16_t *)(sh + off) = val; 204 205 G2_UNLOCK; 206 } 207 208 void 209 g2bus_bus_mem_write_4(void *v, bus_space_handle_t sh, bus_size_t off, 210 u_int32_t val) 211 { 212 213 G2_LOCK; 214 215 *(__volatile u_int32_t *)(sh + off) = val; 216 217 G2_UNLOCK; 218 } 219 220 void 221 g2bus_bus_mem_read_region_1(void *v, bus_space_handle_t sh, bus_size_t off, 222 u_int8_t *addr, bus_size_t len) 223 { 224 __volatile const u_int8_t *baddr = (u_int8_t *)(sh + off); 225 226 G2_LOCK; 227 228 while (len--) 229 *addr++ = *baddr++; 230 231 G2_UNLOCK; 232 } 233 234 void 235 g2bus_bus_mem_write_region_1(void *v, bus_space_handle_t sh, bus_size_t off, 236 const u_int8_t *addr, bus_size_t len) 237 { 238 __volatile u_int8_t *baddr = (u_int8_t *)(sh + off); 239 240 G2_LOCK; 241 242 while (len--) 243 *baddr++ = *addr++; 244 245 G2_UNLOCK; 246 } 247