Subversion Repositories freemyipod

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
15 theseven 1
//
2
//
3
//    Copyright 2010 TheSeven
4
//
5
//
6
//    This file is part of emBIOS.
7
//
8
//    emBIOS is free software: you can redistribute it and/or
9
//    modify it under the terms of the GNU General Public License as
10
//    published by the Free Software Foundation, either version 2 of the
11
//    License, or (at your option) any later version.
12
//
13
//    emBIOS is distributed in the hope that it will be useful,
14
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
//    See the GNU General Public License for more details.
17
//
18
//    You should have received a copy of the GNU General Public License along
19
//    with emBIOS.  If not, see <http://www.gnu.org/licenses/>.
20
//
21
//
22
 
23
 
24
#include "global.h"
25
#include "panic.h"
26
#include "usb.h"
27
#include "usb_ch9.h"
28
#include "usbdrv.h"
29
#include "thread.h"
30
#include "console.h"
31
#include "util.h"
25 theseven 32
#include "contextswitch.h"
54 theseven 33
#include "power.h"
35 theseven 34
#include "mmu.h"
29 theseven 35
#include "shutdown.h"
92 theseven 36
#include "execimage.h"
85 theseven 37
#ifdef HAVE_I2C
38
#include "i2c.h"
39
#endif
95 theseven 40
#ifdef HAVE_BOOTFLASH
41
#include "bootflash.h"
42
#endif
157 theseven 43
#ifdef HAVE_HWKEYAES
44
#include "hwkeyaes.h"
45
#endif
46
#ifdef HAVE_HMACSHA1
47
#include "hmacsha1.h"
48
#endif
226 theseven 49
#ifdef USB_HAVE_TARGET_SPECIFIC_REQUESTS
50
#include "usbtarget.h"
51
#endif
15 theseven 52
 
53
 
54
static uint8_t ctrlresp[2] CACHEALIGN_ATTR;
55
static uint32_t dbgrecvbuf[0x80] CACHEALIGN_ATTR;
56
static uint32_t dbgsendbuf[0x80] CACHEALIGN_ATTR;
57
static uint32_t dbgasyncsendbuf[0x80] CACHEALIGN_ATTR;
58
static char dbgendpoints[4] IBSS_ATTR;
59
 
60
enum dbgaction_t
61
{
62
    DBGACTION_IDLE = 0,
63
    DBGACTION_I2CSEND,
64
    DBGACTION_I2CRECV,
29 theseven 65
    DBGACTION_RESET,
66
    DBGACTION_POWEROFF,
67
    DBGACTION_CWRITE,
68
    DBGACTION_CREAD,
92 theseven 69
    DBGACTION_CFLUSH,
95 theseven 70
    DBGACTION_EXECIMAGE,
127 theseven 71
    DBGACTION_EXECFIRMWARE,
95 theseven 72
    DBGACTION_READBOOTFLASH,
157 theseven 73
    DBGACTION_WRITEBOOTFLASH,
74
    DBGACTION_HWKEYAES,
226 theseven 75
    DBGACTION_HMACSHA1,
76
    DBGACTION_TARGETSPECIFIC
15 theseven 77
};
78
 
79
static uint32_t dbgstack[0x100] STACK_ATTR;
80
struct wakeup dbgwakeup IBSS_ATTR;
81
extern struct scheduler_thread* scheduler_threads;
82
static enum dbgaction_t dbgaction IBSS_ATTR;
29 theseven 83
static int dbgi2cbus;
84
static int dbgi2cslave;
85
static int dbgactionaddr;
95 theseven 86
static int dbgactionoffset;
29 theseven 87
static int dbgactionlength;
88
static int dbgactionconsoles;
89
static int dbgactiontype;
25 theseven 90
static char dbgconsendbuf[4096];
91
static char dbgconrecvbuf[1024];
92
static int dbgconsendreadidx IBSS_ATTR;
93
static int dbgconsendwriteidx IBSS_ATTR;
94
static int dbgconrecvreadidx IBSS_ATTR;
95
static int dbgconrecvwriteidx IBSS_ATTR;
96
static struct wakeup dbgconsendwakeup IBSS_ATTR;
97
static struct wakeup dbgconrecvwakeup IBSS_ATTR;
98
static bool dbgconsoleattached IBSS_ATTR;
15 theseven 99
 
25 theseven 100
static const char dbgconoverflowstr[] = "\n\n[overflowed]\n\n";
15 theseven 101
 
35 theseven 102
extern int _initstart;   // These aren't ints at all, but gcc complains about void types being
336 theseven 103
extern int _sdramstart;  // used here, and we only need the address, so just make it happy...
25 theseven 104
 
35 theseven 105
 
15 theseven 106
static struct usb_device_descriptor CACHEALIGN_ATTR device_descriptor =
107
{
108
    .bLength            = sizeof(struct usb_device_descriptor),
109
    .bDescriptorType    = USB_DT_DEVICE,
110
    .bcdUSB             = 0x0200,
111
    .bDeviceClass       = USB_CLASS_VENDOR_SPEC,
112
    .bDeviceSubClass    = 0xff,
113
    .bDeviceProtocol    = 0xff,
114
    .bMaxPacketSize0    = 64,
115
    .idVendor           = 0xffff,
116
    .idProduct          = 0xe000,
117
    .bcdDevice          = 0x0001,
118
    .iManufacturer      = 1,
119
    .iProduct           = 2,
120
    .iSerialNumber      = 0,
121
    .bNumConfigurations = 1
122
};
123
 
