Subversion Repositories freemyipod

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
892 theseven 1
//
2
//
3
//    Copyright 2010 TheSeven
4
//
5
//
6
//    This file is part of emCORE.
7
//
8
//    emCORE 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
//    emCORE 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 emCORE.  If not, see <http://www.gnu.org/licenses/>.
20
//
21
//
22
 
23
 
24
#include "global.h"
25
#include "usbdebug.h"
26
#include "panic.h"
27
#include "usb.h"
28
#include "thread.h"
29
#include "console.h"
30
#include "util.h"
31
#include "contextswitch.h"
32
#include "power.h"
33
#include "mmu.h"
34
#include "shutdown.h"
35
#include "execimage.h"
36
#ifdef HAVE_I2C
37
#include "i2c.h"
38
#endif
39
#ifdef HAVE_BOOTFLASH
40
#include "bootflash.h"
41
#endif
42
#ifdef HAVE_HWKEYAES
43
#include "hwkeyaes.h"
44
#endif
45
#ifdef HAVE_HMACSHA1
46
#include "hmacsha1.h"
47
#endif
48
#ifdef USB_HAVE_TARGET_SPECIFIC_REQUESTS
49
#include "usbtarget.h"
50
#endif
51
#ifdef HAVE_STORAGE
52
#include "storage.h"
53
#include "disk.h"
54
#include "file.h"
55
#include "dir.h"
56
#include "libc/include/errno.h"
57
#endif
58
 
59
 
60
static uint32_t dbgbuf[16] CACHEALIGN_ATTR;
61
 
62
enum dbgstate_t
63
{
64
    DBGSTATE_IDLE = 0,
65
    DBGSTATE_SETUP,
66
    DBGSTATE_WRITE_MEM,
896 theseven 67
    DBGSTATE_WRITE_CONSOLE,
892 theseven 68
    DBGSTATE_ASYNC,
69
    DBGSTATE_RESPOND,
896 theseven 70
    DBGSTATE_READ_CONSOLE,
892 theseven 71
};
72
 
73
static struct scheduler_thread dbgthread_handle IBSS_ATTR;
74
static uint32_t dbgstack[0x200] STACK_ATTR;
75
struct wakeup dbgwakeup IBSS_ATTR;
76
static bool dbgenabled IBSS_ATTR;
77
static bool dbgbusy IBSS_ATTR;
78
static const struct usb_instance* dbgusb IBSS_ATTR;
79
static enum dbgstate_t dbgstate IBSS_ATTR;
80
static void* dbgmemaddr IBSS_ATTR;
81
static uint32_t dbgmemlen IBSS_ATTR;
82
static char dbgconsendbuf[4096];
83
static char dbgconrecvbuf[1024];
84
static int dbgconsendreadidx IBSS_ATTR;
85
static int dbgconsendwriteidx IBSS_ATTR;
86
static int dbgconrecvreadidx IBSS_ATTR;
87
static int dbgconrecvwriteidx IBSS_ATTR;
88
static struct wakeup dbgconsendwakeup IBSS_ATTR;
89
static struct wakeup dbgconrecvwakeup IBSS_ATTR;
90
static bool dbgconsoleattached IBSS_ATTR;
949 theseven 91
static int maxpacket IBSS_ATTR;
92
static struct bulk_state
93
{
94
    void* addr;
95
    int size;
96
} bulk_state[2] IBSS_ATTR;
97
static int bulk_ctrlreq_ep IBSS_ATTR;
892 theseven 98
 
99
static const char dbgconoverflowstr[] = "\n\n[overflowed]\n\n";
100
 
101
extern int _poolstart;   // These aren't ints at all, but gcc complains about void types being
102
extern int _poolend;     // used here, and we only need the address, so just make it happy...
103
 
104
 
105
void reset() __attribute__((noreturn));
106
 
107
void usbdebug_enable(const struct usb_instance* data, int interface, int altsetting)
108
{
109
    dbgusb = data;
110
    dbgstate = DBGSTATE_IDLE;
111
    dbgenabled = true;
112
}
113
 
114
void usbdebug_disable(const struct usb_instance* data, int interface, int altsetting)
115
{
116
    dbgenabled = false;
117
    dbgstate = DBGSTATE_IDLE;
118
}
119
 
949 theseven 120
void usbdebug_bus_reset(const struct usb_instance* data, int highspeed)
121
{
122
    maxpacket = highspeed ? 512 : 64;
123
}
124
 
125
void usbdebug_bulk_enable(const struct usb_instance* data, int interface, int altsetting)
126
{
127
    usbdebug_enable(data, interface, altsetting);
128
    union usb_endpoint_number outep = { .number = USBDEBUG_ENDPOINT_OUT, .direction = USB_ENDPOINT_DIRECTION_OUT };
129
    union usb_endpoint_number inep = { .number = USBDEBUG_ENDPOINT_IN, .direction = USB_ENDPOINT_DIRECTION_IN };
130
    usb_configure_ep(data, outep, USB_ENDPOINT_TYPE_BULK, maxpacket);
131
    usb_configure_ep(data, inep, USB_ENDPOINT_TYPE_BULK, maxpacket);
132
}
133
 
134
void usbdebug_bulk_disable(const struct usb_instance* data, int interface, int altsetting)
135
{
136
    union usb_endpoint_number outep = { .number = USBDEBUG_ENDPOINT_OUT, .direction = USB_ENDPOINT_DIRECTION_OUT };
137
    union usb_endpoint_number inep = { .number = USBDEBUG_ENDPOINT_IN, .direction = USB_ENDPOINT_DIRECTION_IN };
138
    usb_unconfigure_ep(data, outep);
139
    usb_unconfigure_ep(data, inep);
140
    usbdebug_disable(data, interface, altsetting);
141
}
142
 
