1/* $NetBSD: bus_defs.h,v 1.6 2021/07/18 05:12:27 thorpej Exp $ */
2
3/*-
4 * Copyright (c) 1997, 1998, 2000, 2001 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) 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#ifndef _ALPHA_BUS_DEFS_H_
61#define	_ALPHA_BUS_DEFS_H_
62
63#include <sys/types.h>
64#include <machine/bus_user.h>
65
66#if !defined(_KERNEL) && !defined(_STANDALONE)
67#include <stdbool.h>
68#endif
69#include <sys/stdint.h>
70
71#ifdef _KERNEL
72
73/*
74 * Turn on BUS_SPACE_DEBUG if the global DEBUG option is enabled.
75 */
76#if defined(DEBUG) && !defined(BUS_SPACE_DEBUG)
77#define	BUS_SPACE_DEBUG
78#endif
79
80#ifdef BUS_SPACE_DEBUG
81#include <sys/systm.h> /* for printf() prototype */
82/*
83 * Macros for checking the aligned-ness of pointers passed to bus
84 * space ops.  Strict alignment is required by the Alpha architecture,
85 * and a trap will occur if unaligned access is performed.  These
86 * may aid in the debugging of a broken device driver by displaying
87 * useful information about the problem.
88 */
89#define	__BUS_SPACE_ALIGNED_ADDRESS(p, t)				\
90	((((u_long)(p)) & (sizeof(t)-1)) == 0)
91
92#define	__BUS_SPACE_ADDRESS_SANITY(p, t, d)				\
93({									\
94	if (__BUS_SPACE_ALIGNED_ADDRESS((p), t) == 0) {			\
95		printf("%s 0x%lx not aligned to %lu bytes %s:%d\n",	\
96		    d, (u_long)(p), sizeof(t), __FILE__, __LINE__);	\
97	}								\
98	(void) 0;							\
99})
100
101#define BUS_SPACE_ALIGNED_POINTER(p, t) __BUS_SPACE_ALIGNED_ADDRESS(p, t)
102#else
103#define	__BUS_SPACE_ADDRESS_SANITY(p, t, d)	(void) 0
104#define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
105#endif /* BUS_SPACE_DEBUG */
106#endif /* _KERNEL */
107
108struct alpha_bus_space_translation;
109
110/*
111 * Access methods for bus space.
112 */
113typedef struct alpha_bus_space *bus_space_tag_t;
114typedef u_long bus_space_handle_t;
115
116#define PRIxBSH		"lx"
117
118struct alpha_bus_space {
119	/* cookie */
120	void		*abs_cookie;
121
122	/* mapping/unmapping */
123	int		(*abs_map)(void *, bus_addr_t, bus_size_t,
124			    int, bus_space_handle_t *, int);
125	void		(*abs_unmap)(void *, bus_space_handle_t,
126			    bus_size_t, int);
127	int		(*abs_subregion)(void *, bus_space_handle_t,
128			    bus_size_t, bus_size_t, bus_space_handle_t *);
129
130	/* ALPHA SPECIFIC MAPPING METHOD */
131	int		(*abs_translate)(void *, bus_addr_t, bus_size_t,
132			    int, struct alpha_bus_space_translation *);
133	int		(*abs_get_window)(void *, int,
134			    struct alpha_bus_space_translation *);
135
136	/* allocation/deallocation */
137	int		(*abs_alloc)(void *, bus_addr_t, bus_addr_t,
138			    bus_size_t, bus_size_t, bus_size_t, int,
139			    bus_addr_t *, bus_space_handle_t *);
140	void		(*abs_free)(void *, bus_space_handle_t,
141			    bus_size_t);
142
143	/* get kernel virtual address */
144	void *		(*abs_vaddr)(void *, bus_space_handle_t);
145
146	/* mmap bus space for user */
147	paddr_t		(*abs_mmap)(void *, bus_addr_t, off_t, int, int);
148
149	/* barrier */
150	void		(*abs_barrier)(void *, bus_space_handle_t,
151			    bus_size_t, bus_size_t, int);
152
153	/* read (single) */
154	uint8_t	(*abs_r_1)(void *, bus_space_handle_t,
155			    bus_size_t);
156	uint16_t	(*abs_r_2)(void *, bus_space_handle_t,
157			    bus_size_t);
158	uint32_t	(*abs_r_4)(void *, bus_space_handle_t,
159			    bus_size_t);
160	uint64_t	(*abs_r_8)(void *, bus_space_handle_t,
161			    bus_size_t);
162
163	/* read multiple */
164	void		(*abs_rm_1)(void *, bus_space_handle_t,
165			    bus_size_t, uint8_t *, bus_size_t);
166	void		(*abs_rm_2)(void *, bus_space_handle_t,
167			    bus_size_t, uint16_t *, bus_size_t);
168	void		(*abs_rm_4)(void *, bus_space_handle_t,
169			    bus_size_t, uint32_t *, bus_size_t);
170	void		(*abs_rm_8)(void *, bus_space_handle_t,
171			    bus_size_t, uint64_t *, bus_size_t);
172
173	/* read region */
174	void		(*abs_rr_1)(void *, bus_space_handle_t,
175			    bus_size_t, uint8_t *, bus_size_t);
176	void		(*abs_rr_2)(void *, bus_space_handle_t,
177			    bus_size_t, uint16_t *, bus_size_t);
178	void		(*abs_rr_4)(void *, bus_space_handle_t,
179			    bus_size_t, uint32_t *, bus_size_t);
180	void		(*abs_rr_8)(void *, bus_space_handle_t,
181			    bus_size_t, uint64_t *, bus_size_t);
182
183	/* write (single) */
184	void		(*abs_w_1)(void *, bus_space_handle_t,
185			    bus_size_t, uint8_t);
186	void		(*abs_w_2)(void *, bus_space_handle_t,
187			    bus_size_t, uint16_t);
188	void		(*abs_w_4)(void *, bus_space_handle_t,
189			    bus_size_t, uint32_t);
190	void		(*abs_w_8)(void *, bus_space_handle_t,
191			    bus_size_t, uint64_t);
192
193	/* write multiple */
194	void		(*abs_wm_1)(void *, bus_space_handle_t,
195			    bus_size_t, const uint8_t *, bus_size_t);
196	void		(*abs_wm_2)(void *, bus_space_handle_t,
197			    bus_size_t, const uint16_t *, bus_size_t);
198	void		(*abs_wm_4)(void *, bus_space_handle_t,
199			    bus_size_t, const uint32_t *, bus_size_t);
200	void		(*abs_wm_8)(void *, bus_space_handle_t,
201			    bus_size_t, const uint64_t *, bus_size_t);
202
203	/* write region */
204	void		(*abs_wr_1)(void *, bus_space_handle_t,
205			    bus_size_t, const uint8_t *, bus_size_t);
206	void		(*abs_wr_2)(void *, bus_space_handle_t,
207			    bus_size_t, const uint16_t *, bus_size_t);
208	void		(*abs_wr_4)(void *, bus_space_handle_t,
209			    bus_size_t, const uint32_t *, bus_size_t);
210	void		(*abs_wr_8)(void *, bus_space_handle_t,
211			    bus_size_t, const uint64_t *, bus_size_t);
212
213	/* set multiple */
214	void		(*abs_sm_1)(void *, bus_space_handle_t,
215			    bus_size_t, uint8_t, bus_size_t);
216	void		(*abs_sm_2)(void *, bus_space_handle_t,
217			    bus_size_t, uint16_t, bus_size_t);
218	void		(*abs_sm_4)(void *, bus_space_handle_t,
219			    bus_size_t, uint32_t, bus_size_t);
220	void		(*abs_sm_8)(void *, bus_space_handle_t,
221			    bus_size_t, uint64_t, bus_size_t);
222
223	/* set region */
224	void		(*abs_sr_1)(void *, bus_space_handle_t,
225			    bus_size_t, uint8_t, bus_size_t);
226	void		(*abs_sr_2)(void *, bus_space_handle_t,
227			    bus_size_t, uint16_t, bus_size_t);
228	void		(*abs_sr_4)(void *, bus_space_handle_t,
229			    bus_size_t, uint32_t, bus_size_t);
230	void		(*abs_sr_8)(void *, bus_space_handle_t,
231			    bus_size_t, uint64_t, bus_size_t);
232
233	/* copy */
234	void		(*abs_c_1)(void *, bus_space_handle_t, bus_size_t,
235			    bus_space_handle_t, bus_size_t, bus_size_t);
236	void		(*abs_c_2)(void *, bus_space_handle_t, bus_size_t,
237			    bus_space_handle_t, bus_size_t, bus_size_t);
238	void		(*abs_c_4)(void *, bus_space_handle_t, bus_size_t,
239			    bus_space_handle_t, bus_size_t, bus_size_t);
240	void		(*abs_c_8)(void *, bus_space_handle_t, bus_size_t,
241			    bus_space_handle_t, bus_size_t, bus_size_t);
242};
243
244#define	BUS_SPACE_MAP_CACHEABLE		0x01
245
246#ifdef _KERNEL
247
248#define	BUS_SPACE_BARRIER_READ	0x01
249#define	BUS_SPACE_BARRIER_WRITE	0x02
250/*
251 * Bus stream operations--defined in terms of non-stream counterparts
252 */
253#define __BUS_SPACE_HAS_STREAM_METHODS 1
254
255/*
256 * Flags used in various bus DMA methods.
257 */
258#define	BUS_DMA_WAITOK		0x000	/* safe to sleep (pseudo-flag) */
259#define	BUS_DMA_NOWAIT		0x001	/* not safe to sleep */
260#define	BUS_DMA_ALLOCNOW	0x002	/* perform resource allocation now */
261#define	BUS_DMA_COHERENT	0x004	/* hint: map memory DMA coherent */
262#define	BUS_DMA_STREAMING	0x008	/* hint: sequential, unidirectional */
263#define	BUS_DMA_BUS1		0x010	/* placeholders for bus functions... */
264#define	BUS_DMA_BUS2		0x020
265#define	BUS_DMA_BUS3		0x040
266#define	BUS_DMA_BUS4		0x080
267#define	BUS_DMA_READ		0x100	/* mapping is device -> memory only */
268#define	BUS_DMA_WRITE		0x200	/* mapping is memory -> device only */
269#define	BUS_DMA_NOCACHE		0x400	/* hint: map non-cached memory */
270
271/*
272 * Private flags stored in the DMA map.
273 */
274#define	DMAMAP_NO_COALESCE	0x40000000	/* don't coalesce adjacent
275						   segments */
276
277/* Forwards needed by prototypes below. */
278struct mbuf;
279struct uio;
280struct alpha_sgmap;
281
282/*
283 * Operations performed by bus_dmamap_sync().
284 */
285#define	BUS_DMASYNC_PREREAD	0x01	/* pre-read synchronization */
286#define	BUS_DMASYNC_POSTREAD	0x02	/* post-read synchronization */
287#define	BUS_DMASYNC_PREWRITE	0x04	/* pre-write synchronization */
288#define	BUS_DMASYNC_POSTWRITE	0x08	/* post-write synchronization */
289
290/*
291 *	alpha_bus_t
292 *
293 *	Busses supported by NetBSD/alpha, used by internal
294 *	utility functions.  NOT TO BE USED BY MACHINE-INDEPENDENT
295 *	CODE!
296 */
297typedef enum {
298	ALPHA_BUS_TURBOCHANNEL,
299	ALPHA_BUS_PCI,
300	ALPHA_BUS_EISA,
301	ALPHA_BUS_ISA,
302	ALPHA_BUS_TLSB,
303} alpha_bus_t;
304
305typedef struct alpha_bus_dma_tag	*bus_dma_tag_t;
306typedef struct alpha_bus_dmamap		*bus_dmamap_t;
307
308#define BUS_DMA_TAG_VALID(t)    ((t) != (bus_dma_tag_t)0)
309
310/*
311 *	bus_dma_segment_t
312 *
313 *	Describes a single contiguous DMA transaction.  Values
314 *	are suitable for programming into DMA registers.
315 */
316struct alpha_bus_dma_segment {
317	bus_addr_t	ds_addr;	/* DMA address */
318	bus_size_t	ds_len;		/* length of transfer */
319};
320typedef struct alpha_bus_dma_segment	bus_dma_segment_t;
321
322/*
323 *	bus_dma_tag_t
324 *
325 *	A machine-dependent opaque type describing the implementation of
326 *	DMA for a given bus.
327 */
328struct alpha_bus_dma_tag {
329	void	*_cookie;		/* cookie used in the guts */
330	bus_addr_t _wbase;		/* DMA window base */
331
332	/*
333	 * The following two members are used to chain DMA windows
334	 * together.  If, during the course of a map load, the
335	 * resulting physical memory address is too large to
336	 * be addressed by the window, the next window will be
337	 * attempted.  These would be chained together like so:
338	 *
339	 *	direct -> sgmap -> NULL
340	 *  or
341	 *	sgmap -> NULL
342	 *  or
343	 *	direct -> NULL
344	 *
345	 * If the window size is 0, it will not be checked (e.g.
346	 * TURBOchannel DMA).
347	 */
348	bus_size_t _wsize;
349	struct alpha_bus_dma_tag *_next_window;
350
351	/*
352	 * Some chipsets have a built-in boundary constraint, independent
353	 * of what the device requests.  This allows that boundary to
354	 * be specified.  If the device has a more restrictive constraint,
355	 * the map will use that, otherwise this boundary will be used.
356	 * This value is ignored if 0.
357	 */
358	bus_size_t _boundary;
359
360	/*
361	 * A chipset may have more than one SGMAP window, so SGMAP
362	 * windows also get a pointer to their SGMAP state.
363	 */
364	struct alpha_sgmap *_sgmap;
365
366	/*
367	 * Some chipsets may want to enforce a minimum alignment
368	 * constraint for SGMAP DMA addresses.
369	 */
370	bus_size_t _sgmap_minalign;
371
372	/*
373	 * The SGMAP MMU implements a prefetch FIFO to keep data
374	 * moving down the pipe, when doing host->bus DMA writes.
375	 * The threshold (distance until the next page) used to
376	 * trigger the prefetch is differnet on different chipsets,
377	 * and we need to know what it is in order to know whether
378	 * or not to allocate a spill page.
379	 */
380	bus_size_t _pfthresh;
381
382	/*
383	 * Internal-use only utility methods.  NOT TO BE USED BY
384	 * MACHINE-INDEPENDENT CODE!
385	 */
386	bus_dma_tag_t (*_get_tag)(bus_dma_tag_t, alpha_bus_t);
387
388	/*
389	 * DMA mapping methods.
390	 */
391	int	(*_dmamap_create)(bus_dma_tag_t, bus_size_t, int,
392		    bus_size_t, bus_size_t, int, bus_dmamap_t *);
393	void	(*_dmamap_destroy)(bus_dma_tag_t, bus_dmamap_t);
394	int	(*_dmamap_load)(bus_dma_tag_t, bus_dmamap_t, void *,
395		    bus_size_t, struct proc *, int);
396	int	(*_dmamap_load_mbuf)(bus_dma_tag_t, bus_dmamap_t,
397		    struct mbuf *, int);
398	int	(*_dmamap_load_uio)(bus_dma_tag_t, bus_dmamap_t,
399		    struct uio *, int);
400	int	(*_dmamap_load_raw)(bus_dma_tag_t, bus_dmamap_t,
401		    bus_dma_segment_t *, int, bus_size_t, int);
402	void	(*_dmamap_unload)(bus_dma_tag_t, bus_dmamap_t);
403	void	(*_dmamap_sync)(bus_dma_tag_t, bus_dmamap_t,
404		    bus_addr_t, bus_size_t, int);
405
406	/*
407	 * DMA memory utility functions.
408	 */
409	int	(*_dmamem_alloc)(bus_dma_tag_t, bus_size_t, bus_size_t,
410		    bus_size_t, bus_dma_segment_t *, int, int *, int);
411	void	(*_dmamem_free)(bus_dma_tag_t,
412		    bus_dma_segment_t *, int);
413	int	(*_dmamem_map)(bus_dma_tag_t, bus_dma_segment_t *,
414		    int, size_t, void **, int);
415	void	(*_dmamem_unmap)(bus_dma_tag_t, void *, size_t);
416	paddr_t	(*_dmamem_mmap)(bus_dma_tag_t, bus_dma_segment_t *,
417		    int, off_t, int, int);
418};
419
420#define	alphabus_dma_get_tag(t, b)				\
421	(*(t)->_get_tag)(t, b)
422
423/*
424 *	bus_dmamap_t
425 *
426 *	Describes a DMA mapping.
427 */
428struct alpha_bus_dmamap {
429	/*
430	 * PRIVATE MEMBERS: not for use my machine-independent code.
431	 */
432	bus_size_t	_dm_size;	/* largest DMA transfer mappable */
433	int		_dm_segcnt;	/* number of segs this map can map */
434	bus_size_t	_dm_maxmaxsegsz; /* fixed largest possible segment */
435	bus_size_t	_dm_boundary;	/* don't cross this */
436	int		_dm_flags;	/* misc. flags */
437
438	/*
439	 * Private cookie to be used by the DMA back-end.
440	 */
441	void		*_dm_cookie;
442
443	/*
444	 * The DMA window that we ended up being mapped in.
445	 */
446	bus_dma_tag_t	_dm_window;
447
448	/*
449	 * PUBLIC MEMBERS: these are used by machine-independent code.
450	 */
451	bus_size_t	dm_maxsegsz;	/* largest possible segment */
452	bus_size_t	dm_mapsize;	/* size of the mapping */
453	int		dm_nsegs;	/* # valid segments in mapping */
454	bus_dma_segment_t dm_segs[1];	/* segments; variable length */
455};
456
457#endif /* _KERNEL */
458
459#endif /* _ALPHA_BUS_DEFS_H_ */
460