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
//
427 farthen 6
//    This file is part of emCORE.
15 theseven 7
//
427 farthen 8
//    emCORE is free software: you can redistribute it and/or
15 theseven 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
//
427 farthen 13
//    emCORE is distributed in the hope that it will be useful,
15 theseven 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
427 farthen 19
//    with emCORE.  If not, see <http://www.gnu.org/licenses/>.
15 theseven 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"
685 theseven 37
#include "dbgconsole.h"
85 theseven 38
#ifdef HAVE_I2C
39
#include "i2c.h"
40
#endif
95 theseven 41
#ifdef HAVE_BOOTFLASH
42
#include "bootflash.h"
43
#endif
157 theseven 44
#ifdef HAVE_HWKEYAES
45
#include "hwkeyaes.h"
46
#endif
47
#ifdef HAVE_HMACSHA1
48
#include "hmacsha1.h"
49
#endif
226 theseven 50
#ifdef USB_HAVE_TARGET_SPECIFIC_REQUESTS
51
#include "usbtarget.h"
52
#endif
346 theseven 53
#ifdef HAVE_STORAGE
54
#include "storage.h"
55
#include "disk.h"
56
#include "file.h"
57
#include "dir.h"
347 theseven 58
#include "libc/include/errno.h"
346 theseven 59
#endif
15 theseven 60
 
61
 
62
static uint8_t ctrlresp[2] CACHEALIGN_ATTR;
63
static uint32_t dbgrecvbuf[0x80] CACHEALIGN_ATTR;
64
static uint32_t dbgsendbuf[0x80] CACHEALIGN_ATTR;
65
static uint32_t dbgasyncsendbuf[0x80] CACHEALIGN_ATTR;
66
static char dbgendpoints[4] IBSS_ATTR;
67
 
68
enum dbgaction_t
69
{
70
    DBGACTION_IDLE = 0,
71
    DBGACTION_I2CSEND,
72
    DBGACTION_I2CRECV,
29 theseven 73
    DBGACTION_RESET,
74
    DBGACTION_POWEROFF,
75
    DBGACTION_CWRITE,
76
    DBGACTION_CREAD,
92 theseven 77
    DBGACTION_CFLUSH,
95 theseven 78
    DBGACTION_EXECIMAGE,
127 theseven 79
    DBGACTION_EXECFIRMWARE,
95 theseven 80
    DBGACTION_READBOOTFLASH,
157 theseven 81
    DBGACTION_WRITEBOOTFLASH,
82
    DBGACTION_HWKEYAES,
226 theseven 83
    DBGACTION_HMACSHA1,
346 theseven 84
    DBGACTION_TARGETSPECIFIC,
438 theseven 85
    DBGACTION_STORAGE,
86
    DBGACTION_MALLOC,
87
    DBGACTION_MEMALIGN,
88
    DBGACTION_REALLOC,
89
    DBGACTION_REOWNALLOC,
471 theseven 90
    DBGACTION_FREE,
91
    DBGACTION_FREEMONITOR
15 theseven 92
};
93
 
429 theseven 94
static struct scheduler_thread dbgthread_handle IBSS_ATTR;
346 theseven 95
static uint32_t dbgstack[0x200] STACK_ATTR;
15 theseven 96
struct wakeup dbgwakeup IBSS_ATTR;
97
static enum dbgaction_t dbgaction IBSS_ATTR;
29 theseven 98
static int dbgi2cbus;
99
static int dbgi2cslave;
100
static int dbgactionaddr;
95 theseven 101
static int dbgactionoffset;
29 theseven 102
static int dbgactionlength;
103
static int dbgactionconsoles;
104
static int dbgactiontype;
25 theseven 105
static char dbgconsendbuf[4096];
106
static char dbgconrecvbuf[1024];
107
static int dbgconsendreadidx IBSS_ATTR;
108
static int dbgconsendwriteidx IBSS_ATTR;
109
static int dbgconrecvreadidx IBSS_ATTR;
110
static int dbgconrecvwriteidx IBSS_ATTR;
111
static struct wakeup dbgconsendwakeup IBSS_ATTR;
112
static struct wakeup dbgconrecvwakeup IBSS_ATTR;
113
static bool dbgconsoleattached IBSS_ATTR;
15 theseven 114
 
25 theseven 115
static const char dbgconoverflowstr[] = "\n\n[overflowed]\n\n";
15 theseven 116
 
438 theseven 117
extern int _poolstart;   // These aren't ints at all, but gcc complains about void types being
118
extern int _poolend;     // used here, and we only need the address, so just make it happy...
25 theseven 119
 
35 theseven 120
 
15 theseven 121
static struct usb_device_descriptor CACHEALIGN_ATTR device_descriptor =
122
{
123
    .bLength            = sizeof(struct usb_device_descriptor),
124
    .bDescriptorType    = USB_DT_DEVICE,
125
    .bcdUSB             = 0x0200,
126
    .bDeviceClass       = USB_CLASS_VENDOR_SPEC,
127
    .bDeviceSubClass    = 0xff,
128
    .bDeviceProtocol    = 0xff,
129
    .bMaxPacketSize0    = 64,
130
    .idVendor           = 0xffff,
131
    .idProduct          = 0xe000,
132
    .bcdDevice          = 0x0001,
133
    .iManufacturer      = 1,
134
    .iProduct           = 2,
135
    .iSerialNumber      = 0,
136
    .bNumConfigurations = 1
137
};
138
 