124
static struct usb_config_bundle
125
{
126
    struct usb_config_descriptor config_descriptor;
127
    struct usb_interface_descriptor interface_descriptor;
128
    struct usb_endpoint_descriptor endpoint1_descriptor;
129
    struct usb_endpoint_descriptor endpoint2_descriptor;
130
    struct usb_endpoint_descriptor endpoint3_descriptor;
131
    struct usb_endpoint_descriptor endpoint4_descriptor;
132
} __attribute__((packed)) CACHEALIGN_ATTR config_bundle = 
133
{
134
    .config_descriptor =
135
    {
136
        .bLength             = sizeof(struct usb_config_descriptor),
137
        .bDescriptorType     = USB_DT_CONFIG,
138
        .wTotalLength        = sizeof(struct usb_config_descriptor)
139
                             + sizeof(struct usb_interface_descriptor)
140
                             + sizeof(struct usb_endpoint_descriptor) * 4,
141
        .bNumInterfaces      = 1,
142
        .bConfigurationValue = 1,
143
        .iConfiguration      = 0,
144
        .bmAttributes        = USB_CONFIG_ATT_ONE,
145
        .bMaxPower           = 250
146
    },
147
    .interface_descriptor =
148
    {
149
        .bLength             = sizeof(struct usb_interface_descriptor),
150
        .bDescriptorType     = USB_DT_INTERFACE,
151
        .bInterfaceNumber    = 0,
152
        .bAlternateSetting   = 0,
153
        .bNumEndpoints       = 4,
154
        .bInterfaceClass     = USB_CLASS_VENDOR_SPEC,
155
        .bInterfaceSubClass  = 0xff,
156
        .bInterfaceProtocol  = 0xff,
157
        .iInterface          = 0
158
    },
159
    .endpoint1_descriptor =
160
    {
161
        .bLength             = sizeof(struct usb_endpoint_descriptor),
162
        .bDescriptorType     = USB_DT_ENDPOINT,
163
        .bEndpointAddress    = 0,
164
        .bmAttributes        = USB_ENDPOINT_XFER_BULK,
165
        .wMaxPacketSize      = 0,
166
        .bInterval           = 1
167
    },
168
    .endpoint2_descriptor =
169
    {
170
        .bLength             = sizeof(struct usb_endpoint_descriptor),
171
        .bDescriptorType     = USB_DT_ENDPOINT,
172
        .bEndpointAddress    = 0,
173
        .bmAttributes        = USB_ENDPOINT_XFER_BULK,
174
        .wMaxPacketSize      = 0,
175
        .bInterval           = 1
176
    },
177
    .endpoint3_descriptor =
178
    {
179
        .bLength             = sizeof(struct usb_endpoint_descriptor),
180
        .bDescriptorType     = USB_DT_ENDPOINT,
181
        .bEndpointAddress    = 0,
182
        .bmAttributes        = USB_ENDPOINT_XFER_BULK,
183
        .wMaxPacketSize      = 0,
184
        .bInterval           = 1
185
    },
186
    .endpoint4_descriptor =
187
    {
188
        .bLength             = sizeof(struct usb_endpoint_descriptor),
189
        .bDescriptorType     = USB_DT_ENDPOINT,
190
        .bEndpointAddress    = 0,
191
        .bmAttributes        = USB_ENDPOINT_XFER_BULK,
192
        .wMaxPacketSize      = 0,
193
        .bInterval           = 1
194
    }
195
};
196
 
197
static struct usb_string_descriptor CACHEALIGN_ATTR string_devicename =
198
{
199
    32,
200
    USB_DT_STRING,
201
    {'e', 'm', 'B', 'I', 'O', 'S', ' ', 'D', 'e', 'b', 'u', 'g', 'g', 'e', 'r'}
202
};
203
 
204
static const struct usb_string_descriptor CACHEALIGN_ATTR lang_descriptor =
205
{
206
    4,
207
    USB_DT_STRING,
208
    {0x0409}
209
};
210
 
211
 
212
void usb_setup_dbg_listener()
213
{
214
    usb_drv_recv(dbgendpoints[0], dbgrecvbuf, usb_drv_port_speed() ? 512 : 64);
215
}
216
 
