/src/cmp_tool/lib/rdcu_compress/rmap.h
Line | Count | Source (jump to first uncovered line) |
1 | | /** |
2 | | * @file rmap.h |
3 | | * @author Armin Luntzer (armin.luntzer@univie.ac.at) |
4 | | * @date 2018 |
5 | | * |
6 | | * @copyright GPLv2 |
7 | | * This program is free software; you can redistribute it and/or modify it |
8 | | * under the terms and conditions of the GNU General Public License, |
9 | | * version 2, as published by the Free Software Foundation. |
10 | | * |
11 | | * This program is distributed in the hope it will be useful, but WITHOUT |
12 | | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
13 | | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
14 | | * more details. |
15 | | * |
16 | | * @brief rmap command/reply helper functions |
17 | | */ |
18 | | |
19 | | #ifndef RMAP_H |
20 | | #define RMAP_H |
21 | | |
22 | | #include <stdint.h> |
23 | | #include <stddef.h> |
24 | | |
25 | | #include "../common/compiler.h" |
26 | | #include "../common/byteorder.h" |
27 | | |
28 | | /** |
29 | | * valid RMAP command codes, see Table 5-1 of ECSS‐E‐ST‐50‐52C |
30 | | * |
31 | | * all valid commands are made up of the four bits below |
32 | | */ |
33 | | |
34 | | |
35 | 0 | #define RMAP_CMD_BIT_WRITE 0x8 |
36 | | #define RMAP_CMD_BIT_VERIFY 0x4 |
37 | | #define RMAP_CMD_BIT_REPLY 0x2 |
38 | | #define RMAP_CMD_BIT_INC 0x1 |
39 | | |
40 | 0 | #define RMAP_READ_ADDR_SINGLE 0x2 |
41 | 0 | #define RMAP_READ_ADDR_INC 0x3 |
42 | 0 | #define RMAP_READ_MODIFY_WRITE_ADDR_INC 0x7 |
43 | 0 | #define RMAP_WRITE_ADDR_SINGLE 0x8 |
44 | 0 | #define RMAP_WRITE_ADDR_INC 0x9 |
45 | 0 | #define RMAP_WRITE_ADDR_SINGLE_REPLY 0xa |
46 | 0 | #define RMAP_WRITE_ADDR_INC_REPLY 0xb |
47 | 0 | #define RMAP_WRITE_ADDR_SINGLE_VERIFY 0xc |
48 | 0 | #define RMAP_WRITE_ADDR_INC_VERIFY 0xd |
49 | 0 | #define RMAP_WRITE_ADDR_SINGLE_VERIFY_REPLY 0xe |
50 | 0 | #define RMAP_WRITE_ADDR_INC_VERIFY_REPLY 0xf |
51 | | |
52 | | /** |
53 | | * RMAP error and status codes, see Table 5-4 of ECSS‐E‐ST‐50‐52C |
54 | | */ |
55 | | |
56 | 0 | #define RMAP_STATUS_SUCCESS 0x0 |
57 | 0 | #define RMAP_STATUS_GENERAL_ERROR 0x1 |
58 | 0 | #define RMAP_STATUS_UNUSED_TYPE_OR_CODE 0x2 |
59 | 0 | #define RMAP_STATUS_INVALID_KEY 0x3 |
60 | 0 | #define RMAP_STATUS_INVALID_DATA_CRC 0x4 |
61 | 0 | #define RMAP_STATUS_EARLY_EOP 0x5 |
62 | 0 | #define RMAP_STATUS_TOO_MUCH_DATA 0x6 |
63 | 0 | #define RMAP_STATUS_EEP 0x7 |
64 | 0 | #define RMAP_STATUS_RESERVED 0x8 |
65 | 0 | #define RMAP_STATUS_VERIFY_BUFFER_OVERRRUN 0x9 |
66 | 0 | #define RMAP_STATUS_CMD_NOT_IMPL_OR_AUTH 0xa |
67 | 0 | #define RMAP_STATUS_RMW_DATA_LEN_ERROR 0xb |
68 | 0 | #define RMAP_STATUS_INVALID_TARGET_LOGICAL_ADDR 0xc |
69 | | |
70 | | |
71 | | /** |
72 | | * RMAP minimum header sizes, see ECSS‐E‐ST‐50‐52C |
73 | | */ |
74 | | |
75 | 0 | #define RMAP_HDR_MIN_SIZE_WRITE_CMD 15 |
76 | 0 | #define RMAP_HDR_MIN_SIZE_WRITE_REP 7 |
77 | | |
78 | 0 | #define RMAP_HDR_MIN_SIZE_READ_CMD RMAP_HDR_MIN_SIZE_WRITE_CMD |
79 | 0 | #define RMAP_HDR_MIN_SIZE_READ_REP 11 |
80 | | |
81 | | #define RMAP_HDR_MIN_SIZE_RMW_CMD RMAP_HDR_MIN_SIZE_READ_CMD |
82 | | #define RMAP_HDR_MIN_SIZE_RMW_REP RMAP_HDR_MIN_SIZE_READ_REP |
83 | | |
84 | | |
85 | | |
86 | | /* RMAP header bytes in relative offsets following last entry in target path */ |
87 | 0 | #define RMAP_DEST_ADDRESS 0x00 |
88 | 0 | #define RMAP_PROTOCOL_ID 0x01 |
89 | 0 | #define RMAP_INSTRUCTION 0x02 |
90 | 0 | #define RMAP_CMD_DESTKEY 0x03 |
91 | 0 | #define RMAP_REPLY_STATUS RMAP_CMD_DESTKEY |
92 | 0 | #define RMAP_REPLY_ADDR_START 0x04 /* optional */ |
93 | | |
94 | | /* RMAP header bytes in relative offsets, add (reply address length * 4) */ |
95 | 0 | #define RMAP_SRC_ADDR 0x04 |
96 | 0 | #define RMAP_TRANS_ID_BYTE0 0x05 |
97 | 0 | #define RMAP_TRANS_ID_BYTE1 0x06 |
98 | | |
99 | | /* depending on the command, this is 0 or may contain an address extension */ |
100 | | #define RMAP_RESERVED 0x07 |
101 | | #define RMAP_EXTENDED RMAP_RESERVED |
102 | | |
103 | | /* optional RMAP header bytes in relative offsets */ |
104 | 0 | #define RMAP_ADDR_BYTE0 0x08 |
105 | 0 | #define RMAP_ADDR_BYTE1 0x09 |
106 | 0 | #define RMAP_ADDR_BYTE2 0x0a |
107 | 0 | #define RMAP_ADDR_BYTE3 0x0b |
108 | | |
109 | | /* RMAP header bytes in relative offsets (add extra 4 if address present) */ |
110 | 0 | #define RMAP_DATALEN_BYTE0 0x08 |
111 | 0 | #define RMAP_DATALEN_BYTE1 0x09 |
112 | 0 | #define RMAP_DATALEN_BYTE2 0x0a |
113 | 0 | #define RMAP_HEADER_CRC 0x0b |
114 | 0 | #define RMAP_DATA_START 0x0c |
115 | | |
116 | | /** |
117 | | * While the size of a SpW packet is in principl not limited, the size of the |
118 | | * header cannot be more than 255 bytes given the 8-bit width of the transfer |
119 | | * descriptor's HEADERLEN field in the GRSPW2 core, so we'll use that as our |
120 | | * limit. |
121 | | * |
122 | | * The reply address path can be at most 12 bytes, as the reply address length |
123 | | * field in the RMAP instruction field is only 2 bits wide and counts the |
124 | | * number of 32 bit words needed to hold the return path. |
125 | | * |
126 | | * The maximum data length is 2^24-1 bits |
127 | | * |
128 | | * All other fields in the header (not counting the header CRC) amount to |
129 | | * 27 bytes. |
130 | | * |
131 | | * @see GR712RC-UM v2.7 p112 and ECSS‐E‐ST‐50‐52C e.g. 5.3.1.1 |
132 | | */ |
133 | | |
134 | 0 | #define RMAP_MAX_PATH_LEN 15 |
135 | | #define RMAP_MAX_REPLY_ADDR_LEN 3 |
136 | 0 | #define RMAP_MAX_REPLY_PATH_LEN 12 |
137 | 0 | #define RMAP_MAX_DATA_LEN 0xFFFFFFUL |
138 | | |
139 | | |
140 | | /** |
141 | | * @brief RMAP header instruction field definition |
142 | | */ |
143 | | |
144 | | __extension__ |
145 | | struct rmap_instruction { |
146 | | #ifdef __BIG_ENDIAN |
147 | | uint8_t reserved:1; |
148 | | uint8_t cmd_resp:1; |
149 | | uint8_t cmd:4; |
150 | | uint8_t reply_addr_len:2; |
151 | | #elif defined(__LITTLE_ENDIAN) |
152 | | uint8_t reply_addr_len:2; |
153 | | uint8_t cmd:4; |
154 | | uint8_t cmd_resp:1; |
155 | | uint8_t reserved:1; |
156 | | #else |
157 | | #error "Unknown byte order" |
158 | | #endif |
159 | | } __attribute__((packed)); |
160 | | |
161 | | compile_time_assert(sizeof(struct rmap_instruction) == sizeof(uint8_t), RMAP_INSTRUCTION_STRUCT_WRONG_SIZE); |
162 | | |
163 | | |
164 | | /** |
165 | | * @brief This structure holds the relevant contents of an RMAP packet. |
166 | | * |
167 | | * @note this is NOT an actual RMAP packet! |
168 | | */ |
169 | | |
170 | | __extension__ |
171 | | struct rmap_pkt { |
172 | | uint8_t *path; /**< path to SpW target */ |
173 | | uint8_t path_len; /**< entries in the path */ |
174 | | uint8_t dst; /**< target logical address */ |
175 | | uint8_t proto_id; /**< protocol id (0x1 = RMAP */ |
176 | | union { |
177 | | struct rmap_instruction ri; |
178 | | uint8_t instruction; |
179 | | }; |
180 | | union { |
181 | | uint8_t key; /**< command authorisation key */ |
182 | | uint8_t status; /**< reply error/status codes */ |
183 | | }; |
184 | | uint8_t src; /**< initiator logical address */ |
185 | | uint8_t *rpath; /**< reply path */ |
186 | | uint8_t rpath_len; /**< entries in the reply path */ |
187 | | uint16_t tr_id; /**< transaction identifier */ |
188 | | uint32_t addr; /**< (first) data address */ |
189 | | uint8_t *data; |
190 | | uint32_t data_len; /**< length of data in bytes */ |
191 | | uint8_t hdr_crc; |
192 | | uint8_t data_crc; |
193 | | }; |
194 | | |
195 | | |
196 | | |
197 | | uint8_t rmap_crc8(const uint8_t *buf, const size_t len); |
198 | | |
199 | | struct rmap_pkt *rmap_create_packet(void); |
200 | | struct rmap_pkt *rmap_pkt_from_buffer(uint8_t *buf, uint32_t len); |
201 | | int rmap_build_hdr(struct rmap_pkt *pkt, uint8_t *hdr); |
202 | | int rmap_set_data_len(struct rmap_pkt *pkt, uint32_t len); |
203 | | void rmap_set_data_addr(struct rmap_pkt *pkt, uint32_t addr); |
204 | | int rmap_set_cmd(struct rmap_pkt *pkt, uint8_t cmd); |
205 | | |
206 | | |
207 | | void rmap_set_dst(struct rmap_pkt *pkt, uint8_t addr); |
208 | | void rmap_set_src(struct rmap_pkt *pkt, uint8_t addr); |
209 | | void rmap_set_key(struct rmap_pkt *pkt, uint8_t key); |
210 | | void rmap_set_tr_id(struct rmap_pkt *pkt, uint16_t id); |
211 | | |
212 | | int rmap_set_reply_path(struct rmap_pkt *pkt, const uint8_t *rpath, uint8_t len); |
213 | | int rmap_set_dest_path(struct rmap_pkt *pkt, const uint8_t *path, uint8_t len); |
214 | | |
215 | | |
216 | | void rmap_erase_packet(struct rmap_pkt *pkt); |
217 | | |
218 | | |
219 | | void rmap_parse_pkt(uint8_t *pkt); |
220 | | |
221 | | |
222 | | #endif /* RMAP_H */ |