tc_bus_mem.c revision 1.7 1 /* $NetBSD: tc_bus_mem.c,v 1.7 1996/07/09 00:55:33 cgd Exp $ */
2
3 /*
4 * Copyright (c) 1996 Carnegie-Mellon University.
5 * All rights reserved.
6 *
7 * Author: Chris G. Demetriou
8 *
9 * Permission to use, copy, modify and distribute this software and
10 * its documentation is hereby granted, provided that both the copyright
11 * notice and this permission notice appear in all copies of the
12 * software, derivative works or modified versions, and any portions
13 * thereof, and that both notices appear in supporting documentation.
14 *
15 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
16 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
17 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
18 *
19 * Carnegie Mellon requests users of this software to return to
20 *
21 * Software Distribution Coordinator or Software.Distribution (at) CS.CMU.EDU
22 * School of Computer Science
23 * Carnegie Mellon University
24 * Pittsburgh PA 15213-3890
25 *
26 * any improvements or extensions that they make and grant Carnegie the
27 * rights to redistribute these changes.
28 */
29
30 /*
31 * Common TurboChannel Chipset "bus memory" functions.
32 */
33
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/malloc.h>
37 #include <sys/syslog.h>
38 #include <sys/device.h>
39 #include <vm/vm.h>
40
41 #include <machine/bus.h>
42 #include <dev/tc/tcvar.h>
43
44 int tc_mem_map __P((void *, bus_mem_addr_t, bus_mem_size_t,
45 int, bus_mem_handle_t *));
46 void tc_mem_unmap __P((void *, bus_mem_handle_t,
47 bus_mem_size_t));
48 int tc_mem_subregion __P((void *, bus_mem_handle_t, bus_mem_size_t,
49 bus_mem_size_t, bus_mem_handle_t *));
50 u_int8_t tc_mem_read_1 __P((void *, bus_mem_handle_t,
51 bus_mem_size_t));
52 u_int16_t tc_mem_read_2 __P((void *, bus_mem_handle_t,
53 bus_mem_size_t));
54 u_int32_t tc_mem_read_4 __P((void *, bus_mem_handle_t,
55 bus_mem_size_t));
56 u_int64_t tc_mem_read_8 __P((void *, bus_mem_handle_t,
57 bus_mem_size_t));
58 void tc_mem_write_1 __P((void *, bus_mem_handle_t,
59 bus_mem_size_t, u_int8_t));
60 void tc_mem_write_2 __P((void *, bus_mem_handle_t,
61 bus_mem_size_t, u_int16_t));
62 void tc_mem_write_4 __P((void *, bus_mem_handle_t,
63 bus_mem_size_t, u_int32_t));
64 void tc_mem_write_8 __P((void *, bus_mem_handle_t,
65 bus_mem_size_t, u_int64_t));
66
67 /* XXX DOES NOT BELONG */
68 vm_offset_t tc_XXX_dmamap __P((void *));
69
70 void
71 tc_bus_mem_init(bc, memv)
72 bus_chipset_tag_t bc;
73 void *memv;
74 {
75
76 bc->bc_m_v = memv;
77
78 bc->bc_m_map = tc_mem_map;
79 bc->bc_m_unmap = tc_mem_unmap;
80 bc->bc_m_subregion = tc_mem_subregion;
81
82 bc->bc_mr1 = tc_mem_read_1;
83 bc->bc_mr2 = tc_mem_read_2;
84 bc->bc_mr4 = tc_mem_read_4;
85 bc->bc_mr8 = tc_mem_read_8;
86
87 bc->bc_mw1 = tc_mem_write_1;
88 bc->bc_mw2 = tc_mem_write_2;
89 bc->bc_mw4 = tc_mem_write_4;
90 bc->bc_mw8 = tc_mem_write_8;
91
92 /* XXX DOES NOT BELONG */
93 bc->bc_XXX_dmamap = tc_XXX_dmamap;
94 }
95
96 int
97 tc_mem_map(v, memaddr, memsize, cacheable, memhp)
98 void *v;
99 bus_mem_addr_t memaddr;
100 bus_mem_size_t memsize;
101 int cacheable;
102 bus_mem_handle_t *memhp;
103 {
104
105 if (memaddr & 0x7)
106 panic("tc_mem_map needs 8 byte alignment");
107 if (cacheable)
108 *memhp = ALPHA_PHYS_TO_K0SEG(memaddr);
109 else
110 *memhp = ALPHA_PHYS_TO_K0SEG(TC_DENSE_TO_SPARSE(memaddr));
111 return (0);
112 }
113
114 void
115 tc_mem_unmap(v, memh, memsize)
116 void *v;
117 bus_mem_handle_t memh;
118 bus_mem_size_t memsize;
119 {
120
121 /* XXX nothing to do. */
122 }
123
124 int
125 tc_mem_subregion(v, memh, offset, size, nmemh)
126 void *v;
127 bus_mem_handle_t memh, *nmemh;
128 bus_mem_size_t offset, size;
129 {
130
131 /* Disallow subregioning that would make the handle unaligned. */
132 if ((offset & 0x7) != 0)
133 return (1);
134
135 if ((memh & TC_SPACE_SPARSE) != 0)
136 *nmemh = memh + (offset << 1);
137 else
138 *nmemh = memh + offset;
139
140 return (0);
141 }
142
143 u_int8_t
144 tc_mem_read_1(v, memh, off)
145 void *v;
146 bus_mem_handle_t memh;
147 bus_mem_size_t off;
148 {
149 volatile u_int8_t *p;
150
151 alpha_mb();
152
153 if ((memh & TC_SPACE_SPARSE) != 0)
154 panic("tc_mem_read_1 not implemented for sparse space");
155
156 p = (u_int8_t *)(memh + off);
157 return (*p);
158 }
159
160 u_int16_t
161 tc_mem_read_2(v, memh, off)
162 void *v;
163 bus_mem_handle_t memh;
164 bus_mem_size_t off;
165 {
166 volatile u_int16_t *p;
167
168 alpha_mb();
169
170 if ((memh & TC_SPACE_SPARSE) != 0)
171 panic("tc_mem_read_2 not implemented for sparse space");
172
173 p = (u_int16_t *)(memh + off);
174 return (*p);
175 }
176
177 u_int32_t
178 tc_mem_read_4(v, memh, off)
179 void *v;
180 bus_mem_handle_t memh;
181 bus_mem_size_t off;
182 {
183 volatile u_int32_t *p;
184
185 alpha_mb();
186
187 if ((memh & TC_SPACE_SPARSE) != 0)
188 /* Nothing special to do for 4-byte sparse space accesses */
189 p = (u_int32_t *)(memh + (off << 1));
190 else
191 p = (u_int32_t *)(memh + off);
192 return (*p);
193 }
194
195 u_int64_t
196 tc_mem_read_8(v, memh, off)
197 void *v;
198 bus_mem_handle_t memh;
199 bus_mem_size_t off;
200 {
201 volatile u_int64_t *p;
202
203 alpha_mb();
204
205 if ((memh & TC_SPACE_SPARSE) != 0)
206 panic("tc_mem_read_8 not implemented for sparse space");
207
208 p = (u_int64_t *)(memh + off);
209 return (*p);
210 }
211
212 void
213 tc_mem_write_1(v, memh, off, val)
214 void *v;
215 bus_mem_handle_t memh;
216 bus_mem_size_t off;
217 u_int8_t val;
218 {
219
220 if ((memh & TC_SPACE_SPARSE) != 0) {
221 volatile u_int64_t *p, v;
222 u_int64_t shift, msk;
223
224 shift = off & 0x3;
225 off &= 0x3;
226
227 p = (u_int64_t *)(memh + (off << 1));
228
229 msk = ~(0x1 << shift) & 0xf;
230 v = (msk << 32) | (((u_int64_t)val) << (shift * 8));
231
232 *p = val;
233 } else {
234 volatile u_int8_t *p;
235
236 p = (u_int8_t *)(memh + off);
237 *p = val;
238 }
239 alpha_mb();
240 }
241
242 void
243 tc_mem_write_2(v, memh, off, val)
244 void *v;
245 bus_mem_handle_t memh;
246 bus_mem_size_t off;
247 u_int16_t val;
248 {
249
250 if ((memh & TC_SPACE_SPARSE) != 0) {
251 volatile u_int64_t *p, v;
252 u_int64_t shift, msk;
253
254 shift = off & 0x2;
255 off &= 0x3;
256
257 p = (u_int64_t *)(memh + (off << 1));
258
259 msk = ~(0x3 << shift) & 0xf;
260 v = (msk << 32) | (((u_int64_t)val) << (shift * 8));
261
262 *p = val;
263 } else {
264 volatile u_int16_t *p;
265
266 p = (u_int16_t *)(memh + off);
267 *p = val;
268 }
269 alpha_mb();
270 }
271
272 void
273 tc_mem_write_4(v, memh, off, val)
274 void *v;
275 bus_mem_handle_t memh;
276 bus_mem_size_t off;
277 u_int32_t val;
278 {
279 volatile u_int32_t *p;
280
281 if ((memh & TC_SPACE_SPARSE) != 0)
282 /* Nothing special to do for 4-byte sparse space accesses */
283 p = (u_int32_t *)(memh + (off << 1));
284 else
285 p = (u_int32_t *)(memh + off);
286 *p = val;
287 alpha_mb();
288 }
289
290 void
291 tc_mem_write_8(v, memh, off, val)
292 void *v;
293 bus_mem_handle_t memh;
294 bus_mem_size_t off;
295 u_int64_t val;
296 {
297 volatile u_int64_t *p;
298
299 if ((memh & TC_SPACE_SPARSE) != 0)
300 panic("tc_mem_read_8 not implemented for sparse space");
301
302 p = (u_int64_t *)(memh + off);
303 *p = val;
304 alpha_mb();
305 }
306
307 /* XXX DOES NOT BELONG */
308 vm_offset_t
309 tc_XXX_dmamap(addr)
310 void *addr;
311 {
312
313 return (vtophys((vm_offset_t)addr));
314 }
315