139
static struct usb_config_bundle
140
{
141
    struct usb_config_descriptor config_descriptor;
142
    struct usb_interface_descriptor interface_descriptor;
143
    struct usb_endpoint_descriptor endpoint1_descriptor;
144
    struct usb_endpoint_descriptor endpoint2_descriptor;
145
    struct usb_endpoint_descriptor endpoint3_descriptor;
146
    struct usb_endpoint_descriptor endpoint4_descriptor;
147
} __attribute__((packed)) CACHEALIGN_ATTR config_bundle = 
148
{
149
    .config_descriptor =
150
    {
151
        .bLength             = sizeof(struct usb_config_descriptor),
152
        .bDescriptorType     = USB_DT_CONFIG,
153
        .wTotalLength        = sizeof(struct usb_config_descriptor)
154
                             + sizeof(struct usb_interface_descriptor)
155
                             + sizeof(struct usb_endpoint_descriptor) * 4,
156
        .bNumInterfaces      = 1,
157
        .bConfigurationValue = 1,
158
        .iConfiguration      = 0,
159
        .bmAttributes        = USB_CONFIG_ATT_ONE,
160
        .bMaxPower           = 250
161
    },
162
    .interface_descriptor =
163
    {
164
        .bLength             = sizeof(struct usb_interface_descriptor),
165
        .bDescriptorType     = USB_DT_INTERFACE,
166
        .bInterfaceNumber    = 0,
167
        .bAlternateSetting   = 0,
168
        .bNumEndpoints       = 4,
169
        .bInterfaceClass     = USB_CLASS_VENDOR_SPEC,
170
        .bInterfaceSubClass  = 0xff,
171
        .bInterfaceProtocol  = 0xff,
172
        .iInterface          = 0
173
    },
174
    .endpoint1_descriptor =
175
    {
176
        .bLength             = sizeof(struct usb_endpoint_descriptor),
177
        .bDescriptorType     = USB_DT_ENDPOINT,
178
        .bEndpointAddress    = 0,
179
        .bmAttributes        = USB_ENDPOINT_XFER_BULK,
180
        .wMaxPacketSize      = 0,
181
        .bInterval           = 1
182
    },
183
    .endpoint2_descriptor =
184
    {
185
        .bLength             = sizeof(struct usb_endpoint_descriptor),
186
        .bDescriptorType     = USB_DT_ENDPOINT,
187
        .bEndpointAddress    = 0,
188
        .bmAttributes        = USB_ENDPOINT_XFER_BULK,
189
        .wMaxPacketSize      = 0,
190
        .bInterval           = 1
191
    },
192
    .endpoint3_descriptor =
193
    {
194
        .bLength             = sizeof(struct usb_endpoint_descriptor),
195
        .bDescriptorType     = USB_DT_ENDPOINT,
196
        .bEndpointAddress    = 0,
197
        .bmAttributes        = USB_ENDPOINT_XFER_BULK,
198
        .wMaxPacketSize      = 0,
199
        .bInterval           = 1
200
    },
201
    .endpoint4_descriptor =
202
    {
203
        .bLength             = sizeof(struct usb_endpoint_descriptor),
204
        .bDescriptorType     = USB_DT_ENDPOINT,
205
        .bEndpointAddress    = 0,
206
        .bmAttributes        = USB_ENDPOINT_XFER_BULK,
207
        .wMaxPacketSize      = 0,
208
        .bInterval           = 1
209
    }
210
};
211
 
696 theseven 212
static struct usb_string_descriptor CACHEALIGN_ATTR string_vendor =
15 theseven 213
{
696 theseven 214
    30,
215
    USB_DT_STRING,
216
    {'f', 'r', 'e', 'e', 'm', 'y', 'i', 'p', 'o', 'd', '.', 'o', 'r', 'g'}
217
};
218
 
219
static struct usb_string_descriptor CACHEALIGN_ATTR string_product =
220
{
15 theseven 221
    32,
222
    USB_DT_STRING,
631 theseven 223
    {'e', 'm', 'C', 'O', 'R', 'E', ' ', 'D', 'e', 'b', 'u', 'g', 'g', 'e', 'r'}
15 theseven 224
};
225
 
226
static const struct usb_string_descriptor CACHEALIGN_ATTR lang_descriptor =
227
{
228
    4,
229
    USB_DT_STRING,
230
    {0x0409}
231
};
232
 
233
 
234
void usb_setup_dbg_listener()
235
{
464 theseven 236
    usb_drv_recv(dbgendpoints[0], dbgrecvbuf, 512);
15 theseven 237
}
238
 
239
void usb_handle_control_request(struct usb_ctrlrequest* req)
240
{
241
    const void* addr;
242
    int size = -1;
243
    switch (req->bRequest)
244
    {
245
    case USB_REQ_GET_STATUS:
246
        if (req->bRequestType == USB_DIR_IN) ctrlresp[0] = 1;
247
        else ctrlresp[0] = 0;
248
        ctrlresp[1] = 0;
249
        addr = ctrlresp;
250
        size = 2;
251
        break;
252
    case USB_REQ_CLEAR_FEATURE:
253
        if (req->bRequestType == USB_RECIP_ENDPOINT && req->wValue == USB_ENDPOINT_HALT)
254
            usb_drv_stall(req->wIndex & 0xf, false, req->wIndex >> 7);
255
        size = 0;
256
        break;
257
    case USB_REQ_SET_FEATURE:
258
        size = 0;
259
        break;
260
    case USB_REQ_SET_ADDRESS:
261
        size = 0;
262
        usb_drv_cancel_all_transfers();
263
        usb_drv_set_address(req->wValue);
264
        usb_setup_dbg_listener();
265
        break;
266
    case USB_REQ_GET_DESCRIPTOR:
267
        switch (req->wValue >> 8)
268
        {
269
        case USB_DT_DEVICE:
270
            addr = &device_descriptor;
271
            size = sizeof(device_descriptor);
272
            break;
273
        case USB_DT_OTHER_SPEED_CONFIG:
696 theseven 274
 
15 theseven 275
        case USB_DT_CONFIG:
276
            if ((req->wValue >> 8) == USB_DT_CONFIG)
277
            {
278
                int maxpacket = usb_drv_port_speed() ? 512 : 64;
279
                config_bundle.endpoint1_descriptor.wMaxPacketSize = maxpacket;
280
                config_bundle.endpoint2_descriptor.wMaxPacketSize = maxpacket;
281
                config_bundle.endpoint3_descriptor.wMaxPacketSize = maxpacket;
282
                config_bundle.endpoint4_descriptor.wMaxPacketSize = maxpacket;
283
                config_bundle.config_descriptor.bDescriptorType = USB_DT_CONFIG;
284
            }
285
            else
286
            {
287
                int maxpacket = usb_drv_port_speed() ? 64 : 512;
288
                config_bundle.endpoint1_descriptor.wMaxPacketSize = maxpacket;
289
                config_bundle.endpoint2_descriptor.wMaxPacketSize = maxpacket;
290
                config_bundle.endpoint3_descriptor.wMaxPacketSize = maxpacket;
291
                config_bundle.endpoint4_descriptor.wMaxPacketSize = maxpacket;
292
                config_bundle.config_descriptor.bDescriptorType = USB_DT_OTHER_SPEED_CONFIG;
293
            }
294
            addr = &config_bundle;
295
            size = sizeof(config_bundle);
296
            break;
297
        case USB_DT_STRING:
298
            switch (req->wValue & 0xff)
299
            {
300
            case 0:
301
                addr = &lang_descriptor;
234 theseven 302
                size = lang_descriptor.bLength;
15 theseven 303
                break;
304
            case 1:
696 theseven 305
                addr = &string_vendor;
306
                size = string_vendor.bLength;
234 theseven 307
                break;
15 theseven 308
            case 2:
696 theseven 309
                addr = &string_product;
310
                size = string_product.bLength;
15 theseven 311
                break;
312
            }
313
            break;
314
        }
315
        break;
316
    case USB_REQ_GET_CONFIGURATION:
317
        ctrlresp[0] = 1;
318
        addr = ctrlresp;
319
        size = 1;
320
        break;
321
    case USB_REQ_SET_CONFIGURATION:
322
        usb_drv_cancel_all_transfers();
323
        usb_setup_dbg_listener();
324
        size = 0;
325
        break;
326
    }
327
    if (!size) usb_drv_send_nonblocking(0, NULL, 0);
328
    else if (size == -1)
329
    {
330
        usb_drv_stall(0, true, true);
331
        usb_drv_stall(0, true, false);
332
    }
333
    else
334
    {
335
        usb_drv_recv(0, NULL, 0);
336
        usb_drv_send_nonblocking(0, addr, size > req->wLength ? req->wLength : size);
337
    }
338
}
339
 
