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

Subversion Repositories or1k

[/] [or1k/] [branches/] [oc/] [gdb-5.0/] [gdb/] [rdi-share/] [devsw.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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