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