29 theseven 340
bool set_dbgaction(enum dbgaction_t action, int addsize)
15 theseven 341
{
342
    if (dbgaction != DBGACTION_IDLE)
343
    {
344
        dbgsendbuf[0] = 3;
29 theseven 345
        usb_drv_send_nonblocking(dbgendpoints[1], dbgsendbuf, 16 + addsize);
15 theseven 346
        return true;
347
    }
348
    dbgaction = action;
349
    wakeup_signal(&dbgwakeup);
350
    return false;
351
}
352
 
353
void reset() __attribute__((noreturn));
354
 
355
void usb_handle_transfer_complete(int endpoint, int dir, int status, int length)
356
{
357
    void* addr = dbgsendbuf;
358
    int size = 0;
359
    if (endpoint == dbgendpoints[0])
360
    {
226 theseven 361
#ifdef USB_HAVE_TARGET_SPECIFIC_REQUESTS
362
        if (dbgrecvbuf[0] >= 0xffff0000)
363
        {
364
            if (!set_dbgaction(DBGACTION_TARGETSPECIFIC, 0))
365
                memcpy(dbgasyncsendbuf, dbgrecvbuf, sizeof(dbgasyncsendbuf));
366
            usb_setup_dbg_listener();
367
            return;
368
        }
369
#endif
15 theseven 370
        switch (dbgrecvbuf[0])
371
        {
28 theseven 372
        case 1:  // GET INFO
15 theseven 373
            dbgsendbuf[0] = 1;
374
            size = 16;
28 theseven 375
            switch (dbgrecvbuf[1])
376
            {
377
            case 0:  // GET VERSION INFO
85 theseven 378
                dbgsendbuf[1] = VERSION_SVN_INT;
379
                dbgsendbuf[2] = VERSION_MAJOR | (VERSION_MINOR << 8)
429 theseven 380
                              | (VERSION_PATCH << 16) | (2 << 24);
85 theseven 381
                dbgsendbuf[3] = PLATFORM_ID;
28 theseven 382
                break;
383
            case 1:  // GET PACKET SIZE INFO
384
                dbgsendbuf[1] = 0x02000200;
385
                dbgsendbuf[2] = usb_drv_get_max_out_size();
386
                dbgsendbuf[3] = usb_drv_get_max_in_size();
387
                break;
35 theseven 388
            case 2:  // GET USER MEMORY INFO
438 theseven 389
                dbgsendbuf[1] = (uint32_t)&_poolstart;
390
                dbgsendbuf[2] = (uint32_t)&_poolend;
35 theseven 391
                break;
28 theseven 392
            default:
393
                dbgsendbuf[0] = 2;
394
            }
15 theseven 395
            break;
396
        case 2:  // RESET
29 theseven 397
            if (dbgrecvbuf[1])
398
            {
399
                if (set_dbgaction(DBGACTION_RESET, 0)) break;
400
                dbgsendbuf[0] = 1;
401
                size = 16;
402
            }
403
            else reset();
15 theseven 404
            break;
405
        case 3:  // POWER OFF
29 theseven 406
            if (set_dbgaction(DBGACTION_POWEROFF, 0)) break;
407
            dbgactiontype = dbgrecvbuf[1];
408
            dbgsendbuf[0] = 1;
409
            size = 16;
15 theseven 410
            break;
411
        case 4:  // READ MEMORY
412
            dbgsendbuf[0] = 1;
413
            memcpy(&dbgsendbuf[4], (const void*)dbgrecvbuf[1], dbgrecvbuf[2]);
414
            size = dbgrecvbuf[2] + 16;
415
            break;
416
        case 5:  // WRITE MEMORY
417
            dbgsendbuf[0] = 1;
418
            memcpy((void*)dbgrecvbuf[1], &dbgrecvbuf[4], dbgrecvbuf[2]);
419
            size = 16;
420
            break;
421
        case 6:  // READ DMA
422
            dbgsendbuf[0] = 1;
423
            usb_drv_send_nonblocking(dbgendpoints[1], dbgsendbuf, 16);
424
            usb_drv_send_nonblocking(dbgendpoints[3], (const void*)dbgrecvbuf[1], dbgrecvbuf[2]);
425
            break;
426
        case 7:  // WRITE DMA
427
            dbgsendbuf[0] = 1;
428
            size = 16;
429
            usb_drv_recv(dbgendpoints[2], (void*)dbgrecvbuf[1], dbgrecvbuf[2]);
430
            break;
85 theseven 431
#ifdef HAVE_I2C
15 theseven 432
        case 8:  // READ I2C
29 theseven 433
            if (set_dbgaction(DBGACTION_I2CRECV, dbgrecvbuf[1] >> 24)) break;
15 theseven 434
            dbgi2cbus = dbgrecvbuf[1] & 0xff;
435
            dbgi2cslave = (dbgrecvbuf[1] >> 8) & 0xff;
29 theseven 436
            dbgactionaddr = (dbgrecvbuf[1] >> 16) & 0xff;
437
            dbgactionlength = dbgrecvbuf[1] >> 24;
175 theseven 438
            if (!dbgactionlength) dbgactionlength = 256;
15 theseven 439
            break;
440
        case 9:  // WRITE I2C
29 theseven 441
            if (set_dbgaction(DBGACTION_I2CSEND, 0)) break;
15 theseven 442
            dbgi2cbus = dbgrecvbuf[1] & 0xff;
443
            dbgi2cslave = (dbgrecvbuf[1] >> 8) & 0xff;
29 theseven 444
            dbgactionaddr = (dbgrecvbuf[1] >> 16) & 0xff;
445
            dbgactionlength = dbgrecvbuf[1] >> 24;
175 theseven 446
            if (!dbgactionlength) dbgactionlength = 256;
212 theseven 447
            memcpy(dbgasyncsendbuf, &dbgrecvbuf[4], dbgactionlength);
15 theseven 448
            break;
85 theseven 449
#endif
25 theseven 450
        case 10:  // READ CONSOLE
451
            dbgconsoleattached = true;
452
            int bytes = dbgconsendwriteidx - dbgconsendreadidx;
336 theseven 453
            int used = 0;
25 theseven 454
            if (bytes)
455
            {
456
                if (bytes < 0) bytes += sizeof(dbgconsendbuf);
336 theseven 457
                used = bytes;
25 theseven 458
                if (bytes > dbgrecvbuf[1]) bytes = dbgrecvbuf[1];
459
                int readbytes = bytes;
460
                char* outptr = (char*)&dbgsendbuf[4];
461
                if (dbgconsendreadidx + bytes >= sizeof(dbgconsendbuf))
462
                {
463
                    readbytes = sizeof(dbgconsendbuf) - dbgconsendreadidx;
464
                    memcpy(outptr, &dbgconsendbuf[dbgconsendreadidx], readbytes);
465
                    dbgconsendreadidx = 0;
466
                    outptr = &outptr[readbytes];
467
                    readbytes = bytes - readbytes;
468
                }
469
                if (readbytes) memcpy(outptr, &dbgconsendbuf[dbgconsendreadidx], readbytes);
470
                dbgconsendreadidx += readbytes;
26 theseven 471
                wakeup_signal(&dbgconsendwakeup);
25 theseven 472
            }
473
            dbgsendbuf[0] = 1;
474
            dbgsendbuf[1] = bytes;
475
            dbgsendbuf[2] = sizeof(dbgconsendbuf);
336 theseven 476
            dbgsendbuf[3] = used - bytes;
25 theseven 477
            size = 16 + dbgrecvbuf[1];
478
            break;
26 theseven 479
        case 11:  // WRITE CONSOLE
480
            bytes = dbgconrecvreadidx - dbgconrecvwriteidx - 1;
481
            if (bytes < 0) bytes += sizeof(dbgconrecvbuf);
482
            if (bytes)
483
            {
484
                if (bytes > dbgrecvbuf[1]) bytes = dbgrecvbuf[1];
485
                int writebytes = bytes;
486
                char* readptr = (char*)&dbgrecvbuf[4];
487
                if (dbgconrecvwriteidx + bytes >= sizeof(dbgconrecvbuf))
488
                {
489
                    writebytes = sizeof(dbgconrecvbuf) - dbgconrecvwriteidx;
490
                    memcpy(&dbgconrecvbuf[dbgconrecvwriteidx], readptr, writebytes);
491
                    dbgconrecvwriteidx = 0;
492
                    readptr = &readptr[writebytes];
493
                    writebytes = bytes - writebytes;
494
                }
495
                if (writebytes) memcpy(&dbgconrecvbuf[dbgconrecvwriteidx], readptr, writebytes);
496
                dbgconrecvwriteidx += writebytes;
497
                wakeup_signal(&dbgconrecvwakeup);
498
            }
499
            dbgsendbuf[0] = 1;
500
            dbgsendbuf[1] = bytes;
501
            dbgsendbuf[2] = sizeof(dbgconrecvbuf);
502
            dbgsendbuf[3] = dbgconrecvreadidx - dbgconrecvwriteidx - 1;
503
            size = 16;
504
            break;
29 theseven 505
        case 12:  // CWRITE
506
            if (set_dbgaction(DBGACTION_CWRITE, 0)) break;
507
            dbgactionconsoles = dbgrecvbuf[1];
508
            dbgactionlength = dbgrecvbuf[2];
509
            memcpy(dbgasyncsendbuf, &dbgrecvbuf[4], dbgactionlength);
510
            break;
511
        case 13:  // CREAD
512
            if (set_dbgaction(DBGACTION_CREAD, dbgrecvbuf[2])) break;
513
            dbgactionconsoles = dbgrecvbuf[1];
514
            dbgactionlength = dbgrecvbuf[2];
515
            break;
516
        case 14:  // CFLUSH
517
            if (set_dbgaction(DBGACTION_CFLUSH, 0)) break;
518
            dbgactionconsoles = dbgrecvbuf[1];
519
            break;
31 theseven 520
        case 15:  // GET PROCESS INFO
521
            dbgsendbuf[0] = 1;
522
            dbgsendbuf[1] = SCHEDULER_THREAD_INFO_VERSION;
429 theseven 523
            dbgsendbuf[2] = (uint32_t)head_thread;
524
            size = 16;
31 theseven 525
            break;
34 theseven 526
        case 16:  // FREEZE SCHEDULER
54 theseven 527
            dbgsendbuf[1] = scheduler_freeze(dbgrecvbuf[1]);
595 theseven 528
            scheduler_switch(NULL, NULL);
34 theseven 529
            dbgsendbuf[0] = 1;
530
            size = 16;
531
            break;
35 theseven 532
        case 17:  // SUSPEND THREAD
54 theseven 533
            if (dbgrecvbuf[1])
534
            {
429 theseven 535
                if (thread_suspend((struct scheduler_thread*)(dbgrecvbuf[2])) == ALREADY_SUSPENDED)
536
                    dbgsendbuf[1] = 1;
54 theseven 537
                else dbgsendbuf[1] = 0;
538
            }
539
            else
540
            {
429 theseven 541
                if (thread_resume((struct scheduler_thread*)(dbgrecvbuf[2])) == ALREADY_RESUMED)
542
                    dbgsendbuf[1] = 0;
54 theseven 543
                else dbgsendbuf[1] = 1;
544
            }
35 theseven 545
            dbgsendbuf[0] = 1;
546
            size = 16;
547
            break;
548
        case 18:  // KILL THREAD
429 theseven 549
            thread_terminate((struct scheduler_thread*)(dbgrecvbuf[1]));
35 theseven 550
            dbgsendbuf[0] = 1;
551
            size = 16;
552
            break;
438 theseven 553
        case 19:  // CREATE THREAD
35 theseven 554
            dbgsendbuf[0] = 1;
429 theseven 555
            dbgsendbuf[1] = (uint32_t)thread_create(NULL, (const char*)(dbgsendbuf[1]),
556
                                                    (const void*)(dbgsendbuf[2]),
557
                                                    (char*)(dbgsendbuf[3]),
558
                                                    dbgsendbuf[4], (enum thread_type)dbgsendbuf[5],
559
                                                    dbgsendbuf[6], dbgsendbuf[7]);
35 theseven 560
            size = 16;
561
            break;
562
        case 20:  // FLUSH CACHE
563
            clean_dcache();
564
            invalidate_icache();
565
            dbgsendbuf[0] = 1;
566
            size = 16;
567
            break;
92 theseven 568
        case 21:  // EXECIMAGE
569
            if (set_dbgaction(DBGACTION_EXECIMAGE, 0)) break;
570
            dbgactionaddr = dbgrecvbuf[1];
453 theseven 571
            dbgactiontype = dbgrecvbuf[2];
92 theseven 572
            break;
95 theseven 573
#ifdef HAVE_BOOTFLASH
574
        case 22:  // READ BOOT FLASH
575
            if (set_dbgaction(DBGACTION_READBOOTFLASH, 0)) break;
576
            dbgactionaddr = dbgrecvbuf[1];
577
            dbgactionoffset = dbgrecvbuf[2];
578
            dbgactionlength = dbgrecvbuf[3];
579
            break;
580
        case 23:  // WRITE BOOT FLASH
581
            if (set_dbgaction(DBGACTION_WRITEBOOTFLASH, 0)) break;
582
            dbgactionaddr = dbgrecvbuf[1];
583
            dbgactionoffset = dbgrecvbuf[2];
584
            dbgactionlength = dbgrecvbuf[3];
585
            break;
586
#endif
127 theseven 587
        case 24:  // EXECFIRMWARE
588
            if (set_dbgaction(DBGACTION_EXECFIRMWARE, 0)) break;
589
            dbgactionaddr = dbgrecvbuf[1];
438 theseven 590
            dbgactionoffset = dbgrecvbuf[2];
591
            dbgactionlength = dbgrecvbuf[3];
127 theseven 592
            break;
157 theseven 593
#ifdef HAVE_HWKEYAES
594
        case 25:  // HWKEYAES
595
            if (set_dbgaction(DBGACTION_HWKEYAES, 0)) break;
596
            dbgactiontype = ((uint8_t*)dbgrecvbuf)[4];
597
            dbgactionoffset = ((uint16_t*)dbgrecvbuf)[3];
598
            dbgactionaddr = dbgrecvbuf[2];
599
            dbgactionlength = dbgrecvbuf[3];
179 theseven 600
            break;
157 theseven 601
#endif
602
#ifdef HAVE_HMACSHA1
603
        case 26:  // HMACSHA1
604
            if (set_dbgaction(DBGACTION_HMACSHA1, 0)) break;
605
            dbgactionaddr = dbgrecvbuf[1];
606
            dbgactionlength = dbgrecvbuf[2];
607
            dbgactionoffset = dbgrecvbuf[3];
179 theseven 608
            break;
157 theseven 609
#endif
346 theseven 610
#ifdef HAVE_STORAGE
611
        case 27:  // STORAGE_GET_INFO
612
        case 28:  // STORAGE_READ_SECTORS_MD
613
        case 29:  // STORAGE_WRITE_SECTORS_MD
614
        case 30:  // FILE_OPEN
615
        case 31:  // FILESIZE
616
        case 32:  // READ
617
        case 33:  // WRITE
618
        case 34:  // LSEEK
619
        case 35:  // FTRUNCATE
620
        case 36:  // FSYNC
621
        case 37:  // CLOSE
622
        case 38:  // CLOSE_MONITOR_FILES
623
        case 39:  // RELEASE_FILES
624
        case 40:  // REMOVE
625
        case 41:  // RENAME
626
        case 42:  // OPENDIR
627
        case 43:  // READDIR
628
        case 44:  // CLOSEDIR
629
        case 45:  // CLOSE_MONITOR_DIRS
630
        case 46:  // RELEASE_DIRS
631
        case 47:  // MKDIR
632
        case 48:  // RMDIR
633
        case 49:  // ERRNO
634
#ifdef HAVE_HOTSWAP
635
        case 50:  // DISK_MOUNT
636
        case 51:  // DISK_UNMOUNT
637
#endif
479 theseven 638
        case 58:  // FAT_ENABLE_FLUSHING
634 theseven 639
        case 59:  // FAT_SIZE
346 theseven 640
            if (!set_dbgaction(DBGACTION_STORAGE, 0))
641
                memcpy(dbgasyncsendbuf, dbgrecvbuf, sizeof(dbgasyncsendbuf));
642
            break;
643
#endif
438 theseven 644
        case 52:  // MALLOC
645
            if (set_dbgaction(DBGACTION_MALLOC, 0)) break;
646
            dbgactionlength = dbgrecvbuf[1];
647
            break;
648
        case 53:  // MEMALIGN
649
            if (set_dbgaction(DBGACTION_MEMALIGN, 0)) break;
650
            dbgactionoffset = dbgrecvbuf[1];
651
            dbgactionlength = dbgrecvbuf[2];
652
            break;
653
        case 54:  // REALLOC
654
            if (set_dbgaction(DBGACTION_REALLOC, 0)) break;
655
            dbgactionaddr = dbgrecvbuf[1];
656
            dbgactionlength = dbgrecvbuf[2];
657
            break;
658
        case 55:  // REOWNALLOC
659
            if (set_dbgaction(DBGACTION_REOWNALLOC, 0)) break;
660
            dbgactionaddr = dbgrecvbuf[1];
661
            dbgactionoffset = dbgrecvbuf[2];
662
            break;
663
        case 56:  // FREE
664
            if (set_dbgaction(DBGACTION_FREE, 0)) break;
665
            dbgactionaddr = dbgrecvbuf[1];
666
            break;
471 theseven 667
        case 57:  // FREE MONITOR ALLOCATIONS
668
            if (set_dbgaction(DBGACTION_FREEMONITOR, 0)) break;
669
            break;
15 theseven 670
        default:
671
            dbgsendbuf[0] = 2;
672
            size = 16;
673
        }
674
        usb_setup_dbg_listener();
675
        if (size) usb_drv_send_nonblocking(dbgendpoints[1], addr, size);
676
    }
677
}
678
 
