#ifndef _BHND_BHNDB_PRIVATE_H_
#define _BHND_BHNDB_PRIVATE_H_
#include <sys/param.h>
#include <sys/bitstring.h>
#include <sys/bus.h>
#include <sys/systm.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
#include "bhndbvar.h"
struct bhndb_dw_alloc;
struct bhndb_intr_handler;
struct bhndb_region;
struct bhndb_resources;
struct bhndb_resources *bhndb_alloc_resources(device_t dev,
device_t parent_dev,
const struct bhndb_hwcfg *cfg);
void bhndb_free_resources(
struct bhndb_resources *br);
int bhndb_add_resource_region(
struct bhndb_resources *br,
bhnd_addr_t addr, bhnd_size_t size,
bhndb_priority_t priority,
uint32_t alloc_flags,
const struct bhndb_regwin *static_regwin);
int bhndb_find_resource_limits(
struct bhndb_resources *br,
struct resource *r, rman_res_t *start,
rman_res_t *end);
struct bhndb_intr_handler *bhndb_alloc_intr_handler(device_t owner,
struct resource *r,
struct bhndb_intr_isrc *isrc);
void bhndb_free_intr_handler(
struct bhndb_intr_handler *ih);
void bhndb_register_intr_handler(
struct bhndb_resources *br,
struct bhndb_intr_handler *ih);
void bhndb_deregister_intr_handler(
struct bhndb_resources *br,
struct bhndb_intr_handler *ih);
struct bhndb_intr_handler *bhndb_find_intr_handler(
struct bhndb_resources *br,
void *cookiep);
bool bhndb_has_static_region_mapping(
struct bhndb_resources *br,
bhnd_addr_t addr, bhnd_size_t size);
struct bhndb_region *bhndb_find_resource_region(
struct bhndb_resources *br,
bhnd_addr_t addr, bhnd_size_t size);
struct bhndb_dw_alloc *bhndb_dw_find_resource(
struct bhndb_resources *dr,
struct resource *r);
struct bhndb_dw_alloc *bhndb_dw_find_mapping(
struct bhndb_resources *br,
bhnd_addr_t addr, bhnd_size_t size);
int bhndb_dw_retain(
struct bhndb_resources *br,
struct bhndb_dw_alloc *dwa,
struct resource *res);
void bhndb_dw_release(
struct bhndb_resources *br,
struct bhndb_dw_alloc *dwa,
struct resource *res);
int bhndb_dw_set_addr(device_t dev,
struct bhndb_resources *br,
struct bhndb_dw_alloc *dwa,
bus_addr_t addr, bus_size_t size);
struct bhndb_dw_alloc *bhndb_dw_steal(struct bhndb_resources *br,
bus_addr_t *saved);
void bhndb_dw_return_stolen(device_t dev,
struct bhndb_resources *br,
struct bhndb_dw_alloc *dwa,
bus_addr_t saved);
const struct bhndb_hw_priority *bhndb_hw_priority_find_core(
const struct bhndb_hw_priority *table,
struct bhnd_core_info *core);
const struct bhndb_port_priority *bhndb_hw_priorty_find_port(
const struct bhndb_hw_priority *table,
struct bhnd_core_info *core,
bhnd_port_type port_type, u_int port,
u_int region);
struct bhndb_dw_rentry {
struct resource *dw_res;
LIST_ENTRY(bhndb_dw_rentry) dw_link;
};
struct bhndb_dw_alloc {
const struct bhndb_regwin *win;
struct resource *parent_res;
u_int rnid;
rman_res_t target;
LIST_HEAD(, bhndb_dw_rentry) refs;
};
struct bhndb_region {
bhnd_addr_t addr;
bhnd_size_t size;
bhndb_priority_t priority;
uint32_t alloc_flags;
const struct bhndb_regwin *static_regwin;
STAILQ_ENTRY(bhndb_region) link;
};
struct bhndb_intr_handler {
device_t ih_owner;
struct resource *ih_res;
void *ih_cookiep;
struct bhndb_intr_isrc *ih_isrc;
bool ih_active;
STAILQ_ENTRY(bhndb_intr_handler) ih_link;
};
struct bhndb_resources {
device_t dev;
const struct bhndb_hwcfg *cfg;
struct bhndb_host_resources *res;
struct rman ht_mem_rman;
struct rman br_mem_rman;
struct rman br_irq_rman;
STAILQ_HEAD(, bhndb_region) bus_regions;
struct mtx dw_steal_mtx;
struct bhndb_dw_alloc *dw_alloc;
size_t dwa_count;
bitstr_t *dwa_freelist;
bhndb_priority_t min_prio;
STAILQ_HEAD(,bhndb_intr_handler) bus_intrs;
};
static inline bool
bhndb_dw_all_free(struct bhndb_resources *br)
{
int bit;
bit_ffs(br->dwa_freelist, br->dwa_count, &bit);
return (bit == -1);
}
static inline struct bhndb_dw_alloc *
bhndb_dw_next_free(struct bhndb_resources *br)
{
struct bhndb_dw_alloc *dw_free;
int bit;
bit_ffc(br->dwa_freelist, br->dwa_count, &bit);
if (bit == -1)
return (NULL);
dw_free = &br->dw_alloc[bit];
KASSERT(LIST_EMPTY(&dw_free->refs),
("free list out of sync with refs"));
return (dw_free);
}
static inline bool
bhndb_dw_is_free(struct bhndb_resources *br, struct bhndb_dw_alloc *dwa)
{
bool is_free = LIST_EMPTY(&dwa->refs);
KASSERT(is_free == !bit_test(br->dwa_freelist, dwa->rnid),
("refs out of sync with free list"));
return (is_free);
}
#define BHNDB_LOCK_INIT(sc) \
mtx_init(&(sc)->sc_mtx, device_get_nameunit((sc)->dev), \
"bhndb resource allocator lock", MTX_DEF)
#define BHNDB_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
#define BHNDB_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx)
#define BHNDB_LOCK_ASSERT(sc, what) mtx_assert(&(sc)->sc_mtx, what)
#define BHNDB_LOCK_DESTROY(sc) mtx_destroy(&(sc)->sc_mtx)
#endif