Path: blob/main/sys/dev/bhnd/bhndb/bhndb_private.h
39536 views
/*-1* Copyright (c) 2015-2016 Landon Fuller <[email protected]>2* Copyright (c) 2017 The FreeBSD Foundation3* All rights reserved.4*5* Portions of this software were developed by Landon Fuller6* under sponsorship from the FreeBSD Foundation.7*8* Portions of this software were developed by Landon Fuller9* under sponsorship from the FreeBSD Foundation.10*11* Redistribution and use in source and binary forms, with or without12* modification, are permitted provided that the following conditions13* are met:14* 1. Redistributions of source code must retain the above copyright15* notice, this list of conditions and the following disclaimer,16* without modification.17* 2. Redistributions in binary form must reproduce at minimum a disclaimer18* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any19* redistribution must be conditioned upon including a substantially20* similar Disclaimer requirement for further binary redistribution.21*22* NO WARRANTY23* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS24* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT25* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY26* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL27* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,28* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF29* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS30* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER31* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)32* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF33* THE POSSIBILITY OF SUCH DAMAGES.34*35*/3637#ifndef _BHND_BHNDB_PRIVATE_H_38#define _BHND_BHNDB_PRIVATE_H_3940#include <sys/param.h>41#include <sys/bitstring.h>42#include <sys/bus.h>43#include <sys/systm.h>4445#include <machine/bus.h>46#include <sys/rman.h>47#include <machine/resource.h>4849#include "bhndbvar.h"5051/*52* Private bhndb(4) driver definitions.53*/5455struct bhndb_dw_alloc;56struct bhndb_intr_handler;57struct bhndb_region;58struct bhndb_resources;5960struct bhndb_resources *bhndb_alloc_resources(device_t dev,61device_t parent_dev,62const struct bhndb_hwcfg *cfg);6364void bhndb_free_resources(65struct bhndb_resources *br);6667int bhndb_add_resource_region(68struct bhndb_resources *br,69bhnd_addr_t addr, bhnd_size_t size,70bhndb_priority_t priority,71uint32_t alloc_flags,72const struct bhndb_regwin *static_regwin);7374int bhndb_find_resource_limits(75struct bhndb_resources *br,76struct resource *r, rman_res_t *start,77rman_res_t *end);7879struct bhndb_intr_handler *bhndb_alloc_intr_handler(device_t owner,80struct resource *r,81struct bhndb_intr_isrc *isrc);82void bhndb_free_intr_handler(83struct bhndb_intr_handler *ih);8485void bhndb_register_intr_handler(86struct bhndb_resources *br,87struct bhndb_intr_handler *ih);88void bhndb_deregister_intr_handler(89struct bhndb_resources *br,90struct bhndb_intr_handler *ih);91struct bhndb_intr_handler *bhndb_find_intr_handler(92struct bhndb_resources *br,93void *cookiep);9495bool bhndb_has_static_region_mapping(96struct bhndb_resources *br,97bhnd_addr_t addr, bhnd_size_t size);9899struct bhndb_region *bhndb_find_resource_region(100struct bhndb_resources *br,101bhnd_addr_t addr, bhnd_size_t size);102103struct bhndb_dw_alloc *bhndb_dw_find_resource(104struct bhndb_resources *dr,105struct resource *r);106107struct bhndb_dw_alloc *bhndb_dw_find_mapping(108struct bhndb_resources *br,109bhnd_addr_t addr, bhnd_size_t size);110111int bhndb_dw_retain(112struct bhndb_resources *br,113struct bhndb_dw_alloc *dwa,114struct resource *res);115116void bhndb_dw_release(117struct bhndb_resources *br,118struct bhndb_dw_alloc *dwa,119struct resource *res);120121int bhndb_dw_set_addr(device_t dev,122struct bhndb_resources *br,123struct bhndb_dw_alloc *dwa,124bus_addr_t addr, bus_size_t size);125126struct bhndb_dw_alloc *bhndb_dw_steal(struct bhndb_resources *br,127bus_addr_t *saved);128129void bhndb_dw_return_stolen(device_t dev,130struct bhndb_resources *br,131struct bhndb_dw_alloc *dwa,132bus_addr_t saved);133134const struct bhndb_hw_priority *bhndb_hw_priority_find_core(135const struct bhndb_hw_priority *table,136struct bhnd_core_info *core);137138const struct bhndb_port_priority *bhndb_hw_priorty_find_port(139const struct bhndb_hw_priority *table,140struct bhnd_core_info *core,141bhnd_port_type port_type, u_int port,142u_int region);143144/**145* Dynamic register window allocation reference.146*/147struct bhndb_dw_rentry {148struct resource *dw_res; /**< child resource */149LIST_ENTRY(bhndb_dw_rentry) dw_link;150};151152/**153* A dynamic register window allocation record.154*/155struct bhndb_dw_alloc {156const struct bhndb_regwin *win; /**< window definition */157struct resource *parent_res; /**< enclosing resource */158u_int rnid; /**< region identifier */159rman_res_t target; /**< the current window address, or 0x0 if unknown */160161LIST_HEAD(, bhndb_dw_rentry) refs; /**< references */162};163164/**165* A bus address region description.166*/167struct bhndb_region {168bhnd_addr_t addr; /**< start of mapped range */169bhnd_size_t size; /**< size of mapped range */170bhndb_priority_t priority; /**< direct resource allocation priority */171uint32_t alloc_flags; /**< resource allocation flags (@see bhndb_alloc_flags) */172const struct bhndb_regwin *static_regwin; /**< fixed mapping regwin, if any */173174STAILQ_ENTRY(bhndb_region) link;175};176177/**178* Attached interrupt handler state179*/180struct bhndb_intr_handler {181device_t ih_owner; /**< child device */182struct resource *ih_res; /**< child resource */183void *ih_cookiep; /**< hostb-assigned cookiep, or NULL if bus_setup_intr() incomplete. */184struct bhndb_intr_isrc *ih_isrc; /**< host interrupt source routing the child's interrupt */185bool ih_active; /**< handler has been registered via bhndb_register_intr_handler */186187STAILQ_ENTRY(bhndb_intr_handler) ih_link;188};189190/**191* BHNDB resource allocation state.192*/193struct bhndb_resources {194device_t dev; /**< bridge device */195const struct bhndb_hwcfg *cfg; /**< hardware configuration */196197struct bhndb_host_resources *res; /**< host resources, or NULL if not allocated */198199struct rman ht_mem_rman; /**< host memory manager */200struct rman br_mem_rman; /**< bridged memory manager */201struct rman br_irq_rman; /**< bridged irq manager */202203STAILQ_HEAD(, bhndb_region) bus_regions; /**< bus region descriptors */204205struct mtx dw_steal_mtx; /**< spinlock must be held when stealing a dynamic window allocation */206struct bhndb_dw_alloc *dw_alloc; /**< dynamic window allocation records */207size_t dwa_count; /**< number of dynamic windows available. */208bitstr_t *dwa_freelist; /**< dynamic window free list */209bhndb_priority_t min_prio; /**< minimum resource priority required to210allocate a dynamic window */211212STAILQ_HEAD(,bhndb_intr_handler) bus_intrs; /**< attached child interrupt handlers */213};214215/**216* Returns true if the all dynamic windows are marked free, false217* otherwise.218*219* @param br The resource state to check.220*/221static inline bool222bhndb_dw_all_free(struct bhndb_resources *br)223{224int bit;225bit_ffs(br->dwa_freelist, br->dwa_count, &bit);226return (bit == -1);227}228229/**230* Find the next free dynamic window region in @p br.231*232* @param br The resource state to search.233*/234static inline struct bhndb_dw_alloc *235bhndb_dw_next_free(struct bhndb_resources *br)236{237struct bhndb_dw_alloc *dw_free;238int bit;239240bit_ffc(br->dwa_freelist, br->dwa_count, &bit);241if (bit == -1)242return (NULL);243244dw_free = &br->dw_alloc[bit];245246KASSERT(LIST_EMPTY(&dw_free->refs),247("free list out of sync with refs"));248249return (dw_free);250}251252/**253* Returns true if a dynamic window allocation is marked as free.254*255* @param br The resource state owning @p dwa.256* @param dwa The dynamic window allocation record to be checked.257*/258static inline bool259bhndb_dw_is_free(struct bhndb_resources *br, struct bhndb_dw_alloc *dwa)260{261bool is_free = LIST_EMPTY(&dwa->refs);262263KASSERT(is_free == !bit_test(br->dwa_freelist, dwa->rnid),264("refs out of sync with free list"));265266return (is_free);267}268269#define BHNDB_LOCK_INIT(sc) \270mtx_init(&(sc)->sc_mtx, device_get_nameunit((sc)->dev), \271"bhndb resource allocator lock", MTX_DEF)272#define BHNDB_LOCK(sc) mtx_lock(&(sc)->sc_mtx)273#define BHNDB_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx)274#define BHNDB_LOCK_ASSERT(sc, what) mtx_assert(&(sc)->sc_mtx, what)275#define BHNDB_LOCK_DESTROY(sc) mtx_destroy(&(sc)->sc_mtx)276277#endif /* _BHND_BHNDB_PRIVATE_H_ */278279280