Subversion Repositories freemyipod

Rev

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