679
void usb_handle_bus_reset(void)
680
{
681
    dbgendpoints[0] = usb_drv_request_endpoint(USB_ENDPOINT_XFER_BULK, USB_DIR_OUT);
682
    dbgendpoints[1] = usb_drv_request_endpoint(USB_ENDPOINT_XFER_BULK, USB_DIR_IN);
683
    dbgendpoints[2] = usb_drv_request_endpoint(USB_ENDPOINT_XFER_BULK, USB_DIR_OUT);
684
    dbgendpoints[3] = usb_drv_request_endpoint(USB_ENDPOINT_XFER_BULK, USB_DIR_IN);
685
    config_bundle.endpoint1_descriptor.bEndpointAddress = dbgendpoints[0];
686
    config_bundle.endpoint2_descriptor.bEndpointAddress = dbgendpoints[1];
687
    config_bundle.endpoint3_descriptor.bEndpointAddress = dbgendpoints[2];
688
    config_bundle.endpoint4_descriptor.bEndpointAddress = dbgendpoints[3];
689
    usb_setup_dbg_listener();
690
}
691
 
692
void dbgthread(void)
693
{
429 theseven 694
    struct scheduler_thread* t;
15 theseven 695
    while (1)
696
    {
697
        wakeup_wait(&dbgwakeup, TIMEOUT_BLOCK);
429 theseven 698
        for (t = head_thread; t; t = t->thread_next)
699
            if (t->state == THREAD_DEFUNCT)
15 theseven 700
            {
429 theseven 701
                if (t->block_type == THREAD_DEFUNCT_STKOV)
35 theseven 702
                {
429 theseven 703
                    if (t->name) cprintf(1, "\n*PANIC*\nStack overflow! (%s)\n", t->name);
704
                    else cprintf(1, "\n*PANIC*\nStack overflow! (%08X)\n", t);
35 theseven 705
                }
429 theseven 706
                t->state = THREAD_DEFUNCT_ACK;
15 theseven 707
            }
708
        if (dbgaction != DBGACTION_IDLE)
709
        {
710
            switch (dbgaction)
711
            {
85 theseven 712
#ifdef HAVE_I2C
15 theseven 713
            case DBGACTION_I2CSEND:
29 theseven 714
                i2c_send(dbgi2cbus, dbgi2cslave, dbgactionaddr,
715
                         (uint8_t*)dbgasyncsendbuf, dbgactionlength);
15 theseven 716
                dbgasyncsendbuf[0] = 1;
717
                usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
718
                break;
719
            case DBGACTION_I2CRECV:
29 theseven 720
                i2c_recv(dbgi2cbus, dbgi2cslave, dbgactionaddr,
721
                         (uint8_t*)(&dbgasyncsendbuf[4]), dbgactionlength);
15 theseven 722
                dbgasyncsendbuf[0] = 1;
29 theseven 723
                usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16 + dbgactionlength);
15 theseven 724
                break;
85 theseven 725
#endif
15 theseven 726
            case DBGACTION_POWEROFF:
127 theseven 727
                if (dbgactiontype) shutdown(true);
54 theseven 728
                power_off();
15 theseven 729
                break;
29 theseven 730
            case DBGACTION_RESET:
439 theseven 731
                shutdown(false);
29 theseven 732
                reset();
733
                break;
734
            case DBGACTION_CWRITE:
735
                cwrite(dbgactionconsoles, (const char*)dbgasyncsendbuf, dbgactionlength);
736
                dbgasyncsendbuf[0] = 1;
737
                usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
738
                break;
739
            case DBGACTION_CREAD:
740
                dbgasyncsendbuf[0] = 1;
30 theseven 741
                dbgasyncsendbuf[1] = cread(dbgactionconsoles, (char*)&dbgasyncsendbuf[4],
742
                                           dbgactionlength, 0);
226 theseven 743
                usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16 + dbgactionlength);
29 theseven 744
                break;
745
            case DBGACTION_CFLUSH:
746
                cflush(dbgactionconsoles);
747
                dbgasyncsendbuf[0] = 1;
748
                usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
749
                break;
92 theseven 750
            case DBGACTION_EXECIMAGE:
751
                dbgasyncsendbuf[0] = 1;
453 theseven 752
                dbgasyncsendbuf[1] = (uint32_t)execimage((void*)dbgactionaddr, dbgactiontype);
92 theseven 753
                usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
754
                break;
127 theseven 755
            case DBGACTION_EXECFIRMWARE:
756
                dbgasyncsendbuf[0] = 1;
757
                usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
439 theseven 758
                shutdown(false);
438 theseven 759
                execfirmware((void*)dbgactionaddr, (void*)dbgactionoffset,
760
                             (size_t)dbgactionlength);
95 theseven 761
#ifdef HAVE_BOOTFLASH
762
            case DBGACTION_READBOOTFLASH:
763
                bootflash_readraw((void*)dbgactionaddr, dbgactionoffset, dbgactionlength);
764
                dbgasyncsendbuf[0] = 1;
765
                usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
766
                break;
767
            case DBGACTION_WRITEBOOTFLASH:
768
                bootflash_writeraw((void*)dbgactionaddr, dbgactionoffset, dbgactionlength);
769
                dbgasyncsendbuf[0] = 1;
770
                usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
771
                break;
772
#endif
157 theseven 773
#ifdef HAVE_HWKEYAES
774
            case DBGACTION_HWKEYAES:
775
                hwkeyaes((enum hwkeyaes_direction) dbgactiontype, dbgactionoffset,
776
                         (void*)dbgactionaddr, dbgactionlength);
777
                dbgasyncsendbuf[0] = 1;
778
                usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
779
                break;
780
#endif
781
#ifdef HAVE_HMACSHA1
782
            case DBGACTION_HMACSHA1:
783
                hmacsha1((void*)dbgactionaddr, dbgactionlength, (void*)dbgactionoffset);
784
                dbgasyncsendbuf[0] = 1;
785
                usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
786
                break;
787
#endif
226 theseven 788
#ifdef USB_HAVE_TARGET_SPECIFIC_REQUESTS
789
            case DBGACTION_TARGETSPECIFIC:
790
            {
791
                int size = usb_target_handle_request(dbgasyncsendbuf, sizeof(dbgasyncsendbuf));
792
                if (size) usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, size);
793
                break;
15 theseven 794
            }
226 theseven 795
#endif
346 theseven 796
#ifdef HAVE_STORAGE
797
            case DBGACTION_STORAGE:
798
                switch(dbgasyncsendbuf[0])
799
                {
800
                case 27:  // STORAGE_GET_INFO
801
                    dbgasyncsendbuf[0] = 1;
802
                    storage_get_info(dbgasyncsendbuf[1],
803
                                     (struct storage_info*)&dbgasyncsendbuf[4]);
804
                    dbgasyncsendbuf[1] = 1;
805
                    usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf,
806
                                             16 + sizeof(struct storage_info));
807
                    break;
808
                case 28:  // STORAGE_READ_SECTORS_MD
809
                {
810
                    dbgasyncsendbuf[0] = 1;
811
                    int rc = storage_read_sectors_md(dbgasyncsendbuf[1],
812
                                                     dbgasyncsendbuf[2]
813
                                                   | (((uint64_t)(dbgasyncsendbuf[3]) << 32)),
814
                                                     dbgasyncsendbuf[4],
815
                                                     (void*)(dbgasyncsendbuf[5]));
816
                    dbgasyncsendbuf[1] = (uint32_t)rc;
817
                    usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
818
                    break;
819
                }
820
                case 29:  // STORAGE_WRITE_SECTORS_MD
821
                {
822
                    dbgasyncsendbuf[0] = 1;
823
                    int rc = storage_write_sectors_md(dbgasyncsendbuf[1],
824
                                                      dbgasyncsendbuf[2]
825
                                                    | (((uint64_t)(dbgasyncsendbuf[3]) << 32)),
826
                                                      dbgasyncsendbuf[4],
827
                                                      (void*)(dbgasyncsendbuf[5]));
828
                    dbgasyncsendbuf[1] = (uint32_t)rc;
829
                    usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
830
                    break;
831
                }
832
                case 30:  // FILE_OPEN
833
                {
834
                    dbgasyncsendbuf[0] = 1;
835
                    int fd = file_open((char*)(&dbgasyncsendbuf[4]), (int)(dbgasyncsendbuf[1]));
836
                    dbgasyncsendbuf[1] = (uint32_t)fd;
837
                    usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
838
                    break;
839
                }
840
                case 31:  // FILESIZE
841
                    dbgasyncsendbuf[0] = 1;
842
                    dbgasyncsendbuf[1] = (uint32_t)filesize((int)(dbgasyncsendbuf[1]));
843
                    usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
844
                    break;
845
                case 32:  // READ
846
                    dbgasyncsendbuf[0] = 1;
847
                    dbgasyncsendbuf[1] = (uint32_t)read((int)(dbgasyncsendbuf[1]),
848
                                                        (void*)(dbgasyncsendbuf[2]),
849
                                                        (size_t)(dbgasyncsendbuf[3]));
850
                    usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
851
                    break;
852
                case 33:  // WRITE
853
                    dbgasyncsendbuf[0] = 1;
854
                    dbgasyncsendbuf[1] = (uint32_t)write((int)(dbgasyncsendbuf[1]),
855
                                                         (void*)(dbgasyncsendbuf[2]),
856
                                                         (size_t)(dbgasyncsendbuf[3]));
857
                    usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
858
                    break;
859
                case 34:  // LSEEK
860
                    dbgasyncsendbuf[0] = 1;
861
                    dbgasyncsendbuf[1] = (uint32_t)lseek((int)(dbgasyncsendbuf[1]),
862
                                                         (off_t)(dbgasyncsendbuf[2]),
863
                                                         (int)(dbgasyncsendbuf[3]));
864
                    usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
865
                    break;
866
                case 35:  // FTRUNCATE
867
                    dbgasyncsendbuf[0] = 1;
868
                    dbgasyncsendbuf[1] = (uint32_t)ftruncate((int)(dbgasyncsendbuf[1]),
869
                                                             (off_t)(dbgasyncsendbuf[2]));
870
                    usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
871
                    break;
872
                case 36:  // FSYNC
873
                    dbgasyncsendbuf[0] = 1;
874
                    dbgasyncsendbuf[1] = (uint32_t)fsync((int)(dbgasyncsendbuf[1]));
875
                    usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
876
                    break;
877
                case 37:  // CLOSE
878
                    dbgasyncsendbuf[0] = 1;
879
                    dbgasyncsendbuf[1] = (uint32_t)close((int)(dbgasyncsendbuf[1]));
880
                    usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
881
                    break;
882
                case 38:  // CLOSE_MONITOR_FILES
883
                    dbgasyncsendbuf[0] = 1;
884
                    dbgasyncsendbuf[1] = (uint32_t)close_all_of_process(current_thread);
885
                    usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
886
                    break;
887
                case 39:  // RELEASE_FILES
888
                    dbgasyncsendbuf[0] = 1;
889
                    dbgasyncsendbuf[1] = (uint32_t)release_files((int)(dbgasyncsendbuf[1]));
890
                    usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
891
                    break;
892
                case 40:  // REMOVE
893
                    dbgasyncsendbuf[0] = 1;
894
                    dbgasyncsendbuf[1] = (uint32_t)remove((char*)(&dbgasyncsendbuf[4]));
895
                    usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
896
                    break;
897
                case 41:  // RENAME
898
                    dbgasyncsendbuf[0] = 1;
899
                    dbgasyncsendbuf[1] = (uint32_t)rename((char*)(&dbgasyncsendbuf[4]),
900
                                                          (char*)(&dbgasyncsendbuf[66]));
901
                    usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
902
                    break;
903
                case 42:  // OPENDIR
904
                    dbgasyncsendbuf[0] = 1;
905
                    dbgasyncsendbuf[1] = (uint32_t)opendir((char*)(&dbgasyncsendbuf[4]));
906
                    usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
907
                    break;
908
                case 43:  // READDIR
909
                    dbgasyncsendbuf[0] = 1;
910
                    dbgasyncsendbuf[3] = (uint32_t)readdir((DIR*)(dbgasyncsendbuf[1]));
911
                    dbgasyncsendbuf[1] = 1;
912
                    dbgasyncsendbuf[2] = MAX_PATH;
913
                    usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
914
                    break;
915
                case 44:  // CLOSEDIR
916
                    dbgasyncsendbuf[0] = 1;
917
                    dbgasyncsendbuf[1] = (uint32_t)closedir((DIR*)(dbgasyncsendbuf[1]));
918
                    usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
919
                    break;
920
                case 45:  // CLOSE_MONITOR_DIRS
921
                    dbgasyncsendbuf[0] = 1;
922
                    dbgasyncsendbuf[1] = (uint32_t)closedir_all_of_process(current_thread);
923
                    usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
924
                    break;
925
                case 46:  // RELEASE_DIRS
926
                    dbgasyncsendbuf[0] = 1;
927
                    dbgasyncsendbuf[1] = (uint32_t)release_dirs((int)(dbgasyncsendbuf[1]));
928
                    usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
929
                    break;
930
                case 47:  // MKDIR
931
                    dbgasyncsendbuf[0] = 1;
932
                    dbgasyncsendbuf[1] = (uint32_t)mkdir((char*)(&dbgasyncsendbuf[4]));
933
                    usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
934
                    break;
935
                case 48:  // RMDIR
936
                    dbgasyncsendbuf[0] = 1;
937
                    dbgasyncsendbuf[1] = (uint32_t)rmdir((char*)(&dbgasyncsendbuf[4]));
938
                    usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
939
                    break;
940
                case 49:  // ERRNO
941
                    dbgasyncsendbuf[0] = 1;
942
                    dbgasyncsendbuf[1] = (uint32_t)errno;
943
                    usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
944
                    break;
945
#ifdef HAVE_HOTSWAP
946
                case 50:  // DISK_MOUNT
947
                    dbgasyncsendbuf[0] = 1;
948
                    dbgasyncsendbuf[1] = (uint32_t)disk_mount((int)(dbgasyncsendbuf[1]));
949
                    usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
950
                    break;
951
                case 51:  // DISK_UNMOUNT
952
                    dbgasyncsendbuf[0] = 1;
953
                    dbgasyncsendbuf[1] = (uint32_t)disk_unmount((int)(dbgasyncsendbuf[1]));
954
                    usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
955
                    break;
956
#endif
479 theseven 957
                case 58:  // FAT_ENABLE_FLUSHING
958
                    dbgasyncsendbuf[0] = 1;
959
                    fat_enable_flushing((bool)(dbgasyncsendbuf[1]));
960
                    usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
961
                    break;
634 theseven 962
                case 59:  // FAT_SIZE
963
                    dbgasyncsendbuf[0] = 1;
964
                    fat_size_mv(dbgasyncsendbuf[1], &dbgasyncsendbuf[1], &dbgasyncsendbuf[2]);
965
                    usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
966
                    break;
346 theseven 967
                }