143
void usbdebug_bulk_xfer_complete(const struct usb_instance* data, int interface, int endpoint, int bytesleft)
144
{
145
    struct bulk_state* state = &bulk_state[endpoint];
146
    if (!bytesleft && state->size)
147
    {
148
        int size;
149
        if (endpoint)
150
        {
151
            union usb_endpoint_number ep = { .number = USBDEBUG_ENDPOINT_IN, .direction = USB_ENDPOINT_DIRECTION_IN };
152
            size = MIN(state->size, maxpacket * usb_get_max_transfer_size(data, ep));
153
            usb_start_rx(data, ep, state->addr, size);
154
        }
155
        else
156
        {
157
            union usb_endpoint_number ep = { .number = USBDEBUG_ENDPOINT_OUT, .direction = USB_ENDPOINT_DIRECTION_OUT };
158
            size = MIN(state->size, maxpacket * usb_get_max_transfer_size(data, ep));
159
            usb_start_tx(data, ep, state->addr, size);
160
        }
161
        state->addr += size;
162
        state->size -= size;
163
    }
164
}
165
 
166
bool usbdebug_bulk_handle_data(const struct usb_instance* data, union usb_endpoint_number epnum, int bytesleft)
167
{
168
    uint32_t* buf = (uint32_t*)data->buffer->raw;
169
    int len = 64 - bytesleft;
170
    union usb_endpoint_number ep0out = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_OUT };
171
    union usb_endpoint_number ep0in = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_IN };
172
    usb_ep0_start_rx(data, false, 0, NULL);
173
    switch (buf[0])
174
    {
175
    case 1:  // START MEMORY TRANSFER
176
        if (len == 12)
177
        {
178
            bulk_state[bulk_ctrlreq_ep].addr = (void*)buf[1];
179
            bulk_state[bulk_ctrlreq_ep].size = buf[2];
180
            usbdebug_bulk_xfer_complete(data, 0, bulk_ctrlreq_ep, 0);  // Convenient way to start a transfer.
181
            usb_set_stall(data, ep0out, true);
182
            usb_ep0_start_tx(data, NULL, 0, NULL);
183
            break;
184
        }
185
    default:
186
        usb_set_stall(data, ep0out, true);
187
        usb_set_stall(data, ep0in, true);
188
        break;
189
    }
190
    return true;
191
}
192
 
193
int usbdebug_bulk_ctrl_request(const struct usb_instance* data, int interface, int endpoint, union usb_ep0_buffer* request, const void** response)
194
{
195
    int size = -1;
196
    union usb_endpoint_number ep0out = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_OUT };
197
    switch (request->setup.bmRequestType.type)
198
    {
199
    case USB_SETUP_BMREQUESTTYPE_TYPE_VENDOR:
200
        switch (request->setup.bRequest.raw)
201
        {
202
        case 0x00:
203
            switch (data->buffer->setup.bmRequestType.direction)
204
            {
205
            case USB_SETUP_BMREQUESTTYPE_DIRECTION_OUT:
206
                bulk_ctrlreq_ep = endpoint;
207
                usb_ep0_start_rx(data, true, 64, usbdebug_bulk_handle_data);
208
                return -3;
209
            case USB_SETUP_BMREQUESTTYPE_DIRECTION_IN:
210
                return -2;
211
            }
212
            break;
213
        default: break;
214
        }
215
        break;
216
        default: break;
217
    }
218
    return size;
219
}
220
 
944 theseven 221
bool usbdebug_handle_data(const struct usb_instance* data, union usb_endpoint_number epnum, int bytesleft)
892 theseven 222
{
944 theseven 223
    union usb_endpoint_number ep0in = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_IN };
224
    union usb_endpoint_number ep0out = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_OUT };
892 theseven 225
    uint32_t* buf = (uint32_t*)data->buffer->raw;
944 theseven 226
    usb_ep0_start_rx(dbgusb, false, 0, NULL);
892 theseven 227
    switch (dbgstate)
