1 // SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
2 /* Copyright 2013-2017 IBM Corp. */
3 
4 #ifndef __HDIF_H
5 #define __HDIF_H
6 
7 #include <skiboot.h>
8 #include <types.h>
9 #include <ccan/endian/endian.h>
10 
11 struct HDIF_common_hdr {
12 	__be16	d1f0;		/* 0xd1f0 */
13 	char	id[6];		/* eye catcher string */
14 	__be16	instnum;	/* instance number */
15 	__be16	version;	/* version */
16 	__be32	total_len;	/* total structure length */
17 	__be32	hdr_len;	/* header length (currently 0x20) */
18 	__be32	idptr_off;	/* offset to idata pointers */
19 	__be16	idptr_count;	/* number of idata pointers */
20 	__be16	child_count;	/* number of child structures */
21 	__be32	child_off;	/* offset to child structures array */
22 } __packed __align(0x10);
23 
24 struct HDIF_idata_ptr {
25 	__be32	offset;
26 	__be32	size;
27 } __packed __align(0x8);
28 
29 struct HDIF_array_hdr {
30 	__be32	offset;
31 	__be32	ecnt;
32 	__be32	esize;
33 	__be32	eactsz;
34 } __packed __align(0x4);
35 
36 struct HDIF_child_ptr {
37 	__be32	offset;
38 	__be32	size;
39 	__be32	count;
40 } __packed;
41 
42 #define HDIF_HDR_LEN		(sizeof(struct HDIF_common_hdr))
43 #define HDIF_ARRAY_OFFSET	(sizeof(struct HDIF_array_hdr))
44 
45 #define HDIF_ID(_id)		.d1f0 = CPU_TO_BE16(0xd1f0), .id = _id
46 
47 #define HDIF_SIMPLE_HDR(id, vers, type)			\
48 {							\
49 	HDIF_ID(id),					\
50 	.instnum	= CPU_TO_BE16(0),		\
51 	.version	= CPU_TO_BE16(vers),		\
52 	.total_len	= CPU_TO_BE32(sizeof(type)),	\
53 	.hdr_len	= CPU_TO_BE32(HDIF_HDR_LEN),	\
54 	.idptr_off	= CPU_TO_BE32(HDIF_HDR_LEN),	\
55 	.idptr_count	= CPU_TO_BE16(1),		\
56 	.child_count	= CPU_TO_BE16(0),		\
57 	.child_off	= CPU_TO_BE32(0),		\
58 }
59 
60 #define HDIF_IDATA_PTR(_offset, _size)			\
61 {							\
62 	.offset	= CPU_TO_BE32(_offset),			\
63 	.size	= CPU_TO_BE32(_size),			\
64 }
65 
HDIF_check(const void * hdif,const char id[])66 static inline bool HDIF_check(const void *hdif, const char id[])
67 {
68 	const struct HDIF_common_hdr *hdr = hdif;
69 
70 	return hdr->d1f0 == CPU_TO_BE16(0xd1f0) &&
71 		memcmp(hdr->id, id, sizeof(hdr->id)) == 0;
72 }
73 
74 /* HDIF_get_idata - Get a pointer to internal data block
75  *
76  * @hdif  : HDIF structure pointer
77  * @di    : Index of the idata pointer
78  * @size  : Return the data size (or NULL if ignored)
79  */
80 extern const void *HDIF_get_idata(const struct HDIF_common_hdr *hdif,
81 				  unsigned int di,
82 				  unsigned int *size);
83 
84 /* HDIF_get_iarray - Get a pointer to an elemnt of an internal data array
85  *
86  * @hdif  : HDIF structure pointer
87  * @di    : Index of the idata pointer
88  * @ai    : Index in the resulting array
89  * @size  : Return the entry actual size (or NULL if ignored)
90  */
91 extern const void *HDIF_get_iarray_item(const struct HDIF_common_hdr *hdif,
92 					unsigned int di,
93 					unsigned int ai, unsigned int *size);
94 
95 /* HDIF_get_iarray - Get a pointer to an internal array header
96  *
97  * @hdif  : HDIF structure pointer
98  * @di    : Index of the idata pointer
99  * @ai    : Index in the resulting array
100  * @size  : Return the entry actual size (or NULL if ignored)
101  */
102 extern const struct HDIF_array_hdr *HDIF_get_iarray(
103 		const struct HDIF_common_hdr *hdif, unsigned int di,
104 		unsigned int *items);
105 
106 extern const void *HDIF_iarray_item(const struct HDIF_array_hdr *hdif,
107 				unsigned int index);
108 
109 #define HDIF_iarray_for_each(arr, idx, ptr) \
110 	for (idx = 0, ptr = HDIF_iarray_item(arr, idx); \
111 		ptr; idx++, ptr = HDIF_iarray_item(arr, idx))
112 
113 /* HDIF_get_iarray_size - Get the number of elements of an internal data array
114  *
115  * @hdif  : HDIF structure pointer
116  * @di    : Index of the idata pointer
117  *
118  * A negative result means an error
119  */
120 extern int HDIF_get_iarray_size(const struct HDIF_common_hdr *hdif,
121 				unsigned int di);
122 
123 /* HDIF_child_arr - Get a child array from this HDIF.
124  *
125  * @hdif  : HDIF structure pointer
126  * @idx	  : the child to get
127  *
128  * NULL means an error (not that many children).
129  */
130 extern struct HDIF_child_ptr *
131 HDIF_child_arr(const struct HDIF_common_hdr *hdif, unsigned int idx);
132 
133 /* HDIF_child - Deref a child_ptr entry.
134  *
135  * @hdif  : HDIF structure pointer
136  * @child : the child returned from HDIF_child_arr
137  * @idx	  : the index of the child to get (< child->count).
138  * @eyecatcher: the 6-char ID expected for this child.
139  *
140  * NULL means an error.
141  */
142 extern struct HDIF_common_hdr *HDIF_child(const struct HDIF_common_hdr *hdif,
143 					  const struct HDIF_child_ptr *child,
144 					  unsigned int idx,
145 					  const char *eyecatcher);
146 #endif /* __HDIF_H */
147