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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [hal/] [arm/] [ebsa285/] [current/] [src/] [hal_diag.c] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
/*=============================================================================
2
//
3
//      hal_diag.c
4
//
5
//      HAL diagnostic output code
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):   nickg, gthomas
43
// Contributors:nickg, gthomas
44
// Date:        1998-03-02
45
// Purpose:     HAL diagnostic output
46
// Description: Implementations of HAL diagnostic output support.
47
//
48
//####DESCRIPTIONEND####
49
//
50
//===========================================================================*/
51
 
52
#include <pkgconf/hal.h>
53
#include <pkgconf/system.h>
54
#include CYGBLD_HAL_PLATFORM_H
55
 
56
#include <cyg/infra/cyg_type.h>         // base types
57
#include <cyg/infra/cyg_trac.h>         // tracing macros
58
#include <cyg/infra/cyg_ass.h>          // assertion macros
59
 
60
#include <cyg/hal/hal_arch.h>           // basic machine info
61
#include <cyg/hal/hal_intr.h>           // interrupt macros
62
#include <cyg/hal/hal_io.h>             // IO macros
63
#include <cyg/hal/hal_if.h>             // calling interface API
64
#include <cyg/hal/hal_misc.h>           // helper functions
65
#include <cyg/hal/hal_diag.h>
66
#include <cyg/hal/hal_ebsa285.h>        // Hardware definitions
67
#include <cyg/hal/drv_api.h>            // cyg_drv_interrupt_acknowledge
68
 
69
/*---------------------------------------------------------------------------*/
70
 
71
struct ebsa_serial {
72
  volatile cyg_uint32 data_register;
73
  volatile cyg_uint32 rxstat;
74
  volatile cyg_uint32 h_baud_control;
75
  volatile cyg_uint32 m_baud_control;
76
  volatile cyg_uint32 l_baud_control;
77
  volatile cyg_uint32 control_register;
78
  volatile cyg_uint32 flag_register;
79
};
80
 
81
/*---------------------------------------------------------------------------*/
82
 
83
static void
84
init_channel(void* __ch_data)
85
{
86
    volatile struct ebsa_serial* base = (struct ebsa_serial*)__ch_data;
87
 
88
    int dummy;
89
    /*
90
     * Make sure everything is off
91
     */
92
    base->control_register = SA110_UART_DISABLED | SA110_SIR_DISABLED;
93
 
94
    /*
95
     * Read the RXStat to drain the fifo
96
     */
97
    dummy = base->rxstat;
98
 
99
    /*
100
     * Set the baud rate - this also turns the uart on.
101
     *
102
     * Note that the ordering of these writes is critical,
103
     * and the writes to the H_BAUD_CONTROL and CONTROL_REGISTER
104
     * are necessary to force the UART to update its register
105
     * contents.
106
     */
107
    base->l_baud_control   = 0x13; // bp->divisor_low;
108
    base->m_baud_control   = 0x00; // bp->divisor_high;
109
    base->h_baud_control = SA110_UART_BREAK_DISABLED    |
110
        SA110_UART_PARITY_DISABLED   |
111
        SA110_UART_STOP_BITS_ONE     |
112
        SA110_UART_FIFO_ENABLED      |
113
        SA110_UART_DATA_LENGTH_8_BITS;
114
    base->control_register = SA110_UART_ENABLED | SA110_SIR_DISABLED;
115
    // All done
116
}
117
 
118
void
119
cyg_hal_plf_serial_putc(void *__ch_data, char c)
120
{
121
    volatile struct ebsa_serial* base = (struct ebsa_serial*)__ch_data;
122
    CYGARC_HAL_SAVE_GP();
123
 
124
    // Wait for Tx FIFO not full
125
    while ((base->flag_register & SA110_TX_FIFO_STATUS_MASK) == SA110_TX_FIFO_BUSY)
126
        ;
127
    base->data_register = c;
128
 
129
    CYGARC_HAL_RESTORE_GP();
130
}
131
 
132
 
133
static cyg_bool
134
cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch)
135
{
136
    volatile struct ebsa_serial* base = (struct ebsa_serial*)__ch_data;
137
 
138
 
139
    if ((base->flag_register & SA110_RX_FIFO_STATUS_MASK) == SA110_RX_FIFO_EMPTY)
140
        return false;
141
 
142
    *ch = (char)(base->data_register & 0xFF);
143
 
144
    return true;
145
}
146
 