217
void usb_handle_control_request(struct usb_ctrlrequest* req)
218
{
219
    const void* addr;
220
    int size = -1;
221
    switch (req->bRequest)
222
    {
223
    case USB_REQ_GET_STATUS:
224
        if (req->bRequestType == USB_DIR_IN) ctrlresp[0] = 1;
225
        else ctrlresp[0] = 0;
226
        ctrlresp[1] = 0;
227
        addr = ctrlresp;
228
        size = 2;
229
        break;
230
    case USB_REQ_CLEAR_FEATURE:
231
        if (req->bRequestType == USB_RECIP_ENDPOINT && req->wValue == USB_ENDPOINT_HALT)
232
            usb_drv_stall(req->wIndex & 0xf, false, req->wIndex >> 7);
233
        size = 0;
234
        break;
235
    case USB_REQ_SET_FEATURE:
236
        size = 0;
237
        break;
238
    case USB_REQ_SET_ADDRESS:
239
        size = 0;
240
        usb_drv_cancel_all_transfers();
241
        usb_drv_set_address(req->wValue);
242
        usb_setup_dbg_listener();
243
        break;
244
    case USB_REQ_GET_DESCRIPTOR:
245
        switch (req->wValue >> 8)
246
        {
247
        case USB_DT_DEVICE:
248
            addr = &device_descriptor;
249
            size = sizeof(device_descriptor);
250
            break;
251
        case USB_DT_OTHER_SPEED_CONFIG:
252
        case USB_DT_CONFIG:
253
            if ((req->wValue >> 8) == USB_DT_CONFIG)
254
            {
255
                int maxpacket = usb_drv_port_speed() ? 512 : 64;
256
                config_bundle.endpoint1_descriptor.wMaxPacketSize = maxpacket;
257
                config_bundle.endpoint2_descriptor.wMaxPacketSize = maxpacket;
258
                config_bundle.endpoint3_descriptor.wMaxPacketSize = maxpacket;
259
                config_bundle.endpoint4_descriptor.wMaxPacketSize = maxpacket;
260
                config_bundle.config_descriptor.bDescriptorType = USB_DT_CONFIG;
261
            }
262
            else
263
            {
264
                int maxpacket = usb_drv_port_speed() ? 64 : 512;
265
                config_bundle.endpoint1_descriptor.wMaxPacketSize = maxpacket;
266
                config_bundle.endpoint2_descriptor.wMaxPacketSize = maxpacket;
267
                config_bundle.endpoint3_descriptor.wMaxPacketSize = maxpacket;
268
                config_bundle.endpoint4_descriptor.wMaxPacketSize = maxpacket;
269
                config_bundle.config_descriptor.bDescriptorType = USB_DT_OTHER_SPEED_CONFIG;
270
            }
271
            addr = &config_bundle;
272
            size = sizeof(config_bundle);
273
            break;
274
        case USB_DT_STRING:
275
            switch (req->wValue & 0xff)
276
            {
277
            case 0:
278
                addr = &lang_descriptor;
234 theseven 279
                size = lang_descriptor.bLength;
15 theseven 280
                break;
281
            case 1:
282
                string_devicename.bLength = 14;
283
                addr = &string_devicename;
234 theseven 284
                size = string_devicename.bLength;
285
                break;
15 theseven 286
            case 2:
235 theseven 287
                string_devicename.bLength = 32;
15 theseven 288
                addr = &string_devicename;
234 theseven 289
                size = string_devicename.bLength;
15 theseven 290
                break;
291
            }
292
            break;
293
        }
294
        break;
295
    case USB_REQ_GET_CONFIGURATION:
296
        ctrlresp[0] = 1;
297
        addr = ctrlresp;
298
        size = 1;
299
        break;
300
    case USB_REQ_SET_CONFIGURATION:
301
        usb_drv_cancel_all_transfers();
302
        usb_setup_dbg_listener();
303
        size = 0;
304
        break;
305
    }
306
    if (!size) usb_drv_send_nonblocking(0, NULL, 0);
307
    else if (size == -1)
308
    {
309
        usb_drv_stall(0, true, true);
310
        usb_drv_stall(0, true, false);
311
    }
312
    else
313
    {
314
        usb_drv_recv(0, NULL, 0);
315
        usb_drv_send_nonblocking(0, addr, size > req->wLength ? req->wLength : size);
316
    }
317
}
318
 
29 theseven 319
bool set_dbgaction(enum dbgaction_t action, int addsize)
15 theseven 320
{
321
    if (dbgaction != DBGACTION_IDLE)
322
    {
323
        dbgsendbuf[0] = 3;
29 theseven 324
        usb_drv_send_nonblocking(dbgendpoints[1], dbgsendbuf, 16 + addsize);
15 theseven 325
        return true;
326
    }
327
    dbgaction = action;
328
    wakeup_signal(&dbgwakeup);
329
    return false;
330
}
331
 
332
void reset() __attribute__((noreturn));
333
 
