bhnd.h revision 301408
1/*-
2 * Copyright (c) 2015 Landon Fuller <landon@landonf.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer,
10 *    without modification.
11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12 *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13 *    redistribution must be conditioned upon including a substantially
14 *    similar Disclaimer requirement for further binary redistribution.
15 *
16 * NO WARRANTY
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27 * THE POSSIBILITY OF SUCH DAMAGES.
28 *
29 * $FreeBSD: head/sys/dev/bhnd/bhnd.h 301408 2016-06-04 19:31:06Z landonf $
30 */
31
32#ifndef _BHND_BHND_H_
33#define _BHND_BHND_H_
34
35#include <sys/types.h>
36#include <sys/bus.h>
37
38#include <machine/bus.h>
39
40#include "bhnd_ids.h"
41#include "bhnd_types.h"
42#include "bhnd_debug.h"
43#include "bhnd_bus_if.h"
44#include "bhnd_match.h"
45
46extern devclass_t bhnd_devclass;
47extern devclass_t bhnd_hostb_devclass;
48extern devclass_t bhnd_nvram_devclass;
49
50/**
51 * bhnd child instance variables
52 */
53enum bhnd_device_vars {
54	BHND_IVAR_VENDOR,	/**< Designer's JEP-106 manufacturer ID. */
55	BHND_IVAR_DEVICE,	/**< Part number */
56	BHND_IVAR_HWREV,	/**< Core revision */
57	BHND_IVAR_DEVICE_CLASS,	/**< Core class (@sa bhnd_devclass_t) */
58	BHND_IVAR_VENDOR_NAME,	/**< Core vendor name */
59	BHND_IVAR_DEVICE_NAME,	/**< Core name */
60	BHND_IVAR_CORE_INDEX,	/**< Bus-assigned core number */
61	BHND_IVAR_CORE_UNIT,	/**< Bus-assigned core unit number,
62				     assigned sequentially (starting at 0) for
63				     each vendor/device pair. */
64};
65
66/**
67 * bhnd device probe priority bands.
68 */
69enum {
70	BHND_PROBE_ROOT         = 0,    /**< Nexus or host bridge */
71	BHND_PROBE_BUS		= 1000,	/**< Busses and bridges */
72	BHND_PROBE_CPU		= 2000,	/**< CPU devices */
73	BHND_PROBE_INTERRUPT	= 3000,	/**< Interrupt controllers. */
74	BHND_PROBE_TIMER	= 4000,	/**< Timers and clocks. */
75	BHND_PROBE_RESOURCE	= 5000,	/**< Resource discovery (including NVRAM/SPROM) */
76	BHND_PROBE_DEFAULT	= 6000,	/**< Default device priority */
77};
78
79/**
80 * Constants defining fine grained ordering within a BHND_PROBE_* priority band.
81 *
82 * Example:
83 * @code
84 * BHND_PROBE_BUS + BHND_PROBE_ORDER_FIRST
85 * @endcode
86 */
87enum {
88	BHND_PROBE_ORDER_FIRST		= 0,
89	BHND_PROBE_ORDER_EARLY		= 25,
90	BHND_PROBE_ORDER_MIDDLE		= 50,
91	BHND_PROBE_ORDER_LATE		= 75,
92	BHND_PROBE_ORDER_LAST		= 100
93
94};
95
96/*
97 * Simplified accessors for bhnd device ivars
98 */
99#define	BHND_ACCESSOR(var, ivar, type) \
100	__BUS_ACCESSOR(bhnd, var, BHND, ivar, type)
101
102BHND_ACCESSOR(vendor,		VENDOR,		uint16_t);
103BHND_ACCESSOR(device,		DEVICE,		uint16_t);
104BHND_ACCESSOR(hwrev,		HWREV,		uint8_t);
105BHND_ACCESSOR(class,		DEVICE_CLASS,	bhnd_devclass_t);
106BHND_ACCESSOR(vendor_name,	VENDOR_NAME,	const char *);
107BHND_ACCESSOR(device_name,	DEVICE_NAME,	const char *);
108BHND_ACCESSOR(core_index,	CORE_INDEX,	u_int);
109BHND_ACCESSOR(core_unit,	CORE_UNIT,	int);
110
111#undef	BHND_ACCESSOR
112
113/**
114 * A bhnd(4) board descriptor.
115 */
116struct bhnd_board_info {
117	uint16_t	board_vendor;	/**< PCI-SIG vendor ID (even on non-PCI
118					  *  devices).
119					  *
120					  *  On PCI devices, this will generally
121					  *  be the subsystem vendor ID, but the
122					  *  value may be overridden in device
123					  *  NVRAM.
124					  */
125	uint16_t	board_type;	/**< Board type (See BHND_BOARD_*)
126					  *
127					  *  On PCI devices, this will generally
128					  *  be the subsystem device ID, but the
129					  *  value may be overridden in device
130					  *  NVRAM.
131					  */
132	uint16_t	board_rev;	/**< Board revision. */
133	uint8_t		board_srom_rev;	/**< Board SROM format revision */
134
135	uint32_t	board_flags;	/**< Board flags (see BHND_BFL_*) */
136	uint32_t	board_flags2;	/**< Board flags 2 (see BHND_BFL2_*) */
137	uint32_t	board_flags3;	/**< Board flags 3 (see BHND_BFL3_*) */
138};
139
140
141/**
142 * Chip Identification
143 *
144 * This is read from the ChipCommon ID register; on earlier bhnd(4) devices
145 * where ChipCommon is unavailable, known values must be supplied.
146 */
147struct bhnd_chipid {
148	uint16_t	chip_id;	/**< chip id (BHND_CHIPID_*) */
149	uint8_t		chip_rev;	/**< chip revision */
150	uint8_t		chip_pkg;	/**< chip package (BHND_PKGID_*) */
151	uint8_t		chip_type;	/**< chip type (BHND_CHIPTYPE_*) */
152
153	bhnd_addr_t	enum_addr;	/**< chip_type-specific enumeration
154					  *  address; either the siba(4) base
155					  *  core register block, or the bcma(4)
156					  *  EROM core address. */
157
158	uint8_t		ncores;		/**< number of cores, if known. 0 if
159					  *  not available. */
160};
161
162/**
163 * A bhnd(4) core descriptor.
164 */
165struct bhnd_core_info {
166	uint16_t	vendor;		/**< JEP-106 vendor (BHND_MFGID_*) */
167	uint16_t	device;		/**< device */
168	uint16_t	hwrev;		/**< hardware revision */
169	u_int		core_idx;	/**< bus-assigned core index */
170	int		unit;		/**< bus-assigned core unit */
171};
172
173/**
174* A bhnd(4) bus resource.
175*
176* This provides an abstract interface to per-core resources that may require
177* bus-level remapping of address windows prior to access.
178*/
179struct bhnd_resource {
180	struct resource	*res;		/**< the system resource. */
181	bool		 direct;	/**< false if the resource requires
182					 *   bus window remapping before it
183					 *   is MMIO accessible. */
184};
185
186/**
187 * Device quirk table descriptor.
188 */
189struct bhnd_device_quirk {
190	struct bhnd_device_match desc;		/**< device match descriptor */
191	uint32_t		 quirks;	/**< quirk flags */
192};
193
194#define	BHND_CORE_QUIRK(_rev, _flags)		\
195	{{ BHND_MATCH_CORE_REV(_rev) }, (_flags) }
196
197#define	BHND_CHIP_QUIRK(_chip, _rev, _flags)	\
198	{{ BHND_CHIP_IR(BCM ## _chip, _rev) }, (_flags) }
199
200#define	BHND_PKG_QUIRK(_chip, _pkg, _flags)	\
201	{{ BHND_CHIP_IP(BCM ## _chip, BCM ## _chip ## _pkg) }, (_flags) }
202
203#define	BHND_BOARD_QUIRK(_board, _flags)	\
204	{{ BHND_MATCH_BOARD_TYPE(_board) },	\
205	    (_flags) }
206
207#define	BHND_DEVICE_QUIRK_END		{ { BHND_MATCH_ANY }, 0 }
208#define	BHND_DEVICE_QUIRK_IS_END(_q)	\
209	(((_q)->desc.m.match_flags == 0) && (_q)->quirks == 0)
210
211enum {
212	BHND_DF_ANY	= 0,
213	BHND_DF_HOSTB	= (1<<0),	/**< core is serving as the bus' host
214					  *  bridge. implies BHND_DF_ADAPTER */
215	BHND_DF_SOC	= (1<<1),	/**< core is attached to a native
216					     bus (BHND_ATTACH_NATIVE) */
217	BHND_DF_ADAPTER	= (1<<2),	/**< core is attached to a bridged
218					  *  adapter (BHND_ATTACH_ADAPTER) */
219};
220
221/** Device probe table descriptor */
222struct bhnd_device {
223	const struct bhnd_device_match	 core;		/**< core match descriptor */
224	const char			*desc;		/**< device description, or NULL. */
225	const struct bhnd_device_quirk	*quirks_table;	/**< quirks table for this device, or NULL */
226	uint32_t			 device_flags;	/**< required BHND_DF_* flags */
227};
228
229#define	_BHND_DEVICE(_vendor, _device, _desc, _quirks,		\
230     _flags, ...)						\
231	{ { BHND_MATCH_CORE(BHND_MFGID_ ## _vendor,		\
232	    BHND_COREID_ ## _device) }, _desc, _quirks,		\
233	    _flags }
234
235#define	BHND_MIPS_DEVICE(_device, _desc, _quirks, ...)	\
236	_BHND_DEVICE(MIPS, _device, _desc, _quirks,	\
237	    ## __VA_ARGS__, 0)
238
239#define	BHND_ARM_DEVICE(_device, _desc, _quirks, ...)	\
240	_BHND_DEVICE(ARM, _device, _desc, _quirks,	\
241	    ## __VA_ARGS__, 0)
242
243#define	BHND_DEVICE(_device, _desc, _quirks, ...)		\
244	_BHND_DEVICE(BCM, _device, _desc, _quirks,	\
245	    ## __VA_ARGS__, 0)
246
247#define	BHND_DEVICE_END		{ { BHND_MATCH_ANY }, NULL, NULL, 0 }
248#define	BHND_DEVICE_IS_END(_d)	\
249	(BHND_MATCH_IS_ANY(&(_d)->core) && (_d)->desc == NULL)
250
251const char			*bhnd_vendor_name(uint16_t vendor);
252const char			*bhnd_port_type_name(bhnd_port_type port_type);
253
254const char 			*bhnd_find_core_name(uint16_t vendor,
255				     uint16_t device);
256bhnd_devclass_t			 bhnd_find_core_class(uint16_t vendor,
257				     uint16_t device);
258
259const char			*bhnd_core_name(const struct bhnd_core_info *ci);
260bhnd_devclass_t			 bhnd_core_class(const struct bhnd_core_info *ci);
261
262
263device_t			 bhnd_match_child(device_t dev,
264				     const struct bhnd_core_match *desc);
265
266device_t			 bhnd_find_child(device_t dev,
267				     bhnd_devclass_t class, int unit);
268
269device_t			 bhnd_find_bridge_root(device_t dev,
270				     devclass_t bus_class);
271
272const struct bhnd_core_info	*bhnd_match_core(
273				     const struct bhnd_core_info *cores,
274				     u_int num_cores,
275				     const struct bhnd_core_match *desc);
276
277const struct bhnd_core_info	*bhnd_find_core(
278				     const struct bhnd_core_info *cores,
279				     u_int num_cores, bhnd_devclass_t class);
280
281bool				 bhnd_core_matches(
282				     const struct bhnd_core_info *core,
283				     const struct bhnd_core_match *desc);
284
285bool				 bhnd_chip_matches(
286				     const struct bhnd_chipid *chipid,
287				     const struct bhnd_chip_match *desc);
288
289bool				 bhnd_board_matches(
290				     const struct bhnd_board_info *info,
291				     const struct bhnd_board_match *desc);
292
293bool				 bhnd_hwrev_matches(uint16_t hwrev,
294				     const struct bhnd_hwrev_match *desc);
295
296bool				 bhnd_device_matches(device_t dev,
297				     const struct bhnd_device_match *desc);
298
299const struct bhnd_device	*bhnd_device_lookup(device_t dev,
300				     const struct bhnd_device *table,
301				     size_t entry_size);
302
303uint32_t			 bhnd_device_quirks(device_t dev,
304				     const struct bhnd_device *table,
305				     size_t entry_size);
306
307struct bhnd_core_info		 bhnd_get_core_info(device_t dev);
308
309int				 bhnd_alloc_resources(device_t dev,
310				     struct resource_spec *rs,
311				     struct bhnd_resource **res);
312
313void				 bhnd_release_resources(device_t dev,
314				     const struct resource_spec *rs,
315				     struct bhnd_resource **res);
316
317struct bhnd_chipid		 bhnd_parse_chipid(uint32_t idreg,
318				     bhnd_addr_t enum_addr);
319
320int				 bhnd_read_chipid(device_t dev,
321				     struct resource_spec *rs,
322				     bus_size_t chipc_offset,
323				     struct bhnd_chipid *result);
324
325void				 bhnd_set_custom_core_desc(device_t dev,
326				     const char *name);
327void				 bhnd_set_default_core_desc(device_t dev);
328
329
330bool				 bhnd_bus_generic_is_hw_disabled(device_t dev,
331				     device_t child);
332bool				 bhnd_bus_generic_is_region_valid(device_t dev,
333				     device_t child, bhnd_port_type type,
334				     u_int port, u_int region);
335int				 bhnd_bus_generic_read_nvram_var(device_t dev,
336				     device_t child, const char *name,
337				     void *buf, size_t *size);
338const struct bhnd_chipid	*bhnd_bus_generic_get_chipid(device_t dev,
339				     device_t child);
340int				 bhnd_bus_generic_read_board_info(device_t dev,
341				     device_t child,
342				     struct bhnd_board_info *info);
343int				 bhnd_bus_generic_get_nvram_var(device_t dev,
344				    device_t child, const char *name,
345				    void *buf, size_t *size);
346struct bhnd_resource		*bhnd_bus_generic_alloc_resource (device_t dev,
347				     device_t child, int type, int *rid,
348				     rman_res_t start, rman_res_t end,
349				     rman_res_t count, u_int flags);
350int				 bhnd_bus_generic_release_resource (device_t dev,
351				     device_t child, int type, int rid,
352				     struct bhnd_resource *r);
353int				 bhnd_bus_generic_activate_resource (device_t dev,
354				     device_t child, int type, int rid,
355				     struct bhnd_resource *r);
356int				 bhnd_bus_generic_deactivate_resource (device_t dev,
357				     device_t child, int type, int rid,
358				     struct bhnd_resource *r);
359bhnd_attach_type		 bhnd_bus_generic_get_attach_type(device_t dev,
360				     device_t child);
361
362
363
364/**
365 * Return the active host bridge core for the bhnd bus, if any, or NULL if
366 * not found.
367 *
368 * @param dev A bhnd bus device.
369 */
370static inline device_t
371bhnd_find_hostb_device(device_t dev) {
372	return (BHND_BUS_FIND_HOSTB_DEVICE(dev));
373}
374
375/**
376 * Return true if the hardware components required by @p dev are known to be
377 * unpopulated or otherwise unusable.
378 *
379 * In some cases, enumerated devices may have pins that are left floating, or
380 * the hardware may otherwise be non-functional; this method allows a parent
381 * device to explicitly specify if a successfully enumerated @p dev should
382 * be disabled.
383 *
384 * @param dev A bhnd bus child device.
385 */
386static inline bool
387bhnd_is_hw_disabled(device_t dev) {
388	return (BHND_BUS_IS_HW_DISABLED(device_get_parent(dev), dev));
389}
390
391/**
392 * Return the BHND chip identification info for the bhnd bus.
393 *
394 * @param dev A bhnd bus child device.
395 */
396static inline const struct bhnd_chipid *
397bhnd_get_chipid(device_t dev) {
398	return (BHND_BUS_GET_CHIPID(device_get_parent(dev), dev));
399};
400
401/**
402 * Return the BHND attachment type of the parent bhnd bus.
403 *
404 * @param dev A bhnd bus child device.
405 *
406 * @retval BHND_ATTACH_ADAPTER if the bus is resident on a bridged adapter,
407 * such as a WiFi chipset.
408 * @retval BHND_ATTACH_NATIVE if the bus provides hardware services (clock,
409 * CPU, etc) to a directly attached native host.
410 */
411static inline bhnd_attach_type
412bhnd_get_attach_type (device_t dev) {
413	return (BHND_BUS_GET_ATTACH_TYPE(device_get_parent(dev), dev));
414}
415
416/**
417 * Attempt to read the BHND board identification from the bhnd bus.
418 *
419 * This relies on NVRAM access, and will fail if a valid NVRAM device cannot
420 * be found, or is not yet attached.
421 *
422 * @param dev The parent of @p child.
423 * @param child The bhnd device requesting board info.
424 * @param[out] info On success, will be populated with the bhnd(4) device's
425 * board information.
426 *
427 * @retval 0 success
428 * @retval ENODEV	No valid NVRAM source could be found.
429 * @retval non-zero	If reading @p name otherwise fails, a regular unix
430 *			error code will be returned.
431 */
432static inline int
433bhnd_read_board_info(device_t dev, struct bhnd_board_info *info)
434{
435	return (BHND_BUS_READ_BOARD_INFO(device_get_parent(dev), dev, info));
436}
437
438/**
439 * Determine an NVRAM variable's expected size.
440 *
441 * @param 	dev	A bhnd bus child device.
442 * @param	name	The variable name.
443 * @param[out]	len	On success, the variable's size, in bytes.
444 *
445 * @retval 0		success
446 * @retval ENOENT	The requested variable was not found.
447 * @retval ENODEV	No valid NVRAM source could be found.
448 * @retval non-zero	If reading @p name otherwise fails, a regular unix
449 *			error code will be returned.
450 */
451static inline int
452bhnd_nvram_getvarlen(device_t dev, const char *name, size_t *len)
453{
454	return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), dev, name, NULL,
455	    len));
456}
457
458/**
459 * Read an NVRAM variable.
460 *
461 * @param 	dev	A bhnd bus child device.
462 * @param	name	The NVRAM variable name.
463 * @param	buf	A buffer large enough to hold @p len bytes. On success,
464 * 			the requested value will be written to this buffer.
465 * @param	len	The required variable length.
466 *
467 * @retval 0		success
468 * @retval ENOENT	The requested variable was not found.
469 * @retval EINVAL	If @p len does not match the actual variable size.
470 * @retval ENODEV	No valid NVRAM source could be found.
471 * @retval non-zero	If reading @p name otherwise fails, a regular unix
472 *			error code will be returned.
473 */
474static inline int
475bhnd_nvram_getvar(device_t dev, const char *name, void *buf, size_t len)
476{
477	size_t	var_len;
478	int	error;
479
480	if ((error = bhnd_nvram_getvarlen(dev, name, &var_len)))
481		return (error);
482
483	if (len != var_len)
484		return (EINVAL);
485
486	return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), dev, name, buf,
487	    &len));
488}
489
490/**
491 * Allocate a resource from a device's parent bhnd(4) bus.
492 *
493 * @param dev The device requesting resource ownership.
494 * @param type The type of resource to allocate. This may be any type supported
495 * by the standard bus APIs.
496 * @param rid The bus-specific handle identifying the resource being allocated.
497 * @param start The start address of the resource.
498 * @param end The end address of the resource.
499 * @param count The size of the resource.
500 * @param flags The flags for the resource to be allocated. These may be any
501 * values supported by the standard bus APIs.
502 *
503 * To request the resource's default addresses, pass @p start and
504 * @p end values of @c 0 and @c ~0, respectively, and
505 * a @p count of @c 1.
506 *
507 * @retval NULL The resource could not be allocated.
508 * @retval resource The allocated resource.
509 */
510static inline struct bhnd_resource *
511bhnd_alloc_resource(device_t dev, int type, int *rid, rman_res_t start,
512    rman_res_t end, rman_res_t count, u_int flags)
513{
514	return BHND_BUS_ALLOC_RESOURCE(device_get_parent(dev), dev, type, rid,
515	    start, end, count, flags);
516}
517
518
519/**
520 * Allocate a resource from a device's parent bhnd(4) bus, using the
521 * resource's default start, end, and count values.
522 *
523 * @param dev The device requesting resource ownership.
524 * @param type The type of resource to allocate. This may be any type supported
525 * by the standard bus APIs.
526 * @param rid The bus-specific handle identifying the resource being allocated.
527 * @param flags The flags for the resource to be allocated. These may be any
528 * values supported by the standard bus APIs.
529 *
530 * @retval NULL The resource could not be allocated.
531 * @retval resource The allocated resource.
532 */
533static inline struct bhnd_resource *
534bhnd_alloc_resource_any(device_t dev, int type, int *rid, u_int flags)
535{
536	return bhnd_alloc_resource(dev, type, rid, 0, ~0, 1, flags);
537}
538
539/**
540 * Activate a previously allocated bhnd resource.
541 *
542 * @param dev The device holding ownership of the allocated resource.
543 * @param type The type of the resource.
544 * @param rid The bus-specific handle identifying the resource.
545 * @param r A pointer to the resource returned by bhnd_alloc_resource or
546 * BHND_BUS_ALLOC_RESOURCE.
547 *
548 * @retval 0 success
549 * @retval non-zero an error occurred while activating the resource.
550 */
551static inline int
552bhnd_activate_resource(device_t dev, int type, int rid,
553   struct bhnd_resource *r)
554{
555	return BHND_BUS_ACTIVATE_RESOURCE(device_get_parent(dev), dev, type,
556	    rid, r);
557}
558
559/**
560 * Deactivate a previously activated bhnd resource.
561 *
562 * @param dev The device holding ownership of the activated resource.
563 * @param type The type of the resource.
564 * @param rid The bus-specific handle identifying the resource.
565 * @param r A pointer to the resource returned by bhnd_alloc_resource or
566 * BHND_BUS_ALLOC_RESOURCE.
567 *
568 * @retval 0 success
569 * @retval non-zero an error occurred while activating the resource.
570 */
571static inline int
572bhnd_deactivate_resource(device_t dev, int type, int rid,
573   struct bhnd_resource *r)
574{
575	return BHND_BUS_DEACTIVATE_RESOURCE(device_get_parent(dev), dev, type,
576	    rid, r);
577}
578
579/**
580 * Free a resource allocated by bhnd_alloc_resource().
581 *
582 * @param dev The device holding ownership of the resource.
583 * @param type The type of the resource.
584 * @param rid The bus-specific handle identifying the resource.
585 * @param r A pointer to the resource returned by bhnd_alloc_resource or
586 * BHND_ALLOC_RESOURCE.
587 *
588 * @retval 0 success
589 * @retval non-zero an error occurred while activating the resource.
590 */
591static inline int
592bhnd_release_resource(device_t dev, int type, int rid,
593   struct bhnd_resource *r)
594{
595	return BHND_BUS_RELEASE_RESOURCE(device_get_parent(dev), dev, type,
596	    rid, r);
597}
598
599/**
600 * Return true if @p region_num is a valid region on @p port_num of
601 * @p type attached to @p dev.
602 *
603 * @param dev A bhnd bus child device.
604 * @param type The port type being queried.
605 * @param port_num The port number being queried.
606 * @param region_num The region number being queried.
607 */
608static inline bool
609bhnd_is_region_valid(device_t dev, bhnd_port_type type, u_int port_num,
610    u_int region_num)
611{
612	return (BHND_BUS_IS_REGION_VALID(device_get_parent(dev), dev, type,
613	    port_num, region_num));
614}
615
616/**
617 * Return the number of ports of type @p type attached to @p def.
618 *
619 * @param dev A bhnd bus child device.
620 * @param type The port type being queried.
621 */
622static inline u_int
623bhnd_get_port_count(device_t dev, bhnd_port_type type) {
624	return (BHND_BUS_GET_PORT_COUNT(device_get_parent(dev), dev, type));
625}
626
627/**
628 * Return the number of memory regions mapped to @p child @p port of
629 * type @p type.
630 *
631 * @param dev A bhnd bus child device.
632 * @param port The port number being queried.
633 * @param type The port type being queried.
634 */
635static inline u_int
636bhnd_get_region_count(device_t dev, bhnd_port_type type, u_int port) {
637	return (BHND_BUS_GET_REGION_COUNT(device_get_parent(dev), dev, type,
638	    port));
639}
640
641/**
642 * Return the resource-ID for a memory region on the given device port.
643 *
644 * @param dev A bhnd bus child device.
645 * @param type The port type.
646 * @param port The port identifier.
647 * @param region The identifier of the memory region on @p port.
648 *
649 * @retval int The RID for the given @p port and @p region on @p device.
650 * @retval -1 No such port/region found.
651 */
652static inline int
653bhnd_get_port_rid(device_t dev, bhnd_port_type type, u_int port, u_int region)
654{
655	return BHND_BUS_GET_PORT_RID(device_get_parent(dev), dev, type, port,
656	    region);
657}
658
659/**
660 * Decode a port / region pair on @p dev defined by @p rid.
661 *
662 * @param dev A bhnd bus child device.
663 * @param type The resource type.
664 * @param rid The resource identifier.
665 * @param[out] port_type The decoded port type.
666 * @param[out] port The decoded port identifier.
667 * @param[out] region The decoded region identifier.
668 *
669 * @retval 0 success
670 * @retval non-zero No matching port/region found.
671 */
672static inline int
673bhnd_decode_port_rid(device_t dev, int type, int rid, bhnd_port_type *port_type,
674    u_int *port, u_int *region)
675{
676	return BHND_BUS_DECODE_PORT_RID(device_get_parent(dev), dev, type, rid,
677	    port_type, port, region);
678}
679
680/**
681 * Get the address and size of @p region on @p port.
682 *
683 * @param dev A bhnd bus child device.
684 * @param port_type The port type.
685 * @param port The port identifier.
686 * @param region The identifier of the memory region on @p port.
687 * @param[out] region_addr The region's base address.
688 * @param[out] region_size The region's size.
689 *
690 * @retval 0 success
691 * @retval non-zero No matching port/region found.
692 */
693static inline int
694bhnd_get_region_addr(device_t dev, bhnd_port_type port_type, u_int port,
695    u_int region, bhnd_addr_t *region_addr, bhnd_size_t *region_size)
696{
697	return BHND_BUS_GET_REGION_ADDR(device_get_parent(dev), dev, port_type,
698	    port, region, region_addr, region_size);
699}
700
701/*
702 * bhnd bus-level equivalents of the bus_(read|write|set|barrier|...)
703 * macros (compatible with bhnd_resource).
704 *
705 * Generated with bhnd/tools/bus_macro.sh
706 */
707#define bhnd_bus_barrier(r, o, l, f) \
708    ((r)->direct) ? \
709	bus_barrier((r)->res, (o), (l), (f)) : \
710	BHND_BUS_BARRIER( \
711	    device_get_parent(rman_get_device((r)->res)),	\
712	    rman_get_device((r)->res), (r), (o), (l), (f))
713#define bhnd_bus_read_1(r, o) \
714    ((r)->direct) ? \
715	bus_read_1((r)->res, (o)) : \
716	BHND_BUS_READ_1( \
717	    device_get_parent(rman_get_device((r)->res)),	\
718	    rman_get_device((r)->res), (r), (o))
719#define bhnd_bus_read_multi_1(r, o, d, c) \
720    ((r)->direct) ? \
721	bus_read_multi_1((r)->res, (o), (d), (c)) : \
722	BHND_BUS_READ_MULTI_1( \
723	    device_get_parent(rman_get_device((r)->res)),	\
724	    rman_get_device((r)->res), (r), (o), (d), (c))
725#define bhnd_bus_read_region_1(r, o, d, c) \
726    ((r)->direct) ? \
727	bus_read_region_1((r)->res, (o), (d), (c)) : \
728	BHND_BUS_READ_REGION_1( \
729	    device_get_parent(rman_get_device((r)->res)),	\
730	    rman_get_device((r)->res), (r), (o), (d), (c))
731#define bhnd_bus_write_1(r, o, v) \
732    ((r)->direct) ? \
733	bus_write_1((r)->res, (o), (v)) : \
734	BHND_BUS_WRITE_1( \
735	    device_get_parent(rman_get_device((r)->res)),	\
736	    rman_get_device((r)->res), (r), (o), (v))
737#define bhnd_bus_write_multi_1(r, o, d, c) \
738    ((r)->direct) ? \
739	bus_write_multi_1((r)->res, (o), (d), (c)) : \
740	BHND_BUS_WRITE_MULTI_1( \
741	    device_get_parent(rman_get_device((r)->res)),	\
742	    rman_get_device((r)->res), (r), (o), (d), (c))
743#define bhnd_bus_write_region_1(r, o, d, c) \
744    ((r)->direct) ? \
745	bus_write_region_1((r)->res, (o), (d), (c)) : \
746	BHND_BUS_WRITE_REGION_1( \
747	    device_get_parent(rman_get_device((r)->res)),	\
748	    rman_get_device((r)->res), (r), (o), (d), (c))
749#define bhnd_bus_read_stream_1(r, o) \
750    ((r)->direct) ? \
751	bus_read_stream_1((r)->res, (o)) : \
752	BHND_BUS_READ_STREAM_1( \
753	    device_get_parent(rman_get_device((r)->res)),	\
754	    rman_get_device((r)->res), (r), (o))
755#define bhnd_bus_read_multi_stream_1(r, o, d, c) \
756    ((r)->direct) ? \
757	bus_read_multi_stream_1((r)->res, (o), (d), (c)) : \
758	BHND_BUS_READ_MULTI_STREAM_1( \
759	    device_get_parent(rman_get_device((r)->res)),	\
760	    rman_get_device((r)->res), (r), (o), (d), (c))
761#define bhnd_bus_read_region_stream_1(r, o, d, c) \
762    ((r)->direct) ? \
763	bus_read_region_stream_1((r)->res, (o), (d), (c)) : \
764	BHND_BUS_READ_REGION_STREAM_1( \
765	    device_get_parent(rman_get_device((r)->res)),	\
766	    rman_get_device((r)->res), (r), (o), (d), (c))
767#define bhnd_bus_write_stream_1(r, o, v) \
768    ((r)->direct) ? \
769	bus_write_stream_1((r)->res, (o), (v)) : \
770	BHND_BUS_WRITE_STREAM_1( \
771	    device_get_parent(rman_get_device((r)->res)),	\
772	    rman_get_device((r)->res), (r), (o), (v))
773#define bhnd_bus_write_multi_stream_1(r, o, d, c) \
774    ((r)->direct) ? \
775	bus_write_multi_stream_1((r)->res, (o), (d), (c)) : \
776	BHND_BUS_WRITE_MULTI_STREAM_1( \
777	    device_get_parent(rman_get_device((r)->res)),	\
778	    rman_get_device((r)->res), (r), (o), (d), (c))
779#define bhnd_bus_write_region_stream_1(r, o, d, c) \
780    ((r)->direct) ? \
781	bus_write_region_stream_1((r)->res, (o), (d), (c)) : \
782	BHND_BUS_WRITE_REGION_STREAM_1( \
783	    device_get_parent(rman_get_device((r)->res)),	\
784	    rman_get_device((r)->res), (r), (o), (d), (c))
785#define bhnd_bus_set_multi_1(r, o, v, c) \
786    ((r)->direct) ? \
787	bus_set_multi_1((r)->res, (o), (v), (c)) : \
788	BHND_BUS_SET_MULTI_1( \
789	    device_get_parent(rman_get_device((r)->res)),	\
790	    rman_get_device((r)->res), (r), (o), (v), (c))
791#define bhnd_bus_set_region_1(r, o, v, c) \
792    ((r)->direct) ? \
793	bus_set_region_1((r)->res, (o), (v), (c)) : \
794	BHND_BUS_SET_REGION_1( \
795	    device_get_parent(rman_get_device((r)->res)),	\
796	    rman_get_device((r)->res), (r), (o), (v), (c))
797#define bhnd_bus_read_2(r, o) \
798    ((r)->direct) ? \
799	bus_read_2((r)->res, (o)) : \
800	BHND_BUS_READ_2( \
801	    device_get_parent(rman_get_device((r)->res)),	\
802	    rman_get_device((r)->res), (r), (o))
803#define bhnd_bus_read_multi_2(r, o, d, c) \
804    ((r)->direct) ? \
805	bus_read_multi_2((r)->res, (o), (d), (c)) : \
806	BHND_BUS_READ_MULTI_2( \
807	    device_get_parent(rman_get_device((r)->res)),	\
808	    rman_get_device((r)->res), (r), (o), (d), (c))
809#define bhnd_bus_read_region_2(r, o, d, c) \
810    ((r)->direct) ? \
811	bus_read_region_2((r)->res, (o), (d), (c)) : \
812	BHND_BUS_READ_REGION_2( \
813	    device_get_parent(rman_get_device((r)->res)),	\
814	    rman_get_device((r)->res), (r), (o), (d), (c))
815#define bhnd_bus_write_2(r, o, v) \
816    ((r)->direct) ? \
817	bus_write_2((r)->res, (o), (v)) : \
818	BHND_BUS_WRITE_2( \
819	    device_get_parent(rman_get_device((r)->res)),	\
820	    rman_get_device((r)->res), (r), (o), (v))
821#define bhnd_bus_write_multi_2(r, o, d, c) \
822    ((r)->direct) ? \
823	bus_write_multi_2((r)->res, (o), (d), (c)) : \
824	BHND_BUS_WRITE_MULTI_2( \
825	    device_get_parent(rman_get_device((r)->res)),	\
826	    rman_get_device((r)->res), (r), (o), (d), (c))
827#define bhnd_bus_write_region_2(r, o, d, c) \
828    ((r)->direct) ? \
829	bus_write_region_2((r)->res, (o), (d), (c)) : \
830	BHND_BUS_WRITE_REGION_2( \
831	    device_get_parent(rman_get_device((r)->res)),	\
832	    rman_get_device((r)->res), (r), (o), (d), (c))
833#define bhnd_bus_read_stream_2(r, o) \
834    ((r)->direct) ? \
835	bus_read_stream_2((r)->res, (o)) : \
836	BHND_BUS_READ_STREAM_2( \
837	    device_get_parent(rman_get_device((r)->res)),	\
838	    rman_get_device((r)->res), (r), (o))
839#define bhnd_bus_read_multi_stream_2(r, o, d, c) \
840    ((r)->direct) ? \
841	bus_read_multi_stream_2((r)->res, (o), (d), (c)) : \
842	BHND_BUS_READ_MULTI_STREAM_2( \
843	    device_get_parent(rman_get_device((r)->res)),	\
844	    rman_get_device((r)->res), (r), (o), (d), (c))
845#define bhnd_bus_read_region_stream_2(r, o, d, c) \
846    ((r)->direct) ? \
847	bus_read_region_stream_2((r)->res, (o), (d), (c)) : \
848	BHND_BUS_READ_REGION_STREAM_2( \
849	    device_get_parent(rman_get_device((r)->res)),	\
850	    rman_get_device((r)->res), (r), (o), (d), (c))
851#define bhnd_bus_write_stream_2(r, o, v) \
852    ((r)->direct) ? \
853	bus_write_stream_2((r)->res, (o), (v)) : \
854	BHND_BUS_WRITE_STREAM_2( \
855	    device_get_parent(rman_get_device((r)->res)),	\
856	    rman_get_device((r)->res), (r), (o), (v))
857#define bhnd_bus_write_multi_stream_2(r, o, d, c) \
858    ((r)->direct) ? \
859	bus_write_multi_stream_2((r)->res, (o), (d), (c)) : \
860	BHND_BUS_WRITE_MULTI_STREAM_2( \
861	    device_get_parent(rman_get_device((r)->res)),	\
862	    rman_get_device((r)->res), (r), (o), (d), (c))
863#define bhnd_bus_write_region_stream_2(r, o, d, c) \
864    ((r)->direct) ? \
865	bus_write_region_stream_2((r)->res, (o), (d), (c)) : \
866	BHND_BUS_WRITE_REGION_STREAM_2( \
867	    device_get_parent(rman_get_device((r)->res)),	\
868	    rman_get_device((r)->res), (r), (o), (d), (c))
869#define bhnd_bus_set_multi_2(r, o, v, c) \
870    ((r)->direct) ? \
871	bus_set_multi_2((r)->res, (o), (v), (c)) : \
872	BHND_BUS_SET_MULTI_2( \
873	    device_get_parent(rman_get_device((r)->res)),	\
874	    rman_get_device((r)->res), (r), (o), (v), (c))
875#define bhnd_bus_set_region_2(r, o, v, c) \
876    ((r)->direct) ? \
877	bus_set_region_2((r)->res, (o), (v), (c)) : \
878	BHND_BUS_SET_REGION_2( \
879	    device_get_parent(rman_get_device((r)->res)),	\
880	    rman_get_device((r)->res), (r), (o), (v), (c))
881#define bhnd_bus_read_4(r, o) \
882    ((r)->direct) ? \
883	bus_read_4((r)->res, (o)) : \
884	BHND_BUS_READ_4( \
885	    device_get_parent(rman_get_device((r)->res)),	\
886	    rman_get_device((r)->res), (r), (o))
887#define bhnd_bus_read_multi_4(r, o, d, c) \
888    ((r)->direct) ? \
889	bus_read_multi_4((r)->res, (o), (d), (c)) : \
890	BHND_BUS_READ_MULTI_4( \
891	    device_get_parent(rman_get_device((r)->res)),	\
892	    rman_get_device((r)->res), (r), (o), (d), (c))
893#define bhnd_bus_read_region_4(r, o, d, c) \
894    ((r)->direct) ? \
895	bus_read_region_4((r)->res, (o), (d), (c)) : \
896	BHND_BUS_READ_REGION_4( \
897	    device_get_parent(rman_get_device((r)->res)),	\
898	    rman_get_device((r)->res), (r), (o), (d), (c))
899#define bhnd_bus_write_4(r, o, v) \
900    ((r)->direct) ? \
901	bus_write_4((r)->res, (o), (v)) : \
902	BHND_BUS_WRITE_4( \
903	    device_get_parent(rman_get_device((r)->res)),	\
904	    rman_get_device((r)->res), (r), (o), (v))
905#define bhnd_bus_write_multi_4(r, o, d, c) \
906    ((r)->direct) ? \
907	bus_write_multi_4((r)->res, (o), (d), (c)) : \
908	BHND_BUS_WRITE_MULTI_4( \
909	    device_get_parent(rman_get_device((r)->res)),	\
910	    rman_get_device((r)->res), (r), (o), (d), (c))
911#define bhnd_bus_write_region_4(r, o, d, c) \
912    ((r)->direct) ? \
913	bus_write_region_4((r)->res, (o), (d), (c)) : \
914	BHND_BUS_WRITE_REGION_4( \
915	    device_get_parent(rman_get_device((r)->res)),	\
916	    rman_get_device((r)->res), (r), (o), (d), (c))
917#define bhnd_bus_read_stream_4(r, o) \
918    ((r)->direct) ? \
919	bus_read_stream_4((r)->res, (o)) : \
920	BHND_BUS_READ_STREAM_4( \
921	    device_get_parent(rman_get_device((r)->res)),	\
922	    rman_get_device((r)->res), (r), (o))
923#define bhnd_bus_read_multi_stream_4(r, o, d, c) \
924    ((r)->direct) ? \
925	bus_read_multi_stream_4((r)->res, (o), (d), (c)) : \
926	BHND_BUS_READ_MULTI_STREAM_4( \
927	    device_get_parent(rman_get_device((r)->res)),	\
928	    rman_get_device((r)->res), (r), (o), (d), (c))
929#define bhnd_bus_read_region_stream_4(r, o, d, c) \
930    ((r)->direct) ? \
931	bus_read_region_stream_4((r)->res, (o), (d), (c)) : \
932	BHND_BUS_READ_REGION_STREAM_4( \
933	    device_get_parent(rman_get_device((r)->res)),	\
934	    rman_get_device((r)->res), (r), (o), (d), (c))
935#define bhnd_bus_write_stream_4(r, o, v) \
936    ((r)->direct) ? \
937	bus_write_stream_4((r)->res, (o), (v)) : \
938	BHND_BUS_WRITE_STREAM_4( \
939	    device_get_parent(rman_get_device((r)->res)),	\
940	    rman_get_device((r)->res), (r), (o), (v))
941#define bhnd_bus_write_multi_stream_4(r, o, d, c) \
942    ((r)->direct) ? \
943	bus_write_multi_stream_4((r)->res, (o), (d), (c)) : \
944	BHND_BUS_WRITE_MULTI_STREAM_4( \
945	    device_get_parent(rman_get_device((r)->res)),	\
946	    rman_get_device((r)->res), (r), (o), (d), (c))
947#define bhnd_bus_write_region_stream_4(r, o, d, c) \
948    ((r)->direct) ? \
949	bus_write_region_stream_4((r)->res, (o), (d), (c)) : \
950	BHND_BUS_WRITE_REGION_STREAM_4( \
951	    device_get_parent(rman_get_device((r)->res)),	\
952	    rman_get_device((r)->res), (r), (o), (d), (c))
953#define bhnd_bus_set_multi_4(r, o, v, c) \
954    ((r)->direct) ? \
955	bus_set_multi_4((r)->res, (o), (v), (c)) : \
956	BHND_BUS_SET_MULTI_4( \
957	    device_get_parent(rman_get_device((r)->res)),	\
958	    rman_get_device((r)->res), (r), (o), (v), (c))
959#define bhnd_bus_set_region_4(r, o, v, c) \
960    ((r)->direct) ? \
961	bus_set_region_4((r)->res, (o), (v), (c)) : \
962	BHND_BUS_SET_REGION_4( \
963	    device_get_parent(rman_get_device((r)->res)),	\
964	    rman_get_device((r)->res), (r), (o), (v), (c))
965
966#endif /* _BHND_BHND_H_ */
967