228
    {
229
    case DBGSTATE_SETUP:
230
        switch (buf[0])
231
        {
232
        case 1:  // GET INFO
233
            dbgbuf[0] = 1;
234
            switch (buf[1])
235
            {
236
            case 0:  // GET VERSION INFO
237
                dbgbuf[1] = VERSION_SVN_INT;
238
                dbgbuf[2] = VERSION_MAJOR | (VERSION_MINOR << 8) | (VERSION_PATCH << 16) | (2 << 24);
239
                dbgbuf[3] = PLATFORM_ID;
240
                break;
241
            case 1:  // GET USER MEMORY INFO
242
                dbgbuf[1] = (uint32_t)&_poolstart;
243
                dbgbuf[2] = (uint32_t)&_poolend;
244
                break;
245
            default:
246
                dbgbuf[0] = 2;
247
            }
248
            break;
249
        case 4:  // READ MEMORY
250
            dbgbuf[0] = 1;
251
            dbgmemaddr = (void*)buf[1];
252
            dbgmemlen = buf[2];
253
            break;
254
        case 5:  // WRITE MEMORY
255
        {
256
            dbgmemaddr = (void*)buf[1];
257
            dbgmemlen = buf[2];
258
            int len = MIN(48, dbgmemlen);
259
            dbgmemlen -= len;
260
            memcpy(dbgmemaddr, &buf[4], len);
261
            if (dbgmemlen)
262
            {
263
                dbgmemaddr += len;
264
                dbgstate = DBGSTATE_WRITE_MEM;
944 theseven 265
                usb_ep0_start_rx(dbgusb, true, MIN(64, dbgmemlen), usbdebug_handle_data);
892 theseven 266
                return true;
267
            }
268
            dbgbuf[0] = 1;
269
            break;
270
        }
271
        case 10:  // READ CONSOLE
896 theseven 272
            dbgmemaddr = (void*)buf[1];
273
            dbgstate = DBGSTATE_READ_CONSOLE;
944 theseven 274
            usb_set_stall(dbgusb, ep0out, true);
275
            usb_ep0_start_tx(dbgusb, NULL, 0, NULL);
896 theseven 276
            return true;
892 theseven 277
            break;
278
        case 11:  // WRITE CONSOLE
896 theseven 279
        {
280
            int total = 0;
281
            int bytes = dbgconrecvreadidx - dbgconrecvwriteidx - 1;
892 theseven 282
            if (bytes < 0) bytes += sizeof(dbgconrecvbuf);
283
            if (bytes)
284
            {
285
                if (bytes > buf[1]) bytes = buf[1];
896 theseven 286
                total = bytes;
287
                if (bytes > 48) bytes = 48;
892 theseven 288
                int writebytes = bytes;
289
                char* readptr = (char*)&buf[4];
290
                if (dbgconrecvwriteidx + bytes >= sizeof(dbgconrecvbuf))
291
                {
292
                    writebytes = sizeof(dbgconrecvbuf) - dbgconrecvwriteidx;
293
                    memcpy(&dbgconrecvbuf[dbgconrecvwriteidx], readptr, writebytes);
294
                    dbgconrecvwriteidx = 0;
295
                    readptr = &readptr[writebytes];
296
                    writebytes = bytes - writebytes;
297
                }
298
                if (writebytes) memcpy(&dbgconrecvbuf[dbgconrecvwriteidx], readptr, writebytes);
299
                dbgconrecvwriteidx += writebytes;
300
                wakeup_signal(&dbgconrecvwakeup);
301
            }
302
            dbgbuf[0] = 1;
896 theseven 303
            dbgbuf[1] = total;
892 theseven 304
            dbgbuf[2] = sizeof(dbgconrecvbuf);
896 theseven 305
            if (total > 48)
306
            {
307
                dbgmemlen = total - 48;
308
                dbgstate = DBGSTATE_WRITE_CONSOLE;
944 theseven 309
                usb_ep0_start_rx(dbgusb, true, MIN(64, dbgmemlen), usbdebug_handle_data);
896 theseven 310
                return true;
311
            }
892 theseven 312
            dbgbuf[3] = dbgconrecvreadidx - dbgconrecvwriteidx - 1;
313
            break;
896 theseven 314
        }
892 theseven 315
        case 15:  // GET PROCESS INFO
316
            dbgbuf[0] = 1;
317
            dbgbuf[1] = SCHEDULER_THREAD_INFO_VERSION;
318
            dbgbuf[2] = (uint32_t)head_thread;
319
            break;
320
        case 16:  // FREEZE SCHEDULER
321
            dbgbuf[1] = scheduler_freeze(buf[1]);
322
            scheduler_switch(NULL, NULL);
323
            dbgbuf[0] = 1;
324
            break;
325
        case 17:  // SUSPEND THREAD
326
            if (buf[1])
327
            {
328
                if (thread_suspend((struct scheduler_thread*)(buf[2])) == ALREADY_SUSPENDED)
329
                    dbgbuf[1] = 1;
330
                else dbgbuf[1] = 0;
331
            }
332
            else
333
            {
334
                if (thread_resume((struct scheduler_thread*)(buf[2])) == ALREADY_RESUMED)
335
                    dbgbuf[1] = 0;
336
                else dbgbuf[1] = 1;
337
            }
338
            dbgbuf[0] = 1;
339
            break;
340
        case 18:  // KILL THREAD
341
            thread_terminate((struct scheduler_thread*)(buf[1]));
342
            dbgbuf[0] = 1;
343
            break;
344
        case 19:  // CREATE THREAD
345
            dbgbuf[0] = 1;
346
            dbgbuf[1] = (uint32_t)thread_create(NULL, (const char*)(buf[1]), (const void*)(buf[2]),
347
                                                (char*)(buf[3]), buf[4], (enum thread_type)buf[5],
348
                                                buf[6], buf[7], (void*)buf[8], (void*)buf[9],
349
                                                (void*)buf[10], (void*)buf[11]);
350
            break;
351
        case 20:  // FLUSH CACHE
352
            clean_dcache();
353
            invalidate_icache();
354
            buf[0] = 1;
355
            break;
356
        case 2:  // RESET
357
            if (!buf[1]) reset();
358
        default:
359
            if (!dbgbusy)
360
            {
361
                memcpy(dbgbuf, buf, 64);
362
                dbgstate = DBGSTATE_ASYNC;
363
                dbgbusy = 1;
364
                wakeup_signal(&dbgwakeup);
365
                return true;
366
            }
367
            buf[0] = 3;
368
            break;
369
        }
370
        break;
371
    case DBGSTATE_WRITE_MEM:
372
    {
896 theseven 373
        int len = MIN(64 - bytesleft, dbgmemlen);
892 theseven 374
        dbgmemlen -= len;
375
        memcpy(dbgmemaddr, buf, len);
896 theseven 376
        if (dbgmemlen && !bytesleft)
892 theseven 377
        {
378
            dbgmemaddr += len;
944 theseven 379
            usb_ep0_start_rx(dbgusb, true, MIN(64, dbgmemlen), usbdebug_handle_data);
892 theseven 380
            return true;
381
        }
382
        dbgbuf[0] = 1;
383
        break;
384
    }
896 theseven 385
    case DBGSTATE_WRITE_CONSOLE:
386
    {
387
        int bytes = MIN(64 - bytesleft, dbgmemlen);
388
        dbgmemlen -= bytes;
389
        if (bytes)
390
        {
391
            int writebytes = bytes;
392
            char* readptr = (char*)buf;
393
            if (dbgconrecvwriteidx + bytes >= sizeof(dbgconrecvbuf))
394
            {
395
                writebytes = sizeof(dbgconrecvbuf) - dbgconrecvwriteidx;
396
                memcpy(&dbgconrecvbuf[dbgconrecvwriteidx], readptr, writebytes);
397
                dbgconrecvwriteidx = 0;
398
                readptr = &readptr[writebytes];
399
                writebytes = bytes - writebytes;
400
            }
401
            if (writebytes) memcpy(&dbgconrecvbuf[dbgconrecvwriteidx], readptr, writebytes);
402
            dbgconrecvwriteidx += writebytes;
403
            wakeup_signal(&dbgconrecvwakeup);
404
            if (dbgmemlen && !bytesleft)
405
            {
944 theseven 406
                usb_ep0_start_rx(dbgusb, true, MIN(64, dbgmemlen), usbdebug_handle_data);
896 theseven 407
                return true;
408
            }
409
        }
410
        dbgbuf[3] = dbgconrecvreadidx - dbgconrecvwriteidx - 1;
411
        if (dbgbuf[3] < 0) dbgbuf[3] += sizeof(dbgconrecvbuf);
412
    }
892 theseven 413
    default: break;
414
    }
