1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3  * (C) Copyright 2017
4  * Mario Six,  Guntermann & Drunck GmbH, mario.six@gdsys.cc
5  */
6 
7 #ifndef __SYSINFO_H__
8 #define __SYSINFO_H__
9 
10 #include <linux/errno.h>
11 
12 struct udevice;
13 
14 #define SYSINFO_CACHE_LVL_MAX 3
15 
16 /*
17  * This uclass encapsulates hardware methods to gather information about a
18  * sysinfo or a specific device such as hard-wired GPIOs on GPIO expanders,
19  * read-only data in flash ICs, or similar.
20  *
21  * The interface offers functions to read the usual standard data types (bool,
22  * int, string) from the device, each of which is identified by a static
23  * numeric ID (which will usually be defined as a enum in a header file).
24  *
25  * If for example the sysinfo had a read-only serial number flash IC, we could
26  * call
27  *
28  * ret = sysinfo_detect(dev);
29  * if (ret) {
30  *	debug("sysinfo device not found.");
31  *	return ret;
32  * }
33  *
34  * ret = sysinfo_get_int(dev, ID_SERIAL_NUMBER, &serial);
35  * if (ret) {
36  *	debug("Error when reading serial number from device.");
37  *	return ret;
38  * }
39  *
40  * to read the serial number.
41  */
42 
43 /** enum sysinfo_id - Standard IDs defined by U-Boot */
44 enum sysinfo_id {
45 	SYSID_NONE,
46 
47 	/* BIOS Information (Type 0) */
48 	SYSID_SM_BIOS_VENDOR,
49 	SYSID_SM_BIOS_VER,
50 	SYSID_SM_BIOS_REL_DATE,
51 
52 	/* System Information (Type 1) */
53 	SYSID_SM_SYSTEM_MANUFACTURER,
54 	SYSID_SM_SYSTEM_PRODUCT,
55 	SYSID_SM_SYSTEM_VERSION,
56 	SYSID_SM_SYSTEM_SERIAL,
57 	SYSID_SM_SYSTEM_WAKEUP,
58 	SYSID_SM_SYSTEM_SKU,
59 	SYSID_SM_SYSTEM_FAMILY,
60 	SYSID_SM_SYSTEM_UUID,
61 
62 	/* Baseboard (or Module) Information (Type 2) */
63 	SYSID_SM_BASEBOARD_MANUFACTURER,
64 	SYSID_SM_BASEBOARD_PRODUCT,
65 	SYSID_SM_BASEBOARD_VERSION,
66 	SYSID_SM_BASEBOARD_SERIAL,
67 	SYSID_SM_BASEBOARD_ASSET_TAG,
68 	SYSID_SM_BASEBOARD_FEATURE,
69 	SYSID_SM_BASEBOARD_CHASSIS_LOCAT,
70 	SYSID_SM_BASEBOARD_TYPE,
71 	SYSID_SM_BASEBOARD_OBJS_NUM,
72 	SYSID_SM_BASEBOARD_OBJS_HANDLE,
73 
74 	/* System Enclosure or Chassis (Type 3) */
75 	SYSID_SM_ENCLOSURE_MANUFACTURER,
76 	SYSID_SM_ENCLOSURE_VERSION,
77 	SYSID_SM_ENCLOSURE_SERIAL,
78 	SYSID_SM_ENCLOSURE_ASSET_TAG,
79 	SYSID_SM_ENCLOSURE_TYPE,
80 	SYSID_SM_ENCLOSURE_BOOTUP,
81 	SYSID_SM_ENCLOSURE_POW,
82 	SYSID_SM_ENCLOSURE_THERMAL,
83 	SYSID_SM_ENCLOSURE_SECURITY,
84 	SYSID_SM_ENCLOSURE_OEM,
85 	SYSID_SM_ENCLOSURE_HEIGHT,
86 	SYSID_SM_ENCLOSURE_POWCORE_NUM,
87 	SYSID_SM_ENCLOSURE_ELEMENT_CNT,
88 	SYSID_SM_ENCLOSURE_ELEMENT_LEN,
89 	SYSID_SM_ENCLOSURE_ELEMENTS,
90 	SYSID_SM_ENCLOSURE_SKU,
91 
92 	/* Processor Information (Type 4) */
93 	SYSID_SM_PROCESSOR_SOCKET,
94 	SYSID_SM_PROCESSOR_TYPE,
95 	SYSID_SM_PROCESSOR_MANUFACT,
96 	SYSID_SM_PROCESSOR_ID,
97 	SYSID_SM_PROCESSOR_VERSION,
98 	SYSID_SM_PROCESSOR_VOLTAGE,
99 	SYSID_SM_PROCESSOR_EXT_CLOCK,
100 	SYSID_SM_PROCESSOR_MAX_SPEED,
101 	SYSID_SM_PROCESSOR_CUR_SPEED,
102 	SYSID_SM_PROCESSOR_STATUS,
103 	SYSID_SM_PROCESSOR_UPGRADE,
104 	SYSID_SM_PROCESSOR_SN,
105 	SYSID_SM_PROCESSOR_ASSET_TAG,
106 	SYSID_SM_PROCESSOR_PN,
107 	SYSID_SM_PROCESSOR_CORE_CNT,
108 	SYSID_SM_PROCESSOR_CORE_EN,
109 	SYSID_SM_PROCESSOR_THREAD_CNT,
110 	SYSID_SM_PROCESSOR_CHARA,
111 	SYSID_SM_PROCESSOR_FAMILY,
112 	SYSID_SM_PROCESSOR_FAMILY2,
113 	SYSID_SM_PROCESSOR_CORE_CNT2,
114 	SYSID_SM_PROCESSOR_CORE_EN2,
115 	SYSID_SM_PROCESSOR_THREAD_CNT2,
116 	SYSID_SM_PROCESSOR_THREAD_EN,
117 
118 	/*
119 	 * Cache Information (Type 7)
120 	 * Each of the id should reserve space for up to
121 	 * SYSINFO_CACHE_LVL_MAX levels of cache
122 	 */
123 	SYSID_SM_CACHE_LEVEL,
124 	SYSID_SM_CACHE_HANDLE,
125 	SYSID_SM_CACHE_INFO_START,
126 	SYSID_SM_CACHE_SOCKET = SYSID_SM_CACHE_INFO_START,
127 	SYSID_SM_CACHE_CONFIG =
128 		SYSID_SM_CACHE_SOCKET + SYSINFO_CACHE_LVL_MAX,
129 	SYSID_SM_CACHE_MAX_SIZE =
130 		SYSID_SM_CACHE_CONFIG + SYSINFO_CACHE_LVL_MAX,
131 	SYSID_SM_CACHE_INST_SIZE =
132 		SYSID_SM_CACHE_MAX_SIZE + SYSINFO_CACHE_LVL_MAX,
133 	SYSID_SM_CACHE_SUPSRAM_TYPE =
134 		SYSID_SM_CACHE_INST_SIZE + SYSINFO_CACHE_LVL_MAX,
135 	SYSID_SM_CACHE_CURSRAM_TYPE =
136 		SYSID_SM_CACHE_SUPSRAM_TYPE + SYSINFO_CACHE_LVL_MAX,
137 	SYSID_SM_CACHE_SPEED =
138 		SYSID_SM_CACHE_CURSRAM_TYPE + SYSINFO_CACHE_LVL_MAX,
139 	SYSID_SM_CACHE_ERRCOR_TYPE =
140 		SYSID_SM_CACHE_SPEED + SYSINFO_CACHE_LVL_MAX,
141 	SYSID_SM_CACHE_SCACHE_TYPE =
142 		SYSID_SM_CACHE_ERRCOR_TYPE + SYSINFO_CACHE_LVL_MAX,
143 	SYSID_SM_CACHE_ASSOC =
144 		SYSID_SM_CACHE_SCACHE_TYPE + SYSINFO_CACHE_LVL_MAX,
145 	SYSID_SM_CACHE_MAX_SIZE2 =
146 		SYSID_SM_CACHE_ASSOC + SYSINFO_CACHE_LVL_MAX,
147 	SYSID_SM_CACHE_INST_SIZE2 =
148 		SYSID_SM_CACHE_MAX_SIZE2 + SYSINFO_CACHE_LVL_MAX,
149 	SYSID_SM_CACHE_INFO_END =
150 		SYSID_SM_CACHE_INST_SIZE2 + SYSINFO_CACHE_LVL_MAX - 1,
151 
152 	/* For show_board_info() */
153 	SYSID_BOARD_MODEL,
154 	SYSID_BOARD_MANUFACTURER,
155 	SYSID_BOARD_MAC_ADDR,
156 	SYSID_BOARD_RAM_SIZE_MB,
157 	SYSID_PRIOR_STAGE_VERSION,
158 	SYSID_PRIOR_STAGE_DATE,
159 
160 	/* First value available for downstream/board used */
161 	SYSID_USER = 0x1000,
162 };
163 
164 struct sysinfo_ops {
165 	/**
166 	 * detect() - Run the hardware info detection procedure for this
167 	 *	      device.
168 	 * @dev:      The device containing the information
169 	 *
170 	 * This operation might take a long time (e.g. read from EEPROM,
171 	 * check the presence of a device on a bus etc.), hence this is not
172 	 * done in the probe() method, but later during operation in this
173 	 * dedicated method. This method will be called before any other
174 	 * methods.
175 	 *
176 	 * Return: 0 if OK, -ve on error.
177 	 */
178 	int (*detect)(struct udevice *dev);
179 
180 	/**
181 	 * get_bool() - Read a specific bool data value that describes the
182 	 *		hardware setup.
183 	 * @dev:	The sysinfo instance to gather the data.
184 	 * @id:		A unique identifier for the bool value to be read.
185 	 * @val:	Pointer to a buffer that receives the value read.
186 	 *
187 	 * Return: 0 if OK, -ve on error.
188 	 */
189 	int (*get_bool)(struct udevice *dev, int id, bool *val);
190 
191 	/**
192 	 * get_int() - Read a specific int data value that describes the
193 	 *	       hardware setup.
194 	 * @dev:       The sysinfo instance to gather the data.
195 	 * @id:        A unique identifier for the int value to be read.
196 	 * @val:       Pointer to a buffer that receives the value read.
197 	 *
198 	 * Return: 0 if OK, -ve on error.
199 	 */
200 	int (*get_int)(struct udevice *dev, int id, int *val);
201 
202 	/**
203 	 * get_str() - Read a specific string data value that describes the
204 	 *	       hardware setup.
205 	 * @dev:	The sysinfo instance to gather the data.
206 	 * @id:		A unique identifier for the string value to be read.
207 	 * @size:	The size of the buffer to receive the string data.
208 	 * @val:	Pointer to a buffer that receives the value read.
209 	 *
210 	 * Return: 0 if OK, -ve on error.
211 	 */
212 	int (*get_str)(struct udevice *dev, int id, size_t size, char *val);
213 
214 	/**
215 	 * get_data() - Read a specific string data value that describes the
216 	 *	       hardware setup.
217 	 * @dev:	The sysinfo instance to gather the data.
218 	 * @id:		A unique identifier for the data area to be get.
219 	 * @data:	Pointer to the address of the data area.
220 	 * @size:	Pointer to the size of the data area.
221 	 *
222 	 * Return: 0 if OK, -ve on error.
223 	 */
224 	int (*get_data)(struct udevice *dev, int id, void **data, size_t *size);
225 
226 	/**
227 	 * get_item_count() - Get the item count of the specific data area that
228 	 *		describes the hardware setup.
229 	 * @dev:	The sysinfo instance to gather the data.
230 	 * @id:		A unique identifier for the data area to be get.
231 	 *
232 	 * Return: non-negative item count if OK, -ve on error.
233 	 */
234 	int (*get_item_count)(struct udevice *dev, int id);
235 
236 	/**
237 	 * get_data_by_index() - Get a data value by index from the platform.
238 	 *
239 	 * @dev:	The sysinfo instance to gather the data.
240 	 * @id:		A unique identifier for the data area to be get.
241 	 * @index:	The item index, starting from 0.
242 	 * @data:	Pointer to the address of the data area.
243 	 * @size:	Pointer to the size of the data area.
244 	 *
245 	 * Return: 0 if OK, -ve on error.
246 	 */
247 	int (*get_data_by_index)(struct udevice *dev, int id, int index,
248 				 void **data, size_t *size);
249 
250 	/**
251 	 * get_fit_loadable - Get the name of an image to load from FIT
252 	 * This function can be used to provide the image names based on runtime
253 	 * detection. A classic use-case would when DTBOs are used to describe
254 	 * additional daughter cards.
255 	 *
256 	 * @dev:	The sysinfo instance to gather the data.
257 	 * @index:	Index of the image. Starts at 0 and gets incremented
258 	 *		after each call to this function.
259 	 * @type:	The type of image. For example, "fdt" for DTBs
260 	 * @strp:	A pointer to string. Untouched if the function fails
261 	 *
262 	 * Return: 0 if OK, -ENOENT if no loadable is available else -ve on
263 	 * error.
264 	 */
265 	int (*get_fit_loadable)(struct udevice *dev, int index,
266 				const char *type, const char **strp);
267 };
268 
269 #define sysinfo_get_ops(dev)	((struct sysinfo_ops *)(dev)->driver->ops)
270 
271 #if CONFIG_IS_ENABLED(SYSINFO)
272 /**
273  * sysinfo_detect() - Run the hardware info detection procedure for this device.
274  *
275  * @dev:	The device containing the information
276  *
277  * This function must be called before any other accessor function for this
278  * device.
279  *
280  * Return: 0 if OK, -ve on error.
281  */
282 int sysinfo_detect(struct udevice *dev);
283 
284 /**
285  * sysinfo_get_bool() - Read a specific bool data value that describes the
286  *		      hardware setup.
287  * @dev:	The sysinfo instance to gather the data.
288  * @id:		A unique identifier for the bool value to be read.
289  * @val:	Pointer to a buffer that receives the value read.
290  *
291  * Return: 0 if OK, -EPERM if called before sysinfo_detect(), else -ve on
292  * error.
293  */
294 int sysinfo_get_bool(struct udevice *dev, int id, bool *val);
295 
296 /**
297  * sysinfo_get_int() - Read a specific int data value that describes the
298  *		     hardware setup.
299  * @dev:	The sysinfo instance to gather the data.
300  * @id:		A unique identifier for the int value to be read.
301  * @val:	Pointer to a buffer that receives the value read.
302  *
303  * Return: 0 if OK, -EPERM if called before sysinfo_detect(), else -ve on
304  * error.
305  */
306 int sysinfo_get_int(struct udevice *dev, int id, int *val);
307 
308 /**
309  * sysinfo_get_str() - Read a specific string data value that describes the
310  *		     hardware setup.
311  * @dev:	The sysinfo instance to gather the data.
312  * @id:		A unique identifier for the string value to be read.
313  * @size:	The size of the buffer to receive the string data.
314  * @val:	Pointer to a buffer that receives the value read.
315  *
316  * Return: 0 if OK, -EPERM if called before sysinfo_detect(), else -ve on
317  * error.
318  */
319 int sysinfo_get_str(struct udevice *dev, int id, size_t size, char *val);
320 
321 /**
322  * sysinfo_get_data() - Get a data area from the platform.
323  * @dev:	The sysinfo instance to gather the data.
324  * @id:		A unique identifier for the data area to be get.
325  * @data:	Pointer to the address of the data area.
326  * @size:	Pointer to the size of the data area.
327  *
328  * Return: 0 if OK, -EPERM if called before sysinfo_detect(), else -ve on
329  * error.
330  */
331 int sysinfo_get_data(struct udevice *dev, int id, void **data, size_t *size);
332 
333 /**
334  * sysinfo_get_item_count() - Get the item count of the specific data area that
335  *			    describes the hardware setup.
336  * @dev:	The sysinfo instance to gather the data.
337  * @id:		A unique identifier for the data area to be get.
338  *
339  * Return: non-negative item count if OK, -EPERM if called before
340  * sysinfo_detect(), else -ve on error.
341  */
342 int sysinfo_get_item_count(struct udevice *dev, int id);
343 
344 /**
345  * sysinfo_get_data_by_index() - Get a data value by index from the platform.
346  *
347  * @dev:	The sysinfo instance to gather the data.
348  * @id:		A unique identifier for the data area to be get.
349  * @index:	The item index, starting from 0.
350  * @data:	Pointer to the address of the data area.
351  * @size:	Pointer to the size of the data area.
352  *
353  * Return: 0 if OK, -EPERM if called before sysinfo_detect(), else -ve on
354  * error.
355  */
356 int sysinfo_get_data_by_index(struct udevice *dev, int id, int index,
357 			      void **data, size_t *size);
358 
359 /**
360  * sysinfo_get() - Return the sysinfo device for the sysinfo in question.
361  * @devp: Pointer to structure to receive the sysinfo device.
362  *
363  * Since there can only be at most one sysinfo instance, the API can supply a
364  * function that returns the unique device. This is especially useful for use
365  * in sysinfo files.
366  *
367  * Return: 0 if OK, -EPERM if called before sysinfo_detect(), else -ve on
368  * error.
369  */
370 int sysinfo_get(struct udevice **devp);
371 
372 /**
373  * sysinfo_get_fit_loadable - Get the name of an image to load from FIT
374  * This function can be used to provide the image names based on runtime
375  * detection. A classic use-case would when DTBOs are used to describe
376  * additional daughter cards.
377  *
378  * @dev:	The sysinfo instance to gather the data.
379  * @index:	Index of the image. Starts at 0 and gets incremented
380  *		after each call to this function.
381  * @type:	The type of image. For example, "fdt" for DTBs
382  * @strp:	A pointer to string. Untouched if the function fails
383  *
384  *
385  * Return: 0 if OK, -EPERM if called before sysinfo_detect(), -ENOENT if no
386  * loadable is available else -ve on error.
387  */
388 int sysinfo_get_fit_loadable(struct udevice *dev, int index, const char *type,
389 			     const char **strp);
390 
391 #else
392 
sysinfo_detect(struct udevice * dev)393 static inline int sysinfo_detect(struct udevice *dev)
394 {
395 	return -ENOSYS;
396 }
397 
sysinfo_get_bool(struct udevice * dev,int id,bool * val)398 static inline int sysinfo_get_bool(struct udevice *dev, int id, bool *val)
399 {
400 	return -ENOSYS;
401 }
402 
sysinfo_get_int(struct udevice * dev,int id,int * val)403 static inline int sysinfo_get_int(struct udevice *dev, int id, int *val)
404 {
405 	return -ENOSYS;
406 }
407 
sysinfo_get_str(struct udevice * dev,int id,size_t size,char * val)408 static inline int sysinfo_get_str(struct udevice *dev, int id, size_t size,
409 				  char *val)
410 {
411 	return -ENOSYS;
412 }
413 
sysinfo_get_data(struct udevice * dev,int id,void ** data,size_t * size)414 static inline int sysinfo_get_data(struct udevice *dev, int id, void **data,
415 				   size_t *size)
416 {
417 	return -ENOSYS;
418 }
419 
sysinfo_get_item_count(struct udevice * dev,int id)420 static inline int sysinfo_get_item_count(struct udevice *dev, int id)
421 {
422 	return -ENOSYS;
423 }
424 
sysinfo_get_data_by_index(struct udevice * dev,int id,int index,void ** data,size_t * size)425 static inline int sysinfo_get_data_by_index(struct udevice *dev, int id,
426 					    int index, void **data,
427 					    size_t *size)
428 {
429 	return -ENOSYS;
430 }
431 
sysinfo_get(struct udevice ** devp)432 static inline int sysinfo_get(struct udevice **devp)
433 {
434 	return -ENOSYS;
435 }
436 
sysinfo_get_fit_loadable(struct udevice * dev,int index,const char * type,const char ** strp)437 static inline int sysinfo_get_fit_loadable(struct udevice *dev, int index,
438 					   const char *type, const char **strp)
439 {
440 	return -ENOSYS;
441 }
442 
443 #endif
444 #endif
445