968
                break;
969
#endif
438 theseven 970
            case DBGACTION_MALLOC:
971
                dbgasyncsendbuf[0] = 1;
972
                dbgasyncsendbuf[1] = (uint32_t)malloc((size_t)dbgactionlength);
973
                usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
974
                break;
975
            case DBGACTION_MEMALIGN:
976
                dbgasyncsendbuf[0] = 1;
977
                dbgasyncsendbuf[1] = (uint32_t)memalign((size_t)dbgactionoffset,
978
                                                        (size_t)dbgactionlength);
979
                usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
980
                break;
981
            case DBGACTION_REALLOC:
982
                dbgasyncsendbuf[0] = 1;
983
                dbgasyncsendbuf[1] = (uint32_t)realloc((void*)dbgactionaddr,
984
                                                       (size_t)dbgactionlength);
985
                usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
986
                break;
987
            case DBGACTION_REOWNALLOC:
988
                dbgasyncsendbuf[0] = 1;
989
                reownalloc((void*)dbgactionaddr, (void*)dbgactionoffset);
990
                usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
991
                break;
992
            case DBGACTION_FREE:
993
                dbgasyncsendbuf[0] = 1;
994
                free((void*)dbgactionaddr);
995
                usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
996
                break;
471 theseven 997
            case DBGACTION_FREEMONITOR:
