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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [mips/] [upd985xx/] [v2_0/] [src/] [hal_diag.c] - Blame information for rev 587

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

Line No. Rev Author Line
1 27 unneback
/*=============================================================================
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 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):   hmt, nickg
44
// Contributors:        nickg
45
// Date:        2001-05-25
46
// Purpose:     HAL diagnostic output
47
// Description: Implementations of HAL diagnostic output support.
48
//
49
//####DESCRIPTIONEND####
50
//
51
//===========================================================================*/
52
 
53
#include <pkgconf/hal.h>
54
 
55
#include <cyg/infra/cyg_type.h>         // base types
56
#include <cyg/infra/cyg_trac.h>         // tracing macros
57
#include <cyg/infra/cyg_ass.h>          // assertion macros
58
 
59
#include <cyg/hal/hal_arch.h>           // which includes var_arch => UART.
60
#include <cyg/hal/hal_diag.h>
61
#include <cyg/hal/hal_intr.h>
62
#include <cyg/hal/hal_io.h>
63
#include <cyg/hal/drv_api.h>
64
#include <cyg/hal/hal_if.h>             // interface API
65
#include <cyg/hal/hal_misc.h>           // Helper functions
66
 
67
/*---------------------------------------------------------------------------*/
68
//#define CYG_KERNEL_DIAG_GDB
69
 
70
#if defined(CYGSEM_HAL_USE_ROM_MONITOR_GDB_stubs)
71
 
72
#define CYG_KERNEL_DIAG_GDB
73
 
74
#endif
75
 
76
/*---------------------------------------------------------------------------*/
77
static inline
78
void hal_uart_setbaud( int baud )
79
{
80
    // now set the baud rate
81
    *UARTLCR |= UARTLCR_DLAB;
82
    *UARTDLM = UARTDLM_VAL( baud );
83
    *UARTDLL = UARTDLL_VAL( baud );
84
    *UARTLCR &=~UARTLCR_DLAB;
85
}
86
 
87
void hal_uart_init(void)
88
{
89
    // Ensure that we use the internal clock
90
    *S_GMR &=~S_GMR_UCSEL;
91
 
92
    *UARTFCR = UARTFCR_16550_MODE;
93
    *UARTLCR = UARTLCR_8N1;
94
    *UARTIER = UARTIER_ERBFI;           // rx interrupts enabled for CTRL-C
95
 
96
    hal_uart_setbaud( CYGHWR_HAL_MIPS_UPD985XX_DIAG_BAUD );
97
}
98
 
99
void hal_uart_write_char(char c)
100
{
101
    while ( 0 == (UARTLSR_THRE & *UARTLSR) )
102
        /* do nothing */ ;
103
 
104
    *UARTTHR = (unsigned int)c;
105
 
106
    // Ensure that this write does not provoke a spurious interrupt.
107
    HAL_INTERRUPT_ACKNOWLEDGE( CYGHWR_HAL_GDB_PORT_VECTOR );
108
}
109
 
110
void hal_uart_read_char(char *c)
111
{
112
    while ( 0 == (UARTLSR_DR & *UARTLSR) )
113
        /* do nothing */ ;
114
 
115
    *c = (char)*UARTRBR;
116
 
117
    // Ensure that this read does not provoke a spurious interrupt.
118
    HAL_INTERRUPT_ACKNOWLEDGE( CYGHWR_HAL_GDB_PORT_VECTOR );
119
}
120
 
121
int hal_uart_read_char_nonblock(char *c)
122
{
123
    if ( 0 == (UARTLSR_DR & *UARTLSR) )
124
        return 0;
125
 
126
    *c = (char)*UARTRBR;
127
 
128
    // Ensure that this read does not provoke a spurious interrupt.
129
    HAL_INTERRUPT_ACKNOWLEDGE( CYGHWR_HAL_GDB_PORT_VECTOR );
130
 
131
    return 1;
132
}
133
 
134
 
135
/*---------------------------------------------------------------------------*/
136
 
137
#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
138
 
139
#include <cyg/hal/hal_if.h>
140
 
