-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtiny-eep.h
233 lines (217 loc) · 5.62 KB
/
tiny-eep.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
// SPDX-License-Identifier: BSD-2-Clause
/*
* Tiny EEPROM specification.
*
* Copyright (c) 2023, Kontron Europe GmbH
*
* At the moment, the only supported encoding are ASCII strings, but
* they are not terminated by a NUL byte. Instead, the last character
* of a string has the most significant bit set.
*
* After the strings pool, there is a CRC8 checksum.
*
* Sometimes, there are tight size constrains and the usual KEU EEPROM
* (similar to the PICMG EEP) specification cannot be used. This
* specification tries to fill that gap.
*
* There is a three byte header consisting of a magic value 'V' (for
* 'V'PD), a version and the total length. The version is set to 2
* because there already exist EEPROM contents with version 1. This is
* the generalized successor of the former specification (which was
* just used on one board).
*
* The basic idea is to have the usual TLV pairs, so older parsers can
* just skip unknown (to the older parser) types. The type and length
* are encoded in one byte. The length field has 4 bits, thus a TLV
* pair can be at most 17 bytes long. All TLV pairs are concatenated
* after the EEPROM header.
*
* To save space within a TLV (remember the largest value can just hold
* 16 bytes), strings are stored in a common pool. The type will specify
* the encoding of the strings stored in the pool. It is the duty of the
* encoding to determine the length of individual strings. To simplify
* things, there can only be one strings pool which needs to be the last
* TLV. If a parser cannot decode the strings pool, it shouldn't abort
* but just display any references as undecodable. A TLV pair can
* reference a string by an index.
*
* At the moment, the only supported encoding are ASCII strings, but
* they are not terminated by a NUL byte. Instead, the last character
* of a string has the most significant bit set.
*
* After the strings pool, there is a CRC8 checksum.
*/
#ifndef __TINY_EEP_H
#define __TINY_EEP_H
#include <stdint.h>
typedef uint8_t string_idx_t;
#define TINY_EEP_MAGIC 'V'
#define TINY_EEP_VERSION 2
struct eep_header {
uint8_t magic;
uint8_t version;
uint8_t length;
uint8_t data[];
};
/*
* Type length tag
*
* Bit Description
* 7:4 length
* 3:0 type id
*
* Type ids are only unique together with the length. This way, the id
* can be reused with another length.
* If the length is zero, the type is followed by one byte indicating
* its length. This way a tag can be up to 256 bytes long.
*
* Long Tags:
* 00h reserved
* 01h ASCII encoded strings pool
*
* Tags:
* 10h serial number
* 11h factory test flags
* 60h base MAC address
* 61h product identity
* 62h system product identity
* 80h product identity w/ batch code
* 81h system product identity w/ batch code
*/
#define TAG_LENGTH(x) ((x) >> 4 & 0xf)
enum {
TAG_ASCII_STRINGS = 0x01,
TAG_SERIAL_NUMBER = 0x10,
TAG_FACTORY_TEST_FLAGS = 0x11,
TAG_BASE_MAC_ADDRESS = 0x60,
TAG_PRODUCT_IDENTITY = 0x61,
TAG_SYSTEM_PRODUCT_IDENTITY = 0x62,
TAG_PRODUCT_IDENTITY_BATCH = 0x80,
TAG_SYSTEM_PRODUCT_IDENTITY_BATCH = 0x81,
};
/*
* Special ASCII encoded strings (tag 01h)
*
* Size: variable.
*/
struct tag_ascii_strings {
uint8_t tag;
uint8_t length;
uint8_t strings[0];
};
/*
* Serial number (tag 10h)
*
* Size: 2 bytes.
*/
struct tag_serial_number {
uint8_t tag;
string_idx_t serial_number;
} __attribute__((packed));
/*
* (Base) Hardware ethernet address (tag 60h)
*
* Due to size constraints, only the base MAC address is stored.
*
* Size: 7 bytes.
*/
struct tag_mac_address {
uint8_t tag;
uint8_t mac_address[6];
} __attribute__((packed));
/*
* Rev6
*
* Structure: MM NN II
*
* MM
* is alphanumeric, but has the form 0A, 0B, 0C, .., 00, 01, 02, ..
* Thus, we distiguish the two forms with the most significant bit
* and leave the remaining 7 bits as the actual value. Example values
* are 80h:'0A', 81h:'0B', 00h:'00', 63h:'99'.
* NN
* are digits, identity mapped
* Examples: 00h:'00', 01h:'01', 0Ah:'10', 63h:'99'
* II
* is alphanumeric. Treated as a free-form two characters value.
*
* Size: 4 bytes.
*/
struct rev6 {
uint8_t major;
#define MAJOR_PROTOTYPE 0x80
uint8_t minor;
char internal[2];
} __attribute__((packed));
/*
* Batch code
*
* Structure: MM NN BBBB II
*
* See Rev6 for MM, NN and II.
*
* BBBB
* are digits, identity mapped
*
* Size: 6 bytes.
*/
struct batch_code {
struct rev6 rev6;
uint16_t batch;
} __attribute__((packed));
/*
* Product identity (tag 61h or 62h)
*
* Combine serial number, part number and rev6 to uniquely identify
* a product.
*
* Serial number and part number are pointers to the strings pool
* and are flexible in size;
*
* Size: 7 bytes.
*
*/
struct tag_product_identity {
uint8_t tag;
string_idx_t serial_number;
string_idx_t part_number;
struct rev6 rev6;
} __attribute__((packed));
/*
* Product identity with batch (tag 80h or 81h)
*
* Combine serial number, part number and batch code to uniquely
* identify a product.
*
* Serial number and part number are pointers to the strings pool
* and are flexible in size;
*
* Size: 9 bytes.
*
*/
struct tag_product_identity_batch {
uint8_t tag;
string_idx_t serial_number;
string_idx_t part_number;
struct batch_code batch_code;
} __attribute__((packed));
/*
* Factory test flags (tag 11h)
*
* Bit Description
* 7 reserved
* 6 reserved
* 5 reserved
* 4 reserved
* 3 system test successful
* 2 burn-in test successful
* 1 configuration test successful
* 0 assembly test successful
*
* Size: 2 bytes.
*/
struct tag_factory_test_flags {
uint8_t tag;
uint8_t flags;
};
#endif /* __TINY_EEP_H */