freemyipod r949 - Code Review

Jump to: navigation, search
Repository:freemyipod
Revision:r948‎ | r949 | r950 >
Date:04:28, 16 June 2014
Author:theseven
Status:new
Tags:
Comment:
emCORE: Add bulk transfers to USB debugger for better performance
Modified paths:
  • /emcore/trunk/tools/libemcore.py (modified) (history)
  • /emcore/trunk/tools/libemcoredata.py (modified) (history)
  • /emcore/trunk/usb/usb.h (modified) (history)
  • /emcore/trunk/usb/usbdebug.c (modified) (history)
  • /emcore/trunk/usb/usbdebug.h (modified) (history)
  • /emcore/trunk/usb/usbglue.c (modified) (history)

Diff [purge]

Index: emcore/trunk/usb/usbdebug.h
@@ -29,17 +29,22 @@
3030 #include "usb.h"
3131
3232
33 -void usbdebug_enable(const struct usb_instance* data, int interface, int altsetting);
34 -void usbdebug_disable(const struct usb_instance* data, int interface, int altsetting);
35 -int usbdebug_handle_setup(const struct usb_instance* data, int interface, union usb_ep0_buffer* request, const void** response);
36 -void dbgconsole_putc(char string) ICODE_ATTR;
37 -void dbgconsole_puts(const char* string) ICODE_ATTR;
38 -void dbgconsole_write(const char* string, size_t length) ICODE_ATTR;
39 -void dbgconsole_sputc(char string) ICODE_ATTR;
40 -void dbgconsole_sputs(const char* string) ICODE_ATTR;
41 -void dbgconsole_swrite(const char* string, size_t length) ICODE_ATTR;
42 -int dbgconsole_getc(int timeout) ICODE_ATTR;
43 -int dbgconsole_read(char* string, size_t length, int timeout) ICODE_ATTR;
 33+extern void usbdebug_enable(const struct usb_instance* data, int interface, int altsetting);
 34+extern void usbdebug_disable(const struct usb_instance* data, int interface, int altsetting);
 35+extern void usbdebug_bulk_enable(const struct usb_instance* data, int interface, int altsetting);
 36+extern void usbdebug_bulk_disable(const struct usb_instance* data, int interface, int altsetting);
 37+extern int usbdebug_handle_setup(const struct usb_instance* data, int interface, union usb_ep0_buffer* request, const void** response);
 38+extern void usbdebug_bulk_xfer_complete(const struct usb_instance* data, int interface, int endpoint, int bytesleft);
 39+extern int usbdebug_bulk_ctrl_request(const struct usb_instance* data, int interface, int endpoint, union usb_ep0_buffer* request, const void** response);
 40+extern void usbdebug_bus_reset(const struct usb_instance* data, int highspeed);
 41+extern void dbgconsole_putc(char string) ICODE_ATTR;
 42+extern void dbgconsole_puts(const char* string) ICODE_ATTR;
 43+extern void dbgconsole_write(const char* string, size_t length) ICODE_ATTR;
 44+extern void dbgconsole_sputc(char string) ICODE_ATTR;
 45+extern void dbgconsole_sputs(const char* string) ICODE_ATTR;
 46+extern void dbgconsole_swrite(const char* string, size_t length) ICODE_ATTR;
 47+extern int dbgconsole_getc(int timeout) ICODE_ATTR;
 48+extern int dbgconsole_read(char* string, size_t length, int timeout) ICODE_ATTR;
4449
4550
4651 #endif
Index: emcore/trunk/usb/usbglue.c
@@ -25,10 +25,12 @@
2626 .bNumConfigurations = 1,
2727 };
2828
29 -static const struct __attribute__((packed)) _usb_config1_descriptors
 29+static struct __attribute__((packed)) _usb_config1_descriptors