147
 
148
cyg_uint8
149
cyg_hal_plf_serial_getc(void* __ch_data)
150
{
151
    cyg_uint8 ch;
152
    CYGARC_HAL_SAVE_GP();
153
 
154
    while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch));
155
 
156
    CYGARC_HAL_RESTORE_GP();
157
    return ch;
158
}
159
 
160
static cyg_int32 msec_timeout;
161
 
162
static void
163
cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf,
164
                         cyg_uint32 __len)
165
{
166
    CYGARC_HAL_SAVE_GP();
167
 
168
    while(__len-- > 0)
169
        cyg_hal_plf_serial_putc(__ch_data, *__buf++);
170
 
171
    CYGARC_HAL_RESTORE_GP();
172
}
173
 
174
static void
175
cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
176
{
177
    CYGARC_HAL_SAVE_GP();
178
 
179
    while(__len-- > 0)
180
        *__buf++ = cyg_hal_plf_serial_getc(__ch_data);
181
 
182
    CYGARC_HAL_RESTORE_GP();
183
}
184
 
185
cyg_bool
186
cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch)
187
{
188
    int delay_count;
189
    cyg_bool res;
190
    CYGARC_HAL_SAVE_GP();
191
 
192
    delay_count = msec_timeout * 10; // delay in .1 ms steps
193
 
194
    for(;;) {
195
        res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch);
196
        if (res || 0 == delay_count--)
197
            break;
198
 
199
        CYGACC_CALL_IF_DELAY_US(100);
200
    }
201
 
202
    CYGARC_HAL_RESTORE_GP();
203
    return res;
204
}
205
 
206
static int
207
cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...)
208
{
209
    static int irq_state = 0;
210
    int ret = 0;
211
    CYGARC_HAL_SAVE_GP();
212
 
213
    switch (__func) {
214
    case __COMMCTL_IRQ_ENABLE:
215
        irq_state = 1;
216
 
217
        HAL_INTERRUPT_UNMASK(CYGNUM_HAL_INTERRUPT_SERIAL_RX);
218
        break;
219
    case __COMMCTL_IRQ_DISABLE:
220
        ret = irq_state;
221
        irq_state = 0;
222
 
223
        HAL_INTERRUPT_MASK(CYGNUM_HAL_INTERRUPT_SERIAL_RX);
224
        break;
225
    case __COMMCTL_DBG_ISR_VECTOR:
226
        ret = CYGNUM_HAL_INTERRUPT_SERIAL_RX;
227
        break;
228
    case __COMMCTL_SET_TIMEOUT:
229
    {
230
        va_list ap;
231
 
232
        va_start(ap, __func);
233
 
234
        ret = msec_timeout;
235
        msec_timeout = va_arg(ap, cyg_uint32);
236
 
237
        va_end(ap);
238
    }
239
    default:
240
        break;
241
    }
242
    CYGARC_HAL_RESTORE_GP();
243
    return ret;
244
}
245
 
246
static int
247
cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc,
248
                       CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
249
{
250
    int reg, res = 0;
251
    volatile struct ebsa_serial* base = (struct ebsa_serial*)__ch_data;
252
    char c;
253
    CYGARC_HAL_SAVE_GP();
254
 
255
    if ( CYGNUM_HAL_INTERRUPT_SERIAL_RX == __vector ) {
256
        reg = base->flag_register;
257
        // read it anyway just in case - no harm done and we might
258
        // prevent an interrup loop
259
        c = (char)(base->data_register & 0xFF);
260
 
261
        cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_SERIAL_RX);
262
        *__ctrlc = 0;
263
        if ( (reg & SA110_RX_FIFO_STATUS_MASK) != SA110_RX_FIFO_EMPTY ) {
264
            if( cyg_hal_is_break( &c , 1 ) )
265
                *__ctrlc = 1;
266
 
267
        }
268
        res = CYG_ISR_HANDLED;
269
    }
270
 
271
    CYGARC_HAL_RESTORE_GP();
272
    return res;
273
}
274
 
