diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2013-07-16 19:29:42 +0200 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2013-07-16 19:29:42 +0200 |
commit | e5de5e09c1ca6788d155393af0d906a9402ea7bc (patch) | |
tree | 14aa5a0d78ae96d233bdffe96e3207ba27a4631e /utils/hwstub | |
parent | 5ba7e2ca72412a4e58a76f43738f6309b533e03f (diff) | |
download | rockbox-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/hwstub')
-rw-r--r-- | utils/hwstub/hwstub_protocol.h | 32 | ||||
-rw-r--r-- | utils/hwstub/lib/hwstub.c | 21 | ||||
-rw-r--r-- | utils/hwstub/lib/hwstub.h | 5 | ||||
-rw-r--r-- | utils/hwstub/stub/stmp/target.c | 67 | ||||
-rw-r--r-- | utils/hwstub/stub/target.h | 6 |
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 | ||
96 | struct usb_resp_info_features_t | 97 | struct 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 | ||
161 | int hwstub_aes_otp(struct hwstub_device_t *dev, void *buf, size_t sz, uint16_t param) | 161 | int 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 | |||
169 | int 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 */ |
58 | int hwstub_call(struct hwstub_device_t *dev, uint32_t addr); | 58 | int hwstub_call(struct hwstub_device_t *dev, uint32_t addr); |
59 | int hwstub_jump(struct hwstub_device_t *dev, uint32_t addr); | 59 | int 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 */ |
61 | int hwstub_aes_otp(struct hwstub_device_t *dev, void *buf, size_t sz, uint16_t param); | 61 | int hwstub_atexit(struct hwstub_device_t *dev, int action); |
62 | int hwstub_exit(struct hwstub_device_t *dev); | ||
62 | 63 | ||
63 | const char *hwstub_get_product_string(struct usb_resp_info_stmp_t *stmp); | 64 | const char *hwstub_get_product_string(struct usb_resp_info_stmp_t *stmp); |
64 | const char *hwstub_get_rev_string(struct usb_resp_info_stmp_t *stmp); | 65 | const 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 | ||
52 | enum stmp_family_t g_stmp_family = UNKNOWN; | 52 | 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) = 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 | ||
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 + 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 | ||
255 | int target_atexit(int method) | ||
256 | { | ||
257 | g_atexit = method; | ||
258 | return 0; | ||
259 | } | ||
260 | |||
208 | void target_exit(void) | 261 | void 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 */ | ||
26 | void target_init(void); | 27 | void target_init(void); |
28 | /* exit, performing the atexit action (default is target specific) */ | ||
27 | void target_exit(void); | 29 | void target_exit(void); |
28 | /* return actual size or -1 if error */ | 30 | /* get information, return actual size or -1 if error */ |
29 | int target_get_info(int info, void **buffer); | 31 | int target_get_info(int info, void **buffer); |
32 | /* set atexit action or return -1 on error */ | ||
33 | int target_atexit(int action); | ||
30 | 34 | ||
31 | #endif /* __TARGET_H__ */ | 35 | #endif /* __TARGET_H__ */ |