334
void usb_handle_transfer_complete(int endpoint, int dir, int status, int length)
335
{
336
    void* addr = dbgsendbuf;
337
    int size = 0;
338
    if (endpoint == dbgendpoints[0])
339
    {
226 theseven 340
#ifdef USB_HAVE_TARGET_SPECIFIC_REQUESTS
341
        if (dbgrecvbuf[0] >= 0xffff0000)
342
        {
343
            if (!set_dbgaction(DBGACTION_TARGETSPECIFIC, 0))
344
                memcpy(dbgasyncsendbuf, dbgrecvbuf, sizeof(dbgasyncsendbuf));
345
            usb_setup_dbg_listener();
346
            return;
347
        }
348
#endif
15 theseven 349
        switch (dbgrecvbuf[0])
350
        {
28 theseven 351
        case 1:  // GET INFO
15 theseven 352
            dbgsendbuf[0] = 1;
353
            size = 16;
28 theseven 354
            switch (dbgrecvbuf[1])
355
            {
356
            case 0:  // GET VERSION INFO
85 theseven 357
                dbgsendbuf[1] = VERSION_SVN_INT;
358
                dbgsendbuf[2] = VERSION_MAJOR | (VERSION_MINOR << 8)
28 theseven 359
                              | (VERSION_PATCH << 16) | (1 << 24);
85 theseven 360
                dbgsendbuf[3] = PLATFORM_ID;
28 theseven 361
                break;
362
            case 1:  // GET PACKET SIZE INFO
363
                dbgsendbuf[1] = 0x02000200;
364
                dbgsendbuf[2] = usb_drv_get_max_out_size();
365
                dbgsendbuf[3] = usb_drv_get_max_in_size();
366
                break;
35 theseven 367
            case 2:  // GET USER MEMORY INFO
368
                dbgsendbuf[1] = (uint32_t)&_initstart;
369
                dbgsendbuf[2] = (uint32_t)&_sdramstart;
370
                break;
28 theseven 371
            default:
372
                dbgsendbuf[0] = 2;
373
            }
15 theseven 374
            break;
375
        case 2:  // RESET
29 theseven 376
            if (dbgrecvbuf[1])
377
            {
378
                if (set_dbgaction(DBGACTION_RESET, 0)) break;
379
                dbgsendbuf[0] = 1;
380
                size = 16;
381
            }
382
            else reset();
15 theseven 383
            break;
384
        case 3:  // POWER OFF
29 theseven 385
            if (set_dbgaction(DBGACTION_POWEROFF, 0)) break;
386
            dbgactiontype = dbgrecvbuf[1];
387
            dbgsendbuf[0] = 1;
388
            size = 16;
15 theseven 389
            break;
390
        case 4:  // READ MEMORY
391
            dbgsendbuf[0] = 1;
392
            memcpy(&dbgsendbuf[4], (const void*)dbgrecvbuf[1], dbgrecvbuf[2]);
393
            size = dbgrecvbuf[2] + 16;
394
            break;
395
        case 5:  // WRITE MEMORY
396
            dbgsendbuf[0] = 1;
397
            memcpy((void*)dbgrecvbuf[1], &dbgrecvbuf[4], dbgrecvbuf[2]);
398
            size = 16;
399
            break;
400
        case 6:  // READ DMA
401
            dbgsendbuf[0] = 1;
402
            usb_drv_send_nonblocking(dbgendpoints[1], dbgsendbuf, 16);
403
            usb_drv_send_nonblocking(dbgendpoints[3], (const void*)dbgrecvbuf[1], dbgrecvbuf[2]);
404
            break;
405
        case 7:  // WRITE DMA
406
            dbgsendbuf[0] = 1;
407
            size = 16;
408
            usb_drv_recv(dbgendpoints[2], (void*)dbgrecvbuf[1], dbgrecvbuf[2]);
409
            break;
85 theseven 410
#ifdef HAVE_I2C
15 theseven 411
        case 8:  // READ I2C
29 theseven 412
            if (set_dbgaction(DBGACTION_I2CRECV, dbgrecvbuf[1] >> 24)) break;
15 theseven 413
            dbgi2cbus = dbgrecvbuf[1] & 0xff;
414
            dbgi2cslave = (dbgrecvbuf[1] >> 8) & 0xff;
29 theseven 415
            dbgactionaddr = (dbgrecvbuf[1] >> 16) & 0xff;
416
            dbgactionlength = dbgrecvbuf[1] >> 24;
175 theseven 417
            if (!dbgactionlength) dbgactionlength = 256;
15 theseven 418
            break;
419
        case 9:  // WRITE I2C
29 theseven 420
            if (set_dbgaction(DBGACTION_I2CSEND, 0)) break;
15 theseven 421
            dbgi2cbus = dbgrecvbuf[1] & 0xff;
422
            dbgi2cslave = (dbgrecvbuf[1] >> 8) & 0xff;
29 theseven 423
            dbgactionaddr = (dbgrecvbuf[1] >> 16) & 0xff;
424
            dbgactionlength = dbgrecvbuf[1] >> 24;
175 theseven 425
            if (!dbgactionlength) dbgactionlength = 256;
212 theseven 426
            memcpy(dbgasyncsendbuf, &dbgrecvbuf[4], dbgactionlength);
15 theseven 427
            break;
85 theseven 428
#endif
25 theseven 429
        case 10:  // READ CONSOLE
430
            dbgconsoleattached = true;
431
            int bytes = dbgconsendwriteidx - dbgconsendreadidx;
336 theseven 432
            int used = 0;
25 theseven 433
            if (bytes)
434
            {
435
                if (bytes < 0) bytes += sizeof(dbgconsendbuf);
336 theseven 436
                used = bytes;
25 theseven 437
                if (bytes > dbgrecvbuf[1]) bytes = dbgrecvbuf[1];
438
                int readbytes = bytes;
439
                char* outptr = (char*)&dbgsendbuf[4];
440
                if (dbgconsendreadidx + bytes >= sizeof(dbgconsendbuf))
441
                {
442
                    readbytes = sizeof(dbgconsendbuf) - dbgconsendreadidx;
443
                    memcpy(outptr, &dbgconsendbuf[dbgconsendreadidx], readbytes);
444
                    dbgconsendreadidx = 0;
445
                    outptr = &outptr[readbytes];
446
                    readbytes = bytes - readbytes;
447
                }
448
                if (readbytes) memcpy(outptr, &dbgconsendbuf[dbgconsendreadidx], readbytes);
449
                dbgconsendreadidx += readbytes;
26 theseven 450
                wakeup_signal(&dbgconsendwakeup);
25 theseven 451
            }
452
            dbgsendbuf[0] = 1;
453
            dbgsendbuf[1] = bytes;
454
            dbgsendbuf[2] = sizeof(dbgconsendbuf);
336 theseven 455
            dbgsendbuf[3] = used - bytes;
25 theseven 456
            size = 16 + dbgrecvbuf[1];
457
            break;
26 theseven 458
        case 11:  // WRITE CONSOLE
459
            bytes = dbgconrecvreadidx - dbgconrecvwriteidx - 1;
460
            if (bytes < 0) bytes += sizeof(dbgconrecvbuf);
461
            if (bytes)
462
            {
463
                if (bytes > dbgrecvbuf[1]) bytes = dbgrecvbuf[1];
464
                int writebytes = bytes;
465
                char* readptr = (char*)&dbgrecvbuf[4];
466
                if (dbgconrecvwriteidx + bytes >= sizeof(dbgconrecvbuf))
467
                {
468
                    writebytes = sizeof(dbgconrecvbuf) - dbgconrecvwriteidx;
469
                    memcpy(&dbgconrecvbuf[dbgconrecvwriteidx], readptr, writebytes);
470
                    dbgconrecvwriteidx = 0;
471
                    readptr = &readptr[writebytes];
472
                    writebytes = bytes - writebytes;
473
                }
474
                if (writebytes) memcpy(&dbgconrecvbuf[dbgconrecvwriteidx], readptr, writebytes);
475
                dbgconrecvwriteidx += writebytes;
476
                wakeup_signal(&dbgconrecvwakeup);
477
            }
478
            dbgsendbuf[0] = 1;
479
            dbgsendbuf[1] = bytes;
480
            dbgsendbuf[2] = sizeof(dbgconrecvbuf);
481
            dbgsendbuf[3] = dbgconrecvreadidx - dbgconrecvwriteidx - 1;
482
            size = 16;
483
            break;
29 theseven 484
        case 12:  // CWRITE
485
            if (set_dbgaction(DBGACTION_CWRITE, 0)) break;
486
            dbgactionconsoles = dbgrecvbuf[1];
487
            dbgactionlength = dbgrecvbuf[2];
488
            memcpy(dbgasyncsendbuf, &dbgrecvbuf[4], dbgactionlength);
489
            break;
490
        case 13:  // CREAD
491
            if (set_dbgaction(DBGACTION_CREAD, dbgrecvbuf[2])) break;
492
            dbgactionconsoles = dbgrecvbuf[1];
493
            dbgactionlength = dbgrecvbuf[2];
494
            break;
495
        case 14:  // CFLUSH
496
            if (set_dbgaction(DBGACTION_CFLUSH, 0)) break;
497
            dbgactionconsoles = dbgrecvbuf[1];
498
            break;
31 theseven 499
        case 15:  // GET PROCESS INFO
500
            dbgsendbuf[0] = 1;
501
            dbgsendbuf[1] = SCHEDULER_THREAD_INFO_VERSION;
502
            dbgsendbuf[2] = MAX_THREADS * sizeof(struct scheduler_thread);
136 theseven 503
            memcpy(&dbgsendbuf[4], (void*)(((uint32_t)&scheduler_threads) + dbgrecvbuf[1]),
57 theseven 504
                   dbgrecvbuf[2]);
505
            size = dbgrecvbuf[2] + 16;
31 theseven 506
            break;
34 theseven 507
        case 16:  // FREEZE SCHEDULER
54 theseven 508
            dbgsendbuf[1] = scheduler_freeze(dbgrecvbuf[1]);
34 theseven 509
            dbgsendbuf[0] = 1;
510
            size = 16;
511
            break;
35 theseven 512
        case 17:  // SUSPEND THREAD
54 theseven 513
            if (dbgrecvbuf[1])
514
            {
515
                if (thread_suspend(dbgrecvbuf[2]) == -4) dbgsendbuf[1] = 1;
516
                else dbgsendbuf[1] = 0;
517
            }
518
            else
519
            {
520
                if (thread_resume(dbgrecvbuf[2]) == -5) dbgsendbuf[1] = 0;
521
                else dbgsendbuf[1] = 1;
522
            }
35 theseven 523
            dbgsendbuf[0] = 1;
524
            size = 16;
525
            break;
526
        case 18:  // KILL THREAD
527
            thread_terminate(dbgrecvbuf[1]);
528
            dbgsendbuf[0] = 1;
529
            size = 16;
530
            break;
57 theseven 531
        case 19:  // KILL THREAD
35 theseven 532
            dbgsendbuf[0] = 1;
533
            dbgsendbuf[1] = thread_create((const char*)dbgsendbuf[1], (const void*)dbgsendbuf[2],
534
                                          (char*)dbgsendbuf[3], dbgsendbuf[4], dbgsendbuf[5],
535
                                          dbgsendbuf[6], dbgsendbuf[7]);
536
            size = 16;
537
            break;
538
        case 20:  // FLUSH CACHE
539
            clean_dcache();
540
            invalidate_icache();
541
            dbgsendbuf[0] = 1;
542
            size = 16;
543
            break;
92 theseven 544
        case 21:  // EXECIMAGE
545
            if (set_dbgaction(DBGACTION_EXECIMAGE, 0)) break;
546
            dbgactionaddr = dbgrecvbuf[1];
547
            break;
95 theseven 548
#ifdef HAVE_BOOTFLASH
549
        case 22:  // READ BOOT FLASH
550
            if (set_dbgaction(DBGACTION_READBOOTFLASH, 0)) break;
551
            dbgactionaddr = dbgrecvbuf[1];
552
            dbgactionoffset = dbgrecvbuf[2];
553
            dbgactionlength = dbgrecvbuf[3];
554
            break;
555
        case 23:  // WRITE BOOT FLASH
556
            if (set_dbgaction(DBGACTION_WRITEBOOTFLASH, 0)) break;
557
            dbgactionaddr = dbgrecvbuf[1];
558
            dbgactionoffset = dbgrecvbuf[2];
559
            dbgactionlength = dbgrecvbuf[3];
560
            break;
561
#endif
127 theseven 562
        case 24:  // EXECFIRMWARE
563
            if (set_dbgaction(DBGACTION_EXECFIRMWARE, 0)) break;
564
            dbgactionaddr = dbgrecvbuf[1];
565
            break;
157 theseven 566
#ifdef HAVE_HWKEYAES
567
        case 25:  // HWKEYAES
568
            if (set_dbgaction(DBGACTION_HWKEYAES, 0)) break;
569
            dbgactiontype = ((uint8_t*)dbgrecvbuf)[4];
570
            dbgactionoffset = ((uint16_t*)dbgrecvbuf)[3];
571
            dbgactionaddr = dbgrecvbuf[2];
572
            dbgactionlength = dbgrecvbuf[3];
179 theseven 573
            break;
157 theseven 574
#endif
575
#ifdef HAVE_HMACSHA1
576
        case 26:  // HMACSHA1
577
            if (set_dbgaction(DBGACTION_HMACSHA1, 0)) break;
578
            dbgactionaddr = dbgrecvbuf[1];
579
            dbgactionlength = dbgrecvbuf[2];
580
            dbgactionoffset = dbgrecvbuf[3];
179 theseven 581
            break;
157 theseven 582
#endif
15 theseven 583
        default:
584
            dbgsendbuf[0] = 2;
585
            size = 16;
586
        }
587
        usb_setup_dbg_listener();
588
        if (size) usb_drv_send_nonblocking(dbgendpoints[1], addr, size);
589
    }
590
}
591
 
