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