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