3030 {
3131 struct usb_configurationdescriptor c1;
3232 struct usb_interfacedescriptor c1_i0_a0;
 33+ struct usb_endpointdescriptor c1_i0_a0_e1out;
 34+ struct usb_endpointdescriptor c1_i0_a0_e1in;
3335 } usb_config1_descriptors =
3436 {
3537 .c1 =
@@ -48,14 +50,45 @@
4951 .bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE,
5052 .bInterfaceNumber = 0,
5153 .bAlternateSetting = 0,
52 - .bNumEndpoints = 0,
 54+ .bNumEndpoints = 2,
5355 .bInterfaceClass = 0xff,
5456 .bInterfaceSubClass = 0x00,
5557 .bInterfaceProtocol = 0x00,
5658 .iInterface = 0,
5759 },
 60+ .c1_i0_a0_e1out =
 61+ {
 62+ .bLength = sizeof(struct usb_endpointdescriptor),
 63+ .bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT,
 64+ .bEndpointAddress = { .number = USBDEBUG_ENDPOINT_OUT, .direction = USB_ENDPOINT_DIRECTION_OUT },
 65+ .bmAttributes = { .type = USB_ENDPOINT_ATTRIBUTE_TYPE_BULK },
 66+ .wMaxPacketSize = 512,
 67+ .bInterval = 1,
 68+ },
 69+ .c1_i0_a0_e1in =
 70+ {
 71+ .bLength = sizeof(struct usb_endpointdescriptor),
 72+ .bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT,
 73+ .bEndpointAddress = { .number = USBDEBUG_ENDPOINT_IN, .direction = USB_ENDPOINT_DIRECTION_IN },
 74+ .bmAttributes = { .type = USB_ENDPOINT_ATTRIBUTE_TYPE_BULK },
 75+ .wMaxPacketSize = 512,
 76+ .bInterval = 1,
 77+ },
5878 };
5979
 80+static const struct usb_interfacedescriptor usb_simpledebug_intf_desc =
 81+{
 82+ .bLength = sizeof(struct usb_interfacedescriptor),
 83+ .bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE,
 84+ .bInterfaceNumber = 0,
 85+ .bAlternateSetting = 0,
 86+ .bNumEndpoints = 0,
 87+ .bInterfaceClass = 0xff,
 88+ .bInterfaceSubClass = 0x00,
 89+ .bInterfaceProtocol = 0x00,
 90+ .iInterface = 0,
 91+};
 92+
6093 static const struct usb_stringdescriptor usb_string_language =
6194 {
6295 .bLength = sizeof(usb_string_language) + sizeof(*usb_string_language.wString),
@@ -84,8 +117,53 @@
85118 &usb_string_product,
86119 };
87120
 121+static const struct usb_endpoint usb_c1_i0_a0_ep1out =
 122+{
 123+ .number = { .number = USBDEBUG_ENDPOINT_OUT, .direction = USB_ENDPOINT_DIRECTION_OUT },
 124+ .ctrl_request = usbdebug_bulk_ctrl_request,
 125+ .xfer_complete = usbdebug_bulk_xfer_complete,
 126+ .setup_received = NULL,
 127+};
 128+
 129+static const struct usb_endpoint usb_c1_i0_a0_ep1in =
 130+{
 131+ .number = { .number = USBDEBUG_ENDPOINT_IN, .direction = USB_ENDPOINT_DIRECTION_IN },
 132+ .ctrl_request = usbdebug_bulk_ctrl_request,
 133+ .xfer_complete = usbdebug_bulk_xfer_complete,
 134+ .timeout = NULL,
 135+};
 136+