275
static void
276
cyg_hal_plf_serial_init(void)
277
{
278
    hal_virtual_comm_table_t* comm;
279
    int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
280
 
281
    // Init channels
282
    init_channel((void*)UART_BASE_0);
283
 
284
    // Setup procs in the vector table
285
 
286
    // Set channel 0
287
    CYGACC_CALL_IF_SET_CONSOLE_COMM(0);
288
    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
289
    CYGACC_COMM_IF_CH_DATA_SET(*comm, UART_BASE_0);
290
    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
291
    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
292
    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
293
    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
294
    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
295
    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
296
    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
297
 
298
    // Restore original console
299
    CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
300
}
301
 
302
void
303
cyg_hal_plf_comms_init(void)
304
{
305
    static int initialized = 0;
306
 
307
    if (initialized)
308
        return;
309
 
310
    initialized = 1;
311
 
312
    cyg_hal_plf_serial_init();
313
}
314
 
315
 
316
//=============================================================================
317
// Compatibility with older stubs
318
//=============================================================================
319
 
320
#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
321
 
322
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
323
#include <cyg/hal/hal_stub.h>           // cyg_hal_gdb_interrupt
324
#endif
325
 
326
#ifdef CYGSEM_HAL_ROM_MONITOR
327
#define CYG_HAL_STARTUP_ROM
328
#undef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
329
#endif
330
 
331
#if defined(CYG_HAL_STARTUP_ROM) || !defined(CYGDBG_HAL_DIAG_TO_DEBUG_CHAN)
332
#define HAL_DIAG_USES_HARDWARE
333
#endif
334
 
335
/*---------------------------------------------------------------------------*/
336
// EBSA285 Serial Port (UARTx) for Debug
337
 
338
void hal_diag_init(void)
339
{
340
  init_channel((void*)UART_BASE_0);
341
}
342
 
343
 
344
// Actually send character down the wire
345
static void
346
hal_diag_write_char_serial(char c)
347
{
348
    cyg_hal_plf_serial_putc((void*)UART_BASE_0, c);
349
}
350
 
351
static bool
352
hal_diag_read_serial(char *c)
353
{
354
    long timeout = 1000000000;  // A long time...
355
    while (! cyg_hal_plf_serial_getc_nonblock((void*)UART_BASE_0, c) )
356
        if ( --timeout == 0 ) return false;
357
 
358
    return true;
359
}
360
 
361
/*
362
 * Baud rate selection stuff
363
 */
364
#if 0
365
struct _baud {
366
    int baud;
367
    unsigned short divisor_high, divisor_low;
368
};
369
 
370
const static struct _baud bauds[] = {
371
#if (FCLK_MHZ == 50)
372
    {   300, 0xA, 0x2B},                  /* 2603  = 0x0A2B */
373
    {   600, 0x5, 0x15},                  /* 1301  = 0x0515 */
374
    {  1200, 0x2, 0x8A},                  /* 650   = 0x028A */
375
    {  2400, 0x1, 0x45},                  /* 325   = 0x0145 */
376
    {  4800, 0x0, 0xA2},                  /* 162   = 0x00A2 */
377
    {  9600, 0x0, 0x50},                  /* 80    = 0x0050 */
378
    { 19200, 0x0, 0x28},                  /* 40    = 0x0028 */
379
    { 38400, 0x0, 0x13},                  /* 19    = 0x0013 */
380
#elif (FCLK_MHZ == 60)
381
    {   300, 0xC, 0x34},                  /* 2603  = 0x0A2B */
382
    {   600, 0x6, 0x19},                  /* 1301  = 0x0515 */
383
    {  1200, 0x3, 0x0C},                  /* 650   = 0x028A */
384
    {  2400, 0x1, 0x86},                  /* 325   = 0x0145 */
385
    {  4800, 0x0, 0xC2},                  /* 162   = 0x00A2 */
386
    {  9600, 0x0, 0x61},                  /* 80    = 0x0050 */
387
    { 19200, 0x0, 0x30},                  /* 40    = 0x0028 */
388
    { 38400, 0x0, 0x17},                  /* 19    = 0x0013 */
389
#endif
390
};
391
#endif
392
 
393
#ifdef HAL_DIAG_USES_HARDWARE
394
 
395
#ifdef DEBUG_DIAG
396
#ifndef CYG_HAL_STARTUP_ROM
397
#define DIAG_BUFSIZE 2048
398
static char diag_buffer[DIAG_BUFSIZE];
399
static int diag_bp = 0;
400
#endif
401
#endif
402
 
