xref: /netbsd-src/sys/arch/alpha/pci/pci_bwx_bus_mem_chipdep.c (revision 6b54fdb24ad88ed15360450b84084a49b81ab71b)
1 /* $NetBSD: pci_bwx_bus_mem_chipdep.c,v 1.30 2023/12/06 01:46:34 thorpej Exp $ */
2 
3 /*-
4  * Copyright (c) 1997, 1998, 2000 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 of the Numerical Aerospace Simulation Facility,
9  * NASA Ames Research Center.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
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
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
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
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
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /*
34  * Copyright (c) 1995, 1996 Carnegie-Mellon University.
35  * All rights reserved.
36  *
37  * Author: Chris G. Demetriou
38  *
39  * Permission to use, copy, modify and distribute this software and
40  * its documentation is hereby granted, provided that both the copyright
41  * notice and this permission notice appear in all copies of the
42  * software, derivative works or modified versions, and any portions
43  * thereof, and that both notices appear in supporting documentation.
44  *
45  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
46  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
47  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
48  *
49  * Carnegie Mellon requests users of this software to return to
50  *
51  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
52  *  School of Computer Science
53  *  Carnegie Mellon University
54  *  Pittsburgh PA 15213-3890
55  *
56  * any improvements or extensions that they make and grant Carnegie the
57  * rights to redistribute these changes.
58  */
59 
60 /*
61  * Common PCI Chipset "bus I/O" functions, for chipsets which have to
62  * deal with only a single PCI interface chip in a machine.
63  *
64  * uses:
65  *	CHIP		name of the 'chip' it's being compiled for.
66  *	CHIP_MEM_BASE	Mem space base to use.
67  *	CHIP_MEM_ARENA_STORE
68  *			If defined, device-provided static storage area
69  *			for the memory space arena.  If this is
70  *			defined, CHIP_MEM_BTAG_STORE and CHIP_MEM_BTAG_COUNT
71  *			must also be defined.  If this is not defined, a
72  *			static area will be declared.
73  *	CHIP_MEM_BTAG_STORE
74  *			Device-provided static storage area for the
75  *			memory space arena's boundary tags.  Ignored
76  *			unless CHIP_MEM_ARENA_STORE is defined.
77  *	CHIP_MEM_BTAG_COUNT
78  *			The number of device-provided static memory
79  *			space boundary tags.  Ignored unless
80  *			CHIP_MEM_ARENA_STORE is defined.
81  */
82 
83 #include <sys/cdefs.h>
84 __KERNEL_RCSID(1, "$NetBSD: pci_bwx_bus_mem_chipdep.c,v 1.30 2023/12/06 01:46:34 thorpej Exp $");
85 
86 #include <sys/vmem_impl.h>
87 
88 #include <machine/bwx.h>
89 
90 #define	__C(A,B)	__CONCAT(A,B)
91 #define	__S(S)		__STRING(S)
92 
93 /* mapping/unmapping */
94 static int	__C(CHIP,_mem_map)(void *, bus_addr_t, bus_size_t, int,
95 		    bus_space_handle_t *, int);
96 static void	__C(CHIP,_mem_unmap)(void *, bus_space_handle_t,
97 		    bus_size_t, int);
98 static int	__C(CHIP,_mem_subregion)(void *, bus_space_handle_t,
99 		    bus_size_t, bus_size_t, bus_space_handle_t *);
100 
101 static int	__C(CHIP,_mem_translate)(void *, bus_addr_t, bus_size_t,
102 		    int, struct alpha_bus_space_translation *);
103 static int	__C(CHIP,_mem_get_window)(void *, int,
104 		    struct alpha_bus_space_translation *);
105 
106 /* allocation/deallocation */
107 static int	__C(CHIP,_mem_alloc)(void *, bus_addr_t, bus_addr_t,
108 		    bus_size_t, bus_size_t, bus_addr_t, int, bus_addr_t *,
109 	            bus_space_handle_t *);
110 static void	__C(CHIP,_mem_free)(void *, bus_space_handle_t,
111 		    bus_size_t);
112 
113 /* get kernel virtual address */
114 static void *	__C(CHIP,_mem_vaddr)(void *, bus_space_handle_t);
115 
116 /* mmap for user */
117 static paddr_t	__C(CHIP,_mem_mmap)(void *, bus_addr_t, off_t, int, int);
118 
119 /* barrier */
120 static inline void __C(CHIP,_mem_barrier)(void *, bus_space_handle_t,
121 		    bus_size_t, bus_size_t, int);
122 
123 /* read (single) */
124 static inline uint8_t __C(CHIP,_mem_read_1)(void *, bus_space_handle_t,
125 		    bus_size_t);
126 static inline uint16_t __C(CHIP,_mem_read_2)(void *, bus_space_handle_t,
127 		    bus_size_t);
128 static inline uint32_t __C(CHIP,_mem_read_4)(void *, bus_space_handle_t,
129 		    bus_size_t);
130 static inline uint64_t __C(CHIP,_mem_read_8)(void *, bus_space_handle_t,
131 		    bus_size_t);
132 
133 /* read multiple */
134 static void	__C(CHIP,_mem_read_multi_1)(void *, bus_space_handle_t,
135 		    bus_size_t, uint8_t *, bus_size_t);
136 static void	__C(CHIP,_mem_read_multi_2)(void *, bus_space_handle_t,
137 		    bus_size_t, uint16_t *, bus_size_t);
138 static void	__C(CHIP,_mem_read_multi_4)(void *, bus_space_handle_t,
139 		    bus_size_t, uint32_t *, bus_size_t);
140 static void	__C(CHIP,_mem_read_multi_8)(void *, bus_space_handle_t,
141 		    bus_size_t, uint64_t *, bus_size_t);
142 
143 /* read region */
144 static void	__C(CHIP,_mem_read_region_1)(void *, bus_space_handle_t,
145 		    bus_size_t, uint8_t *, bus_size_t);
146 static void	__C(CHIP,_mem_read_region_2)(void *, bus_space_handle_t,
147 		    bus_size_t, uint16_t *, bus_size_t);
148 static void	__C(CHIP,_mem_read_region_4)(void *, bus_space_handle_t,
149 		    bus_size_t, uint32_t *, bus_size_t);
150 static void	__C(CHIP,_mem_read_region_8)(void *, bus_space_handle_t,
151 		    bus_size_t, uint64_t *, bus_size_t);
152 
153 /* write (single) */
154 static inline void __C(CHIP,_mem_write_1)(void *, bus_space_handle_t,
155 		    bus_size_t, uint8_t);
156 static inline void __C(CHIP,_mem_write_2)(void *, bus_space_handle_t,
157 		    bus_size_t, uint16_t);
158 static inline void __C(CHIP,_mem_write_4)(void *, bus_space_handle_t,
159 		    bus_size_t, uint32_t);
160 static inline void __C(CHIP,_mem_write_8)(void *, bus_space_handle_t,
161 		    bus_size_t, uint64_t);
162 
163 /* write multiple */
164 static void	__C(CHIP,_mem_write_multi_1)(void *, bus_space_handle_t,
165 		    bus_size_t, const uint8_t *, bus_size_t);
166 static void	__C(CHIP,_mem_write_multi_2)(void *, bus_space_handle_t,
167 		    bus_size_t, const uint16_t *, bus_size_t);
168 static void	__C(CHIP,_mem_write_multi_4)(void *, bus_space_handle_t,
169 		    bus_size_t, const uint32_t *, bus_size_t);
170 static void	__C(CHIP,_mem_write_multi_8)(void *, bus_space_handle_t,
171 		    bus_size_t, const uint64_t *, bus_size_t);
172 
173 /* write region */
174 static void	__C(CHIP,_mem_write_region_1)(void *, bus_space_handle_t,
175 		    bus_size_t, const uint8_t *, bus_size_t);
176 static void	__C(CHIP,_mem_write_region_2)(void *, bus_space_handle_t,
177 		    bus_size_t, const uint16_t *, bus_size_t);
178 static void	__C(CHIP,_mem_write_region_4)(void *, bus_space_handle_t,
179 		    bus_size_t, const uint32_t *, bus_size_t);
180 static void	__C(CHIP,_mem_write_region_8)(void *, bus_space_handle_t,
181 		    bus_size_t, const uint64_t *, bus_size_t);
182 
183 /* set multiple */
184 static void	__C(CHIP,_mem_set_multi_1)(void *, bus_space_handle_t,
185 		    bus_size_t, uint8_t, bus_size_t);
186 static void	__C(CHIP,_mem_set_multi_2)(void *, bus_space_handle_t,
187 		    bus_size_t, uint16_t, bus_size_t);
188 static void	__C(CHIP,_mem_set_multi_4)(void *, bus_space_handle_t,
189 		    bus_size_t, uint32_t, bus_size_t);
190 static void	__C(CHIP,_mem_set_multi_8)(void *, bus_space_handle_t,
191 		    bus_size_t, uint64_t, bus_size_t);
192 
193 /* set region */
194 static void	__C(CHIP,_mem_set_region_1)(void *, bus_space_handle_t,
195 		    bus_size_t, uint8_t, bus_size_t);
196 static void	__C(CHIP,_mem_set_region_2)(void *, bus_space_handle_t,
197 		    bus_size_t, uint16_t, bus_size_t);
198 static void	__C(CHIP,_mem_set_region_4)(void *, bus_space_handle_t,
199 		    bus_size_t, uint32_t, bus_size_t);
200 static void	__C(CHIP,_mem_set_region_8)(void *, bus_space_handle_t,
201 		    bus_size_t, uint64_t, bus_size_t);
202 
203 /* copy */
204 static void	__C(CHIP,_mem_copy_region_1)(void *, bus_space_handle_t,
205 		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
206 static void	__C(CHIP,_mem_copy_region_2)(void *, bus_space_handle_t,
207 		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
208 static void	__C(CHIP,_mem_copy_region_4)(void *, bus_space_handle_t,
209 		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
210 static void	__C(CHIP,_mem_copy_region_8)(void *, bus_space_handle_t,
211 		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
212 
213 #ifndef CHIP_MEM_ARENA_STORE
214 #define	CHIP_MEM_BTAG_COUNT(v)	VMEM_EST_BTCOUNT(1, 8)
215 #define	CHIP_MEM_BTAG_STORE(v)	__C(CHIP,_mem_btag_store)
216 #define	CHIP_MEM_ARENA_STORE(v)	(&(__C(CHIP,_mem_arena_store)))
217 
218 static struct vmem __C(CHIP,_mem_arena_store);
219 static struct vmem_btag __C(CHIP,_mem_btag_store)[CHIP_MEM_BTAG_COUNT(xxx)];
220 #endif /* CHIP_MEM_ARENA_STORE */
221 
222 void
__C(CHIP,_bus_mem_init)223 __C(CHIP,_bus_mem_init)(
224 	bus_space_tag_t t,
225 	void *v)
226 {
227 	vmem_t *vm;
228 	int error __diagused;
229 
230 	/*
231 	 * Initialize the bus space tag.
232 	 */
233 
234 	/* cookie */
235 	t->abs_cookie =		v;
236 
237 	/* mapping/unmapping */
238 	t->abs_map =		__C(CHIP,_mem_map);
239 	t->abs_unmap =		__C(CHIP,_mem_unmap);
240 	t->abs_subregion =	__C(CHIP,_mem_subregion);
241 
242 	t->abs_translate =	__C(CHIP,_mem_translate);
243 	t->abs_get_window =	__C(CHIP,_mem_get_window);
244 
245 	/* allocation/deallocation */
246 	t->abs_alloc =		__C(CHIP,_mem_alloc);
247 	t->abs_free = 		__C(CHIP,_mem_free);
248 
249 	/* get kernel virtual address */
250 	t->abs_vaddr =		__C(CHIP,_mem_vaddr);
251 
252 	/* mmap for user */
253 	t->abs_mmap =		__C(CHIP,_mem_mmap);
254 
255 	/* barrier */
256 	t->abs_barrier =	__C(CHIP,_mem_barrier);
257 
258 	/* read (single) */
259 	t->abs_r_1 =		__C(CHIP,_mem_read_1);
260 	t->abs_r_2 =		__C(CHIP,_mem_read_2);
261 	t->abs_r_4 =		__C(CHIP,_mem_read_4);
262 	t->abs_r_8 =		__C(CHIP,_mem_read_8);
263 
264 	/* read multiple */
265 	t->abs_rm_1 =		__C(CHIP,_mem_read_multi_1);
266 	t->abs_rm_2 =		__C(CHIP,_mem_read_multi_2);
267 	t->abs_rm_4 =		__C(CHIP,_mem_read_multi_4);
268 	t->abs_rm_8 =		__C(CHIP,_mem_read_multi_8);
269 
270 	/* read region */
271 	t->abs_rr_1 =		__C(CHIP,_mem_read_region_1);
272 	t->abs_rr_2 =		__C(CHIP,_mem_read_region_2);
273 	t->abs_rr_4 =		__C(CHIP,_mem_read_region_4);
274 	t->abs_rr_8 =		__C(CHIP,_mem_read_region_8);
275 
276 	/* write (single) */
277 	t->abs_w_1 =		__C(CHIP,_mem_write_1);
278 	t->abs_w_2 =		__C(CHIP,_mem_write_2);
279 	t->abs_w_4 =		__C(CHIP,_mem_write_4);
280 	t->abs_w_8 =		__C(CHIP,_mem_write_8);
281 
282 	/* write multiple */
283 	t->abs_wm_1 =		__C(CHIP,_mem_write_multi_1);
284 	t->abs_wm_2 =		__C(CHIP,_mem_write_multi_2);
285 	t->abs_wm_4 =		__C(CHIP,_mem_write_multi_4);
286 	t->abs_wm_8 =		__C(CHIP,_mem_write_multi_8);
287 
288 	/* write region */
289 	t->abs_wr_1 =		__C(CHIP,_mem_write_region_1);
290 	t->abs_wr_2 =		__C(CHIP,_mem_write_region_2);
291 	t->abs_wr_4 =		__C(CHIP,_mem_write_region_4);
292 	t->abs_wr_8 =		__C(CHIP,_mem_write_region_8);
293 
294 	/* set multiple */
295 	t->abs_sm_1 =		__C(CHIP,_mem_set_multi_1);
296 	t->abs_sm_2 =		__C(CHIP,_mem_set_multi_2);
297 	t->abs_sm_4 =		__C(CHIP,_mem_set_multi_4);
298 	t->abs_sm_8 =		__C(CHIP,_mem_set_multi_8);
299 
300 	/* set region */
301 	t->abs_sr_1 =		__C(CHIP,_mem_set_region_1);
302 	t->abs_sr_2 =		__C(CHIP,_mem_set_region_2);
303 	t->abs_sr_4 =		__C(CHIP,_mem_set_region_4);
304 	t->abs_sr_8 =		__C(CHIP,_mem_set_region_8);
305 
306 	/* copy */
307 	t->abs_c_1 =		__C(CHIP,_mem_copy_region_1);
308 	t->abs_c_2 =		__C(CHIP,_mem_copy_region_2);
309 	t->abs_c_4 =		__C(CHIP,_mem_copy_region_4);
310 	t->abs_c_8 =		__C(CHIP,_mem_copy_region_8);
311 
312 	vm = vmem_init(CHIP_MEM_ARENA_STORE(v),
313 		       __S(__C(CHIP,_bus_mem)),		/* name */
314 		       0,				/* addr */
315 		       0,				/* size */
316 		       1,				/* quantum */
317 		       NULL,				/* importfn */
318 		       NULL,				/* releasefn */
319 		       NULL,				/* source */
320 		       0,				/* qcache_max */
321 		       VM_NOSLEEP | VM_PRIVTAGS,
322 		       IPL_NONE);
323 	KASSERT(vm != NULL);
324 
325 	vmem_add_bts(vm, CHIP_MEM_BTAG_STORE(v), CHIP_MEM_BTAG_COUNT(v));
326 	error = vmem_add(vm, 0, 0x100000000UL, VM_NOSLEEP);
327 	KASSERT(error == 0);
328 
329 	CHIP_MEM_ARENA(v) = vm;
330 }
331 
332 static int
__C(CHIP,_mem_translate)333 __C(CHIP,_mem_translate)(
334 	void *v,
335 	bus_addr_t memaddr,
336 	bus_size_t memlen,
337 	int flags,
338 	struct alpha_bus_space_translation *abst)
339 {
340 
341 	/* XXX */
342 	return (EOPNOTSUPP);
343 }
344 
345 static int
__C(CHIP,_mem_get_window)346 __C(CHIP,_mem_get_window)(
347 	void *v,
348 	int window,
349 	struct alpha_bus_space_translation *abst)
350 {
351 
352 	switch (window) {
353 	case 0:
354 		abst->abst_bus_start = 0;
355 		abst->abst_bus_end = 0xffffffffUL;
356 		abst->abst_sys_start = CHIP_MEM_SYS_START(v);
357 		abst->abst_sys_end = CHIP_MEM_SYS_START(v) + abst->abst_bus_end;
358 		abst->abst_addr_shift = 0;
359 		abst->abst_size_shift = 0;
360 		abst->abst_flags = ABST_DENSE|ABST_BWX;
361 		break;
362 
363 	default:
364 		panic(__S(__C(CHIP,_mem_get_window)) ": invalid window %d",
365 		    window);
366 	}
367 
368 	return (0);
369 }
370 
371 static int
__C(CHIP,_mem_map)372 __C(CHIP,_mem_map)(
373 	void *v,
374 	bus_addr_t memaddr,
375 	bus_size_t memsize,
376 	int flags,
377 	bus_space_handle_t *memhp,
378 	int acct)
379 {
380 	int error;
381 
382 	if (acct == 0)
383 		goto mapit;
384 
385 #ifdef EXTENT_DEBUG
386 	printf("mem: allocating 0x%lx to 0x%lx\n", memaddr,
387 	    memaddr + memsize - 1);
388 #endif
389 	error = vmem_xalloc_addr(CHIP_MEM_ARENA(v), memaddr, memsize,
390 	    VM_NOSLEEP);
391 	if (error) {
392 #ifdef EXTENT_DEBUG
393 		printf("mem: allocation failed (%d)\n", error);
394 		/* vmem_print(CHIP_MEM_ARENA(v));	XXX */
395 #endif
396 		return (error);
397 	}
398 
399  mapit:
400 	*memhp = ALPHA_PHYS_TO_K0SEG(CHIP_MEM_SYS_START(v)) + memaddr;
401 
402 	return (0);
403 }
404 
405 static void
__C(CHIP,_mem_unmap)406 __C(CHIP,_mem_unmap)(
407 	void *v,
408 	bus_space_handle_t memh,
409 	bus_size_t memsize,
410 	int acct)
411 {
412 	bus_addr_t memaddr;
413 
414 	if (acct == 0)
415 		return;
416 
417 #ifdef EXTENT_DEBUG
418 	printf("mem: freeing handle 0x%lx for 0x%lx\n", memh, memsize);
419 #endif
420 
421 	memaddr = memh - ALPHA_PHYS_TO_K0SEG(CHIP_MEM_SYS_START(v));
422 
423 #ifdef EXTENT_DEBUG
424 	printf("mem: freeing 0x%lx to 0x%lx\n", memaddr, memaddr + memsize - 1);
425 #endif
426 
427 	vmem_xfree(CHIP_MEM_ARENA(v), memaddr, memsize);
428 }
429 
430 static int
__C(CHIP,_mem_subregion)431 __C(CHIP,_mem_subregion)(
432 	void *v,
433 	bus_space_handle_t memh,
434 	bus_size_t offset,
435 	bus_size_t size,
436 	bus_space_handle_t *nmemh)
437 {
438 
439 	*nmemh = memh + offset;
440 	return (0);
441 }
442 
443 static int
__C(CHIP,_mem_alloc)444 __C(CHIP,_mem_alloc)(
445 	void *v,
446 	bus_addr_t rstart,
447 	bus_addr_t rend,
448 	bus_size_t size,
449 	bus_size_t align,
450 	bus_size_t boundary,
451 	int flags,
452 	bus_addr_t *addrp,
453 	bus_space_handle_t *bshp)
454 {
455 	vmem_addr_t memaddr;
456 	int error;
457 
458 	/*
459 	 * Do the requested allocation.
460 	 */
461 #ifdef EXTENT_DEBUG
462 	printf("mem: allocating from 0x%lx to 0x%lx\n", rstart, rend);
463 #endif
464 	error = vmem_xalloc(CHIP_MEM_ARENA(v), size,
465 			    align,		/* align */
466 			    0,			/* phase */
467 			    boundary,		/* nocross */
468 			    rstart,		/* minaddr */
469 			    rend,		/* maxaddr */
470 			    VM_BESTFIT | VM_NOSLEEP,
471 			    &memaddr);
472 	if (error) {
473 #ifdef EXTENT_DEBUG
474 		printf("mem: allocation failed (%d)\n", error);
475 		/* vmem_print(CHIP_MEM_ARENA(v));	XXX */
476 #endif
477 	}
478 
479 #ifdef EXTENT_DEBUG
480 	printf("mem: allocated 0x%lx to 0x%lx\n", memaddr, memaddr + size - 1);
481 #endif
482 
483 	*addrp = memaddr;
484 	*bshp = ALPHA_PHYS_TO_K0SEG(CHIP_MEM_SYS_START(v)) + memaddr;
485 
486 	return (0);
487 }
488 
489 static void
__C(CHIP,_mem_free)490 __C(CHIP,_mem_free)(
491 	void *v,
492 	bus_space_handle_t bsh,
493 	bus_size_t size)
494 {
495 
496 	/* Unmap does all we need to do. */
497 	__C(CHIP,_mem_unmap)(v, bsh, size, 1);
498 }
499 
500 static void *
__C(CHIP,_mem_vaddr)501 __C(CHIP,_mem_vaddr)(
502 	void *v,
503 	bus_space_handle_t bsh)
504 {
505 
506 	return ((void *)bsh);
507 }
508 
509 static paddr_t
__C(CHIP,_mem_mmap)510 __C(CHIP,_mem_mmap)(
511 	void *v,
512 	bus_addr_t addr,
513 	off_t off,
514 	int prot,
515 	int flags)
516 {
517 
518 	return (alpha_btop(CHIP_MEM_SYS_START(v) + addr + off));
519 }
520 
521 static inline void
__C(CHIP,_mem_barrier)522 __C(CHIP,_mem_barrier)(
523 	void *v,
524 	bus_space_handle_t h,
525 	bus_size_t o,
526 	bus_size_t l,
527 	int f)
528 {
529 
530 	if ((f & BUS_SPACE_BARRIER_READ) != 0)
531 		alpha_mb();
532 	else if ((f & BUS_SPACE_BARRIER_WRITE) != 0)
533 		alpha_wmb();
534 }
535 
536 static inline uint8_t
__C(CHIP,_mem_read_1)537 __C(CHIP,_mem_read_1)(
538 	void *v,
539 	bus_space_handle_t memh,
540 	bus_size_t off)
541 {
542 	bus_addr_t addr;
543 
544 	addr = memh + off;
545 	alpha_mb();
546 	return (alpha_ldbu((uint8_t *)addr));
547 }
548 
549 static inline uint16_t
__C(CHIP,_mem_read_2)550 __C(CHIP,_mem_read_2)(
551 	void *v,
552 	bus_space_handle_t memh,
553 	bus_size_t off)
554 {
555 	bus_addr_t addr;
556 
557 	addr = memh + off;
558 #ifdef DIAGNOSTIC
559 	if (addr & 1)
560 		panic(__S(__C(CHIP,_mem_read_2)) ": addr 0x%lx not aligned",
561 		    addr);
562 #endif
563 	alpha_mb();
564 	return (alpha_ldwu((uint16_t *)addr));
565 }
566 
567 static inline uint32_t
__C(CHIP,_mem_read_4)568 __C(CHIP,_mem_read_4)(
569 	void *v,
570 	bus_space_handle_t memh,
571 	bus_size_t off)
572 {
573 	bus_addr_t addr;
574 
575 	addr = memh + off;
576 #ifdef DIAGNOSTIC
577 	if (addr & 3)
578 		panic(__S(__C(CHIP,_mem_read_4)) ": addr 0x%lx not aligned",
579 		    addr);
580 #endif
581 	alpha_mb();
582 	return (*(uint32_t *)addr);
583 }
584 
585 static inline uint64_t
__C(CHIP,_mem_read_8)586 __C(CHIP,_mem_read_8)(
587 	void *v,
588 	bus_space_handle_t memh,
589 	bus_size_t off)
590 {
591 
592 	alpha_mb();
593 
594 	/* XXX XXX XXX */
595 	panic("%s not implemented", __S(__C(CHIP,_mem_read_8)));
596 }
597 
598 #define CHIP_mem_read_multi_N(BYTES,TYPE)				\
599 static void								\
600 __C(__C(CHIP,_mem_read_multi_),BYTES)(					\
601 	void *v,							\
602 	bus_space_handle_t h,						\
603 	bus_size_t o,							\
604 	TYPE *a,							\
605 	bus_size_t c)							\
606 {									\
607 									\
608 	while (c-- > 0) {						\
609 		__C(CHIP,_mem_barrier)(v, h, o, sizeof *a,		\
610 		    BUS_SPACE_BARRIER_READ);				\
611 		*a++ = __C(__C(CHIP,_mem_read_),BYTES)(v, h, o);	\
612 	}								\
613 }
614 CHIP_mem_read_multi_N(1,uint8_t)
615 CHIP_mem_read_multi_N(2,uint16_t)
616 CHIP_mem_read_multi_N(4,uint32_t)
617 CHIP_mem_read_multi_N(8,uint64_t)
618 
619 #define CHIP_mem_read_region_N(BYTES,TYPE)				\
620 static void								\
621 __C(__C(CHIP,_mem_read_region_),BYTES)(					\
622 	void *v,							\
623 	bus_space_handle_t h,						\
624 	bus_size_t o,							\
625 	TYPE *a,							\
626 	bus_size_t c)							\
627 {									\
628 									\
629 	while (c-- > 0) {						\
630 		*a++ = __C(__C(CHIP,_mem_read_),BYTES)(v, h, o);	\
631 		o += sizeof *a;						\
632 	}								\
633 }
634 CHIP_mem_read_region_N(1,uint8_t)
635 CHIP_mem_read_region_N(2,uint16_t)
636 CHIP_mem_read_region_N(4,uint32_t)
637 CHIP_mem_read_region_N(8,uint64_t)
638 
639 static inline void
__C(CHIP,_mem_write_1)640 __C(CHIP,_mem_write_1)(
641 	void *v,
642 	bus_space_handle_t memh,
643 	bus_size_t off,
644 	uint8_t val)
645 {
646 	bus_addr_t addr;
647 
648 	addr = memh + off;
649 	alpha_stb((uint8_t *)addr, val);
650 	alpha_mb();
651 }
652 
653 static inline void
__C(CHIP,_mem_write_2)654 __C(CHIP,_mem_write_2)(
655 	void *v,
656 	bus_space_handle_t memh,
657 	bus_size_t off,
658 	uint16_t val)
659 {
660 	bus_addr_t addr;
661 
662 	addr = memh + off;
663 #ifdef DIAGNOSTIC
664 	if (addr & 1)
665 		panic(__S(__C(CHIP,_mem_write_2)) ": addr 0x%lx not aligned",
666 		    addr);
667 #endif
668 	alpha_stw((uint16_t *)addr, val);
669 	alpha_mb();
670 }
671 
672 static inline void
__C(CHIP,_mem_write_4)673 __C(CHIP,_mem_write_4)(
674 	void *v,
675 	bus_space_handle_t memh,
676 	bus_size_t off,
677 	uint32_t val)
678 {
679 	bus_addr_t addr;
680 
681 	addr = memh + off;
682 #ifdef DIAGNOSTIC
683 	if (addr & 3)
684 		panic(__S(__C(CHIP,_mem_write_4)) ": addr 0x%lx not aligned",
685 		    addr);
686 #endif
687 	*(uint32_t *)addr = val;
688 	alpha_mb();
689 }
690 
691 static inline void
__C(CHIP,_mem_write_8)692 __C(CHIP,_mem_write_8)(
693 	void *v,
694 	bus_space_handle_t memh,
695 	bus_size_t off,
696 	uint64_t val)
697 {
698 
699 	/* XXX XXX XXX */
700 	panic("%s not implemented", __S(__C(CHIP,_mem_write_8)));
701 	alpha_mb();
702 }
703 
704 #define CHIP_mem_write_multi_N(BYTES,TYPE)				\
705 static void								\
706 __C(__C(CHIP,_mem_write_multi_),BYTES)(					\
707 	void *v,							\
708 	bus_space_handle_t h,						\
709 	bus_size_t o,							\
710 	const TYPE *a,							\
711 	bus_size_t c)							\
712 {									\
713 									\
714 	while (c-- > 0) {						\
715 		__C(__C(CHIP,_mem_write_),BYTES)(v, h, o, *a++);	\
716 		__C(CHIP,_mem_barrier)(v, h, o, sizeof *a,		\
717 		    BUS_SPACE_BARRIER_WRITE);				\
718 	}								\
719 }
720 CHIP_mem_write_multi_N(1,uint8_t)
721 CHIP_mem_write_multi_N(2,uint16_t)
722 CHIP_mem_write_multi_N(4,uint32_t)
723 CHIP_mem_write_multi_N(8,uint64_t)
724 
725 #define CHIP_mem_write_region_N(BYTES,TYPE)				\
726 static void								\
727 __C(__C(CHIP,_mem_write_region_),BYTES)(				\
728 	void *v,							\
729 	bus_space_handle_t h,						\
730 	bus_size_t o,							\
731 	const TYPE *a,							\
732 	bus_size_t c)							\
733 {									\
734 									\
735 	while (c-- > 0) {						\
736 		__C(__C(CHIP,_mem_write_),BYTES)(v, h, o, *a++);	\
737 		o += sizeof *a;						\
738 	}								\
739 }
740 CHIP_mem_write_region_N(1,uint8_t)
741 CHIP_mem_write_region_N(2,uint16_t)
742 CHIP_mem_write_region_N(4,uint32_t)
743 CHIP_mem_write_region_N(8,uint64_t)
744 
745 #define CHIP_mem_set_multi_N(BYTES,TYPE)				\
746 static void								\
747 __C(__C(CHIP,_mem_set_multi_),BYTES)(					\
748 	void *v,							\
749 	bus_space_handle_t h,						\
750 	bus_size_t o,							\
751 	TYPE val,							\
752 	bus_size_t c)							\
753 {									\
754 									\
755 	while (c-- > 0) {						\
756 		__C(__C(CHIP,_mem_write_),BYTES)(v, h, o, val);		\
757 		__C(CHIP,_mem_barrier)(v, h, o, sizeof val,		\
758 		    BUS_SPACE_BARRIER_WRITE);				\
759 	}								\
760 }
761 CHIP_mem_set_multi_N(1,uint8_t)
762 CHIP_mem_set_multi_N(2,uint16_t)
763 CHIP_mem_set_multi_N(4,uint32_t)
764 CHIP_mem_set_multi_N(8,uint64_t)
765 
766 #define CHIP_mem_set_region_N(BYTES,TYPE)				\
767 static void								\
768 __C(__C(CHIP,_mem_set_region_),BYTES)(					\
769 	void *v,							\
770 	bus_space_handle_t h,						\
771 	bus_size_t o,							\
772 	TYPE val,							\
773 	bus_size_t c)							\
774 {									\
775 									\
776 	while (c-- > 0) {						\
777 		__C(__C(CHIP,_mem_write_),BYTES)(v, h, o, val);		\
778 		o += sizeof val;					\
779 	}								\
780 }
781 CHIP_mem_set_region_N(1,uint8_t)
782 CHIP_mem_set_region_N(2,uint16_t)
783 CHIP_mem_set_region_N(4,uint32_t)
784 CHIP_mem_set_region_N(8,uint64_t)
785 
786 #define	CHIP_mem_copy_region_N(BYTES)					\
787 static void								\
788 __C(__C(CHIP,_mem_copy_region_),BYTES)(					\
789 	void *v,							\
790 	bus_space_handle_t h1,						\
791 	bus_size_t o1,							\
792 	bus_space_handle_t h2,						\
793 	bus_size_t o2,							\
794 	bus_size_t c)							\
795 {									\
796 	bus_size_t o;							\
797 									\
798 	if ((h1 + o1) >= (h2 + o2)) {					\
799 		/* src after dest: copy forward */			\
800 		for (o = 0; c != 0; c--, o += BYTES) {			\
801 			__C(__C(CHIP,_mem_write_),BYTES)(v, h2, o2 + o,	\
802 			    __C(__C(CHIP,_mem_read_),BYTES)(v, h1, o1 + o)); \
803 		}							\
804 	} else {							\
805 		/* dest after src: copy backwards */			\
806 		for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) {	\
807 			__C(__C(CHIP,_mem_write_),BYTES)(v, h2, o2 + o,	\
808 			    __C(__C(CHIP,_mem_read_),BYTES)(v, h1, o1 + o)); \
809 		}							\
810 	}								\
811 }
812 CHIP_mem_copy_region_N(1)
813 CHIP_mem_copy_region_N(2)
814 CHIP_mem_copy_region_N(4)
815 CHIP_mem_copy_region_N(8)
816