592
void usb_handle_bus_reset(void)
593
{
594
    dbgendpoints[0] = usb_drv_request_endpoint(USB_ENDPOINT_XFER_BULK, USB_DIR_OUT);
595
    dbgendpoints[1] = usb_drv_request_endpoint(USB_ENDPOINT_XFER_BULK, USB_DIR_IN);
596
    dbgendpoints[2] = usb_drv_request_endpoint(USB_ENDPOINT_XFER_BULK, USB_DIR_OUT);
597
    dbgendpoints[3] = usb_drv_request_endpoint(USB_ENDPOINT_XFER_BULK, USB_DIR_IN);
598
    config_bundle.endpoint1_descriptor.bEndpointAddress = dbgendpoints[0];
599
    config_bundle.endpoint2_descriptor.bEndpointAddress = dbgendpoints[1];
600
    config_bundle.endpoint3_descriptor.bEndpointAddress = dbgendpoints[2];
601
    config_bundle.endpoint4_descriptor.bEndpointAddress = dbgendpoints[3];
602
    usb_setup_dbg_listener();
603
}
604
 
605
void dbgthread(void)
606
{
607
    int i;
25 theseven 608
    int t;
15 theseven 609
    while (1)
610
    {
611
        wakeup_wait(&dbgwakeup, TIMEOUT_BLOCK);
612
        for (i = 0; i < MAX_THREADS; i++)
613
            if (scheduler_threads[i].state == THREAD_DEFUNCT)
614
            {
615
                if (scheduler_threads[i].block_type == THREAD_DEFUNCT_STKOV)
35 theseven 616
                {
617
                    if (scheduler_threads[i].name)
618
                        cprintf(1, "\n*PANIC*\nStack overflow! (%s)\n",
619
                                scheduler_threads[i].name);
620
                    else cprintf(1, "\n*PANIC*\nStack overflow! (ID %d)\n", i);
621
                }
15 theseven 622
                scheduler_threads[i].state = THREAD_DEFUNCT_ACK;
623
            }
624
        if (dbgaction != DBGACTION_IDLE)
625
        {
626
            switch (dbgaction)
627
            {
85 theseven 628
#ifdef HAVE_I2C
15 theseven 629
            case DBGACTION_I2CSEND:
29 theseven 630
                i2c_send(dbgi2cbus, dbgi2cslave, dbgactionaddr,
631
                         (uint8_t*)dbgasyncsendbuf, dbgactionlength);
15 theseven 632
                dbgasyncsendbuf[0] = 1;
633
                usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
634
                break;
635
            case DBGACTION_I2CRECV:
29 theseven 636
                i2c_recv(dbgi2cbus, dbgi2cslave, dbgactionaddr,
637
                         (uint8_t*)(&dbgasyncsendbuf[4]), dbgactionlength);
15 theseven 638
                dbgasyncsendbuf[0] = 1;
29 theseven 639
                usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16 + dbgactionlength);
15 theseven 640
                break;
85 theseven 641
#endif
15 theseven 642
            case DBGACTION_POWEROFF:
127 theseven 643
                if (dbgactiontype) shutdown(true);
54 theseven 644
                power_off();
15 theseven 645
                break;
29 theseven 646
            case DBGACTION_RESET:
127 theseven 647
                shutdown(false);
29 theseven 648
                reset();
649
                break;
650
            case DBGACTION_CWRITE:
651
                cwrite(dbgactionconsoles, (const char*)dbgasyncsendbuf, dbgactionlength);
652
                dbgasyncsendbuf[0] = 1;
653
                usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
654
                break;
655
            case DBGACTION_CREAD:
656
                dbgasyncsendbuf[0] = 1;
30 theseven 657
                dbgasyncsendbuf[1] = cread(dbgactionconsoles, (char*)&dbgasyncsendbuf[4],
658
                                           dbgactionlength, 0);
226 theseven 659
                usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16 + dbgactionlength);
29 theseven 660
                break;
661
            case DBGACTION_CFLUSH:
662
                cflush(dbgactionconsoles);
663
                dbgasyncsendbuf[0] = 1;
664
                usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
665
                break;
92 theseven 666
            case DBGACTION_EXECIMAGE:
667
                dbgasyncsendbuf[0] = 1;
668
                dbgasyncsendbuf[1] = execimage((void*)dbgactionaddr);
669
                usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
670
                break;
127 theseven 671
            case DBGACTION_EXECFIRMWARE:
672
                shutdown(false);
673
                dbgasyncsendbuf[0] = 1;
674
                usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
675
                execfirmware((void*)dbgactionaddr);
95 theseven 676
#ifdef HAVE_BOOTFLASH
677
            case DBGACTION_READBOOTFLASH:
678
                bootflash_readraw((void*)dbgactionaddr, dbgactionoffset, dbgactionlength);
679
                dbgasyncsendbuf[0] = 1;
680
                usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
681
                break;
682
            case DBGACTION_WRITEBOOTFLASH:
683
                bootflash_writeraw((void*)dbgactionaddr, dbgactionoffset, dbgactionlength);
684
                dbgasyncsendbuf[0] = 1;
685
                usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
686
                break;
687
#endif
157 theseven 688
#ifdef HAVE_HWKEYAES
689
            case DBGACTION_HWKEYAES:
690
                hwkeyaes((enum hwkeyaes_direction) dbgactiontype, dbgactionoffset,
691
                         (void*)dbgactionaddr, dbgactionlength);
692
                dbgasyncsendbuf[0] = 1;
693
                usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
694
                break;
695
#endif
696
#ifdef HAVE_HMACSHA1
697
            case DBGACTION_HMACSHA1:
698
                hmacsha1((void*)dbgactionaddr, dbgactionlength, (void*)dbgactionoffset);
699
                dbgasyncsendbuf[0] = 1;
700
                usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
701
                break;
702
#endif
226 theseven 703
#ifdef USB_HAVE_TARGET_SPECIFIC_REQUESTS
704
            case DBGACTION_TARGETSPECIFIC:
705
            {
706
                int size = usb_target_handle_request(dbgasyncsendbuf, sizeof(dbgasyncsendbuf));
707
                if (size) usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, size);
708
                break;
15 theseven 709
            }
226 theseven 710
#endif
711
            }