998
                dbgasyncsendbuf[0] = 1;
999
                dbgasyncsendbuf[1] = (uint32_t)free_all_of_thread(current_thread);
1000
                usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
1001
                break;
226 theseven 1002
            }
15 theseven 1003
            dbgaction = DBGACTION_IDLE;
1004
        }
1005
    }
1006
}
1007
 
1008
void usb_init(void)
1009
{
1010
    dbgaction = DBGACTION_IDLE;
1011
    wakeup_init(&dbgwakeup);
25 theseven 1012
    dbgconsendreadidx = 0;
1013
    dbgconsendwriteidx = 0;
1014
    dbgconrecvreadidx = 0;
1015
    dbgconrecvwriteidx = 0;
1016
    wakeup_init(&dbgconsendwakeup);
1017
    wakeup_init(&dbgconrecvwakeup);
85 theseven 1018
    dbgconsoleattached = false;
429 theseven 1019
    thread_create(&dbgthread_handle, "monitor worker", dbgthread, dbgstack,
1020
                  sizeof(dbgstack), CORE_THREAD, 255, true);
15 theseven 1021
    usb_drv_init();
1022
}
25 theseven 1023
 
1024
int dbgconsole_getfree() ICODE_ATTR;
1025
int dbgconsole_getfree()
1026
{
1027
    int free = dbgconsendreadidx - dbgconsendwriteidx - 1;
1028
    if (free < 0) free += sizeof(dbgconsendbuf);
1029
    return free;
1030
}
1031
 
