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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [rdi-share/] [devsw.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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