OpenCores
URL https://opencores.org/ocsvn/altor32/altor32/trunk

Subversion Repositories altor32

[/] [altor32/] [trunk/] [sw/] [gdb_stub/] [gdb.c] - Blame information for rev 43

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 43 ultra_embe
//-----------------------------------------------------------------
2
//                           AltOR32 
3
//                Alternative Lightweight OpenRisc 
4
//                            V2.0
5
//                     Ultra-Embedded.com
6
//                   Copyright 2011 - 2014
7
//
8
//               Email: admin@ultra-embedded.com
9
//
10
//                       License: LGPL
11
//-----------------------------------------------------------------
12
//
13
// Copyright (C) 2011 - 2014 Ultra-Embedded.com
14
//
15
// This source file may be used and distributed without         
16
// restriction provided that this copyright statement is not    
17
// removed from the file and that any derivative work contains  
18
// the original copyright notice and the associated disclaimer. 
19
//
20
// This source file is free software; you can redistribute it   
21
// and/or modify it under the terms of the GNU Lesser General   
22
// Public License as published by the Free Software Foundation; 
23
// either version 2.1 of the License, or (at your option) any   
24
// later version.
25
//
26
// This source is distributed in the hope that it will be       
27
// useful, but WITHOUT ANY WARRANTY; without even the implied   
28
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      
29
// PURPOSE.  See the GNU Lesser General Public License for more 
30
// details.
31
//
32
// You should have received a copy of the GNU Lesser General    
33
// Public License along with this source; if not, write to the 
34
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
35
// Boston, MA  02111-1307  USA
36
//-----------------------------------------------------------------
37
#include "gdb_hw.h"
38
#include "gdb.h"
39
 
40
//-----------------------------------------------------------------
41
// Defines
42
//-----------------------------------------------------------------
43
// Rx / Tx buffer max size
44
#define MAX_BUF_SIZE                          512
45
 
46
// OR1K exception reasons
47
#define OR32_EXC_RESET                        0
48
#define OR32_EXC_FAULT                        1
49
#define OR32_EXC_INT                          2
50
#define OR32_EXC_SYSCALL                      3
51
#define OR32_EXC_BREAKPOINT                   4
52
#define OR32_EXC_BUS_ERROR                    6
53
 
54
#define OR32_SR_STEP                          19
55
#define OR32_SR_DBGEN                         20
56
 
57
#define GDB_SIGHUP                            1
58
#define GDB_SIGINT                            2
59
#define GDB_SIGTRAP                           5
60
#define GDB_SIGSEGV                           11
61
 
62
#define REG_SP                                1
63
#define REG_ARG0                              3
64
#define REG_ARG1                              4
65
#define REG_PC                                33
66
#define REG_SR                                34
67
#define REG_NUM                               35
68
 
69
//-----------------------------------------------------------------
70
// Locals
71
//-----------------------------------------------------------------
72
static char                 _inbuffer[MAX_BUF_SIZE];
73
static char                 _outbuffer[MAX_BUF_SIZE];
74
static int                  _initial_trap;
75
static const char           _hex_char[] = "0123456789abcdef";
76
 
77
static unsigned int *       (*syscall_handler)(unsigned int *registers);
78
static unsigned int *       (*irq_handler)(unsigned int *registers);
79
 