88137 static const struct usb_altsetting usb_c1_i0_a0 =
89138 {
 139+ .set_altsetting = usbdebug_bulk_enable,
 140+ .unset_altsetting = usbdebug_bulk_disable,
 141+ .endpoint_count = 2,
 142+ .endpoints =
 143+ {
 144+ &usb_c1_i0_a0_ep1out,
 145+ &usb_c1_i0_a0_ep1in,
 146+ },
 147+};
 148+
 149+static void usbglue_bus_reset(const struct usb_instance* data, int highspeed)
 150+{
 151+ usb_config1_descriptors.c1_i0_a0_e1out.wMaxPacketSize = highspeed ? 512 : 64;
 152+ usb_config1_descriptors.c1_i0_a0_e1in.wMaxPacketSize = highspeed ? 512 : 64;
 153+}
 154+
 155+static struct usb_interface usb_c1_i0 =
 156+{
 157+ .bus_reset = usbdebug_bus_reset,
 158+ .ctrl_request = usbdebug_handle_setup,
 159+ .altsetting_count = 1,
 160+ .altsettings =
 161+ {
 162+ &usb_c1_i0_a0,
 163+ },
 164+};
 165+
 166+static const struct usb_altsetting usb_simpledebug_intf_a0 =
 167+{
90168 .set_altsetting = usbdebug_enable,
91169 .unset_altsetting = usbdebug_disable,
92170 .endpoint_count = 0,
@@ -94,7 +172,7 @@
95173 },
96174 };
97175
98 -static struct usb_interface usb_c1_i0 =
 176+static struct usb_interface usb_simpledebug_intf =
99177 {
100178 .bus_reset = NULL,
101179 .ctrl_request = usbdebug_handle_setup,
@@ -101,7 +179,7 @@
102180 .altsetting_count = 1,
103181 .altsettings =
104182 {
105 - &usb_c1_i0_a0,
 183+ &usb_simpledebug_intf_a0,
106184 },
107185 };
108186
@@ -136,7 +214,7 @@
137215 .driver_state = &usb_driver_state,
138216 .state = &usb_state,
139217 .buffer = &usb_buffer,
140 - .bus_reset = NULL,
 218+ .bus_reset = usbglue_bus_reset,
