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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [sparc/] [kernel/] [sparc-stub.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1624 jcastillo
/* $Id: sparc-stub.c,v 1.1 2005-12-20 09:50:43 jcastillo Exp $
2
 * sparc-stub.c:  KGDB support for the Linux kernel.
3
 *
4
 * Modifications to run under Linux
5
 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
6
 *
7
 * This file originally came from the gdb sources, and the
8
 * copyright notices have been retained below.
9
 */
10
 
11
/****************************************************************************
12
 
13
                THIS SOFTWARE IS NOT COPYRIGHTED
14
 
15
   HP offers the following for use in the public domain.  HP makes no
16
   warranty with regard to the software or its performance and the
17
   user accepts the software "AS IS" with all faults.
18
 
19
   HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
20
   TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
21
   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22
 
23
****************************************************************************/
24
 
25
/****************************************************************************
26
 *  Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
27
 *
28
 *  Module name: remcom.c $
29
 *  Revision: 1.34 $
30
 *  Date: 91/03/09 12:29:49 $
31
 *  Contributor:     Lake Stevens Instrument Division$
32
 *
33
 *  Description:     low level support for gdb debugger. $
34
 *
35
 *  Considerations:  only works on target hardware $
36
 *
37
 *  Written by:      Glenn Engel $
38
 *  ModuleState:     Experimental $
39
 *
40
 *  NOTES:           See Below $
41
 *
42
 *  Modified for SPARC by Stu Grossman, Cygnus Support.
43
 *
44
 *  This code has been extensively tested on the Fujitsu SPARClite demo board.
45
 *
46
 *  To enable debugger support, two things need to happen.  One, a
47
 *  call to set_debug_traps() is necessary in order to allow any breakpoints
48
 *  or error conditions to be properly intercepted and reported to gdb.
49
 *  Two, a breakpoint needs to be generated to begin communication.  This
50
 *  is most easily accomplished by a call to breakpoint().  Breakpoint()
51
 *  simulates a breakpoint by executing a trap #1.
52
 *
53
 *************
54
 *
55
 *    The following gdb commands are supported:
56
 *
57
 * command          function                               Return value
58
 *
59
 *    g             return the value of the CPU registers  hex data or ENN
60
 *    G             set the value of the CPU registers     OK or ENN
61
 *
62
 *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA      hex data or ENN
63
 *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA      OK or ENN
64
 *
65
 *    c             Resume at current address              SNN   ( signal NN)
66
 *    cAA..AA       Continue at address AA..AA             SNN
67
 *
68
 *    s             Step one instruction                   SNN
69
 *    sAA..AA       Step one instruction from AA..AA       SNN
70
 *
71
 *    k             kill
72
 *
73
 *    ?             What was the last sigval ?             SNN   (signal NN)
74
 *
75
 *    bBB..BB       Set baud rate to BB..BB                OK or BNN, then sets
76
 *                                                         baud rate
77
 *
78
 * All commands and responses are sent with a packet which includes a
79
 * checksum.  A packet consists of
80
 *
81
 * $<packet info>#<checksum>.
82
 *
83
 * where
84
 * <packet info> :: <characters representing the command or response>
85
 * <checksum>    :: < two hex digits computed as modulo 256 sum of <packetinfo>>
86
 *
87
 * When a packet is received, it is first acknowledged with either '+' or '-'.
88
 * '+' indicates a successful transfer.  '-' indicates a failed transfer.
89
 *
90
 * Example:
91
 *
92
 * Host:                  Reply:
93
 * $m0,10#2a               +$00010203040506070809101112131415#42
94
 *
95
 ****************************************************************************/
96
 
97
#include <linux/kernel.h>
98
#include <linux/string.h>
99
#include <linux/mm.h>
100
 
101
#include <asm/system.h>
102
#include <asm/signal.h>
103
#include <asm/oplib.h>
104
#include <asm/head.h>
105
#include <asm/traps.h>
106
#include <asm/system.h>
107
#include <asm/vac-ops.h>
108
#include <asm/kgdb.h>
109
#include <asm/pgtable.h>
110
/*
111
 *
112
 * external low-level support routines
113
 */
114
 
115
extern void putDebugChar(char);   /* write a single character      */
116
extern char getDebugChar(void);   /* read and return a single char */
117
 
118
/*
119
 * BUFMAX defines the maximum number of characters in inbound/outbound buffers
120
 * at least NUMREGBYTES*2 are needed for register packets
121
 */
122
#define BUFMAX 2048
123
 
124
static int initialized = 0;      /* !0 means we've been initialized */
125
 
126
static const char hexchars[]="0123456789abcdef";
127
 
128
#define NUMREGS 72
129
 
130
/* Number of bytes of registers.  */
131
#define NUMREGBYTES (NUMREGS * 4)
132
enum regnames {G0, G1, G2, G3, G4, G5, G6, G7,
133
                 O0, O1, O2, O3, O4, O5, SP, O7,
134
                 L0, L1, L2, L3, L4, L5, L6, L7,
135
                 I0, I1, I2, I3, I4, I5, FP, I7,
136
 
137
                 F0, F1, F2, F3, F4, F5, F6, F7,
138
                 F8, F9, F10, F11, F12, F13, F14, F15,
139
                 F16, F17, F18, F19, F20, F21, F22, F23,
140
                 F24, F25, F26, F27, F28, F29, F30, F31,
141
                 Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR };
142
 
143
 
144
extern void trap_low(void);  /* In arch/sparc/kernel/entry.S */
145
 
146
unsigned long get_sun4cpte(unsigned long addr)
147
{
148
        unsigned long entry;
149
 
150
        __asm__ __volatile__("\n\tlda [%1] %2, %0\n\t" :
151
                             "=r" (entry) :
152
                             "r" (addr), "i" (ASI_PTE));
153
        return entry;
154
}
155
 
156
unsigned long get_sun4csegmap(unsigned long addr)
157
{
158
        unsigned long entry;
159
 
160
        __asm__ __volatile__("\n\tlduba [%1] %2, %0\n\t" :
161
                             "=r" (entry) :
162
                             "r" (addr), "i" (ASI_SEGMAP));
163
        return entry;
164
}
165
 
166
static void flush_cache_all_nop(void)
167
{
168
}
169
 
170
/* Place where we save old trap entries for restoration */
171
struct tt_entry kgdb_savettable[256];
172
typedef void (*trapfunc_t)(void);
173
 
174
/* Helper routine for manipulation of kgdb_savettable */
175
static inline void copy_ttentry(struct tt_entry *src, struct tt_entry *dest)
176
{
177
        dest->inst_one = src->inst_one;
178
        dest->inst_two = src->inst_two;
179
        dest->inst_three = src->inst_three;
180
        dest->inst_four = src->inst_four;
181
}
182
 
183
/* Initialize the kgdb_savettable so that debugging can commence */
184
static void eh_init(void)
185
{
186
        int i, flags;
187
 
188
        save_flags(flags); cli();
189
        for(i=0; i < 256; i++)
190
                copy_ttentry(&sparc_ttable[i], &kgdb_savettable[i]);
191
        restore_flags(flags);
192
}
193
 
194
/* Install an exception handler for kgdb */
195
static void exceptionHandler(int tnum, trapfunc_t trap_entry)
196
{
197
        unsigned long te_addr = (unsigned long) trap_entry;
198
        int flags;
199
 
200
        /* We are dorking with a live trap table, all irqs off */
201
        save_flags(flags); cli();
202
 
203
        /* Make new vector */
204
        sparc_ttable[tnum].inst_one =
205
                SPARC_BRANCH((unsigned long) te_addr,
206
                             (unsigned long) &sparc_ttable[tnum].inst_one);
207
        sparc_ttable[tnum].inst_two = SPARC_RD_PSR_L0;
208
        sparc_ttable[tnum].inst_three = SPARC_NOP;
209
        sparc_ttable[tnum].inst_four = SPARC_NOP;
210
 
211
        restore_flags(flags);
212
}
213
 
214
/* Convert ch from a hex digit to an int */
215
static int
216
hex(unsigned char ch)
217
{
218
        if (ch >= 'a' && ch <= 'f')
219
                return ch-'a'+10;
220
        if (ch >= '0' && ch <= '9')
221
                return ch-'0';
222
        if (ch >= 'A' && ch <= 'F')
223
                return ch-'A'+10;
224
        return -1;
225
}
226
 
227
/* scan for the sequence $<data>#<checksum>     */
228
static void
229
getpacket(char *buffer)
230
{
231
        unsigned char checksum;
232
        unsigned char xmitcsum;
233
        int i;
234
        int count;
235
        unsigned char ch;
236
 
237
        do {
238
                /* wait around for the start character, ignore all other characters */
239
                while ((ch = (getDebugChar() & 0x7f)) != '$') ;
240
 
241
                checksum = 0;
242
                xmitcsum = -1;
243
 
244
                count = 0;
245
 
246
                /* now, read until a # or end of buffer is found */
247
                while (count < BUFMAX) {
248
                        ch = getDebugChar() & 0x7f;
249
                        if (ch == '#')
250
                                break;
251
                        checksum = checksum + ch;
252
                        buffer[count] = ch;
253
                        count = count + 1;
254
                }
255
 
256
                if (count >= BUFMAX)
257
                        continue;
258
 
259
                buffer[count] = 0;
260
 
261
                if (ch == '#') {
262
                        xmitcsum = hex(getDebugChar() & 0x7f) << 4;
263
                        xmitcsum |= hex(getDebugChar() & 0x7f);
264
                        if (checksum != xmitcsum)
265
                                putDebugChar('-');      /* failed checksum */
266
                        else {
267
                                putDebugChar('+'); /* successful transfer */
268
                                /* if a sequence char is present, reply the ID */
269
                                if (buffer[2] == ':') {
270
                                        putDebugChar(buffer[0]);
271
                                        putDebugChar(buffer[1]);
272
                                        /* remove sequence chars from buffer */
273
                                        count = strlen(buffer);
274
                                        for (i=3; i <= count; i++)
275
                                                buffer[i-3] = buffer[i];
276
                                }
277
                        }
278
                }
279
        } while (checksum != xmitcsum);
280
}
281
 
282
/* send the packet in buffer.  */
283
 
284
static void
285
putpacket(unsigned char *buffer)
286
{
287
        unsigned char checksum;
288
        int count;
289
        unsigned char ch, recv;
290
 
291
        /*  $<packet info>#<checksum>. */
292
        do {
293
                putDebugChar('$');
294
                checksum = 0;
295
                count = 0;
296
 
297
                while ((ch = buffer[count])) {
298
                        putDebugChar(ch);
299
                        checksum += ch;
300
                        count += 1;
301
                }
302
 
303
                putDebugChar('#');
304
                putDebugChar(hexchars[checksum >> 4]);
305
                putDebugChar(hexchars[checksum & 0xf]);
306
                recv = getDebugChar();
307
        } while ((recv & 0x7f) != '+');
308
}
309
 
310
static char remcomInBuffer[BUFMAX];
311
static char remcomOutBuffer[BUFMAX];
312
 
313
/* Convert the memory pointed to by mem into hex, placing result in buf.
314
 * Return a pointer to the last char put in buf (null), in case of mem fault,
315
 * return 0.
316
 */
317
 
318
static unsigned char *
319
mem2hex(char *mem, char *buf, int count)
320
{
321
        unsigned char ch;
322
 
323
        while (count-- > 0) {
324
                ch = *mem++;
325
                *buf++ = hexchars[ch >> 4];
326
                *buf++ = hexchars[ch & 0xf];
327
        }
328
 
329
        *buf = 0;
330
        return buf;
331
}
332
 
333
/* convert the hex array pointed to by buf into binary to be placed in mem
334
 * return a pointer to the character AFTER the last byte written.
335
*/
336
static char *
337
hex2mem(char *buf, char *mem, int count)
338
{
339
        int i;
340
        unsigned char ch;
341
 
342
        for (i=0; i<count; i++) {
343
 
344
                ch = hex(*buf++) << 4;
345
                ch |= hex(*buf++);
346
                *mem++ = ch;
347
        }
348
        return mem;
349
}
350
 
351
/* This table contains the mapping between SPARC hardware trap types, and
352
   signals, which are primarily what GDB understands.  It also indicates
353
   which hardware traps we need to commandeer when initializing the stub. */
354
 
355
static struct hard_trap_info
356
{
357
  unsigned char tt;             /* Trap type code for SPARC */
358
  unsigned char signo;          /* Signal that we map this trap into */
359
} hard_trap_info[] = {
360
  {SP_TRAP_SBPT, SIGTRAP},      /* ta 1 - Linux/KGDB software breakpoint */
361
  {0, 0}                  /* Must be last */
362
};
363
 
364
/* Set up exception handlers for tracing and breakpoints */
365
 
366
void
367
set_debug_traps(void)
368
{
369
        struct hard_trap_info *ht;
370
        unsigned long flags;
371
        unsigned char c;
372
 
373
        save_flags(flags); cli();
374
        flush_cache_all = flush_cache_all_nop;
375
 
376
        /* Initialize our copy of the Linux Sparc trap table */
377
        eh_init();
378
 
379
        for (ht = hard_trap_info; ht->tt && ht->signo; ht++) {
380
                /* Only if it doesn't destroy our fault handlers */
381
                if((ht->tt != SP_TRAP_TFLT) &&
382
                   (ht->tt != SP_TRAP_DFLT))
383
                        exceptionHandler(ht->tt, trap_low);
384
        }
385
 
386
        /* In case GDB is started before us, ack any packets (presumably
387
         * "$?#xx") sitting there.
388
         */
389
 
390
        while((c = getDebugChar()) != '$');
391
        while((c = getDebugChar()) != '#');
392
        c = getDebugChar(); /* eat first csum byte */
393
        c = getDebugChar(); /* eat second csum byte */
394
        putDebugChar('+'); /* ack it */
395
 
396
        initialized = 1; /* connect! */
397
        restore_flags(flags);
398
}
399
 
400
/* Convert the SPARC hardware trap type code to a unix signal number. */
401
 
402
static int
403
computeSignal(int tt)
404
{
405
        struct hard_trap_info *ht;
406
 
407
        for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
408
                if (ht->tt == tt)
409
                        return ht->signo;
410
 
411
        return SIGHUP;         /* default for things we don't know about */
412
}
413
 
414
/*
415
 * While we find nice hex chars, build an int.
416
 * Return number of chars processed.
417
 */
418
 
419
static int
420
hexToInt(char **ptr, int *intValue)
421
{
422
        int numChars = 0;
423
        int hexValue;
424
 
425
        *intValue = 0;
426
 
427
        while (**ptr) {
428
                hexValue = hex(**ptr);
429
                if (hexValue < 0)
430
                        break;
431
 
432
                *intValue = (*intValue << 4) | hexValue;
433
                numChars ++;
434
 
435
                (*ptr)++;
436
        }
437
 
438
        return (numChars);
439
}
440
 
441
/*
442
 * This function does all command processing for interfacing to gdb.  It
443
 * returns 1 if you should skip the instruction at the trap address, 0
444
 * otherwise.
445
 */
446
 
447
extern void breakinst(void);
448
 
449
void
450
handle_exception (unsigned long *registers)
451
{
452
        int tt;       /* Trap type */
453
        int sigval;
454
        int addr;
455
        int length;
456
        char *ptr;
457
        unsigned long *sp;
458
 
459
        /* First, we must force all of the windows to be spilled out */
460
 
461
        asm("save %sp, -64, %sp\n\t"
462
            "save %sp, -64, %sp\n\t"
463
            "save %sp, -64, %sp\n\t"
464
            "save %sp, -64, %sp\n\t"
465
            "save %sp, -64, %sp\n\t"
466
            "save %sp, -64, %sp\n\t"
467
            "save %sp, -64, %sp\n\t"
468
            "save %sp, -64, %sp\n\t"
469
            "restore\n\t"
470
            "restore\n\t"
471
            "restore\n\t"
472
            "restore\n\t"
473
            "restore\n\t"
474
            "restore\n\t"
475
            "restore\n\t"
476
            "restore\n\t");
477
 
478
        if (registers[PC] == (unsigned long)breakinst) {
479
                /* Skip over breakpoint trap insn */
480
                registers[PC] = registers[NPC];
481
                registers[NPC] += 4;
482
        }
483
 
484
        sp = (unsigned long *)registers[SP];
485
 
486
        tt = (registers[TBR] >> 4) & 0xff;
487
 
488
        /* reply to host that an exception has occurred */
489
        sigval = computeSignal(tt);
490
        ptr = remcomOutBuffer;
491
 
492
        *ptr++ = 'T';
493
        *ptr++ = hexchars[sigval >> 4];
494
        *ptr++ = hexchars[sigval & 0xf];
495
 
496
        *ptr++ = hexchars[PC >> 4];
497
        *ptr++ = hexchars[PC & 0xf];
498
        *ptr++ = ':';
499
        ptr = mem2hex((char *)&registers[PC], ptr, 4);
500
        *ptr++ = ';';
501
 
502
        *ptr++ = hexchars[FP >> 4];
503
        *ptr++ = hexchars[FP & 0xf];
504
        *ptr++ = ':';
505
        ptr = mem2hex((char *) (sp + 8 + 6), ptr, 4); /* FP */
506
        *ptr++ = ';';
507
 
508
        *ptr++ = hexchars[SP >> 4];
509
        *ptr++ = hexchars[SP & 0xf];
510
        *ptr++ = ':';
511
        ptr = mem2hex((char *)&sp, ptr, 4);
512
        *ptr++ = ';';
513
 
514
        *ptr++ = hexchars[NPC >> 4];
515
        *ptr++ = hexchars[NPC & 0xf];
516
        *ptr++ = ':';
517
        ptr = mem2hex((char *)&registers[NPC], ptr, 4);
518
        *ptr++ = ';';
519
 
520
        *ptr++ = hexchars[O7 >> 4];
521
        *ptr++ = hexchars[O7 & 0xf];
522
        *ptr++ = ':';
523
        ptr = mem2hex((char *)&registers[O7], ptr, 4);
524
        *ptr++ = ';';
525
 
526
        *ptr++ = 0;
527
 
528
        putpacket(remcomOutBuffer);
529
 
530
        /* XXX We may want to add some features dealing with poking the
531
         * XXX page tables, the real ones on the srmmu, and what is currently
532
         * XXX loaded in the sun4/sun4c tlb at this point in time.  But this
533
         * XXX also required hacking to the gdb sources directly...
534
         */
535
 
536
        while (1) {
537
                remcomOutBuffer[0] = 0;
538
 
539
                getpacket(remcomInBuffer);
540
                switch (remcomInBuffer[0]) {
541
                case '?':
542
                        remcomOutBuffer[0] = 'S';
543
                        remcomOutBuffer[1] = hexchars[sigval >> 4];
544
                        remcomOutBuffer[2] = hexchars[sigval & 0xf];
545
                        remcomOutBuffer[3] = 0;
546
                        break;
547
 
548
                case 'd':
549
                        /* toggle debug flag */
550
                        break;
551
 
552
                case 'g':               /* return the value of the CPU registers */
553
                {
554
                        ptr = remcomOutBuffer;
555
                        /* G & O regs */
556
                        ptr = mem2hex((char *)registers, ptr, 16 * 4);
557
                        /* L & I regs */
558
                        ptr = mem2hex((char *) (sp + 0), ptr, 16 * 4);
559
                        /* Floating point */
560
                        memset(ptr, '0', 32 * 8);
561
                        /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
562
                        mem2hex((char *)&registers[Y], (ptr + 32 * 4 * 2), (8 * 4));
563
                }
564
                        break;
565
 
566
                case 'G':          /* set the value of the CPU registers - return OK */
567
                {
568
                        unsigned long *newsp, psr;
569
 
570
                        psr = registers[PSR];
571
 
572
                        ptr = &remcomInBuffer[1];
573
                        /* G & O regs */
574
                        hex2mem(ptr, (char *)registers, 16 * 4);
575
                        /* L & I regs */
576
                        hex2mem(ptr + 16 * 4 * 2, (char *) (sp + 0), 16 * 4);
577
                        /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
578
                        hex2mem(ptr + 64 * 4 * 2, (char *)&registers[Y], 8 * 4);
579
 
580
                        /* See if the stack pointer has moved.  If so,
581
                         * then copy the saved locals and ins to the
582
                         * new location.  This keeps the window
583
                         * overflow and underflow routines happy.
584
                         */
585
 
586
                        newsp = (unsigned long *)registers[SP];
587
                        if (sp != newsp)
588
                                sp = memcpy(newsp, sp, 16 * 4);
589
 
590
                        /* Don't allow CWP to be modified. */
591
 
592
                        if (psr != registers[PSR])
593
                                registers[PSR] = (psr & 0x1f) | (registers[PSR] & ~0x1f);
594
 
595
                        strcpy(remcomOutBuffer,"OK");
596
                }
597
                        break;
598
 
599
                case 'm':         /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
600
                        /* Try to read %x,%x.  */
601
 
602
                        ptr = &remcomInBuffer[1];
603
 
604
                        if (hexToInt(&ptr, &addr)
605
                            && *ptr++ == ','
606
                            && hexToInt(&ptr, &length)) {
607
                                if (mem2hex((char *)addr, remcomOutBuffer, length))
608
                                        break;
609
 
610
                                strcpy (remcomOutBuffer, "E03");
611
                        } else {
612
                                strcpy(remcomOutBuffer,"E01");
613
                        }
614
                        break;
615
 
616
                case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
617
                        /* Try to read '%x,%x:'.  */
618
 
619
                        ptr = &remcomInBuffer[1];
620
 
621
                        if (hexToInt(&ptr, &addr)
622
                            && *ptr++ == ','
623
                            && hexToInt(&ptr, &length)
624
                            && *ptr++ == ':') {
625
                                if (hex2mem(ptr, (char *)addr, length)) {
626
                                        strcpy(remcomOutBuffer, "OK");
627
                                } else {
628
                                        strcpy(remcomOutBuffer, "E03");
629
                                }
630
                        } else {
631
                                strcpy(remcomOutBuffer, "E02");
632
                        }
633
                        break;
634
 
635
                case 'c':    /* cAA..AA    Continue at address AA..AA(optional) */
636
                        /* try to read optional parameter, pc unchanged if no parm */
637
 
638
                        ptr = &remcomInBuffer[1];
639
                        if (hexToInt(&ptr, &addr)) {
640
                                registers[PC] = addr;
641
                                registers[NPC] = addr + 4;
642
                        }
643
 
644
/* Need to flush the instruction cache here, as we may have deposited a
645
 * breakpoint, and the icache probably has no way of knowing that a data ref to
646
 * some location may have changed something that is in the instruction cache.
647
 */
648
                        flush_cache_all();
649
                        return;
650
 
651
                        /* kill the program */
652
                case 'k' :              /* do nothing */
653
                        break;
654
                case 'r':               /* Reset */
655
                        asm ("call 0\n\t"
656
                             "nop\n\t");
657
                        break;
658
                }                       /* switch */
659
 
660
                /* reply to the request */
661
                putpacket(remcomOutBuffer);
662
        } /* while(1) */
663
}
664
 
665
/* This function will generate a breakpoint exception.  It is used at the
666
   beginning of a program to sync up with a debugger and can be used
667
   otherwise as a quick means to stop program execution and "break" into
668
   the debugger. */
669
 
670
void
671
breakpoint(void)
672
{
673
        if (!initialized)
674
                return;
675
 
676
        /* Again, watch those c-prefixes for solaris/elf kernels */
677
#ifndef __svr4__
678
        asm("   .globl _breakinst
679
 
680
             _breakinst: ta 1
681
            ");
682
#else
683
        asm("   .globl breakinst
684
 
685
             breakinst: ta 1
686
            ");
687
#endif
688
}

powered by: WebSVN 2.1.0

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