1/* $NetBSD: pci_bwx_bus_mem_chipdep.c,v 1.24 2012/01/27 18:52:49 para 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_EX_STORE
68 *			If defined, device-provided static storage area
69 *			for the memory space extent.  If this is
70 *			defined, CHIP_MEM_EX_STORE_SIZE must also be
71 *			defined.  If this is not defined, a static area
72 *			will be declared.
73 *	CHIP_MEM_EX_STORE_SIZE
74 *			Size of the device-provided static storage area
75 *			for the memory space extent.
76 */
77
78#include <sys/cdefs.h>
79__KERNEL_RCSID(1, "$NetBSD: pci_bwx_bus_mem_chipdep.c,v 1.24 2012/01/27 18:52:49 para Exp $");
80
81#include <sys/extent.h>
82
83#include <machine/bwx.h>
84
85#define	__C(A,B)	__CONCAT(A,B)
86#define	__S(S)		__STRING(S)
87
88/* mapping/unmapping */
89int		__C(CHIP,_mem_map)(void *, bus_addr_t, bus_size_t, int,
90		    bus_space_handle_t *, int);
91void		__C(CHIP,_mem_unmap)(void *, bus_space_handle_t,
92		    bus_size_t, int);
93int		__C(CHIP,_mem_subregion)(void *, bus_space_handle_t,
94		    bus_size_t, bus_size_t, bus_space_handle_t *);
95
96int		__C(CHIP,_mem_translate)(void *, bus_addr_t, bus_size_t,
97		    int, struct alpha_bus_space_translation *);
98int		__C(CHIP,_mem_get_window)(void *, int,
99		    struct alpha_bus_space_translation *);
100
101/* allocation/deallocation */
102int		__C(CHIP,_mem_alloc)(void *, bus_addr_t, bus_addr_t,
103		    bus_size_t, bus_size_t, bus_addr_t, int, bus_addr_t *,
104	            bus_space_handle_t *);
105void		__C(CHIP,_mem_free)(void *, bus_space_handle_t,
106		    bus_size_t);
107
108/* get kernel virtual address */
109void *		__C(CHIP,_mem_vaddr)(void *, bus_space_handle_t);
110
111/* mmap for user */
112paddr_t		__C(CHIP,_mem_mmap)(void *, bus_addr_t, off_t, int, int);
113
114/* barrier */
115static inline void	__C(CHIP,_mem_barrier)(void *, bus_space_handle_t,
116		    bus_size_t, bus_size_t, int);
117
118/* read (single) */
119static inline uint8_t	__C(CHIP,_mem_read_1)(void *, bus_space_handle_t,
120		    bus_size_t);
121static inline uint16_t __C(CHIP,_mem_read_2)(void *, bus_space_handle_t,
122		    bus_size_t);
123static inline uint32_t __C(CHIP,_mem_read_4)(void *, bus_space_handle_t,
124		    bus_size_t);
125static inline uint64_t __C(CHIP,_mem_read_8)(void *, bus_space_handle_t,
126		    bus_size_t);
127
128/* read multiple */
129void		__C(CHIP,_mem_read_multi_1)(void *, bus_space_handle_t,
130		    bus_size_t, uint8_t *, bus_size_t);
131void		__C(CHIP,_mem_read_multi_2)(void *, bus_space_handle_t,
132		    bus_size_t, uint16_t *, bus_size_t);
133void		__C(CHIP,_mem_read_multi_4)(void *, bus_space_handle_t,
134		    bus_size_t, uint32_t *, bus_size_t);
135void		__C(CHIP,_mem_read_multi_8)(void *, bus_space_handle_t,
136		    bus_size_t, uint64_t *, bus_size_t);
137
138/* read region */
139void		__C(CHIP,_mem_read_region_1)(void *, bus_space_handle_t,
140		    bus_size_t, uint8_t *, bus_size_t);
141void		__C(CHIP,_mem_read_region_2)(void *, bus_space_handle_t,
142		    bus_size_t, uint16_t *, bus_size_t);
143void		__C(CHIP,_mem_read_region_4)(void *, bus_space_handle_t,
144		    bus_size_t, uint32_t *, bus_size_t);
145void		__C(CHIP,_mem_read_region_8)(void *, bus_space_handle_t,
146		    bus_size_t, uint64_t *, bus_size_t);
147
148/* write (single) */
149static inline void	__C(CHIP,_mem_write_1)(void *, bus_space_handle_t,
150		    bus_size_t, uint8_t);
151static inline void	__C(CHIP,_mem_write_2)(void *, bus_space_handle_t,
152		    bus_size_t, uint16_t);
153static inline void	__C(CHIP,_mem_write_4)(void *, bus_space_handle_t,
154		    bus_size_t, uint32_t);
155static inline void	__C(CHIP,_mem_write_8)(void *, bus_space_handle_t,
156		    bus_size_t, uint64_t);
157
158/* write multiple */
159void		__C(CHIP,_mem_write_multi_1)(void *, bus_space_handle_t,
160		    bus_size_t, const uint8_t *, bus_size_t);
161void		__C(CHIP,_mem_write_multi_2)(void *, bus_space_handle_t,
162		    bus_size_t, const uint16_t *, bus_size_t);
163void		__C(CHIP,_mem_write_multi_4)(void *, bus_space_handle_t,
164		    bus_size_t, const uint32_t *, bus_size_t);
165void		__C(CHIP,_mem_write_multi_8)(void *, bus_space_handle_t,
166		    bus_size_t, const uint64_t *, bus_size_t);
167
168/* write region */
169void		__C(CHIP,_mem_write_region_1)(void *, bus_space_handle_t,
170		    bus_size_t, const uint8_t *, bus_size_t);
171void		__C(CHIP,_mem_write_region_2)(void *, bus_space_handle_t,
172		    bus_size_t, const uint16_t *, bus_size_t);
173void		__C(CHIP,_mem_write_region_4)(void *, bus_space_handle_t,
174		    bus_size_t, const uint32_t *, bus_size_t);
175void		__C(CHIP,_mem_write_region_8)(void *, bus_space_handle_t,
176		    bus_size_t, const uint64_t *, bus_size_t);
177
178/* set multiple */
179void		__C(CHIP,_mem_set_multi_1)(void *, bus_space_handle_t,
180		    bus_size_t, uint8_t, bus_size_t);
181void		__C(CHIP,_mem_set_multi_2)(void *, bus_space_handle_t,
182		    bus_size_t, uint16_t, bus_size_t);
183void		__C(CHIP,_mem_set_multi_4)(void *, bus_space_handle_t,
184		    bus_size_t, uint32_t, bus_size_t);
185void		__C(CHIP,_mem_set_multi_8)(void *, bus_space_handle_t,
186		    bus_size_t, uint64_t, bus_size_t);
187
188/* set region */
189void		__C(CHIP,_mem_set_region_1)(void *, bus_space_handle_t,
190		    bus_size_t, uint8_t, bus_size_t);
191void		__C(CHIP,_mem_set_region_2)(void *, bus_space_handle_t,
192		    bus_size_t, uint16_t, bus_size_t);
193void		__C(CHIP,_mem_set_region_4)(void *, bus_space_handle_t,
194		    bus_size_t, uint32_t, bus_size_t);
195void		__C(CHIP,_mem_set_region_8)(void *, bus_space_handle_t,
196		    bus_size_t, uint64_t, bus_size_t);
197
198/* copy */
199void		__C(CHIP,_mem_copy_region_1)(void *, bus_space_handle_t,
200		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
201void		__C(CHIP,_mem_copy_region_2)(void *, bus_space_handle_t,
202		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
203void		__C(CHIP,_mem_copy_region_4)(void *, bus_space_handle_t,
204		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
205void		__C(CHIP,_mem_copy_region_8)(void *, bus_space_handle_t,
206		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
207
208#ifndef	CHIP_MEM_EX_STORE
209static long
210    __C(CHIP,_mem_ex_storage)[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)];
211#define	CHIP_MEM_EX_STORE(v)		(__C(CHIP,_mem_ex_storage))
212#define	CHIP_MEM_EX_STORE_SIZE(v)	(sizeof __C(CHIP,_mem_ex_storage))
213#endif
214
215void
216__C(CHIP,_bus_mem_init)(
217	bus_space_tag_t t,
218	void *v)
219{
220	struct extent *ex;
221
222	/*
223	 * Initialize the bus space tag.
224	 */
225
226	/* cookie */
227	t->abs_cookie =		v;
228
229	/* mapping/unmapping */
230	t->abs_map =		__C(CHIP,_mem_map);
231	t->abs_unmap =		__C(CHIP,_mem_unmap);
232	t->abs_subregion =	__C(CHIP,_mem_subregion);
233
234	t->abs_translate =	__C(CHIP,_mem_translate);
235	t->abs_get_window =	__C(CHIP,_mem_get_window);
236
237	/* allocation/deallocation */
238	t->abs_alloc =		__C(CHIP,_mem_alloc);
239	t->abs_free = 		__C(CHIP,_mem_free);
240
241	/* get kernel virtual address */
242	t->abs_vaddr =		__C(CHIP,_mem_vaddr);
243
244	/* mmap for user */
245	t->abs_mmap =		__C(CHIP,_mem_mmap);
246
247	/* barrier */
248	t->abs_barrier =	__C(CHIP,_mem_barrier);
249
250	/* read (single) */
251	t->abs_r_1 =		__C(CHIP,_mem_read_1);
252	t->abs_r_2 =		__C(CHIP,_mem_read_2);
253	t->abs_r_4 =		__C(CHIP,_mem_read_4);
254	t->abs_r_8 =		__C(CHIP,_mem_read_8);
255
256	/* read multiple */
257	t->abs_rm_1 =		__C(CHIP,_mem_read_multi_1);
258	t->abs_rm_2 =		__C(CHIP,_mem_read_multi_2);
259	t->abs_rm_4 =		__C(CHIP,_mem_read_multi_4);
260	t->abs_rm_8 =		__C(CHIP,_mem_read_multi_8);
261
262	/* read region */
263	t->abs_rr_1 =		__C(CHIP,_mem_read_region_1);
264	t->abs_rr_2 =		__C(CHIP,_mem_read_region_2);
265	t->abs_rr_4 =		__C(CHIP,_mem_read_region_4);
266	t->abs_rr_8 =		__C(CHIP,_mem_read_region_8);
267
268	/* write (single) */
269	t->abs_w_1 =		__C(CHIP,_mem_write_1);
270	t->abs_w_2 =		__C(CHIP,_mem_write_2);
271	t->abs_w_4 =		__C(CHIP,_mem_write_4);
272	t->abs_w_8 =		__C(CHIP,_mem_write_8);
273
274	/* write multiple */
275	t->abs_wm_1 =		__C(CHIP,_mem_write_multi_1);
276	t->abs_wm_2 =		__C(CHIP,_mem_write_multi_2);
277	t->abs_wm_4 =		__C(CHIP,_mem_write_multi_4);
278	t->abs_wm_8 =		__C(CHIP,_mem_write_multi_8);
279
280	/* write region */
281	t->abs_wr_1 =		__C(CHIP,_mem_write_region_1);
282	t->abs_wr_2 =		__C(CHIP,_mem_write_region_2);
283	t->abs_wr_4 =		__C(CHIP,_mem_write_region_4);
284	t->abs_wr_8 =		__C(CHIP,_mem_write_region_8);
285
286	/* set multiple */
287	t->abs_sm_1 =		__C(CHIP,_mem_set_multi_1);
288	t->abs_sm_2 =		__C(CHIP,_mem_set_multi_2);
289	t->abs_sm_4 =		__C(CHIP,_mem_set_multi_4);
290	t->abs_sm_8 =		__C(CHIP,_mem_set_multi_8);
291
292	/* set region */
293	t->abs_sr_1 =		__C(CHIP,_mem_set_region_1);
294	t->abs_sr_2 =		__C(CHIP,_mem_set_region_2);
295	t->abs_sr_4 =		__C(CHIP,_mem_set_region_4);
296	t->abs_sr_8 =		__C(CHIP,_mem_set_region_8);
297
298	/* copy */
299	t->abs_c_1 =		__C(CHIP,_mem_copy_region_1);
300	t->abs_c_2 =		__C(CHIP,_mem_copy_region_2);
301	t->abs_c_4 =		__C(CHIP,_mem_copy_region_4);
302	t->abs_c_8 =		__C(CHIP,_mem_copy_region_8);
303
304	ex = extent_create(__S(__C(CHIP,_bus_mem)), 0x0UL, 0xffffffffUL,
305	    (void *)CHIP_MEM_EX_STORE(v), CHIP_MEM_EX_STORE_SIZE(v),
306	    EX_NOWAIT|EX_NOCOALESCE);
307
308	CHIP_MEM_EXTENT(v) = ex;
309}
310
311int
312__C(CHIP,_mem_translate)(
313	void *v,
314	bus_addr_t memaddr,
315	bus_size_t memlen,
316	int flags,
317	struct alpha_bus_space_translation *abst)
318{
319
320	/* XXX */
321	return (EOPNOTSUPP);
322}
323
324int
325__C(CHIP,_mem_get_window)(
326	void *v,
327	int window,
328	struct alpha_bus_space_translation *abst)
329{
330
331	switch (window) {
332	case 0:
333		abst->abst_bus_start = 0;
334		abst->abst_bus_end = 0xffffffffUL;
335		abst->abst_sys_start = CHIP_MEM_SYS_START(v);
336		abst->abst_sys_end = CHIP_MEM_SYS_START(v) + abst->abst_bus_end;
337		abst->abst_addr_shift = 0;
338		abst->abst_size_shift = 0;
339		abst->abst_flags = ABST_DENSE|ABST_BWX;
340		break;
341
342	default:
343		panic(__S(__C(CHIP,_mem_get_window)) ": invalid window %d",
344		    window);
345	}
346
347	return (0);
348}
349
350int
351__C(CHIP,_mem_map)(
352	void *v,
353	bus_addr_t memaddr,
354	bus_size_t memsize,
355	int flags,
356	bus_space_handle_t *memhp,
357	int acct)
358{
359	int error;
360
361	if (acct == 0)
362		goto mapit;
363
364#ifdef EXTENT_DEBUG
365	printf("mem: allocating 0x%lx to 0x%lx\n", memaddr,
366	    memaddr + memsize - 1);
367#endif
368	error = extent_alloc_region(CHIP_MEM_EXTENT(v), memaddr, memsize,
369	    EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0));
370	if (error) {
371#ifdef EXTENT_DEBUG
372		printf("mem: allocation failed (%d)\n", error);
373		extent_print(CHIP_MEM_EXTENT(v));
374#endif
375		return (error);
376	}
377
378 mapit:
379	*memhp = ALPHA_PHYS_TO_K0SEG(CHIP_MEM_SYS_START(v)) + memaddr;
380
381	return (0);
382}
383
384void
385__C(CHIP,_mem_unmap)(
386	void *v,
387	bus_space_handle_t memh,
388	bus_size_t memsize,
389	int acct)
390{
391	bus_addr_t memaddr;
392	int error;
393
394	if (acct == 0)
395		return;
396
397#ifdef EXTENT_DEBUG
398	printf("mem: freeing handle 0x%lx for 0x%lx\n", memh, memsize);
399#endif
400
401	memaddr = memh - ALPHA_PHYS_TO_K0SEG(CHIP_MEM_SYS_START(v));
402
403#ifdef EXTENT_DEBUG
404	printf("mem: freeing 0x%lx to 0x%lx\n", memaddr, memaddr + memsize - 1);
405#endif
406
407	error = extent_free(CHIP_MEM_EXTENT(v), memaddr, memsize,
408	    EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0));
409	if (error) {
410		printf("%s: WARNING: could not unmap 0x%lx-0x%lx (error %d)\n",
411		    __S(__C(CHIP,_mem_unmap)), memaddr, memaddr + memsize - 1,
412		    error);
413#ifdef EXTENT_DEBUG
414		extent_print(CHIP_MEM_EXTENT(v));
415#endif
416	}
417}
418
419int
420__C(CHIP,_mem_subregion)(
421	void *v,
422	bus_space_handle_t memh,
423	bus_size_t offset,
424	bus_size_t size,
425	bus_space_handle_t *nmemh)
426{
427
428	*nmemh = memh + offset;
429	return (0);
430}
431
432int
433__C(CHIP,_mem_alloc)(
434	void *v,
435	bus_addr_t rstart,
436	bus_addr_t rend,
437	bus_size_t size,
438	bus_size_t align,
439	bus_size_t boundary,
440	int flags,
441	bus_addr_t *addrp,
442	bus_space_handle_t *bshp)
443{
444	bus_addr_t memaddr;
445	int error;
446
447	/*
448	 * Do the requested allocation.
449	 */
450#ifdef EXTENT_DEBUG
451	printf("mem: allocating from 0x%lx to 0x%lx\n", rstart, rend);
452#endif
453	error = extent_alloc_subregion(CHIP_MEM_EXTENT(v), rstart, rend,
454	    size, align, boundary,
455	    EX_FAST | EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0),
456	    &memaddr);
457	if (error) {
458#ifdef EXTENT_DEBUG
459		printf("mem: allocation failed (%d)\n", error);
460		extent_print(CHIP_MEM_EXTENT(v));
461#endif
462	}
463
464#ifdef EXTENT_DEBUG
465	printf("mem: allocated 0x%lx to 0x%lx\n", memaddr, memaddr + size - 1);
466#endif
467
468	*addrp = memaddr;
469	*bshp = ALPHA_PHYS_TO_K0SEG(CHIP_MEM_SYS_START(v)) + memaddr;
470
471	return (0);
472}
473
474void
475__C(CHIP,_mem_free)(
476	void *v,
477	bus_space_handle_t bsh,
478	bus_size_t size)
479{
480
481	/* Unmap does all we need to do. */
482	__C(CHIP,_mem_unmap)(v, bsh, size, 1);
483}
484
485void *
486__C(CHIP,_mem_vaddr)(
487	void *v,
488	bus_space_handle_t bsh)
489{
490
491	return ((void *)bsh);
492}
493
494paddr_t
495__C(CHIP,_mem_mmap)(
496	void *v,
497	bus_addr_t addr,
498	off_t off,
499	int prot,
500	int flags)
501{
502
503	return (alpha_btop(CHIP_MEM_SYS_START(v) + addr + off));
504}
505
506static inline void
507__C(CHIP,_mem_barrier)(
508	void *v,
509	bus_space_handle_t h,
510	bus_size_t o,
511	bus_size_t l,
512	int f)
513{
514
515	if ((f & BUS_SPACE_BARRIER_READ) != 0)
516		alpha_mb();
517	else if ((f & BUS_SPACE_BARRIER_WRITE) != 0)
518		alpha_wmb();
519}
520
521static inline uint8_t
522__C(CHIP,_mem_read_1)(
523	void *v,
524	bus_space_handle_t memh,
525	bus_size_t off)
526{
527	bus_addr_t addr;
528
529	addr = memh + off;
530	alpha_mb();
531	return (alpha_ldbu((uint8_t *)addr));
532}
533
534static inline uint16_t
535__C(CHIP,_mem_read_2)(
536	void *v,
537	bus_space_handle_t memh,
538	bus_size_t off)
539{
540	bus_addr_t addr;
541
542	addr = memh + off;
543#ifdef DIAGNOSTIC
544	if (addr & 1)
545		panic(__S(__C(CHIP,_mem_read_2)) ": addr 0x%lx not aligned",
546		    addr);
547#endif
548	alpha_mb();
549	return (alpha_ldwu((uint16_t *)addr));
550}
551
552static inline uint32_t
553__C(CHIP,_mem_read_4)(
554	void *v,
555	bus_space_handle_t memh,
556	bus_size_t off)
557{
558	bus_addr_t addr;
559
560	addr = memh + off;
561#ifdef DIAGNOSTIC
562	if (addr & 3)
563		panic(__S(__C(CHIP,_mem_read_4)) ": addr 0x%lx not aligned",
564		    addr);
565#endif
566	alpha_mb();
567	return (*(uint32_t *)addr);
568}
569
570static inline uint64_t
571__C(CHIP,_mem_read_8)(
572	void *v,
573	bus_space_handle_t memh,
574	bus_size_t off)
575{
576
577	alpha_mb();
578
579	/* XXX XXX XXX */
580	panic("%s not implemented", __S(__C(CHIP,_mem_read_8)));
581}
582
583#define CHIP_mem_read_multi_N(BYTES,TYPE)				\
584void									\
585__C(__C(CHIP,_mem_read_multi_),BYTES)(					\
586	void *v,							\
587	bus_space_handle_t h,						\
588	bus_size_t o,							\
589	TYPE *a,							\
590	bus_size_t c)							\
591{									\
592									\
593	while (c-- > 0) {						\
594		__C(CHIP,_mem_barrier)(v, h, o, sizeof *a,		\
595		    BUS_SPACE_BARRIER_READ);				\
596		*a++ = __C(__C(CHIP,_mem_read_),BYTES)(v, h, o);	\
597	}								\
598}
599CHIP_mem_read_multi_N(1,uint8_t)
600CHIP_mem_read_multi_N(2,uint16_t)
601CHIP_mem_read_multi_N(4,uint32_t)
602CHIP_mem_read_multi_N(8,uint64_t)
603
604#define CHIP_mem_read_region_N(BYTES,TYPE)				\
605void									\
606__C(__C(CHIP,_mem_read_region_),BYTES)(					\
607	void *v,							\
608	bus_space_handle_t h,						\
609	bus_size_t o,							\
610	TYPE *a,							\
611	bus_size_t c)							\
612{									\
613									\
614	while (c-- > 0) {						\
615		*a++ = __C(__C(CHIP,_mem_read_),BYTES)(v, h, o);	\
616		o += sizeof *a;						\
617	}								\
618}
619CHIP_mem_read_region_N(1,uint8_t)
620CHIP_mem_read_region_N(2,uint16_t)
621CHIP_mem_read_region_N(4,uint32_t)
622CHIP_mem_read_region_N(8,uint64_t)
623
624static inline void
625__C(CHIP,_mem_write_1)(
626	void *v,
627	bus_space_handle_t memh,
628	bus_size_t off,
629	uint8_t val)
630{
631	bus_addr_t addr;
632
633	addr = memh + off;
634	alpha_stb((uint8_t *)addr, val);
635	alpha_mb();
636}
637
638static inline void
639__C(CHIP,_mem_write_2)(
640	void *v,
641	bus_space_handle_t memh,
642	bus_size_t off,
643	uint16_t val)
644{
645	bus_addr_t addr;
646
647	addr = memh + off;
648#ifdef DIAGNOSTIC
649	if (addr & 1)
650		panic(__S(__C(CHIP,_mem_write_2)) ": addr 0x%lx not aligned",
651		    addr);
652#endif
653	alpha_stw((uint16_t *)addr, val);
654	alpha_mb();
655}
656
657static inline void
658__C(CHIP,_mem_write_4)(
659	void *v,
660	bus_space_handle_t memh,
661	bus_size_t off,
662	uint32_t val)
663{
664	bus_addr_t addr;
665
666	addr = memh + off;
667#ifdef DIAGNOSTIC
668	if (addr & 3)
669		panic(__S(__C(CHIP,_mem_write_4)) ": addr 0x%lx not aligned",
670		    addr);
671#endif
672	*(uint32_t *)addr = val;
673	alpha_mb();
674}
675
676static inline void
677__C(CHIP,_mem_write_8)(
678	void *v,
679	bus_space_handle_t memh,
680	bus_size_t off,
681	uint64_t val)
682{
683
684	/* XXX XXX XXX */
685	panic("%s not implemented", __S(__C(CHIP,_mem_write_8)));
686	alpha_mb();
687}
688
689#define CHIP_mem_write_multi_N(BYTES,TYPE)				\
690void									\
691__C(__C(CHIP,_mem_write_multi_),BYTES)(					\
692	void *v,							\
693	bus_space_handle_t h,						\
694	bus_size_t o,							\
695	const TYPE *a,							\
696	bus_size_t c)							\
697{									\
698									\
699	while (c-- > 0) {						\
700		__C(__C(CHIP,_mem_write_),BYTES)(v, h, o, *a++);	\
701		__C(CHIP,_mem_barrier)(v, h, o, sizeof *a,		\
702		    BUS_SPACE_BARRIER_WRITE);				\
703	}								\
704}
705CHIP_mem_write_multi_N(1,uint8_t)
706CHIP_mem_write_multi_N(2,uint16_t)
707CHIP_mem_write_multi_N(4,uint32_t)
708CHIP_mem_write_multi_N(8,uint64_t)
709
710#define CHIP_mem_write_region_N(BYTES,TYPE)				\
711void									\
712__C(__C(CHIP,_mem_write_region_),BYTES)(				\
713	void *v,							\
714	bus_space_handle_t h,						\
715	bus_size_t o,							\
716	const TYPE *a,							\
717	bus_size_t c)							\
718{									\
719									\
720	while (c-- > 0) {						\
721		__C(__C(CHIP,_mem_write_),BYTES)(v, h, o, *a++);	\
722		o += sizeof *a;						\
723	}								\
724}
725CHIP_mem_write_region_N(1,uint8_t)
726CHIP_mem_write_region_N(2,uint16_t)
727CHIP_mem_write_region_N(4,uint32_t)
728CHIP_mem_write_region_N(8,uint64_t)
729
730#define CHIP_mem_set_multi_N(BYTES,TYPE)				\
731void									\
732__C(__C(CHIP,_mem_set_multi_),BYTES)(					\
733	void *v,							\
734	bus_space_handle_t h,						\
735	bus_size_t o,							\
736	TYPE val,							\
737	bus_size_t c)							\
738{									\
739									\
740	while (c-- > 0) {						\
741		__C(__C(CHIP,_mem_write_),BYTES)(v, h, o, val);		\
742		__C(CHIP,_mem_barrier)(v, h, o, sizeof val,		\
743		    BUS_SPACE_BARRIER_WRITE);				\
744	}								\
745}
746CHIP_mem_set_multi_N(1,uint8_t)
747CHIP_mem_set_multi_N(2,uint16_t)
748CHIP_mem_set_multi_N(4,uint32_t)
749CHIP_mem_set_multi_N(8,uint64_t)
750
751#define CHIP_mem_set_region_N(BYTES,TYPE)				\
752void									\
753__C(__C(CHIP,_mem_set_region_),BYTES)(					\
754	void *v,							\
755	bus_space_handle_t h,						\
756	bus_size_t o,							\
757	TYPE val,							\
758	bus_size_t c)							\
759{									\
760									\
761	while (c-- > 0) {						\
762		__C(__C(CHIP,_mem_write_),BYTES)(v, h, o, val);		\
763		o += sizeof val;					\
764	}								\
765}
766CHIP_mem_set_region_N(1,uint8_t)
767CHIP_mem_set_region_N(2,uint16_t)
768CHIP_mem_set_region_N(4,uint32_t)
769CHIP_mem_set_region_N(8,uint64_t)
770
771#define	CHIP_mem_copy_region_N(BYTES)					\
772void									\
773__C(__C(CHIP,_mem_copy_region_),BYTES)(					\
774	void *v,							\
775	bus_space_handle_t h1,						\
776	bus_size_t o1,							\
777	bus_space_handle_t h2,						\
778	bus_size_t o2,							\
779	bus_size_t c)							\
780{									\
781	bus_size_t o;							\
782									\
783	if ((h1 + o1) >= (h2 + o2)) {					\
784		/* src after dest: copy forward */			\
785		for (o = 0; c != 0; c--, o += BYTES) {			\
786			__C(__C(CHIP,_mem_write_),BYTES)(v, h2, o2 + o,	\
787			    __C(__C(CHIP,_mem_read_),BYTES)(v, h1, o1 + o)); \
788		}							\
789	} else {							\
790		/* dest after src: copy backwards */			\
791		for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) {	\
792			__C(__C(CHIP,_mem_write_),BYTES)(v, h2, o2 + o,	\
793			    __C(__C(CHIP,_mem_read_),BYTES)(v, h1, o1 + o)); \
794		}							\
795	}								\
796}
797CHIP_mem_copy_region_N(1)
798CHIP_mem_copy_region_N(2)
799CHIP_mem_copy_region_N(4)
800CHIP_mem_copy_region_N(8)
801