summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
Diffstat (limited to 'utils')
-rw-r--r--utils/hwstub/hwstub_protocol.h (renamed from utils/hwstub/hwemul_protocol.h)68
-rw-r--r--utils/hwstub/lib/Makefile17
-rw-r--r--utils/hwstub/lib/hwemul_protocol.h1
-rw-r--r--utils/hwstub/lib/hwstub.c (renamed from utils/hwstub/lib/hwemul.c)41
-rw-r--r--utils/hwstub/lib/hwstub.h (renamed from utils/hwstub/lib/hwemul.h)39
-rw-r--r--utils/hwstub/lib/hwstub_protocol.h1
-rw-r--r--utils/hwstub/stmp/Makefile87
-rw-r--r--utils/hwstub/stmp/config.h29
-rw-r--r--utils/hwstub/stmp/format.h6
-rw-r--r--utils/hwstub/stmp/hwstub.db (renamed from utils/hwstub/stmp/hwemul.db)6
-rw-r--r--utils/hwstub/stmp/hwstub.lds (renamed from utils/hwstub/stmp/hwemul.lds)1
-rw-r--r--utils/hwstub/stmp/link.lds49
-rw-r--r--utils/hwstub/stmp/logf.h6
-rw-r--r--utils/hwstub/stmp/main.c536
-rw-r--r--utils/hwstub/stmp/memcpy.S176
-rw-r--r--utils/hwstub/stmp/memmove.S190
-rw-r--r--utils/hwstub/stmp/memset.S98
-rw-r--r--utils/hwstub/stmp/protocol.h2
-rw-r--r--utils/hwstub/stmp/stddef.h6
-rw-r--r--utils/hwstub/stmp/string.h6
-rw-r--r--utils/hwstub/stmp/system.h6
-rw-r--r--utils/hwstub/tools/Makefile36
-rw-r--r--utils/hwstub/tools/hwemul_tool.c558
-rw-r--r--utils/hwstub/tools/hwstub_load.cpp316
-rw-r--r--utils/hwstub/tools/hwstub_shell.cpp873
-rw-r--r--utils/hwstub/tools/init.lua104
26 files changed, 2063 insertions, 1195 deletions
diff --git a/utils/hwstub/hwemul_protocol.h b/utils/hwstub/hwstub_protocol.h
index f11fd91352..41be3957e8 100644
--- a/utils/hwstub/hwemul_protocol.h
+++ b/utils/hwstub/hwstub_protocol.h
@@ -18,19 +18,19 @@
18 * KIND, either express or implied. 18 * KIND, either express or implied.
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21#ifndef __HWEMUL_PROTOCOL__ 21#ifndef __HWSTUB_PROTOCOL__
22#define __HWEMUL_PROTOCOL__ 22#define __HWSTUB_PROTOCOL__
23 23
24#define HWEMUL_CLASS 0xfe 24#define HWSTUB_CLASS 0xfe
25#define HWEMUL_SUBCLASS 0xac 25#define HWSTUB_SUBCLASS 0xac
26#define HWEMUL_PROTOCOL 0x1d 26#define HWSTUB_PROTOCOL 0x1d
27 27
28#define HWEMUL_VERSION_MAJOR 2 28#define HWSTUB_VERSION_MAJOR 2
29#define HWEMUL_VERSION_MINOR 8 29#define HWSTUB_VERSION_MINOR 9
30#define HWEMUL_VERSION_REV 2 30#define HWSTUB_VERSION_REV 2
31 31
32#define HWEMUL_USB_VID 0xfee1 32#define HWSTUB_USB_VID 0xfee1
33#define HWEMUL_USB_PID 0xdead 33#define HWSTUB_USB_PID 0xdead
34 34
35/** 35/**
36 * Control commands 36 * Control commands
@@ -41,22 +41,22 @@
41 */ 41 */
42 42
43/* list of commands */ 43/* list of commands */
44#define HWEMUL_GET_INFO 0 /* mandatory */ 44#define HWSTUB_GET_INFO 0 /* mandatory */
45#define HWEMUL_GET_LOG 1 /* optional */ 45#define HWSTUB_GET_LOG 1 /* optional */
46#define HWEMUL_RW_MEM 2 /* optional */ 46#define HWSTUB_RW_MEM 2 /* optional */
47#define HWEMUL_CALL 3 /* optional */ 47#define HWSTUB_CALL 3 /* optional */
48#define HWEMUL_JUMP 4 /* optional */ 48#define HWSTUB_JUMP 4 /* optional */
49#define HWEMUL_AES_OTP 5 /* optional */ 49#define HWSTUB_AES_OTP 5 /* optional */
50 50
51/** 51/**
52 * HWEMUL_GET_INFO: get some information about an aspect of the device. 52 * HWSTUB_GET_INFO: get some information about an aspect of the device.
53 * The wIndex field of the SETUP specifies which information to get. */ 53 * The wIndex field of the SETUP specifies which information to get. */
54 54
55/* list of possible information */ 55/* list of possible information */
56#define HWEMUL_INFO_VERSION 0 56#define HWSTUB_INFO_VERSION 0
57#define HWEMUL_INFO_LAYOUT 1 57#define HWSTUB_INFO_LAYOUT 1
58#define HWEMUL_INFO_STMP 2 58#define HWSTUB_INFO_STMP 2
59#define HWEMUL_INFO_FEATURES 3 59#define HWSTUB_INFO_FEATURES 3
60 60
61struct usb_resp_info_version_t 61struct usb_resp_info_version_t
62{ 62{
@@ -86,11 +86,11 @@ struct usb_resp_info_stmp_t
86} __attribute__((packed)); 86} __attribute__((packed));
87 87
88/* list of possible features */ 88/* list of possible features */
89#define HWEMUL_FEATURE_LOG (1 << 0) 89#define HWSTUB_FEATURE_LOG (1 << 0)
90#define HWEMUL_FEATURE_MEM (1 << 1) 90#define HWSTUB_FEATURE_MEM (1 << 1)
91#define HWEMUL_FEATURE_CALL (1 << 2) 91#define HWSTUB_FEATURE_CALL (1 << 2)
92#define HWEMUL_FEATURE_JUMP (1 << 2) 92#define HWSTUB_FEATURE_JUMP (1 << 2)
93#define HWEMUL_FEATURE_AES_OTP (1 << 3) 93#define HWSTUB_FEATURE_AES_OTP (1 << 3)
94 94
95struct usb_resp_info_features_t 95struct usb_resp_info_features_t
96{ 96{
@@ -98,30 +98,32 @@ struct usb_resp_info_features_t
98}; 98};
99 99
100/** 100/**
101 * HWEMUL_GET_LOG: only if has HWEMUL_FEATURE_LOG. 101 * HWSTUB_GET_LOG: only if has HWSTUB_FEATURE_LOG.
102 * The log is returned as part of the control transfer. 102 * The log is returned as part of the control transfer.
103 */ 103 */
104 104
105/** 105/**
106 * HWEMUL_RW_MEM: only if has HWEMUL_FEATURE_MEM. 106 * HWSTUB_RW_MEM: only if has HWSTUB_FEATURE_MEM.
107 * The 32-bit address is split into two parts. 107 * The 32-bit address is split into two parts.
108 * The low 16-bit are stored in wValue and the upper 108 * The low 16-bit are stored in wValue and the upper
109 * 16-bit are stored in wIndex. Depending on the transfer direction, 109 * 16-bit are stored in wIndex. Depending on the transfer direction,
110 * the transfer is either a read or a write. */ 110 * the transfer is either a read or a write.
111 * The read/write on the device are guaranteed to be 16-bit/32-bit when
112 * possible, making it suitable to read/write registers. */
111 113
112/** 114/**
113 * HWEMUL_x: only if has HWEMUL_FEATURE_x where x=CALL or JUMP. 115 * HWSTUB_x: only if has HWSTUB_FEATURE_x where x=CALL or JUMP.
114 * The 32-bit address is split into two parts. 116 * The 32-bit address is split into two parts.
115 * The low 16-bit are stored in wValue and the upper 117 * The low 16-bit are stored in wValue and the upper
116 * 16-bit are stored in wIndex. Depending on the transfer direction, 118 * 16-bit are stored in wIndex. Depending on the transfer direction,
117 * the transfer is either a read or a write. */ 119 * the transfer is either a read or a write. */
118 120
119/** 121/**
120 * HWEMUL_AES_OTP: only if has HWEMUL_FEATURE_AES_OTP. 122 * HWSTUB_AES_OTP: only if has HWSTUB_FEATURE_AES_OTP.
121 * The control transfer contains the data to be en/decrypted and the data 123 * The control transfer contains the data to be en/decrypted and the data
122 * is sent back on the interrupt endpoint. The first 16-bytes of the data 124 * is sent back on the interrupt endpoint. The first 16-bytes of the data
123 * are interpreted as the IV. The output format is the same. 125 * are interpreted as the IV. The output format is the same.
124 * The wValue field contains the parameters of the process. */ 126 * The wValue field contains the parameters of the process. */
125#define HWEMUL_AES_OTP_ENCRYPT (1 << 0) 127#define HWSTUB_AES_OTP_ENCRYPT (1 << 0)
126 128
127#endif /* __HWEMUL_PROTOCOL__ */ 129#endif /* __HWSTUB_PROTOCOL__ */
diff --git a/utils/hwstub/lib/Makefile b/utils/hwstub/lib/Makefile
index 7280fe8e38..7c455e4586 100644
--- a/utils/hwstub/lib/Makefile
+++ b/utils/hwstub/lib/Makefile
@@ -2,26 +2,19 @@ CC=gcc
2AR=ar 2AR=ar
3CFLAGS=-W -Wall -O2 `pkg-config --cflags libusb-1.0` -std=c99 -g -fPIC 3CFLAGS=-W -Wall -O2 `pkg-config --cflags libusb-1.0` -std=c99 -g -fPIC
4LDFLAGS=`pkg-config --libs libusb-1.0` -fPIC 4LDFLAGS=`pkg-config --libs libusb-1.0` -fPIC
5LIB=libhwemul.a 5LIB=libhwstub.a
6REGTOOLS=../../regtools 6SRC=$(wildcard *.c)
7DESC=$(REGTOOLS)/desc
8HWEMULGEN=$(REGTOOLS)/hwemulgen
9HWEMULSOC_PREFIX=hwemul_soc
10SRC=$(wildcard *.c) $(HWEMULSOC_PREFIX).c
11OBJ=$(SRC:.c=.o) 7OBJ=$(SRC:.c=.o)
12 8
13all: $(LIB) $(EXEC) 9all: $(LIB)
14 10
15$(HWEMULSOC_PREFIX).c $(HWEMULSOC_PREFIX).h: 11%.o: %.c
16 $(HWEMULGEN) $(DESC)/*.xml $(HWEMULSOC_PREFIX)
17
18%.o: %.c $(HWEMULSOC_PREFIX).h
19 $(CC) $(CFLAGS) -c -o $@ $< 12 $(CC) $(CFLAGS) -c -o $@ $<
20 13
21$(LIB): $(OBJ) 14$(LIB): $(OBJ)
22 $(AR) rcs $@ $^ 15 $(AR) rcs $@ $^
23 16
24clean: 17clean:
25 rm -rf $(OBJ) $(LIB) $(HWEMULSOC_PREFIX).c $(HWEMULSOC_PREFIX).h 18 rm -rf $(OBJ) $(LIB)
26 19
27 20
diff --git a/utils/hwstub/lib/hwemul_protocol.h b/utils/hwstub/lib/hwemul_protocol.h
deleted file mode 100644
index d3ffb6ce00..0000000000
--- a/utils/hwstub/lib/hwemul_protocol.h
+++ /dev/null
@@ -1 +0,0 @@
1#include "../hwemul_protocol.h"
diff --git a/utils/hwstub/lib/hwemul.c b/utils/hwstub/lib/hwstub.c
index 3e2e6de38a..92010e710b 100644
--- a/utils/hwstub/lib/hwemul.c
+++ b/utils/hwstub/lib/hwstub.c
@@ -18,15 +18,14 @@
18 * KIND, either express or implied. 18 * KIND, either express or implied.
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21#include "hwemul.h" 21#include "hwstub.h"
22#include "hwemul_soc.h"
23 22
24#ifndef MIN 23#ifndef MIN
25#define MIN(a,b) ((a) < (b) ? (a) : (b)) 24#define MIN(a,b) ((a) < (b) ? (a) : (b))
26#endif 25#endif
27 26
28/* requires then ->handle field only */ 27/* requires then ->handle field only */
29int hwemul_probe(struct hwemul_device_t *dev) 28int hwstub_probe(struct hwstub_device_t *dev)
30{ 29{
31 libusb_device *mydev = libusb_get_device(dev->handle); 30 libusb_device *mydev = libusb_get_device(dev->handle);
32 31
@@ -44,9 +43,9 @@ int hwemul_probe(struct hwemul_device_t *dev)
44 const struct libusb_interface_descriptor *interface = 43 const struct libusb_interface_descriptor *interface =
45 &config->interface[intf].altsetting[0]; 44 &config->interface[intf].altsetting[0];
46 if(interface->bNumEndpoints != 3 || 45 if(interface->bNumEndpoints != 3 ||
47 interface->bInterfaceClass != HWEMUL_CLASS || 46 interface->bInterfaceClass != HWSTUB_CLASS ||
48 interface->bInterfaceSubClass != HWEMUL_SUBCLASS || 47 interface->bInterfaceSubClass != HWSTUB_SUBCLASS ||
49 interface->bInterfaceProtocol != HWEMUL_PROTOCOL) 48 interface->bInterfaceProtocol != HWSTUB_PROTOCOL)
50 continue; 49 continue;
51 dev->intf = intf; 50 dev->intf = intf;
52 dev->bulk_in = dev->bulk_out = dev->int_in = -1; 51 dev->bulk_in = dev->bulk_out = dev->int_in = -1;
@@ -73,26 +72,26 @@ int hwemul_probe(struct hwemul_device_t *dev)
73 return libusb_claim_interface(dev->handle, intf); 72 return libusb_claim_interface(dev->handle, intf);
74} 73}
75 74
76int hwemul_release(struct hwemul_device_t *dev) 75int hwstub_release(struct hwstub_device_t *dev)
77{ 76{
78 return libusb_release_interface(dev->handle, dev->intf); 77 return libusb_release_interface(dev->handle, dev->intf);
79} 78}
80 79
81int hwemul_get_info(struct hwemul_device_t *dev, uint16_t idx, void *info, size_t sz) 80int hwstub_get_info(struct hwstub_device_t *dev, uint16_t idx, void *info, size_t sz)
82{ 81{
83 return libusb_control_transfer(dev->handle, 82 return libusb_control_transfer(dev->handle,
84 LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN, 83 LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN,
85 HWEMUL_GET_INFO, 0, idx, info, sz, 1000); 84 HWSTUB_GET_INFO, 0, idx, info, sz, 1000);
86} 85}
87 86
88int hwemul_get_log(struct hwemul_device_t *dev, void *buf, size_t sz) 87int hwstub_get_log(struct hwstub_device_t *dev, void *buf, size_t sz)
89{ 88{
90 return libusb_control_transfer(dev->handle, 89 return libusb_control_transfer(dev->handle,
91 LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN, 90 LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN,
92 HWEMUL_GET_LOG, 0, 0, buf, sz, 1000); 91 HWSTUB_GET_LOG, 0, 0, buf, sz, 1000);
93} 92}
94 93
95int hwemul_rw_mem(struct hwemul_device_t *dev, int read, uint32_t addr, void *buf, size_t sz) 94int hwstub_rw_mem(struct hwstub_device_t *dev, int read, uint32_t addr, void *buf, size_t sz)
96{ 95{
97 size_t tot_sz = 0; 96 size_t tot_sz = 0;
98 while(sz) 97 while(sz)
@@ -101,7 +100,7 @@ int hwemul_rw_mem(struct hwemul_device_t *dev, int read, uint32_t addr, void *bu
101 int ret = libusb_control_transfer(dev->handle, 100 int ret = libusb_control_transfer(dev->handle,
102 LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE | 101 LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE |
103 (read ? LIBUSB_ENDPOINT_IN : LIBUSB_ENDPOINT_OUT), 102 (read ? LIBUSB_ENDPOINT_IN : LIBUSB_ENDPOINT_OUT),
104 HWEMUL_RW_MEM, addr & 0xffff, addr >> 16, buf, xfer, 1000); 103 HWSTUB_RW_MEM, addr & 0xffff, addr >> 16, buf, xfer, 1000);
105 if(ret != xfer) 104 if(ret != xfer)
106 return ret; 105 return ret;
107 sz -= xfer; 106 sz -= xfer;
@@ -112,23 +111,23 @@ int hwemul_rw_mem(struct hwemul_device_t *dev, int read, uint32_t addr, void *bu
112 return tot_sz; 111 return tot_sz;
113} 112}
114 113
115int hwemul_call(struct hwemul_device_t *dev, uint32_t addr) 114int hwstub_call(struct hwstub_device_t *dev, uint32_t addr)
116{ 115{
117 return libusb_control_transfer(dev->handle, 116 return libusb_control_transfer(dev->handle,
118 LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE | 117 LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE |
119 LIBUSB_ENDPOINT_OUT, HWEMUL_CALL, addr & 0xffff, addr >> 16, NULL, 0, 118 LIBUSB_ENDPOINT_OUT, HWSTUB_CALL, addr & 0xffff, addr >> 16, NULL, 0,
120 1000); 119 1000);
121} 120}
122 121
123int hwemul_jump(struct hwemul_device_t *dev, uint32_t addr) 122int hwstub_jump(struct hwstub_device_t *dev, uint32_t addr)
124{ 123{
125 return libusb_control_transfer(dev->handle, 124 return libusb_control_transfer(dev->handle,
126 LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE | 125 LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE |
127 LIBUSB_ENDPOINT_OUT, HWEMUL_JUMP, addr & 0xffff, addr >> 16, NULL, 0, 126 LIBUSB_ENDPOINT_OUT, HWSTUB_JUMP, addr & 0xffff, addr >> 16, NULL, 0,
128 1000); 127 1000);
129} 128}
130 129
131const char *hwemul_get_product_string(struct usb_resp_info_stmp_t *stmp) 130const char *hwstub_get_product_string(struct usb_resp_info_stmp_t *stmp)
132{ 131{
133 switch(stmp->chipid) 132 switch(stmp->chipid)
134 { 133 {
@@ -139,7 +138,7 @@ const char *hwemul_get_product_string(struct usb_resp_info_stmp_t *stmp)
139 } 138 }
140} 139}
141 140
142const char *hwemul_get_rev_string(struct usb_resp_info_stmp_t *stmp) 141const char *hwstub_get_rev_string(struct usb_resp_info_stmp_t *stmp)
143{ 142{
144 switch(stmp->chipid) 143 switch(stmp->chipid)
145 { 144 {
@@ -159,11 +158,11 @@ const char *hwemul_get_rev_string(struct usb_resp_info_stmp_t *stmp)
159 } 158 }
160} 159}
161 160
162int hwemul_aes_otp(struct hwemul_device_t *dev, void *buf, size_t sz, uint16_t param) 161int hwstub_aes_otp(struct hwstub_device_t *dev, void *buf, size_t sz, uint16_t param)
163{ 162{
164 int ret = libusb_control_transfer(dev->handle, 163 int ret = libusb_control_transfer(dev->handle,
165 LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE | 164 LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE |
166 LIBUSB_ENDPOINT_OUT, HWEMUL_AES_OTP, param, 0, buf, sz, 165 LIBUSB_ENDPOINT_OUT, HWSTUB_AES_OTP, param, 0, buf, sz,
167 1000); 166 1000);
168 if(ret <0 || (unsigned)ret != sz) 167 if(ret <0 || (unsigned)ret != sz)
169 return -1; 168 return -1;
diff --git a/utils/hwstub/lib/hwemul.h b/utils/hwstub/lib/hwstub.h
index 376ba65381..ed058dfa3b 100644
--- a/utils/hwstub/lib/hwemul.h
+++ b/utils/hwstub/lib/hwstub.h
@@ -18,12 +18,15 @@
18 * KIND, either express or implied. 18 * KIND, either express or implied.
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21#ifndef __HWEMUL__ 21#ifndef __HWSTUB__
22#define __HWEMUL__ 22#define __HWSTUB__
23 23
24#include <libusb.h> 24#include <libusb.h>
25#include "hwemul_protocol.h" 25#include "hwstub_protocol.h"
26#include "hwemul_soc.h" 26
27#ifdef __cplusplus
28extern "C" {
29#endif
27 30
28/** 31/**
29 * 32 *
@@ -31,7 +34,7 @@
31 * 34 *
32 */ 35 */
33 36
34struct hwemul_device_t 37struct hwstub_device_t
35{ 38{
36 libusb_device_handle *handle; 39 libusb_device_handle *handle;
37 int intf; 40 int intf;
@@ -41,23 +44,27 @@ struct hwemul_device_t
41}; 44};
42 45
43/* Requires then ->handle field only. Returns 0 on success */ 46/* Requires then ->handle field only. Returns 0 on success */
44int hwemul_probe(struct hwemul_device_t *dev); 47int hwstub_probe(struct hwstub_device_t *dev);
45/* Returns 0 on success */ 48/* Returns 0 on success */
46int hwemul_release(struct hwemul_device_t *dev); 49int hwstub_release(struct hwstub_device_t *dev);
47 50
48/* Returns number of bytes filled */ 51/* Returns number of bytes filled */
49int hwemul_get_info(struct hwemul_device_t *dev, uint16_t idx, void *info, size_t sz); 52int hwstub_get_info(struct hwstub_device_t *dev, uint16_t idx, void *info, size_t sz);
50/* Returns number of bytes filled */ 53/* Returns number of bytes filled */
51int hwemul_get_log(struct hwemul_device_t *dev, void *buf, size_t sz); 54int hwstub_get_log(struct hwstub_device_t *dev, void *buf, size_t sz);
52/* Returns number of bytes written/read or <0 on error */ 55/* Returns number of bytes written/read or <0 on error */
53int hwemul_rw_mem(struct hwemul_device_t *dev, int read, uint32_t addr, void *buf, size_t sz); 56int hwstub_rw_mem(struct hwstub_device_t *dev, int read, uint32_t addr, void *buf, size_t sz);
54/* Returns <0 on error */ 57/* Returns <0 on error */
55int hwemul_call(struct hwemul_device_t *dev, uint32_t addr); 58int hwstub_call(struct hwstub_device_t *dev, uint32_t addr);
56int hwemul_jump(struct hwemul_device_t *dev, uint32_t addr); 59int hwstub_jump(struct hwstub_device_t *dev, uint32_t addr);
57/* Returns <0 on error. The size must be a multiple of 16. */ 60/* Returns <0 on error. The size must be a multiple of 16. */
58int hwemul_aes_otp(struct hwemul_device_t *dev, void *buf, size_t sz, uint16_t param); 61int hwstub_aes_otp(struct hwstub_device_t *dev, void *buf, size_t sz, uint16_t param);
62
63const 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);
59 65
60const char *hwemul_get_product_string(struct usb_resp_info_stmp_t *stmp); 66#ifdef __cplusplus
61const char *hwemul_get_rev_string(struct usb_resp_info_stmp_t *stmp); 67} // extern "C"
68#endif
62 69
63#endif /* __HWEMUL__ */ \ No newline at end of file 70#endif /* __HWSTUB__ */ \ No newline at end of file
diff --git a/utils/hwstub/lib/hwstub_protocol.h b/utils/hwstub/lib/hwstub_protocol.h
new file mode 100644
index 0000000000..35510fa9b2
--- /dev/null
+++ b/utils/hwstub/lib/hwstub_protocol.h
@@ -0,0 +1 @@
#include "../hwstub_protocol.h"
diff --git a/utils/hwstub/stmp/Makefile b/utils/hwstub/stmp/Makefile
index ca61fe392d..7fd33c3d9e 100644
--- a/utils/hwstub/stmp/Makefile
+++ b/utils/hwstub/stmp/Makefile
@@ -1,58 +1,51 @@
1PREFIX?=arm-elf-eabi- 1#
2CC=$(PREFIX)gcc 2# common
3LD=$(PREFIX)gcc 3#
4AS=$(PREFIX)gcc 4CC=arm-elf-eabi-gcc
5OC=$(PREFIX)objcopy 5LD=arm-elf-eabi-gcc
6SBTOOLS=../../sbtools/ 6AS=arm-elf-eabi-gcc
7OC=arm-elf-eabi-objcopy
7CFLAGS=-W -Wall -Wundef -O -nostdlib -ffreestanding -Wstrict-prototypes -pipe -std=gnu99 -mcpu=arm926ej-s -fomit-frame-pointer -Wno-pointer-sign -Wno-override-init -ffunction-sections 8CFLAGS=-W -Wall -Wundef -O -nostdlib -ffreestanding -Wstrict-prototypes -pipe -std=gnu99 -mcpu=arm926ej-s -fomit-frame-pointer -Wno-pointer-sign -Wno-override-init -ffunction-sections
8CFLAGS_3700=$(CFLAGS) -DHAVE_STMP3700
9ASFLAGS=$(CFLAGS) -D__ASSEMBLER__ 9ASFLAGS=$(CFLAGS) -D__ASSEMBLER__
10ASFLAGS_3700=$(CFLAGS_3700) -D__ASSEMBLER__
11OCFLAGS= 10OCFLAGS=
12LINKER_FILE=hwemul.lds 11LINKER_FILE=hwstub.lds
13LDFLAGS=-lgcc -Os -nostdlib -Tlink.lds -Wl,-Map,hwemul.map 12TMP_LDS=link.lds
14LDFLAGS_3700=-lgcc -Os -nostdlib -Tlink.lds -Wl,-Map,hwemul3700.map 13TMP_MAP=hwstub.map
14LDFLAGS=-lgcc -Os -nostdlib -T$(TMP_LDS) -Wl,-Map,$(TMP_MAP)
15SRC_C=$(wildcard *.c) 15SRC_C=$(wildcard *.c)
16SRC_S=$(wildcard *.S) 16SRC_S=$(wildcard *.S)
17OBJ_C=$(SRC_C:.c=.o) 17OBJ_C=$(SRC_C:.c=.o)
18OBJ_S=$(SRC_S:.S=.o) 18OBJ_S=$(SRC_S:.S=.o)
19OBJ_C_3700=$(SRC_C:.c=.3700.o)
20OBJ_S_3700=$(SRC_S:.S=.3700.o)
21OBJ=$(OBJ_C) $(OBJ_S) 19OBJ=$(OBJ_C) $(OBJ_S)
22OBJ_3700=$(OBJ_C_3700) $(OBJ_S_3700)
23OBJ_EXCEPT_CRT0=$(filter-out crt0.o,$(OBJ)) 20OBJ_EXCEPT_CRT0=$(filter-out crt0.o,$(OBJ))
24OBJ_EXCEPT_CRT0_3700=$(filter-out crt0.3700.o,$(OBJ_3700))
25DEPS=$(OBJ:.o=.d) 21DEPS=$(OBJ:.o=.d)
26EXEC_ELF=hwemul.elf 22EXEC_ELF=hwstub.elf
27EXEC_SB=hwemul.sb
28EXEC_ELF_3700=hwemul3700.elf
29EXEC_SB_3700=hwemul3700.sb
30 23
24#
25# image production
26#
27TOOLS=../../../tools
28SBTOOLS=../../imxtools/sbtools
29
30# sb (stmp37xx)
31EXEC_SB=hwstub.sb
31ELF2SB=$(SBTOOLS)/elftosb -d 32ELF2SB=$(SBTOOLS)/elftosb -d
32ELF2SB_CMD=-c hwemul.db 33ELF2SB_CMD=-c hwstub.db
33ELF2SB_KEY=-z 34ELF2SB_KEY?=-z
34SBLOADER=$(SBTOOLS)/sbloader
35SBLOADER_CMD=0 $(EXEC_SB)
36SBLOADER_CMD_3700=0 $(EXEC_SB_3700)
37 35
38TOOLS=../../../../tools/ 36# sb1 (stmp36xx)
39SCRAMBLE=$(TOOLS)/scramble 37EXEC_SB1=hwstub.sb1
38ELF2SB1_CMD=-loadjump $(EXEC_ELF)
39ELF2SB1_KEY?=
40ELF2SB1=$(SBTOOLS)/elftosb1 -d
40 41
41EXEC=$(EXEC_SB) $(EXEC_SB_3700) $(EXEC_ELF) $(EXEC_ELF_3700) 42EXEC=$(EXEC_ELF) $(EXEC_SB) $(EXEC_SB1)
42 43
43all: $(EXEC) 44all: $(EXEC)
44 45
45# pull in dependency info for *existing* .o files 46# pull in dependency info for *existing* .o files
46-include $(DEPS) 47-include $(DEPS)
47 48
48%.3700.o: %.c
49 $(CC) $(CFLAGS_3700) -c -o $@ $<
50 $(CC) -MM $(CFLAGS_3700) $*.c > $*.d
51 @cp -f $*.d $*.d.tmp
52 @sed -e 's/.*://' -e 's/\\$$//' < $*.d.tmp | fmt -1 | \
53 sed -e 's/^ *//' -e 's/$$/:/' >> $*.d
54 @rm -f $*.d.tmp
55
56%.o: %.c 49%.o: %.c
57 $(CC) $(CFLAGS) -c -o $@ $< 50 $(CC) $(CFLAGS) -c -o $@ $<
58 $(CC) -MM $(CFLAGS) $*.c > $*.d 51 $(CC) -MM $(CFLAGS) $*.c > $*.d
@@ -61,32 +54,20 @@ all: $(EXEC)
61 sed -e 's/^ *//' -e 's/$$/:/' >> $*.d 54 sed -e 's/^ *//' -e 's/$$/:/' >> $*.d
62 @rm -f $*.d.tmp 55 @rm -f $*.d.tmp
63 56
64%.3700.o: %.S
65 $(AS) $(ASFLAGS_3700) -c -o $@ $<
66
67%.o: %.S 57%.o: %.S
68 $(AS) $(ASFLAGS) -c -o $@ $< 58 $(AS) $(ASFLAGS) -c -o $@ $<
69 59
70link.lds: $(LINKER_FILE) 60$(TMP_LDS): $(LINKER_FILE)
71 $(CC) -E -x c - < $< | sed '/#/d' > $@ 61 $(CC) -E -x c - < $< | sed '/#/d' > $@
72 62
73$(EXEC_ELF): $(OBJ) link.lds 63$(EXEC_ELF): $(OBJ) $(TMP_LDS)
74 $(LD) $(LDFLAGS) -o $@ $(OBJ_EXCEPT_CRT0) 64 $(LD) $(LDFLAGS) -o $@ $(OBJ_EXCEPT_CRT0)
75 65
76$(EXEC_SB): $(EXEC_ELF) 66$(EXEC_SB): $(EXEC_ELF)
77 $(ELF2SB) $(ELF2SB_CMD) $(ELF2SB_KEY) -o $@ 67 $(ELF2SB) $(ELF2SB_CMD) $(ELF2SB_KEY) -o $@
78 68
79$(EXEC_ELF_3700): $(OBJ_3700) link.lds 69$(EXEC_SB1): $(EXEC_ELF)
80 $(LD) $(LDFLAGS_3700) -o $@ $(OBJ_EXCEPT_CRT0_3700) 70 $(ELF2SB1) $(ELF2SB1_CMD) $(ELF2SB1_KEY) -o $@
81
82$(EXEC_SB_3700): $(EXEC_ELF_3700)
83 $(ELF2SB) $(ELF2SB_CMD) $(ELF2SB_KEY) -o $@
84
85sbload: $(EXEC_SB)
86 $(SBLOADER) $(SBLOADER_CMD)
87
88sbload3700: $(EXEC_SB_3700)
89 $(SBLOADER) $(SBLOADER_CMD_3700)
90 71
91clean: 72clean:
92 rm -rf $(OBJ) $(OBJ_3700) $(DEPS) $(EXEC) *.map 73 rm -rf $(OBJ) $(DEPS) $(EXEC) $(TMP_LDS) $(TMP_MAP) \ No newline at end of file
diff --git a/utils/hwstub/stmp/config.h b/utils/hwstub/stmp/config.h
index 6bd995e147..9d6de07f33 100644
--- a/utils/hwstub/stmp/config.h
+++ b/utils/hwstub/stmp/config.h
@@ -18,8 +18,8 @@
18 * KIND, either express or implied. 18 * KIND, either express or implied.
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21#ifndef __HWEMUL_CONFIG__ 21#ifndef __HWSTUB_CONFIG__
22#define __HWEMUL_CONFIG__ 22#define __HWSTUB_CONFIG__
23 23
24#define MEMORYSIZE 0 24#define MEMORYSIZE 0
25#define STACK_SIZE 0x1000 25#define STACK_SIZE 0x1000
@@ -30,4 +30,27 @@
30#define DRAM_ORIG 0x40000000 30#define DRAM_ORIG 0x40000000
31#define DRAM_SIZE (MEMORYSIZE * 0x100000) 31#define DRAM_SIZE (MEMORYSIZE * 0x100000)
32 32
33#endif /* __HWEMUL_CONFIG__ */ 33#define CPU_ARM
34#define ARM_ARCH 5
35
36#if defined(CPU_ARM) && defined(__ASSEMBLER__)
37/* ARMv4T doesn't switch the T bit when popping pc directly, we must use BX */
38.macro ldmpc cond="", order="ia", regs
39#if ARM_ARCH == 4 && defined(USE_THUMB)
40 ldm\cond\order sp!, { \regs, lr }
41 bx\cond lr
42#else
43 ldm\cond\order sp!, { \regs, pc }
44#endif
45.endm
46.macro ldrpc cond=""
47#if ARM_ARCH == 4 && defined(USE_THUMB)
48 ldr\cond lr, [sp], #4
49 bx\cond lr
50#else
51 ldr\cond pc, [sp], #4
52#endif
53.endm
54#endif
55
56#endif /* __HWSTUB_CONFIG__ */
diff --git a/utils/hwstub/stmp/format.h b/utils/hwstub/stmp/format.h
index a514c882ba..2ad4229f1e 100644
--- a/utils/hwstub/stmp/format.h
+++ b/utils/hwstub/stmp/format.h
@@ -18,12 +18,12 @@
18 * KIND, either express or implied. 18 * KIND, either express or implied.
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21#ifndef __HWEMUL_FORMAT__ 21#ifndef __HWSTUB_FORMAT__
22#define __HWEMUL_FORMAT__ 22#define __HWSTUB_FORMAT__
23 23
24#include <stdarg.h> 24#include <stdarg.h>
25 25
26void vuprintf(int (*push)(void *userp, unsigned char data), 26void vuprintf(int (*push)(void *userp, unsigned char data),
27 void *userp, const char *fmt, va_list ap); 27 void *userp, const char *fmt, va_list ap);
28 28
29#endif /* __HWEMUL_FORMAT__ */ 29#endif /* __HWSTUB_FORMAT__ */
diff --git a/utils/hwstub/stmp/hwemul.db b/utils/hwstub/stmp/hwstub.db
index 7a6f930f57..1a085da50a 100644
--- a/utils/hwstub/stmp/hwemul.db
+++ b/utils/hwstub/stmp/hwstub.db
@@ -20,12 +20,12 @@
20 ****************************************************************************/ 20 ****************************************************************************/
21sources 21sources
22{ 22{
23 hwemul = "hwemul.elf"; 23 hwstub = "hwstub.elf";
24} 24}
25 25
26section(0) 26section(0)
27{ 27{
28 load hwemul; 28 load hwstub;
29 jump hwemul(1); 29 jump hwstub(1);
30} 30}
31 31
diff --git a/utils/hwstub/stmp/hwemul.lds b/utils/hwstub/stmp/hwstub.lds
index 7e3ac747a2..61504a3e75 100644
--- a/utils/hwstub/stmp/hwemul.lds
+++ b/utils/hwstub/stmp/hwstub.lds
@@ -38,6 +38,7 @@ SECTIONS
38 { 38 {
39 oc_codestart = .; 39 oc_codestart = .;
40 *(.text*) 40 *(.text*)
41 *(.icode*)
41 *(.data*) 42 *(.data*)
42 *(.rodata*) 43 *(.rodata*)
43 } > OCRAM 44 } > OCRAM
diff --git a/utils/hwstub/stmp/link.lds b/utils/hwstub/stmp/link.lds
deleted file mode 100644
index 97b259955f..0000000000
--- a/utils/hwstub/stmp/link.lds
+++ /dev/null
@@ -1,49 +0,0 @@
1
2ENTRY(start)
3OUTPUT_FORMAT(elf32-littlearm)
4OUTPUT_ARCH(arm)
5STARTUP(crt0.o)
6
7
8
9MEMORY
10{
11 OCRAM : ORIGIN = 0, LENGTH = 0x8000
12}
13
14SECTIONS
15{
16 .octext :
17 {
18 oc_codestart = .;
19 *(.text*)
20 *(.data*)
21 *(.rodata*)
22 } > OCRAM
23
24 .bss (NOLOAD) :
25 {
26 bss_start = .;
27 *(.bss)
28 bss_end = .;
29 } > OCRAM
30
31 .stack (NOLOAD) :
32 {
33 oc_codeend = .;
34 oc_stackstart = .;
35 . += 0x1000;
36 oc_stackend = .;
37 oc_bufferstart = .;
38 } > OCRAM
39
40 .ocend (0 + 0x8000) (NOLOAD) :
41 {
42 oc_bufferend = .;
43 } > OCRAM
44
45 /DISCARD/ :
46 {
47 *(.eh_frame)
48 }
49}
diff --git a/utils/hwstub/stmp/logf.h b/utils/hwstub/stmp/logf.h
index 5aa882a630..48c8c2c9b9 100644
--- a/utils/hwstub/stmp/logf.h
+++ b/utils/hwstub/stmp/logf.h
@@ -18,8 +18,8 @@
18 * KIND, either express or implied. 18 * KIND, either express or implied.
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21#ifndef __HWEMUL_LOGF__ 21#ifndef __HWSTUB_LOGF__
22#define __HWEMUL_LOGF__ 22#define __HWSTUB_LOGF__
23 23
24#include "stddef.h" 24#include "stddef.h"
25#include <stdarg.h> 25#include <stdarg.h>
@@ -28,4 +28,4 @@ void enable_logf(bool en);
28void logf(const char *fmt, ...); 28void logf(const char *fmt, ...);
29size_t logf_readback(char *buf, size_t max_size); 29size_t logf_readback(char *buf, size_t max_size);
30 30
31#endif /* __HWEMUL_LOGF__ */ 31#endif /* __HWSTUB_LOGF__ */
diff --git a/utils/hwstub/stmp/main.c b/utils/hwstub/stmp/main.c
index 09bb6c7714..845f3842ea 100644
--- a/utils/hwstub/stmp/main.c
+++ b/utils/hwstub/stmp/main.c
@@ -34,118 +34,20 @@ extern unsigned char oc_bufferend[];
34 34
35/** 35/**
36 * 36 *
37 * Pin control 37 * Global
38 * 38 *
39 */ 39 */
40 40
41#define HW_PINCTRL_BASE 0x80018000 41enum stmp_family_t
42
43#define HW_PINCTRL_CTRL (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x0))
44#define HW_PINCTRL_MUXSEL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x100 + (i) * 0x10))
45#define HW_PINCTRL_DRIVE(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x200 + (i) * 0x10))
46#ifdef HAVE_STMP3700
47#define HW_PINCTRL_PULL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x300 + (i) * 0x10))
48#define HW_PINCTRL_DOUT(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x400 + (i) * 0x10))
49#define HW_PINCTRL_DIN(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x500 + (i) * 0x10))
50#define HW_PINCTRL_DOE(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x600 + (i) * 0x10))
51#define HW_PINCTRL_PIN2IRQ(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x700 + (i) * 0x10))
52#define HW_PINCTRL_IRQEN(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x800 + (i) * 0x10))
53#define HW_PINCTRL_IRQLEVEL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x900 + (i) * 0x10))
54#define HW_PINCTRL_IRQPOL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0xa00 + (i) * 0x10))
55#define HW_PINCTRL_IRQSTAT(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0xb00 + (i) * 0x10))
56#else
57#define HW_PINCTRL_PULL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x400 + (i) * 0x10))
58#define HW_PINCTRL_DOUT(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x500 + (i) * 0x10))
59#define HW_PINCTRL_DIN(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x600 + (i) * 0x10))
60#define HW_PINCTRL_DOE(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x700 + (i) * 0x10))
61#define HW_PINCTRL_PIN2IRQ(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x800 + (i) * 0x10))
62#define HW_PINCTRL_IRQEN(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0x900 + (i) * 0x10))
63#define HW_PINCTRL_IRQLEVEL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0xa00 + (i) * 0x10))
64#define HW_PINCTRL_IRQPOL(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0xb00 + (i) * 0x10))
65#define HW_PINCTRL_IRQSTAT(i) (*(volatile uint32_t *)(HW_PINCTRL_BASE + 0xc00 + (i) * 0x10))
66#endif
67
68#define PINCTRL_FUNCTION_MAIN 0
69#define PINCTRL_FUNCTION_ALT1 1
70#define PINCTRL_FUNCTION_ALT2 2
71#define PINCTRL_FUNCTION_GPIO 3
72
73#define PINCTRL_DRIVE_4mA 0
74#define PINCTRL_DRIVE_8mA 1
75#define PINCTRL_DRIVE_12mA 2
76#define PINCTRL_DRIVE_16mA 3 /* not available on all pins */
77
78typedef void (*pin_irq_cb_t)(int bank, int pin);
79
80static inline void imx233_pinctrl_init(void)
81{ 42{
82 __REG_CLR(HW_PINCTRL_CTRL) = __BLOCK_CLKGATE | __BLOCK_SFTRST; 43 UNKNOWN,
83} 44 STMP3600,
84 45 STMP3700,
85static inline void imx233_set_pin_drive_strength(unsigned bank, unsigned pin, unsigned strength) 46 STMP3770,
86{ 47 STMP3780
87 __REG_CLR(HW_PINCTRL_DRIVE(4 * bank + pin / 8)) = 3 << (4 * (pin % 8)); 48};
88 __REG_SET(HW_PINCTRL_DRIVE(4 * bank + pin / 8)) = strength << (4 * (pin % 8));
89}
90
91static inline void imx233_enable_gpio_output(unsigned bank, unsigned pin, bool enable)
92{
93 if(enable)
94 __REG_SET(HW_PINCTRL_DOE(bank)) = 1 << pin;
95 else
96 __REG_CLR(HW_PINCTRL_DOE(bank)) = 1 << pin;
97}
98
99static inline void imx233_enable_gpio_output_mask(unsigned bank, uint32_t pin_mask, bool enable)
100{
101 if(enable)
102 __REG_SET(HW_PINCTRL_DOE(bank)) = pin_mask;
103 else
104 __REG_CLR(HW_PINCTRL_DOE(bank)) = pin_mask;
105}
106
107static inline void imx233_set_gpio_output(unsigned bank, unsigned pin, bool value)
108{
109 if(value)
110 __REG_SET(HW_PINCTRL_DOUT(bank)) = 1 << pin;
111 else
112 __REG_CLR(HW_PINCTRL_DOUT(bank)) = 1 << pin;
113}
114
115static inline void imx233_set_gpio_output_mask(unsigned bank, uint32_t pin_mask, bool value)
116{
117 if(value)
118 __REG_SET(HW_PINCTRL_DOUT(bank)) = pin_mask;
119 else
120 __REG_CLR(HW_PINCTRL_DOUT(bank)) = pin_mask;
121}
122
123static inline uint32_t imx233_get_gpio_input_mask(unsigned bank, uint32_t pin_mask)
124{
125 return HW_PINCTRL_DIN(bank) & pin_mask;
126}
127
128static inline void imx233_set_pin_function(unsigned bank, unsigned pin, unsigned function)
129{
130 __REG_CLR(HW_PINCTRL_MUXSEL(2 * bank + pin / 16)) = 3 << (2 * (pin % 16));
131 __REG_SET(HW_PINCTRL_MUXSEL(2 * bank + pin / 16)) = function << (2 * (pin % 16));
132}
133
134static inline void imx233_enable_pin_pullup(unsigned bank, unsigned pin, bool enable)
135{
136 if(enable)
137 __REG_SET(HW_PINCTRL_PULL(bank)) = 1 << pin;
138 else
139 __REG_CLR(HW_PINCTRL_PULL(bank)) = 1 << pin;
140}
141 49
142static inline void imx233_enable_pin_pullup_mask(unsigned bank, uint32_t pin_msk, bool enable) 50enum stmp_family_t g_stmp_family = UNKNOWN;
143{
144 if(enable)
145 __REG_SET(HW_PINCTRL_PULL(bank)) = pin_msk;
146 else
147 __REG_CLR(HW_PINCTRL_PULL(bank)) = pin_msk;
148}
149 51
150/** 52/**
151 * 53 *
@@ -458,287 +360,38 @@ static void usb_drv_configure_endpoint(int ep_num, int type)
458 360
459/** 361/**
460 * 362 *
461 * Clock control 363 * Clkctrl
462 * 364 *
463 **/ 365 */
464#define __CLK_CLKGATE (1 << 31)
465#define __CLK_BUSY (1 << 29)
466 366
467#define HW_CLKCTRL_BASE 0x80040000 367#define HW_CLKCTRL_BASE 0x80040000
468 368
469#define HW_CLKCTRL_PLLCTRL0 (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x0)) 369#define HW_CLKCTRL_PLLCTRL0 (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x0))
370#define HW_CLKCTRL_PLLCTRL0__BYPASS (1 << 17) /* STMP3600 only */
470#define HW_CLKCTRL_PLLCTRL0__POWER (1 << 16) 371#define HW_CLKCTRL_PLLCTRL0__POWER (1 << 16)
471#define HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS (1 << 18) 372#define HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS (1 << 18)
472#define HW_CLKCTRL_PLLCTRL0__DIV_SEL_BP 20
473#define HW_CLKCTRL_PLLCTRL0__DIV_SEL_BM (3 << 20)
474 373
475#define HW_CLKCTRL_PLLCTRL1 (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x10)) 374#define HW_CLKCTRL_PLLCTRL1 (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x10))
375#define HW_CLKCTRL_PLLCTRL1__LOCK (1 << 31)
476 376
477#define HW_CLKCTRL_CPU (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x20)) 377/* STMP3600 only */
478#define HW_CLKCTRL_CPU__DIV_CPU_BP 0 378#define HW_CLKCTRL_CPUCLKCTRL (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x20))
479#define HW_CLKCTRL_CPU__DIV_CPU_BM 0x3f 379#define HW_CLKCTRL_CPUCLKCTRL__DIV_BP 0
480#define HW_CLKCTRL_CPU__INTERRUPT_WAIT (1 << 12) 380#define HW_CLKCTRL_CPUCLKCTRL__DIV_BM 0x3ff
481#define HW_CLKCTRL_CPU__DIV_XTAL_BP 16 381#define HW_CLKCTRL_CPUCLKCTRL__WAIT_PLL_LOCK (1 << 30)
482#define HW_CLKCTRL_CPU__DIV_XTAL_BM (0x3ff << 16)
483#define HW_CLKCTRL_CPU__DIV_XTAL_FRAC_EN (1 << 26)
484#define HW_CLKCTRL_CPU__BUSY_REF_CPU (1 << 28)
485
486#define HW_CLKCTRL_HBUS (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x30))
487#define HW_CLKCTRL_HBUS__DIV_BP 0
488#define HW_CLKCTRL_HBUS__DIV_BM 0x1f
489#define HW_CLKCTRL_HBUS__DIV_FRAC_EN (1 << 5)
490#define HW_CLKCTRL_HBUS__SLOW_DIV_BP 16
491#define HW_CLKCTRL_HBUS__SLOW_DIV_BM (0x7 << 16)
492#define HW_CLKCTRL_HBUS__AUTO_SLOW_MODE (1 << 20)
493
494#define HW_CLKCTRL_XBUS (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x40))
495#define HW_CLKCTRL_XBUS__DIV_BP 0
496#define HW_CLKCTRL_XBUS__DIV_BM 0x3ff
497#define HW_CLKCTRL_XBUS__BUSY (1 << 31)
498
499#define HW_CLKCTRL_XTAL (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x50))
500#define HW_CLKCTRL_XTAL__TIMROT_CLK32K_GATE (1 << 26)
501#define HW_CLKCTRL_XTAL__DRI_CLK24M_GATE (1 << 28)
502#define HW_CLKCTRL_XTAL__PWM_CLK24M_GATE (1 << 29)
503#define HW_CLKCTRL_XTAL__FILT_CLK24M_GATE (1 << 30)
504
505#define HW_CLKCTRL_PIX (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x60))
506#define HW_CLKCTRL_PIX__DIV_BP 0
507#define HW_CLKCTRL_PIX__DIV_BM 0xfff
508
509#define HW_CLKCTRL_SSP (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x70))
510#define HW_CLKCTRL_SSP__DIV_BP 0
511#define HW_CLKCTRL_SSP__DIV_BM 0x1ff
512
513#define HW_CLKCTRL_EMI (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0xa0))
514#define HW_CLKCTRL_EMI__DIV_EMI_BP 0
515#define HW_CLKCTRL_EMI__DIV_EMI_BM 0x3f
516#define HW_CLKCTRL_EMI__DIV_XTAL_BP 8
517#define HW_CLKCTRL_EMI__DIV_XTAL_BM (0xf << 8)
518#define HW_CLKCTRL_EMI__BUSY_REF_EMI (1 << 28)
519#define HW_CLKCTRL_EMI__SYNC_MODE_EN (1 << 30)
520#define HW_CLKCTRL_EMI__CLKGATE (1 << 31)
521
522#ifdef HAVE_STMP3770
523#define HW_CLKCTRL_CLKSEQ (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0xe0))
524#else
525#define HW_CLKCTRL_CLKSEQ (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x110))
526#endif
527#define HW_CLKCTRL_CLKSEQ__BYPASS_PIX (1 << 1)
528#define HW_CLKCTRL_CLKSEQ__BYPASS_SSP (1 << 5)
529#define HW_CLKCTRL_CLKSEQ__BYPASS_EMI (1 << 6)
530#define HW_CLKCTRL_CLKSEQ__BYPASS_CPU (1 << 7)
531
532#ifdef HAVE_STMP3770
533#define HW_CLKCTRL_FRAC (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0xd0))
534#else
535#define HW_CLKCTRL_FRAC (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0xf0))
536#endif
537#define HW_CLKCTRL_FRAC_CPU (*(volatile uint8_t *)(HW_CLKCTRL_BASE + 0xf0))
538#define HW_CLKCTRL_FRAC_EMI (*(volatile uint8_t *)(HW_CLKCTRL_BASE + 0xf1))
539#define HW_CLKCTRL_FRAC_PIX (*(volatile uint8_t *)(HW_CLKCTRL_BASE + 0xf2))
540#define HW_CLKCTRL_FRAC_IO (*(volatile uint8_t *)(HW_CLKCTRL_BASE + 0xf3))
541#define HW_CLKCTRL_FRAC_XX__XXDIV_BM 0x3f
542#define HW_CLKCTRL_FRAC_XX__XX_STABLE (1 << 6)
543#define HW_CLKCTRL_FRAC_XX__CLKGATEXX (1 << 7)
544
545#define HW_CLKCTRL_RESET (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x120))
546#define HW_CLKCTRL_RESET_CHIP 0x2
547#define HW_CLKCTRL_RESET_DIG 0x1
548
549/**
550 *
551 * DMA
552 *
553 */
554
555/********
556 * APHB *
557 ********/
558
559#define HW_APBH_BASE 0x80004000
560
561/* APHB channels */
562#define HW_APBH_SSP(ssp) ssp
563
564#define HW_APBH_CTRL0 (*(volatile uint32_t *)(HW_APBH_BASE + 0x0))
565#define HW_APBH_CTRL0__FREEZE_CHANNEL(i) (1 << (i))
566#define HW_APBH_CTRL0__CLKGATE_CHANNEL(i) (1 << ((i) + 8))
567#define HW_APBH_CTRL0__RESET_CHANNEL(i) (1 << ((i) + 16))
568#define HW_APBH_CTRL0__APB_BURST4_EN (1 << 28)
569#define HW_APBH_CTRL0__APB_BURST8_EN (1 << 29)
570
571#define HW_APBH_CTRL1 (*(volatile uint32_t *)(HW_APBH_BASE + 0x10))
572#define HW_APBH_CTRL1__CHx_CMDCMPLT_IRQ(i) (1 << (i))
573#define HW_APBH_CTRL1__CHx_CMDCMPLT_IRQ_EN(i) (1 << ((i) + 16))
574
575#define HW_APBH_CTRL2 (*(volatile uint32_t *)(HW_APBH_BASE + 0x20))
576#define HW_APBH_CTRL2__CHx_ERROR_IRQ(i) (1 << (i))
577#define HW_APBH_CTRL2__CHx_ERROR_STATUS(i) (1 << ((i) + 16))
578
579#define HW_APBH_CHx_CURCMDAR(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x40 + 0x70 * (i)))
580
581#define HW_APBH_CHx_NXTCMDAR(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x50 + 0x70 * (i)))
582
583#define HW_APBH_CHx_CMD(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x60 + 0x70 * (i)))
584
585#define HW_APBH_CHx_BAR(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x70 + 0x70 * (i)))
586
587#define HW_APBH_CHx_SEMA(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x80 + 0x70 * (i)))
588
589#define HW_APBH_CHx_DEBUG1(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0x90 + 0x70 * (i)))
590
591#define HW_APBH_CHx_DEBUG2(i) (*(volatile uint32_t *)(HW_APBH_BASE + 0xa0 + 0x70 * (i)))
592#define HW_APBH_CHx_DEBUG2__AHB_BYTES_BP 0
593#define HW_APBH_CHx_DEBUG2__AHB_BYTES_BM 0xffff
594#define HW_APBH_CHx_DEBUG2__APB_BYTES_BP 16
595#define HW_APBH_CHx_DEBUG2__APB_BYTES_BM 0xffff0000
596
597/********
598 * APHX *
599 ********/
600
601/* APHX channels */
602#define HW_APBX_AUDIO_ADC 0
603#define HW_APBX_AUDIO_DAC 1
604#define HW_APBX_I2C 3
605
606#define HW_APBX_BASE 0x80024000
607
608#define HW_APBX_CTRL0 (*(volatile uint32_t *)(HW_APBX_BASE + 0x0))
609
610#define HW_APBX_CTRL1 (*(volatile uint32_t *)(HW_APBX_BASE + 0x10))
611#define HW_APBX_CTRL1__CHx_CMDCMPLT_IRQ(i) (1 << (i))
612#define HW_APBX_CTRL1__CHx_CMDCMPLT_IRQ_EN(i) (1 << ((i) + 16))
613
614#define HW_APBX_CTRL2 (*(volatile uint32_t *)(HW_APBX_BASE + 0x20))
615#define HW_APBX_CTRL2__CHx_ERROR_IRQ(i) (1 << (i))
616#define HW_APBX_CTRL2__CHx_ERROR_STATUS(i) (1 << ((i) + 16))
617 382
618#define HW_APBX_CHANNEL_CTRL (*(volatile uint32_t *)(HW_APBX_BASE + 0x30)) 383/* STMP3600 */
619#define HW_APBX_CHANNEL_CTRL__FREEZE_CHANNEL(i) (1 << (i)) 384#define HW_CLKCTRL_HBUSCLKCTRL (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x30))
620#define HW_APBX_CHANNEL_CTRL__RESET_CHANNEL(i) (1 << ((i) + 16))
621 385
622#define HW_APBX_CHx_CURCMDAR(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x100 + (i) * 0x70)) 386/* STMP3600 only */
387#define HW_CLKCTRL_XBUSCLKCTRL (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x40))
388#define HW_CLKCTRL_XBUSCLKCTRL__DIV_BP 0
389#define HW_CLKCTRL_XBUSCLKCTRL__DIV_BM 0x3ff
623 390
624#define HW_APBX_CHx_NXTCMDAR(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x110 + (i) * 0x70)) 391/* STMP3600 only */
625 392#define HW_CLKCTRL_UTMICLKCTRL (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x70))
626#define HW_APBX_CHx_CMD(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x120 + (i) * 0x70)) 393#define HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK30M_GATE (1 << 30)
627 394#define HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK120M_GATE (1 << 31)
628#define HW_APBX_CHx_BAR(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x130 + (i) * 0x70))
629
630#define HW_APBX_CHx_SEMA(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x140 + (i) * 0x70))
631
632#define HW_APBX_CHx_DEBUG1(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x150 + (i) * 0x70))
633
634#define HW_APBX_CHx_DEBUG2(i) (*(volatile uint32_t *)(HW_APBX_BASE + 0x160 + (i) * 0x70))
635#define HW_APBX_CHx_DEBUG2__AHB_BYTES_BP 0
636#define HW_APBX_CHx_DEBUG2__AHB_BYTES_BM 0xffff
637#define HW_APBX_CHx_DEBUG2__APB_BYTES_BP 16
638#define HW_APBX_CHx_DEBUG2__APB_BYTES_BM 0xffff0000
639
640/**********
641 * COMMON *
642 **********/
643
644struct apb_dma_command_t
645{
646 struct apb_dma_command_t *next;
647 uint32_t cmd;
648 void *buffer;
649 /* PIO words follow */
650};
651
652#define APBH_DMA_CHANNEL(i) i
653#define APBX_DMA_CHANNEL(i) ((i) | 0x10)
654#define APB_IS_APBX_CHANNEL(x) ((x) & 0x10)
655#define APB_GET_DMA_CHANNEL(x) ((x) & 0xf)
656
657#define APB_SSP(ssp) APBH_DMA_CHANNEL(HW_APBH_SSP(ssp))
658#define APB_AUDIO_ADC APBX_DMA_CHANNEL(HW_APBX_AUDIO_ADC)
659#define APB_AUDIO_DAC APBX_DMA_CHANNEL(HW_APBX_AUDIO_DAC)
660#define APB_I2C APBX_DMA_CHANNEL(HW_APBX_I2C)
661
662#define HW_APB_CHx_CMD__COMMAND_BM 0x3
663#define HW_APB_CHx_CMD__COMMAND__NO_XFER 0
664#define HW_APB_CHx_CMD__COMMAND__WRITE 1
665#define HW_APB_CHx_CMD__COMMAND__READ 2
666#define HW_APB_CHx_CMD__COMMAND__SENSE 3
667#define HW_APB_CHx_CMD__CHAIN (1 << 2)
668#define HW_APB_CHx_CMD__IRQONCMPLT (1 << 3)
669/* those two are only available on APHB */
670#define HW_APBH_CHx_CMD__NANDLOCK (1 << 4)
671#define HW_APBH_CHx_CMD__NANDWAIT4READY (1 << 5)
672#define HW_APB_CHx_CMD__SEMAPHORE (1 << 6)
673#define HW_APB_CHx_CMD__WAIT4ENDCMD (1 << 7)
674/* An errata advise not to use it */
675//#define HW_APB_CHx_CMD__HALTONTERMINATE (1 << 8)
676#define HW_APB_CHx_CMD__CMDWORDS_BM 0xf000
677#define HW_APB_CHx_CMD__CMDWORDS_BP 12
678#define HW_APB_CHx_CMD__XFER_COUNT_BM 0xffff0000
679#define HW_APB_CHx_CMD__XFER_COUNT_BP 16
680/* For software use */
681#define HW_APB_CHx_CMD__UNUSED_BP 8
682#define HW_APB_CHx_CMD__UNUSED_BM (0xf << 8)
683#define HW_APB_CHx_CMD__UNUSED_MAGIC (0xa << 8)
684
685#define HW_APB_CHx_SEMA__PHORE_BM 0xff0000
686#define HW_APB_CHx_SEMA__PHORE_BP 16
687
688/* A single descriptor cannot transfer more than 2^16 bytes */
689#define IMX233_MAX_SINGLE_DMA_XFER_SIZE (1 << 16)
690
691static void imx233_dma_init(void)
692{
693 __REG_CLR(HW_APBH_CTRL0) = __BLOCK_CLKGATE | __BLOCK_SFTRST;
694 __REG_CLR(HW_APBX_CTRL0) = __BLOCK_CLKGATE | __BLOCK_SFTRST;
695}
696
697static void imx233_dma_reset_channel(unsigned chan)
698{
699 volatile uint32_t *ptr;
700 uint32_t bm;
701 if(APB_IS_APBX_CHANNEL(chan))
702 {
703 ptr = &HW_APBX_CHANNEL_CTRL;
704 bm = HW_APBX_CHANNEL_CTRL__RESET_CHANNEL(APB_GET_DMA_CHANNEL(chan));
705 }
706 else
707 {
708 ptr = &HW_APBH_CTRL0;
709 bm = HW_APBH_CTRL0__RESET_CHANNEL(APB_GET_DMA_CHANNEL(chan));
710 }
711 __REG_SET(*ptr) = bm;
712 /* wait for end of reset */
713 while(*ptr & bm)
714 ;
715}
716
717static void imx233_dma_start_command(unsigned chan, struct apb_dma_command_t *cmd)
718{
719 if(APB_IS_APBX_CHANNEL(chan))
720 {
721 HW_APBX_CHx_NXTCMDAR(APB_GET_DMA_CHANNEL(chan)) = (uint32_t)cmd;
722 HW_APBX_CHx_SEMA(APB_GET_DMA_CHANNEL(chan)) = 1;
723 }
724 else
725 {
726 HW_APBH_CHx_NXTCMDAR(APB_GET_DMA_CHANNEL(chan)) = (uint32_t)cmd;
727 HW_APBH_CHx_SEMA(APB_GET_DMA_CHANNEL(chan)) = 1;
728 }
729}
730
731static void imx233_dma_wait_completion(unsigned chan)
732{
733 volatile uint32_t *sema;
734 if(APB_IS_APBX_CHANNEL(chan))
735 sema = &HW_APBX_CHx_SEMA(APB_GET_DMA_CHANNEL(chan));
736 else
737 sema = &HW_APBH_CHx_SEMA(APB_GET_DMA_CHANNEL(chan));
738
739 while(*sema & HW_APB_CHx_SEMA__PHORE_BM)
740 ;
741}
742 395
743/** 396/**
744 * 397 *
@@ -751,8 +404,6 @@ static void imx233_dma_wait_completion(unsigned chan)
751#define HW_DIGCTL_CTRL (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0)) 404#define HW_DIGCTL_CTRL (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0))
752#define HW_DIGCTL_CTRL__USB_CLKGATE (1 << 2) 405#define HW_DIGCTL_CTRL__USB_CLKGATE (1 << 2)
753 406
754#define HW_DIGCTL_HCLKCOUNT (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0x20))
755
756#define HW_DIGCTL_MICROSECONDS (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0xC0)) 407#define HW_DIGCTL_MICROSECONDS (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0xC0))
757 408
758#define HW_DIGCTL_CHIPID (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0x310)) 409#define HW_DIGCTL_CHIPID (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0x310))
@@ -786,7 +437,6 @@ static void udelay(unsigned us)
786/* USB Phy */ 437/* USB Phy */
787#define HW_USBPHY_BASE 0x8007C000 438#define HW_USBPHY_BASE 0x8007C000
788#define HW_USBPHY_PWD (*(volatile uint32_t *)(HW_USBPHY_BASE + 0)) 439#define HW_USBPHY_PWD (*(volatile uint32_t *)(HW_USBPHY_BASE + 0))
789#define HW_USBPHY_PWD__ALL (7 << 10 | 0xf << 17)
790 440
791#define HW_USBPHY_CTRL (*(volatile uint32_t *)(HW_USBPHY_BASE + 0x30)) 441#define HW_USBPHY_CTRL (*(volatile uint32_t *)(HW_USBPHY_BASE + 0x30))
792 442
@@ -852,17 +502,9 @@ struct dcp_packet_t
852 * 502 *
853 */ 503 */
854 504
855void memcpy(uint8_t *dst, const uint8_t *src, uint32_t length) 505void memcpy(void *dest, const void *src, size_t n);
856{ 506void memmove(void *dest, const void *src, size_t n);
857 for(uint32_t i = 0; i < length; i++) 507void memset(void *dst, int value, size_t n);
858 dst[i] = src[i];
859}
860
861void memset(uint8_t *dst, uint8_t fill, uint32_t length)
862{
863 for(uint32_t i = 0; i < length; i++)
864 dst[i] = fill;
865}
866 508
867/** 509/**
868 * 510 *
@@ -880,9 +522,9 @@ static struct usb_device_descriptor __attribute__((aligned(2)))
880 .bDeviceSubClass = 0, 522 .bDeviceSubClass = 0,
881 .bDeviceProtocol = 0, 523 .bDeviceProtocol = 0,
882 .bMaxPacketSize0 = 64, 524 .bMaxPacketSize0 = 64,
883 .idVendor = HWEMUL_USB_VID, 525 .idVendor = HWSTUB_USB_VID,
884 .idProduct = HWEMUL_USB_PID, 526 .idProduct = HWSTUB_USB_PID,
885 .bcdDevice = HWEMUL_VERSION_MAJOR << 8 | HWEMUL_VERSION_MINOR, 527 .bcdDevice = HWSTUB_VERSION_MAJOR << 8 | HWSTUB_VERSION_MINOR,
886 .iManufacturer = 1, 528 .iManufacturer = 1,
887 .iProduct = 2, 529 .iProduct = 2,
888 .iSerialNumber = 3, 530 .iSerialNumber = 3,
@@ -913,9 +555,9 @@ static struct usb_interface_descriptor __attribute__((aligned(2)))
913 .bInterfaceNumber = 0, 555 .bInterfaceNumber = 0,
914 .bAlternateSetting = 0, 556 .bAlternateSetting = 0,
915 .bNumEndpoints = 3, 557 .bNumEndpoints = 3,
916 .bInterfaceClass = HWEMUL_CLASS, 558 .bInterfaceClass = HWSTUB_CLASS,
917 .bInterfaceSubClass = HWEMUL_SUBCLASS, 559 .bInterfaceSubClass = HWSTUB_SUBCLASS,
918 .bInterfaceProtocol = HWEMUL_PROTOCOL, 560 .bInterfaceProtocol = HWSTUB_PROTOCOL,
919 .iInterface = 4 561 .iInterface = 4
920}; 562};
921 563
@@ -966,9 +608,9 @@ static struct usb_string_descriptor __attribute__((aligned(2)))
966 28, 608 28,
967 USB_DT_STRING, 609 USB_DT_STRING,
968 {'A', 'c', 'i', 'd', ' ', 610 {'A', 'c', 'i', 'd', ' ',
969 '0' + (HWEMUL_VERSION_MAJOR >> 4), '0' + (HWEMUL_VERSION_MAJOR & 0xf), '.', 611 '0' + (HWSTUB_VERSION_MAJOR >> 4), '0' + (HWSTUB_VERSION_MAJOR & 0xf), '.',
970 '0' + (HWEMUL_VERSION_MINOR >> 4), '0' + (HWEMUL_VERSION_MINOR & 0xf), '.', 612 '0' + (HWSTUB_VERSION_MINOR >> 4), '0' + (HWSTUB_VERSION_MINOR & 0xf), '.',
971 '0' + (HWEMUL_VERSION_REV >> 4), '0' + (HWEMUL_VERSION_REV & 0xf) } 613 '0' + (HWSTUB_VERSION_REV >> 4), '0' + (HWSTUB_VERSION_REV & 0xf) }
972}; 614};
973 615
974/* this is stringid #0: languages supported */ 616/* this is stringid #0: languages supported */
@@ -1138,9 +780,9 @@ static void handle_std_req(struct usb_ctrlrequest *req)
1138 780
1139struct usb_resp_info_version_t g_version = 781struct usb_resp_info_version_t g_version =
1140{ 782{
1141 .major = HWEMUL_VERSION_MAJOR, 783 .major = HWSTUB_VERSION_MAJOR,
1142 .minor = HWEMUL_VERSION_MINOR, 784 .minor = HWSTUB_VERSION_MINOR,
1143 .revision = HWEMUL_VERSION_REV 785 .revision = HWSTUB_VERSION_REV
1144}; 786};
1145 787
1146struct usb_resp_info_layout_t g_layout; 788struct usb_resp_info_layout_t g_layout;
@@ -1149,8 +791,8 @@ struct usb_resp_info_stmp_t g_stmp;
1149 791
1150struct usb_resp_info_features_t g_features = 792struct usb_resp_info_features_t g_features =
1151{ 793{
1152 .feature_mask = HWEMUL_FEATURE_LOG | HWEMUL_FEATURE_MEM | 794 .feature_mask = HWSTUB_FEATURE_LOG | HWSTUB_FEATURE_MEM |
1153 HWEMUL_FEATURE_CALL | HWEMUL_FEATURE_JUMP | HWEMUL_FEATURE_AES_OTP 795 HWSTUB_FEATURE_CALL | HWSTUB_FEATURE_JUMP | HWSTUB_FEATURE_AES_OTP
1154}; 796};
1155 797
1156static void fill_layout_info(void) 798static void fill_layout_info(void)
@@ -1177,21 +819,21 @@ static void handle_get_info(struct usb_ctrlrequest *req)
1177 int size = 0; 819 int size = 0;
1178 switch(req->wIndex) 820 switch(req->wIndex)
1179 { 821 {
1180 case HWEMUL_INFO_VERSION: 822 case HWSTUB_INFO_VERSION:
1181 ptr = &g_version; 823 ptr = &g_version;
1182 size = sizeof(g_version); 824 size = sizeof(g_version);
1183 break; 825 break;
1184 case HWEMUL_INFO_LAYOUT: 826 case HWSTUB_INFO_LAYOUT:
1185 fill_layout_info(); 827 fill_layout_info();
1186 ptr = &g_layout; 828 ptr = &g_layout;
1187 size = sizeof(g_layout); 829 size = sizeof(g_layout);
1188 break; 830 break;
1189 case HWEMUL_INFO_STMP: 831 case HWSTUB_INFO_STMP:
1190 fill_stmp_info(); 832 fill_stmp_info();
1191 ptr = &g_stmp; 833 ptr = &g_stmp;
1192 size = sizeof(g_stmp); 834 size = sizeof(g_stmp);
1193 break; 835 break;
1194 case HWEMUL_INFO_FEATURES: 836 case HWSTUB_INFO_FEATURES:
1195 ptr = &g_features; 837 ptr = &g_features;
1196 size = sizeof(g_features); 838 size = sizeof(g_features);
1197 break; 839 break;
@@ -1249,17 +891,22 @@ static void handle_call_jump(struct usb_ctrlrequest *req)
1249{ 891{
1250 uint32_t addr = req->wValue | req->wIndex << 16; 892 uint32_t addr = req->wValue | req->wIndex << 16;
1251 893
1252 if(req->bRequest == HWEMUL_CALL) 894 if(req->bRequest == HWSTUB_CALL)
1253 ((void (*)(void))addr)(); 895 ((void (*)(void))addr)();
1254 else 896 else
897 {
898 /* disconnect to make sure usb/dma won't interfere */
899 REG_USBCMD &= ~USBCMD_RUN;
900 REG_USBCMD |= USBCMD_CTRL_RESET;
1255 asm volatile("bx %0\n" : : "r" (addr) : "memory"); 901 asm volatile("bx %0\n" : : "r" (addr) : "memory");
902 }
1256} 903}
1257 904
1258static void do_aes_otp(void *buffer, unsigned length, unsigned params) 905static void do_aes_otp(void *buffer, unsigned length, unsigned params)
1259{ 906{
1260 static struct dcp_packet_t dcp_packet; 907 static struct dcp_packet_t dcp_packet;
1261 908
1262 bool encrypt = !!(params & HWEMUL_AES_OTP_ENCRYPT); 909 bool encrypt = !!(params & HWSTUB_AES_OTP_ENCRYPT);
1263 /* reset DCP */ 910 /* reset DCP */
1264 __REG_SET(HW_DCP_CTRL) = 0x80000000; 911 __REG_SET(HW_DCP_CTRL) = 0x80000000;
1265 /* clear clock gate */ 912 /* clear clock gate */
@@ -1307,20 +954,20 @@ static void handle_class_dev_req(struct usb_ctrlrequest *req)
1307{ 954{
1308 switch(req->bRequest) 955 switch(req->bRequest)
1309 { 956 {
1310 case HWEMUL_GET_INFO: 957 case HWSTUB_GET_INFO:
1311 handle_get_info(req); 958 handle_get_info(req);
1312 break; 959 break;
1313 case HWEMUL_GET_LOG: 960 case HWSTUB_GET_LOG:
1314 handle_get_log(req); 961 handle_get_log(req);
1315 break; 962 break;
1316 case HWEMUL_RW_MEM: 963 case HWSTUB_RW_MEM:
1317 handle_rw_mem(req); 964 handle_rw_mem(req);
1318 break; 965 break;
1319 case HWEMUL_CALL: 966 case HWSTUB_CALL:
1320 case HWEMUL_JUMP: 967 case HWSTUB_JUMP:
1321 handle_call_jump(req); 968 handle_call_jump(req);
1322 break; 969 break;
1323 case HWEMUL_AES_OTP: 970 case HWSTUB_AES_OTP:
1324 handle_aes_otp(req); 971 handle_aes_otp(req);
1325 break; 972 break;
1326 default: 973 default:
@@ -1348,19 +995,68 @@ static void handle_class_req(struct usb_ctrlrequest *req)
1348void main(uint32_t arg) 995void main(uint32_t arg)
1349{ 996{
1350 usb_buffer_size = oc_buffersize; 997 usb_buffer_size = oc_buffersize;
1351 998
1352 logf("hwemul %d.%d.%d\n", HWEMUL_VERSION_MAJOR, HWEMUL_VERSION_MINOR, 999 logf("hwstub %d.%d.%d\n", HWSTUB_VERSION_MAJOR, HWSTUB_VERSION_MINOR,
1353 HWEMUL_VERSION_REV); 1000 HWSTUB_VERSION_REV);
1354 logf("argument: 0x%08x\n", arg); 1001 logf("argument: 0x%08x\n", arg);
1355 1002
1003 /* detect family */
1004 uint16_t product_code = __XTRACT(HW_DIGCTL_CHIPID, PRODUCT_CODE);
1005 if(product_code >= 0x3600 && product_code < 0x3700)
1006 {
1007 logf("identified STMP3600 family\n");
1008 g_stmp_family = STMP3600;
1009 }
1010 else if(product_code == 0x3700)
1011 {
1012 logf("identified STMP3700 family\n");
1013 g_stmp_family = STMP3700;
1014 }
1015 else if(product_code == 0x37b0)
1016 {
1017 logf("identified STMP3770 family\n");
1018 g_stmp_family = STMP3770;
1019 }
1020 else if(product_code == 0x3780)
1021 {
1022 logf("identified STMP3780 family\n");
1023 g_stmp_family = STMP3780;
1024 }
1025 else
1026 logf("cannot identify family: 0x%x\n", product_code);
1027
1356 /* we don't know if USB was connected or not. In USB recovery mode it will 1028 /* we don't know if USB was connected or not. In USB recovery mode it will
1357 * but in other cases it might not be. In doubt, disconnect */ 1029 * but in other cases it might not be. In doubt, disconnect */
1358 REG_USBCMD &= ~USBCMD_RUN; 1030 REG_USBCMD &= ~USBCMD_RUN;
1031 if(g_stmp_family == STMP3600)
1032 {
1033 /* CPU clock is always derived from PLL, if we switch to PLL, cpu will
1034 * run at 480 MHz unprepared ! That's bad so prepare to run at slow sleed
1035 * (1.2MHz) for a safe transition */
1036 HW_CLKCTRL_CPUCLKCTRL = HW_CLKCTRL_CPUCLKCTRL__WAIT_PLL_LOCK | 400;
1037 /* We need to ensure that XBUS < HBUS but HBUS will be 1.2 MHz after the
1038 * switch so lower XBUS too */
1039 HW_CLKCTRL_XBUSCLKCTRL = 20;
1040 /* Power PLL */
1041 __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__POWER;
1042 HW_CLKCTRL_PLLCTRL0 = (HW_CLKCTRL_PLLCTRL0 & ~0x3ff) | 480;
1043 /* Wait lock */
1044 while(!(HW_CLKCTRL_PLLCTRL1 & HW_CLKCTRL_PLLCTRL1__LOCK));
1045 /* Switch to PLL source */
1046 __REG_CLR(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__BYPASS;
1047 /* Get back XBUS = 24 MHz and CPU = HBUS = 64MHz */
1048 HW_CLKCTRL_CPUCLKCTRL = 7;
1049 HW_CLKCTRL_HBUSCLKCTRL = 7;
1050 HW_CLKCTRL_XBUSCLKCTRL = 1;
1051 __REG_CLR(HW_CLKCTRL_UTMICLKCTRL) = HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK120M_GATE;
1052 __REG_CLR(HW_CLKCTRL_UTMICLKCTRL) = HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK30M_GATE;
1053 }
1054 else
1055 __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__POWER;
1359 /* enable USB PHY PLL */ 1056 /* enable USB PHY PLL */
1360 __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS; 1057 __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS;
1361 /* power up USB PHY */ 1058 /* power up USB PHY */
1362 __REG_CLR(HW_USBPHY_CTRL) = __BLOCK_CLKGATE | __BLOCK_SFTRST; 1059 __REG_CLR(HW_USBPHY_CTRL) = __BLOCK_CLKGATE | __BLOCK_SFTRST;
1363 //__REG_CLR(HW_USBPHY_PWD) = HW_USBPHY_PWD__ALL;
1364 HW_USBPHY_PWD = 0; 1060 HW_USBPHY_PWD = 0;
1365 /* enable USB controller */ 1061 /* enable USB controller */
1366 __REG_CLR(HW_DIGCTL_CTRL) = HW_DIGCTL_CTRL__USB_CLKGATE; 1062 __REG_CLR(HW_DIGCTL_CTRL) = HW_DIGCTL_CTRL__USB_CLKGATE;
@@ -1382,7 +1078,7 @@ void main(uint32_t arg)
1382 REG_ENDPTSETUPSTAT = EPSETUP_STATUS_EP0; 1078 REG_ENDPTSETUPSTAT = EPSETUP_STATUS_EP0;
1383 /* run! */ 1079 /* run! */
1384 REG_USBCMD |= USBCMD_RUN; 1080 REG_USBCMD |= USBCMD_RUN;
1385 1081
1386 while(1) 1082 while(1)
1387 { 1083 {
1388 /* wait for setup */ 1084 /* wait for setup */
diff --git a/utils/hwstub/stmp/memcpy.S b/utils/hwstub/stmp/memcpy.S
new file mode 100644
index 0000000000..2a55fb5656
--- /dev/null
+++ b/utils/hwstub/stmp/memcpy.S
@@ -0,0 +1,176 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 Free Software Foundation, Inc.
11 * This file was originally part of the GNU C Library
12 * Contributed to glibc by MontaVista Software, Inc. (written by Nicolas Pitre)
13 * Adapted for Rockbox by Daniel Ankers
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
22 *
23 ****************************************************************************/
24
25#include "config.h"
26
27/*
28 * Endian independent macros for shifting bytes within registers.
29 */
30#ifndef __ARMEB__
31#define pull lsr
32#define push lsl
33#else
34#define pull lsl
35#define push lsr
36#endif
37
38/* Prototype: void *memcpy(void *dest, const void *src, size_t n); */
39
40 .section .icode,"ax",%progbits
41
42 .align 2
43 .global memcpy
44 .type memcpy,%function
45
46memcpy:
47 stmfd sp!, {r0, r4, lr}
48
49 subs r2, r2, #4
50 blt 8f
51 ands ip, r0, #3
52 bne 9f
53 ands ip, r1, #3
54 bne 10f
55
561: subs r2, r2, #(28)
57 stmfd sp!, {r5 - r8}
58 blt 5f
59
602:
613:
624: ldmia r1!, {r3, r4, r5, r6, r7, r8, ip, lr}
63 subs r2, r2, #32
64 stmia r0!, {r3, r4, r5, r6, r7, r8, ip, lr}
65 bge 3b
66
675: ands ip, r2, #28
68 rsb ip, ip, #32
69 addne pc, pc, ip @ C is always clear here
70 b 7f
716: nop
72 ldr r3, [r1], #4
73 ldr r4, [r1], #4
74 ldr r5, [r1], #4
75 ldr r6, [r1], #4
76 ldr r7, [r1], #4
77 ldr r8, [r1], #4
78 ldr lr, [r1], #4
79
80 add pc, pc, ip
81 nop
82 nop
83 str r3, [r0], #4
84 str r4, [r0], #4
85 str r5, [r0], #4
86 str r6, [r0], #4
87 str r7, [r0], #4
88 str r8, [r0], #4
89 str lr, [r0], #4
90
917: ldmfd sp!, {r5 - r8}
92
938: movs r2, r2, lsl #31
94 ldrneb r3, [r1], #1
95 ldrcsb r4, [r1], #1
96 ldrcsb ip, [r1]
97 strneb r3, [r0], #1
98 strcsb r4, [r0], #1
99 strcsb ip, [r0]
100
101 ldmpc regs="r0, r4"
102
1039: rsb ip, ip, #4
104 cmp ip, #2
105 ldrgtb r3, [r1], #1
106 ldrgeb r4, [r1], #1
107 ldrb lr, [r1], #1
108 strgtb r3, [r0], #1
109 strgeb r4, [r0], #1
110 subs r2, r2, ip
111 strb lr, [r0], #1
112 blt 8b
113 ands ip, r1, #3
114 beq 1b
115
11610: bic r1, r1, #3
117 cmp ip, #2
118 ldr lr, [r1], #4
119 beq 17f
120 bgt 18f
121
122
123 .macro forward_copy_shift pull push
124
125 subs r2, r2, #28
126 blt 14f
127
12811: stmfd sp!, {r5 - r9}
129
13012:
13113: ldmia r1!, {r4, r5, r6, r7}
132 mov r3, lr, pull #\pull
133 subs r2, r2, #32
134 ldmia r1!, {r8, r9, ip, lr}
135 orr r3, r3, r4, push #\push
136 mov r4, r4, pull #\pull
137 orr r4, r4, r5, push #\push
138 mov r5, r5, pull #\pull
139 orr r5, r5, r6, push #\push
140 mov r6, r6, pull #\pull
141 orr r6, r6, r7, push #\push
142 mov r7, r7, pull #\pull
143 orr r7, r7, r8, push #\push
144 mov r8, r8, pull #\pull
145 orr r8, r8, r9, push #\push
146 mov r9, r9, pull #\pull
147 orr r9, r9, ip, push #\push
148 mov ip, ip, pull #\pull
149 orr ip, ip, lr, push #\push
150 stmia r0!, {r3, r4, r5, r6, r7, r8, r9, ip}
151 bge 12b
152
153 ldmfd sp!, {r5 - r9}
154
15514: ands ip, r2, #28
156 beq 16f
157
15815: mov r3, lr, pull #\pull
159 ldr lr, [r1], #4
160 subs ip, ip, #4
161 orr r3, r3, lr, push #\push
162 str r3, [r0], #4
163 bgt 15b
164
16516: sub r1, r1, #(\push / 8)
166 b 8b
167
168 .endm
169
170
171 forward_copy_shift pull=8 push=24
172
17317: forward_copy_shift pull=16 push=16
174
17518: forward_copy_shift pull=24 push=8
176
diff --git a/utils/hwstub/stmp/memmove.S b/utils/hwstub/stmp/memmove.S
new file mode 100644
index 0000000000..d8cab048be
--- /dev/null
+++ b/utils/hwstub/stmp/memmove.S
@@ -0,0 +1,190 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 Free Software Foundation, Inc.
11 * This file was originally part of the GNU C Library
12 * Contributed to glibc by MontaVista Software, Inc. (written by Nicolas Pitre)
13 * Adapted for Rockbox by Daniel Ankers
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
22 *
23 ****************************************************************************/
24
25#include "config.h"
26
27/*
28 * Endian independent macros for shifting bytes within registers.
29 */
30#ifndef __ARMEB__
31#define pull lsr
32#define push lsl
33#else
34#define pull lsl
35#define push lsr
36#endif
37
38 .text
39
40/*
41 * Prototype: void *memmove(void *dest, const void *src, size_t n);
42 *
43 * Note:
44 *
45 * If the memory regions don't overlap, we simply branch to memcpy which is
46 * normally a bit faster. Otherwise the copy is done going downwards.
47 */
48
49 .section .icode,"ax",%progbits
50
51 .align 2
52 .global memmove
53 .type memmove,%function
54
55memmove:
56
57 subs ip, r0, r1
58 cmphi r2, ip
59 bls memcpy
60
61 stmfd sp!, {r0, r4, lr}
62 add r1, r1, r2
63 add r0, r0, r2
64 subs r2, r2, #4
65 blt 8f
66 ands ip, r0, #3
67 bne 9f
68 ands ip, r1, #3
69 bne 10f
70
711: subs r2, r2, #(28)
72 stmfd sp!, {r5 - r8}
73 blt 5f
74
752:
763:
774: ldmdb r1!, {r3, r4, r5, r6, r7, r8, ip, lr}
78 subs r2, r2, #32
79 stmdb r0!, {r3, r4, r5, r6, r7, r8, ip, lr}
80 bge 3b
81
825: ands ip, r2, #28
83 rsb ip, ip, #32
84 addne pc, pc, ip @ C is always clear here
85 b 7f
866: nop
87 ldr r3, [r1, #-4]!
88 ldr r4, [r1, #-4]!
89 ldr r5, [r1, #-4]!
90 ldr r6, [r1, #-4]!
91 ldr r7, [r1, #-4]!
92 ldr r8, [r1, #-4]!
93 ldr lr, [r1, #-4]!
94
95 add pc, pc, ip
96 nop
97 nop
98 str r3, [r0, #-4]!
99 str r4, [r0, #-4]!
100 str r5, [r0, #-4]!
101 str r6, [r0, #-4]!
102 str r7, [r0, #-4]!
103 str r8, [r0, #-4]!
104 str lr, [r0, #-4]!
105
1067: ldmfd sp!, {r5 - r8}
107
1088: movs r2, r2, lsl #31
109 ldrneb r3, [r1, #-1]!
110 ldrcsb r4, [r1, #-1]!
111 ldrcsb ip, [r1, #-1]
112 strneb r3, [r0, #-1]!
113 strcsb r4, [r0, #-1]!
114 strcsb ip, [r0, #-1]
115 ldmpc regs="r0, r4"
116
1179: cmp ip, #2
118 ldrgtb r3, [r1, #-1]!
119 ldrgeb r4, [r1, #-1]!
120 ldrb lr, [r1, #-1]!
121 strgtb r3, [r0, #-1]!
122 strgeb r4, [r0, #-1]!
123 subs r2, r2, ip
124 strb lr, [r0, #-1]!
125 blt 8b
126 ands ip, r1, #3
127 beq 1b
128
12910: bic r1, r1, #3
130 cmp ip, #2
131 ldr r3, [r1, #0]
132 beq 17f
133 blt 18f
134
135
136 .macro backward_copy_shift push pull
137
138 subs r2, r2, #28
139 blt 14f
140
14111: stmfd sp!, {r5 - r9}
142
14312:
14413: ldmdb r1!, {r7, r8, r9, ip}
145 mov lr, r3, push #\push
146 subs r2, r2, #32
147 ldmdb r1!, {r3, r4, r5, r6}
148 orr lr, lr, ip, pull #\pull
149 mov ip, ip, push #\push
150 orr ip, ip, r9, pull #\pull
151 mov r9, r9, push #\push
152 orr r9, r9, r8, pull #\pull
153 mov r8, r8, push #\push
154 orr r8, r8, r7, pull #\pull
155 mov r7, r7, push #\push
156 orr r7, r7, r6, pull #\pull
157 mov r6, r6, push #\push
158 orr r6, r6, r5, pull #\pull
159 mov r5, r5, push #\push
160 orr r5, r5, r4, pull #\pull
161 mov r4, r4, push #\push
162 orr r4, r4, r3, pull #\pull
163 stmdb r0!, {r4 - r9, ip, lr}
164 bge 12b
165
166 ldmfd sp!, {r5 - r9}
167
16814: ands ip, r2, #28
169 beq 16f
170
17115: mov lr, r3, push #\push
172 ldr r3, [r1, #-4]!
173 subs ip, ip, #4
174 orr lr, lr, r3, pull #\pull
175 str lr, [r0, #-4]!
176 bgt 15b
177
17816: add r1, r1, #(\pull / 8)
179 b 8b
180
181 .endm
182
183
184 backward_copy_shift push=8 pull=24
185
18617: backward_copy_shift push=16 pull=16
187
18818: backward_copy_shift push=24 pull=8
189
190
diff --git a/utils/hwstub/stmp/memset.S b/utils/hwstub/stmp/memset.S
new file mode 100644
index 0000000000..682da874ce
--- /dev/null
+++ b/utils/hwstub/stmp/memset.S
@@ -0,0 +1,98 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 by Thom Johansen
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#include "config.h"
22
23 .section .icode,"ax",%progbits
24
25 .align 2
26
27/* The following code is based on code found in Linux kernel version 2.6.15.3
28 * linux/arch/arm/lib/memset.S
29 *
30 * Copyright (C) 1995-2000 Russell King
31 */
32
33/* This code will align a pointer for memset, if needed */
341: cmp r2, #4 @ 1 do we have enough
35 blt 5f @ 1 bytes to align with?
36 cmp r3, #2 @ 1
37 strgtb r1, [r0, #-1]! @ 1
38 strgeb r1, [r0, #-1]! @ 1
39 strb r1, [r0, #-1]! @ 1
40 sub r2, r2, r3 @ 1 r2 = r2 - r3
41 b 2f
42
43 .global memset
44 .type memset,%function
45memset:
46 add r0, r0, r2 @ we'll write backwards in memory
47 ands r3, r0, #3 @ 1 unaligned?
48 bne 1b @ 1
492:
50/*
51 * we know that the pointer in r0 is aligned to a word boundary.
52 */
53 orr r1, r1, r1, lsl #8
54 orr r1, r1, r1, lsl #16
55 mov r3, r1
56 cmp r2, #16
57 blt 5f
58/*
59 * We need an extra register for this loop - save the return address and
60 * use the LR
61 */
62 str lr, [sp, #-4]!
63 mov ip, r1
64 mov lr, r1
65
663: subs r2, r2, #64
67 stmgedb r0!, {r1, r3, ip, lr} @ 64 bytes at a time.
68 stmgedb r0!, {r1, r3, ip, lr}
69 stmgedb r0!, {r1, r3, ip, lr}
70 stmgedb r0!, {r1, r3, ip, lr}
71 bgt 3b
72 ldrpc cond=eq @ Now <64 bytes to go.
73/*
74 * No need to correct the count; we're only testing bits from now on
75 */
76 tst r2, #32
77 stmnedb r0!, {r1, r3, ip, lr}
78 stmnedb r0!, {r1, r3, ip, lr}
79 tst r2, #16
80 stmnedb r0!, {r1, r3, ip, lr}
81 ldr lr, [sp], #4
82
835: tst r2, #8
84 stmnedb r0!, {r1, r3}
85 tst r2, #4
86 strne r1, [r0, #-4]!
87/*
88 * When we get here, we've got less than 4 bytes to zero. We
89 * may have an unaligned pointer as well.
90 */
916: tst r2, #2
92 strneb r1, [r0, #-1]!
93 strneb r1, [r0, #-1]!
94 tst r2, #1
95 strneb r1, [r0, #-1]!
96 bx lr
97.end:
98 .size memset,.end-memset
diff --git a/utils/hwstub/stmp/protocol.h b/utils/hwstub/stmp/protocol.h
index d3ffb6ce00..35510fa9b2 100644
--- a/utils/hwstub/stmp/protocol.h
+++ b/utils/hwstub/stmp/protocol.h
@@ -1 +1 @@
#include "../hwemul_protocol.h" #include "../hwstub_protocol.h"
diff --git a/utils/hwstub/stmp/stddef.h b/utils/hwstub/stmp/stddef.h
index 9d59d2913c..9bfd767750 100644
--- a/utils/hwstub/stmp/stddef.h
+++ b/utils/hwstub/stmp/stddef.h
@@ -18,8 +18,8 @@
18 * KIND, either express or implied. 18 * KIND, either express or implied.
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21#ifndef __HWEMUL_STDDEF__ 21#ifndef __HWSTUB_STDDEF__
22#define __HWEMUL_STDDEF__ 22#define __HWSTUB_STDDEF__
23 23
24#include "stdint.h" 24#include "stdint.h"
25 25
@@ -29,4 +29,4 @@ typedef int32_t ssize_t;
29#define MIN(a, b) ((a) < (b) ? (a) : (b)) 29#define MIN(a, b) ((a) < (b) ? (a) : (b))
30#define MAX(a, b) ((a) > (b) ? (a) : (b)) 30#define MAX(a, b) ((a) > (b) ? (a) : (b))
31 31
32#endif /* __HWEMUL_STDDEF__ */ 32#endif /* __HWSTUB_STDDEF__ */
diff --git a/utils/hwstub/stmp/string.h b/utils/hwstub/stmp/string.h
index 7ef460ea6e..184144e525 100644
--- a/utils/hwstub/stmp/string.h
+++ b/utils/hwstub/stmp/string.h
@@ -18,8 +18,8 @@
18 * KIND, either express or implied. 18 * KIND, either express or implied.
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21#ifndef __HWEMUL_STRING__ 21#ifndef __HWSTUB_STRING__
22#define __HWEMUL_STRING__ 22#define __HWSTUB_STRING__
23 23
24#include "stddef.h" 24#include "stddef.h"
25 25
@@ -27,4 +27,4 @@ void memset(void *dst, int c, size_t n);
27void memcpy(void *dst, const void *src, size_t n); 27void memcpy(void *dst, const void *src, size_t n);
28size_t strlen(const char *s); 28size_t strlen(const char *s);
29 29
30#endif /* __HWEMUL_STRING__ */ 30#endif /* __HWSTUB_STRING__ */
diff --git a/utils/hwstub/stmp/system.h b/utils/hwstub/stmp/system.h
index c1babe7d87..e5aea12051 100644
--- a/utils/hwstub/stmp/system.h
+++ b/utils/hwstub/stmp/system.h
@@ -18,8 +18,8 @@
18 * KIND, either express or implied. 18 * KIND, either express or implied.
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21#ifndef __HWEMUL_SYSTEM__ 21#ifndef __HWSTUB_SYSTEM__
22#define __HWEMUL_SYSTEM__ 22#define __HWSTUB_SYSTEM__
23 23
24#define IRQ_ENABLED 0x00 24#define IRQ_ENABLED 0x00
25#define IRQ_DISABLED 0x80 25#define IRQ_DISABLED 0x80
@@ -114,5 +114,5 @@ static inline int disable_interrupt_save(int mask)
114 return cpsr; 114 return cpsr;
115} 115}
116 116
117#endif /* __HWEMUL_SYSTEM__ */ 117#endif /* __HWSTUB_SYSTEM__ */
118 118
diff --git a/utils/hwstub/tools/Makefile b/utils/hwstub/tools/Makefile
index 3466a4e776..6db0c709b1 100644
--- a/utils/hwstub/tools/Makefile
+++ b/utils/hwstub/tools/Makefile
@@ -1,22 +1,38 @@
1CC=gcc 1CC=gcc
2AR=ar 2CXX=g++
3HWEMUL_LIB_DIR=../lib 3LD=g++
4CFLAGS=-W -Wall -O2 `pkg-config --cflags libusb-1.0` -std=c99 -g -I$(HWEMUL_LIB_DIR) 4HWSTUB_LIB_DIR=../lib
5LDFLAGS=`pkg-config --libs libusb-1.0` -lreadline 5REGTOOLS_LIB_DIR=../../regtools/lib
6EXEC=hwemul_tool 6CFLAGS=-Wall -O2 `pkg-config --cflags libusb-1.0` -std=c99 -g -I$(HWSTUB_LIB_DIR) -I$(REGTOOLS_LIB_DIR) `pkg-config --cflags lua5.2`
7HWEMUL_LIB=$(HWEMUL_LIB_DIR)/libhwemul.a 7CXXFLAGS=-Wall -O2 `pkg-config --cflags libusb-1.0` -g -I$(HWSTUB_LIB_DIR) -I$(REGTOOLS_LIB_DIR) `pkg-config --cflags lua5.2`
8LDFLAGS=`pkg-config --libs libusb-1.0` `pkg-config --libs lua5.2` -lreadline -L$(HWSTUB_LIB_DIR) -L$(REGTOOLS_LIB_DIR) -lsocdesc -lhwstub `xml2-config --libs`
9EXEC=hwstub_shell hwstub_load
8SRC=$(wildcard *.c) 10SRC=$(wildcard *.c)
9OBJ=$(SRC:.c=.o) 11SRCXX=$(wildcard *.cpp)
12OBJ=$(SRC:.c=.o) $(SRCXX:.cpp=.o)
13LIBS=$(HWSTUB_LIB_DIR)/libhwstub.a $(REGTOOLS_LIB_DIR)/libsocdesc.a
10 14
11all: $(EXEC) 15all: $(EXEC)
12 16
17$(HWSTUB_LIB_DIR)/libhwstub.a:
18 make -C $(HWSTUB_LIB_DIR)
19
20$(REGTOOLS_LIB_DIR)/libsocdesc.a:
21 make -C $(REGTOOLS_LIB_DIR)
22
13%.o: %.c 23%.o: %.c
14 $(CC) $(CFLAGS) -c -o $@ $< 24 $(CC) $(CFLAGS) -c -o $@ $<
15 25
16hwemul_tool: hwemul_tool.o $(HWEMUL_LIB) 26%.o: %.cpp
17 $(CC) -o $@ $^ $(LDFLAGS) 27 $(CXX) $(CXXFLAGS) -c -o $@ $<
28
29hwstub_shell: hwstub_shell.o $(LIBS)
30 $(LD) -o $@ $^ $(LDFLAGS)
31
32hwstub_load: hwstub_load.o $(LIBS)
33 $(LD) -o $@ $^ $(LDFLAGS)
18 34
19clean: 35clean:
20 rm -rf $(OBJ) $(LIB) 36 rm -rf $(OBJ) $(LIB) $(EXEC)
21 37
22 38
diff --git a/utils/hwstub/tools/hwemul_tool.c b/utils/hwstub/tools/hwemul_tool.c
deleted file mode 100644
index d75cd7a957..0000000000
--- a/utils/hwstub/tools/hwemul_tool.c
+++ /dev/null
@@ -1,558 +0,0 @@
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#include "hwemul.h"
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <getopt.h>
26#include <stdbool.h>
27#include <readline/readline.h>
28#include <readline/history.h>
29
30bool g_quiet = false;
31struct hwemul_device_t hwdev;
32struct hwemul_soc_t *cur_soc = NULL;
33
34void print_log(struct hwemul_device_t *hwdev)
35{
36 do
37 {
38 char buffer[128];
39 int length = hwemul_get_log(hwdev, buffer, sizeof(buffer) - 1);
40 if(length <= 0)
41 break;
42 buffer[length] = 0;
43 printf("%s", buffer);
44 }while(1);
45}
46
47int print_help()
48{
49 printf("Commands:\n");
50 printf(" help\t\tDisplay this help\n");
51 printf(" call <addr>\tCall address <addr>\n");
52 printf(" quit\t\tQuit this session\n");
53 printf(" read32 <addr>\tRead a 32-bit word at <addr>\n");
54 printf(" write32 <value> <addr>\tRead the 32-bit word <value> at <addr>\n");
55 printf(" read <regname>\tRead a register by name\n");
56 printf(" read <regname>.<field>\tRead a register field by name\n");
57 printf(" soc <socname>\tSelect the soc description to use\n");
58 printf(" write <value> <regname>\tWrite a register by name\n");
59 printf(" write <value <regname>.<field>\tWrite a register field by name\n");
60 printf(" NOTE: if the register is SCT variant, no read is performed.\n");
61 return 1;
62}
63
64int syntax_error(char *str)
65{
66 printf("Syntax error at '%s'. Type 'help' to get some help.\n", str);
67 return 1;
68}
69
70int parse_uint32(char *str, uint32_t *u)
71{
72 char *end;
73 *u = strtoul(str, &end, 0);
74 return *end == 0;
75}
76
77int do_call(uint32_t a)
78{
79 hwemul_call(&hwdev, a);
80 return 1;
81}
82
83int parse_call()
84{
85 char *arg = strtok(NULL, " ");
86 uint32_t addr;
87 if(arg && parse_uint32(arg, &addr))
88 return do_call(addr);
89 else
90 return syntax_error(arg);
91}
92
93int do_read32(uint32_t a)
94{
95 uint32_t val;
96 if(hwemul_rw_mem(&hwdev, 1, a, &val, sizeof(val)) == sizeof(val))
97 printf("%#x = %#x\n", a, val);
98 else
99 printf("read error at %#x\n", a);
100 return 1;
101}
102
103int parse_read32()
104{
105 char *arg = strtok(NULL, " ");
106 uint32_t addr;
107 if(arg && parse_uint32(arg, &addr))
108 return do_read32(addr);
109 else
110 return syntax_error(arg);
111}
112
113int do_write32(uint32_t val, uint32_t a)
114{
115 if(hwemul_rw_mem(&hwdev, 0, a, &val, sizeof(val)) == sizeof(val))
116 printf("data written\n");
117 else
118 printf("write error at %#x\n", a);
119 return 1;
120}
121
122int parse_write32()
123{
124 char *arg = strtok(NULL, " ");
125 uint32_t val;
126 if(!arg || !parse_uint32(arg, &val))
127 return syntax_error(arg);
128 uint32_t addr;
129 arg = strtok(NULL, " ");
130 if(arg && parse_uint32(arg, &addr))
131 return do_write32(val, addr);
132 else
133 return syntax_error(arg);
134}
135
136struct hwemul_soc_t *find_soc_by_name(const char *soc)
137{
138 struct hwemul_soc_list_t *list = hwemul_get_soc_list();
139 for(size_t i = 0; i < list->nr_socs; i++)
140 if(strcmp(soc, list->socs[i]->name) == 0)
141 return list->socs[i];
142 return NULL;
143}
144
145struct hwemul_soc_reg_t *find_reg_by_name(struct hwemul_soc_t *soc, const char *reg)
146{
147 for(size_t i = 0; i < soc->nr_regs; i++)
148 if(strcmp(reg, soc->regs_by_name[i]->name) == 0)
149 return soc->regs_by_name[i];
150 return NULL;
151}
152
153struct hwemul_soc_reg_field_t *find_field_by_name(struct hwemul_soc_reg_t *reg, const char *field)
154{
155 for(size_t i = 0; i < reg->nr_fields; i++)
156 if(strcmp(field, reg->fields_by_name[i]->name) == 0)
157 return reg->fields_by_name[i];
158 return NULL;
159}
160
161
162int do_read(char *regname)
163{
164 char *dot = strchr(regname, '.');
165 if(dot != NULL)
166 *dot++ = 0;
167 if(cur_soc == NULL)
168 {
169 printf("No soc selected!\n");
170 return 1;
171 }
172 struct hwemul_soc_reg_t *reg = find_reg_by_name(cur_soc, regname);
173 if(reg == NULL)
174 {
175 printf("no reg '%s' found\n", regname);
176 return 1;
177 }
178 uint32_t val;
179 if(hwemul_rw_mem(&hwdev, 1, reg->addr, &val, sizeof(val)) != sizeof(val))
180 {
181 printf("read error at %#x\n", reg->addr);
182 return 1;
183 }
184 if(dot)
185 {
186 struct hwemul_soc_reg_field_t *field = find_field_by_name(reg, dot);
187 if(field == NULL)
188 {
189 printf("no field '%s' found\n", dot);
190 return 1;
191 }
192 val >>= field->first_bit;
193 val &= (1 << (field->last_bit - field->first_bit + 1)) - 1;
194 printf("%s.%s = %#x\n", regname, dot, val);
195 }
196 else
197 printf("%s = %#x\n", regname, val);
198 return 1;
199}
200
201int parse_read()
202{
203 char *arg = strtok(NULL, " ");
204 if(arg)
205 return do_read(arg);
206 else
207 return syntax_error(arg);
208}
209
210int do_soc(char *soc)
211{
212 struct hwemul_soc_t *s = find_soc_by_name(soc);
213 if(s == NULL)
214 printf("no soc '%s' found\n", soc);
215 else
216 cur_soc = s;
217 return 1;
218}
219
220int parse_soc()
221{
222 char *arg = strtok(NULL, " ");
223 if(arg)
224 return do_soc(arg);
225 else
226 return syntax_error(arg);
227}
228
229int do_write(uint32_t val, char *regname)
230{
231 char *dot = strchr(regname, '.');
232 if(dot != NULL)
233 *dot++ = 0;
234 if(cur_soc == NULL)
235 {
236 printf("No soc selected!\n");
237 return 1;
238 }
239 struct hwemul_soc_reg_t *reg = find_reg_by_name(cur_soc, regname);
240 int is_sct = 0;
241 uint32_t addr_off = 0;
242 if(reg == NULL)
243 {
244 size_t len = strlen(regname);
245 /* try SCT variant */
246 if(strcmp(regname + len - 4, "_SET") == 0)
247 addr_off = 4;
248 else if(strcmp(regname + len - 4, "_CLR") == 0)
249 addr_off = 8;
250 else if(strcmp(regname + len - 4, "_TOG") == 0)
251 addr_off = 12;
252 else
253 {
254 printf("no reg '%s' found\n", regname);
255 return 1;
256 }
257 is_sct = 1;
258 regname[len - 4] = 0;
259 reg = find_reg_by_name(cur_soc, regname);
260 if(reg == NULL)
261 {
262 printf("no reg '%s' found\n", regname);
263 return 1;
264 }
265 }
266 if(dot)
267 {
268 struct hwemul_soc_reg_field_t *field = find_field_by_name(reg, dot);
269 if(field == NULL)
270 {
271 printf("no field '%s' found\n", dot);
272 return 1;
273 }
274 uint32_t actual_val = 0;
275 if(!is_sct)
276 {
277 if(hwemul_rw_mem(&hwdev, 1, reg->addr, &actual_val, sizeof(actual_val)) != sizeof(actual_val))
278 {
279 printf("read error at %#x\n", reg->addr);
280 return 1;
281 }
282 printf("read %#x at %#x\n", actual_val, reg->addr);
283 }
284 uint32_t mask = ((1 << (field->last_bit - field->first_bit + 1)) - 1) << field->first_bit;
285 printf("mask=%#x\n", mask);
286 val = (actual_val & ~mask) | ((val << field->first_bit) & mask);
287 }
288 printf("write %#x to %#x\n", val, reg->addr + addr_off);
289 if(hwemul_rw_mem(&hwdev, 0, reg->addr + addr_off, &val, sizeof(val)) != sizeof(val))
290 {
291 printf("write error at %#x\n", reg->addr);
292 return 1;
293 }
294 return 1;
295}
296
297int parse_write()
298{
299 char *arg = strtok(NULL, " ");
300 uint32_t val;
301 if(!arg || !parse_uint32(arg, &val))
302 return syntax_error(arg);
303 arg = strtok(NULL, " ");
304 if(arg)
305 return do_write(val, arg);
306 else
307 return syntax_error(arg);
308}
309
310int parse_command(char *cmd)
311{
312 if(strcmp(cmd, "help") == 0)
313 return print_help();
314 if(strcmp(cmd, "quit") == 0)
315 return 0;
316 if(strcmp(cmd, "call") == 0)
317 return parse_call();
318 if(strcmp(cmd, "read32") == 0)
319 return parse_read32();
320 if(strcmp(cmd, "write32") == 0)
321 return parse_write32();
322 if(strcmp(cmd, "read") == 0)
323 return parse_read();
324 if(strcmp(cmd, "soc") == 0)
325 return parse_soc();
326 if(strcmp(cmd, "write") == 0)
327 return parse_write();
328 return syntax_error(cmd);
329}
330
331void interactive_mode(void)
332{
333 rl_bind_key('\t', rl_complete);
334 while(1)
335 {
336 char *input = readline("> ");
337 if(!input)
338 break;
339 add_history(input);
340 int ret = parse_command(input);
341 free(input);
342 if(ret == 0)
343 break;
344 }
345}
346
347void usage(void)
348{
349 printf("hwemul_tool, compiled with hwemul %d.%d.%d\n",
350 HWEMUL_VERSION_MAJOR, HWEMUL_VERSION_MINOR, HWEMUL_VERSION_REV);
351 printf("available soc descriptions:");
352 for(unsigned i = 0; i < hwemul_get_soc_list()->nr_socs; i++)
353 printf(" %s", hwemul_get_soc_list()->socs[i]->name);
354 printf("\n");
355 printf("usage: hwemul_tool [options]\n");
356 printf("options:\n");
357 printf(" --help/-?\tDisplay this help\n");
358 printf(" --quiet/-q\tQuiet non-command messages\n");
359 exit(1);
360}
361
362int main(int argc, char **argv)
363{
364 while(1)
365 {
366 static struct option long_options[] =
367 {
368 {"help", no_argument, 0, '?'},
369 {"quiet", no_argument, 0, 'q'},
370 {0, 0, 0, 0}
371 };
372
373 int c = getopt_long(argc, argv, "?q", long_options, NULL);
374 if(c == -1)
375 break;
376 switch(c)
377 {
378 case -1:
379 break;
380 case 'q':
381 g_quiet = true;
382 break;
383 case '?':
384 usage();
385 break;
386 default:
387 abort();
388 }
389 }
390
391 if(argc - optind != 0)
392 {
393 usage();
394 return 1;
395 }
396
397 libusb_context *ctx;
398 libusb_init(&ctx);
399 libusb_set_debug(ctx, 3);
400
401 if(!g_quiet)
402 printf("Looking for device %#04x:%#04x...\n", HWEMUL_USB_VID, HWEMUL_USB_PID);
403
404 libusb_device_handle *handle = libusb_open_device_with_vid_pid(ctx,
405 HWEMUL_USB_VID, HWEMUL_USB_PID);
406 if(handle == NULL)
407 {
408 printf("No device found\n");
409 return 1;
410 }
411
412 libusb_device *mydev = libusb_get_device(handle);
413 if(!g_quiet)
414 {
415 printf("device found at %d:%d\n",
416 libusb_get_bus_number(mydev),
417 libusb_get_device_address(mydev));
418 }
419 hwdev.handle = handle;
420 if(hwemul_probe(&hwdev))
421 {
422 printf("Cannot probe device!\n");
423 return 1;
424 }
425
426 struct usb_resp_info_version_t ver;
427 int ret = hwemul_get_info(&hwdev, HWEMUL_INFO_VERSION, &ver, sizeof(ver));
428 if(ret != sizeof(ver))
429 {
430 printf("Cannot get version!\n");
431 goto Lerr;
432 }
433 if(!g_quiet)
434 printf("Device version: %d.%d.%d\n", ver.major, ver.minor, ver.revision);
435
436 struct usb_resp_info_layout_t layout;
437 ret = hwemul_get_info(&hwdev, HWEMUL_INFO_LAYOUT, &layout, sizeof(layout));
438 if(ret != sizeof(layout))
439 {
440 printf("Cannot get layout: %d\n", ret);
441 goto Lerr;
442 }
443 if(!g_quiet)
444 {
445 printf("Device layout:\n");
446 printf(" Code: 0x%x (0x%x)\n", layout.oc_code_start, layout.oc_code_size);
447 printf(" Stack: 0x%x (0x%x)\n", layout.oc_stack_start, layout.oc_stack_size);
448 printf(" Buffer: 0x%x (0x%x)\n", layout.oc_buffer_start, layout.oc_buffer_size);
449 }
450
451 struct usb_resp_info_features_t features;
452 ret = hwemul_get_info(&hwdev, HWEMUL_INFO_FEATURES, &features, sizeof(features));
453 if(ret != sizeof(features))
454 {
455 printf("Cannot get features: %d\n", ret);
456 goto Lerr;
457 }
458 if(!g_quiet)
459 {
460 printf("Device features:");
461 if(features.feature_mask & HWEMUL_FEATURE_LOG)
462 printf(" log");
463 if(features.feature_mask & HWEMUL_FEATURE_MEM)
464 printf(" mem");
465 if(features.feature_mask & HWEMUL_FEATURE_CALL)
466 printf(" call");
467 if(features.feature_mask & HWEMUL_FEATURE_JUMP)
468 printf(" jump");
469 if(features.feature_mask & HWEMUL_FEATURE_AES_OTP)
470 printf(" aes_otp");
471 printf("\n");
472 }
473
474 struct usb_resp_info_stmp_t stmp;
475 ret = hwemul_get_info(&hwdev, HWEMUL_INFO_STMP, &stmp, sizeof(stmp));
476 if(ret != sizeof(stmp))
477 {
478 printf("Cannot get stmp: %d\n", ret);
479 goto Lerr;
480 }
481 if(!g_quiet)
482 {
483 printf("Device stmp:\n");
484 printf(" chip ID: %x (%s)\n", stmp.chipid,hwemul_get_product_string(&stmp));
485 printf(" revision: %d (%s)\n", stmp.rev, hwemul_get_rev_string(&stmp));
486 printf(" supported: %d\n", stmp.is_supported);
487 }
488
489 if(!g_quiet)
490 {
491 void *rom = malloc(64 * 1024);
492 ret = hwemul_rw_mem(&hwdev, 1, 0xc0000000, rom, 64 * 1024);
493 if(ret != 64 * 1024)
494 {
495 printf("Cannot read ROM: %d\n", ret);
496 goto Lerr;
497 }
498
499 printf("ROM successfully read!\n");
500 FILE *f = fopen("rom.bin", "wb");
501 fwrite(rom, 64 * 1024, 1, f);
502 fclose(f);
503 }
504
505 if(!g_quiet)
506 {
507 struct
508 {
509 uint8_t iv[16];
510 uint8_t data[16];
511 } __attribute__((packed)) dcp_test;
512
513 for(int i = 0; i < 16; i++)
514 dcp_test.iv[i] = rand();
515 for(int i = 0; i < 16; i++)
516 dcp_test.data[i] = rand();
517 printf("DCP\n");
518 printf(" IN\n");
519 printf(" IV:");
520 for(int i = 0; i < 16; i++)
521 printf(" %02x", dcp_test.iv[i]);
522 printf("\n");
523 printf(" IV:");
524 for(int i = 0; i < 16; i++)
525 printf(" %02x", dcp_test.data[i]);
526 printf("\n");
527
528 if(!hwemul_aes_otp(&hwdev, &dcp_test, sizeof(dcp_test), HWEMUL_AES_OTP_ENCRYPT))
529 {
530 printf(" OUT\n");
531 printf(" IV:");
532 for(int i = 0; i < 16; i++)
533 printf(" %02x", dcp_test.iv[i]);
534 printf("\n");
535 printf(" IV:");
536 for(int i = 0; i < 16; i++)
537 printf(" %02x", dcp_test.data[i]);
538 printf("\n");
539 }
540 else
541 printf("DCP error!\n");
542 }
543
544 if(!g_quiet)
545 printf("Starting interactive session. Type 'help' to get help.\n");
546
547 interactive_mode();
548
549 Lerr:
550 if(features.feature_mask & HWEMUL_FEATURE_LOG)
551 {
552 if(!g_quiet)
553 printf("Device log:\n");
554 print_log(&hwdev);
555 }
556 hwemul_release(&hwdev);
557 return 1;
558}
diff --git a/utils/hwstub/tools/hwstub_load.cpp b/utils/hwstub/tools/hwstub_load.cpp
new file mode 100644
index 0000000000..d58eb83396
--- /dev/null
+++ b/utils/hwstub/tools/hwstub_load.cpp
@@ -0,0 +1,316 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2013 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#include "hwstub.h"
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <getopt.h>
26#include <stdbool.h>
27#include <ctype.h>
28
29struct player_info_t
30{
31 const char *name;
32 const char *username;
33 int modelnum;
34};
35
36enum image_type_t
37{
38 IT_RAW,
39 IT_ROCKBOX,
40 IT_DETECT,
41 /* positive values reserved for rockbox-specific models */
42};
43
44struct player_info_t players[] =
45{
46 { "zenv", "Zen V", 85 },
47 { "zmoz", "Zen Mozaic", 87 },
48 { "zen", "Zen", 88 },
49 { "zxfi", "Zen X-Fi", 86 },
50 { NULL, 0 },
51};
52
53enum image_type_t detect_type(unsigned char *buffer, size_t size)
54{
55 if(size < 8)
56 return IT_RAW;
57 int player;
58 for(player = 0; players[player].name; player++)
59 if(memcmp(buffer + 4, players[player].name, 4) == 0)
60 break;
61 if(players[player].name == NULL)
62 return IT_RAW;
63 unsigned long checksum = players[player].modelnum;
64 for(size_t i = 8; i < size; i++)
65 checksum += buffer[i];
66 unsigned long expected = buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
67 if(checksum != expected)
68 return IT_RAW;
69 return IT_ROCKBOX;
70}
71
72const char *get_player_name(unsigned char *buffer)
73{
74 for(int player = 0; players[player].name; player++)
75 if(memcmp(buffer, players[player].name, 4) == 0)
76 return players[player].username;
77 return NULL;
78}
79
80bool could_be_rockbox(unsigned char *buffer, size_t size)
81{
82 /* usually target use 3 or 4 digits */
83 if(size >= 8 && isprint(buffer[4]) && isprint(buffer[5]) && isprint(buffer[6]) &&
84 (isprint(buffer[7]) || buffer[7] == 0))
85 {
86 unsigned long checksum = 0;
87 for(size_t i = 8; i < size; i++)
88 checksum += buffer[i];
89 unsigned long expected = buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
90 unsigned long expected_modelnm = expected - checksum;
91 if(expected_modelnm < 150)
92 fprintf(stderr, "This file looks like a valid rockbox image but I don't know this player: %.4s (modelnum=%ld)\n",
93 buffer + 4, expected_modelnm);
94 else
95 fprintf(stderr, "This file could be a valid rockbox image but I don't know this player and the checksum is strange: %.4s\n",
96 buffer + 4);
97 return true;
98 }
99 else
100 return false;
101}
102
103void usage(void)
104{
105 printf("usage: hwstub_load [options] <addr> <file>\n");
106 printf("options:\n");
107 printf(" --help/-? Display this help\n");
108 printf(" --quiet/-q Quiet output\n");
109 printf(" --type/-t <t> Override file type\n");
110 printf("file types:\n");
111 printf(" raw Load a raw binary blob\n");
112 printf(" rockbox Load a rockbox image produced by scramble\n");
113 printf(" detect Try to guess the format\n");
114 printf("known players:");
115 for(int i = 0; players[i].name; i++)
116 printf(" %s", players[i].name);
117 printf("\n");
118 exit(1);
119}
120
121int main(int argc, char **argv)
122{
123 bool quiet = false;
124 struct hwstub_device_t hwdev;
125 enum image_type_t type = IT_DETECT;
126
127 // parse command line
128 while(1)
129 {
130 static struct option long_options[] =
131 {
132 {"help", no_argument, 0, '?'},
133 {"quiet", no_argument, 0, 'q'},
134 {"type", required_argument, 0, 't'},
135 {0, 0, 0, 0}
136 };
137
138 int c = getopt_long(argc, argv, "?qt:", long_options, NULL);
139 if(c == -1)
140 break;
141 switch(c)
142 {
143 case -1:
144 break;
145 case 'q':
146 quiet = true;
147 break;
148 case '?':
149 usage();
150 break;
151 case 't':
152 if(strcmp(optarg, "raw") == 0)
153 type = IT_RAW;
154 else if(strcmp(optarg, "rockbox") == 0)
155 type = IT_ROCKBOX;
156 else if(strcmp(optarg, "detect") == 0)
157 type = IT_DETECT;
158 else
159 {
160 fprintf(stderr, "Unknown file type '%s'\n", optarg);
161 return 1;
162 }
163 break;
164 default:
165 abort();
166 }
167 }
168
169 if(optind + 2 != argc)
170 usage();
171
172 char *end;
173 unsigned long addr = strtoul(argv[optind], &end, 0);
174 if(*end)
175 {
176 fprintf(stderr, "Invalid load address\n");
177 return 2;
178 }
179
180 FILE *f = fopen(argv[optind + 1], "rb");
181 if(f == NULL)
182 {
183 fprintf(stderr, "Cannot open file for reading: %m\n");
184 return 3;
185 }
186 fseek(f, 0, SEEK_END);
187 size_t size = ftell(f);
188 fseek(f, 0, SEEK_SET);
189 unsigned char *buffer = (unsigned char*)malloc(size);
190 fread(buffer, size, 1, f);
191 fclose(f);
192
193 if(type == IT_ROCKBOX || type == IT_DETECT)
194 {
195 enum image_type_t det = detect_type(buffer, size);
196 if(type == IT_ROCKBOX && det != IT_ROCKBOX)
197 {
198 if(!could_be_rockbox(buffer, size))
199 fprintf(stderr, "This file does not appear to be valid rockbox image.\n");
200 return 4;
201 }
202 if(type == IT_DETECT && det == IT_RAW)
203 could_be_rockbox(buffer, size);
204 type = det;
205 if(type == IT_ROCKBOX)
206 {
207 if(!quiet)
208 printf("Rockox image is for player %s (%.4s)\n", get_player_name(buffer + 4), buffer + 4);
209 memmove(buffer, buffer + 8, size - 8);
210 size -= 8;
211 }
212 }
213
214 if(!quiet)
215 {
216 if(type == IT_RAW)
217 printf("Loading raw image at %#lx\n", addr);
218 else
219 printf("Loading rockbox image at %#lx\n", addr);
220 }
221
222 // create usb context
223 libusb_context *ctx;
224 libusb_init(&ctx);
225 libusb_set_debug(ctx, 3);
226
227 // look for device
228 if(!quiet)
229 printf("Looking for device %#04x:%#04x...\n", HWSTUB_USB_VID, HWSTUB_USB_PID);
230
231 libusb_device_handle *handle = libusb_open_device_with_vid_pid(ctx,
232 HWSTUB_USB_VID, HWSTUB_USB_PID);
233 if(handle == NULL)
234 {
235 fprintf(stderr, "No device found\n");
236 return 1;
237 }
238
239 // admin stuff
240 libusb_device *mydev = libusb_get_device(handle);
241 if(!quiet)
242 {
243 printf("device found at %d:%d\n",
244 libusb_get_bus_number(mydev),
245 libusb_get_device_address(mydev));
246 }
247 hwdev.handle = handle;
248 if(hwstub_probe(&hwdev))
249 {
250 fprintf(stderr, "Cannot probe device!\n");
251 return 1;
252 }
253
254 // get hwstub information
255 struct usb_resp_info_version_t hwdev_ver;
256 int ret = hwstub_get_info(&hwdev, HWSTUB_INFO_VERSION, &hwdev_ver, sizeof(hwdev_ver));
257 if(ret != sizeof(hwdev_ver))
258 {
259 fprintf(stderr, "Cannot get version!\n");
260 goto Lerr;
261 }
262 if(hwdev_ver.major != HWSTUB_VERSION_MAJOR || hwdev_ver.minor < HWSTUB_VERSION_MINOR)
263 {
264 printf("Warning: this tool is possibly incompatible with your device:\n");
265 printf("Device version: %d.%d.%d\n", hwdev_ver.major, hwdev_ver.minor, hwdev_ver.revision);
266 printf("Host version: %d.%d.%d\n", HWSTUB_VERSION_MAJOR, HWSTUB_VERSION_MINOR, HWSTUB_VERSION_REV);
267 }
268
269 // get features
270 struct usb_resp_info_features_t hwdev_features;
271 ret = hwstub_get_info(&hwdev, HWSTUB_INFO_FEATURES, &hwdev_features, sizeof(hwdev_features));
272 if(ret != sizeof(hwdev_features))
273 {
274 fprintf(stderr, "Cannot get features: %d\n", ret);
275 goto Lerr;
276 }
277 if(!(hwdev_features.feature_mask & HWSTUB_RW_MEM))
278 {
279 fprintf(stderr, "Device doesn't support R/W commands\n");
280 goto Lerr;
281 }
282 if(!(hwdev_features.feature_mask & HWSTUB_JUMP))
283 {
284 fprintf(stderr, "Device doesn't support jump commands\n");
285 goto Lerr;
286 }
287 ret = hwstub_rw_mem(&hwdev, 0, addr, buffer, size);
288 if(ret != (int)size)
289 {
290 fprintf(stderr, "Image write failed\n");
291 goto Lerr;
292 }
293 hwstub_jump(&hwdev, addr);
294
295 hwstub_release(&hwdev);
296 return 0;
297
298 Lerr:
299 // display log if handled
300 if(hwdev_features.feature_mask & HWSTUB_FEATURE_LOG)
301 {
302 fprintf(stderr, "Device log:\n");
303 do
304 {
305 char buffer[128];
306 int length = hwstub_get_log(&hwdev, buffer, sizeof(buffer) - 1);
307 if(length <= 0)
308 break;
309 buffer[length] = 0;
310 fprintf(stderr, "%s", buffer);
311 }while(1);
312 }
313 hwstub_release(&hwdev);
314 return 1;
315}
316
diff --git a/utils/hwstub/tools/hwstub_shell.cpp b/utils/hwstub/tools/hwstub_shell.cpp
new file mode 100644
index 0000000000..58147319e0
--- /dev/null
+++ b/utils/hwstub/tools/hwstub_shell.cpp
@@ -0,0 +1,873 @@
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#include "hwstub.h"
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <getopt.h>
26#include <stdbool.h>
27#include <readline/readline.h>
28#include <readline/history.h>
29#include <lua.hpp>
30#include "soc_desc.hpp"
31
32#if LUA_VERSION_NUM < 502
33#warning You need at least lua 5.2
34#endif
35
36/**
37 * Global variables
38 */
39bool g_quiet = false;
40struct hwstub_device_t g_hwdev;
41struct usb_resp_info_version_t g_hwdev_ver;
42struct usb_resp_info_layout_t g_hwdev_layout;
43struct usb_resp_info_features_t g_hwdev_features;
44struct usb_resp_info_stmp_t g_hwdev_stmp;
45lua_State *g_lua;
46
47/**
48 * hw specific
49 */
50
51void print_log(struct hwstub_device_t *hwdev)
52{
53 do
54 {
55 char buffer[128];
56 int length = hwstub_get_log(hwdev, buffer, sizeof(buffer) - 1);
57 if(length <= 0)
58 break;
59 buffer[length] = 0;
60 printf("%s", buffer);
61 }while(1);
62}
63
64/**
65 * Lua specific
66 */
67int my_lua_help(lua_State *state)
68{
69 bool has_sub = false;
70 // implement help() in C so that we do not rely on the init to implement it
71 // help can take optional arguments
72 int n = lua_gettop(state);
73
74 lua_getglobal(state, "hwstub");
75 if(!lua_istable(state, -1))
76 goto Lerr;
77 lua_getfield(state, -1, "help");
78 if(!lua_istable(state, -1))
79 goto Lerr;
80
81 for(int i = 1; i <= n; i++)
82 {
83 lua_pushvalue(state, i);
84 lua_gettable(state, -2);
85 if(lua_isnil(state, -1))
86 {
87 printf("I don't know subtopic '%s'!\n", lua_tostring(state, i));
88 return 0;
89 }
90 if(!lua_istable(state, -1))
91 {
92 printf("Subtopic '%s' is not a table!\n", lua_tostring(state, i));
93 return 0;
94 }
95 }
96
97 printf("================[ HELP ");
98 for(int i = 1; i <= n; i++)
99 printf("> %s ", lua_tostring(state, i));
100 printf("]================\n");
101
102 lua_pushnil(state);
103 while(lua_next(state, -2))
104 {
105 // key is at -2 and value at -1
106 if(lua_isstring(state, -1))
107 printf("%s\n", lua_tostring(state, -1));
108 else if(lua_istable(state, -1))
109 has_sub = true;
110 // pop value but keep key
111 lua_pop(state, 1);
112 }
113
114 if(has_sub)
115 {
116 printf("\n");
117 printf("You can get more information on the following subtopics:\n");
118 lua_pushnil(state);
119 while(lua_next(state, -2))
120 {
121 // key is at -2 and value at -1
122 if(lua_istable(state, -1))
123 printf("* %s\n", lua_tostring(state, -2));
124 // pop value but keep key
125 lua_pop(state, 1);
126 }
127 }
128 printf("================[ STOP ]================\n");
129
130 return 0;
131
132 Lerr:
133 printf("There is a problem with the Lua context. Help is expected to be in hwstub.help\n");
134 printf("You must have messed badly the environment.\n");
135 return 0;
136}
137
138typedef soc_word_t (*hw_readn_fn_t)(lua_State *state, soc_addr_t addr);
139typedef void (*hw_writen_fn_t)(lua_State *state, soc_addr_t addr, soc_word_t val);
140
141soc_word_t hw_read8(lua_State *state, soc_addr_t addr)
142{
143 uint8_t u;
144 if(hwstub_rw_mem(&g_hwdev, 1, addr, &u, sizeof(u)) != sizeof(u))
145 luaL_error(state, "fail to read8 @ %p", addr);
146 return u;
147}
148
149soc_word_t hw_read16(lua_State *state, soc_addr_t addr)
150{
151 uint16_t u;
152 if(hwstub_rw_mem(&g_hwdev, 1, addr, &u, sizeof(u)) != sizeof(u))
153 luaL_error(state, "fail to read16 @ %p", addr);
154 return u;
155}
156
157soc_word_t hw_read32(lua_State *state, soc_addr_t addr)
158{
159 uint32_t u;
160 if(hwstub_rw_mem(&g_hwdev, 1, addr, &u, sizeof(u)) != sizeof(u))
161 luaL_error(state, "fail to read32 @ %p", addr);
162 return u;
163}
164
165void hw_write8(lua_State *state, soc_addr_t addr, soc_word_t val)
166{
167 uint8_t u = val;
168 if(hwstub_rw_mem(&g_hwdev, 0, addr, &u, sizeof(u)) != sizeof(u))
169 luaL_error(state, "fail to write8 @ %p", addr);
170}
171
172void hw_write16(lua_State *state, soc_addr_t addr, soc_word_t val)
173{
174 uint16_t u = val;
175 if(hwstub_rw_mem(&g_hwdev, 0, addr, &u, sizeof(u)) != sizeof(u))
176 luaL_error(state, "fail to write16 @ %p", addr);
177}
178
179void hw_write32(lua_State *state, soc_addr_t addr, soc_word_t val)
180{
181 uint32_t u = val;
182 if(hwstub_rw_mem(&g_hwdev, 0, addr, &u, sizeof(u)) != sizeof(u))
183 luaL_error(state, "fail to write32 @ %p", addr);
184}
185
186int my_lua_readn(lua_State *state)
187{
188 hw_readn_fn_t fn = (hw_readn_fn_t)lua_touserdata(state, lua_upvalueindex(1));
189 int n = lua_gettop(state);
190 if(n != 1)
191 luaL_error(state, "readn takes a single argument");
192 lua_pushunsigned(state, fn(state, luaL_checkunsigned(state, 1)));
193 return 1;
194}
195
196int my_lua_writen(lua_State *state)
197{
198 hw_writen_fn_t fn = (hw_writen_fn_t)lua_touserdata(state, lua_upvalueindex(1));
199 int n = lua_gettop(state);
200 if(n != 2)
201 luaL_error(state, "writen takes two arguments");
202 fn(state, luaL_checkunsigned(state, 1), luaL_checkunsigned(state, 2));
203 return 0;
204}
205
206int my_lua_printlog(lua_State *state)
207{
208 print_log(&g_hwdev);
209 return 0;
210}
211
212bool my_lua_import_hwstub()
213{
214 int oldtop = lua_gettop(g_lua);
215
216 lua_newtable(g_lua); // hwstub
217
218 lua_newtable(g_lua); // options
219 lua_pushboolean(g_lua, g_quiet);
220 lua_setfield(g_lua, -2, "quiet");
221 lua_setfield(g_lua, -2, "options");
222
223 lua_newtable(g_lua); // dev
224 lua_newtable(g_lua); // version
225 lua_pushinteger(g_lua, g_hwdev_ver.major);
226 lua_setfield(g_lua, -2, "major");
227 lua_pushinteger(g_lua, g_hwdev_ver.minor);
228 lua_setfield(g_lua, -2, "minor");
229 lua_pushinteger(g_lua, g_hwdev_ver.revision);
230 lua_setfield(g_lua, -2, "revision");
231 lua_setfield(g_lua, -2, "version");
232
233 lua_newtable(g_lua); // layout
234 lua_newtable(g_lua); // ocram
235 lua_newtable(g_lua); // code
236 lua_pushinteger(g_lua, g_hwdev_layout.oc_code_start);
237 lua_setfield(g_lua, -2, "start");
238 lua_pushinteger(g_lua, g_hwdev_layout.oc_code_size);
239 lua_setfield(g_lua, -2, "size");
240 lua_setfield(g_lua, -2, "code");
241 lua_newtable(g_lua); // stack
242 lua_pushinteger(g_lua, g_hwdev_layout.oc_stack_start);
243 lua_setfield(g_lua, -2, "start");
244 lua_pushinteger(g_lua, g_hwdev_layout.oc_stack_size);
245 lua_setfield(g_lua, -2, "size");
246 lua_setfield(g_lua, -2, "stack");
247 lua_newtable(g_lua); // buffer
248 lua_pushinteger(g_lua, g_hwdev_layout.oc_buffer_start);
249 lua_setfield(g_lua, -2, "start");
250 lua_pushinteger(g_lua, g_hwdev_layout.oc_buffer_size);
251 lua_setfield(g_lua, -2, "size");
252 lua_setfield(g_lua, -2, "buffer");
253 lua_setfield(g_lua, -2, "ocram");
254 lua_setfield(g_lua, -2, "layout");
255
256 lua_newtable(g_lua); // stmp
257 lua_pushinteger(g_lua, g_hwdev_stmp.chipid);
258 lua_setfield(g_lua, -2, "chipid");
259 lua_pushinteger(g_lua, g_hwdev_stmp.rev);
260 lua_setfield(g_lua, -2, "rev");
261 lua_setfield(g_lua, -2, "stmp");
262
263 lua_newtable(g_lua); // features
264 lua_pushboolean(g_lua, !!(g_hwdev_features.feature_mask & HWSTUB_FEATURE_LOG));
265 lua_setfield(g_lua, -2, "log");
266 lua_pushboolean(g_lua, !!(g_hwdev_features.feature_mask & HWSTUB_FEATURE_MEM));
267 lua_setfield(g_lua, -2, "mem");
268 lua_pushboolean(g_lua, !!(g_hwdev_features.feature_mask & HWSTUB_FEATURE_CALL));
269 lua_setfield(g_lua, -2, "call");
270 lua_pushboolean(g_lua, !!(g_hwdev_features.feature_mask & HWSTUB_FEATURE_JUMP));
271 lua_setfield(g_lua, -2, "jump");
272 lua_pushboolean(g_lua, !!(g_hwdev_features.feature_mask & HWSTUB_FEATURE_AES_OTP));
273 lua_setfield(g_lua, -2, "aes_otp");
274 lua_setfield(g_lua, -2, "features");
275
276 lua_pushlightuserdata(g_lua, (void *)&hw_read8);
277 lua_pushcclosure(g_lua, my_lua_readn, 1);
278 lua_setfield(g_lua, -2, "read8");
279 lua_pushlightuserdata(g_lua, (void *)&hw_read16);
280 lua_pushcclosure(g_lua, my_lua_readn, 1);
281 lua_setfield(g_lua, -2, "read16");
282 lua_pushlightuserdata(g_lua, (void *)&hw_read32);
283 lua_pushcclosure(g_lua, my_lua_readn, 1);
284 lua_setfield(g_lua, -2, "read32");
285
286 lua_pushlightuserdata(g_lua, (void *)&hw_write8);
287 lua_pushcclosure(g_lua, my_lua_writen, 1);
288 lua_setfield(g_lua, -2, "write8");
289 lua_pushlightuserdata(g_lua, (void *)&hw_write16);
290 lua_pushcclosure(g_lua, my_lua_writen, 1);
291 lua_setfield(g_lua, -2, "write16");
292 lua_pushlightuserdata(g_lua, (void *)&hw_write32);
293 lua_pushcclosure(g_lua, my_lua_writen, 1);
294 lua_setfield(g_lua, -2, "write32");
295 lua_pushcclosure(g_lua, my_lua_printlog, 0);
296 lua_setfield(g_lua, -2, "print_log");
297
298 lua_setfield(g_lua, -2, "dev");
299
300 lua_newtable(g_lua); // host
301 lua_newtable(g_lua); // version
302 lua_pushinteger(g_lua, HWSTUB_VERSION_MAJOR);
303 lua_setfield(g_lua, -2, "major");
304 lua_pushinteger(g_lua, HWSTUB_VERSION_MINOR);
305 lua_setfield(g_lua, -2, "minor");
306 lua_pushinteger(g_lua, HWSTUB_VERSION_REV);
307 lua_setfield(g_lua, -2, "revision");
308 lua_setfield(g_lua, -2, "version");
309 lua_setfield(g_lua, -2, "host");
310
311 lua_newtable(g_lua); // soc
312 lua_setfield(g_lua, -2, "soc");
313
314 lua_newtable(g_lua); // help
315 lua_pushinteger(g_lua, 1);
316 lua_pushstring(g_lua, "This is the help for hwstub_tool. This tools uses Lua to interpret commands.");
317 lua_settable(g_lua, -3);
318 lua_pushinteger(g_lua, 2);
319 lua_pushstring(g_lua, "You can get help by running help(). Help is organised in topics and subtopics and so on.");
320 lua_settable(g_lua, -3);
321 lua_pushinteger(g_lua, 3);
322 lua_pushstring(g_lua, "If you want to access the help of topic x, subtopic y, subsubtopic z, type help(x,y,z).");
323 lua_settable(g_lua, -3);
324 lua_pushinteger(g_lua, 4);
325 lua_pushstring(g_lua, "Example: help(\"hwstub\").");
326 lua_settable(g_lua, -3);
327 lua_setfield(g_lua, -2, "help");
328
329 lua_setglobal(g_lua, "hwstub");
330
331 lua_pushcfunction(g_lua, my_lua_help);
332 lua_setglobal(g_lua, "help");
333
334 if(lua_gettop(g_lua) != oldtop)
335 {
336 printf("internal error: unbalanced my_lua_import_soc");
337 return false;
338 }
339 return true;
340}
341
342int my_lua_read_reg(lua_State *state)
343{
344 int n = lua_gettop(state);
345 if(n != 0)
346 luaL_error(state, "read() takes no argument");
347 soc_addr_t addr = lua_tounsigned(state, lua_upvalueindex(1));
348 lua_pushunsigned(state, hw_read32(state, addr));
349 return 1;
350}
351
352int my_lua_write_reg(lua_State *state)
353{
354 int n = lua_gettop(state);
355 if(n != 1)
356 luaL_error(state, "write() takes one argument");
357 soc_word_t val = luaL_checkunsigned(state, 1);
358 soc_addr_t addr = lua_tounsigned(state, lua_upvalueindex(1));
359 hw_write32(state, addr, val);
360 return 0;
361}
362
363int my_lua_read_field(lua_State *state)
364{
365 int n = lua_gettop(state);
366 if(n != 0)
367 luaL_error(state, "read() takes no argument");
368 soc_addr_t addr = lua_tounsigned(state, lua_upvalueindex(1));
369 soc_word_t shift = lua_tounsigned(state, lua_upvalueindex(2));
370 soc_word_t mask = lua_tounsigned(state, lua_upvalueindex(3));
371 lua_pushunsigned(state, (hw_read32(state, addr) >> shift) & mask);
372 return 1;
373}
374
375int my_lua_write_field(lua_State *state)
376{
377 int n = lua_gettop(state);
378 if(n != 0 && n!= 1)
379 luaL_error(state, "write() takes one or no argument");
380 soc_addr_t addr = lua_tounsigned(state, lua_upvalueindex(1));
381 soc_word_t shift = lua_tounsigned(state, lua_upvalueindex(2));
382 soc_word_t mask = lua_tounsigned(state, lua_upvalueindex(3));
383 bool is_sct = lua_toboolean(state, lua_upvalueindex(5));
384
385 soc_word_t value = mask;
386 if(n == 1)
387 {
388 if(!lua_isnumber(state, 1) && lua_isstring(state, 1))
389 {
390 lua_pushvalue(state, lua_upvalueindex(4));
391 lua_pushvalue(state, 1);
392 lua_gettable(state, -2);
393 if(lua_isnil(state, -1))
394 luaL_error(state, "field has no value %s", lua_tostring(state, 1));
395 value = luaL_checkunsigned(state, -1);
396 lua_pop(state, 2);
397 }
398 else
399 value = luaL_checkunsigned(state, 1);
400 value &= mask;
401 }
402
403 if(!is_sct)
404 value = value << shift | (hw_read32(state, addr) & ~(mask << shift));
405 else
406 value <<= shift;
407
408 hw_write32(state, addr, value);
409 return 0;
410}
411
412void my_lua_create_field(soc_addr_t addr, const soc_reg_field_t& field, bool sct)
413{
414 lua_newtable(g_lua);
415
416 lua_pushstring(g_lua, field.name.c_str());
417 lua_setfield(g_lua, -2, "name");
418
419 lua_pushunsigned(g_lua, addr);
420 lua_setfield(g_lua, -2, "addr");
421
422 lua_pushboolean(g_lua, sct);
423 lua_setfield(g_lua, -2, "sct");
424
425 lua_pushunsigned(g_lua, field.first_bit);
426 lua_setfield(g_lua, -2, "first_bit");
427
428 lua_pushunsigned(g_lua, field.last_bit);
429 lua_setfield(g_lua, -2, "last_bit");
430
431 lua_pushunsigned(g_lua, field.bitmask());
432 lua_setfield(g_lua, -2, "bitmask");
433
434 soc_word_t local_bitmask = field.bitmask() >> field.first_bit;
435 lua_pushunsigned(g_lua, local_bitmask);
436 lua_setfield(g_lua, -2, "local_bitmask");
437
438 lua_pushunsigned(g_lua, addr);
439 lua_pushunsigned(g_lua, field.first_bit);
440 lua_pushunsigned(g_lua, local_bitmask);
441 lua_pushcclosure(g_lua, my_lua_read_field, 3);
442 lua_setfield(g_lua, -2, "read");
443
444 lua_pushunsigned(g_lua, addr);
445 lua_pushunsigned(g_lua, field.first_bit);
446 lua_pushunsigned(g_lua, local_bitmask);
447 lua_pushvalue(g_lua, -4);
448 lua_pushboolean(g_lua, false);
449 lua_pushcclosure(g_lua, my_lua_write_field, 5);
450 lua_setfield(g_lua, -2, "write");
451
452 if(sct)
453 {
454 lua_pushunsigned(g_lua, addr + 4);
455 lua_pushunsigned(g_lua, field.first_bit);
456 lua_pushunsigned(g_lua, local_bitmask);
457 lua_pushvalue(g_lua, -4);
458 lua_pushboolean(g_lua, true);
459 lua_pushcclosure(g_lua, my_lua_write_field, 5);
460 lua_setfield(g_lua, -2, "set");
461
462 lua_pushunsigned(g_lua, addr + 8);
463 lua_pushunsigned(g_lua, field.first_bit);
464 lua_pushunsigned(g_lua, local_bitmask);
465 lua_pushvalue(g_lua, -4);
466 lua_pushboolean(g_lua, true);
467 lua_pushcclosure(g_lua, my_lua_write_field, 5);
468 lua_setfield(g_lua, -2, "clr");
469
470 lua_pushunsigned(g_lua, addr + 12);
471 lua_pushunsigned(g_lua, field.first_bit);
472 lua_pushunsigned(g_lua, local_bitmask);
473 lua_pushvalue(g_lua, -4);
474 lua_pushboolean(g_lua, true);
475 lua_pushcclosure(g_lua, my_lua_write_field, 5);
476 lua_setfield(g_lua, -2, "tog");
477 }
478
479 for(size_t i = 0; i < field.value.size(); i++)
480 {
481 lua_pushunsigned(g_lua, field.value[i].value);
482 lua_setfield(g_lua, -2, field.value[i].name.c_str());
483 }
484}
485
486void my_lua_create_reg(soc_addr_t addr, size_t index, const soc_reg_t& reg)
487{
488 lua_newtable(g_lua);
489
490 lua_pushstring(g_lua, reg.addr[index].name.c_str());
491 lua_setfield(g_lua, -2, "name");
492
493 lua_pushunsigned(g_lua, addr + reg.addr[index].addr);
494 lua_setfield(g_lua, -2, "addr");
495
496 lua_pushboolean(g_lua, !!(reg.flags & REG_HAS_SCT));
497 lua_setfield(g_lua, -2, "sct");
498
499 lua_pushunsigned(g_lua, addr + reg.addr[index].addr);
500 lua_pushcclosure(g_lua, my_lua_read_reg, 1);
501 lua_setfield(g_lua, -2, "read");
502
503 lua_pushunsigned(g_lua, addr + reg.addr[index].addr);
504 lua_pushcclosure(g_lua, my_lua_write_reg, 1);
505 lua_setfield(g_lua, -2, "write");
506
507 if(reg.flags & REG_HAS_SCT)
508 {
509 lua_pushunsigned(g_lua, addr + reg.addr[index].addr + 4);
510 lua_pushcclosure(g_lua, my_lua_write_reg, 1);
511 lua_setfield(g_lua, -2, "set");
512
513 lua_pushunsigned(g_lua, addr + reg.addr[index].addr + 8);
514 lua_pushcclosure(g_lua, my_lua_write_reg, 1);
515 lua_setfield(g_lua, -2, "clr");
516
517 lua_pushunsigned(g_lua, addr + reg.addr[index].addr + 12);
518 lua_pushcclosure(g_lua, my_lua_write_reg, 1);
519 lua_setfield(g_lua, -2, "tog");
520 }
521
522 for(size_t i = 0; i < reg.field.size(); i++)
523 {
524 my_lua_create_field(addr + reg.addr[index].addr, reg.field[i],
525 reg.flags & REG_HAS_SCT);
526 lua_setfield(g_lua, -2, reg.field[i].name.c_str());
527 }
528}
529
530void my_lua_create_dev(size_t index, const soc_dev_t& dev)
531{
532 lua_newtable(g_lua);
533
534 lua_pushstring(g_lua, dev.addr[index].name.c_str());
535 lua_setfield(g_lua, -2, "name");
536
537 lua_pushunsigned(g_lua, dev.addr[index].addr);
538 lua_setfield(g_lua, -2, "addr");
539
540 for(size_t i = 0; i < dev.reg.size(); i++)
541 {
542 bool table = dev.reg[i].addr.size() > 1;
543 if(table)
544 lua_newtable(g_lua);
545 else
546 lua_pushnil(g_lua);
547
548 for(size_t k = 0; k < dev.reg[i].addr.size(); k++)
549 {
550 my_lua_create_reg(dev.addr[index].addr, k, dev.reg[i]);
551 if(table)
552 {
553 lua_pushinteger(g_lua, k);
554 lua_pushvalue(g_lua, -2);
555 lua_settable(g_lua, -4);
556 }
557 lua_setfield(g_lua, -3, dev.reg[i].addr[k].name.c_str());
558 }
559
560 if(table)
561 lua_setfield(g_lua, -2, dev.reg[i].name.c_str());
562 else
563 lua_pop(g_lua, 1);
564 }
565}
566
567bool my_lua_import_soc(const soc_t& soc)
568{
569 int oldtop = lua_gettop(g_lua);
570
571 lua_getglobal(g_lua, "hwstub");
572 lua_getfield(g_lua, -1, "soc");
573
574 lua_newtable(g_lua);
575
576 lua_pushstring(g_lua, soc.name.c_str());
577 lua_setfield(g_lua, -2, "name");
578
579 lua_pushstring(g_lua, soc.desc.c_str());
580 lua_setfield(g_lua, -2, "desc");
581
582 for(size_t i = 0; i < soc.dev.size(); i++)
583 {
584 bool table = soc.dev[i].addr.size() > 1;
585 if(table)
586 lua_newtable(g_lua);
587 else
588 lua_pushnil(g_lua);
589
590 for(size_t k = 0; k < soc.dev[i].addr.size(); k++)
591 {
592 my_lua_create_dev(k, soc.dev[i]);
593 if(table)
594 {
595 lua_pushinteger(g_lua, k + 1);
596 lua_pushvalue(g_lua, -2);
597 lua_settable(g_lua, -4);
598 }
599 lua_setfield(g_lua, -3, soc.dev[i].addr[k].name.c_str());
600 }
601
602 if(table)
603 lua_setfield(g_lua, -2, soc.dev[i].name.c_str());
604 else
605 lua_pop(g_lua, 1);
606 }
607
608 lua_setfield(g_lua, -2, soc.name.c_str());
609
610 lua_pop(g_lua, 2);
611
612 if(lua_gettop(g_lua) != oldtop)
613 {
614 printf("internal error: unbalanced my_lua_import_soc\n");
615 return false;
616 }
617 return true;
618}
619
620bool my_lua_import_soc(const std::vector< soc_t >& socs)
621{
622 for(size_t i = 0; i < socs.size(); i++)
623 {
624 if(!g_quiet)
625 printf("importing %s...\n", socs[i].name.c_str());
626 if(!my_lua_import_soc(socs[i]))
627 return false;
628 }
629 return true;
630}
631
632/**
633 * glue
634 */
635
636void usage(void)
637{
638 printf("hwstub_tool, compiled with hwstub %d.%d.%d\n",
639 HWSTUB_VERSION_MAJOR, HWSTUB_VERSION_MINOR, HWSTUB_VERSION_REV);
640 printf("\n");
641 printf("usage: hwstub_tool [options] <soc desc files>\n");
642 printf("options:\n");
643 printf(" --help/-?\tDisplay this help\n");
644 printf(" --quiet/-q\tQuiet non-command messages\n");
645 printf(" -i <init>\tSet lua init file (default is init.lua)\n");
646 exit(1);
647}
648
649int main(int argc, char **argv)
650{
651 const char *lua_init = "init.lua";
652 // parse command line
653 while(1)
654 {
655 static struct option long_options[] =
656 {
657 {"help", no_argument, 0, '?'},
658 {"quiet", no_argument, 0, 'q'},
659 {0, 0, 0, 0}
660 };
661
662 int c = getopt_long(argc, argv, "?qi:", long_options, NULL);
663 if(c == -1)
664 break;
665 switch(c)
666 {
667 case -1:
668 break;
669 case 'q':
670 g_quiet = true;
671 break;
672 case '?':
673 usage();
674 break;
675 case 'i':
676 lua_init = optarg;
677 break;
678 default:
679 abort();
680 }
681 }
682
683 // load register descriptions
684 std::vector< soc_t > socs;
685 for(int i = optind; i < argc; i++)
686 if(!soc_desc_parse_xml(argv[i], socs))
687 {
688 printf("Cannot load description '%s'\n", argv[i]);
689 return 2;
690 }
691
692 // create usb context
693 libusb_context *ctx;
694 libusb_init(&ctx);
695 libusb_set_debug(ctx, 3);
696
697 // look for device
698 if(!g_quiet)
699 printf("Looking for device %#04x:%#04x...\n", HWSTUB_USB_VID, HWSTUB_USB_PID);
700
701 libusb_device_handle *handle = libusb_open_device_with_vid_pid(ctx,
702 HWSTUB_USB_VID, HWSTUB_USB_PID);
703 if(handle == NULL)
704 {
705 printf("No device found\n");
706 return 1;
707 }
708
709 // admin stuff
710 libusb_device *mydev = libusb_get_device(handle);
711 if(!g_quiet)
712 {
713 printf("device found at %d:%d\n",
714 libusb_get_bus_number(mydev),
715 libusb_get_device_address(mydev));
716 }
717 g_hwdev.handle = handle;
718 if(hwstub_probe(&g_hwdev))
719 {
720 printf("Cannot probe device!\n");
721 return 1;
722 }
723
724 // get hwstub information
725 int ret = hwstub_get_info(&g_hwdev, HWSTUB_INFO_VERSION, &g_hwdev_ver, sizeof(g_hwdev_ver));
726 if(ret != sizeof(g_hwdev_ver))
727 {
728 printf("Cannot get version!\n");
729 goto Lerr;
730 }
731 if(g_hwdev_ver.major != HWSTUB_VERSION_MAJOR || g_hwdev_ver.minor < HWSTUB_VERSION_MINOR)
732 {
733 printf("Warning: this tool is possibly incompatible with your device:\n");
734 printf("Device version: %d.%d.%d\n", g_hwdev_ver.major, g_hwdev_ver.minor, g_hwdev_ver.revision);
735 printf("Host version: %d.%d.%d\n", HWSTUB_VERSION_MAJOR, HWSTUB_VERSION_MINOR, HWSTUB_VERSION_REV);
736 }
737
738 // get memory layout information
739 ret = hwstub_get_info(&g_hwdev, HWSTUB_INFO_LAYOUT, &g_hwdev_layout, sizeof(g_hwdev_layout));
740 if(ret != sizeof(g_hwdev_layout))
741 {
742 printf("Cannot get layout: %d\n", ret);
743 goto Lerr;
744 }
745
746 // get features
747 ret = hwstub_get_info(&g_hwdev, HWSTUB_INFO_FEATURES, &g_hwdev_features, sizeof(g_hwdev_features));
748 if(ret != sizeof(g_hwdev_features))
749 {
750 printf("Cannot get features: %d\n", ret);
751 goto Lerr;
752 }
753
754 // get STMP specific information
755 ret = hwstub_get_info(&g_hwdev, HWSTUB_INFO_STMP, &g_hwdev_stmp, sizeof(g_hwdev_stmp));
756 if(ret != sizeof(g_hwdev_stmp))
757 {
758 printf("Cannot get stmp: %d\n", ret);
759 goto Lerr;
760 }
761
762 // dump ROM
763 if(!g_quiet)
764 {
765 void *rom = malloc(64 * 1024);
766 ret = hwstub_rw_mem(&g_hwdev, 1, 0xc0000000, rom, 64 * 1024);
767 if(ret != 64 * 1024)
768 {
769 printf("Cannot read ROM: %d\n", ret);
770 goto Lerr;
771 }
772
773 printf("ROM successfully read!\n");
774 FILE *f = fopen("rom.bin", "wb");
775 fwrite(rom, 64 * 1024, 1, f);
776 fclose(f);
777 }
778
779 // test DCP
780#if 0
781 if(!g_quiet)
782 {
783 struct
784 {
785 uint8_t iv[16];
786 uint8_t data[16];
787 } __attribute__((packed)) dcp_test;
788
789 for(int i = 0; i < 16; i++)
790 dcp_test.iv[i] = rand();
791 for(int i = 0; i < 16; i++)
792 dcp_test.data[i] = rand();
793 printf("DCP\n");
794 printf(" IN\n");
795 printf(" IV:");
796 for(int i = 0; i < 16; i++)
797 printf(" %02x", dcp_test.iv[i]);
798 printf("\n");
799 printf(" IV:");
800 for(int i = 0; i < 16; i++)
801 printf(" %02x", dcp_test.data[i]);
802 printf("\n");
803
804 if(!hwstub_aes_otp(&g_hwdev, &dcp_test, sizeof(dcp_test), HWSTUB_AES_OTP_ENCRYPT))
805 {
806 printf(" OUT\n");
807 printf(" IV:");
808 for(int i = 0; i < 16; i++)
809 printf(" %02x", dcp_test.iv[i]);
810 printf("\n");
811 printf(" IV:");
812 for(int i = 0; i < 16; i++)
813 printf(" %02x", dcp_test.data[i]);
814 printf("\n");
815 }
816 else
817 printf("DCP error!\n");
818 }
819#endif
820
821 /** Init lua */
822
823 // create lua state
824 g_lua = luaL_newstate();
825 if(g_lua == NULL)
826 {
827 printf("Cannot create lua state\n");
828 return 1;
829 }
830 // import hwstub
831 if(!my_lua_import_hwstub())
832 printf("Cannot import hwstub description into Lua context\n");
833 // open all standard libraires
834 luaL_openlibs(g_lua);
835 // import socs
836 if(!my_lua_import_soc(socs))
837 printf("Cannot import SoC descriptions into Lua context\n");
838
839 if(luaL_dofile(g_lua, lua_init))
840 printf("error in init: %s\n", lua_tostring(g_lua, -1));
841 lua_pop(g_lua, lua_gettop(g_lua));
842
843 /** start interactive mode */
844 if(!g_quiet)
845 printf("Starting interactive lua session. Type 'help()' to get some help\n");
846
847 // use readline to provide some history and completion
848 rl_bind_key('\t', rl_complete);
849 while(1)
850 {
851 char *input = readline("> ");
852 if(!input)
853 break;
854 add_history(input);
855 // evaluate string
856 if(luaL_dostring(g_lua, input))
857 printf("error: %s\n", lua_tostring(g_lua, -1));
858 // pop everything to start from a clean stack
859 lua_pop(g_lua, lua_gettop(g_lua));
860 free(input);
861 }
862
863 Lerr:
864 // display log if handled
865 if(g_hwdev_features.feature_mask & HWSTUB_FEATURE_LOG)
866 {
867 if(!g_quiet)
868 printf("Device log:\n");
869 print_log(&g_hwdev);
870 }
871 hwstub_release(&g_hwdev);
872 return 1;
873}
diff --git a/utils/hwstub/tools/init.lua b/utils/hwstub/tools/init.lua
new file mode 100644
index 0000000000..142c77e20a
--- /dev/null
+++ b/utils/hwstub/tools/init.lua
@@ -0,0 +1,104 @@
1-- init code for hwstub_tools
2
3--
4-- HELP
5--
6HELP = hwstub.help
7
8function HELP:create_topic(name)
9 self[name] = { create_topic = HELP.create_topic, add = HELP.add, get_topic = HELP.get_topic }
10 return self[name]
11end
12
13function HELP:get_topic(name)
14 return self[name]
15end
16
17function HELP:add(text)
18 table.insert(self, text)
19end
20
21do
22 local h = HELP:create_topic("hwstub")
23 h:add("This tool uses a number of well-defined namespaces (tables) to organise its features.")
24 h:add("The hwstub table contains a number of information and functions related to the tool itself.")
25 h:add("Of particular interest are")
26 h:add("* hwstub.host which holds host specific information.")
27 h:add("* hwstub.dev which holds device specific information. See DEV")
28 h:add("* hwstub.help (aka HELP) which holds the help. See HELP.");
29 h:add("* hwstub.soc which holds soc specific information. See HW");
30
31 h = HELP:create_topic("HELP");
32 h:add("This variable redirects to hwstub.help and provides access to the help system.");
33 h:add("You can enhance the help using the following methods on any topic (including HELP itself).");
34 h:add("* t:create_topic(s) to create a new subtopic named s under topic t");
35 h:add("* t:add(s) to add a help line to topic t");
36 h:add("* t:get_topic(s) to get the subtopic s under topic t");
37
38 h = HELP:create_topic("DEV");
39 h:add("This variable redirects to hwstub.dev and provides direct access to the device.");
40 h:add("It contains some information about the device and the following methods.");
41 h:add("* read8/16/32(a) reads a 8/16/32-bit integer at address a");
42 h:add("* write8/16/32(a, v) writes the 8/16/32-bit integer v at address a");
43
44 h = HELP:create_topic("HW");
45 h:add("This variable redirects to the current soc under hwstub.soc and should be changed by calling hwstub:soc:select only.");
46 h:add("The complete register tree can be found under HW in a well organise fashion.");
47 h:add("* HW.dev points to device dev");
48 h:add("* HW.dev[i] points to device devi if there are several copies of the device at different addresses.");
49 h:add("* HW.dev.reg points to the register reg under dev");
50 h:add("* HW.dev.reg[i] points to the register regi if there are several copies.");
51 h:add("* HW.dev.reg.f points to the field f under register reg.");
52 h:add("* HW.dev.reg.f.v gives the value of named value v of field f.");
53 h:add("* All registers can be read using HW.dev.reg.read() and written using HW.dev.reg.write(v).");
54 h:add("* Register with a SCT variant also implement HW.dev.reg.set/clr/tog(v).");
55 h:add("* All register field can be read using HW.dev.reg.f.read() and written using HW.dev.reg.f.write(v).");
56 h:add("* Field writes can either give a integer or a named value to write(v).");
57 h:add("* Register with a SCT variant also implement HW.dev.reg.f.set/clr/tog(v) with the same properties.");
58 h:add("* All devices, registers and fields also have descriptions available such as addresses.");
59end
60
61--
62-- INFO
63--
64
65if not hwstub.options.quiet then
66 print("information")
67 print(" hwstub")
68 print(" version: " .. string.format("%d.%d.%d", hwstub.host.version.major,
69 hwstub.host.version.minor, hwstub.host.version.revision))
70 print(" device")
71 print(" version: " .. string.format("%d.%d.%d", hwstub.dev.version.major,
72 hwstub.dev.version.minor, hwstub.dev.version.revision))
73 print(" layout")
74 print(" on-chip ram")
75 print(" code: " .. string.format("%#x bytes @ %#x",
76 hwstub.dev.layout.ocram.code.size, hwstub.dev.layout.ocram.code.start))
77 print(" stack: " .. string.format("%#x bytes @ %#x",
78 hwstub.dev.layout.ocram.stack.size, hwstub.dev.layout.ocram.stack.start))
79 print(" buffer: " .. string.format("%#x bytes @ %#x",
80 hwstub.dev.layout.ocram.buffer.size, hwstub.dev.layout.ocram.buffer.start))
81 print(" features");
82 print(" log: " .. tostring(hwstub.dev.features.log))
83 print(" mem: " .. tostring(hwstub.dev.features.mem))
84 print(" call: " .. tostring(hwstub.dev.features.call))
85 print(" jump: " .. tostring(hwstub.dev.features.jump))
86 print(" aes_otp: " .. tostring(hwstub.dev.features.aes_otp))
87end
88
89--
90-- SOC
91--
92function hwstub.soc:select(soc)
93 if self[soc] == nil then return false end
94 print("Selecting soc " .. soc .. ". Redirecting HW to hwstub.soc." .. soc)
95 HW = self[soc]
96 return true
97end
98
99--
100-- DEV
101--
102DEV = hwstub.dev
103
104require "lua/load"