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
bhnd_erom_probe(bhnd_erom_class_t * cls,struct bhnd_erom_io * eio,const struct bhnd_chipid * hint,struct bhnd_chipid * cid)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
bhnd_erom_get_core_table(bhnd_erom_t * erom,struct bhnd_core_info ** cores,u_int * num_cores)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
bhnd_erom_free_core_table(bhnd_erom_t * erom,struct bhnd_core_info * cores)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
bhnd_erom_lookup_core(bhnd_erom_t * erom,const struct bhnd_core_match * desc,struct bhnd_core_info * core)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
bhnd_erom_lookup_core_addr(bhnd_erom_t * erom,const struct bhnd_core_match * desc,bhnd_port_type type,u_int port,u_int region,struct bhnd_core_info * core,bhnd_addr_t * addr,bhnd_size_t * size)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
bhnd_erom_dump(bhnd_erom_t * erom)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