415
    dbgstate = DBGSTATE_RESPOND;
944 theseven 416
    usb_set_stall(dbgusb, ep0out, true);
417
    usb_ep0_start_tx(dbgusb, NULL, 0, NULL);
892 theseven 418
    return true;
419
}
420
 
944 theseven 421
bool read_console_callback(const struct usb_instance* data, union usb_endpoint_number epnum, int bytesleft)
896 theseven 422
{
944 theseven 423
    if (bytesleft || !dbgmemaddr)
424
    {
425
        usb_ep0_start_rx(dbgusb, true, 0, usb_ep0_ack_callback);
426
        if (!dbgmemaddr) usb_ep0_start_tx(dbgusb, NULL, 0, usb_ep0_short_tx_callback);
427
        dbgusb->state->ep0_tx_ptr = NULL;
428
        return false;
429
    }
896 theseven 430
    dbgconsoleattached = true;
431
    int bytes = MIN(64, dbgmemlen);
432
    if (bytes)
433
    {
434
        int readbytes = bytes;
435
        char* outptr = (char*)dbgbuf;
436
        if (dbgconsendreadidx + bytes >= sizeof(dbgconsendbuf))
437
        {
438
            readbytes = sizeof(dbgconsendbuf) - dbgconsendreadidx;
439
            memcpy(outptr, &dbgconsendbuf[dbgconsendreadidx], readbytes);
440
            dbgconsendreadidx = 0;
441
            outptr = &outptr[readbytes];
442
            readbytes = bytes - readbytes;
443
        }
444
        if (readbytes) memcpy(outptr, &dbgconsendbuf[dbgconsendreadidx], readbytes);
445
        dbgconsendreadidx += readbytes;
446
        wakeup_signal(&dbgconsendwakeup);
447
        dbgmemlen -= bytes;
448
    }
449
    bytes = MIN(64, (int)dbgmemaddr);
450
    dbgmemaddr -= bytes;
451
    if (dbgmemaddr)
452
    {
944 theseven 453
        usb_ep0_start_tx(dbgusb, dbgbuf, bytes,
454
                         bytes < 64 ? usb_ep0_short_tx_callback : read_console_callback);
896 theseven 455
    }
944 theseven 456
    else usb_ep0_start_tx(dbgusb, dbgbuf, bytes, NULL);
896 theseven 457
    return true;
458
}
459
 
