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