15 theseven 712
            dbgaction = DBGACTION_IDLE;
713
        }
714
    }
715
}
716
 
717
void usb_init(void)
718
{
719
    dbgaction = DBGACTION_IDLE;
720
    wakeup_init(&dbgwakeup);
25 theseven 721
    dbgconsendreadidx = 0;
722
    dbgconsendwriteidx = 0;
723
    dbgconrecvreadidx = 0;
724
    dbgconrecvwriteidx = 0;
725
    wakeup_init(&dbgconsendwakeup);
726
    wakeup_init(&dbgconrecvwakeup);
85 theseven 727
    dbgconsoleattached = false;
167 theseven 728
    thread_create("monitor worker", dbgthread, dbgstack, sizeof(dbgstack), CORE_THREAD, 255, true);
15 theseven 729
    usb_drv_init();
730
}
25 theseven 731
 
732
int dbgconsole_getfree() ICODE_ATTR;
733
int dbgconsole_getfree()
734
{
735
    int free = dbgconsendreadidx - dbgconsendwriteidx - 1;
736
    if (free < 0) free += sizeof(dbgconsendbuf);
737
    return free;
738
}
739
 
740
int dbgconsole_makespace(int length) ICODE_ATTR;
741
int dbgconsole_makespace(int length)
742
{
743
    int free = dbgconsole_getfree();
744
    while (!free && dbgconsoleattached)
745
    {
336 theseven 746
        dbgconsoleattached = false;
747
        wakeup_wait(&dbgconsendwakeup, 2000000);
25 theseven 748
        free = dbgconsole_getfree();
749
    }
750
    if (free) return free > length ? length : free;
751
    if (length > sizeof(dbgconsendbuf) - 17) length = sizeof(dbgconsendbuf) - 17;
752
    uint32_t mode = enter_critical_section();
753
    dbgconsendreadidx += length;
754
    if (dbgconsendreadidx >= sizeof(dbgconsendbuf))
755
        dbgconsendreadidx -= sizeof(dbgconsendbuf);
756
    int offset = 0;
757
    int idx = dbgconsendreadidx;
758
    if (idx + 16 >= sizeof(dbgconsendbuf))
759
    {
760
        offset = sizeof(dbgconsendbuf) - dbgconsendreadidx;
761
        memcpy(&dbgconsendbuf[dbgconsendreadidx], dbgconoverflowstr, offset);
762
        idx = 0;
763
    }
764
    if (offset != 16) memcpy(&dbgconsendbuf[idx], &dbgconoverflowstr[offset], 16 - offset);
765
    leave_critical_section(mode);
766
    return length;
767
}
768
 
