/*-1* SPDX-License-Identifier: BSD-2-Clause2*3* Copyright (c) 2015-2017 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_EROM_BHND_EROM_H_37#define _BHND_EROM_BHND_EROM_H_3839#include <sys/param.h>40#include <sys/kobj.h>41#include <sys/linker_set.h>4243#include <dev/bhnd/bhnd.h>44#include <dev/bhnd/bhnd_erom_types.h>4546#include "bhnd_erom_if.h"4748/* forward declarations */49struct bhnd_erom_io;50struct bhnd_erom_iobus;5152bhnd_erom_class_t *bhnd_erom_probe_driver_classes(devclass_t bus_devclass,53struct bhnd_erom_io *eio,54const struct bhnd_chipid *hint,55struct bhnd_chipid *cid);5657bhnd_erom_t *bhnd_erom_alloc(bhnd_erom_class_t *cls,58const struct bhnd_chipid *cid,59struct bhnd_erom_io *eio);6061int bhnd_erom_init_static(bhnd_erom_class_t *cls,62bhnd_erom_t *erom, size_t esize,63const struct bhnd_chipid *cid,64struct bhnd_erom_io *eio);6566void bhnd_erom_fini_static(bhnd_erom_t *erom);6768void bhnd_erom_free(bhnd_erom_t *erom);6970struct bhnd_erom_io *bhnd_erom_iores_new(device_t dev, int rid);71int bhnd_erom_iobus_init(struct bhnd_erom_iobus *iobus,72bhnd_addr_t addr, bhnd_size_t size,73bus_space_tag_t bst, bus_space_handle_t bsh);7475int bhnd_erom_io_map(struct bhnd_erom_io *eio,76bhnd_addr_t addr, bhnd_size_t size);77int bhnd_erom_io_tell(struct bhnd_erom_io *eio,78bhnd_addr_t *addr, bhnd_size_t *size);79uint32_t bhnd_erom_io_read(struct bhnd_erom_io *eio,80bhnd_size_t offset, u_int width);81void bhnd_erom_io_fini(struct bhnd_erom_io *eio);8283/**84* Abstract bhnd_erom instance state. Must be first member of all subclass85* instances.86*/87struct bhnd_erom {88KOBJ_FIELDS;89};9091/** Number of additional bytes to reserve for statically allocated92* bhnd_erom instances. */93#define BHND_EROM_STATIC_BYTES 649495/**96* A bhnd_erom instance structure large enough to statically allocate97* any known bhnd_erom subclass.98*99* The maximum size of subclasses is verified statically in100* BHND_EROM_DEFINE_CLASS(), and at runtime in bhnd_erom_init_static().101*/102struct bhnd_erom_static {103struct bhnd_erom obj;104uint8_t idata[BHND_EROM_STATIC_BYTES];105};106107/** Registered EROM parser class instances. */108SET_DECLARE(bhnd_erom_class_set, bhnd_erom_class_t);109110#define BHND_EROM_DEFINE_CLASS(name, classvar, methods, size) \111DEFINE_CLASS_0(name, classvar, methods, size); \112BHND_EROM_CLASS_DEF(classvar); \113_Static_assert(size <= sizeof(struct bhnd_erom_static), \114"cannot statically allocate instance data; " \115"increase BHND_EROM_STATIC_BYTES");116117#define BHND_EROM_CLASS_DEF(classvar) DATA_SET(bhnd_erom_class_set, classvar)118119/**120* Probe to see if this device enumeration class supports the bhnd bus121* mapped by @p eio, returning a standard newbus device probe result122* (see BUS_PROBE_*) and the probed chip identification.123*124* @param cls The erom class to probe.125* @param eio A bus I/O instance, configured with a mapping of the126* first bus core.127* @param hint Identification hint used to identify the device.128* If chipset supports standard chip identification129* registers within the first core, this parameter should130* be NULL.131* @param[out] cid On success, the probed chip identifier.132*133* @retval 0 if this is the only possible device enumeration134* parser for the probed bus.135* @retval negative if the probe succeeds, a negative value should be136* returned; the parser returning the highest negative137* value will be selected to handle device enumeration.138* @retval ENXIO If the bhnd bus type is not handled by this parser.139* @retval positive if an error occurs during probing, a regular unix error140* code should be returned.141*/142static inline int143bhnd_erom_probe(bhnd_erom_class_t *cls, struct bhnd_erom_io *eio,144const struct bhnd_chipid *hint, struct bhnd_chipid *cid)145{146return (BHND_EROM_PROBE(cls, eio, hint, cid));147}148149/**150* Parse all cores descriptors in @p erom, returning the array in @p cores and151* the count in @p num_cores.152*153* The memory allocated for the table must be freed via154* bhnd_erom_free_core_table().155*156* @param erom The erom parser to be queried.157* @param[out] cores The table of parsed core descriptors.158* @param[out] num_cores The number of core records in @p cores.159*160* @retval 0 success161* @retval non-zero if an error occurs, a regular unix error code will162* be returned.163*/164static inline int165bhnd_erom_get_core_table(bhnd_erom_t *erom, struct bhnd_core_info **cores,166u_int *num_cores)167{168return (BHND_EROM_GET_CORE_TABLE(erom, cores, num_cores));169}170171/**172* Free any memory allocated in a previous call to BHND_EROM_GET_CORE_TABLE().173*174* @param erom The erom parser instance.175* @param cores A core table allocated by @p erom.176*/177static inline void178bhnd_erom_free_core_table(bhnd_erom_t *erom, struct bhnd_core_info *cores)179{180return (BHND_EROM_FREE_CORE_TABLE(erom, cores));181};182183/**184* Locate the first core table entry in @p erom that matches @p desc.185*186* @param erom The erom parser to be queried.187* @param desc A core match descriptor.188* @param[out] core On success, the matching core info record.189*190* @retval 0 success191* @retval ENOENT No core matching @p desc was found.192* @retval non-zero Reading or parsing failed.193*/194static inline int195bhnd_erom_lookup_core(bhnd_erom_t *erom, const struct bhnd_core_match *desc,196struct bhnd_core_info *core)197{198return (BHND_EROM_LOOKUP_CORE(erom, desc, core));199}200201/**202* Locate the first core table entry in @p erom that matches @p desc,203* and return the specified port region's base address and size.204*205* If a core matching @p desc is not found, or the requested port region206* is not mapped to the matching core, ENOENT is returned.207*208* @param erom The erom parser to be queried.209* @param desc A core match descriptor.210* @param type The port type to search for.211* @param port The port to search for.212* @param region The port region to search for.213* @param[out] core If not NULL, will be populated with the matched core214* info record on success.215* @param[out] addr On success, the base address of the port region.216* @param[out] size On success, the total size of the port region.217*218* @retval 0 success219* @retval ENOENT No core matching @p desc was found.220* @retval ENOENT No port region matching @p type, @p port, and @p region221* was found.222* @retval non-zero Reading or parsing failed.223*/224static inline int225bhnd_erom_lookup_core_addr(bhnd_erom_t *erom, const struct bhnd_core_match *desc,226bhnd_port_type type, u_int port, u_int region, struct bhnd_core_info *core,227bhnd_addr_t *addr, bhnd_size_t *size)228{229return (BHND_EROM_LOOKUP_CORE_ADDR(erom, desc, type, port, region,230core, addr, size));231};232233/**234* Enumerate and print all entries in @p erom.235*236* @param erom The erom parser to be enumerated.237*238* @retval 0 success239* @retval non-zero If an error occurs parsing the EROM table, a regular240* unix error code will be returned.241*/242static inline int243bhnd_erom_dump(bhnd_erom_t *erom)244{245return (BHND_EROM_DUMP(erom));246}247248#endif /* _BHND_EROM_BHND_EROM_H_ */249250251