xref: /freebsd/sys/dev/bhnd/bhndb/bhndb_private.h (revision 094fc1ed0f2627525c7b0342efcbad5be7a8546a)
1 /*-
2  * Copyright (c) 2015-2016 Landon Fuller <landon@landonf.org>
3  * All rights reserved.
4  *
5  * Portions of this software were developed by Landon Fuller
6  * under sponsorship from the FreeBSD Foundation.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer,
13  *    without modification.
14  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
15  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
16  *    redistribution must be conditioned upon including a substantially
17  *    similar Disclaimer requirement for further binary redistribution.
18  *
19  * NO WARRANTY
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
23  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
24  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
25  * OR 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
28  * IN 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
30  * THE POSSIBILITY OF SUCH DAMAGES.
31  *
32  * $FreeBSD$
33  */
34 
35 #ifndef _BHND_BHNDB_PRIVATE_H_
36 #define _BHND_BHNDB_PRIVATE_H_
37 
38 #include <sys/param.h>
39 #include <sys/bitstring.h>
40 #include <sys/bus.h>
41 #include <sys/systm.h>
42 
43 #include <machine/bus.h>
44 #include <sys/rman.h>
45 #include <machine/resource.h>
46 
47 #include "bhndbvar.h"
48 
49 /*
50  * Private bhndb(4) driver definitions.
51  */
52 
53 struct bhndb_dw_alloc;
54 struct bhndb_region;
55 struct bhndb_resources;
56 
57 struct bhndb_resources		*bhndb_alloc_resources(device_t dev,
58 				     device_t parent_dev,
59 				     const struct bhndb_hwcfg *cfg);
60 
61 void				 bhndb_free_resources(
62 				     struct bhndb_resources *br);
63 
64 int				 bhndb_add_resource_region(
65 				     struct bhndb_resources *br,
66 				     bhnd_addr_t addr, bhnd_size_t size,
67 				     bhndb_priority_t priority,
68 				     const struct bhndb_regwin *static_regwin);
69 
70 int				 bhndb_find_resource_limits(
71 				     struct bhndb_resources *br,
72 				     struct resource *r, rman_res_t *start,
73 				     rman_res_t *end);
74 
75 struct bhndb_region		*bhndb_find_resource_region(
76 				     struct bhndb_resources *br,
77 				     bhnd_addr_t addr, bhnd_size_t size);
78 
79 struct bhndb_dw_alloc		*bhndb_dw_find_resource(
80 				     struct bhndb_resources *dr,
81 				     struct resource *r);
82 
83 struct bhndb_dw_alloc		*bhndb_dw_find_mapping(
84 				     struct bhndb_resources *br,
85 				     bhnd_addr_t addr, bhnd_size_t size);
86 
87 int				 bhndb_dw_retain(
88 				     struct bhndb_resources *br,
89 				     struct bhndb_dw_alloc *dwa,
90 				     struct resource *res);
91 
92 void				 bhndb_dw_release(
93 				     struct bhndb_resources *br,
94 				     struct bhndb_dw_alloc *dwa,
95 				     struct resource *res);
96 
97 int				 bhndb_dw_set_addr(device_t dev,
98 				     struct bhndb_resources *br,
99 				     struct bhndb_dw_alloc *dwa,
100 				     bus_addr_t addr, bus_size_t size);
101 
102 const struct bhndb_hw_priority	*bhndb_hw_priority_find_core(
103 				     const struct bhndb_hw_priority *table,
104 				     struct bhnd_core_info *core);
105 
106 
107 /**
108  * Dynamic register window allocation reference.
109  */
110 struct bhndb_dw_rentry {
111 	struct resource			*dw_res;	/**< child resource */
112 	LIST_ENTRY(bhndb_dw_rentry)	 dw_link;
113 };
114 
115 /**
116  * A dynamic register window allocation record.
117  */
118 struct bhndb_dw_alloc {
119 	const struct bhndb_regwin	*win;		/**< window definition */
120 	struct resource			*parent_res;	/**< enclosing resource */
121 	u_int				 rnid;		/**< region identifier */
122 	rman_res_t			 target;	/**< the current window address, or 0x0 if unknown */
123 
124 	LIST_HEAD(, bhndb_dw_rentry)	 refs;		/**< references */
125 };
126 
127 /**
128  * A bus address region description.
129  */
130 struct bhndb_region {
131 	bhnd_addr_t			 addr;		/**< start of mapped range */
132 	bhnd_size_t			 size;		/**< size of mapped range */
133 	bhndb_priority_t		 priority;	/**< direct resource allocation priority */
134 	const struct bhndb_regwin	*static_regwin;	/**< fixed mapping regwin, if any */
135 
136 	STAILQ_ENTRY(bhndb_region)	 link;
137 };
138 
139 /**
140  * BHNDB resource allocation state.
141  */
142 struct bhndb_resources {
143 	device_t			 dev;		/**< bridge device */
144 	const struct bhndb_hwcfg	*cfg;		/**< hardware configuration */
145 
146 	struct bhndb_host_resources	*res;		/**< host resources, or NULL if not allocated */
147 
148 	struct rman			 ht_mem_rman;	/**< host memory manager */
149 	struct rman			 br_mem_rman;	/**< bridged memory manager */
150 
151 	STAILQ_HEAD(, bhndb_region) 	 bus_regions;	/**< bus region descriptors */
152 
153 	struct bhndb_dw_alloc		*dw_alloc;	/**< dynamic window allocation records */
154 	size_t				 dwa_count;	/**< number of dynamic windows available. */
155 	bitstr_t			*dwa_freelist;	/**< dynamic window free list */
156 	bhndb_priority_t		 min_prio;	/**< minimum resource priority required to
157 							     allocate a dynamic window */
158 };
159 
160 /**
161  * Returns true if the all dynamic windows are marked free, false
162  * otherwise.
163  *
164  * @param br The resource state to check.
165  */
166 static inline bool
167 bhndb_dw_all_free(struct bhndb_resources *br)
168 {
169 	int bit;
170 	bit_ffs(br->dwa_freelist, br->dwa_count, &bit);
171 	return (bit == -1);
172 }
173 
174 /**
175  * Find the next free dynamic window region in @p br.
176  *
177  * @param br The resource state to search.
178  */
179 static inline struct bhndb_dw_alloc *
180 bhndb_dw_next_free(struct bhndb_resources *br)
181 {
182 	struct bhndb_dw_alloc	*dw_free;
183 	int			 bit;
184 
185 	bit_ffc(br->dwa_freelist, br->dwa_count, &bit);
186 	if (bit == -1)
187 		return (NULL);
188 
189 	dw_free = &br->dw_alloc[bit];
190 
191 	KASSERT(LIST_EMPTY(&dw_free->refs),
192 	    ("free list out of sync with refs"));
193 
194 	return (dw_free);
195 }
196 
197 /**
198  * Returns true if a dynamic window allocation is marked as free.
199  *
200  * @param br The resource state owning @p dwa.
201  * @param dwa The dynamic window allocation record to be checked.
202  */
203 static inline bool
204 bhndb_dw_is_free(struct bhndb_resources *br, struct bhndb_dw_alloc *dwa)
205 {
206 	bool is_free = LIST_EMPTY(&dwa->refs);
207 
208 	KASSERT(is_free == !bit_test(br->dwa_freelist, dwa->rnid),
209 	    ("refs out of sync with free list"));
210 
211 	return (is_free);
212 }
213 
214 
215 #define	BHNDB_LOCK_INIT(sc) \
216 	mtx_init(&(sc)->sc_mtx, device_get_nameunit((sc)->dev), \
217 	    "bhndb resource allocator lock", MTX_DEF)
218 #define	BHNDB_LOCK(sc)			mtx_lock(&(sc)->sc_mtx)
219 #define	BHNDB_UNLOCK(sc)		mtx_unlock(&(sc)->sc_mtx)
220 #define	BHNDB_LOCK_ASSERT(sc, what)	mtx_assert(&(sc)->sc_mtx, what)
221 #define	BHNDB_LOCK_DESTROY(sc)		mtx_destroy(&(sc)->sc_mtx)
222 
223 #endif /* _BHND_BHNDB_PRIVATE_H_ */
224