141
// This is lame, duplicating all these wrappers with slightly different details.
142
// All this should be in hal_if.c
143
static void
144
cyg_hal_plf_serial_putc(void* __ch_data, cyg_uint8 c)
145
{
146
    CYGARC_HAL_SAVE_GP();
147
    hal_uart_write_char( (char)c );
148
    CYGARC_HAL_RESTORE_GP();
149
}
150
 
151
static cyg_uint8
152
cyg_hal_plf_serial_getc(void* __ch_data)
153
{
154
    cyg_uint8 result;
155
    CYGARC_HAL_SAVE_GP();
156
    hal_uart_read_char( (char *)&result );
157
    CYGARC_HAL_RESTORE_GP();
158
    return result;
159
}
160
 
161
static int
162
cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8 *pc)
163
{
164
    return hal_uart_read_char_nonblock( (char *)pc );
165
}
166
 
167
static void
168
cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf,
169
                         cyg_uint32 __len)
170
{
171
    CYGARC_HAL_SAVE_GP();
172
 
173
    while(__len-- > 0)
174
        cyg_hal_plf_serial_putc(__ch_data, *__buf++);
175
 
176
    CYGARC_HAL_RESTORE_GP();
177
}
178
 
179
static void
180
cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
181
{
182
    CYGARC_HAL_SAVE_GP();
183
 
184
    while(__len-- > 0)
185
        *__buf++ = cyg_hal_plf_serial_getc(__ch_data);
186
 
187
    CYGARC_HAL_RESTORE_GP();
188
}
189
 
190
static int chan__msec_timeout = 0;
191
static int chan__irq_state = 0;
192
static int chan__baud_rate = CYGHWR_HAL_MIPS_UPD985XX_DIAG_BAUD;
193
 
194
cyg_bool
195
cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch)
196
{
197
    int delay_count;
198
    cyg_bool res;
199
    CYGARC_HAL_SAVE_GP();
200
 
201
    delay_count = chan__msec_timeout * 10; // delay in .1 ms steps
202
 
203
    for(;;) {
204
        res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch);
205
        if (res || 0 >= delay_count--)
206
            break;
207
 
208
        CYGACC_CALL_IF_DELAY_US(100);
209
    }
210
 
211
    CYGARC_HAL_RESTORE_GP();
212
    return res;
213
}
214
 
215
static int
216
cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...)
217
{
218
    int ret = -1;
219
    va_list ap;
220
 
221
    CYGARC_HAL_SAVE_GP();
222
    va_start(ap, __func);
223
 
224
    switch (__func) {
225
    case __COMMCTL_GETBAUD:
226
        ret = chan__baud_rate;
227
        break;
228
    case __COMMCTL_SETBAUD:
229
        ret = 0;
230
        chan__baud_rate = va_arg(ap, cyg_int32);
231
        hal_uart_setbaud( chan__baud_rate );
232
        break;
233
    case __COMMCTL_IRQ_ENABLE:
234
        ret = chan__irq_state;
235
        chan__irq_state = 1;
236
        HAL_INTERRUPT_UNMASK( CYGHWR_HAL_GDB_PORT_VECTOR );
237
        break;
238
    case __COMMCTL_IRQ_DISABLE:
239
        ret = chan__irq_state;
240
        chan__irq_state = 0;
241
        HAL_INTERRUPT_MASK( CYGHWR_HAL_GDB_PORT_VECTOR );
242
        break;
243
    case __COMMCTL_DBG_ISR_VECTOR:
244
        ret = CYGHWR_HAL_GDB_PORT_VECTOR;
245
        break;
246
    case __COMMCTL_SET_TIMEOUT:
247
        ret = chan__msec_timeout;
248
        chan__msec_timeout = va_arg(ap, cyg_uint32);
249
        break;
250
    default:
251
        break;
252
    }
253
    va_end(ap);
254
    CYGARC_HAL_RESTORE_GP();
255
    return ret;
256
}
257
 
258
static int
259
cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc,
260
                       CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