141219 .ep0_setup_hook = NULL,
142220 .configuration_count = 1,
143221 .stringdescriptor_count = 3,
@@ -275,9 +353,9 @@
276354 {
277355 struct usb_interfacedescriptor* intfdescriptor = (struct usb_interfacedescriptor*)descbuf;
278356 descbuf += sizeof(struct usb_interfacedescriptor);
279 - memcpy(intfdescriptor, &usb_config1_descriptors.c1_i0_a0, sizeof(struct usb_interfacedescriptor));
 357+ memcpy(intfdescriptor, &usb_simpledebug_intf_desc, sizeof(struct usb_interfacedescriptor));
280358 intfdescriptor->bInterfaceNumber = j;
281 - config->interfaces[j] = &usb_c1_i0;
 359+ config->interfaces[j] = &usb_simpledebug_intf;
282360 config->interface_count++;
283361 cfgdescriptor->wTotalLength += sizeof(struct usb_interfacedescriptor);
284362 cfgdescriptor->bNumInterfaces++;
Index: emcore/trunk/usb/usb.h
@@ -3,6 +3,75 @@
44
55 #include "../global.h"
66
 7+#ifndef IN_APPLICATION_CODE
 8+#if USB_ENDPOINTS & 0b00000000000000000000000000000010
 9+#define USBDEBUG_ENDPOINT_OUT 1
 10+#elif USB_ENDPOINTS & 0b00000000000000000000000000000010
 11+#define USBDEBUG_ENDPOINT_OUT 2
 12+#elif USB_ENDPOINTS & 0b00000000000000000000000000000100
 13+#define USBDEBUG_ENDPOINT_OUT 3
 14+#elif USB_ENDPOINTS & 0b00000000000000000000000000001000
 15+#define USBDEBUG_ENDPOINT_OUT 4
 16+#elif USB_ENDPOINTS & 0b00000000000000000000000000010000
 17+#define USBDEBUG_ENDPOINT_OUT 5
 18+#elif USB_ENDPOINTS & 0b00000000000000000000000000100000
 19+#define USBDEBUG_ENDPOINT_OUT 6
 20+#elif USB_ENDPOINTS & 0b00000000000000000000000001000000
 21+#define USBDEBUG_ENDPOINT_OUT 7
 22+#elif USB_ENDPOINTS & 0b00000000000000000000000010000000
 23+#define USBDEBUG_ENDPOINT_OUT 8
 24+#elif USB_ENDPOINTS & 0b00000000000000000000001000000000
 25+#define USBDEBUG_ENDPOINT_OUT 9
 26+#elif USB_ENDPOINTS & 0b00000000000000000000010000000000
 27+#define USBDEBUG_ENDPOINT_OUT 10
 28+#elif USB_ENDPOINTS & 0b00000000000000000000100000000000
 29+#define USBDEBUG_ENDPOINT_OUT 11
 30+#elif USB_ENDPOINTS & 0b00000000000000000001000000000000
 31+#define USBDEBUG_ENDPOINT_OUT 12
 32+#elif USB_ENDPOINTS & 0b00000000000000000010000000000000
 33+#define USBDEBUG_ENDPOINT_OUT 13
 34+#elif USB_ENDPOINTS & 0b00000000000000000100000000000000
 35+#define USBDEBUG_ENDPOINT_OUT 14
 36+#elif USB_ENDPOINTS & 0b00000000000000001000000000000000
 37+#define USBDEBUG_ENDPOINT_OUT 15
 38+#else
 39+#error USBDEBUG: No OUT endpoints available!
 40+#endif
 41+#if USB_ENDPOINTS & 0b00000000000000100000000000000000
 42+#define USBDEBUG_ENDPOINT_IN 1
 43+#elif USB_ENDPOINTS & 0b00000000000000100000000000000000
 44+#define USBDEBUG_ENDPOINT_IN 2
 45+#elif USB_ENDPOINTS & 0b00000000000001000000000000000000
 46+#define USBDEBUG_ENDPOINT_IN 3
 47+#elif USB_ENDPOINTS & 0b00000000000010000000000000000000
 48+#define USBDEBUG_ENDPOINT_IN 4
 49+#elif USB_ENDPOINTS & 0b00000000000100000000000000000000
 50+#define USBDEBUG_ENDPOINT_IN 5
 51+#elif USB_ENDPOINTS & 0b00000000001000000000000000000000
 52+#define USBDEBUG_ENDPOINT_IN 6
 53+#elif USB_ENDPOINTS & 0b00000000010000000000000000000000
 54+#define USBDEBUG_ENDPOINT_IN 7
 55+#elif USB_ENDPOINTS & 0b00000000100000000000000000000000
 56+#define USBDEBUG_ENDPOINT_IN 8
 57+#elif USB_ENDPOINTS & 0b00000010000000000000000000000000
 58+#define USBDEBUG_ENDPOINT_IN 9
 59+#elif USB_ENDPOINTS & 0b00000100000000000000000000000000
 60+#define USBDEBUG_ENDPOINT_IN 10
 61+#elif USB_ENDPOINTS & 0b00001000000000000000000000000000
 62+#define USBDEBUG_ENDPOINT_IN 11
 63+#elif USB_ENDPOINTS & 0b00010000000000000000000000000000
 64+#define USBDEBUG_ENDPOINT_IN 12
 65+#elif USB_ENDPOINTS & 0b00100000000000000000000000000000
 66+#define USBDEBUG_ENDPOINT_IN 13
 67+#elif USB_ENDPOINTS & 0b01000000000000000000000000000000
 68+#define USBDEBUG_ENDPOINT_IN 14
 69+#elif USB_ENDPOINTS & 0b10000000000000000000000000000000
 70+#define USBDEBUG_ENDPOINT_IN 15
 71+#else
 72+#error USBDEBUG: No IN endpoints available!
 73+#endif
 74+#endif
 75+
776 struct usb_instance;
877
978 union __attribute__((packed,aligned(4))) usb_ep0_buffer
Index: emcore/trunk/usb/usbdebug.c
@@ -88,6 +88,13 @@
8989 static struct wakeup dbgconsendwakeup IBSS_ATTR;
9090 static struct wakeup dbgconrecvwakeup IBSS_ATTR;
9191 static bool dbgconsoleattached IBSS_ATTR;
 92+static int maxpacket IBSS_ATTR;
 93+static struct bulk_state
 94+{
 95+ void* addr;
 96+ int size;
 97+} bulk_state[2] IBSS_ATTR;
 98+static int bulk_ctrlreq_ep IBSS_ATTR;
9299
93100 static const char dbgconoverflowstr[] = "\n\n[overflowed]\n\n";
94101
@@ -110,6 +117,107 @@
111118 dbgstate = DBGSTATE_IDLE;
112119 }
113120
 121+void usbdebug_bus_reset(const struct usb_instance* data, int highspeed)
 122+{
 123+ maxpacket = highspeed ? 512 : 64;
 124+}
 125+
 126+void usbdebug_bulk_enable(const struct usb_instance* data, int interface, int altsetting)
 127+{
 128+ usbdebug_enable(data, interface, altsetting);
 129+ union usb_endpoint_number outep = { .number = USBDEBUG_ENDPOINT_OUT, .direction = USB_ENDPOINT_DIRECTION_OUT };
 130+ union usb_endpoint_number inep = { .number = USBDEBUG_ENDPOINT_IN, .direction = USB_ENDPOINT_DIRECTION_IN };
 131+ usb_configure_ep(data, outep, USB_ENDPOINT_TYPE_BULK, maxpacket);
 132+ usb_configure_ep(data, inep, USB_ENDPOINT_TYPE_BULK, maxpacket);
 133+}
 134+
 135+void usbdebug_bulk_disable(const struct usb_instance* data, int interface, int altsetting)
 136+{
 137+ union usb_endpoint_number outep = { .number = USBDEBUG_ENDPOINT_OUT, .direction = USB_ENDPOINT_DIRECTION_OUT };
 138+ union usb_endpoint_number inep = { .number = USBDEBUG_ENDPOINT_IN, .direction = USB_ENDPOINT_DIRECTION_IN };
 139+ usb_unconfigure_ep(data, outep);
 140+ usb_unconfigure_ep(data, inep);
 141+ usbdebug_disable(data, interface, altsetting);
 142+}
 143+
 144+void usbdebug_bulk_xfer_complete(const struct usb_instance* data, int interface, int endpoint, int bytesleft)
 145+{
 146+ struct bulk_state* state = &bulk_state[endpoint];
 147+ if (!bytesleft && state->size)
 148+ {
 149+ int size;
 150+ if (endpoint)
 151+ {
 152+ union usb_endpoint_number ep = { .number = USBDEBUG_ENDPOINT_IN, .direction = USB_ENDPOINT_DIRECTION_IN };
 153+ size = MIN(state->size, maxpacket * usb_get_max_transfer_size(data, ep));
 154+ usb_start_rx(data, ep, state->addr, size);
 155+ }
 156+ else
 157+ {
 158+ union usb_endpoint_number ep = { .number = USBDEBUG_ENDPOINT_OUT, .direction = USB_ENDPOINT_DIRECTION_OUT };
 159+ size = MIN(state->size, maxpacket * usb_get_max_transfer_size(data, ep));
 160+ usb_start_tx(data, ep, state->addr, size);
 161+ }
 162+ state->addr += size;
 163+ state->size -= size;
 164+ }
 165+}
 166+
 167+bool usbdebug_bulk_handle_data(const struct usb_instance* data, union usb_endpoint_number epnum, int bytesleft)
 168+{
 169+ uint32_t* buf = (uint32_t*)data->buffer->raw;
 170+ int len = 64 - bytesleft;
 171+ union usb_endpoint_number ep0out = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_OUT };
 172+ union usb_endpoint_number ep0in = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_IN };
 173+ usb_ep0_start_rx(data, false, 0, NULL);
 174+ switch (buf[0])
 175+ {
 176+ case 1: // START MEMORY TRANSFER
 177+ if (len == 12)
 178+ {
 179+ bulk_state[bulk_ctrlreq_ep].addr = (void*)buf[1];
 180+ bulk_state[bulk_ctrlreq_ep].size = buf[2];
 181+ usbdebug_bulk_xfer_complete(data, 0, bulk_ctrlreq_ep, 0); // Convenient way to start a transfer.
 182+ usb_set_stall(data, ep0out, true);
 183+ usb_ep0_start_tx(data, NULL, 0, NULL);
 184+ break;
 185+ }
 186+ default:
 187+ usb_set_stall(data, ep0out, true);
 188+ usb_set_stall(data, ep0in, true);
 189+ break;
 190+ }
 191+ return true;
 192+}
 193+
 194+int usbdebug_bulk_ctrl_request(const struct usb_instance* data, int interface, int endpoint, union usb_ep0_buffer* request, const void** response)
 195+{
 196+ int size = -1;
 197+ union usb_endpoint_number ep0out = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_OUT };
 198+ switch (request->setup.bmRequestType.type)
 199+ {
 200+ case USB_SETUP_BMREQUESTTYPE_TYPE_VENDOR:
 201+ switch (request->setup.bRequest.raw)
 202+ {
 203+ case 0x00:
 204+ switch (data->buffer->setup.bmRequestType.direction)
 205+ {
 206+ case USB_SETUP_BMREQUESTTYPE_DIRECTION_OUT:
 207+ bulk_ctrlreq_ep = endpoint;
 208+ usb_ep0_start_rx(data, true, 64, usbdebug_bulk_handle_data);
 209+ return -3;
 210+ case USB_SETUP_BMREQUESTTYPE_DIRECTION_IN:
 211+ return -2;
 212+ }
 213+ break;
 214+ default: break;
 215+ }
 216+ break;
 217+ default: break;
 218+ }
 219+ return size;
 220+}
 221+
