xref: /freebsd/sys/dev/bhnd/bhndb/bhndb_private.h (revision eaa5fb4b80217414600aa44e263f11bc22205db5)
14ad7e9b0SAdrian Chadd /*-
289294a78SLandon J. Fuller  * Copyright (c) 2015-2016 Landon Fuller <landon@landonf.org>
3caeff9a3SLandon J. Fuller  * Copyright (c) 2017 The FreeBSD Foundation
44ad7e9b0SAdrian Chadd  * All rights reserved.
54ad7e9b0SAdrian Chadd  *
689294a78SLandon J. Fuller  * Portions of this software were developed by Landon Fuller
789294a78SLandon J. Fuller  * under sponsorship from the FreeBSD Foundation.
889294a78SLandon J. Fuller  *
9caeff9a3SLandon J. Fuller  * Portions of this software were developed by Landon Fuller
10caeff9a3SLandon J. Fuller  * under sponsorship from the FreeBSD Foundation.
11caeff9a3SLandon J. Fuller  *
124ad7e9b0SAdrian Chadd  * Redistribution and use in source and binary forms, with or without
134ad7e9b0SAdrian Chadd  * modification, are permitted provided that the following conditions
144ad7e9b0SAdrian Chadd  * are met:
154ad7e9b0SAdrian Chadd  * 1. Redistributions of source code must retain the above copyright
164ad7e9b0SAdrian Chadd  *    notice, this list of conditions and the following disclaimer,
174ad7e9b0SAdrian Chadd  *    without modification.
184ad7e9b0SAdrian Chadd  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
194ad7e9b0SAdrian Chadd  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
204ad7e9b0SAdrian Chadd  *    redistribution must be conditioned upon including a substantially
214ad7e9b0SAdrian Chadd  *    similar Disclaimer requirement for further binary redistribution.
224ad7e9b0SAdrian Chadd  *
234ad7e9b0SAdrian Chadd  * NO WARRANTY
244ad7e9b0SAdrian Chadd  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
254ad7e9b0SAdrian Chadd  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
264ad7e9b0SAdrian Chadd  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
274ad7e9b0SAdrian Chadd  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
284ad7e9b0SAdrian Chadd  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
294ad7e9b0SAdrian Chadd  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
304ad7e9b0SAdrian Chadd  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
314ad7e9b0SAdrian Chadd  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
324ad7e9b0SAdrian Chadd  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
334ad7e9b0SAdrian Chadd  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
344ad7e9b0SAdrian Chadd  * THE POSSIBILITY OF SUCH DAMAGES.
354ad7e9b0SAdrian Chadd  *
364ad7e9b0SAdrian Chadd  * $FreeBSD$
374ad7e9b0SAdrian Chadd  */
384ad7e9b0SAdrian Chadd 
394ad7e9b0SAdrian Chadd #ifndef _BHND_BHNDB_PRIVATE_H_
404ad7e9b0SAdrian Chadd #define _BHND_BHNDB_PRIVATE_H_
414ad7e9b0SAdrian Chadd 
424ad7e9b0SAdrian Chadd #include <sys/param.h>
439dfeb414SLandon J. Fuller #include <sys/bitstring.h>
444ad7e9b0SAdrian Chadd #include <sys/bus.h>
454ad7e9b0SAdrian Chadd #include <sys/systm.h>
464ad7e9b0SAdrian Chadd 
474ad7e9b0SAdrian Chadd #include <machine/bus.h>
484ad7e9b0SAdrian Chadd #include <sys/rman.h>
494ad7e9b0SAdrian Chadd #include <machine/resource.h>
504ad7e9b0SAdrian Chadd 
514ad7e9b0SAdrian Chadd #include "bhndbvar.h"
524ad7e9b0SAdrian Chadd 
534ad7e9b0SAdrian Chadd /*
544ad7e9b0SAdrian Chadd  * Private bhndb(4) driver definitions.
554ad7e9b0SAdrian Chadd  */
564ad7e9b0SAdrian Chadd 
574ad7e9b0SAdrian Chadd struct bhndb_dw_alloc;
58caeff9a3SLandon J. Fuller struct bhndb_intr_handler;
594ad7e9b0SAdrian Chadd struct bhndb_region;
604ad7e9b0SAdrian Chadd struct bhndb_resources;
614ad7e9b0SAdrian Chadd 
624ad7e9b0SAdrian Chadd struct bhndb_resources		*bhndb_alloc_resources(device_t dev,
634ad7e9b0SAdrian Chadd 				     device_t parent_dev,
644ad7e9b0SAdrian Chadd 				     const struct bhndb_hwcfg *cfg);
654ad7e9b0SAdrian Chadd 
664ad7e9b0SAdrian Chadd void				 bhndb_free_resources(
674ad7e9b0SAdrian Chadd 				     struct bhndb_resources *br);
684ad7e9b0SAdrian Chadd 
694ad7e9b0SAdrian Chadd int				 bhndb_add_resource_region(
704ad7e9b0SAdrian Chadd 				     struct bhndb_resources *br,
714ad7e9b0SAdrian Chadd 				     bhnd_addr_t addr, bhnd_size_t size,
724ad7e9b0SAdrian Chadd 				     bhndb_priority_t priority,
73*eaa5fb4bSLandon J. Fuller 				     uint32_t alloc_flags,
744ad7e9b0SAdrian Chadd 				     const struct bhndb_regwin *static_regwin);
754ad7e9b0SAdrian Chadd 
76249f3d3fSAdrian Chadd int				 bhndb_find_resource_limits(
77caeff9a3SLandon J. Fuller 				     struct bhndb_resources *br, int type,
78249f3d3fSAdrian Chadd 				     struct resource *r, rman_res_t *start,
79249f3d3fSAdrian Chadd 				     rman_res_t *end);
80249f3d3fSAdrian Chadd 
81caeff9a3SLandon J. Fuller struct bhndb_intr_handler	*bhndb_alloc_intr_handler(device_t owner,
82caeff9a3SLandon J. Fuller 				     struct resource *r,
83caeff9a3SLandon J. Fuller 				     struct bhndb_intr_isrc *isrc);
84caeff9a3SLandon J. Fuller void				 bhndb_free_intr_handler(
85caeff9a3SLandon J. Fuller 				     struct bhndb_intr_handler *ih);
86caeff9a3SLandon J. Fuller 
87caeff9a3SLandon J. Fuller void				 bhndb_register_intr_handler(
88caeff9a3SLandon J. Fuller 				     struct bhndb_resources *br,
89caeff9a3SLandon J. Fuller 				     struct bhndb_intr_handler *ih);
90caeff9a3SLandon J. Fuller void				 bhndb_deregister_intr_handler(
91caeff9a3SLandon J. Fuller 				     struct bhndb_resources *br,
92caeff9a3SLandon J. Fuller 				     struct bhndb_intr_handler *ih);
93caeff9a3SLandon J. Fuller struct bhndb_intr_handler	*bhndb_find_intr_handler(
94caeff9a3SLandon J. Fuller 				     struct bhndb_resources *br,
95caeff9a3SLandon J. Fuller 				     void *cookiep);
96caeff9a3SLandon J. Fuller 
97*eaa5fb4bSLandon J. Fuller bool				 bhndb_has_static_region_mapping(
98*eaa5fb4bSLandon J. Fuller 				     struct bhndb_resources *br,
99*eaa5fb4bSLandon J. Fuller 				     bhnd_addr_t addr, bhnd_size_t size);
100*eaa5fb4bSLandon J. Fuller 
1014ad7e9b0SAdrian Chadd struct bhndb_region		*bhndb_find_resource_region(
1024ad7e9b0SAdrian Chadd 				     struct bhndb_resources *br,
1034ad7e9b0SAdrian Chadd 				     bhnd_addr_t addr, bhnd_size_t size);
1044ad7e9b0SAdrian Chadd 
1054ad7e9b0SAdrian Chadd struct bhndb_dw_alloc		*bhndb_dw_find_resource(
1064ad7e9b0SAdrian Chadd 				     struct bhndb_resources *dr,
1074ad7e9b0SAdrian Chadd 				     struct resource *r);
1084ad7e9b0SAdrian Chadd 
1094ad7e9b0SAdrian Chadd struct bhndb_dw_alloc		*bhndb_dw_find_mapping(
1104ad7e9b0SAdrian Chadd 				     struct bhndb_resources *br,
1114ad7e9b0SAdrian Chadd 				     bhnd_addr_t addr, bhnd_size_t size);
1124ad7e9b0SAdrian Chadd 
1134ad7e9b0SAdrian Chadd int				 bhndb_dw_retain(
1144ad7e9b0SAdrian Chadd 				     struct bhndb_resources *br,
1154ad7e9b0SAdrian Chadd 				     struct bhndb_dw_alloc *dwa,
1164ad7e9b0SAdrian Chadd 				     struct resource *res);
1174ad7e9b0SAdrian Chadd 
1184ad7e9b0SAdrian Chadd void				 bhndb_dw_release(
1194ad7e9b0SAdrian Chadd 				     struct bhndb_resources *br,
1204ad7e9b0SAdrian Chadd 				     struct bhndb_dw_alloc *dwa,
1214ad7e9b0SAdrian Chadd 				     struct resource *res);
1224ad7e9b0SAdrian Chadd 
1234ad7e9b0SAdrian Chadd int				 bhndb_dw_set_addr(device_t dev,
1244ad7e9b0SAdrian Chadd 				     struct bhndb_resources *br,
1254ad7e9b0SAdrian Chadd 				     struct bhndb_dw_alloc *dwa,
1264ad7e9b0SAdrian Chadd 				     bus_addr_t addr, bus_size_t size);
1274ad7e9b0SAdrian Chadd 
128*eaa5fb4bSLandon J. Fuller struct bhndb_dw_alloc		*bhndb_dw_steal(struct bhndb_resources *br,
129*eaa5fb4bSLandon J. Fuller 				     bus_addr_t *saved);
130*eaa5fb4bSLandon J. Fuller 
131*eaa5fb4bSLandon J. Fuller void				 bhndb_dw_return_stolen(device_t dev,
132*eaa5fb4bSLandon J. Fuller 				     struct bhndb_resources *br,
133*eaa5fb4bSLandon J. Fuller 				     struct bhndb_dw_alloc *dwa,
134*eaa5fb4bSLandon J. Fuller 				     bus_addr_t saved);
135*eaa5fb4bSLandon J. Fuller 
136111d7cb2SLandon J. Fuller const struct bhndb_hw_priority	*bhndb_hw_priority_find_core(
1374ad7e9b0SAdrian Chadd 				     const struct bhndb_hw_priority *table,
138111d7cb2SLandon J. Fuller 				     struct bhnd_core_info *core);
1394ad7e9b0SAdrian Chadd 
140*eaa5fb4bSLandon J. Fuller const struct bhndb_port_priority *bhndb_hw_priorty_find_port(
141*eaa5fb4bSLandon J. Fuller 				     const struct bhndb_hw_priority *table,
142*eaa5fb4bSLandon J. Fuller 				     struct bhnd_core_info *core,
143*eaa5fb4bSLandon J. Fuller 				     bhnd_port_type port_type, u_int port,
144*eaa5fb4bSLandon J. Fuller 				     u_int region);
145*eaa5fb4bSLandon J. Fuller 
1464ad7e9b0SAdrian Chadd 
1474ad7e9b0SAdrian Chadd /**
1484ad7e9b0SAdrian Chadd  * Dynamic register window allocation reference.
1494ad7e9b0SAdrian Chadd  */
1504ad7e9b0SAdrian Chadd struct bhndb_dw_rentry {
1514ad7e9b0SAdrian Chadd 	struct resource			*dw_res;	/**< child resource */
1524ad7e9b0SAdrian Chadd 	LIST_ENTRY(bhndb_dw_rentry)	 dw_link;
1534ad7e9b0SAdrian Chadd };
1544ad7e9b0SAdrian Chadd 
1554ad7e9b0SAdrian Chadd /**
1564ad7e9b0SAdrian Chadd  * A dynamic register window allocation record.
1574ad7e9b0SAdrian Chadd  */
1584ad7e9b0SAdrian Chadd struct bhndb_dw_alloc {
1594ad7e9b0SAdrian Chadd 	const struct bhndb_regwin	*win;		/**< window definition */
1604ad7e9b0SAdrian Chadd 	struct resource			*parent_res;	/**< enclosing resource */
1614ad7e9b0SAdrian Chadd 	u_int				 rnid;		/**< region identifier */
1624ad7e9b0SAdrian Chadd 	rman_res_t			 target;	/**< the current window address, or 0x0 if unknown */
1634ad7e9b0SAdrian Chadd 
1644ad7e9b0SAdrian Chadd 	LIST_HEAD(, bhndb_dw_rentry)	 refs;		/**< references */
1654ad7e9b0SAdrian Chadd };
1664ad7e9b0SAdrian Chadd 
1674ad7e9b0SAdrian Chadd /**
1684ad7e9b0SAdrian Chadd  * A bus address region description.
1694ad7e9b0SAdrian Chadd  */
1704ad7e9b0SAdrian Chadd struct bhndb_region {
1714ad7e9b0SAdrian Chadd 	bhnd_addr_t			 addr;		/**< start of mapped range */
1724ad7e9b0SAdrian Chadd 	bhnd_size_t			 size;		/**< size of mapped range */
1734ad7e9b0SAdrian Chadd 	bhndb_priority_t		 priority;	/**< direct resource allocation priority */
174*eaa5fb4bSLandon J. Fuller 	uint32_t			 alloc_flags;	/**< resource allocation flags (@see bhndb_alloc_flags) */
1754ad7e9b0SAdrian Chadd 	const struct bhndb_regwin	*static_regwin;	/**< fixed mapping regwin, if any */
1764ad7e9b0SAdrian Chadd 
1774ad7e9b0SAdrian Chadd 	STAILQ_ENTRY(bhndb_region)	 link;
1784ad7e9b0SAdrian Chadd };
1794ad7e9b0SAdrian Chadd 
1804ad7e9b0SAdrian Chadd /**
181caeff9a3SLandon J. Fuller  * Attached interrupt handler state
182caeff9a3SLandon J. Fuller  */
183caeff9a3SLandon J. Fuller struct bhndb_intr_handler {
184caeff9a3SLandon J. Fuller 	device_t		 ih_owner;	/**< child device */
185caeff9a3SLandon J. Fuller 	struct resource		*ih_res;	/**< child resource */
186caeff9a3SLandon J. Fuller 	void			*ih_cookiep;	/**< hostb-assigned cookiep, or NULL if bus_setup_intr() incomplete. */
187caeff9a3SLandon J. Fuller 	struct bhndb_intr_isrc	*ih_isrc;	/**< host interrupt source routing the child's interrupt  */
188caeff9a3SLandon J. Fuller 	bool			 ih_active;	/**< handler has been registered via bhndb_register_intr_handler */
189caeff9a3SLandon J. Fuller 
190caeff9a3SLandon J. Fuller 	STAILQ_ENTRY(bhndb_intr_handler) ih_link;
191caeff9a3SLandon J. Fuller };
192caeff9a3SLandon J. Fuller 
193caeff9a3SLandon J. Fuller /**
1944ad7e9b0SAdrian Chadd  * BHNDB resource allocation state.
1954ad7e9b0SAdrian Chadd  */
1964ad7e9b0SAdrian Chadd struct bhndb_resources {
1974ad7e9b0SAdrian Chadd 	device_t			 dev;		/**< bridge device */
1984ad7e9b0SAdrian Chadd 	const struct bhndb_hwcfg	*cfg;		/**< hardware configuration */
1994ad7e9b0SAdrian Chadd 
20089294a78SLandon J. Fuller 	struct bhndb_host_resources	*res;		/**< host resources, or NULL if not allocated */
2014ad7e9b0SAdrian Chadd 
202e9378f45SAdrian Chadd 	struct rman			 ht_mem_rman;	/**< host memory manager */
203e9378f45SAdrian Chadd 	struct rman			 br_mem_rman;	/**< bridged memory manager */
204caeff9a3SLandon J. Fuller 	struct rman			 br_irq_rman;	/**< bridged irq manager */
205e9378f45SAdrian Chadd 
2064ad7e9b0SAdrian Chadd 	STAILQ_HEAD(, bhndb_region) 	 bus_regions;	/**< bus region descriptors */
2074ad7e9b0SAdrian Chadd 
208*eaa5fb4bSLandon J. Fuller 	struct mtx			 dw_steal_mtx;	/**< spinlock must be held when stealing a dynamic window allocation */
2094ad7e9b0SAdrian Chadd 	struct bhndb_dw_alloc		*dw_alloc;	/**< dynamic window allocation records */
2104ad7e9b0SAdrian Chadd 	size_t				 dwa_count;	/**< number of dynamic windows available. */
2119dfeb414SLandon J. Fuller 	bitstr_t			*dwa_freelist;	/**< dynamic window free list */
2124ad7e9b0SAdrian Chadd 	bhndb_priority_t		 min_prio;	/**< minimum resource priority required to
2134ad7e9b0SAdrian Chadd 							     allocate a dynamic window */
214caeff9a3SLandon J. Fuller 
215caeff9a3SLandon J. Fuller 	STAILQ_HEAD(,bhndb_intr_handler) bus_intrs;	/**< attached child interrupt handlers */
2164ad7e9b0SAdrian Chadd };
2174ad7e9b0SAdrian Chadd 
2184ad7e9b0SAdrian Chadd /**
2199dfeb414SLandon J. Fuller  * Returns true if the all dynamic windows are marked free, false
2204ad7e9b0SAdrian Chadd  * otherwise.
2214ad7e9b0SAdrian Chadd  *
2224ad7e9b0SAdrian Chadd  * @param br The resource state to check.
2234ad7e9b0SAdrian Chadd  */
2244ad7e9b0SAdrian Chadd static inline bool
2259dfeb414SLandon J. Fuller bhndb_dw_all_free(struct bhndb_resources *br)
2264ad7e9b0SAdrian Chadd {
2279dfeb414SLandon J. Fuller 	int bit;
2289dfeb414SLandon J. Fuller 	bit_ffs(br->dwa_freelist, br->dwa_count, &bit);
2299dfeb414SLandon J. Fuller 	return (bit == -1);
2304ad7e9b0SAdrian Chadd }
2314ad7e9b0SAdrian Chadd 
2324ad7e9b0SAdrian Chadd /**
2334ad7e9b0SAdrian Chadd  * Find the next free dynamic window region in @p br.
2344ad7e9b0SAdrian Chadd  *
2354ad7e9b0SAdrian Chadd  * @param br The resource state to search.
2364ad7e9b0SAdrian Chadd  */
2374ad7e9b0SAdrian Chadd static inline struct bhndb_dw_alloc *
2384ad7e9b0SAdrian Chadd bhndb_dw_next_free(struct bhndb_resources *br)
2394ad7e9b0SAdrian Chadd {
2404ad7e9b0SAdrian Chadd 	struct bhndb_dw_alloc	*dw_free;
2419dfeb414SLandon J. Fuller 	int			 bit;
2424ad7e9b0SAdrian Chadd 
2439dfeb414SLandon J. Fuller 	bit_ffc(br->dwa_freelist, br->dwa_count, &bit);
2449dfeb414SLandon J. Fuller 	if (bit == -1)
2454ad7e9b0SAdrian Chadd 		return (NULL);
2464ad7e9b0SAdrian Chadd 
2479dfeb414SLandon J. Fuller 	dw_free = &br->dw_alloc[bit];
2484ad7e9b0SAdrian Chadd 
2494ad7e9b0SAdrian Chadd 	KASSERT(LIST_EMPTY(&dw_free->refs),
2504ad7e9b0SAdrian Chadd 	    ("free list out of sync with refs"));
2514ad7e9b0SAdrian Chadd 
2524ad7e9b0SAdrian Chadd 	return (dw_free);
2534ad7e9b0SAdrian Chadd }
2544ad7e9b0SAdrian Chadd 
2554ad7e9b0SAdrian Chadd /**
2564ad7e9b0SAdrian Chadd  * Returns true if a dynamic window allocation is marked as free.
2574ad7e9b0SAdrian Chadd  *
2584ad7e9b0SAdrian Chadd  * @param br The resource state owning @p dwa.
2594ad7e9b0SAdrian Chadd  * @param dwa The dynamic window allocation record to be checked.
2604ad7e9b0SAdrian Chadd  */
2614ad7e9b0SAdrian Chadd static inline bool
2624ad7e9b0SAdrian Chadd bhndb_dw_is_free(struct bhndb_resources *br, struct bhndb_dw_alloc *dwa)
2634ad7e9b0SAdrian Chadd {
2644ad7e9b0SAdrian Chadd 	bool is_free = LIST_EMPTY(&dwa->refs);
2654ad7e9b0SAdrian Chadd 
2669dfeb414SLandon J. Fuller 	KASSERT(is_free == !bit_test(br->dwa_freelist, dwa->rnid),
2674ad7e9b0SAdrian Chadd 	    ("refs out of sync with free list"));
2684ad7e9b0SAdrian Chadd 
2694ad7e9b0SAdrian Chadd 	return (is_free);
2704ad7e9b0SAdrian Chadd }
2714ad7e9b0SAdrian Chadd 
2724ad7e9b0SAdrian Chadd 
2734ad7e9b0SAdrian Chadd #define	BHNDB_LOCK_INIT(sc) \
2744ad7e9b0SAdrian Chadd 	mtx_init(&(sc)->sc_mtx, device_get_nameunit((sc)->dev), \
2754ad7e9b0SAdrian Chadd 	    "bhndb resource allocator lock", MTX_DEF)
2764ad7e9b0SAdrian Chadd #define	BHNDB_LOCK(sc)			mtx_lock(&(sc)->sc_mtx)
2774ad7e9b0SAdrian Chadd #define	BHNDB_UNLOCK(sc)		mtx_unlock(&(sc)->sc_mtx)
2784ad7e9b0SAdrian Chadd #define	BHNDB_LOCK_ASSERT(sc, what)	mtx_assert(&(sc)->sc_mtx, what)
2794ad7e9b0SAdrian Chadd #define	BHNDB_LOCK_DESTROY(sc)		mtx_destroy(&(sc)->sc_mtx)
2804ad7e9b0SAdrian Chadd 
2814ad7e9b0SAdrian Chadd #endif /* _BHND_BHNDB_PRIVATE_H_ */
282