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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [hal/] [v85x/] [v850/] [current/] [src/] [v850_ice.cxx] - Blame information for rev 843

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//========================================================================
2
//
3
//      v850_ice.cxx
4
//
5
//      ICE debugging support for V850 processors
6
//
7
//========================================================================
8
// ####ECOSGPLCOPYRIGHTBEGIN####                                            
9
// -------------------------------------------                              
10
// This file is part of eCos, the Embedded Configurable Operating System.   
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under    
14
// the terms of the GNU General Public License as published by the Free     
15
// Software Foundation; either version 2 or (at your option) any later      
16
// version.                                                                 
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT      
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
21
// for more details.                                                        
22
//
23
// You should have received a copy of the GNU General Public License        
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
26
//
27
// As a special exception, if other files instantiate templates or use      
28
// macros or inline functions from this file, or you compile this file      
29
// and link it with other works to produce a work based on this file,       
30
// this file does not by itself cause the resulting work to be covered by   
31
// the GNU General Public License. However the source code for this file    
32
// must still be made available in accordance with section (3) of the GNU   
33
// General Public License v2.                                               
34
//
35
// This exception does not invalidate any other reasons why a work based    
36
// on this file might be covered by the GNU General Public License.         
37
// -------------------------------------------                              
38
// ####ECOSGPLCOPYRIGHTEND####                                              
39
//========================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):     jlarmour
43
// Contributors:  
44
// Date:          2001-03-12
45
// Purpose:       
46
// Description:   ICE debugging support for V850 processors
47
// Usage:         
48
//
49
//####DESCRIPTIONEND####
50
//
51
//========================================================================
52
 
53
#include <pkgconf/hal.h>
54
 
55
#ifdef CYGDBG_HAL_V850_ICE
56
 
57
#include <stddef.h>
58
#include <cyg/infra/cyg_type.h>
59
#include <cyg/hal/dbg-threads-api.h>
60
#include <cyg/hal/nec-stub.h>
61
#include <cyg/hal/hal_arch.h>
62
 
63
#define ICEDEBUG 0
64
 
65
#if ICEDEBUG
66
#include <cyg/infra/diag.h>
67
#endif
68
 
69
/* ----------------------------------------------------------------------- */
70
/* Common ICE syscall information */
71
 
72
/* Magic area for syscall information, from vectors.S */
73
__externC char hal_v85x_ice_syscall_info[];
74
 
75
/* Syscall operation codes. This is a "contract" with the host. */
76
 
77
#define V850ICE_SYSCALL_GET_THREADNEXT 1
78
#define V850ICE_SYSCALL_GET_THREADREGS 2
79
#define V850ICE_SYSCALL_SET_THREADREGS 3
80
#define V850ICE_SYSCALL_GET_CURRTHREAD 4
81
#define V850ICE_SYSCALL_GET_THREADINFO 5
82
#define V850ICE_SYSCALL_CONSOLE_INPUT  6
83
 
84
/* System call information area layout */
85
#define ICE_SYSCALL_INFO_VALIDATOR     (*(int *)&hal_v85x_ice_syscall_info[0])
86
#define ICE_SYSCALL_INFO_STARTPC       (*(int *)&hal_v85x_ice_syscall_info[4])
87
#define ICE_SYSCALL_INFO_ENDPC         (*(int *)&hal_v85x_ice_syscall_info[8])
88
#define ICE_SYSCALL_INFO_STACK         (*(int *)&hal_v85x_ice_syscall_info[12])
89
#define ICE_SYSCALL_INFO_IOBUF         (*(int *)&hal_v85x_ice_syscall_info[16])
90
#define ICE_SYSCALL_INFO_DIAGOUTPC     (*(int *)&hal_v85x_ice_syscall_info[20])
91
#define ICE_SYSCALL_INFO_DIAGOUTBUF    (*(int *)&hal_v85x_ice_syscall_info[24])
92
#define ICE_SYSCALL_INFO_DIAGOUTBUFEND (*(int *)&hal_v85x_ice_syscall_info[28])
93
 
94
/* We can't use normal memcpy when invoked via the ICE. It may be unsafe. */
95
static void
96
my_memcpy( void *vd, const void *vs, int n)
97
{
98
    char *d = (char *)vd;
99
    char *s = (char *)vs;
100
 
101
    while (n--)
102
        *d++=*s++;
103
}
104
 
