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