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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [gdb-5.3/] [gdb/] [rdi-share/] [devsw.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1181 sfurman
/*
2
 * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
3
 *
4
 * This software may be freely used, copied, modified, and distributed
5
 * provided that the above copyright notice is preserved in all copies of the
6
 * software.
7
 */
8
 
9
/* -*-C-*-
10
 *
11 1183 sfurman
 * $Revision: 1.2 $
12
 *     $Date: 2003-08-15 01:06:10 $
13 1181 sfurman
 *
14
 */
15
#include <stdio.h>
16
#include <stdlib.h>
17
#include <string.h>
18
#include <fcntl.h>
19
#include <time.h>
20
 
21
#include "adp.h"
22
#include "sys.h"
23
#include "hsys.h"
24
#include "rxtx.h"
25
#include "drivers.h"
26
#include "buffers.h"
27
#include "devclnt.h"
28
#include "adperr.h"
29
#include "devsw.h"
30
#include "hostchan.h"
31
#include "logging.h"
32
 
33
static char *angelDebugFilename = NULL;
34
static FILE *angelDebugLogFile = NULL;
35
static int angelDebugLogEnable = 0;
36
 
37
static void openLogFile ()
38
{
39
  time_t t;
40
 
41
  if (angelDebugFilename == NULL || *angelDebugFilename =='\0')
42
    return;
43
 
44
  angelDebugLogFile = fopen (angelDebugFilename,"a");
45
 
46
  if (!angelDebugLogFile)
47
    {
48
      fprintf (stderr,"Error opening log file '%s'\n",angelDebugFilename);
49
      perror ("fopen");
50
    }
51
  else
52
    {
53
      /* The following line is equivalent to: */
54
      /* setlinebuf (angelDebugLogFile); */
55
      setvbuf(angelDebugLogFile, (char *)NULL, _IOLBF, 0);
56
#if defined(__CYGWIN__)
57
      setmode(fileno(angelDebugLogFile), O_TEXT);
58
#endif
59
    }
60
 
61
  time (&t);
62
  fprintf (angelDebugLogFile,"ADP log file opened at %s\n",asctime(localtime(&t)));
63
}
64
 
65
 
66
static void closeLogFile (void)
67
{
68
  time_t t;
69
 
70
  if (!angelDebugLogFile)
71
    return;
72
 
73
  time (&t);
74
  fprintf (angelDebugLogFile,"ADP log file closed at %s\n",asctime(localtime(&t)));
75
 
76
  fclose (angelDebugLogFile);
77
  angelDebugLogFile = NULL;
78
}
79
 
80
void DevSW_SetLogEnable (int logEnableFlag)
81
{
82
  if (logEnableFlag && !angelDebugLogFile)
83
    openLogFile ();
84
  else if (!logEnableFlag && angelDebugLogFile)
85
    closeLogFile ();
86
 
87
  angelDebugLogEnable = logEnableFlag;
88
}
89
 
90
 
91
void DevSW_SetLogfile (const char *filename)
92
{
93
  closeLogFile ();
94
 
95
  if (angelDebugFilename)
96
    {
97
      free (angelDebugFilename);
98
      angelDebugFilename = NULL;
99
    }
100
 
101
  if (filename && *filename)
102
    {
103
      angelDebugFilename = strdup (filename);
104
      if (angelDebugLogEnable)
105
        openLogFile ();
106
    }
107
}
108
 
109
 
110
#define WordAt(p)  ((unsigned long) ((p)[0] | ((p)[1]<<8) | ((p)[2]<<16) | ((p)[3]<<24)))
111
 
112
static void dumpPacket(FILE *fp, char *label, struct data_packet *p)
113
{
114
  unsigned r;
115
  int i;
116
  unsigned char channel;
117
 
118
  if (!fp)
119
    return;
120
 
121
  fprintf(fp,"%s [T=%d L=%d] ",label,p->type,p->len);
122
  for (i=0; i<p->len; ++i)
123
    fprintf(fp,"%02x ",p->data[i]);
124
  fprintf(fp,"\n");
125
 
126
  channel = p->data[0];
127
 
128
  r = WordAt(p->data+4);
129
 
130
  fprintf(fp,"R=%08x ",r);
131
  fprintf(fp,"%s ", r&0x80000000 ? "H<-T" : "H->T");
132
 
133
  switch (channel)
134
    {
135
     case CI_PRIVATE: fprintf(fp,"CI_PRIVATE: "); break;
136
     case CI_HADP: fprintf(fp,"CI_HADP: "); break;
137
     case CI_TADP: fprintf(fp,"CI_TADP: "); break;
138
     case CI_HBOOT: fprintf(fp,"CI_HBOOT: "); break;
139
     case CI_TBOOT: fprintf(fp,"CI_TBOOT: "); break;
140
     case CI_CLIB: fprintf(fp,"CI_CLIB: "); break;
141
     case CI_HUDBG: fprintf(fp,"CI_HUDBG: "); break;
142
     case CI_TUDBG: fprintf(fp,"CI_TUDBG: "); break;
143
     case CI_HTDCC: fprintf(fp,"CI_HTDCC: "); break;
144
     case CI_TTDCC: fprintf(fp,"CI_TTDCC: "); break;
145
     case CI_TLOG: fprintf(fp,"CI_TLOG: "); break;
146
     default:      fprintf(fp,"BadChan: "); break;
147
    }
148
 
149
  switch (r & 0xffffff)
150
    {
151
     case ADP_Booted: fprintf(fp," ADP_Booted "); break;
152
#if defined(ADP_TargetResetIndication)
153
     case ADP_TargetResetIndication: fprintf(fp," ADP_TargetResetIndication "); break;
154
#endif
155
     case ADP_Reboot: fprintf(fp," ADP_Reboot "); break;
156
     case ADP_Reset: fprintf(fp," ADP_Reset "); break;
157
#if defined(ADP_HostResetIndication)
158
     case ADP_HostResetIndication: fprintf(fp," ADP_HostResetIndication "); break;
159
#endif      
160
     case ADP_ParamNegotiate: fprintf(fp," ADP_ParamNegotiate "); break;
161
     case ADP_LinkCheck: fprintf(fp," ADP_LinkCheck "); break;
162
     case ADP_HADPUnrecognised: fprintf(fp," ADP_HADPUnrecognised "); break;
163
     case ADP_Info: fprintf(fp," ADP_Info "); break;
164
     case ADP_Control: fprintf(fp," ADP_Control "); break;
165
     case ADP_Read: fprintf(fp," ADP_Read "); break;
166
     case ADP_Write: fprintf(fp," ADP_Write "); break;
167
     case ADP_CPUread: fprintf(fp," ADP_CPUread "); break;
168
     case ADP_CPUwrite: fprintf(fp," ADP_CPUwrite "); break;
169
     case ADP_CPread: fprintf(fp," ADP_CPread "); break;
170
     case ADP_CPwrite: fprintf(fp," ADP_CPwrite "); break;
171
     case ADP_SetBreak: fprintf(fp," ADP_SetBreak "); break;
172
     case ADP_ClearBreak: fprintf(fp," ADP_ClearBreak "); break;
173
     case ADP_SetWatch: fprintf(fp," ADP_SetWatch "); break;
174
     case ADP_ClearWatch: fprintf(fp," ADP_ClearWatch "); break;
175
     case ADP_Execute: fprintf(fp," ADP_Execute "); break;
176
     case ADP_Step: fprintf(fp," ADP_Step "); break;
177
     case ADP_InterruptRequest: fprintf(fp," ADP_InterruptRequest "); break;
178
     case ADP_HW_Emulation: fprintf(fp," ADP_HW_Emulation "); break;
179
     case ADP_ICEbreakerHADP: fprintf(fp," ADP_ICEbreakerHADP "); break;
180
     case ADP_ICEman: fprintf(fp," ADP_ICEman "); break;
181
     case ADP_Profile: fprintf(fp," ADP_Profile "); break;
182
     case ADP_InitialiseApplication: fprintf(fp," ADP_InitialiseApplication "); break;
183
     case ADP_End: fprintf(fp," ADP_End "); break;
184
     case ADP_TADPUnrecognised: fprintf(fp," ADP_TADPUnrecognised "); break;
185
     case ADP_Stopped: fprintf(fp," ADP_Stopped "); break;
186
     case ADP_TDCC_ToHost: fprintf(fp," ADP_TDCC_ToHost "); break;
187
     case ADP_TDCC_FromHost: fprintf(fp," ADP_TDCC_FromHost "); break;
188
 
189
     case CL_Unrecognised: fprintf(fp," CL_Unrecognised "); break;
190
     case CL_WriteC: fprintf(fp," CL_WriteC "); break;
191
     case CL_Write0: fprintf(fp," CL_Write0 "); break;
192
     case CL_ReadC: fprintf(fp," CL_ReadC "); break;
193
     case CL_System: fprintf(fp," CL_System "); break;
194
     case CL_GetCmdLine: fprintf(fp," CL_GetCmdLine "); break;
195
     case CL_Clock: fprintf(fp," CL_Clock "); break;
196
     case CL_Time: fprintf(fp," CL_Time "); break;
197
     case CL_Remove: fprintf(fp," CL_Remove "); break;
198
     case CL_Rename: fprintf(fp," CL_Rename "); break;
199
     case CL_Open: fprintf(fp," CL_Open "); break;
200
     case CL_Close: fprintf(fp," CL_Close "); break;
201
     case CL_Write: fprintf(fp," CL_Write "); break;
202
     case CL_WriteX: fprintf(fp," CL_WriteX "); break;
203
     case CL_Read: fprintf(fp," CL_Read "); break;
204
     case CL_ReadX: fprintf(fp," CL_ReadX "); break;
205
     case CL_Seek: fprintf(fp," CL_Seek "); break;
206
     case CL_Flen: fprintf(fp," CL_Flen "); break;
207
     case CL_IsTTY: fprintf(fp," CL_IsTTY "); break;
208
     case CL_TmpNam: fprintf(fp," CL_TmpNam "); break;
209
 
210
     default: fprintf(fp," BadReason "); break;
211
    }
212
 
213
  i = 20;
214
 
215
  if (((r & 0xffffff) == ADP_CPUread ||
216
       (r & 0xffffff) == ADP_CPUwrite) && (r&0x80000000)==0)
217
    {
218
      fprintf(fp,"%02x ", p->data[i]);
219
      ++i;
220
    }
221
 
222
  for (; i<p->len; i+=4)
223
    fprintf(fp,"%08x ",WordAt(p->data+i));
224
 
225
  fprintf(fp,"\n");
226
}
227
 
228
 
229
/*
230
 * TODO: this should be adjustable - it could be done by defining
231
 *       a reason code for DevSW_Ioctl.  It could even be a
232
 *       per-devicechannel parameter.
233
 */
234
static const unsigned int allocsize = ADP_BUFFER_MIN_SIZE;
235
 
236
#define illegalDevChanID(type)  ((type) >= DC_NUM_CHANNELS)
237
 
238
/**********************************************************************/
239
 
240
/*
241
 *  Function: initialise_read
242
 *   Purpose: Set up a read request for another packet
243
 *
244
 *    Params:
245
 *      In/Out: ds      State structure to be initialised
246
 *
247
 *   Returns:
248
 *          OK: 0
249
 *       Error: -1
250
 */
251
static int initialise_read(DevSWState *ds)
252
{
253
    struct data_packet *dp;
254
 
255
    /*
256
     * try to claim the structure that will
257
     * eventually hold the new packet.
258
     */
259
    if ((ds->ds_nextreadpacket = DevSW_AllocatePacket(allocsize)) == NULL)
260
        return -1;
261
 
262
    /*
263
     * Calls into the device driver use the DriverCall structure: use
264
     * the buffer we have just allocated, and declare its size.  We
265
     * are also obliged to clear the driver's context pointer.
266
     */
267
    dp = &ds->ds_activeread.dc_packet;
268
    dp->buf_len = allocsize;
269
    dp->data = ds->ds_nextreadpacket->pk_buffer;
270
 
271
    ds->ds_activeread.dc_context = NULL;
272
 
273
    return 0;
274
}
275
 
276
/*
277
 *  Function: initialise_write
278
 *   Purpose: Set up a write request for another packet
279
 *
280
 *    Params:
281
 *       Input: packet  The packet to be written
282
 *
283
 *              type    The type of the packet
284
 *
285
 *      In/Out: dc      The structure to be intialised
286
 *
287
 *   Returns: Nothing
288
 */
289
static void initialise_write(DriverCall *dc, Packet *packet, DevChanID type)
290
{
291
    struct data_packet *dp = &dc->dc_packet;
292
 
293
    dp->len = packet->pk_length;
294
    dp->data = packet->pk_buffer;
295
    dp->type = type;
296
 
297
    /*
298
     * we are required to clear the state structure for the driver
299
     */
300
    dc->dc_context = NULL;
301
}
302
 
303
/*
304
 *  Function: enqueue_packet
305
 *   Purpose: move a newly read packet onto the appropriate queue
306
 *              of read packets
307
 *
308
 *    Params:
309
 *      In/Out: ds      State structure with new packet
310
 *
311
 *   Returns: Nothing
312
 */
313
static void enqueue_packet(DevSWState *ds)
314
{
315
    struct data_packet *dp = &ds->ds_activeread.dc_packet;
316
    Packet *packet = ds->ds_nextreadpacket;
317
 
318
    /*
319
     * transfer the length
320
     */
321
    packet->pk_length = dp->len;
322
 
323
    /*
324
     * take this packet out of the incoming slot
325
     */
326
    ds->ds_nextreadpacket = NULL;
327
 
328
    /*
329
     * try to put it on the correct input queue
330
     */
331
    if (illegalDevChanID(dp->type))
332
    {
333
        /* this shouldn't happen */
334
        WARN("Illegal type for Rx packet");
335
        DevSW_FreePacket(packet);
336
    }
337
    else
338
        Adp_addToQueue(&ds->ds_readqueue[dp->type], packet);
339
}
340
 
341
/*
342
 *  Function: flush_packet
343
 *   Purpose: Send a packet to the device driver
344
 *
345
 *    Params:
346
 *       Input: device  The device to be written to
347
 *
348
 *      In/Out: dc      Describes the packet to be sent
349
 *
350
 *   Returns: Nothing
351
 *
352
 * Post-conditions: If the whole packet was accepted by the device
353
 *                      driver, then dc->dc_packet.data will be
354
 *                      set to NULL.
355
 */
356
static void flush_packet(const DeviceDescr *device, DriverCall *dc)
357
{
358
    if (device->DeviceWrite(dc) > 0)
359
        /*
360
         * the whole packet was swallowed
361
         */
362
        dc->dc_packet.data = NULL;
363
}
364
 
365
/**********************************************************************/
366
 
367
/*
368
 * These are the externally visible functions.  They are documented in
369
 * devsw.h
370
 */
371
Packet *DevSW_AllocatePacket(const unsigned int length)
372
{
373
    Packet *pk;
374
 
375
    if ((pk = malloc(sizeof(*pk))) == NULL)
376
    {
377
        WARN("malloc failure");
378
        return NULL;
379
    }
380
 
381
    if ((pk->pk_buffer = malloc(length+CHAN_HEADER_SIZE)) == NULL)
382
    {
383
        WARN("malloc failure");
384
        free(pk);
385
        return NULL;
386
    }
387
 
388
    return pk;
389
}
390
 
391
void DevSW_FreePacket(Packet *pk)
392
{
393
    free(pk->pk_buffer);
394
    free(pk);
395
}
396
 
397
AdpErrs DevSW_Open(DeviceDescr *device, const char *name, const char *arg,
398
                   const DevChanID type)
399
{
400
    DevSWState *ds;
401
 
402
    /*
403
     * is this the very first open call for this driver?
404
     */
405
    if ((ds = (DevSWState *)(device->SwitcherState)) == NULL)
406
    {
407
        /*
408
         * yes, it is: initialise state
409
         */
410
        if ((ds = malloc(sizeof(*ds))) == NULL)
411
            /* give up */
412
            return adp_malloc_failure;
413
 
414
        (void)memset(ds, 0, sizeof(*ds));
415
        device->SwitcherState = (void *)ds;
416
    }
417
 
418
    /*
419
     * check that we haven't already been opened for this type
420
     */
421
    if ((ds->ds_opendevchans & (1 << type)) != 0)
422
        return adp_device_already_open;
423
 
424
    /*
425
     * if no opens have been done for this device, then do it now
426
     */
427
    if (ds->ds_opendevchans == 0)
428
        if (device->DeviceOpen(name, arg) < 0)
429
            return adp_device_open_failed;
430
 
431
    /*
432
     * open has finished
433
     */
434
    ds->ds_opendevchans |= (1 << type);
435
    return adp_ok;
436
}
437
 
438
AdpErrs DevSW_Match(const DeviceDescr *device, const char *name,
439
                    const char *arg)
440
{
441
    return (device->DeviceMatch(name, arg) == -1) ? adp_failed : adp_ok;
442
}
443
 
444
AdpErrs DevSW_Close (DeviceDescr *device, const DevChanID type)
445
{
446
    DevSWState *ds = (DevSWState *)(device->SwitcherState);
447
    Packet *pk;
448
 
449
    if ((ds->ds_opendevchans & (1 << type)) == 0)
450
        return adp_device_not_open;
451
 
452
    ds->ds_opendevchans &= ~(1 << type);
453
 
454
    /*
455
     * if this is the last close for this channel, then inform the driver
456
     */
457
    if (ds->ds_opendevchans == 0)
458
        device->DeviceClose();
459
 
460
    /*
461
     * release all packets of the appropriate type
462
     */
463
    for (pk = Adp_removeFromQueue(&(ds->ds_readqueue[type]));
464
         pk != NULL;
465
         pk = Adp_removeFromQueue(&(ds->ds_readqueue[type])))
466
        DevSW_FreePacket(pk);
467
 
468
    /* Free memory */
469
    free ((char *) device->SwitcherState);
470
    device->SwitcherState = 0x0;
471
 
472
    /* that's all */
473
    return adp_ok;
474
}
475
 
476
AdpErrs DevSW_Read(const DeviceDescr *device, const DevChanID type,
477
                   Packet **packet, bool block)
478
{
479
  int read_err;
480
  DevSWState *ds = device->SwitcherState;
481
 
482
    /*
483
     * To try to get information out of the device driver as
484
     * quickly as possible, we try and read more packets, even
485
     * if a completed packet is already available.
486
     */
487
 
488
    /*
489
     * have we got a packet currently pending?
490
     */
491
  if (ds->ds_nextreadpacket == NULL)
492
    /*
493
       * no - set things up
494
       */
495
    if (initialise_read(ds) < 0) {
496
      /*
497
       * we failed to initialise the next packet, but can
498
       * still return a packet that has already arrived.
499
       */
500
      *packet = Adp_removeFromQueue(&ds->ds_readqueue[type]);
501
      return adp_ok;
502
    }
503
  read_err = device->DeviceRead(&ds->ds_activeread, block);
504
  switch (read_err) {
505
  case 1:
506
    /*
507
     * driver has pulled in a complete packet, queue it up
508
     */
509
#ifdef RET_DEBUG
510
    printf("got a complete packet\n");
511
#endif
512
 
513
    if (angelDebugLogEnable)
514
      dumpPacket(angelDebugLogFile,"rx:",&ds->ds_activeread.dc_packet);
515
 
516
    enqueue_packet(ds);
517
    *packet = Adp_removeFromQueue(&ds->ds_readqueue[type]);
518
    return adp_ok;
519
  case 0:
520
    /*
521
     * OK, return the head of the read queue for the given type
522
     */
523
    /*    enqueue_packet(ds); */
524
    *packet = Adp_removeFromQueue(&ds->ds_readqueue[type]);
525
    return adp_ok;
526
  case -1:
527
#ifdef RET_DEBUG
528
    printf("got a bad packet\n");
529
#endif
530
    /* bad packet */
531
    *packet = NULL;
532
    return adp_bad_packet;
533
  default:
534
    panic("DevSW_Read: bad read status %d", read_err);
535
  }
536
  return 0; /* get rid of a potential compiler warning */
537
}
538
 
539
 
540
AdpErrs DevSW_FlushPendingWrite(const DeviceDescr *device)
541
{
542
    struct DriverCall *dc;
543
    struct data_packet *dp;
544
 
545
    dc = &((DevSWState *)(device->SwitcherState))->ds_activewrite;
546
    dp = &dc->dc_packet;
547
 
548
    /*
549
     * try to flush any packet that is still being written
550
     */
551
    if (dp->data != NULL)
552
    {
553
        flush_packet(device, dc);
554
 
555
        /* see if it has gone */
556
        if (dp->data != NULL)
557
           return adp_write_busy;
558
        else
559
           return adp_ok;
560
    }
561
    else
562
       return adp_ok;
563
}
564
 
565
 
566
AdpErrs DevSW_Write(const DeviceDescr *device, Packet *packet, DevChanID type)
567
{
568
    struct DriverCall *dc;
569
    struct data_packet *dp;
570
 
571
    dc = &((DevSWState *)(device->SwitcherState))->ds_activewrite;
572
    dp = &dc->dc_packet;
573
 
574
    if (illegalDevChanID(type))
575
        return adp_illegal_args;
576
 
577
    /*
578
     * try to flush any packet that is still being written
579
     */
580
    if (DevSW_FlushPendingWrite(device) != adp_ok)
581
       return adp_write_busy;
582
 
583
    /*
584
     * we can take this packet - set things up, then try to get rid of it
585
     */
586
    initialise_write(dc, packet, type);
587
 
588
    if (angelDebugLogEnable)
589
      dumpPacket(angelDebugLogFile,"tx:",&dc->dc_packet);
590
 
591
    flush_packet(device, dc);
592
 
593
    return adp_ok;
594
}
595
 
596
AdpErrs DevSW_Ioctl(const DeviceDescr *device, const int opcode, void *args)
597
{
598
    return (device->DeviceIoctl(opcode, args) < 0) ? adp_failed : adp_ok;
599
}
600
 
601
bool DevSW_WriteFinished(const DeviceDescr *device)
602
{
603
    struct DriverCall *dc;
604
    struct data_packet *dp;
605
 
606
    dc = &((DevSWState *)(device->SwitcherState))->ds_activewrite;
607
    dp = &dc->dc_packet;
608
 
609
    return (dp == NULL || dp->data == NULL);
610
}
611
 
612
/* EOF devsw.c */

powered by: WebSVN 2.1.0

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