105
static void
106
my_memset( void *vs, char c, int n)
107
{
108
    char *s = (char *)vs;
109
 
110
    while (n--)
111
        *s++ = c;
112
}
113
 
114
/* ----------------------------------------------------------------------- */
115
/* Support for diag output via ICE */
116
 
117
#ifdef CYGDBG_HAL_V85X_V850_ICE_DIAG
118
 
119
#include <cyg/hal/hal_if.h>
120
 
121
static volatile cyg_uint8 v850ice_output_buf[128];
122
static volatile cyg_uint8 *v850ice_output_end = v850ice_output_buf;
123
#define OUTPUT_BUF_END (&v850ice_output_buf[ sizeof(v850ice_output_buf)])
124
static volatile cyg_uint8 v850ice_input_buf[128];
125
#define INPUT_BUF_END (&v850ice_input_buf[ sizeof(v850ice_input_buf)])
126
static volatile cyg_uint8 *v850ice_input_ptr_put = v850ice_input_buf;
127
static volatile cyg_uint8 *v850ice_input_ptr_get = v850ice_input_buf;
128
static volatile cyg_uint8 v850ice_input_buf_bytes_used = 0;
129
 
130
__externC void hal_v850_ice_output_break(void);
131
 
132
static void
133
hal_v850_ice_indicate_output(void)
134
{
135
    HAL_BREAKPOINT(hal_v850_ice_output_break);
136
}
137
 
138
// Actually write character
139
void
140
cyg_hal_plf_diag_ice_putc(void* __ch_data, cyg_uint8 c)
141
{
142
    CYGARC_HAL_SAVE_GP();
143
 
144
    // Send character
145
    *v850ice_output_end++ = c;
146
 
147
    if (c == '\n' ||
148
        v850ice_output_end == OUTPUT_BUF_END) {
149
        hal_v850_ice_indicate_output();
150
        v850ice_output_end = v850ice_output_buf;
151
    }
152
 
153
    CYGARC_HAL_RESTORE_GP();
154
}
155
 
156
static cyg_bool
157
cyg_hal_plf_diag_ice_getc_nonblock(void* __ch_data, cyg_uint8* ch)
158
{
159
    if ( v850ice_input_buf_bytes_used == 0 )
160
        return false; // buffer empty
161
 
162
    *ch = *v850ice_input_ptr_get++;
163
    if ( v850ice_input_ptr_get == INPUT_BUF_END ) {
164
        v850ice_input_ptr_get = v850ice_input_buf;
165
    }
166
 
167
    v850ice_input_buf_bytes_used--;
168
 
169
    return true;
170
}
171
 
172
cyg_uint8
173
cyg_hal_plf_diag_ice_getc(void* __ch_data)
174
{
175
    cyg_uint8 ch;
176
    CYGARC_HAL_SAVE_GP();
177
 
178
    while(!cyg_hal_plf_diag_ice_getc_nonblock(__ch_data, &ch));
179
 
180
    CYGARC_HAL_RESTORE_GP();
181
    return ch;
182
}
183
 
184
static cyg_bool
185
cyg_hal_plf_diag_ice_receive_char(cyg_uint8 ch)
186
{
187
     /* buffer full? */
188
    if ( v850ice_input_buf_bytes_used == sizeof(v850ice_input_buf) )
189
        return false;
190
 
191
    *v850ice_input_ptr_put++ = ch;
192
 
193
    if ( v850ice_input_ptr_put == INPUT_BUF_END ) {
194
        v850ice_input_ptr_put = v850ice_input_buf;
195
    }
196
    return true;
197
}
198
 
199
static void
200
cyg_hal_plf_diag_ice_write(void* __ch_data, const cyg_uint8* __buf,
201
                           cyg_uint32 __len)
202
{
203
    CYGARC_HAL_SAVE_GP();
204
 
205
#define MIN(__x, __y) ((__x) < (__y) ? (__x) : (__y))
206
 
207
    while(__len > 0) {
208
        int copylen = MIN(__len,
209
                          (cyg_uint32) (OUTPUT_BUF_END - v850ice_output_end));
210
 
211
        my_memcpy( (void *)v850ice_output_buf, __buf, copylen );
212
        __len -= copylen;
213
        v850ice_output_end += copylen;
214
        hal_v850_ice_indicate_output();
215
        v850ice_output_end = v850ice_output_buf;
216
    }
217
 
218
    CYGARC_HAL_RESTORE_GP();
219
}
220
 
