diff options
Diffstat (limited to 'utils/hwstub')
-rw-r--r-- | utils/hwstub/hwstub_protocol.h | 120 | ||||
-rw-r--r-- | utils/hwstub/lib/hwstub.c | 121 | ||||
-rw-r--r-- | utils/hwstub/lib/hwstub.h | 23 | ||||
-rw-r--r-- | utils/hwstub/stub/main.c | 241 | ||||
-rw-r--r-- | utils/hwstub/stub/rk27xx/target.c | 59 | ||||
-rw-r--r-- | utils/hwstub/stub/stmp/target.c | 132 | ||||
-rw-r--r-- | utils/hwstub/stub/target.h | 13 | ||||
-rw-r--r-- | utils/hwstub/tools/hwstub_load.cpp | 61 | ||||
-rw-r--r-- | utils/hwstub/tools/hwstub_shell.cpp | 142 | ||||
-rw-r--r-- | utils/hwstub/tools/init.lua | 18 |
10 files changed, 278 insertions, 652 deletions
diff --git a/utils/hwstub/hwstub_protocol.h b/utils/hwstub/hwstub_protocol.h index dc4c52fb04..4feab87f00 100644 --- a/utils/hwstub/hwstub_protocol.h +++ b/utils/hwstub/hwstub_protocol.h | |||
@@ -21,13 +21,13 @@ | |||
21 | #ifndef __HWSTUB_PROTOCOL__ | 21 | #ifndef __HWSTUB_PROTOCOL__ |
22 | #define __HWSTUB_PROTOCOL__ | 22 | #define __HWSTUB_PROTOCOL__ |
23 | 23 | ||
24 | #define HWSTUB_CLASS 0xfe | 24 | #define HWSTUB_CLASS 0xff |
25 | #define HWSTUB_SUBCLASS 0xac | 25 | #define HWSTUB_SUBCLASS 0xac |
26 | #define HWSTUB_PROTOCOL 0x1d | 26 | #define HWSTUB_PROTOCOL 0x1d |
27 | 27 | ||
28 | #define HWSTUB_VERSION_MAJOR 2 | 28 | #define HWSTUB_VERSION_MAJOR 3 |
29 | #define HWSTUB_VERSION_MINOR 11 | 29 | #define HWSTUB_VERSION_MINOR 0 |
30 | #define HWSTUB_VERSION_REV 2 | 30 | #define HWSTUB_VERSION_REV 0 |
31 | 31 | ||
32 | #define HWSTUB_USB_VID 0xfee1 | 32 | #define HWSTUB_USB_VID 0xfee1 |
33 | #define HWSTUB_USB_PID 0xdead | 33 | #define HWSTUB_USB_PID 0xdead |
@@ -41,81 +41,77 @@ | |||
41 | */ | 41 | */ |
42 | 42 | ||
43 | /* list of commands */ | 43 | /* list of commands */ |
44 | #define HWSTUB_GET_INFO 0 /* mandatory */ | 44 | #define HWSTUB_GET_LOG 0 /* optional */ |
45 | #define HWSTUB_GET_LOG 1 /* optional */ | 45 | #define HWSTUB_RW_MEM 1 /* optional */ |
46 | #define HWSTUB_RW_MEM 2 /* optional */ | 46 | #define HWSTUB_CALL 2 /* optional */ |
47 | #define HWSTUB_CALL 3 /* optional */ | 47 | #define HWSTUB_JUMP 3 /* optional */ |
48 | #define HWSTUB_JUMP 4 /* optional */ | ||
49 | #define HWSTUB_EXIT 5 /* optional */ | ||
50 | #define HWSTUB_ATEXIT 6 /* optional */ | ||
51 | 48 | ||
52 | /** | 49 | /** |
53 | * HWSTUB_GET_INFO: get some information about an aspect of the device. | 50 | * Descriptors can be retrieve using configuration descriptor or individually |
54 | * The wIndex field of the SETUP specifies which information to get. */ | 51 | * using the standard GetDescriptor request on the interface. |
52 | */ | ||
55 | 53 | ||
56 | /* list of possible information */ | 54 | /* list of possible information */ |
57 | #define HWSTUB_INFO_VERSION 0 /* mandatory */ | 55 | #define HWSTUB_DT_VERSION 0x41 /* mandatory */ |
58 | #define HWSTUB_INFO_LAYOUT 1 /* mandatory */ | 56 | #define HWSTUB_DT_LAYOUT 0x42 /* mandatory */ |
59 | #define HWSTUB_INFO_STMP 2 /* optional */ | 57 | #define HWSTUB_DT_TARGET 0x43 /* mandatory */ |
60 | #define HWSTUB_INFO_FEATURES 3 /* mandatory */ | 58 | #define HWSTUB_DT_STMP 0x44 /* optional */ |
61 | #define HWSTUB_INFO_TARGET 4 /* mandatory */ | ||
62 | 59 | ||
63 | struct usb_resp_info_version_t | 60 | struct hwstub_version_desc_t |
64 | { | 61 | { |
65 | uint8_t major; | 62 | uint8_t bLength; |
66 | uint8_t minor; | 63 | uint8_t bDescriptorType; |
67 | uint8_t revision; | 64 | /* full version information */ |
65 | uint8_t bMajor; | ||
66 | uint8_t bMinor; | ||
67 | uint8_t bRevision; | ||
68 | } __attribute__((packed)); | 68 | } __attribute__((packed)); |
69 | 69 | ||
70 | struct usb_resp_info_layout_t | 70 | struct hwstub_layout_desc_t |
71 | { | 71 | { |
72 | uint8_t bLength; | ||
73 | uint8_t bDescriptorType; | ||
72 | /* describe the range of memory used by the running code */ | 74 | /* describe the range of memory used by the running code */ |
73 | uint32_t oc_code_start; | 75 | uint32_t dCodeStart; |
74 | uint32_t oc_code_size; | 76 | uint32_t dCodeSize; |
75 | /* describe the range of memory used by the stack */ | 77 | /* describe the range of memory used by the stack */ |
76 | uint32_t oc_stack_start; | 78 | uint32_t dStackStart; |
77 | uint32_t oc_stack_size; | 79 | uint32_t dStackSize; |
78 | /* describe the range of memory available as a buffer */ | 80 | /* describe the range of memory available as a buffer */ |
79 | uint32_t oc_buffer_start; | 81 | uint32_t dBufferStart; |
80 | uint32_t oc_buffer_size; | 82 | uint32_t dBufferSize; |
81 | } __attribute__((packed)); | 83 | } __attribute__((packed)); |
82 | 84 | ||
83 | struct usb_resp_info_stmp_t | 85 | struct hwstub_stmp_desc_t |
84 | { | 86 | { |
85 | uint16_t chipid; /* 0x3780 for STMP3780 for example */ | 87 | uint8_t bLength; |
86 | uint8_t rev; /* 0=TA1 on STMP3780 for example */ | 88 | uint8_t bDescriptorType; |
87 | uint8_t is_supported; /* 1 if the chip is supported */ | 89 | /* Chip ID and revision */ |
90 | uint16_t wChipID; /* 0x3780 for STMP3780 for example */ | ||
91 | uint8_t bRevision; /* 0=TA1 on STMP3780 for example */ | ||
92 | uint8_t bPackage; /* 0=169BGA for example */ | ||
88 | } __attribute__((packed)); | 93 | } __attribute__((packed)); |
89 | 94 | ||
90 | /* list of possible features */ | ||
91 | #define HWSTUB_FEATURE_LOG (1 << 0) | ||
92 | #define HWSTUB_FEATURE_MEM (1 << 1) | ||
93 | #define HWSTUB_FEATURE_CALL (1 << 2) | ||
94 | #define HWSTUB_FEATURE_JUMP (1 << 3) | ||
95 | #define HWSTUB_FEATURE_EXIT (1 << 4) | ||
96 | |||
97 | struct usb_resp_info_features_t | ||
98 | { | ||
99 | uint32_t feature_mask; | ||
100 | }; | ||
101 | |||
102 | #define HWSTUB_TARGET_UNK ('U' | 'N' << 8 | 'K' << 16 | ' ' << 24) | 95 | #define HWSTUB_TARGET_UNK ('U' | 'N' << 8 | 'K' << 16 | ' ' << 24) |
103 | #define HWSTUB_TARGET_STMP ('S' | 'T' << 8 | 'M' << 16 | 'P' << 24) | 96 | #define HWSTUB_TARGET_STMP ('S' | 'T' << 8 | 'M' << 16 | 'P' << 24) |
104 | #define HWSTUB_TARGET_RK27 ('R' | 'K' << 8 | '2' << 16 | '7' << 24) | 97 | #define HWSTUB_TARGET_RK27 ('R' | 'K' << 8 | '2' << 16 | '7' << 24) |
105 | 98 | ||
106 | struct usb_resp_info_target_t | 99 | struct hwstub_target_desc_t |
107 | { | 100 | { |
108 | uint32_t id; | 101 | uint8_t bLength; |
109 | char name[60]; | 102 | uint8_t bDescriptorType; |
110 | }; | 103 | /* Target ID and name */ |
104 | uint32_t dID; | ||
105 | char bName[58]; | ||
106 | } __attribute__((packed)); | ||
111 | 107 | ||
112 | /** | 108 | /** |
113 | * HWSTUB_GET_LOG: only if has HWSTUB_FEATURE_LOG. | 109 | * HWSTUB_GET_LOG: |
114 | * The log is returned as part of the control transfer. | 110 | * The log is returned as part of the control transfer. |
115 | */ | 111 | */ |
116 | 112 | ||
117 | /** | 113 | /** |
118 | * HWSTUB_RW_MEM: only if has HWSTUB_FEATURE_MEM. | 114 | * HWSTUB_RW_MEM: |
119 | * The 32-bit address is split into two parts. | 115 | * The 32-bit address is split into two parts. |
120 | * The low 16-bit are stored in wValue and the upper | 116 | * The low 16-bit are stored in wValue and the upper |
121 | * 16-bit are stored in wIndex. Depending on the transfer direction, | 117 | * 16-bit are stored in wIndex. Depending on the transfer direction, |
@@ -124,30 +120,10 @@ struct usb_resp_info_target_t | |||
124 | * possible, making it suitable to read/write registers. */ | 120 | * possible, making it suitable to read/write registers. */ |
125 | 121 | ||
126 | /** | 122 | /** |
127 | * HWSTUB_x: only if has HWSTUB_FEATURE_x where x=CALL or JUMP. | 123 | * HWSTUB_{CALL,JUMP}: |
128 | * The 32-bit address is split into two parts. | 124 | * The 32-bit address is split into two parts. |
129 | * The low 16-bit are stored in wValue and the upper | 125 | * The low 16-bit are stored in wValue and the upper |
130 | * 16-bit are stored in wIndex. Depending on the transfer direction, | 126 | * 16-bit are stored in wIndex. Depending on the transfer direction, |
131 | * the transfer is either a read or a write. */ | 127 | * the transfer is either a read or a write. */ |
132 | 128 | ||
133 | /** | ||
134 | * HWSTUB_EXIT: only if has HWSTUB_FEATURE_EXIT. | ||
135 | * Stop hwstub now, performing the atexit action. Default exit action | ||
136 | * is target dependent. */ | ||
137 | |||
138 | /** | ||
139 | * HWSTUB_ATEXIT: only if has HWSTUB_FEATURE_EXIT. | ||
140 | * Sets the action to perform at exit. Exit happens by sending HWSTUB_EXIT | ||
141 | * or on USB disconnection. The following actions are available: | ||
142 | * - nop: don't do anything, wait for next connection | ||
143 | * - reboot: reboot the device | ||
144 | * - off: power off | ||
145 | * NOTE the power off action might have to wait for USB disconnection as some | ||
146 | * targets cannot power off while plugged. | ||
147 | * NOTE appart from nop which is mandatory, all other methods can be | ||
148 | * unavailable and thus the atexit command can fail. */ | ||
149 | #define HWSTUB_ATEXIT_REBOOT 0 | ||
150 | #define HWSTUB_ATEXIT_OFF 1 | ||
151 | #define HWSTUB_ATEXIT_NOP 2 | ||
152 | |||
153 | #endif /* __HWSTUB_PROTOCOL__ */ | 129 | #endif /* __HWSTUB_PROTOCOL__ */ |
diff --git a/utils/hwstub/lib/hwstub.c b/utils/hwstub/lib/hwstub.c index 41842fb181..67a797ddfe 100644 --- a/utils/hwstub/lib/hwstub.c +++ b/utils/hwstub/lib/hwstub.c | |||
@@ -19,69 +19,55 @@ | |||
19 | * | 19 | * |
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | #include "hwstub.h" | 21 | #include "hwstub.h" |
22 | #include <string.h> | ||
23 | #include <stdlib.h> | ||
22 | 24 | ||
23 | #ifndef MIN | 25 | #ifndef MIN |
24 | #define MIN(a,b) ((a) < (b) ? (a) : (b)) | 26 | #define MIN(a,b) ((a) < (b) ? (a) : (b)) |
25 | #endif | 27 | #endif |
26 | 28 | ||
27 | /* requires then ->handle field only */ | 29 | struct hwstub_device_t |
28 | int hwstub_probe(struct hwstub_device_t *dev) | ||
29 | { | 30 | { |
31 | libusb_device_handle *handle; | ||
32 | int intf; | ||
33 | int bulk_in; | ||
34 | int bulk_out; | ||
35 | int int_in; | ||
36 | }; | ||
37 | |||
38 | struct hwstub_device_t *hwstub_open(libusb_device_handle *handle) | ||
39 | { | ||
40 | struct hwstub_device_t *dev = malloc(sizeof(struct hwstub_device_t)); | ||
41 | memset(dev, 0, sizeof(struct hwstub_device_t)); | ||
42 | dev->handle = handle; | ||
30 | libusb_device *mydev = libusb_get_device(dev->handle); | 43 | libusb_device *mydev = libusb_get_device(dev->handle); |
31 | 44 | ||
32 | int config_id; | 45 | int config_id; |
33 | libusb_get_configuration(dev->handle, &config_id); | 46 | libusb_get_configuration(dev->handle, &config_id); |
34 | struct libusb_config_descriptor *config; | 47 | struct libusb_device_descriptor dev_desc; |
35 | libusb_get_active_config_descriptor(mydev, &config); | 48 | libusb_get_device_descriptor(mydev, &dev_desc); |
36 | 49 | if(dev_desc.bDeviceClass != HWSTUB_CLASS || | |
37 | const struct libusb_endpoint_descriptor *endp = NULL; | 50 | dev_desc.bDeviceSubClass != HWSTUB_SUBCLASS || |
38 | int intf; | 51 | dev_desc.bDeviceProtocol != HWSTUB_PROTOCOL) |
39 | for(intf = 0; intf < config->bNumInterfaces; intf++) | 52 | goto Lerr; |
40 | { | 53 | return dev; |
41 | if(config->interface[intf].num_altsetting != 1) | ||
42 | continue; | ||
43 | const struct libusb_interface_descriptor *interface = | ||
44 | &config->interface[intf].altsetting[0]; | ||
45 | if(interface->bNumEndpoints != 3 || | ||
46 | interface->bInterfaceClass != HWSTUB_CLASS || | ||
47 | interface->bInterfaceSubClass != HWSTUB_SUBCLASS || | ||
48 | interface->bInterfaceProtocol != HWSTUB_PROTOCOL) | ||
49 | continue; | ||
50 | dev->intf = intf; | ||
51 | dev->bulk_in = dev->bulk_out = dev->int_in = -1; | ||
52 | for(int ep = 0; ep < interface->bNumEndpoints; ep++) | ||
53 | { | ||
54 | endp = &interface->endpoint[ep]; | ||
55 | if((endp->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) == LIBUSB_TRANSFER_TYPE_INTERRUPT && | ||
56 | (endp->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN) | ||
57 | dev->int_in = endp->bEndpointAddress; | ||
58 | if((endp->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) == LIBUSB_TRANSFER_TYPE_BULK && | ||
59 | (endp->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN) | ||
60 | dev->bulk_in = endp->bEndpointAddress; | ||
61 | if((endp->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) == LIBUSB_TRANSFER_TYPE_BULK && | ||
62 | (endp->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT) | ||
63 | dev->bulk_out = endp->bEndpointAddress; | ||
64 | } | ||
65 | if(dev->bulk_in == -1 || dev->bulk_out == -1 || dev->int_in == -1) | ||
66 | continue; | ||
67 | break; | ||
68 | } | ||
69 | if(intf == config->bNumInterfaces) | ||
70 | return 1; | ||
71 | 54 | ||
72 | return libusb_claim_interface(dev->handle, intf); | 55 | Lerr: |
56 | free(dev); | ||
57 | return NULL; | ||
73 | } | 58 | } |
74 | 59 | ||
75 | int hwstub_release(struct hwstub_device_t *dev) | 60 | int hwstub_release(struct hwstub_device_t *dev) |
76 | { | 61 | { |
77 | return libusb_release_interface(dev->handle, dev->intf); | 62 | free(dev); |
63 | return 0; | ||
78 | } | 64 | } |
79 | 65 | ||
80 | int hwstub_get_info(struct hwstub_device_t *dev, uint16_t idx, void *info, size_t sz) | 66 | int hwstub_get_desc(struct hwstub_device_t *dev, uint16_t desc, void *info, size_t sz) |
81 | { | 67 | { |
82 | return libusb_control_transfer(dev->handle, | 68 | return libusb_control_transfer(dev->handle, |
83 | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN, | 69 | LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN, |
84 | HWSTUB_GET_INFO, 0, idx, info, sz, 1000); | 70 | LIBUSB_REQUEST_GET_DESCRIPTOR, desc << 8, 0, info, sz, 1000); |
85 | } | 71 | } |
86 | 72 | ||
87 | int hwstub_get_log(struct hwstub_device_t *dev, void *buf, size_t sz) | 73 | int hwstub_get_log(struct hwstub_device_t *dev, void *buf, size_t sz) |
@@ -126,50 +112,3 @@ int hwstub_jump(struct hwstub_device_t *dev, uint32_t addr) | |||
126 | LIBUSB_ENDPOINT_OUT, HWSTUB_JUMP, addr & 0xffff, addr >> 16, NULL, 0, | 112 | LIBUSB_ENDPOINT_OUT, HWSTUB_JUMP, addr & 0xffff, addr >> 16, NULL, 0, |
127 | 1000); | 113 | 1000); |
128 | } | 114 | } |
129 | |||
130 | const char *hwstub_get_product_string(struct usb_resp_info_stmp_t *stmp) | ||
131 | { | ||
132 | switch(stmp->chipid) | ||
133 | { | ||
134 | case 0x3700: return "STMP 3700"; | ||
135 | case 0x37b0: return "STMP 3770"; | ||
136 | case 0x3780: return "STMP 3780 / i.MX233"; | ||
137 | default: return "unknown"; | ||
138 | } | ||
139 | } | ||
140 | |||
141 | const char *hwstub_get_rev_string(struct usb_resp_info_stmp_t *stmp) | ||
142 | { | ||
143 | switch(stmp->chipid) | ||
144 | { | ||
145 | case 0x37b0: | ||
146 | case 0x3780: | ||
147 | switch(stmp->rev) | ||
148 | { | ||
149 | case 0: return "TA1"; | ||
150 | case 1: return "TA2"; | ||
151 | case 2: return "TA3"; | ||
152 | case 3: return "TA4"; | ||
153 | default: return "unknown"; | ||
154 | } | ||
155 | break; | ||
156 | default: | ||
157 | return "unknown"; | ||
158 | } | ||
159 | } | ||
160 | |||
161 | int hwstub_atexit(struct hwstub_device_t *dev, int method) | ||
162 | { | ||
163 | return libusb_control_transfer(dev->handle, | ||
164 | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE | | ||
165 | LIBUSB_ENDPOINT_OUT, HWSTUB_ATEXIT, 0, method, NULL, 0, | ||
166 | 1000); | ||
167 | } | ||
168 | |||
169 | int hwstub_exit(struct hwstub_device_t *dev) | ||
170 | { | ||
171 | return libusb_control_transfer(dev->handle, | ||
172 | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE | | ||
173 | LIBUSB_ENDPOINT_OUT, HWSTUB_EXIT, 0, 0, NULL, 0, | ||
174 | 1000); | ||
175 | } | ||
diff --git a/utils/hwstub/lib/hwstub.h b/utils/hwstub/lib/hwstub.h index f89bce5de9..69fdc63988 100644 --- a/utils/hwstub/lib/hwstub.h +++ b/utils/hwstub/lib/hwstub.h | |||
@@ -34,22 +34,15 @@ extern "C" { | |||
34 | * | 34 | * |
35 | */ | 35 | */ |
36 | 36 | ||
37 | struct hwstub_device_t | 37 | struct hwstub_device_t; |
38 | { | ||
39 | libusb_device_handle *handle; | ||
40 | int intf; | ||
41 | int bulk_in; | ||
42 | int bulk_out; | ||
43 | int int_in; | ||
44 | }; | ||
45 | 38 | ||
46 | /* Requires then ->handle field only. Returns 0 on success */ | 39 | /* Returns NULL on error */ |
47 | int hwstub_probe(struct hwstub_device_t *dev); | 40 | struct hwstub_device_t *hwstub_open(libusb_device_handle *handle); |
48 | /* Returns 0 on success */ | 41 | /* Returns 0 on success. Does *NOT* close the usb handle */ |
49 | int hwstub_release(struct hwstub_device_t *dev); | 42 | int hwstub_release(struct hwstub_device_t *dev); |
50 | 43 | ||
51 | /* Returns number of bytes filled */ | 44 | /* Returns number of bytes filled */ |
52 | int hwstub_get_info(struct hwstub_device_t *dev, uint16_t idx, void *info, size_t sz); | 45 | int hwstub_get_desc(struct hwstub_device_t *dev, uint16_t desc, void *info, size_t sz); |
53 | /* Returns number of bytes filled */ | 46 | /* Returns number of bytes filled */ |
54 | int hwstub_get_log(struct hwstub_device_t *dev, void *buf, size_t sz); | 47 | int hwstub_get_log(struct hwstub_device_t *dev, void *buf, size_t sz); |
55 | /* Returns number of bytes written/read or <0 on error */ | 48 | /* Returns number of bytes written/read or <0 on error */ |
@@ -57,12 +50,6 @@ int hwstub_rw_mem(struct hwstub_device_t *dev, int read, uint32_t addr, void *bu | |||
57 | /* Returns <0 on error */ | 50 | /* Returns <0 on error */ |
58 | int hwstub_call(struct hwstub_device_t *dev, uint32_t addr); | 51 | int hwstub_call(struct hwstub_device_t *dev, uint32_t addr); |
59 | int hwstub_jump(struct hwstub_device_t *dev, uint32_t addr); | 52 | int hwstub_jump(struct hwstub_device_t *dev, uint32_t addr); |
60 | /* Returns <0 on error */ | ||
61 | int hwstub_atexit(struct hwstub_device_t *dev, int action); | ||
62 | int hwstub_exit(struct hwstub_device_t *dev); | ||
63 | |||
64 | const char *hwstub_get_product_string(struct usb_resp_info_stmp_t *stmp); | ||
65 | const char *hwstub_get_rev_string(struct usb_resp_info_stmp_t *stmp); | ||
66 | 53 | ||
67 | #ifdef __cplusplus | 54 | #ifdef __cplusplus |
68 | } // extern "C" | 55 | } // extern "C" |
diff --git a/utils/hwstub/stub/main.c b/utils/hwstub/stub/main.c index 0923bf85ce..37590e88f8 100644 --- a/utils/hwstub/stub/main.c +++ b/utils/hwstub/stub/main.c | |||
@@ -51,16 +51,16 @@ static struct usb_device_descriptor __attribute__((aligned(2))) | |||
51 | .bLength = sizeof(struct usb_device_descriptor), | 51 | .bLength = sizeof(struct usb_device_descriptor), |
52 | .bDescriptorType = USB_DT_DEVICE, | 52 | .bDescriptorType = USB_DT_DEVICE, |
53 | .bcdUSB = 0x0200, | 53 | .bcdUSB = 0x0200, |
54 | .bDeviceClass = USB_CLASS_PER_INTERFACE, | 54 | .bDeviceClass = HWSTUB_CLASS, |
55 | .bDeviceSubClass = 0, | 55 | .bDeviceSubClass = HWSTUB_SUBCLASS, |
56 | .bDeviceProtocol = 0, | 56 | .bDeviceProtocol = HWSTUB_PROTOCOL, |
57 | .bMaxPacketSize0 = 64, | 57 | .bMaxPacketSize0 = 64, |
58 | .idVendor = HWSTUB_USB_VID, | 58 | .idVendor = HWSTUB_USB_VID, |
59 | .idProduct = HWSTUB_USB_PID, | 59 | .idProduct = HWSTUB_USB_PID, |
60 | .bcdDevice = HWSTUB_VERSION_MAJOR << 8 | HWSTUB_VERSION_MINOR, | 60 | .bcdDevice = HWSTUB_VERSION_MAJOR << 8 | HWSTUB_VERSION_MINOR, |
61 | .iManufacturer = 1, | 61 | .iManufacturer = 1, |
62 | .iProduct = 2, | 62 | .iProduct = 2, |
63 | .iSerialNumber = 3, | 63 | .iSerialNumber = 0, |
64 | .bNumConfigurations = 1 | 64 | .bNumConfigurations = 1 |
65 | }; | 65 | }; |
66 | 66 | ||
@@ -72,40 +72,13 @@ static struct usb_config_descriptor __attribute__((aligned(2))) | |||
72 | .bLength = sizeof(struct usb_config_descriptor), | 72 | .bLength = sizeof(struct usb_config_descriptor), |
73 | .bDescriptorType = USB_DT_CONFIG, | 73 | .bDescriptorType = USB_DT_CONFIG, |
74 | .wTotalLength = 0, /* will be filled in later */ | 74 | .wTotalLength = 0, /* will be filled in later */ |
75 | .bNumInterfaces = 1, | 75 | .bNumInterfaces = 0, |
76 | .bConfigurationValue = 1, | 76 | .bConfigurationValue = 1, |
77 | .iConfiguration = 0, | 77 | .iConfiguration = 0, |
78 | .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, | 78 | .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, |
79 | .bMaxPower = (USB_MAX_CURRENT + 1) / 2, /* In 2mA units */ | 79 | .bMaxPower = (USB_MAX_CURRENT + 1) / 2, /* In 2mA units */ |
80 | }; | 80 | }; |
81 | 81 | ||
82 | /* main interface */ | ||
83 | static struct usb_interface_descriptor __attribute__((aligned(2))) | ||
84 | interface_descriptor = | ||
85 | { | ||
86 | .bLength = sizeof(struct usb_interface_descriptor), | ||
87 | .bDescriptorType = USB_DT_INTERFACE, | ||
88 | .bInterfaceNumber = 0, | ||
89 | .bAlternateSetting = 0, | ||
90 | .bNumEndpoints = 3, | ||
91 | .bInterfaceClass = HWSTUB_CLASS, | ||
92 | .bInterfaceSubClass = HWSTUB_SUBCLASS, | ||
93 | .bInterfaceProtocol = HWSTUB_PROTOCOL, | ||
94 | .iInterface = 4 | ||
95 | }; | ||
96 | |||
97 | |||
98 | static struct usb_endpoint_descriptor __attribute__((aligned(2))) | ||
99 | endpoint_descriptor = | ||
100 | { | ||
101 | .bLength = sizeof(struct usb_endpoint_descriptor), | ||
102 | .bDescriptorType = USB_DT_ENDPOINT, | ||
103 | .bEndpointAddress = 0, | ||
104 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
105 | .wMaxPacketSize = 0, | ||
106 | .bInterval = 0 | ||
107 | }; | ||
108 | |||
109 | static const struct usb_string_descriptor __attribute__((aligned(2))) | 82 | static const struct usb_string_descriptor __attribute__((aligned(2))) |
110 | usb_string_iManufacturer = | 83 | usb_string_iManufacturer = |
111 | { | 84 | { |
@@ -117,42 +90,38 @@ static const struct usb_string_descriptor __attribute__((aligned(2))) | |||
117 | static const struct usb_string_descriptor __attribute__((aligned(2))) | 90 | static const struct usb_string_descriptor __attribute__((aligned(2))) |
118 | usb_string_iProduct = | 91 | usb_string_iProduct = |
119 | { | 92 | { |
120 | 52, | 93 | 44, |
121 | USB_DT_STRING, | 94 | USB_DT_STRING, |
122 | {'R', 'o', 'c', 'k', 'b', 'o', 'x', ' ', | 95 | {'R', 'o', 'c', 'k', 'b', 'o', 'x', ' ', |
123 | 'h', 'a', 'r', 'd', 'w', 'a', 'r', 'e', ' ', | 96 | 'h', 'a', 'r', 'd', 'w', 'a', 'r', 'e', ' ', |
124 | 'e', 'm', 'u', 'l', 'a', 't', 'e', 'r'} | 97 | 's', 't', 'u', 'b'} |
125 | }; | 98 | }; |
126 | 99 | ||
127 | static struct usb_string_descriptor __attribute__((aligned(2))) | 100 | /* this is stringid #0: languages supported */ |
128 | usb_string_iSerial = | 101 | static const struct usb_string_descriptor __attribute__((aligned(2))) |
102 | lang_descriptor = | ||
129 | { | 103 | { |
130 | 84, | 104 | 4, |
131 | USB_DT_STRING, | 105 | USB_DT_STRING, |
132 | {'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', | 106 | {0x0409} /* LANGID US English */ |
133 | '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', | ||
134 | '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', | ||
135 | '0', '0', '0', '0', '0', '0', '0', '0'} | ||
136 | }; | 107 | }; |
137 | 108 | ||
138 | static struct usb_string_descriptor __attribute__((aligned(2))) | 109 | static struct hwstub_version_desc_t __attribute__((aligned(2))) |
139 | usb_string_iInterface = | 110 | version_descriptor = |
140 | { | 111 | { |
141 | 28, | 112 | sizeof(struct hwstub_version_desc_t), |
142 | USB_DT_STRING, | 113 | HWSTUB_DT_VERSION, |
143 | {'A', 'c', 'i', 'd', ' ', | 114 | HWSTUB_VERSION_MAJOR, |
144 | '0' + (HWSTUB_VERSION_MAJOR >> 4), '0' + (HWSTUB_VERSION_MAJOR & 0xf), '.', | 115 | HWSTUB_VERSION_MINOR, |
145 | '0' + (HWSTUB_VERSION_MINOR >> 4), '0' + (HWSTUB_VERSION_MINOR & 0xf), '.', | 116 | HWSTUB_VERSION_REV |
146 | '0' + (HWSTUB_VERSION_REV >> 4), '0' + (HWSTUB_VERSION_REV & 0xf) } | ||
147 | }; | 117 | }; |
148 | 118 | ||
149 | /* this is stringid #0: languages supported */ | 119 | static struct hwstub_layout_desc_t __attribute__((aligned(2))) |
150 | static const struct usb_string_descriptor __attribute__((aligned(2))) | 120 | layout_descriptor = |
151 | lang_descriptor = | ||
152 | { | 121 | { |
153 | 4, | 122 | sizeof(struct hwstub_layout_desc_t), |
154 | USB_DT_STRING, | 123 | HWSTUB_DT_LAYOUT, |
155 | {0x0409} /* LANGID US English */ | 124 | 0, 0, 0, 0, 0, 0 |
156 | }; | 125 | }; |
157 | 126 | ||
158 | #define USB_NUM_STRINGS 5 | 127 | #define USB_NUM_STRINGS 5 |
@@ -162,26 +131,25 @@ static const struct usb_string_descriptor* const usb_strings[USB_NUM_STRINGS] = | |||
162 | &lang_descriptor, | 131 | &lang_descriptor, |
163 | &usb_string_iManufacturer, | 132 | &usb_string_iManufacturer, |
164 | &usb_string_iProduct, | 133 | &usb_string_iProduct, |
165 | &usb_string_iSerial, | ||
166 | &usb_string_iInterface | ||
167 | }; | 134 | }; |
168 | 135 | ||
169 | uint8_t *usb_buffer = oc_bufferstart; | 136 | uint8_t *usb_buffer = oc_bufferstart; |
170 | uint32_t usb_buffer_size = 0; | 137 | uint32_t usb_buffer_size = 0; |
171 | 138 | ||
172 | #define EP_BULK 1 | 139 | static void fill_layout_info(void) |
173 | #define EP_INT 2 | ||
174 | |||
175 | static void set_config(void) | ||
176 | { | 140 | { |
177 | usb_drv_configure_endpoint(EP_BULK, USB_ENDPOINT_XFER_BULK); | 141 | layout_descriptor.dCodeStart = (uint32_t)oc_codestart; |
178 | usb_drv_configure_endpoint(EP_INT, USB_ENDPOINT_XFER_INT); | 142 | layout_descriptor.dCodeSize = oc_codesize; |
143 | layout_descriptor.dStackStart = (uint32_t)oc_stackstart; | ||
144 | layout_descriptor.dStackSize = oc_stacksize; | ||
145 | layout_descriptor.dBufferStart = (uint32_t)oc_bufferstart; | ||
146 | layout_descriptor.dBufferSize = oc_buffersize; | ||
179 | } | 147 | } |
180 | 148 | ||
181 | static void handle_std_dev_desc(struct usb_ctrlrequest *req) | 149 | static void handle_std_dev_desc(struct usb_ctrlrequest *req) |
182 | { | 150 | { |
183 | int size; | 151 | int size; |
184 | const void* ptr = NULL; | 152 | void* ptr = NULL; |
185 | unsigned index = req->wValue & 0xff; | 153 | unsigned index = req->wValue & 0xff; |
186 | 154 | ||
187 | switch(req->wValue >> 8) | 155 | switch(req->wValue >> 8) |
@@ -208,32 +176,22 @@ static void handle_std_dev_desc(struct usb_ctrlrequest *req) | |||
208 | } | 176 | } |
209 | size = sizeof(struct usb_config_descriptor); | 177 | size = sizeof(struct usb_config_descriptor); |
210 | 178 | ||
211 | /* interface */ | 179 | /* hwstub version */ |
212 | memcpy(usb_buffer + size, (void *)&interface_descriptor, | 180 | memcpy(usb_buffer + size, (void *)&version_descriptor, |
213 | sizeof(interface_descriptor)); | 181 | sizeof(version_descriptor)); |
214 | size += sizeof(interface_descriptor); | 182 | size += sizeof(version_descriptor); |
215 | /* endpoint 1: bulk out */ | 183 | /* hwstub layout */ |
216 | endpoint_descriptor.bEndpointAddress = EP_BULK | USB_DIR_OUT; | 184 | fill_layout_info(); |
217 | endpoint_descriptor.bmAttributes = USB_ENDPOINT_XFER_BULK; | 185 | memcpy(usb_buffer + size, (void *)&layout_descriptor, |
218 | endpoint_descriptor.wMaxPacketSize = 512; | 186 | sizeof(layout_descriptor)); |
219 | memcpy(usb_buffer + size, (void *)&endpoint_descriptor, | 187 | size += sizeof(layout_descriptor); |
220 | sizeof(endpoint_descriptor)); | 188 | /* hwstub target */ |
221 | size += sizeof(endpoint_descriptor); | 189 | fill_layout_info(); |
222 | /* endpoint 2: bulk in */ | 190 | memcpy(usb_buffer + size, (void *)&target_descriptor, |
223 | endpoint_descriptor.bEndpointAddress = EP_BULK | USB_DIR_IN; | 191 | sizeof(target_descriptor)); |
224 | endpoint_descriptor.bmAttributes = USB_ENDPOINT_XFER_BULK; | 192 | size += sizeof(target_descriptor); |
225 | endpoint_descriptor.wMaxPacketSize = 512; | 193 | /* target specific descriptors */ |
226 | memcpy(usb_buffer + size, (void *)&endpoint_descriptor, | 194 | target_get_config_desc(usb_buffer + size, &size); |
227 | sizeof(endpoint_descriptor)); | ||
228 | size += sizeof(endpoint_descriptor); | ||
229 | /* endpoint 3: int in */ | ||
230 | endpoint_descriptor.bEndpointAddress = EP_INT | USB_DIR_IN; | ||
231 | endpoint_descriptor.bmAttributes = USB_ENDPOINT_XFER_INT; | ||
232 | endpoint_descriptor.wMaxPacketSize = 1024; | ||
233 | memcpy(usb_buffer + size, (void *)&endpoint_descriptor, | ||
234 | sizeof(endpoint_descriptor)); | ||
235 | size += sizeof(endpoint_descriptor); | ||
236 | |||
237 | /* fix config descriptor */ | 195 | /* fix config descriptor */ |
238 | config_descriptor.bNumInterfaces = 1; | 196 | config_descriptor.bNumInterfaces = 1; |
239 | config_descriptor.wTotalLength = size; | 197 | config_descriptor.wTotalLength = size; |
@@ -246,12 +204,27 @@ static void handle_std_dev_desc(struct usb_ctrlrequest *req) | |||
246 | if(index < USB_NUM_STRINGS) | 204 | if(index < USB_NUM_STRINGS) |
247 | { | 205 | { |
248 | size = usb_strings[index]->bLength; | 206 | size = usb_strings[index]->bLength; |
249 | ptr = usb_strings[index]; | 207 | ptr = (void *)usb_strings[index]; |
250 | } | 208 | } |
251 | else | 209 | else |
252 | usb_drv_stall(EP_CONTROL, true, true); | 210 | usb_drv_stall(EP_CONTROL, true, true); |
253 | break; | 211 | break; |
212 | case HWSTUB_DT_VERSION: | ||
213 | ptr = &version_descriptor; | ||
214 | size = sizeof(version_descriptor); | ||
215 | break; | ||
216 | case HWSTUB_DT_LAYOUT: | ||
217 | ptr = &layout_descriptor; | ||
218 | size = sizeof(layout_descriptor); | ||
219 | break; | ||
220 | case HWSTUB_DT_TARGET: | ||
221 | ptr = &target_descriptor; | ||
222 | size = sizeof(target_descriptor); | ||
223 | break; | ||
254 | default: | 224 | default: |
225 | target_get_desc(req->wValue >> 8, &ptr); | ||
226 | if(ptr != 0) | ||
227 | size = ((struct usb_descriptor_header *)ptr)->bLength; | ||
255 | break; | 228 | break; |
256 | } | 229 | } |
257 | 230 | ||
@@ -280,7 +253,6 @@ static void handle_std_dev_req(struct usb_ctrlrequest *req) | |||
280 | break; | 253 | break; |
281 | case USB_REQ_SET_CONFIGURATION: | 254 | case USB_REQ_SET_CONFIGURATION: |
282 | usb_drv_send(EP_CONTROL, NULL, 0); | 255 | usb_drv_send(EP_CONTROL, NULL, 0); |
283 | set_config(); | ||
284 | break; | 256 | break; |
285 | case USB_REQ_GET_DESCRIPTOR: | 257 | case USB_REQ_GET_DESCRIPTOR: |
286 | handle_std_dev_desc(req); | 258 | handle_std_dev_desc(req); |
@@ -311,67 +283,6 @@ static void handle_std_req(struct usb_ctrlrequest *req) | |||
311 | } | 283 | } |
312 | } | 284 | } |
313 | 285 | ||
314 | struct usb_resp_info_version_t g_version = | ||
315 | { | ||
316 | .major = HWSTUB_VERSION_MAJOR, | ||
317 | .minor = HWSTUB_VERSION_MINOR, | ||
318 | .revision = HWSTUB_VERSION_REV | ||
319 | }; | ||
320 | |||
321 | struct usb_resp_info_layout_t g_layout; | ||
322 | |||
323 | struct usb_resp_info_features_t g_features = | ||
324 | { | ||
325 | .feature_mask = HWSTUB_FEATURE_LOG | HWSTUB_FEATURE_MEM | | ||
326 | HWSTUB_FEATURE_CALL | HWSTUB_FEATURE_JUMP | ||
327 | }; | ||
328 | |||
329 | static void fill_layout_info(void) | ||
330 | { | ||
331 | g_layout.oc_code_start = (uint32_t)oc_codestart; | ||
332 | g_layout.oc_code_size = oc_codesize; | ||
333 | g_layout.oc_stack_start = (uint32_t)oc_stackstart; | ||
334 | g_layout.oc_stack_size = oc_stacksize; | ||
335 | g_layout.oc_buffer_start = (uint32_t)oc_bufferstart; | ||
336 | g_layout.oc_buffer_size = oc_buffersize; | ||
337 | } | ||
338 | |||
339 | static void handle_get_info(struct usb_ctrlrequest *req) | ||
340 | { | ||
341 | void *ptr = NULL; | ||
342 | int size = 0; | ||
343 | switch(req->wIndex) | ||
344 | { | ||
345 | case HWSTUB_INFO_VERSION: | ||
346 | ptr = &g_version; | ||
347 | size = sizeof(g_version); | ||
348 | break; | ||
349 | case HWSTUB_INFO_LAYOUT: | ||
350 | fill_layout_info(); | ||
351 | ptr = &g_layout; | ||
352 | size = sizeof(g_layout); | ||
353 | break; | ||
354 | case HWSTUB_INFO_FEATURES: | ||
355 | ptr = &g_features; | ||
356 | size = sizeof(g_features); | ||
357 | break; | ||
358 | default: | ||
359 | size = target_get_info(req->wIndex, &ptr); | ||
360 | if(size < 0) | ||
361 | usb_drv_stall(EP_CONTROL, true, true); | ||
362 | } | ||
363 | |||
364 | if(ptr) | ||
365 | { | ||
366 | int length = MIN(size, req->wLength); | ||
367 | |||
368 | if(ptr != usb_buffer) | ||
369 | memcpy(usb_buffer, ptr, length); | ||
370 | usb_drv_send(EP_CONTROL, usb_buffer, length); | ||
371 | usb_drv_recv(EP_CONTROL, NULL, 0); | ||
372 | } | ||
373 | } | ||
374 | |||
375 | static void handle_get_log(struct usb_ctrlrequest *req) | 286 | static void handle_get_log(struct usb_ctrlrequest *req) |
376 | { | 287 | { |
377 | enable_logf(false); | 288 | enable_logf(false); |
@@ -421,28 +332,10 @@ static void handle_call_jump(struct usb_ctrlrequest *req) | |||
421 | } | 332 | } |
422 | } | 333 | } |
423 | 334 | ||
424 | static void handle_atexit(struct usb_ctrlrequest *req) | ||
425 | { | ||
426 | if(target_atexit(req->wIndex) < 0) | ||
427 | usb_drv_stall(EP_CONTROL, true, true); | ||
428 | else | ||
429 | usb_drv_send(EP_CONTROL, NULL, 0); | ||
430 | } | ||
431 | |||
432 | static void handle_exit(struct usb_ctrlrequest *req) | ||
433 | { | ||
434 | (void)req; | ||
435 | usb_drv_send(EP_CONTROL, NULL, 0); | ||
436 | g_exit = true; | ||
437 | } | ||
438 | |||
439 | static void handle_class_dev_req(struct usb_ctrlrequest *req) | 335 | static void handle_class_dev_req(struct usb_ctrlrequest *req) |
440 | { | 336 | { |
441 | switch(req->bRequest) | 337 | switch(req->bRequest) |
442 | { | 338 | { |
443 | case HWSTUB_GET_INFO: | ||
444 | handle_get_info(req); | ||
445 | break; | ||
446 | case HWSTUB_GET_LOG: | 339 | case HWSTUB_GET_LOG: |
447 | handle_get_log(req); | 340 | handle_get_log(req); |
448 | break; | 341 | break; |
@@ -453,11 +346,6 @@ static void handle_class_dev_req(struct usb_ctrlrequest *req) | |||
453 | case HWSTUB_JUMP: | 346 | case HWSTUB_JUMP: |
454 | handle_call_jump(req); | 347 | handle_call_jump(req); |
455 | break; | 348 | break; |
456 | case HWSTUB_ATEXIT: | ||
457 | handle_atexit(req); | ||
458 | break; | ||
459 | case HWSTUB_EXIT: | ||
460 | handle_exit(req); | ||
461 | break; | 349 | break; |
462 | default: | 350 | default: |
463 | usb_drv_stall(EP_CONTROL, true, true); | 351 | usb_drv_stall(EP_CONTROL, true, true); |
@@ -510,5 +398,4 @@ void main(uint32_t arg) | |||
510 | } | 398 | } |
511 | } | 399 | } |
512 | usb_drv_exit(); | 400 | usb_drv_exit(); |
513 | target_exit(); | ||
514 | } | 401 | } |
diff --git a/utils/hwstub/stub/rk27xx/target.c b/utils/hwstub/stub/rk27xx/target.c index f9efccaef0..ff2e952909 100644 --- a/utils/hwstub/stub/rk27xx/target.c +++ b/utils/hwstub/stub/rk27xx/target.c | |||
@@ -33,7 +33,6 @@ enum rk27xx_family_t | |||
33 | }; | 33 | }; |
34 | 34 | ||
35 | static enum rk27xx_family_t g_rk27xx_family = UNKNOWN; | 35 | static enum rk27xx_family_t g_rk27xx_family = UNKNOWN; |
36 | static int g_atexit = HWSTUB_ATEXIT_OFF; | ||
37 | 36 | ||
38 | static void _enable_irq(void) | 37 | static void _enable_irq(void) |
39 | { | 38 | { |
@@ -43,23 +42,6 @@ static void _enable_irq(void) | |||
43 | ); | 42 | ); |
44 | } | 43 | } |
45 | 44 | ||
46 | static void power_off(void) | ||
47 | { | ||
48 | GPIO_PCCON &= ~(1<<0); | ||
49 | while(1); | ||
50 | } | ||
51 | |||
52 | static void rk27xx_reset(void) | ||
53 | { | ||
54 | /* use Watchdog to reset */ | ||
55 | SCU_CLKCFG &= ~CLKCFG_WDT; | ||
56 | WDTLR = 1; | ||
57 | WDTCON = (1<<4) | (1<<3); | ||
58 | |||
59 | /* Wait for reboot to kick in */ | ||
60 | while(1); | ||
61 | } | ||
62 | |||
63 | /* us may be at most 2^31/200 (~10 seconds) for 200MHz max cpu freq */ | 45 | /* us may be at most 2^31/200 (~10 seconds) for 200MHz max cpu freq */ |
64 | void target_udelay(int us) | 46 | void target_udelay(int us) |
65 | { | 47 | { |
@@ -132,41 +114,22 @@ void target_init(void) | |||
132 | } | 114 | } |
133 | } | 115 | } |
134 | 116 | ||
135 | static struct usb_resp_info_target_t g_target = | 117 | struct hwstub_target_desc_t __attribute__((aligned(2))) target_descriptor = |
136 | { | 118 | { |
137 | .id = HWSTUB_TARGET_RK27, | 119 | sizeof(struct hwstub_target_desc_t), |
138 | .name = "Rockchip RK27XX" | 120 | HWSTUB_DT_TARGET, |
121 | HWSTUB_TARGET_RK27, | ||
122 | "Rockchip RK27XX" | ||
139 | }; | 123 | }; |
140 | 124 | ||
141 | int target_get_info(int info, void **buffer) | 125 | void target_get_desc(int desc, void **buffer) |
142 | { | 126 | { |
143 | if(info == HWSTUB_INFO_TARGET) | 127 | (void) desc; |
144 | { | 128 | *buffer = NULL; |
145 | *buffer = &g_target; | ||
146 | return sizeof(g_target); | ||
147 | } | ||
148 | else | ||
149 | return -1; | ||
150 | } | 129 | } |
151 | 130 | ||
152 | int target_atexit(int method) | 131 | void target_get_config_desc(void *buffer, int *size) |
153 | { | 132 | { |
154 | g_atexit = method; | 133 | (void) buffer; |
155 | return 0; | 134 | (void) size; |
156 | } | ||
157 | |||
158 | void target_exit(void) | ||
159 | { | ||
160 | switch(g_atexit) | ||
161 | { | ||
162 | case HWSTUB_ATEXIT_OFF: | ||
163 | power_off(); | ||
164 | // fallthrough in case of return | ||
165 | case HWSTUB_ATEXIT_REBOOT: | ||
166 | rk27xx_reset(); | ||
167 | // fallthrough in case of return | ||
168 | case HWSTUB_ATEXIT_NOP: | ||
169 | default: | ||
170 | return; | ||
171 | } | ||
172 | } | 135 | } |
diff --git a/utils/hwstub/stub/stmp/target.c b/utils/hwstub/stub/stmp/target.c index 98f65da625..8d48707088 100644 --- a/utils/hwstub/stub/stmp/target.c +++ b/utils/hwstub/stub/stmp/target.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include "target.h" | 22 | #include "target.h" |
23 | #include "system.h" | 23 | #include "system.h" |
24 | #include "logf.h" | 24 | #include "logf.h" |
25 | #include "memory.h" | ||
25 | 26 | ||
26 | #define __REG_SET(reg) (*((volatile uint32_t *)(® + 1))) | 27 | #define __REG_SET(reg) (*((volatile uint32_t *)(® + 1))) |
27 | #define __REG_CLR(reg) (*((volatile uint32_t *)(® + 2))) | 28 | #define __REG_CLR(reg) (*((volatile uint32_t *)(® + 2))) |
@@ -50,34 +51,6 @@ enum stmp_family_t | |||
50 | }; | 51 | }; |
51 | 52 | ||
52 | static enum stmp_family_t g_stmp_family = UNKNOWN; | 53 | static enum stmp_family_t g_stmp_family = UNKNOWN; |
53 | static int g_atexit = HWSTUB_ATEXIT_OFF; | ||
54 | |||
55 | /** | ||
56 | * | ||
57 | * Power | ||
58 | * | ||
59 | */ | ||
60 | |||
61 | #define HW_POWER_BASE 0x80044000 | ||
62 | |||
63 | void power_off(void) | ||
64 | { | ||
65 | switch(g_stmp_family) | ||
66 | { | ||
67 | case STMP3600: | ||
68 | *(volatile uint32_t *)(HW_POWER_BASE + 0xc0) = 0x3e770014; | ||
69 | break; | ||
70 | case STMP3700: | ||
71 | case STMP3770: | ||
72 | *(volatile uint32_t *)(HW_POWER_BASE + 0xe0) = 0x3e770001; | ||
73 | break; | ||
74 | case STMP3780: | ||
75 | *(volatile uint32_t *)(HW_POWER_BASE + 0x100) = 0x3e770001; | ||
76 | break; | ||
77 | default: | ||
78 | break; | ||
79 | } | ||
80 | } | ||
81 | 54 | ||
82 | /** | 55 | /** |
83 | * | 56 | * |
@@ -114,25 +87,6 @@ void power_off(void) | |||
114 | #define HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK30M_GATE (1 << 30) | 87 | #define HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK30M_GATE (1 << 30) |
115 | #define HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK120M_GATE (1 << 31) | 88 | #define HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK120M_GATE (1 << 31) |
116 | 89 | ||
117 | void clkctrl_reset(void) | ||
118 | { | ||
119 | switch(g_stmp_family) | ||
120 | { | ||
121 | case STMP3600: | ||
122 | *(volatile uint32_t *)(HW_POWER_BASE + 0xc0) = 0x3e770002; | ||
123 | break; | ||
124 | case STMP3700: | ||
125 | case STMP3770: | ||
126 | *(volatile uint32_t *)(HW_CLKCTRL_BASE + 0xf0) = 0x1; | ||
127 | break; | ||
128 | case STMP3780: | ||
129 | *(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x120) = 0x1; | ||
130 | break; | ||
131 | default: | ||
132 | break; | ||
133 | } | ||
134 | } | ||
135 | |||
136 | /** | 90 | /** |
137 | * | 91 | * |
138 | * Digctl | 92 | * Digctl |
@@ -143,11 +97,18 @@ void clkctrl_reset(void) | |||
143 | #define HW_DIGCTL_BASE 0x8001C000 | 97 | #define HW_DIGCTL_BASE 0x8001C000 |
144 | #define HW_DIGCTL_CTRL (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0)) | 98 | #define HW_DIGCTL_CTRL (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0)) |
145 | #define HW_DIGCTL_CTRL__USB_CLKGATE (1 << 2) | 99 | #define HW_DIGCTL_CTRL__USB_CLKGATE (1 << 2) |
100 | #define HW_DIGCTL_CTRL__PACKAGE_SENSE_ENABLE_STMP3600 (1 << 0) | ||
101 | |||
102 | #define HW_DIGCTL_STATUS (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0x10)) | ||
103 | #define HW_DIGCTL_STATUS__PACKAGE_TYPE_BP 1 | ||
104 | #define HW_DIGCTL_STATUS__PACKAGE_TYPE_BM (7 << 1) | ||
105 | #define HW_DIGCTL_STATUS__PACKAGE_TYPE_STMP3600_BP 1 | ||
106 | #define HW_DIGCTL_STATUS__PACKAGE_TYPE_STMP3600_BM (1 << 1) | ||
146 | 107 | ||
147 | /* STMP3700+ */ | 108 | /* STMP3700+ */ |
148 | #define HW_DIGCTL_MICROSECONDS (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0xC0)) | 109 | #define HW_DIGCTL_MICROSECONDS (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0xC0)) |
149 | /* STMP3600 */ | 110 | /* STMP3600 */ |
150 | #define HW_DIGCTL_MICROSECONDS2 (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0xB0)) | 111 | #define HW_DIGCTL_MICROSECONDS_STMP3600 (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0xB0)) |
151 | 112 | ||
152 | #define HW_DIGCTL_CHIPID (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0x310)) | 113 | #define HW_DIGCTL_CHIPID (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0x310)) |
153 | #define HW_DIGCTL_CHIPID__PRODUCT_CODE_BP 16 | 114 | #define HW_DIGCTL_CHIPID__PRODUCT_CODE_BP 16 |
@@ -177,8 +138,25 @@ void clkctrl_reset(void) | |||
177 | #define HW_RTC_CTRL (*(volatile uint32_t *)(HW_RTC_BASE + 0)) | 138 | #define HW_RTC_CTRL (*(volatile uint32_t *)(HW_RTC_BASE + 0)) |
178 | #define HW_RTC_CTRL__WATCHDOGEN (1 << 4) | 139 | #define HW_RTC_CTRL__WATCHDOGEN (1 << 4) |
179 | 140 | ||
141 | struct hwstub_target_desc_t __attribute__((aligned(2))) target_descriptor = | ||
142 | { | ||
143 | sizeof(struct hwstub_target_desc_t), | ||
144 | HWSTUB_DT_TARGET, | ||
145 | HWSTUB_TARGET_STMP, | ||
146 | "STMP3600 / STMP3700 / STMP3780 (i.MX233)" | ||
147 | }; | ||
148 | |||
149 | static struct hwstub_stmp_desc_t __attribute__((aligned(2))) stmp_descriptor = | ||
150 | { | ||
151 | sizeof(struct hwstub_stmp_desc_t), | ||
152 | HWSTUB_DT_STMP, | ||
153 | 0, 0, 0 | ||
154 | }; | ||
155 | |||
180 | void target_init(void) | 156 | void target_init(void) |
181 | { | 157 | { |
158 | stmp_descriptor.wChipID = __XTRACT(HW_DIGCTL_CHIPID, PRODUCT_CODE); | ||
159 | stmp_descriptor.bRevision = __XTRACT(HW_DIGCTL_CHIPID, REVISION); | ||
182 | /* detect family */ | 160 | /* detect family */ |
183 | uint16_t product_code = __XTRACT(HW_DIGCTL_CHIPID, PRODUCT_CODE); | 161 | uint16_t product_code = __XTRACT(HW_DIGCTL_CHIPID, PRODUCT_CODE); |
184 | if(product_code >= 0x3600 && product_code < 0x3700) | 162 | if(product_code >= 0x3600 && product_code < 0x3700) |
@@ -208,6 +186,7 @@ void target_init(void) | |||
208 | 186 | ||
209 | if(g_stmp_family == STMP3600) | 187 | if(g_stmp_family == STMP3600) |
210 | { | 188 | { |
189 | stmp_descriptor.bPackage = __XTRACT(HW_DIGCTL_STATUS, PACKAGE_TYPE); | ||
211 | /* CPU clock is always derived from PLL, if we switch to PLL, cpu will | 190 | /* CPU clock is always derived from PLL, if we switch to PLL, cpu will |
212 | * run at 480 MHz unprepared ! That's bad so prepare to run at slow sleed | 191 | * run at 480 MHz unprepared ! That's bad so prepare to run at slow sleed |
213 | * (1.2MHz) for a safe transition */ | 192 | * (1.2MHz) for a safe transition */ |
@@ -230,7 +209,13 @@ void target_init(void) | |||
230 | __REG_CLR(HW_CLKCTRL_UTMICLKCTRL) = HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK30M_GATE; | 209 | __REG_CLR(HW_CLKCTRL_UTMICLKCTRL) = HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK30M_GATE; |
231 | } | 210 | } |
232 | else | 211 | else |
212 | { | ||
213 | __REG_SET(HW_DIGCTL_CTRL) = HW_DIGCTL_CTRL__PACKAGE_SENSE_ENABLE_STMP3600; | ||
214 | stmp_descriptor.bPackage = __XTRACT(HW_DIGCTL_STATUS, PACKAGE_TYPE_STMP3600); | ||
215 | __REG_CLR(HW_DIGCTL_CTRL) = HW_DIGCTL_CTRL__PACKAGE_SENSE_ENABLE_STMP3600; | ||
216 | |||
233 | __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__POWER; | 217 | __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__POWER; |
218 | } | ||
234 | /* enable USB PHY PLL */ | 219 | /* enable USB PHY PLL */ |
235 | __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS; | 220 | __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS; |
236 | /* power up USB PHY */ | 221 | /* power up USB PHY */ |
@@ -240,57 +225,24 @@ void target_init(void) | |||
240 | __REG_CLR(HW_DIGCTL_CTRL) = HW_DIGCTL_CTRL__USB_CLKGATE; | 225 | __REG_CLR(HW_DIGCTL_CTRL) = HW_DIGCTL_CTRL__USB_CLKGATE; |
241 | } | 226 | } |
242 | 227 | ||
243 | static struct usb_resp_info_stmp_t g_stmp; | 228 | void target_get_desc(int desc, void **buffer) |
244 | static struct usb_resp_info_target_t g_target = | ||
245 | { | ||
246 | .id = HWSTUB_TARGET_STMP, | ||
247 | .name = "STMP3600 / STMP3700 / STMP3780 (i.MX233)" | ||
248 | }; | ||
249 | |||
250 | int target_get_info(int info, void **buffer) | ||
251 | { | 229 | { |
252 | if(info == HWSTUB_INFO_STMP) | 230 | if(desc == HWSTUB_DT_STMP) |
253 | { | 231 | *buffer = &stmp_descriptor; |
254 | g_stmp.chipid = __XTRACT(HW_DIGCTL_CHIPID, PRODUCT_CODE); | ||
255 | g_stmp.rev = __XTRACT(HW_DIGCTL_CHIPID, REVISION); | ||
256 | g_stmp.is_supported = g_stmp_family != 0; | ||
257 | *buffer = &g_stmp; | ||
258 | return sizeof(g_stmp); | ||
259 | } | ||
260 | else if(info == HWSTUB_INFO_TARGET) | ||
261 | { | ||
262 | *buffer = &g_target; | ||
263 | return sizeof(g_target); | ||
264 | } | ||
265 | else | 232 | else |
266 | return -1; | 233 | *buffer = NULL; |
267 | } | 234 | } |
268 | 235 | ||
269 | int target_atexit(int method) | 236 | void target_get_config_desc(void *buffer, int *size) |
270 | { | 237 | { |
271 | g_atexit = method; | 238 | memcpy(buffer, &stmp_descriptor, sizeof(stmp_descriptor)); |
272 | return 0; | 239 | *size += sizeof(stmp_descriptor); |
273 | } | ||
274 | |||
275 | void target_exit(void) | ||
276 | { | ||
277 | switch(g_atexit) | ||
278 | { | ||
279 | case HWSTUB_ATEXIT_OFF: | ||
280 | power_off(); | ||
281 | // fallthrough in case of return | ||
282 | case HWSTUB_ATEXIT_REBOOT: | ||
283 | clkctrl_reset(); | ||
284 | // fallthrough in case of return | ||
285 | case HWSTUB_ATEXIT_NOP: | ||
286 | default: | ||
287 | return; | ||
288 | } | ||
289 | } | 240 | } |
290 | 241 | ||
291 | void target_udelay(int us) | 242 | void target_udelay(int us) |
292 | { | 243 | { |
293 | volatile uint32_t *reg = g_stmp_family == STMP3600 ? &HW_DIGCTL_MICROSECONDS2 : &HW_DIGCTL_MICROSECONDS; | 244 | volatile uint32_t *reg = g_stmp_family == STMP3600 ? |
245 | &HW_DIGCTL_MICROSECONDS_STMP3600 : &HW_DIGCTL_MICROSECONDS; | ||
294 | uint32_t cur = *reg; | 246 | uint32_t cur = *reg; |
295 | uint32_t end = cur + us; | 247 | uint32_t end = cur + us; |
296 | if(cur < end) | 248 | if(cur < end) |
diff --git a/utils/hwstub/stub/target.h b/utils/hwstub/stub/target.h index 43151e9a34..cb17401a9c 100644 --- a/utils/hwstub/stub/target.h +++ b/utils/hwstub/stub/target.h | |||
@@ -25,15 +25,16 @@ | |||
25 | 25 | ||
26 | /* do target specific init */ | 26 | /* do target specific init */ |
27 | void target_init(void); | 27 | void target_init(void); |
28 | /* exit, performing the atexit action (default is target specific) */ | 28 | /* get descriptor, set buffer to NULL on error */ |
29 | void target_exit(void); | 29 | void target_get_desc(int desc, void **buffer); |
30 | /* get information, return actual size or -1 if error */ | 30 | /* pack all descriptors for config desc */ |
31 | int target_get_info(int info, void **buffer); | 31 | void target_get_config_desc(void *buffer, int *size); |
32 | /* set atexit action or return -1 on error */ | ||
33 | int target_atexit(int action); | ||
34 | /* Wait a very short time (us<=1000) */ | 32 | /* Wait a very short time (us<=1000) */ |
35 | void target_udelay(int us); | 33 | void target_udelay(int us); |
36 | /* Wait for a short time (ms <= 1000) */ | 34 | /* Wait for a short time (ms <= 1000) */ |
37 | void target_mdelay(int ms); | 35 | void target_mdelay(int ms); |
38 | 36 | ||
37 | /* mandatory for all targets */ | ||
38 | extern struct hwstub_target_desc_t target_descriptor; | ||
39 | |||
39 | #endif /* __TARGET_H__ */ | 40 | #endif /* __TARGET_H__ */ |
diff --git a/utils/hwstub/tools/hwstub_load.cpp b/utils/hwstub/tools/hwstub_load.cpp index 58c8ac726f..8782c158d7 100644 --- a/utils/hwstub/tools/hwstub_load.cpp +++ b/utils/hwstub/tools/hwstub_load.cpp | |||
@@ -121,7 +121,7 @@ void usage(void) | |||
121 | int main(int argc, char **argv) | 121 | int main(int argc, char **argv) |
122 | { | 122 | { |
123 | bool quiet = false; | 123 | bool quiet = false; |
124 | struct hwstub_device_t hwdev; | 124 | struct hwstub_device_t *hwdev; |
125 | enum image_type_t type = IT_DETECT; | 125 | enum image_type_t type = IT_DETECT; |
126 | 126 | ||
127 | // parse command line | 127 | // parse command line |
@@ -244,73 +244,52 @@ int main(int argc, char **argv) | |||
244 | libusb_get_bus_number(mydev), | 244 | libusb_get_bus_number(mydev), |
245 | libusb_get_device_address(mydev)); | 245 | libusb_get_device_address(mydev)); |
246 | } | 246 | } |
247 | hwdev.handle = handle; | 247 | hwdev = hwstub_open(handle); |
248 | if(hwstub_probe(&hwdev)) | 248 | if(hwdev == NULL) |
249 | { | 249 | { |
250 | fprintf(stderr, "Cannot probe device!\n"); | 250 | fprintf(stderr, "Cannot probe device!\n"); |
251 | return 1; | 251 | return 1; |
252 | } | 252 | } |
253 | 253 | ||
254 | // get hwstub information | 254 | // get hwstub information |
255 | struct usb_resp_info_version_t hwdev_ver; | 255 | struct hwstub_version_desc_t hwdev_ver; |
256 | int ret = hwstub_get_info(&hwdev, HWSTUB_INFO_VERSION, &hwdev_ver, sizeof(hwdev_ver)); | 256 | int ret = hwstub_get_desc(hwdev, HWSTUB_DT_VERSION, &hwdev_ver, sizeof(hwdev_ver)); |
257 | if(ret != sizeof(hwdev_ver)) | 257 | if(ret != sizeof(hwdev_ver)) |
258 | { | 258 | { |
259 | fprintf(stderr, "Cannot get version!\n"); | 259 | fprintf(stderr, "Cannot get version!\n"); |
260 | goto Lerr; | 260 | goto Lerr; |
261 | } | 261 | } |
262 | if(hwdev_ver.major != HWSTUB_VERSION_MAJOR || hwdev_ver.minor < HWSTUB_VERSION_MINOR) | 262 | if(hwdev_ver.bMajor != HWSTUB_VERSION_MAJOR || hwdev_ver.bMinor < HWSTUB_VERSION_MINOR) |
263 | { | 263 | { |
264 | printf("Warning: this tool is possibly incompatible with your device:\n"); | 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); | 265 | printf("Device version: %d.%d.%d\n", hwdev_ver.bMajor, hwdev_ver.bMinor, hwdev_ver.bRevision); |
266 | printf("Host version: %d.%d.%d\n", HWSTUB_VERSION_MAJOR, HWSTUB_VERSION_MINOR, HWSTUB_VERSION_REV); | 266 | printf("Host version: %d.%d.%d\n", HWSTUB_VERSION_MAJOR, HWSTUB_VERSION_MINOR, HWSTUB_VERSION_REV); |
267 | } | 267 | } |
268 | 268 | ||
269 | // get features | 269 | ret = hwstub_rw_mem(hwdev, 0, addr, buffer, size); |
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) | 270 | if(ret != (int)size) |
289 | { | 271 | { |
290 | fprintf(stderr, "Image write failed\n"); | 272 | fprintf(stderr, "Image write failed\n"); |
291 | goto Lerr; | 273 | goto Lerr; |
292 | } | 274 | } |
293 | hwstub_jump(&hwdev, addr); | 275 | hwstub_jump(hwdev, addr); |
294 | 276 | ||
295 | hwstub_release(&hwdev); | 277 | hwstub_release(hwdev); |
296 | return 0; | 278 | return 0; |
297 | 279 | ||
298 | Lerr: | 280 | Lerr: |
299 | // display log if handled | 281 | // display log if handled |
300 | if(hwdev_features.feature_mask & HWSTUB_FEATURE_LOG) | 282 | fprintf(stderr, "Device log:\n"); |
283 | do | ||
301 | { | 284 | { |
302 | fprintf(stderr, "Device log:\n"); | 285 | char buffer[128]; |
303 | do | 286 | int length = hwstub_get_log(hwdev, buffer, sizeof(buffer) - 1); |
304 | { | 287 | if(length <= 0) |
305 | char buffer[128]; | 288 | break; |
306 | int length = hwstub_get_log(&hwdev, buffer, sizeof(buffer) - 1); | 289 | buffer[length] = 0; |
307 | if(length <= 0) | 290 | fprintf(stderr, "%s", buffer); |
308 | break; | 291 | }while(1); |
309 | buffer[length] = 0; | 292 | hwstub_release(hwdev); |
310 | fprintf(stderr, "%s", buffer); | ||
311 | }while(1); | ||
312 | } | ||
313 | hwstub_release(&hwdev); | ||
314 | return 1; | 293 | return 1; |
315 | } | 294 | } |
316 | 295 | ||
diff --git a/utils/hwstub/tools/hwstub_shell.cpp b/utils/hwstub/tools/hwstub_shell.cpp index 2a3fc177ed..61cb617509 100644 --- a/utils/hwstub/tools/hwstub_shell.cpp +++ b/utils/hwstub/tools/hwstub_shell.cpp | |||
@@ -39,12 +39,11 @@ | |||
39 | */ | 39 | */ |
40 | bool g_quiet = false; | 40 | bool g_quiet = false; |
41 | bool g_exit = false; | 41 | bool g_exit = false; |
42 | struct hwstub_device_t g_hwdev; | 42 | struct hwstub_device_t *g_hwdev; |
43 | struct usb_resp_info_version_t g_hwdev_ver; | 43 | struct hwstub_version_desc_t g_hwdev_ver; |
44 | struct usb_resp_info_layout_t g_hwdev_layout; | 44 | struct hwstub_layout_desc_t g_hwdev_layout; |
45 | struct usb_resp_info_features_t g_hwdev_features; | 45 | struct hwstub_target_desc_t g_hwdev_target; |
46 | struct usb_resp_info_target_t g_hwdev_target; | 46 | struct hwstub_stmp_desc_t g_hwdev_stmp; |
47 | struct usb_resp_info_stmp_t g_hwdev_stmp; | ||
48 | lua_State *g_lua; | 47 | lua_State *g_lua; |
49 | 48 | ||
50 | /** | 49 | /** |
@@ -144,7 +143,7 @@ typedef void (*hw_writen_fn_t)(lua_State *state, soc_addr_t addr, soc_word_t val | |||
144 | soc_word_t hw_read8(lua_State *state, soc_addr_t addr) | 143 | soc_word_t hw_read8(lua_State *state, soc_addr_t addr) |
145 | { | 144 | { |
146 | uint8_t u; | 145 | uint8_t u; |
147 | if(hwstub_rw_mem(&g_hwdev, 1, addr, &u, sizeof(u)) != sizeof(u)) | 146 | if(hwstub_rw_mem(g_hwdev, 1, addr, &u, sizeof(u)) != sizeof(u)) |
148 | luaL_error(state, "fail to read8 @ %p", addr); | 147 | luaL_error(state, "fail to read8 @ %p", addr); |
149 | return u; | 148 | return u; |
150 | } | 149 | } |
@@ -152,7 +151,7 @@ soc_word_t hw_read8(lua_State *state, soc_addr_t addr) | |||
152 | soc_word_t hw_read16(lua_State *state, soc_addr_t addr) | 151 | soc_word_t hw_read16(lua_State *state, soc_addr_t addr) |
153 | { | 152 | { |
154 | uint16_t u; | 153 | uint16_t u; |
155 | if(hwstub_rw_mem(&g_hwdev, 1, addr, &u, sizeof(u)) != sizeof(u)) | 154 | if(hwstub_rw_mem(g_hwdev, 1, addr, &u, sizeof(u)) != sizeof(u)) |
156 | luaL_error(state, "fail to read16 @ %p", addr); | 155 | luaL_error(state, "fail to read16 @ %p", addr); |
157 | return u; | 156 | return u; |
158 | } | 157 | } |
@@ -160,7 +159,7 @@ soc_word_t hw_read16(lua_State *state, soc_addr_t addr) | |||
160 | soc_word_t hw_read32(lua_State *state, soc_addr_t addr) | 159 | soc_word_t hw_read32(lua_State *state, soc_addr_t addr) |
161 | { | 160 | { |
162 | uint32_t u; | 161 | uint32_t u; |
163 | if(hwstub_rw_mem(&g_hwdev, 1, addr, &u, sizeof(u)) != sizeof(u)) | 162 | if(hwstub_rw_mem(g_hwdev, 1, addr, &u, sizeof(u)) != sizeof(u)) |
164 | luaL_error(state, "fail to read32 @ %p", addr); | 163 | luaL_error(state, "fail to read32 @ %p", addr); |
165 | return u; | 164 | return u; |
166 | } | 165 | } |
@@ -168,21 +167,21 @@ soc_word_t hw_read32(lua_State *state, soc_addr_t addr) | |||
168 | void hw_write8(lua_State *state, soc_addr_t addr, soc_word_t val) | 167 | void hw_write8(lua_State *state, soc_addr_t addr, soc_word_t val) |
169 | { | 168 | { |
170 | uint8_t u = val; | 169 | uint8_t u = val; |
171 | if(hwstub_rw_mem(&g_hwdev, 0, addr, &u, sizeof(u)) != sizeof(u)) | 170 | if(hwstub_rw_mem(g_hwdev, 0, addr, &u, sizeof(u)) != sizeof(u)) |
172 | luaL_error(state, "fail to write8 @ %p", addr); | 171 | luaL_error(state, "fail to write8 @ %p", addr); |
173 | } | 172 | } |
174 | 173 | ||
175 | void hw_write16(lua_State *state, soc_addr_t addr, soc_word_t val) | 174 | void hw_write16(lua_State *state, soc_addr_t addr, soc_word_t val) |
176 | { | 175 | { |
177 | uint16_t u = val; | 176 | uint16_t u = val; |
178 | if(hwstub_rw_mem(&g_hwdev, 0, addr, &u, sizeof(u)) != sizeof(u)) | 177 | if(hwstub_rw_mem(g_hwdev, 0, addr, &u, sizeof(u)) != sizeof(u)) |
179 | luaL_error(state, "fail to write16 @ %p", addr); | 178 | luaL_error(state, "fail to write16 @ %p", addr); |
180 | } | 179 | } |
181 | 180 | ||
182 | void hw_write32(lua_State *state, soc_addr_t addr, soc_word_t val) | 181 | void hw_write32(lua_State *state, soc_addr_t addr, soc_word_t val) |
183 | { | 182 | { |
184 | uint32_t u = val; | 183 | uint32_t u = val; |
185 | if(hwstub_rw_mem(&g_hwdev, 0, addr, &u, sizeof(u)) != sizeof(u)) | 184 | if(hwstub_rw_mem(g_hwdev, 0, addr, &u, sizeof(u)) != sizeof(u)) |
186 | luaL_error(state, "fail to write32 @ %p", addr); | 185 | luaL_error(state, "fail to write32 @ %p", addr); |
187 | } | 186 | } |
188 | 187 | ||
@@ -208,34 +207,7 @@ int my_lua_writen(lua_State *state) | |||
208 | 207 | ||
209 | int my_lua_printlog(lua_State *state) | 208 | int my_lua_printlog(lua_State *state) |
210 | { | 209 | { |
211 | print_log(&g_hwdev); | 210 | print_log(g_hwdev); |
212 | return 0; | ||
213 | } | ||
214 | |||
215 | int my_lua_atexit(lua_State *state) | ||
216 | { | ||
217 | int n = lua_gettop(state); | ||
218 | if(n != 1) | ||
219 | luaL_error(state, "atexit takes one argument"); | ||
220 | const char *arg = luaL_checkstring(state, 1); | ||
221 | int ret = -1; | ||
222 | if(strcmp(arg, "nop") == 0) | ||
223 | ret = hwstub_atexit(&g_hwdev, HWSTUB_ATEXIT_NOP); | ||
224 | else if(strcmp(arg, "reboot") == 0) | ||
225 | ret = hwstub_atexit(&g_hwdev, HWSTUB_ATEXIT_REBOOT); | ||
226 | else if(strcmp(arg, "off") == 0) | ||
227 | ret = hwstub_atexit(&g_hwdev, HWSTUB_ATEXIT_OFF); | ||
228 | else | ||
229 | luaL_error(state, "unknown atexit method '%s'", arg); | ||
230 | if(ret < 0) | ||
231 | luaL_error(state, "fail to set atexit method"); | ||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | int my_lua_exit(lua_State *state) | ||
236 | { | ||
237 | if(hwstub_exit(&g_hwdev) < 0) | ||
238 | luaL_error(state, "fail to exit hwstub"); | ||
239 | return 0; | 211 | return 0; |
240 | } | 212 | } |
241 | 213 | ||
@@ -268,69 +240,60 @@ bool my_lua_import_hwstub() | |||
268 | 240 | ||
269 | lua_newtable(g_lua); // dev | 241 | lua_newtable(g_lua); // dev |
270 | lua_newtable(g_lua); // version | 242 | lua_newtable(g_lua); // version |
271 | lua_pushinteger(g_lua, g_hwdev_ver.major); | 243 | lua_pushinteger(g_lua, g_hwdev_ver.bMajor); |
272 | lua_setfield(g_lua, -2, "major"); | 244 | lua_setfield(g_lua, -2, "major"); |
273 | lua_pushinteger(g_lua, g_hwdev_ver.minor); | 245 | lua_pushinteger(g_lua, g_hwdev_ver.bMinor); |
274 | lua_setfield(g_lua, -2, "minor"); | 246 | lua_setfield(g_lua, -2, "minor"); |
275 | lua_pushinteger(g_lua, g_hwdev_ver.revision); | 247 | lua_pushinteger(g_lua, g_hwdev_ver.bRevision); |
276 | lua_setfield(g_lua, -2, "revision"); | 248 | lua_setfield(g_lua, -2, "revision"); |
277 | lua_setfield(g_lua, -2, "version"); | 249 | lua_setfield(g_lua, -2, "version"); |
278 | 250 | ||
279 | lua_newtable(g_lua); // layout | 251 | lua_newtable(g_lua); // layout |
280 | lua_newtable(g_lua); // ocram | ||
281 | lua_newtable(g_lua); // code | 252 | lua_newtable(g_lua); // code |
282 | lua_pushinteger(g_lua, g_hwdev_layout.oc_code_start); | 253 | lua_pushinteger(g_lua, g_hwdev_layout.dCodeStart); |
283 | lua_setfield(g_lua, -2, "start"); | 254 | lua_setfield(g_lua, -2, "start"); |
284 | lua_pushinteger(g_lua, g_hwdev_layout.oc_code_size); | 255 | lua_pushinteger(g_lua, g_hwdev_layout.dCodeSize); |
285 | lua_setfield(g_lua, -2, "size"); | 256 | lua_setfield(g_lua, -2, "size"); |
286 | lua_setfield(g_lua, -2, "code"); | 257 | lua_setfield(g_lua, -2, "code"); |
287 | lua_newtable(g_lua); // stack | 258 | lua_newtable(g_lua); // stack |
288 | lua_pushinteger(g_lua, g_hwdev_layout.oc_stack_start); | 259 | lua_pushinteger(g_lua, g_hwdev_layout.dStackStart); |
289 | lua_setfield(g_lua, -2, "start"); | 260 | lua_setfield(g_lua, -2, "start"); |
290 | lua_pushinteger(g_lua, g_hwdev_layout.oc_stack_size); | 261 | lua_pushinteger(g_lua, g_hwdev_layout.dStackSize); |
291 | lua_setfield(g_lua, -2, "size"); | 262 | lua_setfield(g_lua, -2, "size"); |
292 | lua_setfield(g_lua, -2, "stack"); | 263 | lua_setfield(g_lua, -2, "stack"); |
293 | lua_newtable(g_lua); // buffer | 264 | lua_newtable(g_lua); // buffer |
294 | lua_pushinteger(g_lua, g_hwdev_layout.oc_buffer_start); | 265 | lua_pushinteger(g_lua, g_hwdev_layout.dBufferStart); |
295 | lua_setfield(g_lua, -2, "start"); | 266 | lua_setfield(g_lua, -2, "start"); |
296 | lua_pushinteger(g_lua, g_hwdev_layout.oc_buffer_size); | 267 | lua_pushinteger(g_lua, g_hwdev_layout.dBufferSize); |
297 | lua_setfield(g_lua, -2, "size"); | 268 | lua_setfield(g_lua, -2, "size"); |
298 | lua_setfield(g_lua, -2, "buffer"); | 269 | lua_setfield(g_lua, -2, "buffer"); |
299 | lua_setfield(g_lua, -2, "ocram"); | ||
300 | lua_setfield(g_lua, -2, "layout"); | 270 | lua_setfield(g_lua, -2, "layout"); |
301 | 271 | ||
302 | lua_newtable(g_lua); // target | 272 | lua_newtable(g_lua); // target |
303 | lua_pushstring(g_lua, g_hwdev_target.name); | 273 | lua_pushstring(g_lua, g_hwdev_target.bName); |
304 | lua_setfield(g_lua, -2, "name"); | 274 | lua_setfield(g_lua, -2, "name"); |
305 | lua_pushinteger(g_lua, g_hwdev_target.id); | 275 | lua_pushinteger(g_lua, g_hwdev_target.dID); |
306 | lua_setfield(g_lua, -2, "id"); | 276 | lua_setfield(g_lua, -2, "id"); |
307 | lua_pushinteger(g_lua, HWSTUB_TARGET_UNK); | 277 | lua_pushinteger(g_lua, HWSTUB_TARGET_UNK); |
308 | lua_setfield(g_lua, -2, "UNK"); | 278 | lua_setfield(g_lua, -2, "UNK"); |
309 | lua_pushinteger(g_lua, HWSTUB_TARGET_STMP); | 279 | lua_pushinteger(g_lua, HWSTUB_TARGET_STMP); |
310 | lua_setfield(g_lua, -2, "STMP"); | 280 | lua_setfield(g_lua, -2, "STMP"); |
281 | lua_pushinteger(g_lua, HWSTUB_TARGET_RK27); | ||
282 | lua_setfield(g_lua, -2, "RK27"); | ||
311 | lua_setfield(g_lua, -2, "target"); | 283 | lua_setfield(g_lua, -2, "target"); |
312 | 284 | ||
313 | if(g_hwdev_target.id == HWSTUB_TARGET_STMP) | 285 | if(g_hwdev_target.dID == HWSTUB_TARGET_STMP) |
314 | { | 286 | { |
315 | lua_newtable(g_lua); // stmp | 287 | lua_newtable(g_lua); // stmp |
316 | lua_pushinteger(g_lua, g_hwdev_stmp.chipid); | 288 | lua_pushinteger(g_lua, g_hwdev_stmp.wChipID); |
317 | lua_setfield(g_lua, -2, "chipid"); | 289 | lua_setfield(g_lua, -2, "chipid"); |
318 | lua_pushinteger(g_lua, g_hwdev_stmp.rev); | 290 | lua_pushinteger(g_lua, g_hwdev_stmp.bRevision); |
319 | lua_setfield(g_lua, -2, "rev"); | 291 | lua_setfield(g_lua, -2, "rev"); |
292 | lua_pushinteger(g_lua, g_hwdev_stmp.bPackage); | ||
293 | lua_setfield(g_lua, -2, "package"); | ||
320 | lua_setfield(g_lua, -2, "stmp"); | 294 | lua_setfield(g_lua, -2, "stmp"); |
321 | } | 295 | } |
322 | 296 | ||
323 | lua_newtable(g_lua); // features | ||
324 | lua_pushboolean(g_lua, !!(g_hwdev_features.feature_mask & HWSTUB_FEATURE_LOG)); | ||
325 | lua_setfield(g_lua, -2, "log"); | ||
326 | lua_pushboolean(g_lua, !!(g_hwdev_features.feature_mask & HWSTUB_FEATURE_MEM)); | ||
327 | lua_setfield(g_lua, -2, "mem"); | ||
328 | lua_pushboolean(g_lua, !!(g_hwdev_features.feature_mask & HWSTUB_FEATURE_CALL)); | ||
329 | lua_setfield(g_lua, -2, "call"); | ||
330 | lua_pushboolean(g_lua, !!(g_hwdev_features.feature_mask & HWSTUB_FEATURE_JUMP)); | ||
331 | lua_setfield(g_lua, -2, "jump"); | ||
332 | lua_setfield(g_lua, -2, "features"); | ||
333 | |||
334 | lua_pushlightuserdata(g_lua, (void *)&hw_read8); | 297 | lua_pushlightuserdata(g_lua, (void *)&hw_read8); |
335 | lua_pushcclosure(g_lua, my_lua_readn, 1); | 298 | lua_pushcclosure(g_lua, my_lua_readn, 1); |
336 | lua_setfield(g_lua, -2, "read8"); | 299 | lua_setfield(g_lua, -2, "read8"); |
@@ -352,10 +315,6 @@ bool my_lua_import_hwstub() | |||
352 | lua_setfield(g_lua, -2, "write32"); | 315 | lua_setfield(g_lua, -2, "write32"); |
353 | lua_pushcclosure(g_lua, my_lua_printlog, 0); | 316 | lua_pushcclosure(g_lua, my_lua_printlog, 0); |
354 | lua_setfield(g_lua, -2, "print_log"); | 317 | lua_setfield(g_lua, -2, "print_log"); |
355 | lua_pushcclosure(g_lua, my_lua_atexit, 0); | ||
356 | lua_setfield(g_lua, -2, "atexit"); | ||
357 | lua_pushcclosure(g_lua, my_lua_exit, 0); | ||
358 | lua_setfield(g_lua, -2, "exit"); | ||
359 | 318 | ||
360 | lua_setfield(g_lua, -2, "dev"); | 319 | lua_setfield(g_lua, -2, "dev"); |
361 | 320 | ||
@@ -404,7 +363,7 @@ bool my_lua_import_hwstub() | |||
404 | 363 | ||
405 | if(lua_gettop(g_lua) != oldtop) | 364 | if(lua_gettop(g_lua) != oldtop) |
406 | { | 365 | { |
407 | printf("internal error: unbalanced my_lua_import_soc"); | 366 | printf("internal error: unbalanced my_lua_import_soc\n"); |
408 | return false; | 367 | return false; |
409 | } | 368 | } |
410 | return true; | 369 | return true; |
@@ -785,45 +744,37 @@ int main(int argc, char **argv) | |||
785 | libusb_get_bus_number(mydev), | 744 | libusb_get_bus_number(mydev), |
786 | libusb_get_device_address(mydev)); | 745 | libusb_get_device_address(mydev)); |
787 | } | 746 | } |
788 | g_hwdev.handle = handle; | 747 | g_hwdev = hwstub_open(handle); |
789 | if(hwstub_probe(&g_hwdev)) | 748 | if(g_hwdev == NULL) |
790 | { | 749 | { |
791 | printf("Cannot probe device!\n"); | 750 | printf("Cannot open device!\n"); |
792 | return 1; | 751 | return 1; |
793 | } | 752 | } |
794 | 753 | ||
795 | // get hwstub information | 754 | // get hwstub information |
796 | int ret = hwstub_get_info(&g_hwdev, HWSTUB_INFO_VERSION, &g_hwdev_ver, sizeof(g_hwdev_ver)); | 755 | int ret = hwstub_get_desc(g_hwdev, HWSTUB_DT_VERSION, &g_hwdev_ver, sizeof(g_hwdev_ver)); |
797 | if(ret != sizeof(g_hwdev_ver)) | 756 | if(ret != sizeof(g_hwdev_ver)) |
798 | { | 757 | { |
799 | printf("Cannot get version!\n"); | 758 | printf("Cannot get version!\n"); |
800 | goto Lerr; | 759 | goto Lerr; |
801 | } | 760 | } |
802 | if(g_hwdev_ver.major != HWSTUB_VERSION_MAJOR || g_hwdev_ver.minor < HWSTUB_VERSION_MINOR) | 761 | if(g_hwdev_ver.bMajor != HWSTUB_VERSION_MAJOR || g_hwdev_ver.bMinor < HWSTUB_VERSION_MINOR) |
803 | { | 762 | { |
804 | printf("Warning: this tool is possibly incompatible with your device:\n"); | 763 | printf("Warning: this tool is possibly incompatible with your device:\n"); |
805 | printf("Device version: %d.%d.%d\n", g_hwdev_ver.major, g_hwdev_ver.minor, g_hwdev_ver.revision); | 764 | printf("Device version: %d.%d.%d\n", g_hwdev_ver.bMajor, g_hwdev_ver.bMinor, g_hwdev_ver.bRevision); |
806 | printf("Host version: %d.%d.%d\n", HWSTUB_VERSION_MAJOR, HWSTUB_VERSION_MINOR, HWSTUB_VERSION_REV); | 765 | printf("Host version: %d.%d.%d\n", HWSTUB_VERSION_MAJOR, HWSTUB_VERSION_MINOR, HWSTUB_VERSION_REV); |
807 | } | 766 | } |
808 | 767 | ||
809 | // get memory layout information | 768 | // get memory layout information |
810 | ret = hwstub_get_info(&g_hwdev, HWSTUB_INFO_LAYOUT, &g_hwdev_layout, sizeof(g_hwdev_layout)); | 769 | ret = hwstub_get_desc(g_hwdev, HWSTUB_DT_LAYOUT, &g_hwdev_layout, sizeof(g_hwdev_layout)); |
811 | if(ret != sizeof(g_hwdev_layout)) | 770 | if(ret != sizeof(g_hwdev_layout)) |
812 | { | 771 | { |
813 | printf("Cannot get layout: %d\n", ret); | 772 | printf("Cannot get layout: %d\n", ret); |
814 | goto Lerr; | 773 | goto Lerr; |
815 | } | 774 | } |
816 | 775 | ||
817 | // get features | ||
818 | ret = hwstub_get_info(&g_hwdev, HWSTUB_INFO_FEATURES, &g_hwdev_features, sizeof(g_hwdev_features)); | ||
819 | if(ret != sizeof(g_hwdev_features)) | ||
820 | { | ||
821 | printf("Cannot get features: %d\n", ret); | ||
822 | goto Lerr; | ||
823 | } | ||
824 | |||
825 | // get target | 776 | // get target |
826 | ret = hwstub_get_info(&g_hwdev, HWSTUB_INFO_TARGET, &g_hwdev_target, sizeof(g_hwdev_target)); | 777 | ret = hwstub_get_desc(g_hwdev, HWSTUB_DT_TARGET, &g_hwdev_target, sizeof(g_hwdev_target)); |
827 | if(ret != sizeof(g_hwdev_target)) | 778 | if(ret != sizeof(g_hwdev_target)) |
828 | { | 779 | { |
829 | printf("Cannot get target: %d\n", ret); | 780 | printf("Cannot get target: %d\n", ret); |
@@ -831,9 +782,9 @@ int main(int argc, char **argv) | |||
831 | } | 782 | } |
832 | 783 | ||
833 | // get STMP specific information | 784 | // get STMP specific information |
834 | if(g_hwdev_target.id == HWSTUB_TARGET_STMP) | 785 | if(g_hwdev_target.dID == HWSTUB_TARGET_STMP) |
835 | { | 786 | { |
836 | ret = hwstub_get_info(&g_hwdev, HWSTUB_INFO_STMP, &g_hwdev_stmp, sizeof(g_hwdev_stmp)); | 787 | ret = hwstub_get_desc(g_hwdev, HWSTUB_DT_STMP, &g_hwdev_stmp, sizeof(g_hwdev_stmp)); |
837 | if(ret != sizeof(g_hwdev_stmp)) | 788 | if(ret != sizeof(g_hwdev_stmp)) |
838 | { | 789 | { |
839 | printf("Cannot get stmp: %d\n", ret); | 790 | printf("Cannot get stmp: %d\n", ret); |
@@ -884,12 +835,9 @@ int main(int argc, char **argv) | |||
884 | 835 | ||
885 | Lerr: | 836 | Lerr: |
886 | // display log if handled | 837 | // display log if handled |
887 | if(g_hwdev_features.feature_mask & HWSTUB_FEATURE_LOG) | 838 | if(!g_quiet) |
888 | { | 839 | printf("Device log:\n"); |
889 | if(!g_quiet) | 840 | print_log(g_hwdev); |
890 | printf("Device log:\n"); | 841 | hwstub_release(g_hwdev); |
891 | print_log(&g_hwdev); | ||
892 | } | ||
893 | hwstub_release(&g_hwdev); | ||
894 | return 1; | 842 | return 1; |
895 | } | 843 | } |
diff --git a/utils/hwstub/tools/init.lua b/utils/hwstub/tools/init.lua index 4c62de007f..3c60abf806 100644 --- a/utils/hwstub/tools/init.lua +++ b/utils/hwstub/tools/init.lua | |||
@@ -79,18 +79,12 @@ if not hwstub.options.quiet then | |||
79 | print(" id: " .. string.format("%#x (%s)", hwstub.dev.target.id, id_str)) | 79 | print(" id: " .. string.format("%#x (%s)", hwstub.dev.target.id, id_str)) |
80 | print(" name: " .. hwstub.dev.target.name) | 80 | print(" name: " .. hwstub.dev.target.name) |
81 | print(" layout") | 81 | print(" layout") |
82 | print(" on-chip ram") | 82 | print(" code: " .. string.format("%#x bytes @ %#x", |
83 | print(" code: " .. string.format("%#x bytes @ %#x", | 83 | hwstub.dev.layout.code.size, hwstub.dev.layout.code.start)) |
84 | hwstub.dev.layout.ocram.code.size, hwstub.dev.layout.ocram.code.start)) | 84 | print(" stack: " .. string.format("%#x bytes @ %#x", |
85 | print(" stack: " .. string.format("%#x bytes @ %#x", | 85 | hwstub.dev.layout.stack.size, hwstub.dev.layout.stack.start)) |
86 | hwstub.dev.layout.ocram.stack.size, hwstub.dev.layout.ocram.stack.start)) | 86 | print(" buffer: " .. string.format("%#x bytes @ %#x", |
87 | print(" buffer: " .. string.format("%#x bytes @ %#x", | 87 | hwstub.dev.layout.buffer.size, hwstub.dev.layout.buffer.start)) |
88 | hwstub.dev.layout.ocram.buffer.size, hwstub.dev.layout.ocram.buffer.start)) | ||
89 | print(" features"); | ||
90 | print(" log: " .. tostring(hwstub.dev.features.log)) | ||
91 | print(" mem: " .. tostring(hwstub.dev.features.mem)) | ||
92 | print(" call: " .. tostring(hwstub.dev.features.call)) | ||
93 | print(" jump: " .. tostring(hwstub.dev.features.jump)) | ||
94 | end | 88 | end |
95 | 89 | ||
96 | -- | 90 | -- |