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