* ltconfig, ltmain.sh: Upgrade to libtool 1.4a 1.641.2.256.
[deliverable/binutils-gdb.git] / gdb / rdi-share / devsw.c
CommitLineData
c906108c
SS
1/*
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$
12 * $Date$
13 *
14 */
15#include <stdio.h>
16#include <stdlib.h>
5c44784c 17#include <string.h>
0fda6bd2 18#include <fcntl.h>
31e28849 19#include <time.h>
c906108c
SS
20
21#include "adp.h"
c3f6f71d 22#include "sys.h"
c906108c
SS
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
5c44784c
JM
33static char *angelDebugFilename = NULL;
34static FILE *angelDebugLogFile = NULL;
35static int angelDebugLogEnable = 0;
36
37static 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
0fda6bd2
JM
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 }
5c44784c
JM
61
62 time (&t);
63 fprintf (angelDebugLogFile,"ADP log file opened at %s\n",asctime(localtime(&t)));
64}
65
66
67static 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
82void 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
93void 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
114static void dumpPacket(FILE *fp, char *label, struct data_packet *p)
115{
116 unsigned r;
117 int i;
c3f6f71d 118 unsigned char channel;
5c44784c
JM
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
c3f6f71d
JM
128 channel = p->data[0];
129
5c44784c
JM
130 r = WordAt(p->data+4);
131
132 fprintf(fp,"R=%08x ",r);
133 fprintf(fp,"%s ", r&0x80000000 ? "H<-T" : "H->T");
134
c3f6f71d 135 switch (channel)
5c44784c
JM
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;
c3f6f71d
JM
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
5c44784c
JM
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
c906108c
SS
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 */
236static 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 */
253static 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 */
291static 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 */
315static 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 */
358static 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 */
373Packet *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
393void DevSW_FreePacket(Packet *pk)
394{
395 free(pk->pk_buffer);
396 free(pk);
397}
398
399AdpErrs 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
440AdpErrs 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
c3f6f71d 446AdpErrs DevSW_Close (DeviceDescr *device, const DevChanID type)
c906108c
SS
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
478AdpErrs 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
5c44784c
JM
514
515 if (angelDebugLogEnable)
516 dumpPacket(angelDebugLogFile,"rx:",&ds->ds_activeread.dc_packet);
517
c906108c
SS
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
542AdpErrs 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
568AdpErrs 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);
5c44784c
JM
589
590 if (angelDebugLogEnable)
591 dumpPacket(angelDebugLogFile,"tx:",&dc->dc_packet);
592
c906108c
SS
593 flush_packet(device, dc);
594
595 return adp_ok;
596}
597
598AdpErrs DevSW_Ioctl(const DeviceDescr *device, const int opcode, void *args)
599{
600 return (device->DeviceIoctl(opcode, args) < 0) ? adp_failed : adp_ok;
601}
602
603bool 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 */
This page took 0.126684 seconds and 4 git commands to generate.