summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2013-07-16 19:29:42 +0200
committerAmaury Pouly <amaury.pouly@gmail.com>2013-07-16 19:29:42 +0200
commite5de5e09c1ca6788d155393af0d906a9402ea7bc (patch)
tree14aa5a0d78ae96d233bdffe96e3207ba27a4631e /utils
parent5ba7e2ca72412a4e58a76f43738f6309b533e03f (diff)
downloadrockbox-e5de5e09c1ca6788d155393af0d906a9402ea7bc.tar.gz
rockbox-e5de5e09c1ca6788d155393af0d906a9402ea7bc.zip
hwstub: enhance exit protocol and implement on stmp
Rename STOP command to EXIT, introduce ATEXIT, this gives better control over the exit of the stub. Add stmp implementation. Change-Id: I45442c8b88b9330d12ef439417ca5ffa1520477a
Diffstat (limited to 'utils')
-rw-r--r--utils/hwstub/hwstub_protocol.h32
-rw-r--r--utils/hwstub/lib/hwstub.c21
-rw-r--r--utils/hwstub/lib/hwstub.h5
-rw-r--r--utils/hwstub/stub/stmp/target.c67
-rw-r--r--utils/hwstub/stub/target.h6
5 files changed, 107 insertions, 24 deletions
diff --git a/utils/hwstub/hwstub_protocol.h b/utils/hwstub/hwstub_protocol.h
index f47ce3b5db..99131aa70c 100644
--- a/utils/hwstub/hwstub_protocol.h
+++ b/utils/hwstub/hwstub_protocol.h
@@ -27,7 +27,7 @@
27 27
28#define HWSTUB_VERSION_MAJOR 2 28#define HWSTUB_VERSION_MAJOR 2
29#define HWSTUB_VERSION_MINOR 11 29#define HWSTUB_VERSION_MINOR 11
30#define HWSTUB_VERSION_REV 1 30#define HWSTUB_VERSION_REV 2
31 31
32#define HWSTUB_USB_VID 0xfee1 32#define HWSTUB_USB_VID 0xfee1
33#define HWSTUB_USB_PID 0xdead 33#define HWSTUB_USB_PID 0xdead
@@ -46,7 +46,8 @@
46#define HWSTUB_RW_MEM 2 /* optional */ 46#define HWSTUB_RW_MEM 2 /* optional */
47#define HWSTUB_CALL 3 /* optional */ 47#define HWSTUB_CALL 3 /* optional */
48#define HWSTUB_JUMP 4 /* optional */ 48#define HWSTUB_JUMP 4 /* optional */
49#define HWSTUB_STOP 5 /* optional */ 49#define HWSTUB_EXIT 5 /* optional */
50#define HWSTUB_ATEXIT 6 /* optional */
50 51
51/** 52/**
52 * HWSTUB_GET_INFO: get some information about an aspect of the device. 53 * HWSTUB_GET_INFO: get some information about an aspect of the device.
@@ -91,7 +92,7 @@ struct usb_resp_info_stmp_t
91#define HWSTUB_FEATURE_MEM (1 << 1) 92#define HWSTUB_FEATURE_MEM (1 << 1)
92#define HWSTUB_FEATURE_CALL (1 << 2) 93#define HWSTUB_FEATURE_CALL (1 << 2)
93#define HWSTUB_FEATURE_JUMP (1 << 3) 94#define HWSTUB_FEATURE_JUMP (1 << 3)
94#define HWSTUB_FEATURE_STOP (1 << 4) 95#define HWSTUB_FEATURE_EXIT (1 << 4)
95 96
96struct usb_resp_info_features_t 97struct usb_resp_info_features_t
97{ 98{
@@ -129,12 +130,23 @@ struct usb_resp_info_target_t
129 * the transfer is either a read or a write. */ 130 * the transfer is either a read or a write. */
130 131
131/** 132/**
132 * HWSTUB_STOP: only if has HWSTUB_FEATURE_STOP. 133 * HWSTUB_EXIT: only if has HWSTUB_FEATURE_EXIT.
133 * Stop hwstub. Several methods can be employed (not all may be supported). 134 * Stop hwstub now, performing the atexit action. Default exit action
134 * The method is stored in wValue and interpreted as follows: 135 * is target dependent. */
135 * - reboot: immediately reboot the device 136
136 * - off: wait for USB disconnection and power off */ 137/**
137#define HWSTUB_STOP_REBOOT 0 138 * HWSTUB_ATEXIT: only if has HWSTUB_FEATURE_EXIT.
138#define HWSTUB_STOP_OFF 1 139 * Sets the action to perform at exit. Exit happens by sending HWSTUB_EXIT
140 * or on USB disconnection. The following actions are available:
141 * - nop: don't do anything, wait for next connection
142 * - reboot: reboot the device
143 * - off: power off
144 * NOTE the power off action might have to wait for USB disconnection as some
145 * targets cannot power off while plugged.
146 * NOTE appart from nop which is mandatory, all other methods can be
147 * unavailable and thus the atexit command can fail. */
148#define HWSTUB_ATEXIT_REBOOT 0
149#define HWSTUB_ATEXIT_OFF 1
150#define HWSTUB_ATEXIT_NOP 2
139 151
140#endif /* __HWSTUB_PROTOCOL__ */ 152#endif /* __HWSTUB_PROTOCOL__ */
diff --git a/utils/hwstub/lib/hwstub.c b/utils/hwstub/lib/hwstub.c
index 92010e710b..41842fb181 100644
--- a/utils/hwstub/lib/hwstub.c
+++ b/utils/hwstub/lib/hwstub.c
@@ -158,17 +158,18 @@ const char *hwstub_get_rev_string(struct usb_resp_info_stmp_t *stmp)
158 } 158 }
159} 159}
160 160
161int hwstub_aes_otp(struct hwstub_device_t *dev, void *buf, size_t sz, uint16_t param) 161int hwstub_atexit(struct hwstub_device_t *dev, int method)
162{ 162{
163 int ret = libusb_control_transfer(dev->handle, 163 return libusb_control_transfer(dev->handle,
164 LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE |
165 LIBUSB_ENDPOINT_OUT, HWSTUB_ATEXIT, 0, method, NULL, 0,
166 1000);
167}
168
169int hwstub_exit(struct hwstub_device_t *dev)
170{
171 return libusb_control_transfer(dev->handle,
164 LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE | 172 LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE |
165 LIBUSB_ENDPOINT_OUT, HWSTUB_AES_OTP, param, 0, buf, sz, 173 LIBUSB_ENDPOINT_OUT, HWSTUB_EXIT, 0, 0, NULL, 0,
166 1000); 174 1000);
167 if(ret <0 || (unsigned)ret != sz)
168 return -1;
169 int xfer;
170 ret = libusb_interrupt_transfer(dev->handle, dev->int_in, buf, sz, &xfer, 1000);
171 if(ret < 0 || (unsigned)xfer != sz)
172 return -1;
173 return ret;
174} 175}
diff --git a/utils/hwstub/lib/hwstub.h b/utils/hwstub/lib/hwstub.h
index ed058dfa3b..f89bce5de9 100644
--- a/utils/hwstub/lib/hwstub.h
+++ b/utils/hwstub/lib/hwstub.h
@@ -57,8 +57,9 @@ int hwstub_rw_mem(struct hwstub_device_t *dev, int read, uint32_t addr, void *bu
57/* Returns <0 on error */ 57/* Returns <0 on error */
58int hwstub_call(struct hwstub_device_t *dev, uint32_t addr); 58int hwstub_call(struct hwstub_device_t *dev, uint32_t addr);
59int hwstub_jump(struct hwstub_device_t *dev, uint32_t addr); 59int hwstub_jump(struct hwstub_device_t *dev, uint32_t addr);
60/* Returns <0 on error. The size must be a multiple of 16. */ 60/* Returns <0 on error */
61int hwstub_aes_otp(struct hwstub_device_t *dev, void *buf, size_t sz, uint16_t param); 61int hwstub_atexit(struct hwstub_device_t *dev, int action);
62int hwstub_exit(struct hwstub_device_t *dev);
62 63
63const char *hwstub_get_product_string(struct usb_resp_info_stmp_t *stmp); 64const char *hwstub_get_product_string(struct usb_resp_info_stmp_t *stmp);
64const char *hwstub_get_rev_string(struct usb_resp_info_stmp_t *stmp); 65const char *hwstub_get_rev_string(struct usb_resp_info_stmp_t *stmp);
diff --git a/utils/hwstub/stub/stmp/target.c b/utils/hwstub/stub/stmp/target.c
index 11516e5492..da46d50779 100644
--- a/utils/hwstub/stub/stmp/target.c
+++ b/utils/hwstub/stub/stmp/target.c
@@ -49,7 +49,35 @@ enum stmp_family_t
49 STMP3780 49 STMP3780
50}; 50};
51 51
52enum stmp_family_t g_stmp_family = UNKNOWN; 52static 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) = 0x3e770003;
73 break;
74 case STMP3780:
75 *(volatile uint32_t *)(HW_POWER_BASE + 0x100) = 0x3e770003;
76 break;
77 default:
78 break;
79 }
80}
53 81
54/** 82/**
55 * 83 *
@@ -86,6 +114,25 @@ enum stmp_family_t g_stmp_family = UNKNOWN;
86#define HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK30M_GATE (1 << 30) 114#define HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK30M_GATE (1 << 30)
87#define HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK120M_GATE (1 << 31) 115#define HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK120M_GATE (1 << 31)
88 116
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 + 0x100) = 0x1;
130 break;
131 default:
132 break;
133 }
134}
135
89/** 136/**
90 * 137 *
91 * Digctl 138 * Digctl
@@ -205,6 +252,24 @@ int target_get_info(int info, void **buffer)
205 return -1; 252 return -1;
206} 253}
207 254
255int target_atexit(int method)
256{
257 g_atexit = method;
258 return 0;
259}
260
208void target_exit(void) 261void target_exit(void)
209{ 262{
263 switch(g_atexit)
264 {
265 case HWSTUB_ATEXIT_OFF:
266 power_off();
267 // fallthrough in case of return
268 case HWSTUB_ATEXIT_REBOOT:
269 clkctrl_reset();
270 // fallthrough in case of return
271 case HWSTUB_ATEXIT_NOP:
272 default:
273 return;
274 }
210} 275}
diff --git a/utils/hwstub/stub/target.h b/utils/hwstub/stub/target.h
index 3f1551c72d..56c960741f 100644
--- a/utils/hwstub/stub/target.h
+++ b/utils/hwstub/stub/target.h
@@ -23,9 +23,13 @@
23 23
24#include "protocol.h" 24#include "protocol.h"
25 25
26/* do target specific init */
26void target_init(void); 27void target_init(void);
28/* exit, performing the atexit action (default is target specific) */
27void target_exit(void); 29void target_exit(void);
28/* return actual size or -1 if error */ 30/* get information, return actual size or -1 if error */
29int target_get_info(int info, void **buffer); 31int target_get_info(int info, void **buffer);
32/* set atexit action or return -1 on error */
33int target_atexit(int action);
30 34
31#endif /* __TARGET_H__ */ 35#endif /* __TARGET_H__ */