summaryrefslogtreecommitdiff
path: root/utils/hwstub/stub
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2014-02-04 00:10:41 +0100
committerAmaury Pouly <amaury.pouly@gmail.com>2014-02-10 23:14:24 +0100
commitc17d30f20466861a244c603665c580feb7758abf (patch)
treec5044f599f89d89de0b1419bd40e92211f8c8b8a /utils/hwstub/stub
parent6d64111b3c2f772cfc3539bb13851f78d4b55870 (diff)
downloadrockbox-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.c241
-rw-r--r--utils/hwstub/stub/rk27xx/target.c59
-rw-r--r--utils/hwstub/stub/stmp/target.c132
-rw-r--r--utils/hwstub/stub/target.h13
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 */
83static 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
98static 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
109static const struct usb_string_descriptor __attribute__((aligned(2))) 82static 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)))
117static const struct usb_string_descriptor __attribute__((aligned(2))) 90static 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
127static struct usb_string_descriptor __attribute__((aligned(2))) 100/* this is stringid #0: languages supported */
128 usb_string_iSerial = 101static 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
138static struct usb_string_descriptor __attribute__((aligned(2))) 109static 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 */ 119static struct hwstub_layout_desc_t __attribute__((aligned(2)))
150static 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
169uint8_t *usb_buffer = oc_bufferstart; 136uint8_t *usb_buffer = oc_bufferstart;
170uint32_t usb_buffer_size = 0; 137uint32_t usb_buffer_size = 0;
171 138
172#define EP_BULK 1 139static void fill_layout_info(void)
173#define EP_INT 2
174
175static 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
181static void handle_std_dev_desc(struct usb_ctrlrequest *req) 149static 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
314struct 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
321struct usb_resp_info_layout_t g_layout;
322
323struct 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
329static 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
339static 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
375static void handle_get_log(struct usb_ctrlrequest *req) 286static 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
424static 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
432static 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
439static void handle_class_dev_req(struct usb_ctrlrequest *req) 335static 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
35static enum rk27xx_family_t g_rk27xx_family = UNKNOWN; 35static enum rk27xx_family_t g_rk27xx_family = UNKNOWN;
36static int g_atexit = HWSTUB_ATEXIT_OFF;
37 36
38static void _enable_irq(void) 37static void _enable_irq(void)
39{ 38{
@@ -43,23 +42,6 @@ static void _enable_irq(void)
43 ); 42 );
44} 43}
45 44
46static void power_off(void)
47{
48 GPIO_PCCON &= ~(1<<0);
49 while(1);
50}
51
52static 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 */
64void target_udelay(int us) 46void target_udelay(int us)
65{ 47{
@@ -132,41 +114,22 @@ void target_init(void)
132 } 114 }
133} 115}
134 116
135static struct usb_resp_info_target_t g_target = 117struct 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
141int target_get_info(int info, void **buffer) 125void 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
152int target_atexit(int method) 131void 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
158void 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 *)(&reg + 1))) 27#define __REG_SET(reg) (*((volatile uint32_t *)(&reg + 1)))
27#define __REG_CLR(reg) (*((volatile uint32_t *)(&reg + 2))) 28#define __REG_CLR(reg) (*((volatile uint32_t *)(&reg + 2)))
@@ -50,34 +51,6 @@ enum stmp_family_t
50}; 51};
51 52
52static enum stmp_family_t g_stmp_family = UNKNOWN; 53static enum stmp_family_t g_stmp_family = UNKNOWN;
53static int g_atexit = HWSTUB_ATEXIT_OFF;
54
55/**
56 *
57 * Power
58 *
59 */
60
61#define HW_POWER_BASE 0x80044000
62
63void 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
117void 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
141struct 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
149static 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
180void target_init(void) 156void 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
243static struct usb_resp_info_stmp_t g_stmp; 228void target_get_desc(int desc, void **buffer)
244static struct usb_resp_info_target_t g_target =
245{
246 .id = HWSTUB_TARGET_STMP,
247 .name = "STMP3600 / STMP3700 / STMP3780 (i.MX233)"
248};
249
250int 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
269int target_atexit(int method) 236void 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
275void 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
291void target_udelay(int us) 242void 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 */
27void target_init(void); 27void target_init(void);
28/* exit, performing the atexit action (default is target specific) */ 28/* get descriptor, set buffer to NULL on error */
29void target_exit(void); 29void target_get_desc(int desc, void **buffer);
30/* get information, return actual size or -1 if error */ 30/* pack all descriptors for config desc */
31int target_get_info(int info, void **buffer); 31void target_get_config_desc(void *buffer, int *size);
32/* set atexit action or return -1 on error */
33int target_atexit(int action);
34/* Wait a very short time (us<=1000) */ 32/* Wait a very short time (us<=1000) */
35void target_udelay(int us); 33void target_udelay(int us);
36/* Wait for a short time (ms <= 1000) */ 34/* Wait for a short time (ms <= 1000) */
37void target_mdelay(int ms); 35void target_mdelay(int ms);
38 36
37/* mandatory for all targets */
38extern struct hwstub_target_desc_t target_descriptor;
39
39#endif /* __TARGET_H__ */ 40#endif /* __TARGET_H__ */