221
static void
222
cyg_hal_plf_diag_ice_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
223
{
224
    CYGARC_HAL_SAVE_GP();
225
 
226
    while(__len-- > 0)
227
        *__buf++ = cyg_hal_plf_diag_ice_getc(__ch_data);
228
 
229
    CYGARC_HAL_RESTORE_GP();
230
}
231
 
232
static cyg_int32 msec_timeout = 1000;
233
 
234
cyg_bool
235
cyg_hal_plf_diag_ice_getc_timeout(void* __ch_data, cyg_uint8* ch)
236
{
237
    int delay_count = msec_timeout * 10; // delay in .1 ms steps
238
    cyg_bool res;
239
    CYGARC_HAL_SAVE_GP();
240
 
241
    for(;;) {
242
        res = cyg_hal_plf_diag_ice_getc_nonblock(__ch_data, ch);
243
        if (res || 0 == delay_count--)
244
            break;
245
 
246
        CYGACC_CALL_IF_DELAY_US(100);
247
    }
248
 
249
    CYGARC_HAL_RESTORE_GP();
250
    return res;
251
}
252
 
253
static int
254
cyg_hal_plf_diag_ice_control(void *__ch_data, __comm_control_cmd_t __func, ...)
255
{
256
    static int irq_state = 0;
257
    int ret = 0;
258
    CYGARC_HAL_SAVE_GP();
259
 
260
    switch (__func) {
261
    case __COMMCTL_IRQ_ENABLE:
262
        irq_state = 1;
263
        break;
264
    case __COMMCTL_IRQ_DISABLE:
265
        ret = irq_state;
266
        irq_state = 0;
267
        break;
268
    case __COMMCTL_DBG_ISR_VECTOR:
269
        ret = 0;
270
        break;
271
    case __COMMCTL_SET_TIMEOUT:
272
    {
273
        va_list ap;
274
 
275
        va_start(ap, __func);
276
 
277
        ret = msec_timeout;
278
        msec_timeout = va_arg(ap, cyg_uint32);
279
 
280
        va_end(ap);
281
    }
282
    default:
283
        break;
284
    }
285
    CYGARC_HAL_RESTORE_GP();
286
    return ret;
287
}
288
 
289
static int
290
cyg_hal_plf_diag_ice_isr(void *__ch_data, int* __ctrlc,
291
                         CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
292
{
293
    CYGARC_HAL_SAVE_GP();
294
    *__ctrlc = 0;
295
    CYGARC_HAL_RESTORE_GP();
296
    return 0;
297
}
298
 
299
__externC void
300
cyg_hal_plf_ice_diag_init()
301
{
302
    hal_virtual_comm_table_t* comm;
303
    int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
304
 
305
    // Init channels
306
    ICE_SYSCALL_INFO_DIAGOUTPC     = (int)&hal_v850_ice_output_break;
307
    ICE_SYSCALL_INFO_DIAGOUTBUF    = (int)&v850ice_output_buf[0];
308
    ICE_SYSCALL_INFO_DIAGOUTBUFEND = (int)&v850ice_output_end;
309
 
310
    // Setup procs in the vector table
311
 
312
    // Set channel 1
313
    CYGACC_CALL_IF_SET_CONSOLE_COMM(1);
314
    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
315
    CYGACC_COMM_IF_CH_DATA_SET(*comm, 0);
316
    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_diag_ice_write);
317
    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_diag_ice_read);
318
    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_diag_ice_putc);
319
    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_diag_ice_getc);
320
    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_diag_ice_control);
321
    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_diag_ice_isr);
322
    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_diag_ice_getc_timeout);
323
 
324
    // Restore original console
325
    CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
326
}
327
 
328
#endif // ifdef CYGDBG_HAL_V85X_V850_ICE_DIAG
329
 
330
 
331
/* ----------------------------------------------------------------------- */
332
/* Support for debugging via ICE */
333
 
334
#define ICE_STACK_SIZE 1024/sizeof(int)
335
static int ice_stack[ICE_STACK_SIZE]; // ints so as to ensure alignment
336
static int ice_iobuf[128];
337
 
