diff options
Diffstat (limited to 'utils/hwstub/include/hwstub_protocol.h')
-rw-r--r-- | utils/hwstub/include/hwstub_protocol.h | 318 |
1 files changed, 318 insertions, 0 deletions
diff --git a/utils/hwstub/include/hwstub_protocol.h b/utils/hwstub/include/hwstub_protocol.h new file mode 100644 index 0000000000..39d2f2ebfe --- /dev/null +++ b/utils/hwstub/include/hwstub_protocol.h | |||
@@ -0,0 +1,318 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2012 by Amaury Pouly | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #ifndef __HWSTUB_PROTOCOL__ | ||
22 | #define __HWSTUB_PROTOCOL__ | ||
23 | |||
24 | #include <stdint.h> | ||
25 | |||
26 | /** | ||
27 | * This file contains the data structures used in the USB and network protocol. | ||
28 | * All USB data uses the standard USB byte order which is little-endian. | ||
29 | */ | ||
30 | |||
31 | /** | ||
32 | * HWStub protocol version | ||
33 | */ | ||
34 | |||
35 | #define HWSTUB_VERSION_MAJOR 4 | ||
36 | #define HWSTUB_VERSION_MINOR 2 | ||
37 | |||
38 | #define HWSTUB_VERSION__(maj, min) #maj"."#min | ||
39 | #define HWSTUB_VERSION_(maj, min) HWSTUB_VERSION__(maj, min) | ||
40 | #define HWSTUB_VERSION HWSTUB_VERSION_(HWSTUB_VERSION_MAJOR, HWSTUB_VERSION_MINOR) | ||
41 | |||
42 | /** | ||
43 | * A device can use any VID:PID but in case hwstub is in full control of the | ||
44 | * device, the preferred VID:PID is the following. | ||
45 | */ | ||
46 | |||
47 | #define HWSTUB_USB_VID 0xfee1 | ||
48 | #define HWSTUB_USB_PID 0xdead | ||
49 | |||
50 | /** | ||
51 | * The device class should be per interface and the hwstub interface must use | ||
52 | * the following class, subclass and protocol. | ||
53 | */ | ||
54 | |||
55 | #define HWSTUB_CLASS 0xff | ||
56 | #define HWSTUB_SUBCLASS 0xde | ||
57 | #define HWSTUB_PROTOCOL 0xad | ||
58 | |||
59 | /********************************** | ||
60 | * Descriptors | ||
61 | **********************************/ | ||
62 | |||
63 | /** | ||
64 | * Descriptors can be retrieved using configuration descriptor or individually | ||
65 | * using the standard GetDescriptor request on the interface. | ||
66 | */ | ||
67 | |||
68 | #define HWSTUB_DT_VERSION 0x41 /* mandatory */ | ||
69 | #define HWSTUB_DT_LAYOUT 0x42 /* mandatory */ | ||
70 | #define HWSTUB_DT_TARGET 0x43 /* mandatory */ | ||
71 | #define HWSTUB_DT_STMP 0x44 /* mandatory for STMP */ | ||
72 | #define HWSTUB_DT_PP 0x45 /* mandatory for PP */ | ||
73 | #define HWSTUB_DT_JZ 0x46 /* mandatory for JZ */ | ||
74 | |||
75 | struct hwstub_version_desc_t | ||
76 | { | ||
77 | uint8_t bLength; | ||
78 | uint8_t bDescriptorType; | ||
79 | /* full version information */ | ||
80 | uint8_t bMajor; | ||
81 | uint8_t bMinor; | ||
82 | uint8_t bRevision; | ||
83 | } __attribute__((packed)); | ||
84 | |||
85 | struct hwstub_layout_desc_t | ||
86 | { | ||
87 | uint8_t bLength; | ||
88 | uint8_t bDescriptorType; | ||
89 | /* describe the range of memory used by the running code */ | ||
90 | uint32_t dCodeStart; | ||
91 | uint32_t dCodeSize; | ||
92 | /* describe the range of memory used by the stack */ | ||
93 | uint32_t dStackStart; | ||
94 | uint32_t dStackSize; | ||
95 | /* describe the range of memory available as a buffer */ | ||
96 | uint32_t dBufferStart; | ||
97 | uint32_t dBufferSize; | ||
98 | } __attribute__((packed)); | ||
99 | |||
100 | struct hwstub_stmp_desc_t | ||
101 | { | ||
102 | uint8_t bLength; | ||
103 | uint8_t bDescriptorType; | ||
104 | /* Chip ID and revision */ | ||
105 | uint16_t wChipID; /* 0x3780 for STMP3780 for example */ | ||
106 | uint8_t bRevision; /* 0=TA1 on STMP3780 for example */ | ||
107 | uint8_t bPackage; /* 0=169BGA for example */ | ||
108 | } __attribute__((packed)); | ||
109 | |||
110 | struct hwstub_pp_desc_t | ||
111 | { | ||
112 | uint8_t bLength; | ||
113 | uint8_t bDescriptorType; | ||
114 | /* Chip ID and revision */ | ||
115 | uint16_t wChipID; /* 0x5002 for PP5002 for example */ | ||
116 | uint8_t bRevision[2]; /* 'B1' for B1 for example */ | ||
117 | } __attribute__((packed)); | ||
118 | |||
119 | struct hwstub_jz_desc_t | ||
120 | { | ||
121 | uint8_t bLength; | ||
122 | uint8_t bDescriptorType; | ||
123 | /* Chip ID and revision */ | ||
124 | uint16_t wChipID; /* 0x4760 for Jz4760 for example */ | ||
125 | uint8_t bRevision; /* 0 for Jz4760, 'B' for JZ4760B */ | ||
126 | } __attribute__((packed)); | ||
127 | |||
128 | #define HWSTUB_TARGET_UNK ('U' | 'N' << 8 | 'K' << 16 | ' ' << 24) | ||
129 | #define HWSTUB_TARGET_STMP ('S' | 'T' << 8 | 'M' << 16 | 'P' << 24) | ||
130 | #define HWSTUB_TARGET_RK27 ('R' | 'K' << 8 | '2' << 16 | '7' << 24) | ||
131 | #define HWSTUB_TARGET_PP ('P' | 'P' << 8 | ' ' << 16 | ' ' << 24) | ||
132 | #define HWSTUB_TARGET_ATJ ('A' | 'T' << 8 | 'J' << 16 | ' ' << 24) | ||
133 | #define HWSTUB_TARGET_JZ ('J' | 'Z' << 8 | '4' << 16 | '7' << 24) | ||
134 | |||
135 | struct hwstub_target_desc_t | ||
136 | { | ||
137 | uint8_t bLength; | ||
138 | uint8_t bDescriptorType; | ||
139 | /* Target ID and name */ | ||
140 | uint32_t dID; | ||
141 | char bName[58]; | ||
142 | } __attribute__((packed)); | ||
143 | |||
144 | /** | ||
145 | * Socket command packet header: any transfer (in both directions) start with this. | ||
146 | * All data is transmitted in network byte order. | ||
147 | */ | ||
148 | #define HWSTUB_NET_ARGS 4 | ||
149 | |||
150 | struct hwstub_net_hdr_t | ||
151 | { | ||
152 | uint32_t magic; /* magic value (HWSERVER_MAGIC) */ | ||
153 | uint32_t cmd; /* command (OR'ed with (N)ACK on response) */ | ||
154 | uint32_t length; /* length of the data following this header */ | ||
155 | uint32_t args[HWSTUB_NET_ARGS]; /* command arguments */ | ||
156 | } __attribute__((packed)); | ||
157 | |||
158 | /** | ||
159 | * Control commands | ||
160 | * | ||
161 | * These commands are sent to the interface, using the standard bRequest field | ||
162 | * of the SETUP packet. The wIndex contains the interface number. The wValue | ||
163 | * contains an ID which is used for requests requiring several transfers. | ||
164 | */ | ||
165 | #define HWSTUB_GET_LOG 0x40 | ||
166 | #define HWSTUB_READ 0x41 | ||
167 | #define HWSTUB_READ2 0x42 | ||
168 | #define HWSTUB_WRITE 0x43 | ||
169 | #define HWSTUB_EXEC 0x44 | ||
170 | #define HWSTUB_READ2_ATOMIC 0x45 | ||
171 | #define HWSTUB_WRITE_ATOMIC 0x46 | ||
172 | |||
173 | /* the following commands and the ACK/NACK mechanism are net only */ | ||
174 | #define HWSERVER_ACK(n) (0x100|(n)) | ||
175 | #define HWSERVER_ACK_MASK 0x100 | ||
176 | #define HWSERVER_NACK(n) (0x200|(n)) | ||
177 | #define HWSERVER_NACK_MASK 0x200 | ||
178 | |||
179 | #define HWSERVER_MAGIC ('h' << 24 | 'w' << 16 | 's' << 8 | 't') | ||
180 | |||
181 | #define HWSERVER_HELLO 0x400 | ||
182 | #define HWSERVER_GET_DEV_LIST 0x401 | ||
183 | #define HWSERVER_DEV_OPEN 0x402 | ||
184 | #define HWSERVER_DEV_CLOSE 0x403 | ||
185 | #define HWSERVER_BYE 0x404 | ||
186 | #define HWSERVER_GET_DESC 0x405 | ||
187 | #define HWSERVER_GET_LOG 0x406 | ||
188 | #define HWSERVER_READ 0x407 | ||
189 | #define HWSERVER_WRITE 0x408 | ||
190 | #define HWSERVER_EXEC 0x409 | ||
191 | |||
192 | /* net errors (always in arg[0] if command is NACKed) */ | ||
193 | #define HWERR_OK 0 /* success */ | ||
194 | #define HWERR_FAIL 1 /* general error from hwstub */ | ||
195 | #define HWERR_INVALID_ID 2 /* invalid id of the device */ | ||
196 | #define HWERR_DISCONNECTED 3 /* device got disconnected */ | ||
197 | |||
198 | /* read/write flags */ | ||
199 | #define HWSERVER_RW_ATOMIC 0x1 | ||
200 | |||
201 | /********************************** | ||
202 | * Control Protocol | ||
203 | **********************************/ | ||
204 | |||
205 | /** | ||
206 | * HWSTUB_GET_LOG: | ||
207 | * The log is returned as part of the control transfer. | ||
208 | */ | ||
209 | |||
210 | /** | ||
211 | * HWSTUB_READ and HWSTUB_READ2(_ATOMIC): | ||
212 | * Read a range of memory. The request works in two steps: first the host | ||
213 | * sends HWSTUB_READ with the parameters (address, length) and then | ||
214 | * a HWSTUB_READ2 to retrieve the buffer. Both requests must use the same | ||
215 | * ID in wValue, otherwise the second request will be STALLed. | ||
216 | * HWSTUB_READ2_ATOMIC behaves the same as HWSTUB_READ2 except that the read | ||
217 | * is guaranteed to be atomic (ie performed as a single memory access) and | ||
218 | * will be STALLed if atomicity can not be ensured. | ||
219 | */ | ||
220 | |||
221 | struct hwstub_read_req_t | ||
222 | { | ||
223 | uint32_t dAddress; | ||
224 | } __attribute__((packed)); | ||
225 | |||
226 | /** | ||
227 | * HWSTUB_WRITE: | ||
228 | * Write a range of memory. The payload starts with the following header, everything | ||
229 | * which follows is data. | ||
230 | * HWSTUB_WRITE_ATOMIC behaves the same except it is atomic. See HWSTUB_READ2_ATOMIC. | ||
231 | */ | ||
232 | struct hwstub_write_req_t | ||
233 | { | ||
234 | uint32_t dAddress; | ||
235 | } __attribute__((packed)); | ||
236 | |||
237 | /** | ||
238 | * HWSTUB_EXEC: | ||
239 | * Execute code at an address. Several options are available regarding ARM vs Thumb, | ||
240 | * jump vs call. | ||
241 | */ | ||
242 | |||
243 | #define HWSTUB_EXEC_ARM (0 << 0) /* target code is ARM */ | ||
244 | #define HWSTUB_EXEC_THUMB (1 << 0) /* target code is Thumb */ | ||
245 | #define HWSTUB_EXEC_JUMP (0 << 1) /* branch, code will never turn */ | ||
246 | #define HWSTUB_EXEC_CALL (1 << 1) /* call and expect return */ | ||
247 | |||
248 | struct hwstub_exec_req_t | ||
249 | { | ||
250 | uint32_t dAddress; | ||
251 | uint16_t bmFlags; | ||
252 | } __attribute__((packed)); | ||
253 | |||
254 | /** | ||
255 | * HWSERVER_HELLO: | ||
256 | * Say hello to the server, give protocol version and get server version. | ||
257 | * Send: args[0] = major << 8 | minor, no data | ||
258 | * Receive: args[0] = major << 8 | minor, no data | ||
259 | */ | ||
260 | |||
261 | /** | ||
262 | * HWSERVER_GET_DEV_LIST: | ||
263 | * Get device list. | ||
264 | * Send: no argument, no data. | ||
265 | * Receive: no argument, data contains a list of device IDs, each ID is a uint32_t | ||
266 | * transmitted in network byte order. | ||
267 | */ | ||
268 | |||
269 | /** | ||
270 | * HWSERVER_DEV_OPEN: | ||
271 | * Open a device and return a handle. | ||
272 | * Send: args[0] = device ID, no data. | ||
273 | * Receive: args[0] = handle ID, no data. | ||
274 | */ | ||
275 | |||
276 | /** | ||
277 | * HWSERVER_DEV_CLOSE: | ||
278 | * Close a device handle. | ||
279 | * Send: args[0] = handle ID, no data. | ||
280 | * Receive: no argument, no data. | ||
281 | */ | ||
282 | |||
283 | /** | ||
284 | * HWSERVER_BYE: | ||
285 | * Say bye to the server, closing all devices and effectively stopping the communication. | ||
286 | * Send: no argument, no data | ||
287 | * Receive: no argument, no data | ||
288 | */ | ||
289 | |||
290 | /** | ||
291 | * HWSERVER_GET_DESC: | ||
292 | * Query a descriptor. | ||
293 | * Send: args[0] = handle ID, args[1] = desc ID, args[2] = requested length, no data | ||
294 | * Receive: no argument, data contains RAW descriptor (ie all fields are in little-endian) | ||
295 | */ | ||
296 | |||
297 | /** | ||
298 | * HWSERVER_GET_LOG: | ||
299 | * Query a descriptor. | ||
300 | * Send: args[0] = handle ID, args[1] = requested length, no data | ||
301 | * Receive: no argument, data contains log data | ||
302 | */ | ||
303 | |||
304 | /** | ||
305 | * HWSERVER_READ: | ||
306 | * Read data. | ||
307 | * Send: args[0] = handle ID, args[1] = addr, args[2] = length, args[3] = flags | ||
308 | * Receive: no argument, data read on device | ||
309 | */ | ||
310 | |||
311 | /** | ||
312 | * HWSERVER_WRITE: | ||
313 | * Read data. | ||
314 | * Send: args[0] = handle ID, args[1] = addr, args[2] = flags, data to write | ||
315 | * Receive: no data | ||
316 | */ | ||
317 | |||
318 | #endif /* __HWSTUB_PROTOCOL__ */ | ||