769
void dbgconsole_putc(char string)
770
{
771
    dbgconsole_makespace(1);
772
    dbgconsendbuf[dbgconsendwriteidx++] = string;
773
    if (dbgconsendwriteidx >= sizeof(dbgconsendbuf))
774
        dbgconsendwriteidx -= sizeof(dbgconsendbuf);
775
}
776
 
777
void dbgconsole_write(const char* string, size_t length)
778
{
779
    while (length)
780
    {
781
        int space = dbgconsole_makespace(length);
782
        if (dbgconsendwriteidx + space >= sizeof(dbgconsendbuf))
783
        {
784
            int bytes = sizeof(dbgconsendbuf) - dbgconsendwriteidx;
785
            memcpy(&dbgconsendbuf[dbgconsendwriteidx], string, bytes);
786
            dbgconsendwriteidx = 0;
787
            string = &string[bytes];
788
            space -= bytes;
789
            length -= bytes;
790
        }
791
        if (space) memcpy(&dbgconsendbuf[dbgconsendwriteidx], string, space);
792
        dbgconsendwriteidx += space;
793
        string = &string[space];
794
        length -= space;
795
    }
796
}
797
 
798
void dbgconsole_puts(const char* string)
799
{
800
    dbgconsole_write(string, strlen(string));
801
}
26 theseven 802
 
