1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 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 * $FreeBSD$ 36 */ 37 38 #ifndef _BHND_EROM_BHND_EROM_H_ 39 #define _BHND_EROM_BHND_EROM_H_ 40 41 #include <sys/param.h> 42 #include <sys/kobj.h> 43 #include <sys/linker_set.h> 44 45 #include <dev/bhnd/bhnd.h> 46 #include <dev/bhnd/bhnd_erom_types.h> 47 48 #include "bhnd_erom_if.h" 49 50 /* forward declarations */ 51 struct bhnd_erom_io; 52 struct bhnd_erom_iobus; 53 54 bhnd_erom_class_t *bhnd_erom_probe_driver_classes(devclass_t bus_devclass, 55 struct bhnd_erom_io *eio, 56 const struct bhnd_chipid *hint, 57 struct bhnd_chipid *cid); 58 59 bhnd_erom_t *bhnd_erom_alloc(bhnd_erom_class_t *cls, 60 const struct bhnd_chipid *cid, 61 struct bhnd_erom_io *eio); 62 63 int bhnd_erom_init_static(bhnd_erom_class_t *cls, 64 bhnd_erom_t *erom, size_t esize, 65 const struct bhnd_chipid *cid, 66 struct bhnd_erom_io *eio); 67 68 void bhnd_erom_fini_static(bhnd_erom_t *erom); 69 70 void bhnd_erom_free(bhnd_erom_t *erom); 71 72 struct bhnd_erom_io *bhnd_erom_iores_new(device_t dev, int rid); 73 int bhnd_erom_iobus_init(struct bhnd_erom_iobus *iobus, 74 bhnd_addr_t addr, bhnd_size_t size, 75 bus_space_tag_t bst, bus_space_handle_t bsh); 76 77 int bhnd_erom_io_map(struct bhnd_erom_io *eio, 78 bhnd_addr_t addr, bhnd_size_t size); 79 int bhnd_erom_io_tell(struct bhnd_erom_io *eio, 80 bhnd_addr_t *addr, bhnd_size_t *size); 81 uint32_t bhnd_erom_io_read(struct bhnd_erom_io *eio, 82 bhnd_size_t offset, u_int width); 83 void bhnd_erom_io_fini(struct bhnd_erom_io *eio); 84 85 /** 86 * Abstract bhnd_erom instance state. Must be first member of all subclass 87 * instances. 88 */ 89 struct bhnd_erom { 90 KOBJ_FIELDS; 91 }; 92 93 94 /** Number of additional bytes to reserve for statically allocated 95 * bhnd_erom instances. */ 96 #define BHND_EROM_STATIC_BYTES 64 97 98 /** 99 * A bhnd_erom instance structure large enough to statically allocate 100 * any known bhnd_erom subclass. 101 * 102 * The maximum size of subclasses is verified statically in 103 * BHND_EROM_DEFINE_CLASS(), and at runtime in bhnd_erom_init_static(). 104 */ 105 struct bhnd_erom_static { 106 struct bhnd_erom obj; 107 uint8_t idata[BHND_EROM_STATIC_BYTES]; 108 }; 109 110 /** Registered EROM parser class instances. */ 111 SET_DECLARE(bhnd_erom_class_set, bhnd_erom_class_t); 112 113 #define BHND_EROM_DEFINE_CLASS(name, classvar, methods, size) \ 114 DEFINE_CLASS_0(name, classvar, methods, size); \ 115 BHND_EROM_CLASS_DEF(classvar); \ 116 _Static_assert(size <= sizeof(struct bhnd_erom_static), \ 117 "cannot statically allocate instance data; " \ 118 "increase BHND_EROM_STATIC_BYTES"); 119 120 #define BHND_EROM_CLASS_DEF(classvar) DATA_SET(bhnd_erom_class_set, classvar) 121 122 /** 123 * Probe to see if this device enumeration class supports the bhnd bus 124 * mapped by @p eio, returning a standard newbus device probe result 125 * (see BUS_PROBE_*) and the probed chip identification. 126 * 127 * @param cls The erom class to probe. 128 * @param eio A bus I/O instance, configured with a mapping of the 129 * first bus core. 130 * @param hint Identification hint used to identify the device. 131 * If chipset supports standard chip identification 132 * registers within the first core, this parameter should 133 * be NULL. 134 * @param[out] cid On success, the probed chip identifier. 135 * 136 * @retval 0 if this is the only possible device enumeration 137 * parser for the probed bus. 138 * @retval negative if the probe succeeds, a negative value should be 139 * returned; the parser returning the highest negative 140 * value will be selected to handle device enumeration. 141 * @retval ENXIO If the bhnd bus type is not handled by this parser. 142 * @retval positive if an error occurs during probing, a regular unix error 143 * code should be returned. 144 */ 145 static inline int 146 bhnd_erom_probe(bhnd_erom_class_t *cls, struct bhnd_erom_io *eio, 147 const struct bhnd_chipid *hint, struct bhnd_chipid *cid) 148 { 149 return (BHND_EROM_PROBE(cls, eio, hint, cid)); 150 } 151 152 /** 153 * Parse all cores descriptors in @p erom, returning the array in @p cores and 154 * the count in @p num_cores. 155 * 156 * The memory allocated for the table must be freed via 157 * bhnd_erom_free_core_table(). 158 * 159 * @param erom The erom parser to be queried. 160 * @param[out] cores The table of parsed core descriptors. 161 * @param[out] num_cores The number of core records in @p cores. 162 * 163 * @retval 0 success 164 * @retval non-zero if an error occurs, a regular unix error code will 165 * be returned. 166 */ 167 static inline int 168 bhnd_erom_get_core_table(bhnd_erom_t *erom, struct bhnd_core_info **cores, 169 u_int *num_cores) 170 { 171 return (BHND_EROM_GET_CORE_TABLE(erom, cores, num_cores)); 172 } 173 174 /** 175 * Free any memory allocated in a previous call to BHND_EROM_GET_CORE_TABLE(). 176 * 177 * @param erom The erom parser instance. 178 * @param cores A core table allocated by @p erom. 179 */ 180 static inline void 181 bhnd_erom_free_core_table(bhnd_erom_t *erom, struct bhnd_core_info *cores) 182 { 183 return (BHND_EROM_FREE_CORE_TABLE(erom, cores)); 184 }; 185 186 /** 187 * Locate the first core table entry in @p erom that matches @p desc. 188 * 189 * @param erom The erom parser to be queried. 190 * @param desc A core match descriptor. 191 * @param[out] core On success, the matching core info record. 192 * 193 * @retval 0 success 194 * @retval ENOENT No core matching @p desc was found. 195 * @retval non-zero Reading or parsing failed. 196 */ 197 static inline int 198 bhnd_erom_lookup_core(bhnd_erom_t *erom, const struct bhnd_core_match *desc, 199 struct bhnd_core_info *core) 200 { 201 return (BHND_EROM_LOOKUP_CORE(erom, desc, core)); 202 } 203 204 /** 205 * Locate the first core table entry in @p erom that matches @p desc, 206 * and return the specified port region's base address and size. 207 * 208 * If a core matching @p desc is not found, or the requested port region 209 * is not mapped to the matching core, ENOENT is returned. 210 * 211 * @param erom The erom parser to be queried. 212 * @param desc A core match descriptor. 213 * @param type The port type to search for. 214 * @param port The port to search for. 215 * @param region The port region to search for. 216 * @param[out] core If not NULL, will be populated with the matched core 217 * info record on success. 218 * @param[out] addr On success, the base address of the port region. 219 * @param[out] size On success, the total size of the port region. 220 * 221 * @retval 0 success 222 * @retval ENOENT No core matching @p desc was found. 223 * @retval ENOENT No port region matching @p type, @p port, and @p region 224 * was found. 225 * @retval non-zero Reading or parsing failed. 226 */ 227 static inline int 228 bhnd_erom_lookup_core_addr(bhnd_erom_t *erom, const struct bhnd_core_match *desc, 229 bhnd_port_type type, u_int port, u_int region, struct bhnd_core_info *core, 230 bhnd_addr_t *addr, bhnd_size_t *size) 231 { 232 return (BHND_EROM_LOOKUP_CORE_ADDR(erom, desc, type, port, region, 233 core, addr, size)); 234 }; 235 236 /** 237 * Enumerate and print all entries in @p erom. 238 * 239 * @param erom The erom parser to be enumerated. 240 * 241 * @retval 0 success 242 * @retval non-zero If an error occurs parsing the EROM table, a regular 243 * unix error code will be returned. 244 */ 245 static inline int 246 bhnd_erom_dump(bhnd_erom_t *erom) 247 { 248 return (BHND_EROM_DUMP(erom)); 249 } 250 251 #endif /* _BHND_EROM_BHND_EROM_H_ */ 252