892 theseven 460
int usbdebug_handle_setup(const struct usb_instance* data, int interface, union usb_ep0_buffer* request, const void** response)
461
{
462
    int size = -1;
944 theseven 463
    union usb_endpoint_number ep0out = { .number = 0, .direction = USB_ENDPOINT_DIRECTION_OUT };
892 theseven 464
    switch (request->setup.bmRequestType.type)
465
    {
466
    case USB_SETUP_BMREQUESTTYPE_TYPE_VENDOR:
467
        switch (request->setup.bRequest.raw)
468
        {
469
        case 0x00:
470
            switch (data->buffer->setup.bmRequestType.direction)
471
            {
472
            case USB_SETUP_BMREQUESTTYPE_DIRECTION_OUT:
473
                dbgstate = DBGSTATE_SETUP;
474
                dbgmemlen = 0;
944 theseven 475
                usb_ep0_start_rx(dbgusb, true, 64, usbdebug_handle_data);
892 theseven 476
                return -3;
477
            case USB_SETUP_BMREQUESTTYPE_DIRECTION_IN:
478
                switch (dbgstate)
479
                {
480
                case DBGSTATE_RESPOND:
481
                {
944 theseven 482
                    dbgmemlen = MIN(dbgmemlen, data->buffer->setup.wLength - 16);
892 theseven 483
                    int len = MIN(48, dbgmemlen);
484
                    if (len) memcpy(&dbgbuf[4], dbgmemaddr, len);
485
                    dbgmemlen -= len;
486
                    if (dbgmemlen)
487
                    {
944 theseven 488
                        usb_ep0_start_rx(dbgusb, false, 0, NULL);
489
                        dbgusb->state->ep0_tx_ptr = dbgmemaddr + 48;
490
                        dbgusb->state->ep0_tx_len = dbgmemlen;
491
                        usb_ep0_start_tx(dbgusb, dbgbuf, len + 16,
492
                                         len < 48 ? usb_ep0_short_tx_callback : usb_ep0_tx_callback);
892 theseven 493
                        return -3;
494
                    }
495
                    dbgstate = DBGSTATE_IDLE;
496
                    *response = dbgbuf;
497
                    return len + 16;
498
                }
896 theseven 499
                case DBGSTATE_READ_CONSOLE:
500
                {
944 theseven 501
                    dbgmemaddr = (void*)MIN((int)dbgmemaddr, data->buffer->setup.wLength - 16);
896 theseven 502
                    dbgconsoleattached = true;
503
                    dbgmemlen = dbgconsendwriteidx - dbgconsendreadidx;
504
                    if (dbgmemlen < 0) dbgmemlen += sizeof(dbgconsendbuf);
505
                    int used = dbgmemlen;
506
                    if (dbgmemlen > (int)dbgmemaddr) dbgmemlen = (int)dbgmemaddr;
507
                    int bytes = MIN(48, dbgmemlen);
508
                    dbgbuf[0] = 1;
509
                    dbgbuf[1] = dbgmemlen;
510
                    dbgbuf[2] = sizeof(dbgconsendbuf);
511
                    dbgbuf[3] = used - dbgmemlen;
512
                    if (bytes)
513
                    {
514
                        int readbytes = bytes;
515
                        char* outptr = (char*)&dbgbuf[4];
516
                        if (dbgconsendreadidx + bytes >= sizeof(dbgconsendbuf))
517
                        {
518
                            readbytes = sizeof(dbgconsendbuf) - dbgconsendreadidx;
519
                            memcpy(outptr, &dbgconsendbuf[dbgconsendreadidx], readbytes);
520
                            dbgconsendreadidx = 0;
521
                            outptr = &outptr[readbytes];
522
                            readbytes = bytes - readbytes;
523
                        }
524
                        if (readbytes) memcpy(outptr, &dbgconsendbuf[dbgconsendreadidx], readbytes);
525
                        dbgconsendreadidx += readbytes;
526
                        wakeup_signal(&dbgconsendwakeup);
527
                    }
528
                    dbgmemlen -= bytes;
529
                    bytes = MIN(48, (int)dbgmemaddr);
530
                    dbgmemaddr -= bytes;
531
                    if (dbgmemaddr)
532
                    {
944 theseven 533
                        dbgusb->state->ep0_tx_ptr = (void*)true;
534
                        usb_ep0_start_rx(dbgusb, false, 0, NULL);
535
                        usb_ep0_start_tx(dbgusb, dbgbuf, bytes + 16,
536
                                         bytes < 48 ? usb_ep0_short_tx_callback : read_console_callback);
896 theseven 537
                        return -3;
538
                    }
539
                    dbgstate = DBGSTATE_IDLE;
540
                    *response = dbgbuf;
541
                    return bytes + 16;
542
                }
892 theseven 543
                default: return -2;
544
                }
545
                break;
546
            }
547
            break;
548
        default: break;
549
        }
550
        break;
551
        default: break;
552
    }
553
    return size;
554
}
555
 
