1 /* $NetBSD: g2bus_bus_mem.c,v 1.14 2008/04/28 20:23:16 martin Exp $ */
4 * Copyright (c) 2001 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
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.
33 * Bus space implementation for the SEGA G2 bus.
35 * NOTE: We only implement a small subset of what the bus_space(9)
36 * API specifies. Right now, the GAPS PCI bridge is only used for
37 * the Dreamcast Broadband Adatper, so we only provide what the
38 * pci(4) and rtk(4) drivers need.
41 #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
42 __KERNEL_RCSID(0, "$NetBSD: g2bus_bus_mem.c,v 1.14 2008/04/28 20:23:16 martin Exp $");
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/device.h>
48 #include <machine/cpu.h>
49 #include <machine/bus.h>
51 #include <dreamcast/dev/g2/g2busvar.h>
53 int g2bus_bus_mem_map(void *, bus_addr_t
, bus_size_t
, int,
54 bus_space_handle_t
*);
55 void g2bus_bus_mem_unmap(void *, bus_space_handle_t
, bus_size_t
);
56 paddr_t
g2bus_bus_mem_mmap(void *, bus_addr_t
, off_t
, int, int);
58 uint8_t g2bus_bus_mem_read_1(void *, bus_space_handle_t
, bus_size_t
);
59 uint16_t g2bus_bus_mem_read_2(void *, bus_space_handle_t
, bus_size_t
);
60 uint32_t g2bus_bus_mem_read_4(void *, bus_space_handle_t
, bus_size_t
);
62 void g2bus_bus_mem_write_1(void *, bus_space_handle_t
, bus_size_t
,
64 void g2bus_bus_mem_write_2(void *, bus_space_handle_t
, bus_size_t
,
66 void g2bus_bus_mem_write_4(void *, bus_space_handle_t
, bus_size_t
,
69 void g2bus_bus_mem_read_region_1(void *, bus_space_handle_t
, bus_size_t
,
70 uint8_t *, bus_size_t
);
71 void g2bus_bus_mem_read_region_2(void *, bus_space_handle_t
, bus_size_t
,
72 uint16_t *, bus_size_t
);
73 void g2bus_bus_mem_read_region_4(void *, bus_space_handle_t
, bus_size_t
,
74 uint32_t *, bus_size_t
);
76 void g2bus_bus_mem_write_region_1(void *, bus_space_handle_t
, bus_size_t
,
77 const uint8_t *, bus_size_t
);
78 void g2bus_bus_mem_write_region_2(void *, bus_space_handle_t
, bus_size_t
,
79 const uint16_t *, bus_size_t
);
80 void g2bus_bus_mem_write_region_4(void *, bus_space_handle_t
, bus_size_t
,
81 const uint32_t *, bus_size_t
);
83 void g2bus_bus_mem_set_region_4(void *, bus_space_handle_t
, bus_size_t
,
84 uint32_t, bus_size_t
);
86 uint8_t g2bus_sparse_bus_mem_read_1(void *, bus_space_handle_t
, bus_size_t
);
87 uint16_t g2bus_sparse_bus_mem_read_2(void *, bus_space_handle_t
, bus_size_t
);
88 uint32_t g2bus_sparse_bus_mem_read_4(void *, bus_space_handle_t
, bus_size_t
);
90 void g2bus_sparse_bus_mem_write_1(void *, bus_space_handle_t
, bus_size_t
,
92 void g2bus_sparse_bus_mem_write_2(void *, bus_space_handle_t
, bus_size_t
,
94 void g2bus_sparse_bus_mem_write_4(void *, bus_space_handle_t
, bus_size_t
,
97 void g2bus_sparse_bus_mem_read_region_1(void *, bus_space_handle_t
,
98 bus_size_t
, uint8_t *, bus_size_t
);
100 void g2bus_sparse_bus_mem_write_region_1(void *, bus_space_handle_t
,
101 bus_size_t
, const uint8_t *, bus_size_t
);
103 void g2bus_sparse_bus_mem_read_multi_1(void *, bus_space_handle_t
,
104 bus_size_t
, uint8_t *, bus_size_t
);
106 void g2bus_sparse_bus_mem_write_multi_1(void *, bus_space_handle_t
,
107 bus_size_t
, const uint8_t *, bus_size_t
);
110 g2bus_bus_mem_init(struct g2bus_softc
*sc
)
112 bus_space_tag_t t
= &sc
->sc_memt
;
114 memset(t
, 0, sizeof(*t
));
116 t
->dbs_map
= g2bus_bus_mem_map
;
117 t
->dbs_unmap
= g2bus_bus_mem_unmap
;
118 t
->dbs_mmap
= g2bus_bus_mem_mmap
;
120 t
->dbs_r_1
= g2bus_bus_mem_read_1
;
121 t
->dbs_r_2
= g2bus_bus_mem_read_2
;
122 t
->dbs_r_4
= g2bus_bus_mem_read_4
;
124 t
->dbs_w_1
= g2bus_bus_mem_write_1
;
125 t
->dbs_w_2
= g2bus_bus_mem_write_2
;
126 t
->dbs_w_4
= g2bus_bus_mem_write_4
;
128 t
->dbs_rr_1
= g2bus_bus_mem_read_region_1
;
129 t
->dbs_rr_2
= g2bus_bus_mem_read_region_2
;
130 t
->dbs_rr_4
= g2bus_bus_mem_read_region_4
;
132 t
->dbs_wr_1
= g2bus_bus_mem_write_region_1
;
133 t
->dbs_wr_2
= g2bus_bus_mem_write_region_2
;
134 t
->dbs_wr_4
= g2bus_bus_mem_write_region_4
;
136 t
->dbs_sr_4
= g2bus_bus_mem_set_region_4
;
140 g2bus_bus_mem_map(void *v
, bus_addr_t addr
, bus_size_t size
, int flags
,
141 bus_space_handle_t
*shp
)
144 KASSERT((addr
& SH3_PHYS_MASK
) == addr
);
145 *shp
= SH3_PHYS_TO_P2SEG(addr
);
151 g2bus_bus_mem_unmap(void *v
, bus_space_handle_t sh
, bus_size_t size
)
154 KASSERT(sh
>= SH3_P2SEG_BASE
&& sh
<= SH3_P2SEG_END
);
159 g2bus_bus_mem_mmap(void *v
, bus_addr_t addr
, off_t offset
, int prot
, int flags
)
162 /* XXX not implemented */
167 * G2 bus cycles must not be interrupted by IRQs or G2 DMA.
168 * The following paired macros will take the necessary precautions.
171 #define G2LOCK_DECL \
176 __s = _cpu_intr_suspend(); \
177 /* suspend any G2 DMA here... */ \
178 while ((*(volatile uint32_t *)0xa05f688c) & 0x20) \
180 } while (/*CONSTCOND*/0)
182 #define G2_UNLOCK() \
184 /* resume any G2 DMA here... */ \
185 _cpu_intr_resume(__s); \
186 } while (/*CONSTCOND*/0)
189 g2bus_bus_mem_read_1(void *v
, bus_space_handle_t sh
, bus_size_t off
)
196 rv
= *(volatile uint8_t *)(sh
+ off
);
204 g2bus_bus_mem_read_2(void *v
, bus_space_handle_t sh
, bus_size_t off
)
211 rv
= *(volatile uint16_t *)(sh
+ off
);
219 g2bus_bus_mem_read_4(void *v
, bus_space_handle_t sh
, bus_size_t off
)
226 rv
= *(volatile uint32_t *)(sh
+ off
);
234 g2bus_bus_mem_write_1(void *v
, bus_space_handle_t sh
, bus_size_t off
,
241 *(volatile uint8_t *)(sh
+ off
) = val
;
247 g2bus_bus_mem_write_2(void *v
, bus_space_handle_t sh
, bus_size_t off
,
254 *(volatile uint16_t *)(sh
+ off
) = val
;
260 g2bus_bus_mem_write_4(void *v
, bus_space_handle_t sh
, bus_size_t off
,
267 *(volatile uint32_t *)(sh
+ off
) = val
;
273 g2bus_bus_mem_read_region_1(void *v
, bus_space_handle_t sh
, bus_size_t off
,
274 uint8_t *addr
, bus_size_t len
)
277 volatile const uint8_t *baddr
= (uint8_t *)(sh
+ off
);
288 g2bus_bus_mem_read_region_2(void *v
, bus_space_handle_t sh
, bus_size_t off
,
289 uint16_t *addr
, bus_size_t len
)
292 volatile const uint16_t *baddr
= (uint16_t *)(sh
+ off
);
303 g2bus_bus_mem_read_region_4(void *v
, bus_space_handle_t sh
, bus_size_t off
,
304 uint32_t *addr
, bus_size_t len
)
307 volatile const uint32_t *baddr
= (uint32_t *)(sh
+ off
);
318 g2bus_bus_mem_write_region_1(void *v
, bus_space_handle_t sh
, bus_size_t off
,
319 const uint8_t *addr
, bus_size_t len
)
322 volatile uint8_t *baddr
= (uint8_t *)(sh
+ off
);
333 g2bus_bus_mem_write_region_2(void *v
, bus_space_handle_t sh
, bus_size_t off
,
334 const uint16_t *addr
, bus_size_t len
)
337 volatile uint16_t *baddr
= (uint16_t *)(sh
+ off
);
348 g2bus_bus_mem_write_region_4(void *v
, bus_space_handle_t sh
, bus_size_t off
,
349 const uint32_t *addr
, bus_size_t len
)
352 volatile uint32_t *baddr
= (uint32_t *)(sh
+ off
);
363 g2bus_bus_mem_set_region_4(void *v
, bus_space_handle_t sh
, bus_size_t off
,
364 uint32_t val
, bus_size_t len
)
367 volatile uint32_t *baddr
= (uint32_t *)(sh
+ off
);
378 g2bus_set_bus_mem_sparse(bus_space_tag_t memt
)
381 memt
->dbs_r_1
= g2bus_sparse_bus_mem_read_1
;
382 memt
->dbs_r_2
= g2bus_sparse_bus_mem_read_2
;
383 memt
->dbs_r_4
= g2bus_sparse_bus_mem_read_4
;
385 memt
->dbs_w_1
= g2bus_sparse_bus_mem_write_1
;
386 memt
->dbs_w_2
= g2bus_sparse_bus_mem_write_2
;
387 memt
->dbs_w_4
= g2bus_sparse_bus_mem_write_4
;
389 memt
->dbs_rr_1
= g2bus_sparse_bus_mem_read_region_1
;
391 memt
->dbs_wr_1
= g2bus_sparse_bus_mem_write_region_1
;
393 memt
->dbs_rm_1
= g2bus_sparse_bus_mem_read_multi_1
;
395 memt
->dbs_wm_1
= g2bus_sparse_bus_mem_write_multi_1
;
399 g2bus_sparse_bus_mem_read_1(void *v
, bus_space_handle_t sh
, bus_size_t off
)
406 rv
= *(volatile uint8_t *)(sh
+ (off
* 4));
414 g2bus_sparse_bus_mem_read_2(void *v
, bus_space_handle_t sh
, bus_size_t off
)
421 rv
= *(volatile uint16_t *)(sh
+ (off
* 4));
429 g2bus_sparse_bus_mem_read_4(void *v
, bus_space_handle_t sh
, bus_size_t off
)
436 rv
= *(volatile uint32_t *)(sh
+ (off
* 4));
444 g2bus_sparse_bus_mem_write_1(void *v
, bus_space_handle_t sh
, bus_size_t off
,
451 *(volatile uint8_t *)(sh
+ (off
* 4)) = val
;
457 g2bus_sparse_bus_mem_write_2(void *v
, bus_space_handle_t sh
, bus_size_t off
,
464 *(volatile uint16_t *)(sh
+ (off
* 4)) = val
;
470 g2bus_sparse_bus_mem_write_4(void *v
, bus_space_handle_t sh
, bus_size_t off
,
477 *(volatile uint32_t *)(sh
+ (off
* 4)) = val
;
483 g2bus_sparse_bus_mem_read_region_1(void *v
, bus_space_handle_t sh
,
484 bus_size_t off
, uint8_t *addr
, bus_size_t len
)
487 volatile const uint8_t *baddr
= (uint8_t *)(sh
+ (off
* 4));
500 g2bus_sparse_bus_mem_write_region_1(void *v
, bus_space_handle_t sh
,
501 bus_size_t off
, const uint8_t *addr
, bus_size_t len
)
504 volatile uint8_t *baddr
= (uint8_t *)(sh
+ (off
* 4));
517 g2bus_sparse_bus_mem_read_multi_1(void *v
, bus_space_handle_t sh
,
518 bus_size_t off
, uint8_t *addr
, bus_size_t len
)
521 volatile const uint8_t *baddr
= (uint8_t *)(sh
+ (off
* 4));
532 g2bus_sparse_bus_mem_write_multi_1(void *v
, bus_space_handle_t sh
,
533 bus_size_t off
, const uint8_t *addr
, bus_size_t len
)
536 volatile uint8_t *baddr
= (uint8_t *)(sh
+ (off
* 4));