114222 bool usbdebug_handle_data(const struct usb_instance* data, union usb_endpoint_number epnum, int bytesleft)
115223 {
116224 union usb_endpoint_number ep0in = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_IN };
Index: emcore/trunk/tools/libemcoredata.py
@@ -99,7 +99,8 @@
100100 swtypes = {
101101 0: "invalid",
102102 1: "emBIOS Debugger",
103 - 2: "emCORE Debugger"
 103+ 2: "emCORE Debugger",
 104+ 3: "emCORE Downloader Stub",
104105 }
105106
106107 hwtypes = {
Index: emcore/trunk/tools/libemcore.py
@@ -107,7 +107,7 @@
108108 self.lib = Lib(self.logger)
109109
110110 self.getversioninfo()
111 - if self.lib.dev.swtypeid != 2:
 111+ if self.lib.dev.swtypeid not in swtypes:
112112 raise DeviceError("Connected to unknown software type. Exiting")
113113
114114 self.getmallocpoolbounds()
@@ -144,11 +144,17 @@
145145 @command()
146146 def getmallocpoolbounds(self):
147147 """ This returns the memory range of the malloc pool """
148 - resp = self.lib.monitorcommand(struct.pack("<IIII", 1, 1, 0, 0), "III", ("lower", "upper", None))
149 - self.logger.debug("Malloc pool bounds = 0x%X - 0x%X\n" % (resp.lower, resp.upper))
150 - self.lib.dev.mallocpool.lower = resp.lower
151 - self.lib.dev.mallocpool.upper = resp.upper
152 - return resp
 148+ try:
 149+ resp = self.lib.monitorcommand(struct.pack("<IIII", 1, 1, 0, 0), "III", ("lower", "upper", None))
 150+ self.logger.debug("Malloc pool bounds = 0x%X - 0x%X\n" % (resp.lower, resp.upper))
 151+ self.lib.dev.mallocpool.lower = resp.lower
 152+ self.lib.dev.mallocpool.upper = resp.upper
 153+ self.lib.dev.havemalloc = True
 154+ return resp
 155+ except:
 156+ self.logger.debug("Device doesn't have a memory allocator\n")
 157+ self.lib.dev.havemalloc = True
 158+ return None
153159
154160 @command()
155161 def reset(self, force=False):
@@ -1077,6 +1083,7 @@
10781084 self.swtypeid = None
10791085 self.hwtypeid = None
10801086
 1087+ self.havemalloc = False
10811088 self.mallocpool = Bunch()
10821089 self.mallocpool.lower = None
10831090 self.mallocpool.upper = None