556
void dbgthread(void* arg0, void* arg1, void* arg2, void* arg3)
557
{
558
    struct scheduler_thread* t;
559
    while (1)
560
    {
561
        wakeup_wait(&dbgwakeup, TIMEOUT_BLOCK);
562
        for (t = head_thread; t; t = t->thread_next)
563
            if (t->state == THREAD_DEFUNCT)
564
            {
565
                if (t->block_type == THREAD_DEFUNCT_STKOV)
566
                {
567
                    if (t->name) cprintf(1, "\n*PANIC*\nStack overflow! (%s)\n", t->name);
568
                    else cprintf(1, "\n*PANIC*\nStack overflow! (%08X)\n", t);
569
                }
570
                t->state = THREAD_DEFUNCT_ACK;
571
            }
572
        uint32_t mode = enter_critical_section();
573
        uint32_t buf[16];
574
        if (dbgstate == DBGSTATE_ASYNC)
575
        {
576
            memcpy(buf, dbgbuf, 64);
577
            leave_critical_section(mode);
578
            void* addr = &buf[4];
579
            int len = 0;
580
            switch (buf[0])
581
            {
582
                case 2:  // RESET
583
                    shutdown(false);
584
                    reset();
585
                case 3:  // POWER OFF
586
                    if (buf[1]) shutdown(true);
587
                    power_off();
588
                    buf[0] = 1;
589
                    break;
590
#ifdef HAVE_I2C
591
                case 8:  // READ I2C
592
                    len = buf[1] >> 24;
593
                    i2c_recv(buf[1] & 0xff, (buf[1] >> 8) & 0xff, (buf[1] >> 16) & 0xff,
594
                             (uint8_t*)&buf[4], len);
595
                    buf[0] = 1;
596
                    break;
597
                case 9:  // WRITE I2C
598
                    i2c_send(buf[1] & 0xff, (buf[1] >> 8) & 0xff, (buf[1] >> 16) & 0xff,
599
                             (uint8_t*)&buf[4], buf[1] >> 24);
600
                    buf[0] = 1;
601
                    break;
602
#endif
603
                case 12:  // CWRITE
604
                    cwrite(buf[1], (const char*)&buf[4], buf[2]);
605
                    buf[0] = 1;
606
                    break;
607
                case 13:  // CREAD
608
                    buf[0] = 1;
609
                    buf[1] = cread(buf[1], (char*)&buf[4], buf[2], 0);
610
                    break;
611
                case 14:  // CFLUSH
612
                    cflush(buf[1]);
613
                    buf[0] = 1;
614
                    break;
615
                case 21:  // EXECIMAGE
616
                {
617
                    int argc = buf[2] >> 24;
618
                    if (!buf[3])
619
                    {
620
                        buf[3] = (uint32_t)&buf[4];
621
                        int i;
622
                        for (i = 0; i < argc; i++) buf[i + 4] += buf[3];
623
                    }
624
                    buf[0] = 1;
625
                    buf[1] = (uint32_t)execimage((void*)buf[1], buf[2] & 0x10000, argc, (const char* const*)buf[3]);
626
                    break;
627
                }
628
#ifdef HAVE_BOOTFLASH
629
                case 22:  // READ BOOT FLASH
630
                    bootflash_readraw((void*)buf[1], buf[2], buf[3]);
631
                    buf[0] = 1;
632
                    break;
633
                case 23:  // WRITE BOOT FLASH
634
                    bootflash_writeraw((void*)buf[1], buf[2], buf[3]);
635
                    buf[0] = 1;
636
                    break;
637
#endif
638
                case 24:  // EXECFIRMWARE
639
                    shutdown(false);
640
                    execfirmware((void*)buf[1], (void*)buf[2], (size_t)buf[3]);
641
                    buf[0] = 1;
642
                    break;
643
#ifdef HAVE_HWKEYAES
644
                case 25:  // HWKEYAES
645
                    hwkeyaes((enum hwkeyaes_direction)((uint8_t*)buf)[4], ((uint16_t*)buf)[3], (void*)buf[2], buf[3]);
646
                    buf[0] = 1;
647
                    break;
648
#endif
649
#ifdef HAVE_HMACSHA1
650
                case 26:  // HMACSHA1
651
                    hmacsha1((void*)buf[1], buf[2], (void*)buf[3]);
652
                    buf[0] = 1;
653
                    break;
654
#endif
655
#ifdef HAVE_STORAGE
656
                case 27:  // STORAGE_GET_INFO
657
                    buf[0] = 1;
658
                    storage_get_info(buf[1], (struct storage_info*)&buf[4]);
659
                    buf[1] = 1;
933 theseven 660
                    len = (sizeof(struct storage_info) + 3) / 4 * 4;
892 theseven 661
                    break;
662
                case 28:  // STORAGE_READ_SECTORS_MD
663
                    buf[0] = 1;
664
                    buf[1] = (uint32_t)storage_read_sectors_md(buf[1], buf[2] | (((uint64_t)(buf[3]) << 32)),
665
                                                               buf[4], (void*)(buf[5]));
666
                    break;
667
                case 29:  // STORAGE_WRITE_SECTORS_MD
668
                    buf[0] = 1;
669
                    buf[1] = (uint32_t)storage_write_sectors_md(buf[1], buf[2] | (((uint64_t)(buf[3]) << 32)),
670
                                                                buf[4], (void*)(buf[5]));
671
                    break;
672
                case 30:  // FILE_OPEN
673
                {
674
                    buf[0] = 1;
675
                    if (!buf[3]) buf[3] = (uint32_t)&buf[4];
676
                    int fd = file_open((char*)buf[3], (int)buf[1]);
677
                    if (fd > 0) reown_file(fd, KERNEL_OWNER(KERNEL_OWNER_USB_MONITOR));
678
                    buf[1] = (uint32_t)fd;
679
                    break;
680
                }
681
                case 31:  // FILESIZE
682
                    buf[0] = 1;
683
                    buf[1] = (uint32_t)filesize((int)buf[1]);
684
                    break;
685
                case 32:  // READ
686
                    buf[0] = 1;
687
                    buf[1] = (uint32_t)read((int)buf[1], (void*)buf[2], (size_t)buf[3]);
688
                    break;
689
                case 33:  // WRITE
690
                    buf[0] = 1;
691
                    buf[1] = (uint32_t)write((int)buf[1], (void*)buf[2], (size_t)buf[3]);
692
                    break;
693
                case 34:  // LSEEK
694
                    buf[0] = 1;
695
                    buf[1] = (uint32_t)lseek((int)buf[1], (off_t)buf[2], (int)buf[3]);
696
                    break;
697
                case 35:  // FTRUNCATE
698
                    buf[0] = 1;
699
                    buf[1] = (uint32_t)ftruncate((int)buf[1], (off_t)buf[2]);
700
                    break;
701
                case 36:  // FSYNC
702
                    buf[0] = 1;
703
                    buf[1] = (uint32_t)fsync((int)buf[1]);
704
                    break;
705
                case 37:  // CLOSE
706
                    buf[0] = 1;
707
                    buf[1] = (uint32_t)close((int)buf[1]);
708
                    break;
709
                case 38:  // CLOSE_MONITOR_FILES
710
                    buf[0] = 1;
711
                    buf[1] = (uint32_t)close_all_of_process(KERNEL_OWNER(KERNEL_OWNER_USB_MONITOR));
712
                    break;
713
                case 39:  // RELEASE_FILES
714
                    buf[0] = 1;
715
                    buf[1] = (uint32_t)release_files((int)buf[1]);
716
                    break;
717
                case 40:  // REMOVE
718
                    buf[0] = 1;
719
                    if (!buf[3]) buf[3] = (uint32_t)&buf[4];
720
                    buf[1] = (uint32_t)remove((char*)buf[3]);
721
                    break;
722
                case 41:  // RENAME
723
                    buf[0] = 1;
724
                    buf[1] = (uint32_t)rename((char*)buf[2], (char*)buf[3]);
725
                    break;
726
                case 42:  // OPENDIR
727
                {
728
                    buf[0] = 1;
729
                    if (!buf[3]) buf[3] = (uint32_t)&buf[4];
730
                    DIR* dir = opendir((char*)buf[3]);
731
                    if (dir > 0) reown_dir(dir, KERNEL_OWNER(KERNEL_OWNER_USB_MONITOR));
732
                    buf[1] = (uint32_t)dir;
733
                    break;
734
                }
735
                case 43:  // READDIR
736
                    buf[0] = 1;
737
                    buf[3] = (uint32_t)readdir((DIR*)buf[1]);
738
                    buf[1] = 1;
739
                    buf[2] = MAX_PATH;
740
                    break;
741
                case 44:  // CLOSEDIR
742
                    buf[0] = 1;
743
                    buf[1] = (uint32_t)closedir((DIR*)buf[1]);
744
                    break;
745
                case 45:  // CLOSE_MONITOR_DIRS
746
                    buf[0] = 1;
747
                    buf[1] = (uint32_t)closedir_all_of_process(KERNEL_OWNER(KERNEL_OWNER_USB_MONITOR));
748
                    break;
749
                case 46:  // RELEASE_DIRS
750
                    buf[0] = 1;
751
                    buf[1] = (uint32_t)release_dirs((int)buf[1]);
752
                    break;
753
                case 47:  // MKDIR
754
                    buf[0] = 1;
755
                    if (!buf[3]) buf[3] = (uint32_t)&buf[4];
756
                    buf[1] = (uint32_t)mkdir((char*)buf[3]);
757
                    break;
758
                case 48:  // RMDIR
759
                    buf[0] = 1;
760
                    if (!buf[3]) buf[3] = (uint32_t)&buf[4];
761
                    buf[1] = (uint32_t)rmdir((char*)buf[3]);
762
                    break;
763
                case 49:  // ERRNO
764
                    buf[0] = 1;
765
                    buf[1] = (uint32_t)errno;
766
                    break;
767
#ifdef HAVE_HOTSWAP
768
                case 50:  // DISK_MOUNT
769
                    buf[0] = 1;
770
                    buf[1] = (uint32_t)disk_mount((int)buf[1]);
771
                    break;
772
                case 51:  // DISK_UNMOUNT
773
                    buf[0] = 1;
774
                    buf[1] = (uint32_t)disk_unmount((int)buf[1]);
775
                    break;
776
#endif
777
                case 58:  // FAT_ENABLE_FLUSHING
778
                    buf[0] = 1;
779
                    fat_enable_flushing((bool)buf[1]);
780
                    break;
781
                case 59:  // FAT_SIZE
782
                    buf[0] = 1;
783
                    fat_size_mv(buf[1], &buf[1], &buf[2]);
784
                    break;
785
#endif
786
                case 52:  // MALLOC
787
                    buf[0] = 1;
788
                    buf[1] = (uint32_t)malloc((size_t)buf[1]);
789
                    if (buf[1]) reownalloc(buf[1], KERNEL_OWNER(KERNEL_OWNER_USB_MONITOR));
790
                    break;
791
                case 53:  // MEMALIGN
792
                    buf[0] = 1;
793
                    buf[1] = (uint32_t)memalign((size_t)buf[1], (size_t)buf[2]);
794
                    if (buf[1]) reownalloc(buf[1], KERNEL_OWNER(KERNEL_OWNER_USB_MONITOR));
795
                    break;
796
                case 54:  // REALLOC
797
                    buf[0] = 1;
798
                    buf[1] = (uint32_t)realloc((void*)buf[1], (size_t)buf[2]);
799
                    break;
800
                case 55:  // REOWNALLOC
801
                    buf[0] = 1;
802
                    reownalloc((void*)buf[1], (void*)buf[2]);
803
                    break;
804
                case 56:  // FREE
805
                    buf[0] = 1;
806
                    free((void*)buf[1]);
807
                    break;
808
                case 57:  // FREE MONITOR ALLOCATIONS
809
                    buf[0] = 1;
810
                    buf[1] = (uint32_t)free_all_of_thread(KERNEL_OWNER(KERNEL_OWNER_USB_MONITOR));
811
                    break;
812
#ifdef HAVE_RTC
813
                case 60:  // RTC READ
814
                    buf[0] = 1;
815
                    rtc_read_datetime((struct rtc_datetime*)&buf[1]);
816
                    break;
817
                case 61:  // RTC WRITE
818
                    buf[0] = 1;
819
                    rtc_write_datetime((const struct rtc_datetime*)&buf[1]);
820
                    break;
821
#endif
931 theseven 822
                default:
892 theseven 823
#ifdef USB_HAVE_TARGET_SPECIFIC_REQUESTS
931 theseven 824
                    if (buf[0] >= 0xffff0000)
825
                        len = usb_target_handle_request(buf, sizeof(buf), &addr);
932 theseven 826
                    else buf[0] = 2;
827
#else
828
                    buf[0] = 2;
892 theseven 829
#endif
830
                    break;
831
            }
832
            mode = enter_critical_section();
833
            if (dbgstate == DBGSTATE_ASYNC)
834
            {
944 theseven 835
                usb_ep0_start_tx(dbgusb, NULL, 0, NULL);
892 theseven 836
                dbgstate = DBGSTATE_RESPOND;
837
                dbgmemaddr = addr;
838
                dbgmemlen = len;
933 theseven 839
                memcpy(dbgbuf, buf, 16);
892 theseven 840
            }
841
        }
842
        dbgbusy = false;
843
        leave_critical_section(mode);
844
    }
845
}
846
 
