1/* $OpenBSD: pci_bwx_bus_mem_chipdep.c,v 1.10 2014/02/23 12:26:18 jsg Exp $ */
2/* $NetBSD: pcs_bus_mem_common.c,v 1.15 1996/12/02 22:19:36 cgd Exp $ */
3
4/*
5 * Copyright (c) 1995, 1996 Carnegie-Mellon University.
6 * All rights reserved.
7 *
8 * Author: Chris G. Demetriou
9 *
10 * Permission to use, copy, modify and distribute this software and
11 * its documentation is hereby granted, provided that both the copyright
12 * notice and this permission notice appear in all copies of the
13 * software, derivative works or modified versions, and any portions
14 * thereof, and that both notices appear in supporting documentation.
15 *
16 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
17 * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
18 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
19 *
20 * Carnegie Mellon requests users of this software to return to
21 *
22 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
23 *  School of Computer Science
24 *  Carnegie Mellon University
25 *  Pittsburgh PA 15213-3890
26 *
27 * any improvements or extensions that they make and grant Carnegie the
28 * rights to redistribute these changes.
29 */
30
31/*
32 * Common PCI Chipset "bus I/O" functions, for chipsets which have to
33 * deal with only a single PCI interface chip in a machine.
34 *
35 * uses:
36 *	CHIP		name of the 'chip' it's being compiled for.
37 *	CHIP_MEM_BASE   Mem space base to use.
38 *	CHIP_MEM_EX_STORE
39 *			If defined, device-provided static storage area
40 *			for the memory space extent.  If this is
41 *			defined, CHIP_MEM_EX_STORE_SIZE must also be
42 *			defined.  If this is not defined, a static area
43 *			will be declared.
44 *	CHIP_MEM_EX_STORE_SIZE
45 *			Size of the device-provided static storage area
46 *			for the memory space extent.
47 */
48
49#include <sys/extent.h>
50#include <machine/bwx.h>
51
52#define	__C(A,B)	__CONCAT(A,B)
53#define	__S(S)		__STRING(S)
54
55#ifndef	CHIP_EXTENT_NAME
56#define	CHIP_EXTENT_NAME(v)	__S(__C(CHIP,_bus_dmem))
57#endif
58
59#ifndef	CHIP_EXTENT_STORAGE
60#define CHIP_EXTENT_STORAGE(v)	__C(CHIP,_mem_ex_storage)
61static long
62    __C(CHIP,_mem_ex_storage)[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)];
63#endif
64
65/* mapping/unmapping */
66int		__C(CHIP,_mem_map)(void *, bus_addr_t, bus_size_t, int,
67		    bus_space_handle_t *);
68void		__C(CHIP,_mem_unmap)(void *, bus_space_handle_t,
69		    bus_size_t);
70int		__C(CHIP,_mem_subregion)(void *, bus_space_handle_t,
71		    bus_size_t, bus_size_t, bus_space_handle_t *);
72
73/* allocation/deallocation */
74int		__C(CHIP,_mem_alloc)(void *, bus_addr_t, bus_addr_t,
75		    bus_size_t, bus_size_t, bus_addr_t, int, bus_addr_t *,
76                    bus_space_handle_t *);
77void		__C(CHIP,_mem_free)(void *, bus_space_handle_t,
78		    bus_size_t);
79
80/* get kernel virtual address */
81void *		__C(CHIP,_mem_vaddr)(void *, bus_space_handle_t);
82
83/* barrier */
84inline void	__C(CHIP,_mem_barrier)(void *, bus_space_handle_t,
85		    bus_size_t, bus_size_t, int);
86
87/* read (single) */
88inline u_int8_t	__C(CHIP,_mem_read_1)(void *, bus_space_handle_t,
89		    bus_size_t);
90inline u_int16_t __C(CHIP,_mem_read_2)(void *, bus_space_handle_t,
91		    bus_size_t);
92inline u_int32_t __C(CHIP,_mem_read_4)(void *, bus_space_handle_t,
93		    bus_size_t);
94inline u_int64_t __C(CHIP,_mem_read_8)(void *, bus_space_handle_t,
95		    bus_size_t);
96
97/* read multiple */
98void		__C(CHIP,_mem_read_multi_1)(void *, bus_space_handle_t,
99		    bus_size_t, u_int8_t *, bus_size_t);
100void		__C(CHIP,_mem_read_multi_2)(void *, bus_space_handle_t,
101		    bus_size_t, u_int16_t *, bus_size_t);
102void		__C(CHIP,_mem_read_multi_4)(void *, bus_space_handle_t,
103		    bus_size_t, u_int32_t *, bus_size_t);
104void		__C(CHIP,_mem_read_multi_8)(void *, bus_space_handle_t,
105		    bus_size_t, u_int64_t *, bus_size_t);
106
107/* read region */
108void		__C(CHIP,_mem_read_region_1)(void *, bus_space_handle_t,
109		    bus_size_t, u_int8_t *, bus_size_t);
110void		__C(CHIP,_mem_read_region_2)(void *, bus_space_handle_t,
111		    bus_size_t, u_int16_t *, bus_size_t);
112void		__C(CHIP,_mem_read_region_4)(void *, bus_space_handle_t,
113		    bus_size_t, u_int32_t *, bus_size_t);
114void		__C(CHIP,_mem_read_region_8)(void *, bus_space_handle_t,
115		    bus_size_t, u_int64_t *, bus_size_t);
116
117/* write (single) */
118inline void	__C(CHIP,_mem_write_1)(void *, bus_space_handle_t,
119		    bus_size_t, u_int8_t);
120inline void	__C(CHIP,_mem_write_2)(void *, bus_space_handle_t,
121		    bus_size_t, u_int16_t);
122inline void	__C(CHIP,_mem_write_4)(void *, bus_space_handle_t,
123		    bus_size_t, u_int32_t);
124inline void	__C(CHIP,_mem_write_8)(void *, bus_space_handle_t,
125		    bus_size_t, u_int64_t);
126
127/* write multiple */
128void		__C(CHIP,_mem_write_multi_1)(void *, bus_space_handle_t,
129		    bus_size_t, const u_int8_t *, bus_size_t);
130void		__C(CHIP,_mem_write_multi_2)(void *, bus_space_handle_t,
131		    bus_size_t, const u_int16_t *, bus_size_t);
132void		__C(CHIP,_mem_write_multi_4)(void *, bus_space_handle_t,
133		    bus_size_t, const u_int32_t *, bus_size_t);
134void		__C(CHIP,_mem_write_multi_8)(void *, bus_space_handle_t,
135		    bus_size_t, const u_int64_t *, bus_size_t);
136
137/* write region */
138void		__C(CHIP,_mem_write_region_1)(void *, bus_space_handle_t,
139		    bus_size_t, const u_int8_t *, bus_size_t);
140void		__C(CHIP,_mem_write_region_2)(void *, bus_space_handle_t,
141		    bus_size_t, const u_int16_t *, bus_size_t);
142void		__C(CHIP,_mem_write_region_4)(void *, bus_space_handle_t,
143		    bus_size_t, const u_int32_t *, bus_size_t);
144void		__C(CHIP,_mem_write_region_8)(void *, bus_space_handle_t,
145		    bus_size_t, const u_int64_t *, bus_size_t);
146
147/* set multiple */
148void		__C(CHIP,_mem_set_multi_1)(void *, bus_space_handle_t,
149		    bus_size_t, u_int8_t, bus_size_t);
150void		__C(CHIP,_mem_set_multi_2)(void *, bus_space_handle_t,
151		    bus_size_t, u_int16_t, bus_size_t);
152void		__C(CHIP,_mem_set_multi_4)(void *, bus_space_handle_t,
153		    bus_size_t, u_int32_t, bus_size_t);
154void		__C(CHIP,_mem_set_multi_8)(void *, bus_space_handle_t,
155		    bus_size_t, u_int64_t, bus_size_t);
156
157/* set region */
158void		__C(CHIP,_mem_set_region_1)(void *, bus_space_handle_t,
159		    bus_size_t, u_int8_t, bus_size_t);
160void		__C(CHIP,_mem_set_region_2)(void *, bus_space_handle_t,
161		    bus_size_t, u_int16_t, bus_size_t);
162void		__C(CHIP,_mem_set_region_4)(void *, bus_space_handle_t,
163		    bus_size_t, u_int32_t, bus_size_t);
164void		__C(CHIP,_mem_set_region_8)(void *, bus_space_handle_t,
165		    bus_size_t, u_int64_t, bus_size_t);
166
167/* copy */
168void		__C(CHIP,_mem_copy_1)(void *, bus_space_handle_t,
169		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
170void		__C(CHIP,_mem_copy_2)(void *, bus_space_handle_t,
171		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
172void		__C(CHIP,_mem_copy_4)(void *, bus_space_handle_t,
173		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
174void		__C(CHIP,_mem_copy_8)(void *, bus_space_handle_t,
175		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
176
177/* read multiple raw */
178void		__C(CHIP,_mem_read_raw_multi_2)(void *,
179		    bus_space_handle_t, bus_size_t, u_int8_t *, bus_size_t);
180void		__C(CHIP,_mem_read_raw_multi_4)(void *,
181		    bus_space_handle_t, bus_size_t, u_int8_t *, bus_size_t);
182void		__C(CHIP,_mem_read_raw_multi_8)(void *,
183		    bus_space_handle_t, bus_size_t, u_int8_t *, bus_size_t);
184
185/* write multiple raw */
186void		__C(CHIP,_mem_write_raw_multi_2)(void *,
187		    bus_space_handle_t, bus_size_t, const u_int8_t *,
188		    bus_size_t);
189void		__C(CHIP,_mem_write_raw_multi_4)(void *,
190		    bus_space_handle_t, bus_size_t, const u_int8_t *,
191		    bus_size_t);
192void		__C(CHIP,_mem_write_raw_multi_8)(void *,
193		    bus_space_handle_t, bus_size_t, const u_int8_t *,
194		    bus_size_t);
195
196void
197__C(CHIP,_bus_mem_init)(t, v)
198	bus_space_tag_t t;
199	void *v;
200{
201	struct extent *ex;
202
203	/*
204	 * Initialize the bus space tag.
205	 */
206
207	/* cookie */
208	t->abs_cookie =		v;
209
210	/* mapping/unmapping */
211	t->abs_map =		__C(CHIP,_mem_map);
212	t->abs_unmap =		__C(CHIP,_mem_unmap);
213	t->abs_subregion =	__C(CHIP,_mem_subregion);
214
215	/* allocation/deallocation */
216	t->abs_alloc =		__C(CHIP,_mem_alloc);
217	t->abs_free = 		__C(CHIP,_mem_free);
218
219	/* get kernel virtual address */
220	t->abs_vaddr =		__C(CHIP,_mem_vaddr);
221
222	/* barrier */
223	t->abs_barrier =	__C(CHIP,_mem_barrier);
224
225	/* read (single) */
226	t->abs_r_1 =		__C(CHIP,_mem_read_1);
227	t->abs_r_2 =		__C(CHIP,_mem_read_2);
228	t->abs_r_4 =		__C(CHIP,_mem_read_4);
229	t->abs_r_8 =		__C(CHIP,_mem_read_8);
230
231	/* read multiple */
232	t->abs_rm_1 =		__C(CHIP,_mem_read_multi_1);
233	t->abs_rm_2 =		__C(CHIP,_mem_read_multi_2);
234	t->abs_rm_4 =		__C(CHIP,_mem_read_multi_4);
235	t->abs_rm_8 =		__C(CHIP,_mem_read_multi_8);
236
237	/* read region */
238	t->abs_rr_1 =		__C(CHIP,_mem_read_region_1);
239	t->abs_rr_2 =		__C(CHIP,_mem_read_region_2);
240	t->abs_rr_4 =		__C(CHIP,_mem_read_region_4);
241	t->abs_rr_8 =		__C(CHIP,_mem_read_region_8);
242
243	/* write (single) */
244	t->abs_w_1 =		__C(CHIP,_mem_write_1);
245	t->abs_w_2 =		__C(CHIP,_mem_write_2);
246	t->abs_w_4 =		__C(CHIP,_mem_write_4);
247	t->abs_w_8 =		__C(CHIP,_mem_write_8);
248
249	/* write multiple */
250	t->abs_wm_1 =		__C(CHIP,_mem_write_multi_1);
251	t->abs_wm_2 =		__C(CHIP,_mem_write_multi_2);
252	t->abs_wm_4 =		__C(CHIP,_mem_write_multi_4);
253	t->abs_wm_8 =		__C(CHIP,_mem_write_multi_8);
254
255	/* write region */
256	t->abs_wr_1 =		__C(CHIP,_mem_write_region_1);
257	t->abs_wr_2 =		__C(CHIP,_mem_write_region_2);
258	t->abs_wr_4 =		__C(CHIP,_mem_write_region_4);
259	t->abs_wr_8 =		__C(CHIP,_mem_write_region_8);
260
261	/* set multiple */
262	t->abs_sm_1 =		__C(CHIP,_mem_set_multi_1);
263	t->abs_sm_2 =		__C(CHIP,_mem_set_multi_2);
264	t->abs_sm_4 =		__C(CHIP,_mem_set_multi_4);
265	t->abs_sm_8 =		__C(CHIP,_mem_set_multi_8);
266
267	/* set region */
268	t->abs_sr_1 =		__C(CHIP,_mem_set_region_1);
269	t->abs_sr_2 =		__C(CHIP,_mem_set_region_2);
270	t->abs_sr_4 =		__C(CHIP,_mem_set_region_4);
271	t->abs_sr_8 =		__C(CHIP,_mem_set_region_8);
272
273	/* copy */
274	t->abs_c_1 =		__C(CHIP,_mem_copy_1);
275	t->abs_c_2 =		__C(CHIP,_mem_copy_2);
276	t->abs_c_4 =		__C(CHIP,_mem_copy_4);
277	t->abs_c_8 =		__C(CHIP,_mem_copy_8);
278
279	/* read multiple raw */
280	t->abs_rrm_2 =		__C(CHIP,_mem_read_raw_multi_2);
281	t->abs_rrm_4 =		__C(CHIP,_mem_read_raw_multi_4);
282	t->abs_rrm_8 =		__C(CHIP,_mem_read_raw_multi_8);
283
284	/* write multiple raw*/
285	t->abs_wrm_2 =		__C(CHIP,_mem_write_raw_multi_2);
286	t->abs_wrm_4 =		__C(CHIP,_mem_write_raw_multi_4);
287	t->abs_wrm_8 =		__C(CHIP,_mem_write_raw_multi_8);
288
289	ex = extent_create(CHIP_EXTENT_NAME(v), 0x0UL,
290	    0xffffffffffffffffUL, M_DEVBUF,
291	    (caddr_t)CHIP_EXTENT_STORAGE(v),
292	    sizeof(CHIP_EXTENT_STORAGE(v)), EX_NOWAIT|EX_NOCOALESCE);
293
294        CHIP_MEM_EXTENT(v) = ex;
295}
296
297int
298__C(CHIP,_mem_map)(v, memaddr, memsize, flags, memhp)
299	void *v;
300	bus_addr_t memaddr;
301	bus_size_t memsize;
302	int flags;
303	bus_space_handle_t *memhp;
304{
305	int error;
306
307#ifdef EXTENT_DEBUG
308	printf("mem: allocating 0x%lx to 0x%lx\n", memaddr,
309	    memaddr + memsize - 1);
310#endif
311	error = extent_alloc_region(CHIP_MEM_EXTENT(v), memaddr, memsize,
312	    EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0));
313	if (error) {
314#ifdef EXTENT_DEBUG
315		printf("mem: allocation failed (%d)\n", error);
316		extent_print(CHIP_MEM_EXTENT(v));
317#endif
318		return (error);
319	}
320
321	*memhp = ALPHA_PHYS_TO_K0SEG(CHIP_MEM_SYS_START(v)) + memaddr;
322
323	return (0);
324}
325
326void
327__C(CHIP,_mem_unmap)(v, memh, memsize)
328	void *v;
329	bus_space_handle_t memh;
330	bus_size_t memsize;
331{
332	bus_addr_t memaddr;
333	int error;
334
335#ifdef EXTENT_DEBUG
336	printf("mem: freeing handle 0x%lx for 0x%lx\n", memh, memsize);
337#endif
338	memaddr = memh - ALPHA_PHYS_TO_K0SEG(CHIP_MEM_SYS_START(v));
339
340#ifdef EXTENT_DEBUG
341	printf("mem: freeing 0x%lx to 0x%lx\n", memaddr, memaddr + memsize - 1);
342#endif
343	error = extent_free(CHIP_MEM_EXTENT(v), memaddr, memsize,
344	    EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0));
345	if (error) {
346		printf("%s: WARNING: could not unmap 0x%lx-0x%lx (error %d)\n",
347		    __S(__C(CHIP,_mem_unmap)), memaddr, memaddr + memsize - 1,
348		    error);
349#ifdef EXTENT_DEBUG
350	extent_print(CHIP_MEM_EXTENT(v));
351#endif
352	}
353}
354
355int
356__C(CHIP,_mem_subregion)(v, memh, offset, size, nmemh)
357	void *v;
358	bus_space_handle_t memh, *nmemh;
359	bus_size_t offset, size;
360{
361
362	*nmemh = memh + offset;
363	return (0);
364}
365
366int
367__C(CHIP,_mem_alloc)(v, rstart, rend, size, align, boundary, flags,
368    addrp, bshp)
369	void *v;
370	bus_addr_t rstart, rend, *addrp;
371	bus_size_t size, align, boundary;
372	int flags;
373	bus_space_handle_t *bshp;
374{
375	bus_addr_t memaddr;
376	int error;
377
378	/*
379	 * Do the requested allocation.
380	 */
381#ifdef EXTENT_DEBUG
382	printf("mem: allocating from 0x%lx to 0x%lx\n", rstart, rend);
383#endif
384	error = extent_alloc_subregion(CHIP_MEM_EXTENT(v), rstart, rend,
385	    size, align, 0, boundary,
386	    EX_FAST | EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0),
387	    &memaddr);
388	if (error) {
389#ifdef EXTENT_DEBUG
390		printf("mem: allocation failed (%d)\n", error);
391		extent_print(CHIP_MEM_EXTENT(v));
392#endif
393	}
394
395#ifdef EXTENT_DEBUG
396	printf("mem: allocated 0x%lx to 0x%lx\n", memaddr, memaddr + size - 1);
397#endif
398
399	*addrp = memaddr;
400	*bshp = ALPHA_PHYS_TO_K0SEG(CHIP_MEM_SYS_START(v)) + memaddr;
401
402	return (0);
403}
404
405void
406__C(CHIP,_mem_free)(v, bsh, size)
407	void *v;
408	bus_space_handle_t bsh;
409	bus_size_t size;
410{
411
412	/* Unmap does all we need to do. */
413	__C(CHIP,_mem_unmap)(v, bsh, size);
414}
415
416void *
417__C(CHIP,_mem_vaddr)(v, bsh)
418	void *v;
419	bus_space_handle_t bsh;
420{
421
422	return ((void *)bsh);
423}
424
425inline void
426__C(CHIP,_mem_barrier)(v, h, o, l, f)
427	void *v;
428	bus_space_handle_t h;
429	bus_size_t o, l;
430	int f;
431{
432
433	if ((f & BUS_SPACE_BARRIER_READ) != 0)
434		alpha_mb();
435	else if ((f & BUS_SPACE_BARRIER_WRITE) != 0)
436		alpha_wmb();
437}
438
439inline u_int8_t
440__C(CHIP,_mem_read_1)(v, memh, off)
441	void *v;
442	bus_space_handle_t memh;
443	bus_size_t off;
444{
445	bus_addr_t addr;
446
447	addr = memh + off;
448	alpha_mb();
449	return (alpha_ldbu((u_int8_t *)addr));
450}
451
452inline u_int16_t
453__C(CHIP,_mem_read_2)(v, memh, off)
454	void *v;
455	bus_space_handle_t memh;
456	bus_size_t off;
457{
458	bus_addr_t addr;
459
460	addr = memh + off;
461#ifdef DIAGNOSTIC
462	if (addr & 1)
463		panic(__S(__C(CHIP,_mem_read_2)) ": addr 0x%lx not aligned",
464		    addr);
465#endif
466	alpha_mb();
467	return (alpha_ldwu((u_int16_t *)addr));
468}
469
470inline u_int32_t
471__C(CHIP,_mem_read_4)(v, memh, off)
472	void *v;
473	bus_space_handle_t memh;
474	bus_size_t off;
475{
476	bus_addr_t addr;
477
478	addr = memh + off;
479#ifdef DIAGNOSTIC
480	if (addr & 3)
481		panic(__S(__C(CHIP,_mem_read_4)) ": addr 0x%lx not aligned",
482		    addr);
483#endif
484	alpha_mb();
485	return (*(u_int32_t *)addr);
486}
487
488inline u_int64_t
489__C(CHIP,_mem_read_8)(v, memh, off)
490	void *v;
491	bus_space_handle_t memh;
492	bus_size_t off;
493{
494
495	alpha_mb();
496
497	/* XXX XXX XXX */
498	panic("%s not implemented", __S(__C(CHIP,_mem_read_8)));
499}
500
501#define CHIP_mem_read_multi_N(BYTES,TYPE)				\
502void									\
503__C(__C(CHIP,_mem_read_multi_),BYTES)(v, h, o, a, c)			\
504	void *v;							\
505	bus_space_handle_t h;						\
506	bus_size_t o, c;						\
507	TYPE *a;							\
508{									\
509									\
510	while (c-- > 0) {						\
511		__C(CHIP,_mem_barrier)(v, h, o, sizeof *a,		\
512		    BUS_SPACE_BARRIER_READ);				\
513		*a++ = __C(__C(CHIP,_mem_read_),BYTES)(v, h, o);	\
514	}								\
515}
516CHIP_mem_read_multi_N(1,u_int8_t)
517CHIP_mem_read_multi_N(2,u_int16_t)
518CHIP_mem_read_multi_N(4,u_int32_t)
519CHIP_mem_read_multi_N(8,u_int64_t)
520
521#define CHIP_mem_read_region_N(BYTES,TYPE)				\
522void									\
523__C(__C(CHIP,_mem_read_region_),BYTES)(v, h, o, a, c)			\
524	void *v;							\
525	bus_space_handle_t h;						\
526	bus_size_t o, c;						\
527	TYPE *a;							\
528{									\
529									\
530	while (c-- > 0) {						\
531		*a++ = __C(__C(CHIP,_mem_read_),BYTES)(v, h, o);	\
532		o += sizeof *a;						\
533	}								\
534}
535CHIP_mem_read_region_N(1,u_int8_t)
536CHIP_mem_read_region_N(2,u_int16_t)
537CHIP_mem_read_region_N(4,u_int32_t)
538CHIP_mem_read_region_N(8,u_int64_t)
539
540inline void
541__C(CHIP,_mem_write_1)(v, memh, off, val)
542	void *v;
543	bus_space_handle_t memh;
544	bus_size_t off;
545	u_int8_t val;
546{
547	bus_addr_t addr;
548
549	addr = memh + off;
550	alpha_stb((u_int8_t *)addr, val);
551	alpha_mb();
552}
553
554inline void
555__C(CHIP,_mem_write_2)(v, memh, off, val)
556	void *v;
557	bus_space_handle_t memh;
558	bus_size_t off;
559	u_int16_t val;
560{
561	bus_addr_t addr;
562
563	addr = memh + off;
564#ifdef DIAGNOSTIC
565	if (addr & 1)
566		panic(__S(__C(CHIP,_mem_write_2)) ": addr 0x%lx not aligned",
567		   addr);
568#endif
569	alpha_stw((u_int16_t *)addr, val);
570	alpha_mb();
571}
572
573inline void
574__C(CHIP,_mem_write_4)(v, memh, off, val)
575	void *v;
576	bus_space_handle_t memh;
577	bus_size_t off;
578	u_int32_t val;
579{
580	bus_addr_t addr;
581
582	addr = memh + off;
583#ifdef DIAGNOSTIC
584	if (addr & 3)
585		panic(__S(__C(CHIP,_mem_write_4)) ": addr 0x%lx not aligned",
586		    addr);
587#endif
588	*(u_int32_t *)addr = val;
589	alpha_mb();
590}
591
592inline void
593__C(CHIP,_mem_write_8)(v, memh, off, val)
594	void *v;
595	bus_space_handle_t memh;
596	bus_size_t off;
597	u_int64_t val;
598{
599
600	/* XXX XXX XXX */
601	panic("%s not implemented", __S(__C(CHIP,_mem_write_8)));
602	alpha_mb();
603}
604
605#define CHIP_mem_write_multi_N(BYTES,TYPE)				\
606void									\
607__C(__C(CHIP,_mem_write_multi_),BYTES)(v, h, o, a, c)			\
608	void *v;							\
609	bus_space_handle_t h;						\
610	bus_size_t o, c;						\
611	const TYPE *a;							\
612{									\
613									\
614	while (c-- > 0) {						\
615		__C(__C(CHIP,_mem_write_),BYTES)(v, h, o, *a++);	\
616		__C(CHIP,_mem_barrier)(v, h, o, sizeof *a,		\
617		    BUS_SPACE_BARRIER_WRITE);				\
618	}								\
619}
620CHIP_mem_write_multi_N(1,u_int8_t)
621CHIP_mem_write_multi_N(2,u_int16_t)
622CHIP_mem_write_multi_N(4,u_int32_t)
623CHIP_mem_write_multi_N(8,u_int64_t)
624
625#define CHIP_mem_write_region_N(BYTES,TYPE)				\
626void									\
627__C(__C(CHIP,_mem_write_region_),BYTES)(v, h, o, a, c)			\
628	void *v;							\
629	bus_space_handle_t h;						\
630	bus_size_t o, c;						\
631	const TYPE *a;							\
632{									\
633									\
634	while (c-- > 0) {						\
635		__C(__C(CHIP,_mem_write_),BYTES)(v, h, o, *a++);	\
636		o += sizeof *a;						\
637	}								\
638}
639CHIP_mem_write_region_N(1,u_int8_t)
640CHIP_mem_write_region_N(2,u_int16_t)
641CHIP_mem_write_region_N(4,u_int32_t)
642CHIP_mem_write_region_N(8,u_int64_t)
643
644#define CHIP_mem_set_multi_N(BYTES,TYPE)				\
645void									\
646__C(__C(CHIP,_mem_set_multi_),BYTES)(v, h, o, val, c)			\
647	void *v;							\
648	bus_space_handle_t h;						\
649	bus_size_t o, c;						\
650	TYPE val;							\
651{									\
652									\
653	while (c-- > 0) {						\
654		__C(__C(CHIP,_mem_write_),BYTES)(v, h, o, val);		\
655		__C(CHIP,_mem_barrier)(v, h, o, sizeof val,		\
656		    BUS_SPACE_BARRIER_WRITE);				\
657	}								\
658}
659CHIP_mem_set_multi_N(1,u_int8_t)
660CHIP_mem_set_multi_N(2,u_int16_t)
661CHIP_mem_set_multi_N(4,u_int32_t)
662CHIP_mem_set_multi_N(8,u_int64_t)
663
664#define CHIP_mem_set_region_N(BYTES,TYPE)				\
665void									\
666__C(__C(CHIP,_mem_set_region_),BYTES)(v, h, o, val, c)			\
667	void *v;							\
668	bus_space_handle_t h;						\
669	bus_size_t o, c;						\
670	TYPE val;							\
671{									\
672									\
673	while (c-- > 0) {						\
674		__C(__C(CHIP,_mem_write_),BYTES)(v, h, o, val);		\
675		o += sizeof val;					\
676	}								\
677}
678CHIP_mem_set_region_N(1,u_int8_t)
679CHIP_mem_set_region_N(2,u_int16_t)
680CHIP_mem_set_region_N(4,u_int32_t)
681CHIP_mem_set_region_N(8,u_int64_t)
682
683#define	CHIP_mem_copy_N(BYTES)						\
684void									\
685__C(__C(CHIP,_mem_copy_),BYTES)(v, h1, o1, h2, o2, c)			\
686	void *v;							\
687	bus_space_handle_t h1, h2;					\
688	bus_size_t o1, o2, c;						\
689{									\
690	bus_size_t i, o;						\
691									\
692	if ((h1 >> 63) != 0 && (h2 >> 63) != 0) {			\
693		bcopy((void *)(h1 + o1), (void *)(h2 + o2), c * BYTES);	\
694		return;							\
695	}								\
696									\
697	/* Circumvent a common case of overlapping problems */		\
698	if (h1 == h2 && o2 > o1)					\
699		for (i = 0, o = (c - 1) * BYTES; i < c; i++, o -= BYTES)\
700			__C(__C(CHIP,_mem_write_),BYTES)(v, h2, o2 + o,	\
701			    __C(__C(CHIP,_mem_read_),BYTES)(v, h1, o1 + o));\
702	else								\
703		for (i = 0, o = 0; i < c; i++, o += BYTES)		\
704			__C(__C(CHIP,_mem_write_),BYTES)(v, h2, o2 + o,	\
705			    __C(__C(CHIP,_mem_read_),BYTES)(v, h1, o1 + o));\
706}
707CHIP_mem_copy_N(1)
708CHIP_mem_copy_N(2)
709CHIP_mem_copy_N(4)
710CHIP_mem_copy_N(8)
711
712#define CHIP_mem_read_raw_multi_N(BYTES,TYPE)				\
713void									\
714__C(__C(CHIP,_mem_read_raw_multi_),BYTES)(v, h, o, a, c)			\
715	void *v;							\
716	bus_space_handle_t h;						\
717	bus_size_t o, c;						\
718	u_int8_t *a;							\
719{									\
720	TYPE temp;							\
721	int i;								\
722									\
723	while (c > 0) {							\
724		__C(CHIP,_mem_barrier)(v, h, o, BYTES,			\
725		    BUS_SPACE_BARRIER_READ);				\
726		temp = __C(__C(CHIP,_mem_read_),BYTES)(v, h, o);	\
727		i = MIN(c, BYTES);					\
728		c -= i;							\
729		while (i--) {						\
730			*a++ = temp & 0xff;				\
731			temp >>= 8;					\
732		}							\
733	}								\
734}
735CHIP_mem_read_raw_multi_N(2,u_int16_t)
736CHIP_mem_read_raw_multi_N(4,u_int32_t)
737CHIP_mem_read_raw_multi_N(8,u_int64_t)
738
739#define CHIP_mem_write_raw_multi_N(BYTES,TYPE)				\
740void									\
741__C(__C(CHIP,_mem_write_raw_multi_),BYTES)(v, h, o, a, c)		\
742	void *v;							\
743	bus_space_handle_t h;						\
744	bus_size_t o, c;						\
745	const u_int8_t *a;						\
746{									\
747	TYPE temp;							\
748	int i;								\
749									\
750	while (c > 0) {							\
751		temp = 0;						\
752		for (i = BYTES - 1; i >= 0; i--) {			\
753			temp <<= 8;					\
754			if (i < c)					\
755				temp |= *(a + i);			\
756		}							\
757		__C(__C(CHIP,_mem_write_),BYTES)(v, h, o, temp);	\
758		__C(CHIP,_mem_barrier)(v, h, o, BYTES,			\
759		    BUS_SPACE_BARRIER_WRITE);				\
760		i = MIN(c, BYTES);					\
761		c -= i;							\
762		a += i;							\
763	}								\
764}
765CHIP_mem_write_raw_multi_N(2,u_int16_t)
766CHIP_mem_write_raw_multi_N(4,u_int32_t)
767CHIP_mem_write_raw_multi_N(8,u_int64_t)
768