diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2014-02-04 00:10:41 +0100 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2014-02-10 23:14:24 +0100 |
commit | c17d30f20466861a244c603665c580feb7758abf (patch) | |
tree | c5044f599f89d89de0b1419bd40e92211f8c8b8a /utils/hwstub/stub | |
parent | 6d64111b3c2f772cfc3539bb13851f78d4b55870 (diff) | |
download | rockbox-c17d30f20466861a244c603665c580feb7758abf.tar.gz rockbox-c17d30f20466861a244c603665c580feb7758abf.zip |
utils/hwstub: completely rework the protocol, drop unused features
The protocol has evolved a lot during the 2.x.y lifetime, bringing more
features which later got unused. This commit removes all the unused stuff
and simplifies everything:
- drop the feature mask: everything is mandatory or stalled on error
- remove the info request and put all static information in standard USB
descriptors which are part of the configuration descriptor (and can be
retrieved using the standard GetDescriptor request).
- remove the USB interface, we had only one anyway
- remove all endpoint descriptors
- remove the exit/atexit stuff, it never worked as intended anyway
- update the hwstub library and make it able to handle any device
- update the tools (mostly renaming and removing of code)
Change-Id: I1872bba7f4177fc3891180e8f944aab88f5bde31
Diffstat (limited to 'utils/hwstub/stub')
-rw-r--r-- | utils/hwstub/stub/main.c | 241 | ||||
-rw-r--r-- | utils/hwstub/stub/rk27xx/target.c | 59 | ||||
-rw-r--r-- | utils/hwstub/stub/stmp/target.c | 132 | ||||
-rw-r--r-- | utils/hwstub/stub/target.h | 13 |
4 files changed, 124 insertions, 321 deletions
diff --git a/utils/hwstub/stub/main.c b/utils/hwstub/stub/main.c index 0923bf85ce..37590e88f8 100644 --- a/utils/hwstub/stub/main.c +++ b/utils/hwstub/stub/main.c | |||
@@ -51,16 +51,16 @@ static struct usb_device_descriptor __attribute__((aligned(2))) | |||
51 | .bLength = sizeof(struct usb_device_descriptor), | 51 | .bLength = sizeof(struct usb_device_descriptor), |
52 | .bDescriptorType = USB_DT_DEVICE, | 52 | .bDescriptorType = USB_DT_DEVICE, |
53 | .bcdUSB = 0x0200, | 53 | .bcdUSB = 0x0200, |
54 | .bDeviceClass = USB_CLASS_PER_INTERFACE, | 54 | .bDeviceClass = HWSTUB_CLASS, |
55 | .bDeviceSubClass = 0, | 55 | .bDeviceSubClass = HWSTUB_SUBCLASS, |
56 | .bDeviceProtocol = 0, | 56 | .bDeviceProtocol = HWSTUB_PROTOCOL, |
57 | .bMaxPacketSize0 = 64, | 57 | .bMaxPacketSize0 = 64, |
58 | .idVendor = HWSTUB_USB_VID, | 58 | .idVendor = HWSTUB_USB_VID, |
59 | .idProduct = HWSTUB_USB_PID, | 59 | .idProduct = HWSTUB_USB_PID, |
60 | .bcdDevice = HWSTUB_VERSION_MAJOR << 8 | HWSTUB_VERSION_MINOR, | 60 | .bcdDevice = HWSTUB_VERSION_MAJOR << 8 | HWSTUB_VERSION_MINOR, |
61 | .iManufacturer = 1, | 61 | .iManufacturer = 1, |
62 | .iProduct = 2, | 62 | .iProduct = 2, |
63 | .iSerialNumber = 3, | 63 | .iSerialNumber = 0, |
64 | .bNumConfigurations = 1 | 64 | .bNumConfigurations = 1 |
65 | }; | 65 | }; |
66 | 66 | ||
@@ -72,40 +72,13 @@ static struct usb_config_descriptor __attribute__((aligned(2))) | |||
72 | .bLength = sizeof(struct usb_config_descriptor), | 72 | .bLength = sizeof(struct usb_config_descriptor), |
73 | .bDescriptorType = USB_DT_CONFIG, | 73 | .bDescriptorType = USB_DT_CONFIG, |
74 | .wTotalLength = 0, /* will be filled in later */ | 74 | .wTotalLength = 0, /* will be filled in later */ |
75 | .bNumInterfaces = 1, | 75 | .bNumInterfaces = 0, |
76 | .bConfigurationValue = 1, | 76 | .bConfigurationValue = 1, |
77 | .iConfiguration = 0, | 77 | .iConfiguration = 0, |
78 | .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, | 78 | .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, |
79 | .bMaxPower = (USB_MAX_CURRENT + 1) / 2, /* In 2mA units */ | 79 | .bMaxPower = (USB_MAX_CURRENT + 1) / 2, /* In 2mA units */ |
80 | }; | 80 | }; |
81 | 81 | ||
82 | /* main interface */ | ||
83 | static struct usb_interface_descriptor __attribute__((aligned(2))) | ||
84 | interface_descriptor = | ||
85 | { | ||
86 | .bLength = sizeof(struct usb_interface_descriptor), | ||
87 | .bDescriptorType = USB_DT_INTERFACE, | ||
88 | .bInterfaceNumber = 0, | ||
89 | .bAlternateSetting = 0, | ||
90 | .bNumEndpoints = 3, | ||
91 | .bInterfaceClass = HWSTUB_CLASS, | ||
92 | .bInterfaceSubClass = HWSTUB_SUBCLASS, | ||
93 | .bInterfaceProtocol = HWSTUB_PROTOCOL, | ||
94 | .iInterface = 4 | ||
95 | }; | ||
96 | |||
97 | |||
98 | static struct usb_endpoint_descriptor __attribute__((aligned(2))) | ||
99 | endpoint_descriptor = | ||
100 | { | ||
101 | .bLength = sizeof(struct usb_endpoint_descriptor), | ||
102 | .bDescriptorType = USB_DT_ENDPOINT, | ||
103 | .bEndpointAddress = 0, | ||
104 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
105 | .wMaxPacketSize = 0, | ||
106 | .bInterval = 0 | ||
107 | }; | ||
108 | |||
109 | static const struct usb_string_descriptor __attribute__((aligned(2))) | 82 | static const struct usb_string_descriptor __attribute__((aligned(2))) |
110 | usb_string_iManufacturer = | 83 | usb_string_iManufacturer = |
111 | { | 84 | { |
@@ -117,42 +90,38 @@ static const struct usb_string_descriptor __attribute__((aligned(2))) | |||
117 | static const struct usb_string_descriptor __attribute__((aligned(2))) | 90 | static const struct usb_string_descriptor __attribute__((aligned(2))) |
118 | usb_string_iProduct = | 91 | usb_string_iProduct = |
119 | { | 92 | { |
120 | 52, | 93 | 44, |
121 | USB_DT_STRING, | 94 | USB_DT_STRING, |
122 | {'R', 'o', 'c', 'k', 'b', 'o', 'x', ' ', | 95 | {'R', 'o', 'c', 'k', 'b', 'o', 'x', ' ', |
123 | 'h', 'a', 'r', 'd', 'w', 'a', 'r', 'e', ' ', | 96 | 'h', 'a', 'r', 'd', 'w', 'a', 'r', 'e', ' ', |
124 | 'e', 'm', 'u', 'l', 'a', 't', 'e', 'r'} | 97 | 's', 't', 'u', 'b'} |
125 | }; | 98 | }; |
126 | 99 | ||
127 | static struct usb_string_descriptor __attribute__((aligned(2))) | 100 | /* this is stringid #0: languages supported */ |
128 | usb_string_iSerial = | 101 | static const struct usb_string_descriptor __attribute__((aligned(2))) |
102 | lang_descriptor = | ||
129 | { | 103 | { |
130 | 84, | 104 | 4, |
131 | USB_DT_STRING, | 105 | USB_DT_STRING, |
132 | {'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', | 106 | {0x0409} /* LANGID US English */ |
133 | '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', | ||
134 | '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', | ||
135 | '0', '0', '0', '0', '0', '0', '0', '0'} | ||
136 | }; | 107 | }; |
137 | 108 | ||
138 | static struct usb_string_descriptor __attribute__((aligned(2))) | 109 | static struct hwstub_version_desc_t __attribute__((aligned(2))) |
139 | usb_string_iInterface = | 110 | version_descriptor = |
140 | { | 111 | { |
141 | 28, | 112 | sizeof(struct hwstub_version_desc_t), |
142 | USB_DT_STRING, | 113 | HWSTUB_DT_VERSION, |
143 | {'A', 'c', 'i', 'd', ' ', | 114 | HWSTUB_VERSION_MAJOR, |
144 | '0' + (HWSTUB_VERSION_MAJOR >> 4), '0' + (HWSTUB_VERSION_MAJOR & 0xf), '.', | 115 | HWSTUB_VERSION_MINOR, |
145 | '0' + (HWSTUB_VERSION_MINOR >> 4), '0' + (HWSTUB_VERSION_MINOR & 0xf), '.', | 116 | HWSTUB_VERSION_REV |
146 | '0' + (HWSTUB_VERSION_REV >> 4), '0' + (HWSTUB_VERSION_REV & 0xf) } | ||
147 | }; | 117 | }; |
148 | 118 | ||
149 | /* this is stringid #0: languages supported */ | 119 | static struct hwstub_layout_desc_t __attribute__((aligned(2))) |
150 | static const struct usb_string_descriptor __attribute__((aligned(2))) | 120 | layout_descriptor = |
151 | lang_descriptor = | ||
152 | { | 121 | { |
153 | 4, | 122 | sizeof(struct hwstub_layout_desc_t), |
154 | USB_DT_STRING, | 123 | HWSTUB_DT_LAYOUT, |
155 | {0x0409} /* LANGID US English */ | 124 | 0, 0, 0, 0, 0, 0 |
156 | }; | 125 | }; |
157 | 126 | ||
158 | #define USB_NUM_STRINGS 5 | 127 | #define USB_NUM_STRINGS 5 |
@@ -162,26 +131,25 @@ static const struct usb_string_descriptor* const usb_strings[USB_NUM_STRINGS] = | |||
162 | &lang_descriptor, | 131 | &lang_descriptor, |
163 | &usb_string_iManufacturer, | 132 | &usb_string_iManufacturer, |
164 | &usb_string_iProduct, | 133 | &usb_string_iProduct, |
165 | &usb_string_iSerial, | ||
166 | &usb_string_iInterface | ||
167 | }; | 134 | }; |
168 | 135 | ||
169 | uint8_t *usb_buffer = oc_bufferstart; | 136 | uint8_t *usb_buffer = oc_bufferstart; |
170 | uint32_t usb_buffer_size = 0; | 137 | uint32_t usb_buffer_size = 0; |
171 | 138 | ||
172 | #define EP_BULK 1 | 139 | static void fill_layout_info(void) |
173 | #define EP_INT 2 | ||
174 | |||
175 | static void set_config(void) | ||
176 | { | 140 | { |
177 | usb_drv_configure_endpoint(EP_BULK, USB_ENDPOINT_XFER_BULK); | 141 | layout_descriptor.dCodeStart = (uint32_t)oc_codestart; |
178 | usb_drv_configure_endpoint(EP_INT, USB_ENDPOINT_XFER_INT); | 142 | layout_descriptor.dCodeSize = oc_codesize; |
143 | layout_descriptor.dStackStart = (uint32_t)oc_stackstart; | ||
144 | layout_descriptor.dStackSize = oc_stacksize; | ||
145 | layout_descriptor.dBufferStart = (uint32_t)oc_bufferstart; | ||
146 | layout_descriptor.dBufferSize = oc_buffersize; | ||
179 | } | 147 | } |
180 | 148 | ||
181 | static void handle_std_dev_desc(struct usb_ctrlrequest *req) | 149 | static void handle_std_dev_desc(struct usb_ctrlrequest *req) |
182 | { | 150 | { |
183 | int size; | 151 | int size; |
184 | const void* ptr = NULL; | 152 | void* ptr = NULL; |
185 | unsigned index = req->wValue & 0xff; | 153 | unsigned index = req->wValue & 0xff; |
186 | 154 | ||
187 | switch(req->wValue >> 8) | 155 | switch(req->wValue >> 8) |
@@ -208,32 +176,22 @@ static void handle_std_dev_desc(struct usb_ctrlrequest *req) | |||
208 | } | 176 | } |
209 | size = sizeof(struct usb_config_descriptor); | 177 | size = sizeof(struct usb_config_descriptor); |
210 | 178 | ||
211 | /* interface */ | 179 | /* hwstub version */ |
212 | memcpy(usb_buffer + size, (void *)&interface_descriptor, | 180 | memcpy(usb_buffer + size, (void *)&version_descriptor, |
213 | sizeof(interface_descriptor)); | 181 | sizeof(version_descriptor)); |
214 | size += sizeof(interface_descriptor); | 182 | size += sizeof(version_descriptor); |
215 | /* endpoint 1: bulk out */ | 183 | /* hwstub layout */ |
216 | endpoint_descriptor.bEndpointAddress = EP_BULK | USB_DIR_OUT; | 184 | fill_layout_info(); |
217 | endpoint_descriptor.bmAttributes = USB_ENDPOINT_XFER_BULK; | 185 | memcpy(usb_buffer + size, (void *)&layout_descriptor, |
218 | endpoint_descriptor.wMaxPacketSize = 512; | 186 | sizeof(layout_descriptor)); |
219 | memcpy(usb_buffer + size, (void *)&endpoint_descriptor, | 187 | size += sizeof(layout_descriptor); |
220 | sizeof(endpoint_descriptor)); | 188 | /* hwstub target */ |
221 | size += sizeof(endpoint_descriptor); | 189 | fill_layout_info(); |
222 | /* endpoint 2: bulk in */ | 190 | memcpy(usb_buffer + size, (void *)&target_descriptor, |
223 | endpoint_descriptor.bEndpointAddress = EP_BULK | USB_DIR_IN; | 191 | sizeof(target_descriptor)); |
224 | endpoint_descriptor.bmAttributes = USB_ENDPOINT_XFER_BULK; | 192 | size += sizeof(target_descriptor); |
225 | endpoint_descriptor.wMaxPacketSize = 512; | 193 | /* target specific descriptors */ |
226 | memcpy(usb_buffer + size, (void *)&endpoint_descriptor, | 194 | target_get_config_desc(usb_buffer + size, &size); |
227 | sizeof(endpoint_descriptor)); | ||
228 | size += sizeof(endpoint_descriptor); | ||
229 | /* endpoint 3: int in */ | ||
230 | endpoint_descriptor.bEndpointAddress = EP_INT | USB_DIR_IN; | ||
231 | endpoint_descriptor.bmAttributes = USB_ENDPOINT_XFER_INT; | ||
232 | endpoint_descriptor.wMaxPacketSize = 1024; | ||
233 | memcpy(usb_buffer + size, (void *)&endpoint_descriptor, | ||
234 | sizeof(endpoint_descriptor)); | ||
235 | size += sizeof(endpoint_descriptor); | ||
236 | |||
237 | /* fix config descriptor */ | 195 | /* fix config descriptor */ |
238 | config_descriptor.bNumInterfaces = 1; | 196 | config_descriptor.bNumInterfaces = 1; |
239 | config_descriptor.wTotalLength = size; | 197 | config_descriptor.wTotalLength = size; |
@@ -246,12 +204,27 @@ static void handle_std_dev_desc(struct usb_ctrlrequest *req) | |||
246 | if(index < USB_NUM_STRINGS) | 204 | if(index < USB_NUM_STRINGS) |
247 | { | 205 | { |
248 | size = usb_strings[index]->bLength; | 206 | size = usb_strings[index]->bLength; |
249 | ptr = usb_strings[index]; | 207 | ptr = (void *)usb_strings[index]; |
250 | } | 208 | } |
251 | else | 209 | else |
252 | usb_drv_stall(EP_CONTROL, true, true); | 210 | usb_drv_stall(EP_CONTROL, true, true); |
253 | break; | 211 | break; |
212 | case HWSTUB_DT_VERSION: | ||
213 | ptr = &version_descriptor; | ||
214 | size = sizeof(version_descriptor); | ||
215 | break; | ||
216 | case HWSTUB_DT_LAYOUT: | ||
217 | ptr = &layout_descriptor; | ||
218 | size = sizeof(layout_descriptor); | ||
219 | break; | ||
220 | case HWSTUB_DT_TARGET: | ||
221 | ptr = &target_descriptor; | ||
222 | size = sizeof(target_descriptor); | ||
223 | break; | ||
254 | default: | 224 | default: |
225 | target_get_desc(req->wValue >> 8, &ptr); | ||
226 | if(ptr != 0) | ||
227 | size = ((struct usb_descriptor_header *)ptr)->bLength; | ||
255 | break; | 228 | break; |
256 | } | 229 | } |
257 | 230 | ||
@@ -280,7 +253,6 @@ static void handle_std_dev_req(struct usb_ctrlrequest *req) | |||
280 | break; | 253 | break; |
281 | case USB_REQ_SET_CONFIGURATION: | 254 | case USB_REQ_SET_CONFIGURATION: |
282 | usb_drv_send(EP_CONTROL, NULL, 0); | 255 | usb_drv_send(EP_CONTROL, NULL, 0); |
283 | set_config(); | ||
284 | break; | 256 | break; |
285 | case USB_REQ_GET_DESCRIPTOR: | 257 | case USB_REQ_GET_DESCRIPTOR: |
286 | handle_std_dev_desc(req); | 258 | handle_std_dev_desc(req); |
@@ -311,67 +283,6 @@ static void handle_std_req(struct usb_ctrlrequest *req) | |||
311 | } | 283 | } |
312 | } | 284 | } |
313 | 285 | ||
314 | struct usb_resp_info_version_t g_version = | ||
315 | { | ||
316 | .major = HWSTUB_VERSION_MAJOR, | ||
317 | .minor = HWSTUB_VERSION_MINOR, | ||
318 | .revision = HWSTUB_VERSION_REV | ||
319 | }; | ||
320 | |||
321 | struct usb_resp_info_layout_t g_layout; | ||
322 | |||
323 | struct usb_resp_info_features_t g_features = | ||
324 | { | ||
325 | .feature_mask = HWSTUB_FEATURE_LOG | HWSTUB_FEATURE_MEM | | ||
326 | HWSTUB_FEATURE_CALL | HWSTUB_FEATURE_JUMP | ||
327 | }; | ||
328 | |||
329 | static void fill_layout_info(void) | ||
330 | { | ||
331 | g_layout.oc_code_start = (uint32_t)oc_codestart; | ||
332 | g_layout.oc_code_size = oc_codesize; | ||
333 | g_layout.oc_stack_start = (uint32_t)oc_stackstart; | ||
334 | g_layout.oc_stack_size = oc_stacksize; | ||
335 | g_layout.oc_buffer_start = (uint32_t)oc_bufferstart; | ||
336 | g_layout.oc_buffer_size = oc_buffersize; | ||
337 | } | ||
338 | |||
339 | static void handle_get_info(struct usb_ctrlrequest *req) | ||
340 | { | ||
341 | void *ptr = NULL; | ||
342 | int size = 0; | ||
343 | switch(req->wIndex) | ||
344 | { | ||
345 | case HWSTUB_INFO_VERSION: | ||
346 | ptr = &g_version; | ||
347 | size = sizeof(g_version); | ||
348 | break; | ||
349 | case HWSTUB_INFO_LAYOUT: | ||
350 | fill_layout_info(); | ||
351 | ptr = &g_layout; | ||
352 | size = sizeof(g_layout); | ||
353 | break; | ||
354 | case HWSTUB_INFO_FEATURES: | ||
355 | ptr = &g_features; | ||
356 | size = sizeof(g_features); | ||
357 | break; | ||
358 | default: | ||
359 | size = target_get_info(req->wIndex, &ptr); | ||
360 | if(size < 0) | ||
361 | usb_drv_stall(EP_CONTROL, true, true); | ||
362 | } | ||
363 | |||
364 | if(ptr) | ||
365 | { | ||
366 | int length = MIN(size, req->wLength); | ||
367 | |||
368 | if(ptr != usb_buffer) | ||
369 | memcpy(usb_buffer, ptr, length); | ||
370 | usb_drv_send(EP_CONTROL, usb_buffer, length); | ||
371 | usb_drv_recv(EP_CONTROL, NULL, 0); | ||
372 | } | ||
373 | } | ||
374 | |||
375 | static void handle_get_log(struct usb_ctrlrequest *req) | 286 | static void handle_get_log(struct usb_ctrlrequest *req) |
376 | { | 287 | { |
377 | enable_logf(false); | 288 | enable_logf(false); |
@@ -421,28 +332,10 @@ static void handle_call_jump(struct usb_ctrlrequest *req) | |||
421 | } | 332 | } |
422 | } | 333 | } |
423 | 334 | ||
424 | static void handle_atexit(struct usb_ctrlrequest *req) | ||
425 | { | ||
426 | if(target_atexit(req->wIndex) < 0) | ||
427 | usb_drv_stall(EP_CONTROL, true, true); | ||
428 | else | ||
429 | usb_drv_send(EP_CONTROL, NULL, 0); | ||
430 | } | ||
431 | |||
432 | static void handle_exit(struct usb_ctrlrequest *req) | ||
433 | { | ||
434 | (void)req; | ||
435 | usb_drv_send(EP_CONTROL, NULL, 0); | ||
436 | g_exit = true; | ||
437 | } | ||
438 | |||
439 | static void handle_class_dev_req(struct usb_ctrlrequest *req) | 335 | static void handle_class_dev_req(struct usb_ctrlrequest *req) |
440 | { | 336 | { |
441 | switch(req->bRequest) | 337 | switch(req->bRequest) |
442 | { | 338 | { |
443 | case HWSTUB_GET_INFO: | ||
444 | handle_get_info(req); | ||
445 | break; | ||
446 | case HWSTUB_GET_LOG: | 339 | case HWSTUB_GET_LOG: |
447 | handle_get_log(req); | 340 | handle_get_log(req); |
448 | break; | 341 | break; |
@@ -453,11 +346,6 @@ static void handle_class_dev_req(struct usb_ctrlrequest *req) | |||
453 | case HWSTUB_JUMP: | 346 | case HWSTUB_JUMP: |
454 | handle_call_jump(req); | 347 | handle_call_jump(req); |
455 | break; | 348 | break; |
456 | case HWSTUB_ATEXIT: | ||
457 | handle_atexit(req); | ||
458 | break; | ||
459 | case HWSTUB_EXIT: | ||
460 | handle_exit(req); | ||
461 | break; | 349 | break; |
462 | default: | 350 | default: |
463 | usb_drv_stall(EP_CONTROL, true, true); | 351 | usb_drv_stall(EP_CONTROL, true, true); |
@@ -510,5 +398,4 @@ void main(uint32_t arg) | |||
510 | } | 398 | } |
511 | } | 399 | } |
512 | usb_drv_exit(); | 400 | usb_drv_exit(); |
513 | target_exit(); | ||
514 | } | 401 | } |
diff --git a/utils/hwstub/stub/rk27xx/target.c b/utils/hwstub/stub/rk27xx/target.c index f9efccaef0..ff2e952909 100644 --- a/utils/hwstub/stub/rk27xx/target.c +++ b/utils/hwstub/stub/rk27xx/target.c | |||
@@ -33,7 +33,6 @@ enum rk27xx_family_t | |||
33 | }; | 33 | }; |
34 | 34 | ||
35 | static enum rk27xx_family_t g_rk27xx_family = UNKNOWN; | 35 | static enum rk27xx_family_t g_rk27xx_family = UNKNOWN; |
36 | static int g_atexit = HWSTUB_ATEXIT_OFF; | ||
37 | 36 | ||
38 | static void _enable_irq(void) | 37 | static void _enable_irq(void) |
39 | { | 38 | { |
@@ -43,23 +42,6 @@ static void _enable_irq(void) | |||
43 | ); | 42 | ); |
44 | } | 43 | } |
45 | 44 | ||
46 | static void power_off(void) | ||
47 | { | ||
48 | GPIO_PCCON &= ~(1<<0); | ||
49 | while(1); | ||
50 | } | ||
51 | |||
52 | static void rk27xx_reset(void) | ||
53 | { | ||
54 | /* use Watchdog to reset */ | ||
55 | SCU_CLKCFG &= ~CLKCFG_WDT; | ||
56 | WDTLR = 1; | ||
57 | WDTCON = (1<<4) | (1<<3); | ||
58 | |||
59 | /* Wait for reboot to kick in */ | ||
60 | while(1); | ||
61 | } | ||
62 | |||
63 | /* us may be at most 2^31/200 (~10 seconds) for 200MHz max cpu freq */ | 45 | /* us may be at most 2^31/200 (~10 seconds) for 200MHz max cpu freq */ |
64 | void target_udelay(int us) | 46 | void target_udelay(int us) |
65 | { | 47 | { |
@@ -132,41 +114,22 @@ void target_init(void) | |||
132 | } | 114 | } |
133 | } | 115 | } |
134 | 116 | ||
135 | static struct usb_resp_info_target_t g_target = | 117 | struct hwstub_target_desc_t __attribute__((aligned(2))) target_descriptor = |
136 | { | 118 | { |
137 | .id = HWSTUB_TARGET_RK27, | 119 | sizeof(struct hwstub_target_desc_t), |
138 | .name = "Rockchip RK27XX" | 120 | HWSTUB_DT_TARGET, |
121 | HWSTUB_TARGET_RK27, | ||
122 | "Rockchip RK27XX" | ||
139 | }; | 123 | }; |
140 | 124 | ||
141 | int target_get_info(int info, void **buffer) | 125 | void target_get_desc(int desc, void **buffer) |
142 | { | 126 | { |
143 | if(info == HWSTUB_INFO_TARGET) | 127 | (void) desc; |
144 | { | 128 | *buffer = NULL; |
145 | *buffer = &g_target; | ||
146 | return sizeof(g_target); | ||
147 | } | ||
148 | else | ||
149 | return -1; | ||
150 | } | 129 | } |
151 | 130 | ||
152 | int target_atexit(int method) | 131 | void target_get_config_desc(void *buffer, int *size) |
153 | { | 132 | { |
154 | g_atexit = method; | 133 | (void) buffer; |
155 | return 0; | 134 | (void) size; |
156 | } | ||
157 | |||
158 | void target_exit(void) | ||
159 | { | ||
160 | switch(g_atexit) | ||
161 | { | ||
162 | case HWSTUB_ATEXIT_OFF: | ||
163 | power_off(); | ||
164 | // fallthrough in case of return | ||
165 | case HWSTUB_ATEXIT_REBOOT: | ||
166 | rk27xx_reset(); | ||
167 | // fallthrough in case of return | ||
168 | case HWSTUB_ATEXIT_NOP: | ||
169 | default: | ||
170 | return; | ||
171 | } | ||
172 | } | 135 | } |
diff --git a/utils/hwstub/stub/stmp/target.c b/utils/hwstub/stub/stmp/target.c index 98f65da625..8d48707088 100644 --- a/utils/hwstub/stub/stmp/target.c +++ b/utils/hwstub/stub/stmp/target.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include "target.h" | 22 | #include "target.h" |
23 | #include "system.h" | 23 | #include "system.h" |
24 | #include "logf.h" | 24 | #include "logf.h" |
25 | #include "memory.h" | ||
25 | 26 | ||
26 | #define __REG_SET(reg) (*((volatile uint32_t *)(® + 1))) | 27 | #define __REG_SET(reg) (*((volatile uint32_t *)(® + 1))) |
27 | #define __REG_CLR(reg) (*((volatile uint32_t *)(® + 2))) | 28 | #define __REG_CLR(reg) (*((volatile uint32_t *)(® + 2))) |
@@ -50,34 +51,6 @@ enum stmp_family_t | |||
50 | }; | 51 | }; |
51 | 52 | ||
52 | static enum stmp_family_t g_stmp_family = UNKNOWN; | 53 | static enum stmp_family_t g_stmp_family = UNKNOWN; |
53 | static int g_atexit = HWSTUB_ATEXIT_OFF; | ||
54 | |||
55 | /** | ||
56 | * | ||
57 | * Power | ||
58 | * | ||
59 | */ | ||
60 | |||
61 | #define HW_POWER_BASE 0x80044000 | ||
62 | |||
63 | void power_off(void) | ||
64 | { | ||
65 | switch(g_stmp_family) | ||
66 | { | ||
67 | case STMP3600: | ||
68 | *(volatile uint32_t *)(HW_POWER_BASE + 0xc0) = 0x3e770014; | ||
69 | break; | ||
70 | case STMP3700: | ||
71 | case STMP3770: | ||
72 | *(volatile uint32_t *)(HW_POWER_BASE + 0xe0) = 0x3e770001; | ||
73 | break; | ||
74 | case STMP3780: | ||
75 | *(volatile uint32_t *)(HW_POWER_BASE + 0x100) = 0x3e770001; | ||
76 | break; | ||
77 | default: | ||
78 | break; | ||
79 | } | ||
80 | } | ||
81 | 54 | ||
82 | /** | 55 | /** |
83 | * | 56 | * |
@@ -114,25 +87,6 @@ void power_off(void) | |||
114 | #define HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK30M_GATE (1 << 30) | 87 | #define HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK30M_GATE (1 << 30) |
115 | #define HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK120M_GATE (1 << 31) | 88 | #define HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK120M_GATE (1 << 31) |
116 | 89 | ||
117 | void clkctrl_reset(void) | ||
118 | { | ||
119 | switch(g_stmp_family) | ||
120 | { | ||
121 | case STMP3600: | ||
122 | *(volatile uint32_t *)(HW_POWER_BASE + 0xc0) = 0x3e770002; | ||
123 | break; | ||
124 | case STMP3700: | ||
125 | case STMP3770: | ||
126 | *(volatile uint32_t *)(HW_CLKCTRL_BASE + 0xf0) = 0x1; | ||
127 | break; | ||
128 | case STMP3780: | ||
129 | *(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x120) = 0x1; | ||
130 | break; | ||
131 | default: | ||
132 | break; | ||
133 | } | ||
134 | } | ||
135 | |||
136 | /** | 90 | /** |
137 | * | 91 | * |
138 | * Digctl | 92 | * Digctl |
@@ -143,11 +97,18 @@ void clkctrl_reset(void) | |||
143 | #define HW_DIGCTL_BASE 0x8001C000 | 97 | #define HW_DIGCTL_BASE 0x8001C000 |
144 | #define HW_DIGCTL_CTRL (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0)) | 98 | #define HW_DIGCTL_CTRL (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0)) |
145 | #define HW_DIGCTL_CTRL__USB_CLKGATE (1 << 2) | 99 | #define HW_DIGCTL_CTRL__USB_CLKGATE (1 << 2) |
100 | #define HW_DIGCTL_CTRL__PACKAGE_SENSE_ENABLE_STMP3600 (1 << 0) | ||
101 | |||
102 | #define HW_DIGCTL_STATUS (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0x10)) | ||
103 | #define HW_DIGCTL_STATUS__PACKAGE_TYPE_BP 1 | ||
104 | #define HW_DIGCTL_STATUS__PACKAGE_TYPE_BM (7 << 1) | ||
105 | #define HW_DIGCTL_STATUS__PACKAGE_TYPE_STMP3600_BP 1 | ||
106 | #define HW_DIGCTL_STATUS__PACKAGE_TYPE_STMP3600_BM (1 << 1) | ||
146 | 107 | ||
147 | /* STMP3700+ */ | 108 | /* STMP3700+ */ |
148 | #define HW_DIGCTL_MICROSECONDS (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0xC0)) | 109 | #define HW_DIGCTL_MICROSECONDS (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0xC0)) |
149 | /* STMP3600 */ | 110 | /* STMP3600 */ |
150 | #define HW_DIGCTL_MICROSECONDS2 (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0xB0)) | 111 | #define HW_DIGCTL_MICROSECONDS_STMP3600 (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0xB0)) |
151 | 112 | ||
152 | #define HW_DIGCTL_CHIPID (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0x310)) | 113 | #define HW_DIGCTL_CHIPID (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0x310)) |
153 | #define HW_DIGCTL_CHIPID__PRODUCT_CODE_BP 16 | 114 | #define HW_DIGCTL_CHIPID__PRODUCT_CODE_BP 16 |
@@ -177,8 +138,25 @@ void clkctrl_reset(void) | |||
177 | #define HW_RTC_CTRL (*(volatile uint32_t *)(HW_RTC_BASE + 0)) | 138 | #define HW_RTC_CTRL (*(volatile uint32_t *)(HW_RTC_BASE + 0)) |
178 | #define HW_RTC_CTRL__WATCHDOGEN (1 << 4) | 139 | #define HW_RTC_CTRL__WATCHDOGEN (1 << 4) |
179 | 140 | ||
141 | struct hwstub_target_desc_t __attribute__((aligned(2))) target_descriptor = | ||
142 | { | ||
143 | sizeof(struct hwstub_target_desc_t), | ||
144 | HWSTUB_DT_TARGET, | ||
145 | HWSTUB_TARGET_STMP, | ||
146 | "STMP3600 / STMP3700 / STMP3780 (i.MX233)" | ||
147 | }; | ||
148 | |||
149 | static struct hwstub_stmp_desc_t __attribute__((aligned(2))) stmp_descriptor = | ||
150 | { | ||
151 | sizeof(struct hwstub_stmp_desc_t), | ||
152 | HWSTUB_DT_STMP, | ||
153 | 0, 0, 0 | ||
154 | }; | ||
155 | |||
180 | void target_init(void) | 156 | void target_init(void) |
181 | { | 157 | { |
158 | stmp_descriptor.wChipID = __XTRACT(HW_DIGCTL_CHIPID, PRODUCT_CODE); | ||
159 | stmp_descriptor.bRevision = __XTRACT(HW_DIGCTL_CHIPID, REVISION); | ||
182 | /* detect family */ | 160 | /* detect family */ |
183 | uint16_t product_code = __XTRACT(HW_DIGCTL_CHIPID, PRODUCT_CODE); | 161 | uint16_t product_code = __XTRACT(HW_DIGCTL_CHIPID, PRODUCT_CODE); |
184 | if(product_code >= 0x3600 && product_code < 0x3700) | 162 | if(product_code >= 0x3600 && product_code < 0x3700) |
@@ -208,6 +186,7 @@ void target_init(void) | |||
208 | 186 | ||
209 | if(g_stmp_family == STMP3600) | 187 | if(g_stmp_family == STMP3600) |
210 | { | 188 | { |
189 | stmp_descriptor.bPackage = __XTRACT(HW_DIGCTL_STATUS, PACKAGE_TYPE); | ||
211 | /* CPU clock is always derived from PLL, if we switch to PLL, cpu will | 190 | /* CPU clock is always derived from PLL, if we switch to PLL, cpu will |
212 | * run at 480 MHz unprepared ! That's bad so prepare to run at slow sleed | 191 | * run at 480 MHz unprepared ! That's bad so prepare to run at slow sleed |
213 | * (1.2MHz) for a safe transition */ | 192 | * (1.2MHz) for a safe transition */ |
@@ -230,7 +209,13 @@ void target_init(void) | |||
230 | __REG_CLR(HW_CLKCTRL_UTMICLKCTRL) = HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK30M_GATE; | 209 | __REG_CLR(HW_CLKCTRL_UTMICLKCTRL) = HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK30M_GATE; |
231 | } | 210 | } |
232 | else | 211 | else |
212 | { | ||
213 | __REG_SET(HW_DIGCTL_CTRL) = HW_DIGCTL_CTRL__PACKAGE_SENSE_ENABLE_STMP3600; | ||
214 | stmp_descriptor.bPackage = __XTRACT(HW_DIGCTL_STATUS, PACKAGE_TYPE_STMP3600); | ||
215 | __REG_CLR(HW_DIGCTL_CTRL) = HW_DIGCTL_CTRL__PACKAGE_SENSE_ENABLE_STMP3600; | ||
216 | |||
233 | __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__POWER; | 217 | __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__POWER; |
218 | } | ||
234 | /* enable USB PHY PLL */ | 219 | /* enable USB PHY PLL */ |
235 | __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS; | 220 | __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS; |
236 | /* power up USB PHY */ | 221 | /* power up USB PHY */ |
@@ -240,57 +225,24 @@ void target_init(void) | |||
240 | __REG_CLR(HW_DIGCTL_CTRL) = HW_DIGCTL_CTRL__USB_CLKGATE; | 225 | __REG_CLR(HW_DIGCTL_CTRL) = HW_DIGCTL_CTRL__USB_CLKGATE; |
241 | } | 226 | } |
242 | 227 | ||
243 | static struct usb_resp_info_stmp_t g_stmp; | 228 | void target_get_desc(int desc, void **buffer) |
244 | static struct usb_resp_info_target_t g_target = | ||
245 | { | ||
246 | .id = HWSTUB_TARGET_STMP, | ||
247 | .name = "STMP3600 / STMP3700 / STMP3780 (i.MX233)" | ||
248 | }; | ||
249 | |||
250 | int target_get_info(int info, void **buffer) | ||
251 | { | 229 | { |
252 | if(info == HWSTUB_INFO_STMP) | 230 | if(desc == HWSTUB_DT_STMP) |
253 | { | 231 | *buffer = &stmp_descriptor; |
254 | g_stmp.chipid = __XTRACT(HW_DIGCTL_CHIPID, PRODUCT_CODE); | ||
255 | g_stmp.rev = __XTRACT(HW_DIGCTL_CHIPID, REVISION); | ||
256 | g_stmp.is_supported = g_stmp_family != 0; | ||
257 | *buffer = &g_stmp; | ||
258 | return sizeof(g_stmp); | ||
259 | } | ||
260 | else if(info == HWSTUB_INFO_TARGET) | ||
261 | { | ||
262 | *buffer = &g_target; | ||
263 | return sizeof(g_target); | ||
264 | } | ||
265 | else | 232 | else |
266 | return -1; | 233 | *buffer = NULL; |
267 | } | 234 | } |
268 | 235 | ||
269 | int target_atexit(int method) | 236 | void target_get_config_desc(void *buffer, int *size) |
270 | { | 237 | { |
271 | g_atexit = method; | 238 | memcpy(buffer, &stmp_descriptor, sizeof(stmp_descriptor)); |
272 | return 0; | 239 | *size += sizeof(stmp_descriptor); |
273 | } | ||
274 | |||
275 | void target_exit(void) | ||
276 | { | ||
277 | switch(g_atexit) | ||
278 | { | ||
279 | case HWSTUB_ATEXIT_OFF: | ||
280 | power_off(); | ||
281 | // fallthrough in case of return | ||
282 | case HWSTUB_ATEXIT_REBOOT: | ||
283 | clkctrl_reset(); | ||
284 | // fallthrough in case of return | ||
285 | case HWSTUB_ATEXIT_NOP: | ||
286 | default: | ||
287 | return; | ||
288 | } | ||
289 | } | 240 | } |
290 | 241 | ||
291 | void target_udelay(int us) | 242 | void target_udelay(int us) |
292 | { | 243 | { |
293 | volatile uint32_t *reg = g_stmp_family == STMP3600 ? &HW_DIGCTL_MICROSECONDS2 : &HW_DIGCTL_MICROSECONDS; | 244 | volatile uint32_t *reg = g_stmp_family == STMP3600 ? |
245 | &HW_DIGCTL_MICROSECONDS_STMP3600 : &HW_DIGCTL_MICROSECONDS; | ||
294 | uint32_t cur = *reg; | 246 | uint32_t cur = *reg; |
295 | uint32_t end = cur + us; | 247 | uint32_t end = cur + us; |
296 | if(cur < end) | 248 | if(cur < end) |
diff --git a/utils/hwstub/stub/target.h b/utils/hwstub/stub/target.h index 43151e9a34..cb17401a9c 100644 --- a/utils/hwstub/stub/target.h +++ b/utils/hwstub/stub/target.h | |||
@@ -25,15 +25,16 @@ | |||
25 | 25 | ||
26 | /* do target specific init */ | 26 | /* do target specific init */ |
27 | void target_init(void); | 27 | void target_init(void); |
28 | /* exit, performing the atexit action (default is target specific) */ | 28 | /* get descriptor, set buffer to NULL on error */ |
29 | void target_exit(void); | 29 | void target_get_desc(int desc, void **buffer); |
30 | /* get information, return actual size or -1 if error */ | 30 | /* pack all descriptors for config desc */ |
31 | int target_get_info(int info, void **buffer); | 31 | void target_get_config_desc(void *buffer, int *size); |
32 | /* set atexit action or return -1 on error */ | ||
33 | int target_atexit(int action); | ||
34 | /* Wait a very short time (us<=1000) */ | 32 | /* Wait a very short time (us<=1000) */ |
35 | void target_udelay(int us); | 33 | void target_udelay(int us); |
36 | /* Wait for a short time (ms <= 1000) */ | 34 | /* Wait for a short time (ms <= 1000) */ |
37 | void target_mdelay(int ms); | 35 | void target_mdelay(int ms); |
38 | 36 | ||
37 | /* mandatory for all targets */ | ||
38 | extern struct hwstub_target_desc_t target_descriptor; | ||
39 | |||
39 | #endif /* __TARGET_H__ */ | 40 | #endif /* __TARGET_H__ */ |