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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [v85x/] [v850/] [v2_0/] [src/] [v850_ice.cxx] - Blame information for rev 174

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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