704 theseven 1032
int dbgconsole_makespace(int length, bool safe) ICODE_ATTR;
1033
int dbgconsole_makespace(int length, bool safe)
25 theseven 1034
{
1035
    int free = dbgconsole_getfree();
704 theseven 1036
    while (!free && dbgconsoleattached && !safe)
25 theseven 1037
    {
336 theseven 1038
        dbgconsoleattached = false;
1039
        wakeup_wait(&dbgconsendwakeup, 2000000);
25 theseven 1040
        free = dbgconsole_getfree();
1041
    }
1042
    if (free) return free > length ? length : free;
1043
    if (length > sizeof(dbgconsendbuf) - 17) length = sizeof(dbgconsendbuf) - 17;
1044
    uint32_t mode = enter_critical_section();
1045
    dbgconsendreadidx += length;
1046
    if (dbgconsendreadidx >= sizeof(dbgconsendbuf))
1047
        dbgconsendreadidx -= sizeof(dbgconsendbuf);
1048
    int offset = 0;
1049
    int idx = dbgconsendreadidx;
1050
    if (idx + 16 >= sizeof(dbgconsendbuf))
1051
    {
1052
        offset = sizeof(dbgconsendbuf) - dbgconsendreadidx;
1053
        memcpy(&dbgconsendbuf[dbgconsendreadidx], dbgconoverflowstr, offset);
1054
        idx = 0;
1055
    }
1056
    if (offset != 16) memcpy(&dbgconsendbuf[idx], &dbgconoverflowstr[offset], 16 - offset);
1057
    leave_critical_section(mode);
1058
    return length;
1059
}
1060
 
