1 /*- 2 * Copyright (c) 2015-2016 Landon Fuller <landonf@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer, 10 * without modification. 11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 13 * redistribution must be conditioned upon including a substantially 14 * similar Disclaimer requirement for further binary redistribution. 15 * 16 * NO WARRANTY 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 22 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 * THE POSSIBILITY OF SUCH DAMAGES. 28 * 29 * $FreeBSD$ 30 */ 31 32 #ifndef _BHND_EROM_BHND_EROM_H_ 33 #define _BHND_EROM_BHND_EROM_H_ 34 35 #include <sys/param.h> 36 #include <sys/kobj.h> 37 #include <sys/linker_set.h> 38 39 #include <dev/bhnd/bhnd.h> 40 #include <dev/bhnd/bhnd_erom_types.h> 41 42 #include "bhnd_erom_if.h" 43 44 bhnd_erom_t *bhnd_erom_alloc(bhnd_erom_class_t *cls, 45 const struct bhnd_chipid *cid, 46 device_t parent, int rid); 47 48 int bhnd_erom_init_static(bhnd_erom_class_t *cls, 49 bhnd_erom_t *erom, size_t esize, 50 const struct bhnd_chipid *cid, 51 bus_space_tag_t bst, 52 bus_space_handle_t bsh); 53 54 void bhnd_erom_fini_static(bhnd_erom_t *erom); 55 56 void bhnd_erom_free(bhnd_erom_t *erom); 57 58 /** 59 * Abstract bhnd_erom instance state. Must be first member of all subclass 60 * instances. 61 */ 62 struct bhnd_erom { 63 KOBJ_FIELDS; 64 }; 65 66 67 /** Number of additional bytes to reserve for statically allocated 68 * bhnd_erom instances. */ 69 #define BHND_EROM_STATIC_BYTES 64 70 71 /** 72 * A bhnd_erom instance structure large enough to statically allocate 73 * any known bhnd_erom subclass. 74 * 75 * The maximum size of subclasses is verified statically in 76 * BHND_EROM_DEFINE_CLASS(), and at runtime in bhnd_erom_init_static(). 77 */ 78 struct bhnd_erom_static { 79 struct bhnd_erom obj; 80 uint8_t idata[BHND_EROM_STATIC_BYTES]; 81 }; 82 83 /** Registered EROM parser class instances. */ 84 SET_DECLARE(bhnd_erom_class_set, bhnd_erom_class_t); 85 86 #define BHND_EROM_DEFINE_CLASS(name, classvar, methods, size) \ 87 DEFINE_CLASS_0(name, classvar, methods, size); \ 88 BHND_EROM_CLASS_DEF(classvar); \ 89 _Static_assert(size <= sizeof(struct bhnd_erom_static), \ 90 "cannot statically allocate instance data; " \ 91 "increase BHND_EROM_STATIC_BYTES"); 92 93 #define BHND_EROM_CLASS_DEF(classvar) DATA_SET(bhnd_erom_class_set, classvar) 94 95 96 /** 97 * Probe to see if this device enumeration class supports the bhnd bus 98 * mapped by the given resource, returning a standard newbus device probe 99 * result (see BUS_PROBE_*) and the probed chip identification. 100 * 101 * @param cls The erom class to probe. 102 * @param res A resource mapping the first bus core (EXTIF or 103 * ChipCommon) 104 * @param offset Offset to the first bus core within @p res. 105 * @param hint Identification hint used to identify the device. If 106 * chipset supports standard chip identification registers 107 * within the first core, this parameter should be NULL. 108 * @param[out] cid On success, the probed chip identifier. 109 * 110 * @retval 0 if this is the only possible device enumeration 111 * parser for the probed bus. 112 * @retval negative if the probe succeeds, a negative value should be 113 * returned; the parser returning the highest negative 114 * value will be selected to handle device enumeration. 115 * @retval ENXIO If the bhnd bus type is not handled by this parser. 116 * @retval positive if an error occurs during probing, a regular unix error 117 * code should be returned. 118 */ 119 static inline int 120 bhnd_erom_probe(bhnd_erom_class_t *cls, struct bhnd_resource *res, 121 bus_size_t offset, const struct bhnd_chipid *hint, struct bhnd_chipid *cid) 122 { 123 return (BHND_EROM_PROBE(cls, res, offset, hint, cid)); 124 } 125 126 /** 127 * Probe to see if this device enumeration class supports the bhnd bus 128 * mapped at the given bus space tag and handle, returning a standard 129 * newbus device probe result (see BUS_PROBE_*) and the probed 130 * chip identification. 131 * 132 * @param cls The erom class to probe. 133 * @param bst Bus space tag. 134 * @param bsh Bus space handle mapping the EXTIF or ChipCommon core. 135 * @param paddr The physical address of the core mapped by @p bst and 136 * @p bsh. 137 * @param hint Identification hint used to identify the device. If 138 * chipset supports standard chip identification registers 139 * within the first core, this parameter should be NULL. 140 * @param[out] cid On success, the probed chip identifier. 141 * 142 * @retval 0 if this is the only possible device enumeration 143 * parser for the probed bus. 144 * @retval negative if the probe succeeds, a negative value should be 145 * returned; the parser returning the lowest value will 146 * be selected to handle device enumeration. 147 * @retval ENXIO If the bhnd bus type is not handled by this parser. 148 * @retval positive if an error occurs during probing, a regular unix error 149 * code should be returned. 150 */ 151 static inline int 152 bhnd_erom_probe_static(bhnd_erom_class_t *cls, bus_space_tag_t bst, 153 bus_space_handle_t bsh, bus_addr_t paddr, const struct bhnd_chipid *hint, 154 struct bhnd_chipid *cid) 155 { 156 return (BHND_EROM_PROBE_STATIC(cls, bst, bsh, paddr, hint, cid)); 157 } 158 159 /** 160 * Parse all cores descriptors in @p erom, returning the array in @p cores and 161 * the count in @p num_cores. 162 * 163 * The memory allocated for the table must be freed via 164 * bhnd_erom_free_core_table(). 165 * 166 * @param erom The erom parser to be queried. 167 * @param[out] cores The table of parsed core descriptors. 168 * @param[out] num_cores The number of core records in @p cores. 169 * 170 * @retval 0 success 171 * @retval non-zero if an error occurs, a regular unix error code will 172 * be returned. 173 */ 174 static inline int 175 bhnd_erom_get_core_table(bhnd_erom_t *erom, struct bhnd_core_info **cores, 176 u_int *num_cores) 177 { 178 return (BHND_EROM_GET_CORE_TABLE(erom, cores, num_cores)); 179 } 180 181 /** 182 * Free any memory allocated in a previous call to BHND_EROM_GET_CORE_TABLE(). 183 * 184 * @param erom The erom parser instance. 185 * @param cores A core table allocated by @p erom. 186 */ 187 static inline void 188 bhnd_erom_free_core_table(bhnd_erom_t *erom, struct bhnd_core_info *cores) 189 { 190 return (BHND_EROM_FREE_CORE_TABLE(erom, cores)); 191 }; 192 193 /** 194 * Locate the first core table entry in @p erom that matches @p desc. 195 * 196 * @param erom The erom parser to be queried. 197 * @param desc A core match descriptor. 198 * @param[out] core On success, the matching core info record. 199 * 200 * @retval 0 success 201 * @retval ENOENT No core matching @p desc was found. 202 * @retval non-zero Reading or parsing failed. 203 */ 204 static inline int 205 bhnd_erom_lookup_core(bhnd_erom_t *erom, const struct bhnd_core_match *desc, 206 struct bhnd_core_info *core) 207 { 208 return (BHND_EROM_LOOKUP_CORE(erom, desc, core)); 209 } 210 211 /** 212 * Locate the first core table entry in @p erom that matches @p desc, 213 * and return the specified port region's base address and size. 214 * 215 * If a core matching @p desc is not found, or the requested port region 216 * is not mapped to the matching core, ENOENT is returned. 217 * 218 * @param erom The erom parser to be queried. 219 * @param desc A core match descriptor. 220 * @param type The port type to search for. 221 * @param port The port to search for. 222 * @param region The port region to search for. 223 * @param[out] core If not NULL, will be populated with the matched core 224 * info record on success. 225 * @param[out] addr On success, the base address of the port region. 226 * @param[out] size On success, the total size of the port region. 227 * 228 * @retval 0 success 229 * @retval ENOENT No core matching @p desc was found. 230 * @retval ENOENT No port region matching @p type, @p port, and @p region 231 * was found. 232 * @retval non-zero Reading or parsing failed. 233 */ 234 static inline int 235 bhnd_erom_lookup_core_addr(bhnd_erom_t *erom, const struct bhnd_core_match *desc, 236 bhnd_port_type type, u_int port, u_int region, struct bhnd_core_info *core, 237 bhnd_addr_t *addr, bhnd_size_t *size) 238 { 239 return (BHND_EROM_LOOKUP_CORE_ADDR(erom, desc, type, port, region, 240 core, addr, size)); 241 }; 242 243 #endif /* _BHND_EROM_BHND_EROM_H_ */ 244