xref: /openbsd-src/gnu/usr.bin/binutils/gdb/rdi-share/msgbuild.c (revision 63addd46c1e40ca0f49488ddcdc4ab598023b0c1)
1b725ae77Skettenis /*
2b725ae77Skettenis  * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
3b725ae77Skettenis  *
4b725ae77Skettenis  * This software may be freely used, copied, modified, and distributed
5b725ae77Skettenis  * provided that the above copyright notice is preserved in all copies of the
6b725ae77Skettenis  * software.
7b725ae77Skettenis  */
8b725ae77Skettenis 
9b725ae77Skettenis /* -*-C-*-
10b725ae77Skettenis  *
11*63addd46Skettenis  * $Revision: 1.3 $
12*63addd46Skettenis  *     $Date: 2004/12/27 14:00:54 $
13b725ae77Skettenis  *
14b725ae77Skettenis  *
15b725ae77Skettenis  * msgbuild.c - utilities for assembling and interpreting ADP messages
16b725ae77Skettenis  *
17b725ae77Skettenis  */
18b725ae77Skettenis 
19b725ae77Skettenis #include <stdarg.h>     /* ANSI varargs support */
20b725ae77Skettenis 
21b725ae77Skettenis #ifdef TARGET
22b725ae77Skettenis # include "angel.h"
23b725ae77Skettenis # include "devconf.h"
24b725ae77Skettenis #else
25b725ae77Skettenis # include "host.h"
26b725ae77Skettenis # include "hostchan.h"
27b725ae77Skettenis #endif
28b725ae77Skettenis 
29b725ae77Skettenis #include "channels.h"
30b725ae77Skettenis #include "buffers.h"
31b725ae77Skettenis #include "angel_endian.h"     /* Endianness support macros */
32b725ae77Skettenis #include "msgbuild.h"   /* Header file for this source code */
33b725ae77Skettenis 
34b725ae77Skettenis #ifndef UNUSED
35b725ae77Skettenis # define UNUSED(x) ((x)=(x))
36b725ae77Skettenis #endif
37b725ae77Skettenis 
38b725ae77Skettenis #ifndef TARGET
39b725ae77Skettenis 
40b725ae77Skettenis extern unsigned int Armsd_BufferSize;
41b725ae77Skettenis 
42b725ae77Skettenis #endif /* ndef TARGET */
43b725ae77Skettenis 
44b725ae77Skettenis 
vmsgbuild(unsigned char * buffer,const char * format,va_list args)45b725ae77Skettenis unsigned int vmsgbuild(unsigned char *buffer, const char *format, va_list args)
46b725ae77Skettenis {
47b725ae77Skettenis     unsigned int blen = 0;
48b725ae77Skettenis     int ch;
49b725ae77Skettenis 
50b725ae77Skettenis     /* Step through the format string */
51b725ae77Skettenis     while ((ch = *format++) != '\0')
52b725ae77Skettenis     {
53b725ae77Skettenis         if (ch != '%')
54b725ae77Skettenis         {
55b725ae77Skettenis             if (buffer != NULL)
56b725ae77Skettenis                 *buffer++ = (unsigned char)ch;
57b725ae77Skettenis 
58b725ae77Skettenis             blen++;
59b725ae77Skettenis         }
60b725ae77Skettenis         else
61b725ae77Skettenis         {
62b725ae77Skettenis             switch (ch = *format++)
63b725ae77Skettenis             {
64b725ae77Skettenis               case 'w':
65b725ae77Skettenis               case 'W':
66b725ae77Skettenis               /* 32bit pointer */
67b725ae77Skettenis               case 'p':
68b725ae77Skettenis               case 'P':
69b725ae77Skettenis               {
70b725ae77Skettenis                   /* 32bit word / 32bit pointer */
71b725ae77Skettenis                   unsigned int na = va_arg(args, unsigned int);
72b725ae77Skettenis 
73b725ae77Skettenis                   if (buffer != NULL)
74b725ae77Skettenis                   {
75b725ae77Skettenis                       PUT32LE(buffer, na);
76b725ae77Skettenis                       buffer += sizeof(unsigned int);
77b725ae77Skettenis                   }
78b725ae77Skettenis 
79b725ae77Skettenis                   blen += sizeof(unsigned int);
80b725ae77Skettenis 
81b725ae77Skettenis                   break;
82b725ae77Skettenis               }
83b725ae77Skettenis 
84b725ae77Skettenis               case 'h':
85b725ae77Skettenis               case 'H':
86b725ae77Skettenis               {
87b725ae77Skettenis                   /* 16bit value */
88b725ae77Skettenis                   unsigned int na = va_arg(args, unsigned int);
89b725ae77Skettenis 
90b725ae77Skettenis                   if (buffer != NULL)
91b725ae77Skettenis                   {
92b725ae77Skettenis                       PUT16LE(buffer, na);
93b725ae77Skettenis                       buffer += sizeof(unsigned short);
94b725ae77Skettenis                   }
95b725ae77Skettenis 
96b725ae77Skettenis                   blen += sizeof(unsigned short);
97b725ae77Skettenis 
98b725ae77Skettenis                   break;
99b725ae77Skettenis               }
100b725ae77Skettenis 
101b725ae77Skettenis               case 'c':
102b725ae77Skettenis               case 'C':
103b725ae77Skettenis               case 'b':
104b725ae77Skettenis               case 'B':
105b725ae77Skettenis                   /* 8bit character / 8bit byte */
106b725ae77Skettenis                   ch = va_arg(args, int);
107b725ae77Skettenis 
108b725ae77Skettenis                   /*
109b725ae77Skettenis                    * XXX
110b725ae77Skettenis                    *
111b725ae77Skettenis                    * fall through to the normal character processing
112b725ae77Skettenis                    */
113b725ae77Skettenis 
114b725ae77Skettenis               case '%':
115b725ae77Skettenis               default:
116b725ae77Skettenis                   /* normal '%' character, or a different normal character */
117b725ae77Skettenis                   if (buffer != NULL)
118b725ae77Skettenis                       *buffer++ = (unsigned char)ch;
119b725ae77Skettenis 
120b725ae77Skettenis                   blen++;
121b725ae77Skettenis                   break;
122b725ae77Skettenis             }
123b725ae77Skettenis         }
124b725ae77Skettenis     }
125b725ae77Skettenis 
126b725ae77Skettenis     return blen;
127b725ae77Skettenis }
128b725ae77Skettenis 
129b725ae77Skettenis /*
130b725ae77Skettenis  * msgbuild
131b725ae77Skettenis  * --------
132b725ae77Skettenis  * Simple routine to aid in construction of Angel messages. See the
133b725ae77Skettenis  * "msgbuild.h" header file for a detailed description of the operation
134b725ae77Skettenis  * of this routine.
135b725ae77Skettenis  */
msgbuild(unsigned char * buffer,const char * format,...)136b725ae77Skettenis unsigned int msgbuild(unsigned char *buffer, const char *format, ...)
137b725ae77Skettenis {
138b725ae77Skettenis     va_list args;
139b725ae77Skettenis     unsigned int blen;
140b725ae77Skettenis 
141b725ae77Skettenis     va_start(args, format);
142b725ae77Skettenis     blen = vmsgbuild(buffer, format, args);
143b725ae77Skettenis     va_end(args);
144b725ae77Skettenis 
145b725ae77Skettenis     return blen;
146b725ae77Skettenis }
147b725ae77Skettenis 
148b725ae77Skettenis #if !defined(JTAG_ADP_SUPPORTED) && !defined(MSG_UTILS_ONLY)
149b725ae77Skettenis /*
150b725ae77Skettenis  * This routine allocates a buffer, puts the data supplied as
151b725ae77Skettenis  * parameters into the buffer and sends the message. It does *NOT*
152b725ae77Skettenis  * wait for a reply.
153b725ae77Skettenis  */
msgsend(ChannelID chan,const char * format,...)154b725ae77Skettenis extern int msgsend(ChannelID chan, const char *format,...)
155b725ae77Skettenis {
156b725ae77Skettenis     unsigned int length;
157b725ae77Skettenis     p_Buffer buffer;
158b725ae77Skettenis     va_list args;
159b725ae77Skettenis # ifndef TARGET
160b725ae77Skettenis     Packet *packet;
161b725ae77Skettenis 
162b725ae77Skettenis     packet = DevSW_AllocatePacket(Armsd_BufferSize);
163b725ae77Skettenis     buffer = packet->pk_buffer;
164b725ae77Skettenis # else
165b725ae77Skettenis     buffer = angel_ChannelAllocBuffer(Angel_ChanBuffSize);
166b725ae77Skettenis # endif
167b725ae77Skettenis 
168b725ae77Skettenis     if (buffer != NULL)
169b725ae77Skettenis     {
170b725ae77Skettenis         va_start(args, format);
171b725ae77Skettenis 
172b725ae77Skettenis         length = vmsgbuild(BUFFERDATA(buffer), format, args);
173b725ae77Skettenis 
174b725ae77Skettenis # ifdef TARGET
175b725ae77Skettenis         angel_ChannelSend(CH_DEFAULT_DEV, chan, buffer, length);
176b725ae77Skettenis # else
177b725ae77Skettenis         packet->pk_length = length;
178b725ae77Skettenis         Adp_ChannelWrite(chan, packet);
179b725ae77Skettenis # endif
180b725ae77Skettenis 
181b725ae77Skettenis         va_end(args);
182b725ae77Skettenis         return 0;
183b725ae77Skettenis     }
184b725ae77Skettenis     else
185b725ae77Skettenis         return -1;
186b725ae77Skettenis }
187b725ae77Skettenis 
188b725ae77Skettenis #endif /* ndef JTAG_ADP_SUPPORTED && ndef MSG_UTILS_ONLY */
189b725ae77Skettenis 
190b725ae77Skettenis /*
191b725ae77Skettenis  * unpack_message
192b725ae77Skettenis  * --------------
193b725ae77Skettenis  */
unpack_message(unsigned char * buffer,const char * format,...)194b725ae77Skettenis extern unsigned int unpack_message(unsigned char *buffer, const char *format, ...)
195b725ae77Skettenis {
196b725ae77Skettenis     va_list args;
197b725ae77Skettenis     unsigned int blen = 0;
198b725ae77Skettenis     int ch;
199b725ae77Skettenis     char *chp = NULL;
200b725ae77Skettenis 
201b725ae77Skettenis     va_start(args, format);
202b725ae77Skettenis 
203b725ae77Skettenis     /* Step through the format string. */
204b725ae77Skettenis     while ((ch = *format++) != '\0')
205b725ae77Skettenis     {
206b725ae77Skettenis         if (ch != '%')
207b725ae77Skettenis         {
208b725ae77Skettenis             if (buffer != NULL)
209b725ae77Skettenis                 ch = (unsigned char)*buffer++;
210b725ae77Skettenis 
211b725ae77Skettenis             blen++;
212b725ae77Skettenis         }
213b725ae77Skettenis         else
214b725ae77Skettenis         {
215b725ae77Skettenis             switch (ch = *format++)
216b725ae77Skettenis             {
217b725ae77Skettenis               case 'w':
218b725ae77Skettenis               case 'W':
219b725ae77Skettenis               {
220b725ae77Skettenis                   /* 32bit word. */
221b725ae77Skettenis                   unsigned int *nap = va_arg(args, unsigned int*);
222b725ae77Skettenis 
223b725ae77Skettenis                   if (buffer != NULL)
224b725ae77Skettenis                   {
225b725ae77Skettenis                       *nap = PREAD32(LE, buffer);
226b725ae77Skettenis                       buffer += sizeof(unsigned int);
227b725ae77Skettenis                   }
228b725ae77Skettenis 
229b725ae77Skettenis                   blen += sizeof(unsigned int);
230b725ae77Skettenis 
231b725ae77Skettenis                   break;
232b725ae77Skettenis               }
233b725ae77Skettenis 
234b725ae77Skettenis               case 'h':
235b725ae77Skettenis               case 'H':
236b725ae77Skettenis               {
237b725ae77Skettenis                   /* 16bit value. */
238b725ae77Skettenis                   unsigned int *nap = va_arg(args, unsigned int*);
239b725ae77Skettenis 
240b725ae77Skettenis                   if (buffer != NULL)
241b725ae77Skettenis                   {
242b725ae77Skettenis                       *nap = PREAD16(LE,buffer);
243b725ae77Skettenis                       buffer += sizeof(unsigned short);
244b725ae77Skettenis                   }
245b725ae77Skettenis 
246b725ae77Skettenis                   blen += sizeof(unsigned short);
247b725ae77Skettenis 
248b725ae77Skettenis                   break;
249b725ae77Skettenis               }
250b725ae77Skettenis 
251b725ae77Skettenis               case 'c':
252b725ae77Skettenis               case 'C':
253b725ae77Skettenis               case 'b':
254b725ae77Skettenis               case 'B':
255b725ae77Skettenis                   /* 8-bit character, or 8-bit byte */
256b725ae77Skettenis                   chp = va_arg(args, char*);
257b725ae77Skettenis 
258b725ae77Skettenis                   /*
259b725ae77Skettenis                    * XXX
260b725ae77Skettenis                    *
261b725ae77Skettenis                    * fall through to the normal character processing.
262b725ae77Skettenis                    */
263b725ae77Skettenis 
264b725ae77Skettenis               case '%':
265b725ae77Skettenis               default:
266b725ae77Skettenis                   /* normal '%' character, or a different normal character */
267b725ae77Skettenis                   if (buffer != NULL)
268b725ae77Skettenis                       *chp = (unsigned char)*buffer++;
269b725ae77Skettenis 
270b725ae77Skettenis                   blen++;
271b725ae77Skettenis 
272b725ae77Skettenis                   break;
273b725ae77Skettenis             }
274b725ae77Skettenis         }
275b725ae77Skettenis     }
276b725ae77Skettenis 
277b725ae77Skettenis     va_end(args);
278b725ae77Skettenis     return(blen);
279b725ae77Skettenis }
280b725ae77Skettenis 
281b725ae77Skettenis 
282b725ae77Skettenis /* EOF msgbuild.c */
283