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 * $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 /** Number of additional bytes to reserve for statically allocated 94 * bhnd_erom instances. */ 95 #define BHND_EROM_STATIC_BYTES 64 96 97 /** 98 * A bhnd_erom instance structure large enough to statically allocate 99 * any known bhnd_erom subclass. 100 * 101 * The maximum size of subclasses is verified statically in 102 * BHND_EROM_DEFINE_CLASS(), and at runtime in bhnd_erom_init_static(). 103 */ 104 struct bhnd_erom_static { 105 struct bhnd_erom obj; 106 uint8_t idata[BHND_EROM_STATIC_BYTES]; 107 }; 108 109 /** Registered EROM parser class instances. */ 110 SET_DECLARE(bhnd_erom_class_set, bhnd_erom_class_t); 111 112 #define BHND_EROM_DEFINE_CLASS(name, classvar, methods, size) \ 113 DEFINE_CLASS_0(name, classvar, methods, size); \ 114 BHND_EROM_CLASS_DEF(classvar); \ 115 _Static_assert(size <= sizeof(struct bhnd_erom_static), \ 116 "cannot statically allocate instance data; " \ 117 "increase BHND_EROM_STATIC_BYTES"); 118 119 #define BHND_EROM_CLASS_DEF(classvar) DATA_SET(bhnd_erom_class_set, classvar) 120 121 /** 122 * Probe to see if this device enumeration class supports the bhnd bus 123 * mapped by @p eio, returning a standard newbus device probe result 124 * (see BUS_PROBE_*) and the probed chip identification. 125 * 126 * @param cls The erom class to probe. 127 * @param eio A bus I/O instance, configured with a mapping of the 128 * first bus core. 129 * @param hint Identification hint used to identify the device. 130 * If chipset supports standard chip identification 131 * registers within the first core, this parameter should 132 * be NULL. 133 * @param[out] cid On success, the probed chip identifier. 134 * 135 * @retval 0 if this is the only possible device enumeration 136 * parser for the probed bus. 137 * @retval negative if the probe succeeds, a negative value should be 138 * returned; the parser returning the highest negative 139 * value will be selected to handle device enumeration. 140 * @retval ENXIO If the bhnd bus type is not handled by this parser. 141 * @retval positive if an error occurs during probing, a regular unix error 142 * code should be returned. 143 */ 144 static inline int 145 bhnd_erom_probe(bhnd_erom_class_t *cls, struct bhnd_erom_io *eio, 146 const struct bhnd_chipid *hint, struct bhnd_chipid *cid) 147 { 148 return (BHND_EROM_PROBE(cls, eio, hint, cid)); 149 } 150 151 /** 152 * Parse all cores descriptors in @p erom, returning the array in @p cores and 153 * the count in @p num_cores. 154 * 155 * The memory allocated for the table must be freed via 156 * bhnd_erom_free_core_table(). 157 * 158 * @param erom The erom parser to be queried. 159 * @param[out] cores The table of parsed core descriptors. 160 * @param[out] num_cores The number of core records in @p cores. 161 * 162 * @retval 0 success 163 * @retval non-zero if an error occurs, a regular unix error code will 164 * be returned. 165 */ 166 static inline int 167 bhnd_erom_get_core_table(bhnd_erom_t *erom, struct bhnd_core_info **cores, 168 u_int *num_cores) 169 { 170 return (BHND_EROM_GET_CORE_TABLE(erom, cores, num_cores)); 171 } 172 173 /** 174 * Free any memory allocated in a previous call to BHND_EROM_GET_CORE_TABLE(). 175 * 176 * @param erom The erom parser instance. 177 * @param cores A core table allocated by @p erom. 178 */ 179 static inline void 180 bhnd_erom_free_core_table(bhnd_erom_t *erom, struct bhnd_core_info *cores) 181 { 182 return (BHND_EROM_FREE_CORE_TABLE(erom, cores)); 183 }; 184 185 /** 186 * Locate the first core table entry in @p erom that matches @p desc. 187 * 188 * @param erom The erom parser to be queried. 189 * @param desc A core match descriptor. 190 * @param[out] core On success, the matching core info record. 191 * 192 * @retval 0 success 193 * @retval ENOENT No core matching @p desc was found. 194 * @retval non-zero Reading or parsing failed. 195 */ 196 static inline int 197 bhnd_erom_lookup_core(bhnd_erom_t *erom, const struct bhnd_core_match *desc, 198 struct bhnd_core_info *core) 199 { 200 return (BHND_EROM_LOOKUP_CORE(erom, desc, core)); 201 } 202 203 /** 204 * Locate the first core table entry in @p erom that matches @p desc, 205 * and return the specified port region's base address and size. 206 * 207 * If a core matching @p desc is not found, or the requested port region 208 * is not mapped to the matching core, ENOENT is returned. 209 * 210 * @param erom The erom parser to be queried. 211 * @param desc A core match descriptor. 212 * @param type The port type to search for. 213 * @param port The port to search for. 214 * @param region The port region to search for. 215 * @param[out] core If not NULL, will be populated with the matched core 216 * info record on success. 217 * @param[out] addr On success, the base address of the port region. 218 * @param[out] size On success, the total size of the port region. 219 * 220 * @retval 0 success 221 * @retval ENOENT No core matching @p desc was found. 222 * @retval ENOENT No port region matching @p type, @p port, and @p region 223 * was found. 224 * @retval non-zero Reading or parsing failed. 225 */ 226 static inline int 227 bhnd_erom_lookup_core_addr(bhnd_erom_t *erom, const struct bhnd_core_match *desc, 228 bhnd_port_type type, u_int port, u_int region, struct bhnd_core_info *core, 229 bhnd_addr_t *addr, bhnd_size_t *size) 230 { 231 return (BHND_EROM_LOOKUP_CORE_ADDR(erom, desc, type, port, region, 232 core, addr, size)); 233 }; 234 235 /** 236 * Enumerate and print all entries in @p erom. 237 * 238 * @param erom The erom parser to be enumerated. 239 * 240 * @retval 0 success 241 * @retval non-zero If an error occurs parsing the EROM table, a regular 242 * unix error code will be returned. 243 */ 244 static inline int 245 bhnd_erom_dump(bhnd_erom_t *erom) 246 { 247 return (BHND_EROM_DUMP(erom)); 248 } 249 250 #endif /* _BHND_EROM_BHND_EROM_H_ */ 251