/*-1* SPDX-License-Identifier: BSD-2-Clause2*3* Copyright (c) 2015-2016 Landon Fuller <[email protected]>4* Copyright (c) 2017 The FreeBSD Foundation5* All rights reserved.6*7* Portions of this software were developed by Landon Fuller8* under sponsorship from the FreeBSD Foundation.9*10* Redistribution and use in source and binary forms, with or without11* modification, are permitted provided that the following conditions12* are met:13* 1. Redistributions of source code must retain the above copyright14* notice, this list of conditions and the following disclaimer,15* without modification.16* 2. Redistributions in binary form must reproduce at minimum a disclaimer17* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any18* redistribution must be conditioned upon including a substantially19* similar Disclaimer requirement for further binary redistribution.20*21* NO WARRANTY22* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS23* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT24* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY25* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL26* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,27* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF28* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS29* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER30* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)31* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF32* THE POSSIBILITY OF SUCH DAMAGES.33*34*/3536#ifndef _BHND_BHND_H_37#define _BHND_BHND_H_3839#include <sys/param.h>40#include <sys/bus.h>41#include <sys/lock.h>42#include <sys/mutex.h>4344#include <machine/bus.h>4546#include "bhnd_ids.h"47#include "bhnd_types.h"48#include "bhnd_erom_types.h"49#include "bhnd_debug.h"50#include "bhnd_bus_if.h"51#include "bhnd_match.h"5253#include "nvram/bhnd_nvram.h"5455#define BHND_CHIPID_MAX_NAMELEN 32 /**< maximum buffer required for a56bhnd_format_chip_id() */5758/**59* bhnd child instance variables60*/61enum bhnd_device_vars {62BHND_IVAR_VENDOR, /**< Designer's JEP-106 manufacturer ID. */63BHND_IVAR_DEVICE, /**< Part number */64BHND_IVAR_HWREV, /**< Core revision */65BHND_IVAR_DEVICE_CLASS, /**< Core class (@sa bhnd_devclass_t) */66BHND_IVAR_VENDOR_NAME, /**< Core vendor name */67BHND_IVAR_DEVICE_NAME, /**< Core name */68BHND_IVAR_CORE_INDEX, /**< Bus-assigned core number */69BHND_IVAR_CORE_UNIT, /**< Bus-assigned core unit number,70assigned sequentially (starting at 0) for71each vendor/device pair. */72BHND_IVAR_PMU_INFO, /**< Internal bus-managed PMU state */73};7475/**76* bhnd device probe priority bands.77*/78enum {79BHND_PROBE_ROOT = 0, /**< Nexus or host bridge */80BHND_PROBE_BUS = 1000, /**< Buses and bridges */81BHND_PROBE_CPU = 2000, /**< CPU devices */82BHND_PROBE_INTERRUPT = 3000, /**< Interrupt controllers. */83BHND_PROBE_TIMER = 4000, /**< Timers and clocks. */84BHND_PROBE_RESOURCE = 5000, /**< Resource discovery (including NVRAM/SPROM) */85BHND_PROBE_DEFAULT = 6000, /**< Default device priority */86};8788/**89* Constants defining fine grained ordering within a BHND_PROBE_* priority band.90*91* Example:92* @code93* BHND_PROBE_BUS + BHND_PROBE_ORDER_FIRST94* @endcode95*/96enum {97BHND_PROBE_ORDER_FIRST = 0,98BHND_PROBE_ORDER_EARLY = 25,99BHND_PROBE_ORDER_MIDDLE = 50,100BHND_PROBE_ORDER_LATE = 75,101BHND_PROBE_ORDER_LAST = 100102103};104105/**106* Per-core IOCTL flags common to all bhnd(4) cores.107*/108enum {109BHND_IOCTL_BIST = 0x8000, /**< Initiate a built-in self-test (BIST). Must be cleared110after BIST results are read via BHND_IOST_BIST_* */111BHND_IOCTL_PME = 0x4000, /**< Enable posting of power management events by the core. */112BHND_IOCTL_CFLAGS = 0x3FFC, /**< Reserved for core-specific ioctl flags. */113BHND_IOCTL_CLK_FORCE = 0x0002, /**< Force disable of clock gating, resulting in all clocks114being distributed within the core. Should be set when115asserting/deasserting reset to ensure the reset signal116fully propagates to the entire core. */117BHND_IOCTL_CLK_EN = 0x0001, /**< If cleared, the core clock will be disabled. Should be118set during normal operation, and cleared when the core is119held in reset. */120};121122/**123* Per-core IOST flags common to all bhnd(4) cores.124*/125enum {126BHND_IOST_BIST_DONE = 0x8000, /**< Set upon BIST completion (see BHND_IOCTL_BIST), and cleared127if 0 is written to BHND_IOCTL_BIST. */128BHND_IOST_BIST_FAIL = 0x4000, /**< Set upon detection of a BIST error; the value is unspecified129if BIST has not completed and BHND_IOST_BIST_DONE is not set. */130BHND_IOST_CLK = 0x2000, /**< Set if the core has requested that gated clocks be enabled, or131cleared otherwise. The value is undefined if a core does not132support clock gating. */133BHND_IOST_DMA64 = 0x1000, /**< Set if this core supports 64-bit DMA */134BHND_IOST_CFLAGS = 0x0FFC, /**< Reserved for core-specific status flags. */135};136137/*138* Simplified accessors for bhnd device ivars139*/140#define BHND_ACCESSOR(var, ivar, type) \141__BUS_ACCESSOR(bhnd, var, BHND, ivar, type)142143BHND_ACCESSOR(vendor, VENDOR, uint16_t);144BHND_ACCESSOR(device, DEVICE, uint16_t);145BHND_ACCESSOR(hwrev, HWREV, uint8_t);146BHND_ACCESSOR(class, DEVICE_CLASS, bhnd_devclass_t);147BHND_ACCESSOR(vendor_name, VENDOR_NAME, const char *);148BHND_ACCESSOR(device_name, DEVICE_NAME, const char *);149BHND_ACCESSOR(core_index, CORE_INDEX, u_int);150BHND_ACCESSOR(core_unit, CORE_UNIT, int);151BHND_ACCESSOR(pmu_info, PMU_INFO, void *);152153#undef BHND_ACCESSOR154155/**156* A bhnd(4) board descriptor.157*/158struct bhnd_board_info {159uint16_t board_vendor; /**< Board vendor (PCI-SIG vendor ID).160*161* On PCI devices, this will default to162* the PCI subsystem vendor ID, but may163* be overridden by the 'boardtype'164* NVRAM variable.165*166* On SoCs, this will default to167* PCI_VENDOR_BROADCOM, but may be168* overridden by the 'boardvendor'169* NVRAM variable.170*/171uint16_t board_type; /**< Board type (See BHND_BOARD_*)172*173* This value is usually a174* Broadcom-assigned reference board175* identifier (see BHND_BOARD_*), but176* may be set to an arbitrary value177* assigned by the board vendor.178*179* On PCI devices, this will default180* to the PCI subsystem ID, but may be181* overridden by the 'boardtype'182* NVRAM variable.183*184* On SoCs, this will always be185* populated with the value of the186* 'boardtype' NVRAM variable.187*/188uint16_t board_devid; /**< Board device ID.189*190* On PCI devices, this will default191* to the PCI device ID, but may192* be overridden by the 'devid'193* NVRAM variable.194*/195uint16_t board_rev; /**< Board revision. */196uint8_t board_srom_rev; /**< Board SROM format revision */197198uint32_t board_flags; /**< Board flags (see BHND_BFL_*) */199uint32_t board_flags2; /**< Board flags 2 (see BHND_BFL2_*) */200uint32_t board_flags3; /**< Board flags 3 (see BHND_BFL3_*) */201};202203/**204* Chip Identification205*206* This is read from the ChipCommon ID register; on earlier bhnd(4) devices207* where ChipCommon is unavailable, known values must be supplied.208*/209struct bhnd_chipid {210uint16_t chip_id; /**< chip id (BHND_CHIPID_*) */211uint8_t chip_rev; /**< chip revision */212uint8_t chip_pkg; /**< chip package (BHND_PKGID_*) */213uint8_t chip_type; /**< chip type (BHND_CHIPTYPE_*) */214uint32_t chip_caps; /**< chip capabilities (BHND_CAP_*) */215216bhnd_addr_t enum_addr; /**< chip_type-specific enumeration217* address; either the siba(4) base218* core register block, or the bcma(4)219* EROM core address. */220221uint8_t ncores; /**< number of cores, if known. 0 if222* not available. */223};224225/**226* Chip capabilities227*/228enum bhnd_cap {229BHND_CAP_BP64 = (1<<0), /**< Backplane supports 64-bit230* addressing */231BHND_CAP_PMU = (1<<1), /**< PMU is present */232};233234/**235* A bhnd(4) core descriptor.236*/237struct bhnd_core_info {238uint16_t vendor; /**< JEP-106 vendor (BHND_MFGID_*) */239uint16_t device; /**< device */240uint16_t hwrev; /**< hardware revision */241u_int core_idx; /**< bus-assigned core index */242int unit; /**< bus-assigned core unit */243};244245/**246* bhnd(4) DMA address widths.247*/248typedef enum {249BHND_DMA_ADDR_30BIT = 30, /**< 30-bit DMA */250BHND_DMA_ADDR_32BIT = 32, /**< 32-bit DMA */251BHND_DMA_ADDR_64BIT = 64, /**< 64-bit DMA */252} bhnd_dma_addrwidth;253254/**255* Convert an address width (in bits) to its corresponding mask.256*/257#define BHND_DMA_ADDR_BITMASK(_width) \258((_width >= 64) ? ~0ULL : \259(_width == 0) ? 0x0 : \260((1ULL << (_width)) - 1)) \261262/**263* bhnd(4) DMA address translation descriptor.264*/265struct bhnd_dma_translation {266/**267* Host-to-device physical address translation.268*269* This may be added to the host physical address to produce a device270* DMA address.271*/272bhnd_addr_t base_addr;273274/**275* Device-addressable address mask.276*277* This defines the device's DMA address range, excluding any bits278* reserved for mapping the address to the base_addr.279*/280bhnd_addr_t addr_mask;281282/**283* Device-addressable extended address mask.284*285* If a per-core bhnd(4) DMA engine supports the 'addrext' control286* field, it can be used to provide address bits excluded by addr_mask.287*288* Support for DMA extended address changes – including coordination289* with the core providing DMA translation – is handled transparently by290* the DMA engine. For example, on PCI(e) Wi-Fi chipsets, the Wi-Fi291* core DMA engine will (in effect) update the PCI core's DMA292* sbtopcitranslation base address to map the full address prior to293* performing a DMA transaction.294*/295bhnd_addr_t addrext_mask;296297/**298* Translation flags (see bhnd_dma_translation_flags).299*/300uint32_t flags;301};302#define BHND_DMA_TRANSLATION_TABLE_END { 0, 0, 0, 0 }303304#define BHND_DMA_IS_TRANSLATION_TABLE_END(_dt) \305((_dt)->base_addr == 0 && (_dt)->addr_mask == 0 && \306(_dt)->addrext_mask == 0 && (_dt)->flags == 0)307308/**309* bhnd(4) DMA address translation flags.310*/311enum bhnd_dma_translation_flags {312/**313* The translation remaps the device's physical address space.314*315* This is used in conjunction with BHND_DMA_TRANSLATION_BYTESWAPPED to316* define a DMA translation that provides byteswapped access to317* physical memory on big-endian MIPS SoCs.318*/319BHND_DMA_TRANSLATION_PHYSMAP = (1<<0),320321/**322* Provides a byte-swapped mapping; write requests will be byte-swapped323* before being written to memory, and read requests will be324* byte-swapped before being returned.325*326* This is primarily used to perform efficient byte swapping of DMA327* data on embedded MIPS SoCs executing in big-endian mode.328*/329BHND_DMA_TRANSLATION_BYTESWAPPED = (1<<1),330};331332/**333* A bhnd(4) bus resource.334*335* This provides an abstract interface to per-core resources that may require336* bus-level remapping of address windows prior to access.337*/338struct bhnd_resource {339struct resource *res; /**< the system resource. */340bool direct; /**< false if the resource requires341* bus window remapping before it342* is MMIO accessible. */343};344345/** Wrap the active resource @p _r in a bhnd_resource structure */346#define BHND_DIRECT_RESOURCE(_r) ((struct bhnd_resource) { \347.res = (_r), \348.direct = true, \349})350351/**352* Device quirk table descriptor.353*/354struct bhnd_device_quirk {355struct bhnd_device_match desc; /**< device match descriptor */356uint32_t quirks; /**< quirk flags */357};358359#define BHND_CORE_QUIRK(_rev, _flags) \360{{ BHND_MATCH_CORE_REV(_rev) }, (_flags) }361362#define BHND_CHIP_QUIRK(_chip, _rev, _flags) \363{{ BHND_MATCH_CHIP_IR(BCM ## _chip, _rev) }, (_flags) }364365#define BHND_PKG_QUIRK(_chip, _pkg, _flags) \366{{ BHND_MATCH_CHIP_IP(BCM ## _chip, BCM ## _chip ## _pkg) }, (_flags) }367368#define BHND_BOARD_QUIRK(_board, _flags) \369{{ BHND_MATCH_BOARD_TYPE(_board) }, \370(_flags) }371#define BHND_DEVICE_QUIRK_END { { BHND_MATCH_ANY }, 0 }372#define BHND_DEVICE_QUIRK_IS_END(_q) \373(((_q)->desc.m.match_flags == 0) && (_q)->quirks == 0)374375enum {376BHND_DF_ANY = 0,377BHND_DF_HOSTB = (1<<0), /**< core is serving as the bus' host378* bridge. implies BHND_DF_ADAPTER */379BHND_DF_SOC = (1<<1), /**< core is attached to a native380bus (BHND_ATTACH_NATIVE) */381BHND_DF_ADAPTER = (1<<2), /**< core is attached to a bridged382* adapter (BHND_ATTACH_ADAPTER) */383};384385/** Device probe table descriptor */386struct bhnd_device {387const struct bhnd_device_match core; /**< core match descriptor */388const char *desc; /**< device description, or NULL. */389const struct bhnd_device_quirk *quirks_table; /**< quirks table for this device, or NULL */390uint32_t device_flags; /**< required BHND_DF_* flags */391};392393#define _BHND_DEVICE(_vendor, _device, _desc, _quirks, \394_flags, ...) \395{ { BHND_MATCH_CORE(BHND_MFGID_ ## _vendor, \396BHND_COREID_ ## _device) }, _desc, _quirks, \397_flags }398399#define BHND_DEVICE(_vendor, _device, _desc, _quirks, ...) \400_BHND_DEVICE(_vendor, _device, _desc, _quirks, \401## __VA_ARGS__, 0)402#define BHND_DEVICE_END { { BHND_MATCH_ANY }, NULL, NULL, 0 }403#define BHND_DEVICE_IS_END(_d) \404(BHND_MATCH_IS_ANY(&(_d)->core) && (_d)->desc == NULL)405406/**407* bhnd device sort order.408*/409typedef enum {410BHND_DEVICE_ORDER_ATTACH, /**< sort by bhnd(4) device attach order;411child devices should be probed/attached412in this order */413BHND_DEVICE_ORDER_DETACH, /**< sort by bhnd(4) device detach order;414child devices should be detached, suspended,415and shutdown in this order */416} bhnd_device_order;417418/**419* A registry of bhnd service providers.420*/421struct bhnd_service_registry {422STAILQ_HEAD(,bhnd_service_entry) entries; /**< registered services */423struct mtx lock; /**< state lock */424};425426/**427* bhnd service provider flags.428*/429enum {430BHND_SPF_INHERITED = (1<<0), /**< service provider reference was inherited from431a parent bus, and should be deregistered when the432last active reference is released */433};434435const char *bhnd_vendor_name(uint16_t vendor);436const char *bhnd_port_type_name(bhnd_port_type port_type);437const char *bhnd_nvram_src_name(bhnd_nvram_src nvram_src);438439const char *bhnd_find_core_name(uint16_t vendor,440uint16_t device);441bhnd_devclass_t bhnd_find_core_class(uint16_t vendor,442uint16_t device);443444const char *bhnd_core_name(const struct bhnd_core_info *ci);445bhnd_devclass_t bhnd_core_class(const struct bhnd_core_info *ci);446447int bhnd_format_chip_id(char *buffer, size_t size,448uint16_t chip_id);449450device_t bhnd_bus_match_child(device_t bus,451const struct bhnd_core_match *desc);452453device_t bhnd_bus_find_child(device_t bus,454bhnd_devclass_t class, int unit);455456int bhnd_bus_get_children(device_t bus,457device_t **devlistp, int *devcountp,458bhnd_device_order order);459460void bhnd_bus_free_children(device_t *devlist);461462int bhnd_bus_probe_children(device_t bus);463464int bhnd_sort_devices(device_t *devlist,465size_t devcount, bhnd_device_order order);466467device_t bhnd_find_bridge_root(device_t dev,468devclass_t bus_class);469470const struct bhnd_core_info *bhnd_match_core(471const struct bhnd_core_info *cores,472u_int num_cores,473const struct bhnd_core_match *desc);474475const struct bhnd_core_info *bhnd_find_core(476const struct bhnd_core_info *cores,477u_int num_cores, bhnd_devclass_t class);478479struct bhnd_core_match bhnd_core_get_match_desc(480const struct bhnd_core_info *core);481482bool bhnd_cores_equal(483const struct bhnd_core_info *lhs,484const struct bhnd_core_info *rhs);485486bool bhnd_core_matches(487const struct bhnd_core_info *core,488const struct bhnd_core_match *desc);489490bool bhnd_chip_matches(491const struct bhnd_chipid *chipid,492const struct bhnd_chip_match *desc);493494bool bhnd_board_matches(495const struct bhnd_board_info *info,496const struct bhnd_board_match *desc);497498bool bhnd_hwrev_matches(uint16_t hwrev,499const struct bhnd_hwrev_match *desc);500501bool bhnd_device_matches(device_t dev,502const struct bhnd_device_match *desc);503504const struct bhnd_device *bhnd_device_lookup(device_t dev,505const struct bhnd_device *table,506size_t entry_size);507508uint32_t bhnd_device_quirks(device_t dev,509const struct bhnd_device *table,510size_t entry_size);511512struct bhnd_core_info bhnd_get_core_info(device_t dev);513514int bhnd_alloc_resources(device_t dev,515struct resource_spec *rs,516struct bhnd_resource **res);517518void bhnd_release_resources(device_t dev,519const struct resource_spec *rs,520struct bhnd_resource **res);521522void bhnd_set_custom_core_desc(device_t dev,523const char *name);524void bhnd_set_default_core_desc(device_t dev);525526void bhnd_set_default_bus_desc(device_t dev,527const struct bhnd_chipid *chip_id);528529int bhnd_nvram_getvar_str(device_t dev,530const char *name, char *buf, size_t len,531size_t *rlen);532533int bhnd_nvram_getvar_uint(device_t dev,534const char *name, void *value, int width);535int bhnd_nvram_getvar_uint8(device_t dev,536const char *name, uint8_t *value);537int bhnd_nvram_getvar_uint16(device_t dev,538const char *name, uint16_t *value);539int bhnd_nvram_getvar_uint32(device_t dev,540const char *name, uint32_t *value);541542int bhnd_nvram_getvar_int(device_t dev,543const char *name, void *value, int width);544int bhnd_nvram_getvar_int8(device_t dev,545const char *name, int8_t *value);546int bhnd_nvram_getvar_int16(device_t dev,547const char *name, int16_t *value);548int bhnd_nvram_getvar_int32(device_t dev,549const char *name, int32_t *value);550551int bhnd_nvram_getvar_array(device_t dev,552const char *name, void *buf, size_t count,553bhnd_nvram_type type);554555int bhnd_service_registry_init(556struct bhnd_service_registry *bsr);557int bhnd_service_registry_fini(558struct bhnd_service_registry *bsr);559int bhnd_service_registry_add(560struct bhnd_service_registry *bsr,561device_t provider,562bhnd_service_t service,563uint32_t flags);564int bhnd_service_registry_remove(565struct bhnd_service_registry *bsr,566device_t provider,567bhnd_service_t service);568device_t bhnd_service_registry_retain(569struct bhnd_service_registry *bsr,570bhnd_service_t service);571bool bhnd_service_registry_release(572struct bhnd_service_registry *bsr,573device_t provider,574bhnd_service_t service);575576int bhnd_bus_generic_register_provider(577device_t dev, device_t child,578device_t provider, bhnd_service_t service);579int bhnd_bus_generic_deregister_provider(580device_t dev, device_t child,581device_t provider, bhnd_service_t service);582device_t bhnd_bus_generic_retain_provider(device_t dev,583device_t child, bhnd_service_t service);584void bhnd_bus_generic_release_provider(device_t dev,585device_t child, device_t provider,586bhnd_service_t service);587588int bhnd_bus_generic_sr_register_provider(589device_t dev, device_t child,590device_t provider, bhnd_service_t service);591int bhnd_bus_generic_sr_deregister_provider(592device_t dev, device_t child,593device_t provider, bhnd_service_t service);594device_t bhnd_bus_generic_sr_retain_provider(device_t dev,595device_t child, bhnd_service_t service);596void bhnd_bus_generic_sr_release_provider(device_t dev,597device_t child, device_t provider,598bhnd_service_t service);599600bool bhnd_bus_generic_is_hw_disabled(device_t dev,601device_t child);602bool bhnd_bus_generic_is_region_valid(device_t dev,603device_t child, bhnd_port_type type,604u_int port, u_int region);605int bhnd_bus_generic_get_nvram_var(device_t dev,606device_t child, const char *name,607void *buf, size_t *size,608bhnd_nvram_type type);609const struct bhnd_chipid *bhnd_bus_generic_get_chipid(device_t dev,610device_t child);611int bhnd_bus_generic_get_dma_translation(612device_t dev, device_t child, u_int width,613uint32_t flags, bus_dma_tag_t *dmat,614struct bhnd_dma_translation *translation);615int bhnd_bus_generic_read_board_info(device_t dev,616device_t child,617struct bhnd_board_info *info);618struct bhnd_resource *bhnd_bus_generic_alloc_resource (device_t dev,619device_t child, int type, int *rid,620rman_res_t start, rman_res_t end,621rman_res_t count, u_int flags);622int bhnd_bus_generic_release_resource (device_t dev,623device_t child, int type, int rid,624struct bhnd_resource *r);625int bhnd_bus_generic_activate_resource (device_t dev,626device_t child, int type, int rid,627struct bhnd_resource *r);628int bhnd_bus_generic_deactivate_resource (device_t dev,629device_t child, int type, int rid,630struct bhnd_resource *r);631uintptr_t bhnd_bus_generic_get_intr_domain(device_t dev,632device_t child, bool self);633634/**635* Return the bhnd(4) bus driver's device enumeration parser class636*637* @param driver A bhnd bus driver instance.638*/639static inline bhnd_erom_class_t *640bhnd_driver_get_erom_class(driver_t *driver)641{642return (BHND_BUS_GET_EROM_CLASS(driver));643}644645/**646* Return the active host bridge core for the bhnd bus, if any, or NULL if647* not found.648*649* @param dev A bhnd bus device.650*/651static inline device_t652bhnd_bus_find_hostb_device(device_t dev) {653return (BHND_BUS_FIND_HOSTB_DEVICE(dev));654}655656/**657* Register a provider for a given @p service.658*659* @param dev The device to register as a service provider660* with its parent bus.661* @param service The service for which @p dev will be registered.662*663* @retval 0 success664* @retval EEXIST if an entry for @p service already exists.665* @retval non-zero if registering @p dev otherwise fails, a regular666* unix error code will be returned.667*/668static inline int669bhnd_register_provider(device_t dev, bhnd_service_t service)670{671return (BHND_BUS_REGISTER_PROVIDER(device_get_parent(dev), dev, dev,672service));673}674675/**676* Attempt to remove a service provider registration for @p dev.677*678* @param dev The device to be deregistered as a service provider.679* @param service The service for which @p dev will be deregistered, or680* BHND_SERVICE_INVALID to remove all service registrations681* for @p dev.682*683* @retval 0 success684* @retval EBUSY if active references to @p dev exist; @see685* bhnd_retain_provider() and bhnd_release_provider().686*/687static inline int688bhnd_deregister_provider(device_t dev, bhnd_service_t service)689{690return (BHND_BUS_DEREGISTER_PROVIDER(device_get_parent(dev), dev, dev,691service));692}693694/**695* Retain and return a reference to the registered @p service provider, if any.696*697* @param dev The requesting device.698* @param service The service for which a provider should be returned.699*700* On success, the caller assumes ownership the returned provider, and701* is responsible for releasing this reference via702* BHND_BUS_RELEASE_PROVIDER().703*704* @retval device_t success705* @retval NULL if no provider is registered for @p service.706*/707static inline device_t708bhnd_retain_provider(device_t dev, bhnd_service_t service)709{710return (BHND_BUS_RETAIN_PROVIDER(device_get_parent(dev), dev,711service));712}713714/**715* Release a reference to a provider device previously returned by716* bhnd_retain_provider().717*718* @param dev The requesting device.719* @param provider The provider to be released.720* @param service The service for which @p provider was previously retained.721*/722static inline void723bhnd_release_provider(device_t dev, device_t provider,724bhnd_service_t service)725{726return (BHND_BUS_RELEASE_PROVIDER(device_get_parent(dev), dev,727provider, service));728}729730/**731* Return true if the hardware components required by @p dev are known to be732* unpopulated or otherwise unusable.733*734* In some cases, enumerated devices may have pins that are left floating, or735* the hardware may otherwise be non-functional; this method allows a parent736* device to explicitly specify if a successfully enumerated @p dev should737* be disabled.738*739* @param dev A bhnd bus child device.740*/741static inline bool742bhnd_is_hw_disabled(device_t dev) {743return (BHND_BUS_IS_HW_DISABLED(device_get_parent(dev), dev));744}745746/**747* Return the BHND chip identification info for the bhnd bus.748*749* @param dev A bhnd bus child device.750*/751static inline const struct bhnd_chipid *752bhnd_get_chipid(device_t dev) {753return (BHND_BUS_GET_CHIPID(device_get_parent(dev), dev));754};755756/**757* Read the current value of a bhnd(4) device's per-core I/O control register.758*759* @param dev The bhnd bus child device to be queried.760* @param[out] ioctl On success, the I/O control register value.761*762* @retval 0 success763* @retval EINVAL If @p child is not a direct child of @p dev.764* @retval ENODEV If agent/config space for @p child is unavailable.765* @retval non-zero If reading the IOCTL register otherwise fails, a regular766* unix error code will be returned.767*/768static inline int769bhnd_read_ioctl(device_t dev, uint16_t *ioctl)770{771return (BHND_BUS_READ_IOCTL(device_get_parent(dev), dev, ioctl));772}773774/**775* Write @p value and @p mask to a bhnd(4) device's per-core I/O control776* register.777*778* @param dev The bhnd bus child device for which the IOCTL register will be779* written.780* @param value The value to be written (see BHND_IOCTL_*).781* @param mask Only the bits defined by @p mask will be updated from @p value.782*783* @retval 0 success784* @retval EINVAL If @p child is not a direct child of @p dev.785* @retval ENODEV If agent/config space for @p child is unavailable.786* @retval non-zero If writing the IOCTL register otherwise fails, a regular787* unix error code will be returned.788*/789static inline int790bhnd_write_ioctl(device_t dev, uint16_t value, uint16_t mask)791{792return (BHND_BUS_WRITE_IOCTL(device_get_parent(dev), dev, value, mask));793}794795/**796* Read the current value of a bhnd(4) device's per-core I/O status register.797*798* @param dev The bhnd bus child device to be queried.799* @param[out] iost On success, the I/O status register value.800*801* @retval 0 success802* @retval EINVAL If @p child is not a direct child of @p dev.803* @retval ENODEV If agent/config space for @p child is unavailable.804* @retval non-zero If reading the IOST register otherwise fails, a regular805* unix error code will be returned.806*/807static inline int808bhnd_read_iost(device_t dev, uint16_t *iost)809{810return (BHND_BUS_READ_IOST(device_get_parent(dev), dev, iost));811}812813/**814* Return true if the given bhnd device's hardware is currently held815* in a RESET state or otherwise not clocked (BHND_IOCTL_CLK_EN).816*817* @param dev The device to query.818*819* @retval true If @p dev is held in RESET or not clocked (BHND_IOCTL_CLK_EN),820* or an error occurred determining @p dev's hardware state.821* @retval false If @p dev is clocked and is not held in RESET.822*/823static inline bool824bhnd_is_hw_suspended(device_t dev)825{826return (BHND_BUS_IS_HW_SUSPENDED(device_get_parent(dev), dev));827}828829/**830* Place the bhnd(4) device's hardware into a low-power RESET state with831* the @p reset_ioctl I/O control flags set, and then bring the hardware out of832* RESET with the @p ioctl I/O control flags set.833*834* Any clock or resource PMU requests previously made by @p child will be835* invalidated.836*837* @param dev The device to be reset.838* @param ioctl Device-specific I/O control flags to be set when bringing839* the core out of its RESET state (see BHND_IOCTL_*).840* @param reset_ioctl Device-specific I/O control flags to be set when placing841* the core into its RESET state.842*843* @retval 0 success844* @retval non-zero error845*/846static inline int847bhnd_reset_hw(device_t dev, uint16_t ioctl, uint16_t reset_ioctl)848{849return (BHND_BUS_RESET_HW(device_get_parent(dev), dev, ioctl,850reset_ioctl));851}852853/**854* Suspend @p child's hardware in a low-power reset state.855*856* Any clock or resource PMU requests previously made by @p dev will be857* invalidated.858*859* The hardware may be brought out of reset via bhnd_reset_hw().860*861* @param dev The device to be suspended.862*863* @retval 0 success864* @retval non-zero error865*/866static inline int867bhnd_suspend_hw(device_t dev, uint16_t ioctl)868{869return (BHND_BUS_SUSPEND_HW(device_get_parent(dev), dev, ioctl));870}871872/**873* Return the BHND attachment type of the parent bhnd bus.874*875* @param dev A bhnd bus child device.876*877* @retval BHND_ATTACH_ADAPTER if the bus is resident on a bridged adapter,878* such as a WiFi chipset.879* @retval BHND_ATTACH_NATIVE if the bus provides hardware services (clock,880* CPU, etc) to a directly attached native host.881*/882static inline bhnd_attach_type883bhnd_get_attach_type (device_t dev) {884return (BHND_BUS_GET_ATTACH_TYPE(device_get_parent(dev), dev));885}886887/**888* Find the best available DMA address translation capable of mapping a889* physical host address to a BHND DMA device address of @p width with890* @p flags.891*892* @param dev A bhnd bus child device.893* @param width The address width within which the translation window must894* reside (see BHND_DMA_ADDR_*).895* @param flags Required translation flags (see BHND_DMA_TRANSLATION_*).896* @param[out] dmat On success, will be populated with a DMA tag specifying the897* @p translation DMA address restrictions. This argment may be NULL if the DMA898* tag is not desired.899* the set of valid host DMA addresses reachable via @p translation.900* @param[out] translation On success, will be populated with a DMA address901* translation descriptor for @p child. This argment may be NULL if the902* descriptor is not desired.903*904* @retval 0 success905* @retval ENODEV If DMA is not supported.906* @retval ENOENT If no DMA translation matching @p width and @p flags is907* available.908* @retval non-zero If determining the DMA address translation for @p child909* otherwise fails, a regular unix error code will be returned.910*/911static inline int912bhnd_get_dma_translation(device_t dev, u_int width, uint32_t flags,913bus_dma_tag_t *dmat, struct bhnd_dma_translation *translation)914{915return (BHND_BUS_GET_DMA_TRANSLATION(device_get_parent(dev), dev, width,916flags, dmat, translation));917}918919/**920* Attempt to read the BHND board identification from the bhnd bus.921*922* This relies on NVRAM access, and will fail if a valid NVRAM device cannot923* be found, or is not yet attached.924*925* @param dev The bhnd device requesting board info.926* @param[out] info On success, will be populated with the bhnd(4) device's927* board information.928*929* @retval 0 success930* @retval ENODEV No valid NVRAM source could be found.931* @retval non-zero If reading @p name otherwise fails, a regular unix932* error code will be returned.933*/934static inline int935bhnd_read_board_info(device_t dev, struct bhnd_board_info *info)936{937return (BHND_BUS_READ_BOARD_INFO(device_get_parent(dev), dev, info));938}939940/**941* Return the number of interrupt lines assigned to @p dev.942*943* @param dev A bhnd bus child device.944*/945static inline u_int946bhnd_get_intr_count(device_t dev)947{948return (BHND_BUS_GET_INTR_COUNT(device_get_parent(dev), dev));949}950951/**952* Get the backplane interrupt vector of the @p intr line attached to @p dev.953*954* @param dev A bhnd bus child device.955* @param intr The index of the interrupt line being queried.956* @param[out] ivec On success, the assigned hardware interrupt vector will be957* written to this pointer.958*959* On bcma(4) devices, this returns the OOB bus line assigned to the960* interrupt.961*962* On siba(4) devices, this returns the target OCP slave flag number assigned963* to the interrupt.964*965* @retval 0 success966* @retval ENXIO If @p intr exceeds the number of interrupt lines967* assigned to @p child.968*/969static inline int970bhnd_get_intr_ivec(device_t dev, u_int intr, u_int *ivec)971{972return (BHND_BUS_GET_INTR_IVEC(device_get_parent(dev), dev, intr,973ivec));974}975976/**977* Map the given @p intr to an IRQ number; until unmapped, this IRQ may be used978* to allocate a resource of type SYS_RES_IRQ.979*980* On success, the caller assumes ownership of the interrupt mapping, and981* is responsible for releasing the mapping via bhnd_unmap_intr().982*983* @param dev The requesting device.984* @param intr The interrupt being mapped.985* @param[out] irq On success, the bus interrupt value mapped for @p intr.986*987* @retval 0 If an interrupt was assigned.988* @retval non-zero If mapping an interrupt otherwise fails, a regular989* unix error code will be returned.990*/991static inline int992bhnd_map_intr(device_t dev, u_int intr, rman_res_t *irq)993{994return (BHND_BUS_MAP_INTR(device_get_parent(dev), dev, intr, irq));995}996997/**998* Unmap an bus interrupt previously mapped via bhnd_map_intr().999*1000* @param dev The requesting device.1001* @param irq The interrupt value being unmapped.1002*/1003static inline void1004bhnd_unmap_intr(device_t dev, rman_res_t irq)1005{1006return (BHND_BUS_UNMAP_INTR(device_get_parent(dev), dev, irq));1007}10081009/**1010* Allocate and enable per-core PMU request handling for @p child.1011*1012* The region containing the core's PMU register block (if any) must be1013* allocated via bus_alloc_resource(9) (or bhnd_alloc_resource) before1014* calling bhnd_alloc_pmu(), and must not be released until after1015* calling bhnd_release_pmu().1016*1017* @param dev The requesting bhnd device.1018*1019* @retval 0 success1020* @retval non-zero If allocating PMU request state otherwise fails, a1021* regular unix error code will be returned.1022*/1023static inline int1024bhnd_alloc_pmu(device_t dev)1025{1026return (BHND_BUS_ALLOC_PMU(device_get_parent(dev), dev));1027}10281029/**1030* Release any per-core PMU resources allocated for @p child. Any outstanding1031* PMU requests are are discarded.1032*1033* @param dev The requesting bhnd device.1034*1035* @retval 0 success1036* @retval non-zero If releasing PMU request state otherwise fails, a1037* regular unix error code will be returned, and1038* the core state will be left unmodified.1039*/1040static inline int1041bhnd_release_pmu(device_t dev)1042{1043return (BHND_BUS_RELEASE_PMU(device_get_parent(dev), dev));1044}10451046/**1047* Return the transition latency required for @p clock in microseconds, if1048* known.1049*1050* The BHND_CLOCK_HT latency value is suitable for use as the D11 core's1051* 'fastpwrup_dly' value.1052*1053* @note A driver must ask the bhnd bus to allocate PMU request state1054* via BHND_BUS_ALLOC_PMU() before querying PMU clocks.1055*1056* @param dev The requesting bhnd device.1057* @param clock The clock to be queried for transition latency.1058* @param[out] latency On success, the transition latency of @p clock in1059* microseconds.1060*1061* @retval 0 success1062* @retval ENODEV If the transition latency for @p clock is not available.1063*/1064static inline int1065bhnd_get_clock_latency(device_t dev, bhnd_clock clock, u_int *latency)1066{1067return (BHND_BUS_GET_CLOCK_LATENCY(device_get_parent(dev), dev, clock,1068latency));1069}10701071/**1072* Return the frequency for @p clock in Hz, if known.1073*1074* @param dev The requesting bhnd device.1075* @param clock The clock to be queried.1076* @param[out] freq On success, the frequency of @p clock in Hz.1077*1078* @note A driver must ask the bhnd bus to allocate PMU request state1079* via BHND_BUS_ALLOC_PMU() before querying PMU clocks.1080*1081* @retval 0 success1082* @retval ENODEV If the frequency for @p clock is not available.1083*/1084static inline int1085bhnd_get_clock_freq(device_t dev, bhnd_clock clock, u_int *freq)1086{1087return (BHND_BUS_GET_CLOCK_FREQ(device_get_parent(dev), dev, clock,1088freq));1089}10901091/**1092* Request that @p clock (or faster) be routed to @p dev.1093*1094* @note A driver must ask the bhnd bus to allocate clock request state1095* via bhnd_alloc_pmu() before it can request clock resources.1096*1097* @note Any outstanding PMU clock requests will be discarded upon calling1098* BHND_BUS_RESET_HW() or BHND_BUS_SUSPEND_HW().1099*1100* @param dev The bhnd(4) device to which @p clock should be routed.1101* @param clock The requested clock source.1102*1103* @retval 0 success1104* @retval ENODEV If an unsupported clock was requested.1105* @retval ENXIO If the PMU has not been initialized or is otherwise unvailable,1106*/1107static inline int1108bhnd_request_clock(device_t dev, bhnd_clock clock)1109{1110return (BHND_BUS_REQUEST_CLOCK(device_get_parent(dev), dev, clock));1111}11121113/**1114* Request that @p clocks be powered on behalf of @p dev.1115*1116* This will power any clock sources (e.g. XTAL, PLL, etc) required for1117* @p clocks and wait until they are ready, discarding any previous1118* requests by @p dev.1119*1120* @note A driver must ask the bhnd bus to allocate clock request state1121* via bhnd_alloc_pmu() before it can request clock resources.1122*1123* @note Any outstanding PMU clock requests will be discarded upon calling1124* BHND_BUS_RESET_HW() or BHND_BUS_SUSPEND_HW().1125*1126* @param dev The requesting bhnd(4) device.1127* @param clocks The clock(s) to be enabled.1128*1129* @retval 0 success1130* @retval ENODEV If an unsupported clock was requested.1131* @retval ENXIO If the PMU has not been initialized or is otherwise unvailable.1132*/1133static inline int1134bhnd_enable_clocks(device_t dev, uint32_t clocks)1135{1136return (BHND_BUS_ENABLE_CLOCKS(device_get_parent(dev), dev, clocks));1137}11381139/**1140* Power up an external PMU-managed resource assigned to @p dev.1141*1142* @note A driver must ask the bhnd bus to allocate PMU request state1143* via bhnd_alloc_pmu() before it can request PMU resources.1144*1145* @note Any outstanding PMU resource requests will be released upon calling1146* bhnd_reset_hw() or bhnd_suspend_hw().1147*1148* @param dev The requesting bhnd(4) device.1149* @param rsrc The core-specific external resource identifier.1150*1151* @retval 0 success1152* @retval ENODEV If the PMU does not support @p rsrc.1153* @retval ENXIO If the PMU has not been initialized or is otherwise unvailable.1154*/1155static inline int1156bhnd_request_ext_rsrc(device_t dev, u_int rsrc)1157{1158return (BHND_BUS_REQUEST_EXT_RSRC(device_get_parent(dev), dev, rsrc));1159}11601161/**1162* Power down an external PMU-managed resource assigned to @p dev.1163*1164* A driver must ask the bhnd bus to allocate PMU request state1165* via bhnd_alloc_pmu() before it can request PMU resources.1166*1167* @param dev The requesting bhnd(4) device.1168* @param rsrc The core-specific external resource identifier.1169*1170* @retval 0 success1171* @retval ENODEV If the PMU does not support @p rsrc.1172* @retval ENXIO If the PMU has not been initialized or is otherwise unvailable.1173*/1174static inline int1175bhnd_release_ext_rsrc(device_t dev, u_int rsrc)1176{1177return (BHND_BUS_RELEASE_EXT_RSRC(device_get_parent(dev), dev, rsrc));1178}11791180/**1181* Read @p width bytes at @p offset from the bus-specific agent/config1182* space of @p dev.1183*1184* @param dev The bhnd device for which @p offset should be read.1185* @param offset The offset to be read.1186* @param[out] value On success, the will be set to the @p width value read1187* at @p offset.1188* @param width The size of the access. Must be 1, 2 or 4 bytes.1189*1190* The exact behavior of this method is bus-specific. In the case of1191* bcma(4), this method provides access to the first agent port of @p child.1192*1193* @note Device drivers should only use this API for functionality1194* that is not available via another bhnd(4) function.1195*1196* @retval 0 success1197* @retval EINVAL If @p child is not a direct child of @p dev.1198* @retval EINVAL If @p width is not one of 1, 2, or 4 bytes.1199* @retval ENODEV If accessing agent/config space for @p child is unsupported.1200* @retval EFAULT If reading @p width at @p offset exceeds the bounds of1201* the mapped agent/config space for @p child.1202*/1203static inline uint32_t1204bhnd_read_config(device_t dev, bus_size_t offset, void *value, u_int width)1205{1206return (BHND_BUS_READ_CONFIG(device_get_parent(dev), dev, offset,1207value, width));1208}12091210/**1211* Write @p width bytes at @p offset to the bus-specific agent/config1212* space of @p dev.1213*1214* @param dev The bhnd device for which @p offset should be read.1215* @param offset The offset to be written.1216* @param value A pointer to the value to be written.1217* @param width The size of @p value. Must be 1, 2 or 4 bytes.1218*1219* The exact behavior of this method is bus-specific. In the case of1220* bcma(4), this method provides access to the first agent port of @p child.1221*1222* @note Device drivers should only use this API for functionality1223* that is not available via another bhnd(4) function.1224*1225* @retval 0 success1226* @retval EINVAL If @p child is not a direct child of @p dev.1227* @retval EINVAL If @p width is not one of 1, 2, or 4 bytes.1228* @retval ENODEV If accessing agent/config space for @p child is unsupported.1229* @retval EFAULT If reading @p width at @p offset exceeds the bounds of1230* the mapped agent/config space for @p child.1231*/1232static inline int1233bhnd_write_config(device_t dev, bus_size_t offset, const void *value,1234u_int width)1235{1236return (BHND_BUS_WRITE_CONFIG(device_get_parent(dev), dev, offset,1237value, width));1238}12391240/**1241* Read an NVRAM variable, coerced to the requested @p type.1242*1243* @param dev A bhnd bus child device.1244* @param name The NVRAM variable name.1245* @param[out] buf A buffer large enough to hold @p len bytes. On1246* success, the requested value will be written to1247* this buffer. This argment may be NULL if1248* the value is not desired.1249* @param[in,out] len The maximum capacity of @p buf. On success,1250* will be set to the actual size of the requested1251* value.1252* @param type The desired data representation to be written1253* to @p buf.1254*1255* @retval 0 success1256* @retval ENOENT The requested variable was not found.1257* @retval ENODEV No valid NVRAM source could be found.1258* @retval ENOMEM If a buffer of @p size is too small to hold the1259* requested value.1260* @retval EOPNOTSUPP If the value cannot be coerced to @p type.1261* @retval ERANGE If value coercion would overflow @p type.1262* @retval non-zero If reading @p name otherwise fails, a regular unix1263* error code will be returned.1264*/1265static inline int1266bhnd_nvram_getvar(device_t dev, const char *name, void *buf, size_t *len,1267bhnd_nvram_type type)1268{1269return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), dev, name, buf,1270len, type));1271}12721273/**1274* Allocate a resource from a device's parent bhnd(4) bus.1275*1276* @param dev The device requesting resource ownership.1277* @param type The type of resource to allocate. This may be any type supported1278* by the standard bus APIs.1279* @param rid The bus-specific handle identifying the resource being allocated.1280* @param start The start address of the resource.1281* @param end The end address of the resource.1282* @param count The size of the resource.1283* @param flags The flags for the resource to be allocated. These may be any1284* values supported by the standard bus APIs.1285*1286* To request the resource's default addresses, pass @p start and1287* @p end values of @c 0 and @c ~0, respectively, and1288* a @p count of @c 1.1289*1290* @retval NULL The resource could not be allocated.1291* @retval resource The allocated resource.1292*/1293static inline struct bhnd_resource *1294bhnd_alloc_resource(device_t dev, int type, int *rid, rman_res_t start,1295rman_res_t end, rman_res_t count, u_int flags)1296{1297return BHND_BUS_ALLOC_RESOURCE(device_get_parent(dev), dev, type, rid,1298start, end, count, flags);1299}13001301/**1302* Allocate a resource from a device's parent bhnd(4) bus, using the1303* resource's default start, end, and count values.1304*1305* @param dev The device requesting resource ownership.1306* @param type The type of resource to allocate. This may be any type supported1307* by the standard bus APIs.1308* @param rid The bus-specific handle identifying the resource being allocated.1309* @param flags The flags for the resource to be allocated. These may be any1310* values supported by the standard bus APIs.1311*1312* @retval NULL The resource could not be allocated.1313* @retval resource The allocated resource.1314*/1315static inline struct bhnd_resource *1316bhnd_alloc_resource_any(device_t dev, int type, int *rid, u_int flags)1317{1318return bhnd_alloc_resource(dev, type, rid, 0, ~0, 1, flags);1319}13201321/**1322* Activate a previously allocated bhnd resource.1323*1324* @param dev The device holding ownership of the allocated resource.1325* @param type The type of the resource.1326* @param rid The bus-specific handle identifying the resource.1327* @param r A pointer to the resource returned by bhnd_alloc_resource or1328* BHND_BUS_ALLOC_RESOURCE.1329*1330* @retval 0 success1331* @retval non-zero an error occurred while activating the resource.1332*/1333static inline int1334bhnd_activate_resource(device_t dev, int type, int rid,1335struct bhnd_resource *r)1336{1337return BHND_BUS_ACTIVATE_RESOURCE(device_get_parent(dev), dev, type,1338rid, r);1339}13401341/**1342* Deactivate a previously activated bhnd resource.1343*1344* @param dev The device holding ownership of the activated resource.1345* @param type The type of the resource.1346* @param rid The bus-specific handle identifying the resource.1347* @param r A pointer to the resource returned by bhnd_alloc_resource or1348* BHND_BUS_ALLOC_RESOURCE.1349*1350* @retval 0 success1351* @retval non-zero an error occurred while activating the resource.1352*/1353static inline int1354bhnd_deactivate_resource(device_t dev, int type, int rid,1355struct bhnd_resource *r)1356{1357return BHND_BUS_DEACTIVATE_RESOURCE(device_get_parent(dev), dev, type,1358rid, r);1359}13601361/**1362* Free a resource allocated by bhnd_alloc_resource().1363*1364* @param dev The device holding ownership of the resource.1365* @param type The type of the resource.1366* @param rid The bus-specific handle identifying the resource.1367* @param r A pointer to the resource returned by bhnd_alloc_resource or1368* BHND_ALLOC_RESOURCE.1369*1370* @retval 0 success1371* @retval non-zero an error occurred while activating the resource.1372*/1373static inline int1374bhnd_release_resource(device_t dev, int type, int rid,1375struct bhnd_resource *r)1376{1377return BHND_BUS_RELEASE_RESOURCE(device_get_parent(dev), dev, type,1378rid, r);1379}13801381/**1382* Return true if @p region_num is a valid region on @p port_num of1383* @p type attached to @p dev.1384*1385* @param dev A bhnd bus child device.1386* @param type The port type being queried.1387* @param port The port number being queried.1388* @param region The region number being queried.1389*/1390static inline bool1391bhnd_is_region_valid(device_t dev, bhnd_port_type type, u_int port,1392u_int region)1393{1394return (BHND_BUS_IS_REGION_VALID(device_get_parent(dev), dev, type,1395port, region));1396}13971398/**1399* Return the number of ports of type @p type attached to @p def.1400*1401* @param dev A bhnd bus child device.1402* @param type The port type being queried.1403*/1404static inline u_int1405bhnd_get_port_count(device_t dev, bhnd_port_type type) {1406return (BHND_BUS_GET_PORT_COUNT(device_get_parent(dev), dev, type));1407}14081409/**1410* Return the number of memory regions mapped to @p child @p port of1411* type @p type.1412*1413* @param dev A bhnd bus child device.1414* @param port The port number being queried.1415* @param type The port type being queried.1416*/1417static inline u_int1418bhnd_get_region_count(device_t dev, bhnd_port_type type, u_int port) {1419return (BHND_BUS_GET_REGION_COUNT(device_get_parent(dev), dev, type,1420port));1421}14221423/**1424* Return the resource-ID for a memory region on the given device port.1425*1426* @param dev A bhnd bus child device.1427* @param type The port type.1428* @param port The port identifier.1429* @param region The identifier of the memory region on @p port.1430*1431* @retval int The RID for the given @p port and @p region on @p device.1432* @retval -1 No such port/region found.1433*/1434static inline int1435bhnd_get_port_rid(device_t dev, bhnd_port_type type, u_int port, u_int region)1436{1437return BHND_BUS_GET_PORT_RID(device_get_parent(dev), dev, type, port,1438region);1439}14401441/**1442* Decode a port / region pair on @p dev defined by @p rid.1443*1444* @param dev A bhnd bus child device.1445* @param type The resource type.1446* @param rid The resource identifier.1447* @param[out] port_type The decoded port type.1448* @param[out] port The decoded port identifier.1449* @param[out] region The decoded region identifier.1450*1451* @retval 0 success1452* @retval non-zero No matching port/region found.1453*/1454static inline int1455bhnd_decode_port_rid(device_t dev, int type, int rid, bhnd_port_type *port_type,1456u_int *port, u_int *region)1457{1458return BHND_BUS_DECODE_PORT_RID(device_get_parent(dev), dev, type, rid,1459port_type, port, region);1460}14611462/**1463* Get the address and size of @p region on @p port.1464*1465* @param dev A bhnd bus child device.1466* @param port_type The port type.1467* @param port The port identifier.1468* @param region The identifier of the memory region on @p port.1469* @param[out] region_addr The region's base address.1470* @param[out] region_size The region's size.1471*1472* @retval 0 success1473* @retval non-zero No matching port/region found.1474*/1475static inline int1476bhnd_get_region_addr(device_t dev, bhnd_port_type port_type, u_int port,1477u_int region, bhnd_addr_t *region_addr, bhnd_size_t *region_size)1478{1479return BHND_BUS_GET_REGION_ADDR(device_get_parent(dev), dev, port_type,1480port, region, region_addr, region_size);1481}14821483/*1484* bhnd bus-level equivalents of the bus_(read|write|set|barrier|...)1485* macros (compatible with bhnd_resource).1486*1487* Generated with bhnd/tools/bus_macro.sh1488*/1489#define bhnd_bus_barrier(r, o, l, f) \1490(((r)->direct) ? \1491bus_barrier((r)->res, (o), (l), (f)) : \1492BHND_BUS_BARRIER( \1493device_get_parent(rman_get_device((r)->res)), \1494rman_get_device((r)->res), (r), (o), (l), (f)))1495#define bhnd_bus_read_1(r, o) \1496(((r)->direct) ? \1497bus_read_1((r)->res, (o)) : \1498BHND_BUS_READ_1( \1499device_get_parent(rman_get_device((r)->res)), \1500rman_get_device((r)->res), (r), (o)))1501#define bhnd_bus_read_multi_1(r, o, d, c) \1502(((r)->direct) ? \1503bus_read_multi_1((r)->res, (o), (d), (c)) : \1504BHND_BUS_READ_MULTI_1( \1505device_get_parent(rman_get_device((r)->res)), \1506rman_get_device((r)->res), (r), (o), (d), (c)))1507#define bhnd_bus_read_region_1(r, o, d, c) \1508(((r)->direct) ? \1509bus_read_region_1((r)->res, (o), (d), (c)) : \1510BHND_BUS_READ_REGION_1( \1511device_get_parent(rman_get_device((r)->res)), \1512rman_get_device((r)->res), (r), (o), (d), (c)))1513#define bhnd_bus_write_1(r, o, v) \1514(((r)->direct) ? \1515bus_write_1((r)->res, (o), (v)) : \1516BHND_BUS_WRITE_1( \1517device_get_parent(rman_get_device((r)->res)), \1518rman_get_device((r)->res), (r), (o), (v)))1519#define bhnd_bus_write_multi_1(r, o, d, c) \1520(((r)->direct) ? \1521bus_write_multi_1((r)->res, (o), (d), (c)) : \1522BHND_BUS_WRITE_MULTI_1( \1523device_get_parent(rman_get_device((r)->res)), \1524rman_get_device((r)->res), (r), (o), (d), (c)))1525#define bhnd_bus_write_region_1(r, o, d, c) \1526(((r)->direct) ? \1527bus_write_region_1((r)->res, (o), (d), (c)) : \1528BHND_BUS_WRITE_REGION_1( \1529device_get_parent(rman_get_device((r)->res)), \1530rman_get_device((r)->res), (r), (o), (d), (c)))1531#define bhnd_bus_read_stream_1(r, o) \1532(((r)->direct) ? \1533bus_read_stream_1((r)->res, (o)) : \1534BHND_BUS_READ_STREAM_1( \1535device_get_parent(rman_get_device((r)->res)), \1536rman_get_device((r)->res), (r), (o)))1537#define bhnd_bus_read_multi_stream_1(r, o, d, c) \1538(((r)->direct) ? \1539bus_read_multi_stream_1((r)->res, (o), (d), (c)) : \1540BHND_BUS_READ_MULTI_STREAM_1( \1541device_get_parent(rman_get_device((r)->res)), \1542rman_get_device((r)->res), (r), (o), (d), (c)))1543#define bhnd_bus_read_region_stream_1(r, o, d, c) \1544(((r)->direct) ? \1545bus_read_region_stream_1((r)->res, (o), (d), (c)) : \1546BHND_BUS_READ_REGION_STREAM_1( \1547device_get_parent(rman_get_device((r)->res)), \1548rman_get_device((r)->res), (r), (o), (d), (c)))1549#define bhnd_bus_write_stream_1(r, o, v) \1550(((r)->direct) ? \1551bus_write_stream_1((r)->res, (o), (v)) : \1552BHND_BUS_WRITE_STREAM_1( \1553device_get_parent(rman_get_device((r)->res)), \1554rman_get_device((r)->res), (r), (o), (v)))1555#define bhnd_bus_write_multi_stream_1(r, o, d, c) \1556(((r)->direct) ? \1557bus_write_multi_stream_1((r)->res, (o), (d), (c)) : \1558BHND_BUS_WRITE_MULTI_STREAM_1( \1559device_get_parent(rman_get_device((r)->res)), \1560rman_get_device((r)->res), (r), (o), (d), (c)))1561#define bhnd_bus_write_region_stream_1(r, o, d, c) \1562(((r)->direct) ? \1563bus_write_region_stream_1((r)->res, (o), (d), (c)) : \1564BHND_BUS_WRITE_REGION_STREAM_1( \1565device_get_parent(rman_get_device((r)->res)), \1566rman_get_device((r)->res), (r), (o), (d), (c)))1567#define bhnd_bus_set_multi_1(r, o, v, c) \1568(((r)->direct) ? \1569bus_set_multi_1((r)->res, (o), (v), (c)) : \1570BHND_BUS_SET_MULTI_1( \1571device_get_parent(rman_get_device((r)->res)), \1572rman_get_device((r)->res), (r), (o), (v), (c)))1573#define bhnd_bus_set_region_1(r, o, v, c) \1574(((r)->direct) ? \1575bus_set_region_1((r)->res, (o), (v), (c)) : \1576BHND_BUS_SET_REGION_1( \1577device_get_parent(rman_get_device((r)->res)), \1578rman_get_device((r)->res), (r), (o), (v), (c)))1579#define bhnd_bus_read_2(r, o) \1580(((r)->direct) ? \1581bus_read_2((r)->res, (o)) : \1582BHND_BUS_READ_2( \1583device_get_parent(rman_get_device((r)->res)), \1584rman_get_device((r)->res), (r), (o)))1585#define bhnd_bus_read_multi_2(r, o, d, c) \1586(((r)->direct) ? \1587bus_read_multi_2((r)->res, (o), (d), (c)) : \1588BHND_BUS_READ_MULTI_2( \1589device_get_parent(rman_get_device((r)->res)), \1590rman_get_device((r)->res), (r), (o), (d), (c)))1591#define bhnd_bus_read_region_2(r, o, d, c) \1592(((r)->direct) ? \1593bus_read_region_2((r)->res, (o), (d), (c)) : \1594BHND_BUS_READ_REGION_2( \1595device_get_parent(rman_get_device((r)->res)), \1596rman_get_device((r)->res), (r), (o), (d), (c)))1597#define bhnd_bus_write_2(r, o, v) \1598(((r)->direct) ? \1599bus_write_2((r)->res, (o), (v)) : \1600BHND_BUS_WRITE_2( \1601device_get_parent(rman_get_device((r)->res)), \1602rman_get_device((r)->res), (r), (o), (v)))1603#define bhnd_bus_write_multi_2(r, o, d, c) \1604(((r)->direct) ? \1605bus_write_multi_2((r)->res, (o), (d), (c)) : \1606BHND_BUS_WRITE_MULTI_2( \1607device_get_parent(rman_get_device((r)->res)), \1608rman_get_device((r)->res), (r), (o), (d), (c)))1609#define bhnd_bus_write_region_2(r, o, d, c) \1610(((r)->direct) ? \1611bus_write_region_2((r)->res, (o), (d), (c)) : \1612BHND_BUS_WRITE_REGION_2( \1613device_get_parent(rman_get_device((r)->res)), \1614rman_get_device((r)->res), (r), (o), (d), (c)))1615#define bhnd_bus_read_stream_2(r, o) \1616(((r)->direct) ? \1617bus_read_stream_2((r)->res, (o)) : \1618BHND_BUS_READ_STREAM_2( \1619device_get_parent(rman_get_device((r)->res)), \1620rman_get_device((r)->res), (r), (o)))1621#define bhnd_bus_read_multi_stream_2(r, o, d, c) \1622(((r)->direct) ? \1623bus_read_multi_stream_2((r)->res, (o), (d), (c)) : \1624BHND_BUS_READ_MULTI_STREAM_2( \1625device_get_parent(rman_get_device((r)->res)), \1626rman_get_device((r)->res), (r), (o), (d), (c)))1627#define bhnd_bus_read_region_stream_2(r, o, d, c) \1628(((r)->direct) ? \1629bus_read_region_stream_2((r)->res, (o), (d), (c)) : \1630BHND_BUS_READ_REGION_STREAM_2( \1631device_get_parent(rman_get_device((r)->res)), \1632rman_get_device((r)->res), (r), (o), (d), (c)))1633#define bhnd_bus_write_stream_2(r, o, v) \1634(((r)->direct) ? \1635bus_write_stream_2((r)->res, (o), (v)) : \1636BHND_BUS_WRITE_STREAM_2( \1637device_get_parent(rman_get_device((r)->res)), \1638rman_get_device((r)->res), (r), (o), (v)))1639#define bhnd_bus_write_multi_stream_2(r, o, d, c) \1640(((r)->direct) ? \1641bus_write_multi_stream_2((r)->res, (o), (d), (c)) : \1642BHND_BUS_WRITE_MULTI_STREAM_2( \1643device_get_parent(rman_get_device((r)->res)), \1644rman_get_device((r)->res), (r), (o), (d), (c)))1645#define bhnd_bus_write_region_stream_2(r, o, d, c) \1646(((r)->direct) ? \1647bus_write_region_stream_2((r)->res, (o), (d), (c)) : \1648BHND_BUS_WRITE_REGION_STREAM_2( \1649device_get_parent(rman_get_device((r)->res)), \1650rman_get_device((r)->res), (r), (o), (d), (c)))1651#define bhnd_bus_set_multi_2(r, o, v, c) \1652(((r)->direct) ? \1653bus_set_multi_2((r)->res, (o), (v), (c)) : \1654BHND_BUS_SET_MULTI_2( \1655device_get_parent(rman_get_device((r)->res)), \1656rman_get_device((r)->res), (r), (o), (v), (c)))1657#define bhnd_bus_set_region_2(r, o, v, c) \1658(((r)->direct) ? \1659bus_set_region_2((r)->res, (o), (v), (c)) : \1660BHND_BUS_SET_REGION_2( \1661device_get_parent(rman_get_device((r)->res)), \1662rman_get_device((r)->res), (r), (o), (v), (c)))1663#define bhnd_bus_read_4(r, o) \1664(((r)->direct) ? \1665bus_read_4((r)->res, (o)) : \1666BHND_BUS_READ_4( \1667device_get_parent(rman_get_device((r)->res)), \1668rman_get_device((r)->res), (r), (o)))1669#define bhnd_bus_read_multi_4(r, o, d, c) \1670(((r)->direct) ? \1671bus_read_multi_4((r)->res, (o), (d), (c)) : \1672BHND_BUS_READ_MULTI_4( \1673device_get_parent(rman_get_device((r)->res)), \1674rman_get_device((r)->res), (r), (o), (d), (c)))1675#define bhnd_bus_read_region_4(r, o, d, c) \1676(((r)->direct) ? \1677bus_read_region_4((r)->res, (o), (d), (c)) : \1678BHND_BUS_READ_REGION_4( \1679device_get_parent(rman_get_device((r)->res)), \1680rman_get_device((r)->res), (r), (o), (d), (c)))1681#define bhnd_bus_write_4(r, o, v) \1682(((r)->direct) ? \1683bus_write_4((r)->res, (o), (v)) : \1684BHND_BUS_WRITE_4( \1685device_get_parent(rman_get_device((r)->res)), \1686rman_get_device((r)->res), (r), (o), (v)))1687#define bhnd_bus_write_multi_4(r, o, d, c) \1688(((r)->direct) ? \1689bus_write_multi_4((r)->res, (o), (d), (c)) : \1690BHND_BUS_WRITE_MULTI_4( \1691device_get_parent(rman_get_device((r)->res)), \1692rman_get_device((r)->res), (r), (o), (d), (c)))1693#define bhnd_bus_write_region_4(r, o, d, c) \1694(((r)->direct) ? \1695bus_write_region_4((r)->res, (o), (d), (c)) : \1696BHND_BUS_WRITE_REGION_4( \1697device_get_parent(rman_get_device((r)->res)), \1698rman_get_device((r)->res), (r), (o), (d), (c)))1699#define bhnd_bus_read_stream_4(r, o) \1700(((r)->direct) ? \1701bus_read_stream_4((r)->res, (o)) : \1702BHND_BUS_READ_STREAM_4( \1703device_get_parent(rman_get_device((r)->res)), \1704rman_get_device((r)->res), (r), (o)))1705#define bhnd_bus_read_multi_stream_4(r, o, d, c) \1706(((r)->direct) ? \1707bus_read_multi_stream_4((r)->res, (o), (d), (c)) : \1708BHND_BUS_READ_MULTI_STREAM_4( \1709device_get_parent(rman_get_device((r)->res)), \1710rman_get_device((r)->res), (r), (o), (d), (c)))1711#define bhnd_bus_read_region_stream_4(r, o, d, c) \1712(((r)->direct) ? \1713bus_read_region_stream_4((r)->res, (o), (d), (c)) : \1714BHND_BUS_READ_REGION_STREAM_4( \1715device_get_parent(rman_get_device((r)->res)), \1716rman_get_device((r)->res), (r), (o), (d), (c)))1717#define bhnd_bus_write_stream_4(r, o, v) \1718(((r)->direct) ? \1719bus_write_stream_4((r)->res, (o), (v)) : \1720BHND_BUS_WRITE_STREAM_4( \1721device_get_parent(rman_get_device((r)->res)), \1722rman_get_device((r)->res), (r), (o), (v)))1723#define bhnd_bus_write_multi_stream_4(r, o, d, c) \1724(((r)->direct) ? \1725bus_write_multi_stream_4((r)->res, (o), (d), (c)) : \1726BHND_BUS_WRITE_MULTI_STREAM_4( \1727device_get_parent(rman_get_device((r)->res)), \1728rman_get_device((r)->res), (r), (o), (d), (c)))1729#define bhnd_bus_write_region_stream_4(r, o, d, c) \1730(((r)->direct) ? \1731bus_write_region_stream_4((r)->res, (o), (d), (c)) : \1732BHND_BUS_WRITE_REGION_STREAM_4( \1733device_get_parent(rman_get_device((r)->res)), \1734rman_get_device((r)->res), (r), (o), (d), (c)))1735#define bhnd_bus_set_multi_4(r, o, v, c) \1736(((r)->direct) ? \1737bus_set_multi_4((r)->res, (o), (v), (c)) : \1738BHND_BUS_SET_MULTI_4( \1739device_get_parent(rman_get_device((r)->res)), \1740rman_get_device((r)->res), (r), (o), (v), (c)))1741#define bhnd_bus_set_region_4(r, o, v, c) \1742(((r)->direct) ? \1743bus_set_region_4((r)->res, (o), (v), (c)) : \1744BHND_BUS_SET_REGION_4( \1745device_get_parent(rman_get_device((r)->res)), \1746rman_get_device((r)->res), (r), (o), (v), (c)))17471748#endif /* _BHND_BHND_H_ */174917501751