261
{
262
    int ret = 0;
263
    char c;
264
 
265
    *__ctrlc = 0;
266
 
267
    if ( hal_uart_read_char_nonblock( &c ) ) {
268
        if ( cyg_hal_is_break( &c , 1 ) )
269
            *__ctrlc = 1;
270
        ret = CYG_ISR_HANDLED;
271
    }
272
 
273
    return ret;
274
}
275
 
276
static void
277
cyg_hal_plf_serial_init(void)
278
{
279
    hal_virtual_comm_table_t* comm;
280
    int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
281
 
282
    // Init channels
283
    CYGACC_CALL_IF_SET_CONSOLE_COMM(0);
284
    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
285
    CYGACC_COMM_IF_CH_DATA_SET(*comm, comm);
286
    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
287
    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
288
    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
289
    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
290
    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
291
    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
292
    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
293
 
294
    // Restore original console
295
    CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
296
}
297
 
298
void
299
cyg_hal_plf_comms_init(void)
300
{
301
    static int initialized = 0;
302
 
303
    if (initialized)
304
        return;
305
 
306
    initialized = 1;
307
 
308
    hal_uart_init();
309
    cyg_hal_plf_serial_init();
310
}
311
 
312
#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
313
 
314
// ------------------------------------------------------------------------
315
 
316
void hal_diag_init(void)
317
{
318
    hal_uart_init();
319
}
320
 
321
void hal_diag_read_char(char *c)
322
{
323
    hal_uart_read_char(c);
324
}
325
 
326
extern cyg_bool cyg_hal_is_break(char *buf, int size);
327
extern void cyg_hal_user_break(CYG_ADDRWORD *regs);
328
 
329
void hal_diag_write_char(char c)
330
{
331
#ifdef CYG_KERNEL_DIAG_GDB    
332
    static char line[100];
333
    static int pos = 0;
334
 
335
    // No need to send CRs
336
    if( c == '\r' ) return;
337
 
338
    line[pos++] = c;
339
 
340
    if( c == '\n' || pos == sizeof(line) )
341
    {
342
 
343
        // Disable interrupts. This prevents GDB trying to interrupt us
344
        // while we are in the middle of sending a packet. The serial
345
        // receive interrupt will be seen when we re-enable interrupts
346
        // later.
347
        CYG_INTERRUPT_STATE oldstate;
348
        HAL_DISABLE_INTERRUPTS(oldstate);
349
 
350
        while(1)
351
        {
352
            static char hex[] = "0123456789ABCDEF";
353
            cyg_uint8 csum = 0;
354
            int i;
355
            char c1;
356
 
357
            hal_uart_write_char('$');
358
            hal_uart_write_char('O');
359
            csum += 'O';
360
            for( i = 0; i < pos; i++ )
361
            {
362
                char ch = line[i];
363
                char h = hex[(ch>>4)&0xF];
364
                char l = hex[ch&0xF];
365
                hal_uart_write_char(h);
366
                hal_uart_write_char(l);
367
                csum += h;
368
                csum += l;
369
            }
370
            hal_uart_write_char('#');
371
            hal_uart_write_char(hex[(csum>>4)&0xF]);
372
            hal_uart_write_char(hex[csum&0xF]);
373
 
374
            hal_uart_read_char( &c1 );
375
 
376
            if( c1 == '+' ) break;
377
 
378
            if( cyg_hal_is_break( &c1 , 1 ) )
379
                cyg_hal_user_break( NULL );
380
 
381
        }
382
 
383
        pos = 0;
384
 
385
        // Disabling the interrupts for an extended period of time
386
        // can provoke a spurious interrupt.
387
 
388
        // Ensure that this write does not provoke a spurious interrupt.
389
        HAL_INTERRUPT_ACKNOWLEDGE( CYGHWR_HAL_GDB_PORT_VECTOR );
390
 
391
        // And re-enable interrupts
392
        HAL_RESTORE_INTERRUPTS( oldstate );
393
 
394
    }
395
#else
396
    hal_uart_write_char(c);
397
#endif    
398
}
399
 
400
/*---------------------------------------------------------------------------*/
401
/* End of hal_diag.c */

powered by: WebSVN 2.1.0

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