338
static void
339
hal_v85x_ice_syscall_end(void)
340
{
341
    for (;;);
342
}
343
 
344
static void
345
hal_v85x_ice_syscall(void)
346
{
347
    int code, len;
348
    code = ice_iobuf[0];
349
    len = ice_iobuf[1];
350
    switch (code) {
351
    case V850ICE_SYSCALL_GET_THREADNEXT:
352
        {
353
            int ret;
354
            threadref currthread, nextthread;
355
            int thread_id;
356
 
357
            /* Unmarshall thread ref */
358
            my_memcpy( &currthread, &ice_iobuf[2], 8 );
359
#if ICEDEBUG
360
            diag_printf("*NEXTTHREAD* currthread=%08x,%08x\n",
361
                        *(int *)&currthread[0],
362
                        *(int *)(((char *)&currthread[0])+4));
363
#endif
364
            // null threadref?
365
            if ((ice_iobuf[2] == 0) &&
366
                (ice_iobuf[3] == 0)) {
367
#if ICEDEBUG
368
                diag_printf("null threadref\n");
369
#endif
370
                ret = dbg_threadlist( 1, NULL, &nextthread );
371
            } else {
372
#if ICEDEBUG
373
                diag_printf("non-null threadref\n");
374
#endif
375
                ret = dbg_threadlist( 0, &currthread, &nextthread );
376
            }
377
#if ICEDEBUG
378
            diag_printf("*NEXTTHREAD* nextthread=%08x,%08x\n",
379
                        *(int *)&nextthread[0],
380
                        *(int *)(((char *)&nextthread[0])+4));
381
#endif
382
            if (ret) { // if valid thread found
383
                thread_id = dbg_thread_id( &nextthread );
384
                /* Returns 0 on error */
385
                if (thread_id != 0) {
386
                    ice_iobuf[1] = thread_id;
387
                    my_memcpy( &ice_iobuf[2], nextthread, 8 );
388
 
389
                    // set return data size to 12
390
                    ice_iobuf[0] = 12;
391
#if ICEDEBUG
392
                    {
393
                        int i;
394
                        for (i=0; i<3; i++)
395
                            diag_printf("%x, ", ice_iobuf[i]);
396
                        diag_printf("\n");
397
                    }
398
#endif
399
                } else {
400
                    ret = 0;
401
                }
402
            }
403
            if (!ret) {
404
                // set to null
405
                my_memset( &ice_iobuf[1], 0, 12 );
406
            }
407
        }
408
        break;
409
    case V850ICE_SYSCALL_GET_THREADREGS:
410
        {
411
            int ret;
412
            threadref thread;
413
 
414
            /* Unmarshall thread ref */
415
            my_memcpy( &thread, &ice_iobuf[2], 8 );
416
#if ICEDEBUG
417
            diag_printf("*GTHREADREGS* thread=%08x,%08x\n", *(int *)&thread[0],
418
                        *(int *)(((char *)&thread[0])+4));
419
#endif
420
            ret = dbg_getthreadreg( &thread, NUMREGS, &ice_iobuf[1]);
421
            if (ret)
422
                ice_iobuf[0] = NUMREGS * 4;
423
            else
424
                ice_iobuf[0] = 0;
425
 
426
        }
427
        break;
428
    case V850ICE_SYSCALL_SET_THREADREGS:
429
        {
430
            int ret;
431
            threadref thread;
432
 
433
            /* Unmarshall thread ref */
434
            my_memcpy( &thread, &ice_iobuf[2], 8 );
435
#if ICEDEBUG
436
            diag_printf("*STHREADREGS* thread=%08x,%08x\n", *(int *)&thread[0],
437
                        *(int *)(((char *)&thread[0])+4));
438
#endif
439
            ret = dbg_setthreadreg( &thread, NUMREGS, &ice_iobuf[4]);
440
            if (ret)
441
                ice_iobuf[0] = 1;
442
            else
443
                ice_iobuf[0] = 0;
444
        }
445
        break;
446
    case V850ICE_SYSCALL_GET_CURRTHREAD:
447
        {
448
            int ret, thread_id;
449
            threadref thread;
450
 
451
            ret = dbg_currthread( &thread );
452
#if ICEDEBUG
453
            diag_printf("*CURRTHREAD* thread=%08x,%08x\n", *(int *)&thread[0],
454
                        *(int *)(((char *)&thread[0])+4));
455
#endif
456
 
457
            if (ret) {
458
                thread_id = dbg_thread_id( &thread );
459
                /* Returns 0 on error */
460
                if (thread_id != 0) {
461
                    ice_iobuf[1] = thread_id;
462
                    my_memcpy( &ice_iobuf[2], thread, 8 );
463
                }
464
                else {
465
                    ret = 0;
466
                }
467
            }
468
            if (ret)
469
                ice_iobuf[0] = 12;
470
            else
471
                ice_iobuf[0] = 0;
472
        }
473
        break;
474
    case V850ICE_SYSCALL_GET_THREADINFO:
475
        {
476
            int ret;
477
            threadref thread;
478
            struct cygmon_thread_debug_info info;
479
            char *s=(char *)&ice_iobuf[1], *p;
480
 
481
            /* Unmarshall thread ref */
482
            my_memcpy( &thread, &ice_iobuf[2], 8 );
483
#if ICEDEBUG
484
            diag_printf("*INFO* thread=%08x,%08x\n", *(int *)&thread[0],
485
                        *(int *)(((char *)&thread[0])+4));
486
#endif
487
 
488
            ret = dbg_threadinfo( &thread, &info );
489
            if (ret) {
490
                if (info.thread_display) {
491
                    my_memcpy (s, "State: ", 7);
492
                    s += 7;
493
                    p = info.thread_display;
494
                    while (*p) {
495
                        *s++ = *p++;
496
                    }
497
                }
498
 
499
                if (info.unique_thread_name && info.unique_thread_name[0]) {
500
                    my_memcpy (s, ", Name: ", 8);
501
                    s += 8;
502
                    p = info.unique_thread_name;
503
                    while (*p) {
504
                        *s++ = *p++;
505
                    }
506
                }
507
 
508
                if (info.more_display) {
509
                    my_memcpy (s, ", ", 2);
510
                    s += 2;
511
                    p = info.more_display;
512
                    while (*p) {
513
                        *s++ = *p++;
514
                    }
515
                }
516
 
517
            }
518
            *s++ = '\0';
519
            if (ret)
520
                ice_iobuf[0] = s - (char *)&ice_iobuf[1];
521
            else
522
                ice_iobuf[0] = 0;
523
        }
524
        break;
525
    case V850ICE_SYSCALL_CONSOLE_INPUT:
526
        {
527
#ifdef CYGDBG_HAL_V85X_V850_ICE_DIAG    
528
            int len = ice_iobuf[0];
529
            int i;
530
 
531
            for (i=1; i <= len; i++) {
532
                if (false == cyg_hal_plf_diag_ice_receive_char(ice_iobuf[i]))
533
                    break;
534
            }
535
            ice_iobuf[0] = i-1;
536
#else
537
            ice_iobuf[0] = 0;
538
#endif
539
        }
540
        break;
541
    default:
542
        // set return data size to 0
543
        ice_iobuf[0] = 0;
544
        break;
545
    }
546
    hal_v85x_ice_syscall_end();
547
}
548
 
549
class Cyg_dummy_ice_syscall_init_class {
550
public:
551
    Cyg_dummy_ice_syscall_init_class() {
552
 
553
        const int valid_string = 0x45434956; // "VICE"
554
 
555
        ICE_SYSCALL_INFO_STARTPC = (int)&hal_v85x_ice_syscall;
556
        ICE_SYSCALL_INFO_ENDPC = (int)&hal_v85x_ice_syscall_end;
557
        // top of stack, less 4 ints for parameter flushback area as per ABI
558
        ICE_SYSCALL_INFO_STACK = (int)&ice_stack[ICE_STACK_SIZE-4];
559
        ICE_SYSCALL_INFO_IOBUF = (int)&ice_iobuf[0];
560
 
561
        HAL_REORDER_BARRIER();
562
 
563
        // Leave validation string to last
564
        ICE_SYSCALL_INFO_VALIDATOR = valid_string;
565
    }
566
};
567
 
568
static Cyg_dummy_ice_syscall_init_class dummy_syscall_class;
569
 
570
#endif // ifdef CYGDBG_HAL_V850_ICE
571
 
572
// EOF v850_ice.cxx

powered by: WebSVN 2.1.0

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