Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/dev/bhnd/bhndb/bhndb_private.h
39536 views
1
/*-
2
* Copyright (c) 2015-2016 Landon Fuller <[email protected]>
3
* Copyright (c) 2017 The FreeBSD Foundation
4
* All rights reserved.
5
*
6
* Portions of this software were developed by Landon Fuller
7
* under sponsorship from the FreeBSD Foundation.
8
*
9
* Portions of this software were developed by Landon Fuller
10
* under sponsorship from the FreeBSD Foundation.
11
*
12
* Redistribution and use in source and binary forms, with or without
13
* modification, are permitted provided that the following conditions
14
* are met:
15
* 1. Redistributions of source code must retain the above copyright
16
* notice, this list of conditions and the following disclaimer,
17
* without modification.
18
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
19
* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
20
* redistribution must be conditioned upon including a substantially
21
* similar Disclaimer requirement for further binary redistribution.
22
*
23
* NO WARRANTY
24
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
27
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
28
* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
29
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
32
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
34
* THE POSSIBILITY OF SUCH DAMAGES.
35
*
36
*/
37
38
#ifndef _BHND_BHNDB_PRIVATE_H_
39
#define _BHND_BHNDB_PRIVATE_H_
40
41
#include <sys/param.h>
42
#include <sys/bitstring.h>
43
#include <sys/bus.h>
44
#include <sys/systm.h>
45
46
#include <machine/bus.h>
47
#include <sys/rman.h>
48
#include <machine/resource.h>
49
50
#include "bhndbvar.h"
51
52
/*
53
* Private bhndb(4) driver definitions.
54
*/
55
56
struct bhndb_dw_alloc;
57
struct bhndb_intr_handler;
58
struct bhndb_region;
59
struct bhndb_resources;
60
61
struct bhndb_resources *bhndb_alloc_resources(device_t dev,
62
device_t parent_dev,
63
const struct bhndb_hwcfg *cfg);
64
65
void bhndb_free_resources(
66
struct bhndb_resources *br);
67
68
int bhndb_add_resource_region(
69
struct bhndb_resources *br,
70
bhnd_addr_t addr, bhnd_size_t size,
71
bhndb_priority_t priority,
72
uint32_t alloc_flags,
73
const struct bhndb_regwin *static_regwin);
74
75
int bhndb_find_resource_limits(
76
struct bhndb_resources *br,
77
struct resource *r, rman_res_t *start,
78
rman_res_t *end);
79
80
struct bhndb_intr_handler *bhndb_alloc_intr_handler(device_t owner,
81
struct resource *r,
82
struct bhndb_intr_isrc *isrc);
83
void bhndb_free_intr_handler(
84
struct bhndb_intr_handler *ih);
85
86
void bhndb_register_intr_handler(
87
struct bhndb_resources *br,
88
struct bhndb_intr_handler *ih);
89
void bhndb_deregister_intr_handler(
90
struct bhndb_resources *br,
91
struct bhndb_intr_handler *ih);
92
struct bhndb_intr_handler *bhndb_find_intr_handler(
93
struct bhndb_resources *br,
94
void *cookiep);
95
96
bool bhndb_has_static_region_mapping(
97
struct bhndb_resources *br,
98
bhnd_addr_t addr, bhnd_size_t size);
99
100
struct bhndb_region *bhndb_find_resource_region(
101
struct bhndb_resources *br,
102
bhnd_addr_t addr, bhnd_size_t size);
103
104
struct bhndb_dw_alloc *bhndb_dw_find_resource(
105
struct bhndb_resources *dr,
106
struct resource *r);
107
108
struct bhndb_dw_alloc *bhndb_dw_find_mapping(
109
struct bhndb_resources *br,
110
bhnd_addr_t addr, bhnd_size_t size);
111
112
int bhndb_dw_retain(
113
struct bhndb_resources *br,
114
struct bhndb_dw_alloc *dwa,
115
struct resource *res);
116
117
void bhndb_dw_release(
118
struct bhndb_resources *br,
119
struct bhndb_dw_alloc *dwa,
120
struct resource *res);
121
122
int bhndb_dw_set_addr(device_t dev,
123
struct bhndb_resources *br,
124
struct bhndb_dw_alloc *dwa,
125
bus_addr_t addr, bus_size_t size);
126
127
struct bhndb_dw_alloc *bhndb_dw_steal(struct bhndb_resources *br,
128
bus_addr_t *saved);
129
130
void bhndb_dw_return_stolen(device_t dev,
131
struct bhndb_resources *br,
132
struct bhndb_dw_alloc *dwa,
133
bus_addr_t saved);
134
135
const struct bhndb_hw_priority *bhndb_hw_priority_find_core(
136
const struct bhndb_hw_priority *table,
137
struct bhnd_core_info *core);
138
139
const struct bhndb_port_priority *bhndb_hw_priorty_find_port(
140
const struct bhndb_hw_priority *table,
141
struct bhnd_core_info *core,
142
bhnd_port_type port_type, u_int port,
143
u_int region);
144
145
/**
146
* Dynamic register window allocation reference.
147
*/
148
struct bhndb_dw_rentry {
149
struct resource *dw_res; /**< child resource */
150
LIST_ENTRY(bhndb_dw_rentry) dw_link;
151
};
152
153
/**
154
* A dynamic register window allocation record.
155
*/
156
struct bhndb_dw_alloc {
157
const struct bhndb_regwin *win; /**< window definition */
158
struct resource *parent_res; /**< enclosing resource */
159
u_int rnid; /**< region identifier */
160
rman_res_t target; /**< the current window address, or 0x0 if unknown */
161
162
LIST_HEAD(, bhndb_dw_rentry) refs; /**< references */
163
};
164
165
/**
166
* A bus address region description.
167
*/
168
struct bhndb_region {
169
bhnd_addr_t addr; /**< start of mapped range */
170
bhnd_size_t size; /**< size of mapped range */
171
bhndb_priority_t priority; /**< direct resource allocation priority */
172
uint32_t alloc_flags; /**< resource allocation flags (@see bhndb_alloc_flags) */
173
const struct bhndb_regwin *static_regwin; /**< fixed mapping regwin, if any */
174
175
STAILQ_ENTRY(bhndb_region) link;
176
};
177
178
/**
179
* Attached interrupt handler state
180
*/
181
struct bhndb_intr_handler {
182
device_t ih_owner; /**< child device */
183
struct resource *ih_res; /**< child resource */
184
void *ih_cookiep; /**< hostb-assigned cookiep, or NULL if bus_setup_intr() incomplete. */
185
struct bhndb_intr_isrc *ih_isrc; /**< host interrupt source routing the child's interrupt */
186
bool ih_active; /**< handler has been registered via bhndb_register_intr_handler */
187
188
STAILQ_ENTRY(bhndb_intr_handler) ih_link;
189
};
190
191
/**
192
* BHNDB resource allocation state.
193
*/
194
struct bhndb_resources {
195
device_t dev; /**< bridge device */
196
const struct bhndb_hwcfg *cfg; /**< hardware configuration */
197
198
struct bhndb_host_resources *res; /**< host resources, or NULL if not allocated */
199
200
struct rman ht_mem_rman; /**< host memory manager */
201
struct rman br_mem_rman; /**< bridged memory manager */
202
struct rman br_irq_rman; /**< bridged irq manager */
203
204
STAILQ_HEAD(, bhndb_region) bus_regions; /**< bus region descriptors */
205
206
struct mtx dw_steal_mtx; /**< spinlock must be held when stealing a dynamic window allocation */
207
struct bhndb_dw_alloc *dw_alloc; /**< dynamic window allocation records */
208
size_t dwa_count; /**< number of dynamic windows available. */
209
bitstr_t *dwa_freelist; /**< dynamic window free list */
210
bhndb_priority_t min_prio; /**< minimum resource priority required to
211
allocate a dynamic window */
212
213
STAILQ_HEAD(,bhndb_intr_handler) bus_intrs; /**< attached child interrupt handlers */
214
};
215
216
/**
217
* Returns true if the all dynamic windows are marked free, false
218
* otherwise.
219
*
220
* @param br The resource state to check.
221
*/
222
static inline bool
223
bhndb_dw_all_free(struct bhndb_resources *br)
224
{
225
int bit;
226
bit_ffs(br->dwa_freelist, br->dwa_count, &bit);
227
return (bit == -1);
228
}
229
230
/**
231
* Find the next free dynamic window region in @p br.
232
*
233
* @param br The resource state to search.
234
*/
235
static inline struct bhndb_dw_alloc *
236
bhndb_dw_next_free(struct bhndb_resources *br)
237
{
238
struct bhndb_dw_alloc *dw_free;
239
int bit;
240
241
bit_ffc(br->dwa_freelist, br->dwa_count, &bit);
242
if (bit == -1)
243
return (NULL);
244
245
dw_free = &br->dw_alloc[bit];
246
247
KASSERT(LIST_EMPTY(&dw_free->refs),
248
("free list out of sync with refs"));
249
250
return (dw_free);
251
}
252
253
/**
254
* Returns true if a dynamic window allocation is marked as free.
255
*
256
* @param br The resource state owning @p dwa.
257
* @param dwa The dynamic window allocation record to be checked.
258
*/
259
static inline bool
260
bhndb_dw_is_free(struct bhndb_resources *br, struct bhndb_dw_alloc *dwa)
261
{
262
bool is_free = LIST_EMPTY(&dwa->refs);
263
264
KASSERT(is_free == !bit_test(br->dwa_freelist, dwa->rnid),
265
("refs out of sync with free list"));
266
267
return (is_free);
268
}
269
270
#define BHNDB_LOCK_INIT(sc) \
271
mtx_init(&(sc)->sc_mtx, device_get_nameunit((sc)->dev), \
272
"bhndb resource allocator lock", MTX_DEF)
273
#define BHNDB_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
274
#define BHNDB_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx)
275
#define BHNDB_LOCK_ASSERT(sc, what) mtx_assert(&(sc)->sc_mtx, what)
276
#define BHNDB_LOCK_DESTROY(sc) mtx_destroy(&(sc)->sc_mtx)
277
278
#endif /* _BHND_BHNDB_PRIVATE_H_ */
279
280