403
void hal_diag_read_char(char *c)
404
{
405
    while (!hal_diag_read_serial(c)) ;
406
}
407
 
408
void hal_diag_write_char(char c)
409
{
410
#ifdef DEBUG_DIAG
411
#ifndef CYG_HAL_STARTUP_ROM
412
    diag_buffer[diag_bp++] = c;
413
    if (diag_bp == sizeof(diag_buffer)) diag_bp = 0;
414
#endif
415
#endif
416
    hal_diag_write_char_serial(c);
417
}
418
 
419
#else // not HAL_DIAG_USES_HARDWARE - it uses GDB protocol
420
 
421
void
422
hal_diag_read_char(char *c)
423
{
424
    while (!hal_diag_read_serial(c)) ;
425
}
426
 
427
void
428
hal_diag_write_char(char c)
429
{
430
    static char line[100];
431
    static int pos = 0;
432
 
433
#if 0
434
    // Do not unconditionally poke the XBUS LED location - XBUS may not be
435
    // available if external arbiter is in use.  This fragment may still be
436
    // useful for debugging in the future, so left thus:
437
    {
438
//        int i;
439
        *(cyg_uint32 *)0x40012000 = 7 & (cyg_uint32)c; // LED XBUS location
440
//        for ( i = 0x1000000; i > 0; i-- ) ;
441
    }
442
#endif
443
 
444
    // No need to send CRs
445
    if( c == '\r' ) return;
446
 
447
    line[pos++] = c;
448
 
449
    if( c == '\n' || pos == sizeof(line) )
450
    {
451
 
452
        CYG_INTERRUPT_STATE old;
453
 
454
        // Disable interrupts. This prevents GDB trying to interrupt us
455
        // while we are in the middle of sending a packet. The serial
456
        // receive interrupt will be seen when we re-enable interrupts
457
        // later.
458
 
459
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
460
        CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION(old);
461
#else
462
        HAL_DISABLE_INTERRUPTS(old);
463
#endif
464
 
465
        while(1)
466
        {
467
            static char hex[] = "0123456789ABCDEF";
468
            cyg_uint8 csum = 0;
469
            int i;
470
#ifndef CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT
471
            char c1;
472
#endif        
473
            hal_diag_write_char_serial('$');
474
            hal_diag_write_char_serial('O');
475
            csum += 'O';
476
            for( i = 0; i < pos; i++ )
477
            {
478
                char ch = line[i];
479
                char h = hex[(ch>>4)&0xF];
480
                char l = hex[ch&0xF];
481
                hal_diag_write_char_serial(h);
482
                hal_diag_write_char_serial(l);
483
                csum += h;
484
                csum += l;
485
            }
486
            hal_diag_write_char_serial('#');
487
            hal_diag_write_char_serial(hex[(csum>>4)&0xF]);
488
            hal_diag_write_char_serial(hex[csum&0xF]);
489
 
490
#ifdef CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT
491
 
492
            break; // regardless
493
 
494
#else // not CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT Ie. usually...
495
 
496
            // Wait for the ACK character '+' from GDB here and handle
497
            // receiving a ^C instead.  This is the reason for this clause
498
            // being a loop.
499
            if (!hal_diag_read_serial(&c1))
500
                continue;   // No response - try sending packet again
501
 
502
            if( c1 == '+' )
503
                break;              // a good acknowledge
504
 
505
#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
506
            cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_SERIAL_RX);
507
            if( c1 == 3 ) {
508
                // Ctrl-C: breakpoint.
509
                cyg_hal_gdb_interrupt(
510
                    (target_register_t)__builtin_return_address(0) );
511
                break;
512
            }
513
#endif // CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
514
 
515
#endif // ! CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT
516
            // otherwise, loop round again
517
        }
518
 
519
        pos = 0;
520
 
521
 
522
        // And re-enable interrupts
523
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
524
        CYG_HAL_GDB_LEAVE_CRITICAL_IO_REGION(old);
525
#else
526
        HAL_RESTORE_INTERRUPTS(old);
527
#endif
528
 
529
    }
530
}
531
#endif
532
 
533
#endif // !CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
534
 
535
/*---------------------------------------------------------------------------*/
536
/* End of hal_diag.c */

powered by: WebSVN 2.1.0

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