| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: bus_space.c,v 1.12 2012/01/27 18:52:59 para Exp $ */ | | 1 | /* $NetBSD: bus_space.c,v 1.13 2023/12/08 01:38:20 thorpej Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace | | 8 | * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace |
9 | * Simulation Facility, NASA Ames Research Center. | | 9 | * Simulation Facility, NASA Ames Research Center. |
10 | * | | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | | 11 | * Redistribution and use in source and binary forms, with or without |
12 | * modification, are permitted provided that the following conditions | | 12 | * modification, are permitted provided that the following conditions |
13 | * are met: | | 13 | * are met: |
14 | * 1. Redistributions of source code must retain the above copyright | | 14 | * 1. Redistributions of source code must retain the above copyright |
| @@ -21,102 +21,76 @@ | | | @@ -21,102 +21,76 @@ |
21 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | | 21 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
22 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | | 22 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
23 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | | 23 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
24 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 24 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
30 | * POSSIBILITY OF SUCH DAMAGE. | | 30 | * POSSIBILITY OF SUCH DAMAGE. |
31 | */ | | 31 | */ |
32 | | | 32 | |
33 | #include <sys/cdefs.h> | | 33 | #include <sys/cdefs.h> |
34 | __KERNEL_RCSID(0, "$NetBSD: bus_space.c,v 1.12 2012/01/27 18:52:59 para Exp $"); | | 34 | __KERNEL_RCSID(0, "$NetBSD: bus_space.c,v 1.13 2023/12/08 01:38:20 thorpej Exp $"); |
35 | | | 35 | |
36 | #include <sys/param.h> | | 36 | #include <sys/param.h> |
37 | #include <sys/systm.h> | | 37 | #include <sys/systm.h> |
38 | #include <sys/malloc.h> | | 38 | #include <sys/malloc.h> |
39 | #include <sys/extent.h> | | | |
40 | | | 39 | |
41 | #include <uvm/uvm_extern.h> | | 40 | #include <uvm/uvm_extern.h> |
42 | | | 41 | |
43 | #include <machine/bus.h> | | 42 | #include <machine/bus.h> |
44 | | | 43 | |
45 | void | | 44 | void |
46 | mipsco_bus_space_init(bus_space_tag_t bst, const char *name, paddr_t paddr, vaddr_t vaddr, bus_addr_t start, bus_size_t size) | | 45 | mipsco_bus_space_init(bus_space_tag_t bst, const char *name, paddr_t paddr, vaddr_t vaddr, bus_addr_t start, bus_size_t size) |
47 | { | | 46 | { |
48 | bst->bs_name = name; | | 47 | bst->bs_name = name; |
49 | bst->bs_extent = NULL; | | 48 | bst->bs_spare = NULL; |
50 | bst->bs_start = start; | | 49 | bst->bs_start = start; |
51 | bst->bs_size = size; | | 50 | bst->bs_size = size; |
52 | bst->bs_pbase = paddr; | | 51 | bst->bs_pbase = paddr; |
53 | bst->bs_vbase = vaddr; | | 52 | bst->bs_vbase = vaddr; |
54 | bst->bs_compose_handle = mipsco_bus_space_compose_handle; | | 53 | bst->bs_compose_handle = mipsco_bus_space_compose_handle; |
55 | bst->bs_dispose_handle = mipsco_bus_space_dispose_handle; | | 54 | bst->bs_dispose_handle = mipsco_bus_space_dispose_handle; |
56 | bst->bs_paddr = mipsco_bus_space_paddr; | | 55 | bst->bs_paddr = mipsco_bus_space_paddr; |
57 | bst->bs_map = mipsco_bus_space_map; | | 56 | bst->bs_map = mipsco_bus_space_map; |
58 | bst->bs_unmap = mipsco_bus_space_unmap; | | 57 | bst->bs_unmap = mipsco_bus_space_unmap; |
59 | bst->bs_subregion = mipsco_bus_space_subregion; | | 58 | bst->bs_subregion = mipsco_bus_space_subregion; |
60 | bst->bs_mmap = mipsco_bus_space_mmap; | | 59 | bst->bs_mmap = mipsco_bus_space_mmap; |
61 | bst->bs_alloc = mipsco_bus_space_alloc; | | 60 | bst->bs_alloc = mipsco_bus_space_alloc; |
62 | bst->bs_free = mipsco_bus_space_free; | | 61 | bst->bs_free = mipsco_bus_space_free; |
63 | bst->bs_aux = NULL; | | 62 | bst->bs_aux = NULL; |
64 | bst->bs_bswap = 0; /* No byte swap for stream methods */ | | 63 | bst->bs_bswap = 0; /* No byte swap for stream methods */ |
65 | mipsco_bus_space_set_aligned_stride(bst, 0); | | 64 | mipsco_bus_space_set_aligned_stride(bst, 0); |
66 | } | | 65 | } |
67 | | | 66 | |
68 | void | | 67 | void |
69 | mipsco_bus_space_init_extent(bus_space_tag_t bst, void *storage, size_t storagesize) | | | |
70 | { | | | |
71 | bst->bs_extent = extent_create(bst->bs_name, | | | |
72 | bst->bs_start, bst->bs_start + bst->bs_size, | | | |
73 | storage, storagesize, EX_NOWAIT); | | | |
74 | if (bst->bs_extent == NULL) | | | |
75 | panic("mipsco_bus_space_init_extent: cannot create extent map %s", | | | |
76 | bst->bs_name); | | | |
77 | } | | | |
78 | | | | |
79 | void | | | |
80 | mipsco_bus_space_set_aligned_stride(bus_space_tag_t bst, unsigned int shift) | | 68 | mipsco_bus_space_set_aligned_stride(bus_space_tag_t bst, unsigned int shift) |
81 | /* shift: log2(alignment) */ | | 69 | /* shift: log2(alignment) */ |
82 | { | | 70 | { |
83 | bst->bs_stride = shift; | | 71 | bst->bs_stride = shift; |
84 | | | 72 | |
85 | if (shift == 2) { /* XXX Assumes Big Endian & 4B */ | | 73 | if (shift == 2) { /* XXX Assumes Big Endian & 4B */ |
86 | bst->bs_offset_1 = 3; | | 74 | bst->bs_offset_1 = 3; |
87 | bst->bs_offset_2 = 2; | | 75 | bst->bs_offset_2 = 2; |
88 | } else { | | 76 | } else { |
89 | bst->bs_offset_1 = 0; | | 77 | bst->bs_offset_1 = 0; |
90 | bst->bs_offset_2 = 0; | | 78 | bst->bs_offset_2 = 0; |
91 | } | | 79 | } |
92 | bst->bs_offset_4 = 0; | | 80 | bst->bs_offset_4 = 0; |
93 | bst->bs_offset_8 = 0; | | 81 | bst->bs_offset_8 = 0; |
94 | } | | 82 | } |
95 | | | 83 | |
96 | static int malloc_safe = 0; | | | |
97 | | | | |
98 | void | | | |
99 | mipsco_bus_space_malloc_set_safe(void) | | | |
100 | { | | | |
101 | malloc_safe = EX_MALLOCOK; | | | |
102 | } | | | |
103 | | | | |
104 | int | | | |
105 | mipsco_bus_space_extent_malloc_flag(void) | | | |
106 | { | | | |
107 | return (malloc_safe); | | | |
108 | } | | | |
109 | | | | |
110 | int | | 84 | int |
111 | mipsco_bus_space_compose_handle(bus_space_tag_t bst, bus_addr_t addr, bus_size_t size, int flags, bus_space_handle_t *bshp) | | 85 | mipsco_bus_space_compose_handle(bus_space_tag_t bst, bus_addr_t addr, bus_size_t size, int flags, bus_space_handle_t *bshp) |
112 | { | | 86 | { |
113 | bus_space_handle_t bsh = bst->bs_vbase + | | 87 | bus_space_handle_t bsh = bst->bs_vbase + |
114 | ((addr - bst->bs_start) << bst->bs_stride); | | 88 | ((addr - bst->bs_start) << bst->bs_stride); |
115 | | | 89 | |
116 | /* | | 90 | /* |
117 | * Since all buses can be linearly mappable, we don't have to check | | 91 | * Since all buses can be linearly mappable, we don't have to check |
118 | * BUS_SPACE_MAP_LINEAR and BUS_SPACE_MAP_PREFETCHABLE. | | 92 | * BUS_SPACE_MAP_LINEAR and BUS_SPACE_MAP_PREFETCHABLE. |
119 | */ | | 93 | */ |
120 | if ((flags & BUS_SPACE_MAP_CACHEABLE) == 0) { | | 94 | if ((flags & BUS_SPACE_MAP_CACHEABLE) == 0) { |
121 | *bshp = bsh; | | 95 | *bshp = bsh; |
122 | return (0); | | 96 | return (0); |
| @@ -161,58 +135,36 @@ mipsco_bus_space_paddr(bus_space_tag_t b | | | @@ -161,58 +135,36 @@ mipsco_bus_space_paddr(bus_space_tag_t b |
161 | else { /* KSEG2 */ | | 135 | else { /* KSEG2 */ |
162 | /* | | 136 | /* |
163 | * Since this region may be mapped by wired TLB, | | 137 | * Since this region may be mapped by wired TLB, |
164 | * kvtophys() is not always available. | | 138 | * kvtophys() is not always available. |
165 | */ | | 139 | */ |
166 | *pap = bst->bs_pbase + (bsh - bst->bs_vbase); | | 140 | *pap = bst->bs_pbase + (bsh - bst->bs_vbase); |
167 | } | | 141 | } |
168 | return (0); | | 142 | return (0); |
169 | } | | 143 | } |
170 | | | 144 | |
171 | int | | 145 | int |
172 | mipsco_bus_space_map(bus_space_tag_t bst, bus_addr_t addr, bus_size_t size, int flags, bus_space_handle_t *bshp) | | 146 | mipsco_bus_space_map(bus_space_tag_t bst, bus_addr_t addr, bus_size_t size, int flags, bus_space_handle_t *bshp) |
173 | { | | 147 | { |
174 | int err; | | | |
175 | | | 148 | |
176 | if (addr < bst->bs_start || addr + size > bst->bs_start + bst->bs_size) | | 149 | if (addr < bst->bs_start || addr + size > bst->bs_start + bst->bs_size) |
177 | return (EINVAL); | | 150 | return (EINVAL); |
178 | | | 151 | |
179 | if (bst->bs_extent != NULL) { | | | |
180 | err = extent_alloc_region(bst->bs_extent, addr, size, | | | |
181 | EX_NOWAIT | malloc_safe); | | | |
182 | if (err) | | | |
183 | return (err); | | | |
184 | } | | | |
185 | | | | |
186 | return (bus_space_compose_handle(bst, addr, size, flags, bshp)); | | 152 | return (bus_space_compose_handle(bst, addr, size, flags, bshp)); |
187 | } | | 153 | } |
188 | | | 154 | |
189 | void | | 155 | void |
190 | mipsco_bus_space_unmap(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t size) | | 156 | mipsco_bus_space_unmap(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t size) |
191 | { | | 157 | { |
192 | if (bst->bs_extent != NULL) { | | | |
193 | paddr_t pa; | | | |
194 | bus_addr_t addr; | | | |
195 | int err; | | | |
196 | | | | |
197 | /* bus_space_paddr() becomes unavailable after unmapping */ | | | |
198 | err = bus_space_paddr(bst, bsh, &pa); | | | |
199 | if (err) | | | |
200 | panic("mipsco_bus_space_unmap: %s va %p: error %d", | | | |
201 | bst->bs_name, (void *)bsh, err); | | | |
202 | addr = (bus_size_t)(pa - bst->bs_pbase) + bst->bs_start; | | | |
203 | extent_free(bst->bs_extent, addr, size, | | | |
204 | EX_NOWAIT | malloc_safe); | | | |
205 | } | | | |
206 | bus_space_dispose_handle(bst, bsh, size); | | 158 | bus_space_dispose_handle(bst, bsh, size); |
207 | } | | 159 | } |
208 | | | 160 | |
209 | int | | 161 | int |
210 | mipsco_bus_space_subregion(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp) | | 162 | mipsco_bus_space_subregion(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp) |
211 | { | | 163 | { |
212 | *nbshp = bsh + (offset << bst->bs_stride); | | 164 | *nbshp = bsh + (offset << bst->bs_stride); |
213 | return (0); | | 165 | return (0); |
214 | } | | 166 | } |
215 | | | 167 | |
216 | paddr_t | | 168 | paddr_t |
217 | mipsco_bus_space_mmap(bus_space_tag_t bst, bus_addr_t addr, off_t off, int prot, int flags) | | 169 | mipsco_bus_space_mmap(bus_space_tag_t bst, bus_addr_t addr, off_t off, int prot, int flags) |
218 | { | | 170 | { |
| @@ -222,32 +174,16 @@ mipsco_bus_space_mmap(bus_space_tag_t bs | | | @@ -222,32 +174,16 @@ mipsco_bus_space_mmap(bus_space_tag_t bs |
222 | * XXX which we should be doing. | | 174 | * XXX which we should be doing. |
223 | */ | | 175 | */ |
224 | | | 176 | |
225 | if (addr < bst->bs_start || | | 177 | if (addr < bst->bs_start || |
226 | (addr + off) >= (bst->bs_start + bst->bs_size)) | | 178 | (addr + off) >= (bst->bs_start + bst->bs_size)) |
227 | return (-1); | | 179 | return (-1); |
228 | | | 180 | |
229 | return (mips_btop(bst->bs_pbase + (addr - bst->bs_start) + off)); | | 181 | return (mips_btop(bst->bs_pbase + (addr - bst->bs_start) + off)); |
230 | } | | 182 | } |
231 | | | 183 | |
232 | int | | 184 | int |
233 | mipsco_bus_space_alloc(bus_space_tag_t bst, bus_addr_t start, bus_addr_t end, bus_size_t size, bus_size_t align, bus_size_t boundary, int flags, bus_addr_t *addrp, bus_space_handle_t *bshp) | | 185 | mipsco_bus_space_alloc(bus_space_tag_t bst, bus_addr_t start, bus_addr_t end, bus_size_t size, bus_size_t align, bus_size_t boundary, int flags, bus_addr_t *addrp, bus_space_handle_t *bshp) |
234 | { | | 186 | { |
235 | u_long addr; | | | |
236 | int err; | | | |
237 | | | 187 | |
238 | if (bst->bs_extent == NULL) | | 188 | panic("bus_space_alloc() not implemented"); |
239 | panic("mipsco_bus_space_alloc: extent map %s not available", | | | |
240 | bst->bs_name); | | | |
241 | | | | |
242 | if (start < bst->bs_start || | | | |
243 | start + size > bst->bs_start + bst->bs_size) | | | |
244 | return (EINVAL); | | | |
245 | | | | |
246 | err = extent_alloc_subregion(bst->bs_extent, start, end, size, | | | |
247 | align, boundary, EX_FAST | EX_NOWAIT | malloc_safe, &addr); | | | |
248 | if (err) | | | |
249 | return (err); | | | |
250 | | | | |
251 | *addrp = addr; | | | |
252 | return (bus_space_compose_handle(bst, addr, size, flags, bshp)); | | | |
253 | } | | 189 | } |