80
//-----------------------------------------------------------------
81
// gdb_atoi_hex: Convert from hex character to integer
82
//-----------------------------------------------------------------
83
static int gdb_atoi_hex(char ch)
84
{
85
    if (ch >= 'a' && ch <= 'f')
86
        return ch - 'a' + 10;
87
    else if (ch >= '0' && ch <= '9')
88
        return ch - '0';
89
    else if (ch >= 'A' && ch <= 'F')
90
        return ch - 'A' + 10;
91
    return -1;
92
}
93
//-----------------------------------------------------------------
94
// gdb_strcpy: String copy (avoid using any library functions)
95
//-----------------------------------------------------------------
96
static void gdb_strcpy(char *buf, const char *s)
97
{
98
    while (*s)
99
        *buf++ = *s++;
100
    *buf = 0;
101
}
102
//-----------------------------------------------------------------
103
// gdb_mem2hex: Convert block of memory to ASCII
104
//-----------------------------------------------------------------
105
static char *gdb_mem2hex(unsigned char *mem, char *target, int count)
106
{
107
    while (count)
108
    {
109
        *target++ = _hex_char[((*mem) >> 4) & 0xf];
110
        *target++ = _hex_char[((*mem) >> 0) & 0xf];
111
        mem++;
112
        count--;
113
    }
114
 
115
    *target = 0;
116
    return target;
117
}
118
//-----------------------------------------------------------------
119
// gdb_hex2mem: Convert ASCII hex string to binary
120
//-----------------------------------------------------------------
121
static char *gdb_hex2mem(char *src, unsigned char *mem, int count)
122
{
123
    unsigned char ch;
124
 
125
    while (count)
126
    {
127
        ch =  gdb_atoi_hex(*src++) << 4;
128
        ch |= gdb_atoi_hex(*src++) << 0;
129
 
130
        *mem++ = ch;
131
        count--;
132
    }
133
 
134
    return (char *)mem;
135
}
136
//-----------------------------------------------------------------
137
// gdb_gethexword: Convert ASCII hex word to integer
138
//-----------------------------------------------------------------
139
static int gdb_gethexword(char **s, unsigned int *val)
140
{
141
    int count = 0;
142
 
143
    *val = 0;
144
 
145
    while (**s)
146
    {
147
        int hexval = gdb_atoi_hex(**s);
148
        if (hexval < 0)
149
            break;
150
 
151
        (*s)++;
152
        count++;
153
 
154
        *val = (*val << 4) | (hexval & 0xF);
155
    }
156
 
157
    return count;
158
}
159
//-----------------------------------------------------------------
160
// gdb_send: Send GDB formatted packet ($buffer#checksum)
161
//-----------------------------------------------------------------
162
static void gdb_send(char *buffer)
163
{
164
    unsigned char checksum;
165
    int index;
166
 
167
    do
168
    {
169
        checksum = 0;
170
        index    = 0;
171
 
172
        // Start of packet
173
        gdb_putchar ('$');
174
 
175
        // Payload (if any)
176
        while (buffer[index] != 0)
177
        {
178
            gdb_putchar(buffer[index]);
179
            checksum += (unsigned char)buffer[index++];
180
        }
181
 
182
        // Checksum
183
        gdb_putchar('#');
184
        gdb_putchar(_hex_char[(checksum >> 4) & 0xF]);
185
        gdb_putchar(_hex_char[(checksum >> 0) & 0xF]);
186
    }
187
    while (gdb_getchar () != '+');
188
}
189
//-----------------------------------------------------------------
190
// gdb_recv: Wait for valid GDB packet ($cmd#checksum).
191
//          'cmd' is returned
192
//-----------------------------------------------------------------
193
static char * gdb_recv(void)
194
{
195
    int found_start = 0;
196
    unsigned char checksum;
197
    unsigned char csum_rx;
198
    int index;
199
    char ch;
200
 
201
    while (1)
202
    {
203
        ch = gdb_getchar();
204
 
205
        // Start of packet indicator?
206
        if (ch == '$')
207
        {
208
            found_start = 1;
209
            checksum    = 0;
210
            csum_rx     = 0;
211
            index       = 0;
212
        }
213
        // Already received start of packet
214
        else if (found_start)
215
        {
216
            // Found start of checksum
217
            if (ch == '#')
218
                break;
219
 
220
            if (index < (MAX_BUF_SIZE-1))
221
                _inbuffer[index++] = ch;
222
 
223
            checksum = checksum + ch;
224
        }
225
    }
226
    _inbuffer[index++] = 0;
227
 
228
    // If command received without overflowing buffer
229
    if (index < MAX_BUF_SIZE)
230
    {
231
        // Extract / wait for checksum
232
        ch = gdb_getchar();
233
        csum_rx = gdb_atoi_hex (ch) << 4;
234
        ch = gdb_getchar ();
235
        csum_rx += gdb_atoi_hex (ch);
236
 
237
        // Valid checksum
238
        if (checksum == csum_rx)
239
        {
240
            // Sequence number?
241
            if (_inbuffer[2] == ':')
242
            {
243
                gdb_putchar('+');
244
                gdb_putchar (_inbuffer[0]);
245
                gdb_putchar (_inbuffer[1]);
246
 
247
                return &_inbuffer[3];
248
            }
249
            else
250
            {
251
                // Simple Ack
252
                gdb_putchar('+');
253
 
254
                return &_inbuffer[0];
255
            }
256
        }
257
        else
258
        {
259
            _inbuffer[0] = 0;
260
 
261
            return &_inbuffer[0];
262
        }
263
    }
264
    else
265
    {
266
        _inbuffer[0] = 0;
267
 
268
        return &_inbuffer[0];
269
    }
270
}
271
//-----------------------------------------------------------------
272
// gdb_exception
273
//-----------------------------------------------------------------
274
unsigned int * gdb_exception(unsigned int *registers, unsigned int reason)
275
{
276
    int sig_val;
277
    unsigned int len;
278
    unsigned int val;
279
    unsigned int regnum;
280
    char *str;
281
    char *ptr;
282
    int flush_caches = 0;
283
 
284
    switch (reason)
285
    {
286
    case OR32_EXC_INT:
287
      sig_val = GDB_SIGINT;
288
      break;
289
    case OR32_EXC_BREAKPOINT:
290
      sig_val = GDB_SIGTRAP;
291
      break;
292
    case OR32_EXC_FAULT:
293
      sig_val = GDB_SIGSEGV;
294
      break;
295
    default:
296
      sig_val = GDB_SIGHUP;
297
      break;
298
    }
299
 
300
    // Exception due external interrupt
301
    if (reason == OR32_EXC_INT)
302
    {
303
        if (irq_handler)
304
            return irq_handler(registers);
305
    }
306
    // Exception due to syscall instruction
307
    else if (reason == OR32_EXC_SYSCALL)
308
    {
309
        // Get l.sys opcode
310
        unsigned int opcode = *((unsigned int*)(registers[REG_PC] - 4));
311
        unsigned int sys_num = opcode & 0xFFFF;
312
 
313
        ptr = _outbuffer;
314
        switch (sys_num)
315
        {
316
          //---------------------------------------------------
317
          // l.sys 1 -> putchar(r3)
318
          //---------------------------------------------------
319
          case 1:
320
              *ptr++ = 'O';
321
              *ptr++ = _hex_char[(registers[REG_ARG0] >> 4) & 0xf];
322
              *ptr++ = _hex_char[registers[REG_ARG0] & 0xf];
323
              *ptr++ = 0;
324
              gdb_send (_outbuffer);
325
 
326
              return registers;
327
          //---------------------------------------------------
328
          // l.sys 2 -> putstr(r3)
329
          //---------------------------------------------------
330
          case 2:
331
              // Pointer to string
332
              str = (char*)registers[REG_ARG0];
333
              len = 0;
334
 
335
              *ptr++ = 'O';
336
              while (*str && (len < ((sizeof(_outbuffer)-2)/2)))
337
              {
338
                  *ptr++ = _hex_char[((*str) >> 4) & 0xf];
339
                  *ptr++ = _hex_char[((*str) >> 0) & 0xf];
340
                  str++;
341
              }
342
              *ptr++ = 0;
343
              gdb_send (_outbuffer);
344
 
345
              return registers;
346
          //---------------------------------------------------
347
          // l.sys 3 -> exit(r3)
348
          //---------------------------------------------------
349
          case 3:
350
              *ptr++ = 'W';
351
              *ptr++ = _hex_char[(registers[REG_ARG0] >> 4) & 0xf];
352
              *ptr++ = _hex_char[registers[REG_ARG0] & 0xf];
353
              *ptr++ = 0;
354
              gdb_send (_outbuffer);
355
 
356
              // Remain in GDB stub...
357
              break;
358
          //---------------------------------------------------
359
          // l.sys 4 -> set syscall_handler = r3
360
          //---------------------------------------------------
361
          case 4:
362
              syscall_handler = (void*)registers[REG_ARG0];
363
              return registers;
364
          //---------------------------------------------------
365
          // l.sys 5 -> set irq_handler = r3
366
          //---------------------------------------------------
367
          case 5:
368
              irq_handler = (void*)registers[REG_ARG0];
369
              return registers;
370
          //---------------------------------------------------
371
          // Default: User syscall
372
          //---------------------------------------------------
373
          default:
374
              if (syscall_handler)
375
                  return syscall_handler(registers);
376
              // Not supported
377
              else
378
              {
379
                  registers[REG_ARG0] = 0;
380
                  return registers;
381
              }
382
        }
383
    }
384
 
385
    // Make sure debug enabled on return to user program
386
    registers[REG_SR] |= (1 << OR32_SR_DBGEN);
387
 
388
    // Send status response (signal type, PC & SP)
389
    if (!_initial_trap)
390
    {
391
        ptr = _outbuffer;
392
        *ptr++ = 'T';
393
        *ptr++ = _hex_char[(sig_val >> 4) & 0xf];
394
        *ptr++ = _hex_char[sig_val & 0xf];
395
        *ptr++ = _hex_char[(REG_PC >> 4) & 0xf];
396
        *ptr++ = _hex_char[REG_PC & 0xf];
397
        *ptr++ = ':';
398
        ptr = gdb_mem2hex ((unsigned char *)&registers[REG_PC], ptr, 4);
399
        *ptr++ = ';';
400
        *ptr++ = _hex_char[(REG_SP >> 4) & 0xf];
401
        *ptr++ = _hex_char[REG_SP & 0xf];
402
        *ptr++ = ':';
403
        ptr = gdb_mem2hex ((unsigned char *)&registers[REG_SP], ptr, 4);
404
        *ptr++ = ';';
405
        *ptr++ = 0;
406
        gdb_send (_outbuffer);
407
    }
408
    // Initial trap (jump to GDB stub)
409
    else
410
    {
411
        sig_val = GDB_SIGHUP;
412
        _initial_trap = 0;
413
    }
414
 
415
    while (1)
416
    {
417
        // Wait for request from GDB
418
        ptr = gdb_recv();
419
 
420
        _outbuffer[0] = 0;
421
        switch (*ptr++)
422
        {
423
        //---------------------------------------------------
424
        // ? - Return signal value
425
        //---------------------------------------------------
426
        case '?':
427
            _outbuffer[0] = 'S';
428
            _outbuffer[1] = _hex_char[sig_val >> 4];
429
            _outbuffer[2] = _hex_char[sig_val & 0xf];
430
            _outbuffer[3] = 0;
431
            break;
432
        //---------------------------------------------------
433
        // g - Return all registers
434
        //---------------------------------------------------
435
        case 'g':
436
            ptr = gdb_mem2hex ((unsigned char *)registers, _outbuffer, REG_NUM * 4);
437
            break;
438
        //---------------------------------------------------
439
        // G - Set all registers
440
        //---------------------------------------------------
441
        case 'G':
442
            gdb_hex2mem (ptr, (unsigned char *)registers, REG_NUM * 4);
443
            gdb_strcpy (_outbuffer, "OK");
444
 
445
            // Make sure debug enabled on return to user program
446
            registers[REG_SR] |= (1 << OR32_SR_DBGEN);
447
            break;
448
        //---------------------------------------------------
449
        // p - Return a single register
450
        //---------------------------------------------------
451
        case 'p':
452
            if (gdb_gethexword (&ptr, &val) && (val < REG_NUM))
453
                ptr = gdb_mem2hex ((unsigned char *)&registers[val], _outbuffer, 4);
454
            else
455
                gdb_strcpy (_outbuffer, "E22");
456
            break;
457
        //---------------------------------------------------
458
        // P - Set a single register
459
        //---------------------------------------------------
460
        case 'P':
461
            // Get register number
462
            if (gdb_gethexword (&ptr, &regnum) && (*ptr++ == '=') && (regnum < REG_NUM))
463
            {
464
                // Get value to set register to
465
                gdb_gethexword(&ptr, &val);
466
                registers[regnum] = val;
467
 
468
                // If SR, make sure debug enabled on return to user program
469
                if (regnum == REG_SR)
470
                    registers[regnum] |= (1 << OR32_SR_DBGEN);
471
 
472
                gdb_strcpy (_outbuffer, "OK");
473
            }
474
            else
475
                gdb_strcpy (_outbuffer, "E22");
476
            break;
477
        //---------------------------------------------------
478
        // m - Read a block of memory
479
        //---------------------------------------------------
480
        case 'm':
481
            if (gdb_gethexword (&ptr, &val) && (*ptr++ == ',') &&
482
                gdb_gethexword (&ptr, &len) && (len < ((sizeof(_outbuffer)-1)/2)))
483
            {
484
                if (!gdb_mem2hex((unsigned char *)val, _outbuffer, len))
485
                    gdb_strcpy (_outbuffer, "E14");
486
            }
487
            else
488
                gdb_strcpy (_outbuffer,"E22");
489
            break;
490
        //---------------------------------------------------
491
        // M - Write a block of memory
492
        //---------------------------------------------------
493
        case 'M':
494
            if (gdb_gethexword (&ptr, &val) && (*ptr++ == ',') &&
495
                gdb_gethexword (&ptr, &len) && (*ptr++ == ':'))
496
            {
497
                if (gdb_hex2mem(ptr, (unsigned char *)val, len))
498
                    gdb_strcpy (_outbuffer, "OK");
499
                else
500
                    gdb_strcpy (_outbuffer, "E14");
501
 
502
                flush_caches = 1;
503
            }
504
            else
505
                gdb_strcpy (_outbuffer, "E22");
506
            break;
507
        //---------------------------------------------------
508
        // c - Continue from address (or last PC)
509
        //---------------------------------------------------
510
        case 'c':
511
            // Optional PC
512
            if (gdb_gethexword (&ptr, &val))
513
                registers[REG_PC] = val;
514
 
515
            if (flush_caches)
516
                gdb_flush_cache();
517
 
518
            return registers;
519
        //---------------------------------------------------
520
        // s - Step from address (or last PC)
521
        //---------------------------------------------------
522
        case 's':
523
            // Optional PC
524
            if (gdb_gethexword (&ptr, &val))
525
                registers[REG_PC] = val;
526
 
527
            // Set step in ESR and make sure debug is enabled
528
            registers[REG_SR] |= (1 << OR32_SR_STEP);
529
            registers[REG_SR] |= (1 << OR32_SR_DBGEN);
530
 
531
            if (flush_caches)
532
                gdb_flush_cache();
533
 
534
            return registers;
535
        }
536
 
537
        // Send response to GDB host
538
        gdb_send (_outbuffer);
539
    }
540
}
541
//-----------------------------------------------------------------
542
// gdb_main
543
//-----------------------------------------------------------------
544
void gdb_main(void)
545
{
546
    gdb_putstr("\r\nGDB Debug Agent\r\n");
547
 
548
    // Jump to debugger
549
    _initial_trap = 1;
550
    asm volatile ("l.trap 0");
551
 
552
    while (1)
553
      ;
554
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.