847
void usbdebug_init(void)
848
{
849
    wakeup_init(&dbgwakeup);
850
    dbgconsendreadidx = 0;
851
    dbgconsendwriteidx = 0;
852
    dbgconrecvreadidx = 0;
853
    dbgconrecvwriteidx = 0;
854
    wakeup_init(&dbgconsendwakeup);
855
    wakeup_init(&dbgconrecvwakeup);
856
    dbgenabled = false;
857
    dbgbusy = false;
858
    dbgstate = DBGSTATE_IDLE;
859
    dbgconsoleattached = false;
860
    thread_create(&dbgthread_handle, "monitor worker", dbgthread, dbgstack,
861
                  sizeof(dbgstack), CORE_THREAD, 255, true, NULL, NULL, NULL, NULL);
862
}
863
 
864
int dbgconsole_getfree() ICODE_ATTR;
865
int dbgconsole_getfree()
866
{
867
    int free = dbgconsendreadidx - dbgconsendwriteidx - 1;
868
    if (free < 0) free += sizeof(dbgconsendbuf);
869
    return free;
870
}
871
 
872
int dbgconsole_makespace(int length, bool safe) ICODE_ATTR;
873
int dbgconsole_makespace(int length, bool safe)
874
{
875
    int free = dbgconsole_getfree();
876
    while (!free && dbgconsoleattached && !safe)
877
    {
878
        dbgconsoleattached = false;
879
        wakeup_wait(&dbgconsendwakeup, 2000000);
880
        free = dbgconsole_getfree();
881
    }
882
    if (free) return free > length ? length : free;
883
    if (length > sizeof(dbgconsendbuf) - 17) length = sizeof(dbgconsendbuf) - 17;
884
    uint32_t mode = enter_critical_section();
885
    dbgconsendreadidx += length;
886
    if (dbgconsendreadidx >= sizeof(dbgconsendbuf))
887
        dbgconsendreadidx -= sizeof(dbgconsendbuf);
888
    int offset = 0;
889
    int idx = dbgconsendreadidx;
890
    if (idx + 16 >= sizeof(dbgconsendbuf))
891
    {
892
        offset = sizeof(dbgconsendbuf) - dbgconsendreadidx;
893
        memcpy(&dbgconsendbuf[dbgconsendreadidx], dbgconoverflowstr, offset);
894
        idx = 0;
895
    }
896
    if (offset != 16) memcpy(&dbgconsendbuf[idx], &dbgconoverflowstr[offset], 16 - offset);
897
    leave_critical_section(mode);
898
    return length;
899
}
900
 
