]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/cygmon/v2_0/misc/utils.c
Initial revision
[karo-tx-redboot.git] / packages / cygmon / v2_0 / misc / utils.c
1 //==========================================================================
2 //
3 //      utils.c
4 //
5 //      Monitor utilities.
6 //
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 //
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
16 //
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 // for more details.
21 //
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 //
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
32 //
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
35 //
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
42 //
43 // Author(s):    
44 // Contributors: gthomas, dmoseley
45 // Date:         1999-10-20
46 // Purpose:      Monitor utilities.
47 // Description:  
48 //               
49 //
50 //####DESCRIPTIONEND####
51 //
52 //=========================================================================
53
54 #include <limits.h>
55 #include <stdlib.h>
56 #include <string.h>
57 #include <ctype.h>
58 #ifdef HAVE_BSP
59 #include <bsp/bsp.h>
60 #include <bsp/cpu.h>
61 #include <bsp/hex-utils.h>
62 #endif
63 #include "monitor.h"
64 #include "tservice.h"
65
66 #if USE_CYGMON_PROTOTYPES
67 /* Use common prototypes */
68 /* Some of the composed board.h files compose these
69    prototypes redundently, but if they dont,
70    these are the common definitions */
71 #include "fmt_util.h"   /* Interface to string formatting utilities */
72 #include "generic-stub.h" /* from libstub */
73 #endif /* USE_CYGMON_PROTOTYPES */
74
75 volatile int switch_to_stub_flag = 0;
76
77 /* Input routine for the line editor. */
78 int
79 input_char (void)
80 {
81   int i;
82
83   /* We have to drop the '+' characters on the floor
84      because gdb will send a '+' as the first character
85      when connecting to the target. If we waste time
86      echoing that, slow hw might get a uart overrun. */
87   while ((i = xgetchar ()) == '+');
88
89   if (i == '$')
90     {
91       xungetchar ('$');
92       switch_to_stub_flag = 1;
93       i = '\n';
94     }
95   return i;
96 }
97
98
99 static char tohex_array[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
100                                '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
101
102 #define tohex(X) (tohex_array[(X) & 15])
103
104 #ifdef HAVE_BSP
105 #define fromhex __hex
106 #else
107 static int
108 fromhex (a)
109 {
110   int number = -1;
111
112   if (a >= '0' && a <= '9')
113     number = a - '0';
114   else if (a >= 'a' && a <= 'f')
115     number = a - 'a' + 10;
116   else if (a >= 'A' && a <= 'F')
117     number = a - 'A' + 10;
118   else 
119     xprintf ("Invalid hex digit %c", a);
120
121   return number;
122 }
123 #endif
124
125
126 static unsigned long long
127 str2ull (char *str, int base)
128 {
129   unsigned long long l = 0;
130
131   if (str[0] == '0' && str[1] == 'x')
132     {
133       str += 2 ;
134       base = 16 ;
135     }
136
137   while (*str != '\0')
138     {
139       if (*str == '.')
140         str++;
141       else
142         l = (l * base) + fromhex(*str++);
143     }
144
145   return l;
146 }
147
148
149 /* Converts a string to a long, base is the assumed base of the string */
150
151 target_register_t
152 str2int (char *str, int base)
153 {
154   return str2ull(str, base);
155 }
156
157 /* Converts a string to a double, input is a raw integer string
158  * of the given assumed base. */
159 #if HAVE_DOUBLE_REGS
160 static double
161 str2double (char *str, int base)
162 {
163   double d;
164
165   switch (sizeof(double))
166     {
167       case sizeof(unsigned int):
168         *((unsigned int *)&d) = str2ull(str, base);
169         break;
170 #if __LONG_MAX__ != __INT_MAX__
171       case sizeof(unsigned long):
172         *((unsigned long *)&d) = str2ull(str, base);
173         break;
174 #endif
175 #if __LONG_LONG_MAX__ != __LONG_MAX__
176       case sizeof(unsigned long long):
177         *((unsigned long long *)&d) = str2ull(str, base);
178         break;
179 #endif
180       default:
181         d = 0.0;
182         break;
183     }
184   return d;
185 }
186 #endif
187
188 target_register_t
189 str2intlen (char *str, int base, int len)
190 {
191   target_register_t number = 0;
192
193   while ((len--) > 0 && *str != '\0')
194     number = number * base + fromhex (*(str++));
195
196   return number;
197 }
198
199 int
200 hex2bytes (char *str, char *dest, int maxsize)
201 {
202   int i;
203   char *ptr;
204
205   for (i = 0; i < maxsize; i++)
206     dest[i] = 0;
207   maxsize--;
208
209   // Don't try and convert 0x prefix
210   if ((str[0] == '0') && (str[1] == 'x'))
211       str += 2;
212
213   ptr = str + strlen(str) - 1;
214   while (maxsize >= 0 && ptr >= str)
215     {
216       dest [maxsize] = fromhex(*ptr);
217       ptr--;
218       if (ptr >= str)
219         {
220           dest [maxsize--] |= fromhex(*ptr) * 16;
221           ptr--;
222         }
223     }
224   return 0;
225 }
226
227
228 /* Converts an unsigned long long to an ASCII string, adding leading
229    zeroes to pad space up to numdigs. */
230 static int use_dots = 1;
231
232 #define MAX_NUM_DIGS 51
233
234 static char *
235 ull2str (unsigned long long number, int base, int numdigs)
236 {
237   static char string[MAX_NUM_DIGS+1];
238   int dots, i;
239   char *ptr = string + MAX_NUM_DIGS;
240
241   dots = (use_dots && base == 16);
242
243   *(ptr--) = '\0';
244   *(ptr--) = tohex (number % base);
245   i = 1;
246   number = number / base;
247
248   while (number != 0)
249     {
250       if (dots && (i % 4) == 0)
251         *(ptr--) = '.';
252       *(ptr--) = tohex (number % base);
253       i++;
254       number = number / base;
255     }
256
257   if (numdigs == 0)
258     {
259       numdigs = i;
260     }
261   else
262     {
263       while(i < numdigs)
264         {
265           if (dots && (i % 4) == 0)
266             *(ptr--) = '.';
267           *(ptr--) = '0';
268           i++;
269         }
270     }
271   return ptr + 1;
272 }
273
274
275 char *
276 int2str (target_register_t number, int base, int numdigs)
277 {
278   return ull2str((unsigned long long)number, base, numdigs);
279 }
280
281 #if HAVE_DOUBLE_REGS
282 static char *
283 double2str(double d)
284 {
285   switch(sizeof(double))
286     {
287       case sizeof(unsigned int):
288         return ull2str(*((unsigned int *)&d), 16, sizeof(double) * 2);
289         break;
290 #if __LONG_MAX__ != __INT_MAX__
291       case sizeof(unsigned long):
292         return ull2str(*((unsigned long *)&d), 16, sizeof(double) * 2);
293         break;
294 #endif
295 #if __LONG_LONG_MAX__ != __LONG_MAX__
296       case sizeof(unsigned long long):
297         return ull2str(*((unsigned long long *)&d), 16, sizeof(double) * 2);
298         break;
299 #endif
300     }
301   return "....fixme...";
302 }
303 #endif
304
305 #ifndef NO_MALLOC
306 char *
307 strdup(const char *str)
308 {
309   char *x = malloc (strlen (str) + 1);
310   if (x != NULL)
311     strcpy (x, str);
312   return x;
313 }
314 #endif
315
316
317 target_register_t
318 get_pc(void)
319 {
320     return get_register(REG_PC);
321 }
322
323
324 #if defined(HAVE_BSP) && !defined(__ECOS__)
325 static int
326 get_register_type(regnames_t which)
327 {
328     int i;
329
330     for (i = 0; regtab[i].registername != NULL; i++)
331       if (regtab[i].registernumber == which)
332         return regtab[i].registertype;
333     return REGTYPE_INT;
334 }
335 #endif
336
337 char *get_register_str (regnames_t which, int detail, int valid)
338 {
339 #ifdef SPECIAL_REG_OUTPUT
340   char *res;
341
342   if ((res = SPECIAL_REG_OUTPUT (which, detail)) != NULL)
343     {
344       return res;
345     }
346 #endif
347   if (valid == 0)
348     {
349       switch (sizeof (target_register_t))
350         {
351         case 1:  return "...";
352         case 2:  return ".....";
353         case 4:  return ".........";
354         case 8:  return ".................";
355         default: return ".........";
356         }
357     }
358   else
359     {
360       return int2str (get_register (which), 16, sizeof (target_register_t) * 2);
361     }
362 }
363
364
365 void
366 store_register (regnames_t which, char *string)
367 {
368 #ifdef SPECIAL_REG_STORE
369   if (SPECIAL_REG_STORE(which, string))
370     return;
371 #endif
372   put_register (which, str2int (string, 16));
373 }
374
375
376