803
int dbgconsole_getavailable() ICODE_ATTR;
804
int dbgconsole_getavailable()
805
{
806
    int available = dbgconrecvwriteidx - dbgconrecvreadidx;
807
    if (available < 0) available += sizeof(dbgconrecvbuf);
808
    return available;
809
}
810
 
811
int dbgconsole_getc(int timeout)
812
{
813
    if (!dbgconsole_getavailable())
814
    {
815
        wakeup_wait(&dbgconrecvwakeup, TIMEOUT_NONE);
816
        if (!dbgconsole_getavailable())
817
        {
818
            wakeup_wait(&dbgconrecvwakeup, timeout);
819
            if (!dbgconsole_getavailable()) return -1;
820
        }
821
    }
822
    int byte = dbgconrecvbuf[dbgconrecvreadidx++];
823
    if (dbgconrecvreadidx >= sizeof(dbgconrecvbuf))
824
        dbgconrecvreadidx -= sizeof(dbgconrecvbuf);
825
    return byte;
826
}
827
 
828
int dbgconsole_read(char* buffer, size_t length, int timeout)
829
{
830
    if (!length) return 0;
831
    int available = dbgconsole_getavailable();
832
    if (!available)
833
    {
834
        wakeup_wait(&dbgconrecvwakeup, TIMEOUT_NONE);
835
        int available = dbgconsole_getavailable();
836
        if (!available)
837
        {
838
            wakeup_wait(&dbgconrecvwakeup, timeout);
839
            int available = dbgconsole_getavailable();
840
            if (!available) return 0;
841
        }
842
    }
843
    if (available > length) available = length;
844
    int left = available;
845
    if (dbgconrecvreadidx + available >= sizeof(dbgconrecvbuf))
846
    {
847
        int bytes = sizeof(dbgconrecvbuf) - dbgconrecvreadidx;
848
        memcpy(buffer, &dbgconrecvbuf[dbgconrecvreadidx], bytes);
849
        dbgconrecvreadidx = 0;
850
        buffer = &buffer[bytes];
851
        left -= bytes;
852
    }
853
    if (left) memcpy(buffer, &dbgconrecvbuf[dbgconrecvreadidx], left);
854
    dbgconrecvreadidx += left;
855
    return available;
856
}
240 theseven 857
 
858
void usb_exit(void)
859
{
860
    usb_drv_exit();
861
}