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