704 theseven 1061
void dbgconsole_putc_internal(char string, bool safe)
25 theseven 1062
{
704 theseven 1063
    dbgconsole_makespace(1, safe);
25 theseven 1064
    dbgconsendbuf[dbgconsendwriteidx++] = string;
1065
    if (dbgconsendwriteidx >= sizeof(dbgconsendbuf))
1066
        dbgconsendwriteidx -= sizeof(dbgconsendbuf);
1067
}
1068
 
704 theseven 1069
void dbgconsole_putc(char string)
25 theseven 1070
{
704 theseven 1071
    dbgconsole_putc_internal(string, false);
1072
}
1073
 
1074
void dbgconsole_sputc(char string)
1075
{
1076
    dbgconsole_putc_internal(string, true);
1077
}
1078
 
1079
void dbgconsole_write_internal(const char* string, size_t length, bool safe)
1080
{
25 theseven 1081
    while (length)
1082
    {
704 theseven 1083
        int space = dbgconsole_makespace(length, safe);
25 theseven 1084
        if (dbgconsendwriteidx + space >= sizeof(dbgconsendbuf))
1085
        {
1086
            int bytes = sizeof(dbgconsendbuf) - dbgconsendwriteidx;
1087
            memcpy(&dbgconsendbuf[dbgconsendwriteidx], string, bytes);
1088
            dbgconsendwriteidx = 0;
1089
            string = &string[bytes];
1090
            space -= bytes;
1091
            length -= bytes;
1092
        }
1093
        if (space) memcpy(&dbgconsendbuf[dbgconsendwriteidx], string, space);
1094
        dbgconsendwriteidx += space;
1095
        string = &string[space];
1096
        length -= space;
1097
    }
1098
}
1099
 
704 theseven 1100
void dbgconsole_write(const char* string, size_t length)
1101
{
1102
    dbgconsole_write_internal(string, length, false);
1103
}
1104
 
1105
void dbgconsole_swrite(const char* string, size_t length)
1106
{
1107
    dbgconsole_write_internal(string, length, true);
1108
}
1109
 
25 theseven 1110
void dbgconsole_puts(const char* string)
1111
{
1112
    dbgconsole_write(string, strlen(string));
1113
}
26 theseven 1114
 
704 theseven 1115
void dbgconsole_sputs(const char* string)
1116
{
1117
    dbgconsole_swrite(string, strlen(string));
1118
}
1119
 
26 theseven 1120
int dbgconsole_getavailable() ICODE_ATTR;
1121
int dbgconsole_getavailable()
1122
{
1123
    int available = dbgconrecvwriteidx - dbgconrecvreadidx;
1124
    if (available < 0) available += sizeof(dbgconrecvbuf);
1125
    return available;
1126
}
1127
 
1128
int dbgconsole_getc(int timeout)
1129
{
1130
    if (!dbgconsole_getavailable())
1131
    {
1132
        wakeup_wait(&dbgconrecvwakeup, TIMEOUT_NONE);
1133
        if (!dbgconsole_getavailable())
1134
        {
1135
            wakeup_wait(&dbgconrecvwakeup, timeout);
1136
            if (!dbgconsole_getavailable()) return -1;
1137
        }
1138
    }
1139
    int byte = dbgconrecvbuf[dbgconrecvreadidx++];
1140
    if (dbgconrecvreadidx >= sizeof(dbgconrecvbuf))
1141
        dbgconrecvreadidx -= sizeof(dbgconrecvbuf);
1142
    return byte;
1143
}
1144
 
1145
int dbgconsole_read(char* buffer, size_t length, int timeout)
1146
{
1147
    if (!length) return 0;
1148
    int available = dbgconsole_getavailable();
1149
    if (!available)
1150
    {
1151
        wakeup_wait(&dbgconrecvwakeup, TIMEOUT_NONE);
1152
        int available = dbgconsole_getavailable();
1153
        if (!available)
1154
        {
1155
            wakeup_wait(&dbgconrecvwakeup, timeout);
1156
            int available = dbgconsole_getavailable();
1157
            if (!available) return 0;
1158
        }
1159
    }
1160
    if (available > length) available = length;
1161
    int left = available;
1162
    if (dbgconrecvreadidx + available >= sizeof(dbgconrecvbuf))
1163
    {
1164
        int bytes = sizeof(dbgconrecvbuf) - dbgconrecvreadidx;
1165
        memcpy(buffer, &dbgconrecvbuf[dbgconrecvreadidx], bytes);
1166
        dbgconrecvreadidx = 0;
1167
        buffer = &buffer[bytes];
1168
        left -= bytes;
1169
    }
1170
    if (left) memcpy(buffer, &dbgconrecvbuf[dbgconrecvreadidx], left);
1171
    dbgconrecvreadidx += left;
1172
    return available;
1173
}
240 theseven 1174
 
1175
void usb_exit(void)
1176
{
1177
    usb_drv_exit();
1178
}