901
void dbgconsole_putc_internal(char string, bool safe)
902
{
903
    dbgconsole_makespace(1, safe);
904
    dbgconsendbuf[dbgconsendwriteidx++] = string;
905
    if (dbgconsendwriteidx >= sizeof(dbgconsendbuf))
906
        dbgconsendwriteidx -= sizeof(dbgconsendbuf);
907
}
908
 
909
void dbgconsole_putc(char string)
910
{
911
    dbgconsole_putc_internal(string, false);
912
}
913
 
914
void dbgconsole_sputc(char string)
915
{
916
    dbgconsole_putc_internal(string, true);
917
}
918
 
919
void dbgconsole_write_internal(const char* string, size_t length, bool safe)
920
{
921
    while (length)
922
    {
923
        int space = dbgconsole_makespace(length, safe);
924
        if (dbgconsendwriteidx + space >= sizeof(dbgconsendbuf))
925
        {
926
            int bytes = sizeof(dbgconsendbuf) - dbgconsendwriteidx;
927
            memcpy(&dbgconsendbuf[dbgconsendwriteidx], string, bytes);
928
            dbgconsendwriteidx = 0;
929
            string = &string[bytes];
930
            space -= bytes;
931
            length -= bytes;
932
        }
933
        if (space) memcpy(&dbgconsendbuf[dbgconsendwriteidx], string, space);
934
        dbgconsendwriteidx += space;
935
        string = &string[space];
936
        length -= space;
937
    }
938
}
939
 
940
void dbgconsole_write(const char* string, size_t length)
941
{
942
    dbgconsole_write_internal(string, length, false);
943
}
944
 
945
void dbgconsole_swrite(const char* string, size_t length)
946
{
947
    dbgconsole_write_internal(string, length, true);
948
}
949
 
950
void dbgconsole_puts(const char* string)
951
{
952
    dbgconsole_write(string, strlen(string));
953
}
954
 
955
void dbgconsole_sputs(const char* string)
956
{
957
    dbgconsole_swrite(string, strlen(string));
958
}
959
 
960
int dbgconsole_getavailable() ICODE_ATTR;
961
int dbgconsole_getavailable()
962
{
963
    int available = dbgconrecvwriteidx - dbgconrecvreadidx;
964
    if (available < 0) available += sizeof(dbgconrecvbuf);
965
    return available;
966
}
967
 
968
int dbgconsole_getc(int timeout)
969
{
970
    if (!dbgconsole_getavailable())
971
    {
972
        wakeup_wait(&dbgconrecvwakeup, TIMEOUT_NONE);
973
        if (!dbgconsole_getavailable())
974
        {
975
            wakeup_wait(&dbgconrecvwakeup, timeout);
976
            if (!dbgconsole_getavailable()) return -1;
977
        }
978
    }
979
    int byte = dbgconrecvbuf[dbgconrecvreadidx++];
980
    if (dbgconrecvreadidx >= sizeof(dbgconrecvbuf))
981
        dbgconrecvreadidx -= sizeof(dbgconrecvbuf);
982
    return byte;
983
}
984
 
985
int dbgconsole_read(char* buffer, size_t length, int timeout)
986
{
987
    if (!length) return 0;
988
    int available = dbgconsole_getavailable();
989
    if (!available)
990
    {
991
        wakeup_wait(&dbgconrecvwakeup, TIMEOUT_NONE);
992
        int available = dbgconsole_getavailable();
993
        if (!available)
994
        {
995
            wakeup_wait(&dbgconrecvwakeup, timeout);
996
            int available = dbgconsole_getavailable();
997
            if (!available) return 0;
998
        }
999
    }
1000
    if (available > length) available = length;
1001
    int left = available;
1002
    if (dbgconrecvreadidx + available >= sizeof(dbgconrecvbuf))
1003
    {
1004
        int bytes = sizeof(dbgconrecvbuf) - dbgconrecvreadidx;
1005
        memcpy(buffer, &dbgconrecvbuf[dbgconrecvreadidx], bytes);
1006
        dbgconrecvreadidx = 0;
1007
        buffer = &buffer[bytes];
1008
        left -= bytes;
1009
    }
1010
    if (left) memcpy(buffer, &dbgconrecvbuf[dbgconrecvreadidx], left);
1011
    dbgconrecvreadidx += left;
1012
    return available;
1013
}
1014