xref: /freebsd/sys/dev/bhnd/bhnd_erom.h (revision 66fd12cf4896eb08ad8e7a2627537f84ead84dd3)
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