/* The common simulator framework for GDB, the GNU Debugger.
- Copyright 2002, 2007 Free Software Foundation, Inc.
+ Copyright 2002-2021 Free Software Foundation, Inc.
Contributed by Andrew Cagney and Red Hat.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* This must come before any other includes. */
+#include "defs.h"
#include "hw-main.h"
#include "hw-base.h"
#include "sim-io.h"
#include "sim-assert.h"
-#ifdef HAVE_STDLIB_H
#include <stdlib.h>
-#endif
-
-#ifdef HAVE_STRING_H
#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
-
#include <ctype.h>
/* manipulate/lookup device names */
-typedef struct _name_specifier {
-
+typedef struct _name_specifier
+{
+
/* components in the full length name */
char *path;
char *property;
char *value;
-
+
/* current device */
char *family;
char *name;
char *unit;
char *args;
-
+
/* previous device */
char *last_name;
char *last_family;
char *last_unit;
char *last_args;
-
+
/* work area */
char buf[1024];
-
+
} name_specifier;
name_specifier *spec)
{
char *chp = NULL;
-
+
/* expand any leading alias if present */
if (current != NULL
&& *device_specifier != '\0'
{
alias[len] = device_specifier[len];
len++;
- if (len >= sizeof(alias))
+ if (len >= sizeof (alias))
hw_abort (NULL, "split_device_specifier: buffer overflow");
}
alias[len] = '\0';
if (aliases != NULL
&& hw_find_property (aliases, alias))
{
- strcpy (spec->buf, hw_find_string_property(aliases, alias));
+ strcpy (spec->buf, hw_find_string_property (aliases, alias));
strcat (spec->buf, device_specifier + len);
}
else
}
else
{
- strcpy(spec->buf, device_specifier);
+ strcpy (spec->buf, device_specifier);
}
-
+
/* check no overflow */
- if (strlen(spec->buf) >= sizeof(spec->buf))
+ if (strlen (spec->buf) >= sizeof (spec->buf))
hw_abort (NULL, "split_device_specifier: buffer overflow\n");
-
+
/* strip leading spaces */
chp = spec->buf;
- while (*chp != '\0' && isspace(*chp))
+ while (*chp != '\0' && isspace (*chp))
chp++;
if (*chp == '\0')
return 0;
-
+
/* find the path and terminate it with null */
spec->path = chp;
- while (*chp != '\0' && !isspace(*chp))
+ while (*chp != '\0' && !isspace (*chp))
chp++;
if (*chp != '\0')
{
*chp = '\0';
chp++;
}
-
+
/* and any value */
- while (*chp != '\0' && isspace(*chp))
+ while (*chp != '\0' && isspace (*chp))
chp++;
spec->value = chp;
-
+
/* now go back and chop the property off of the path */
if (spec->value[0] == '\0')
{
/* an interrupt spec */
spec->property = NULL;
}
- else {
- chp = strrchr(spec->path, '/');
- if (chp == NULL)
- {
- spec->property = spec->path;
- spec->path = strchr(spec->property, '\0');
- }
- else {
- *chp = '\0';
- spec->property = chp+1;
+ else
+ {
+ chp = strrchr (spec->path, '/');
+ if (chp == NULL)
+ {
+ spec->property = spec->path;
+ spec->path = strchr (spec->property, '\0');
+ }
+ else
+ {
+ *chp = '\0';
+ spec->property = chp+1;
+ }
}
- }
-
+
/* and mark the rest as invalid */
spec->name = NULL;
spec->family = NULL;
spec->last_family = NULL;
spec->last_unit = NULL;
spec->last_args = NULL;
-
+
return 1;
}
chp = strchr (spec->name, '/');
if (chp == NULL)
spec->path = strchr (spec->name, '\0');
- else
+ else
{
spec->path = chp+1;
*chp = '\0';
/* break out the base */
if (spec->name[0] == '(')
{
- chp = strchr(spec->name, ')');
+ chp = strchr (spec->name, ')');
if (chp == NULL)
{
spec->family = spec->name;
spec->family = spec->name;
}
/* now break out the unit */
- chp = strchr(spec->name, '@');
+ chp = strchr (spec->name, '@');
if (chp == NULL)
{
spec->unit = NULL;
spec->unit = chp;
}
/* finally any args */
- chp = strchr(chp, ':');
+ chp = strchr (chp, ':');
if (chp == NULL)
spec->args = NULL;
else
else
break;
}
-
+
/* now go through the path proper */
-
+
if (current == NULL)
{
split_device_name (spec);
return NULL;
}
-
+
while (split_device_name (spec))
{
struct hw *child;
return current; /* search failed */
current = child;
}
-
+
return current;
}
/* break it up */
if (!split_device_specifier (current, device_specifier, spec))
hw_abort (current, "error parsing %s\n", device_specifier);
-
+
/* fill our tree with its contents */
current = split_find_device (current, spec);
-
+
/* add any additional devices as needed */
if (spec->name != NULL)
{
}
while (split_device_name (spec));
}
-
+
return current;
}
/* <non-white-space> */
static const char *
-skip_token(const char *chp)
+skip_token (const char *chp)
{
- while (!isspace(*chp) && *chp != '\0')
+ while (!isspace (*chp) && *chp != '\0')
chp++;
- while (isspace(*chp) && *chp != '\0')
+ while (isspace (*chp) && *chp != '\0')
chp++;
return chp;
}
int i;
int nr;
const char *curr = chp;
- memset(size, 0, sizeof(*size));
+ memset (size, 0, sizeof (*size));
/* parse the numeric list */
size->nr_cells = hw_unit_nr_size_cells (bus);
nr = 0;
int reg_nr;
reg_property_spec *regs;
const char *chp;
-
+
/* determine the number of reg entries by counting tokens */
nr_regs = count_entries (current, property_name, property_value, 2);
-
+
/* create working space */
regs = zalloc (nr_regs * sizeof (*regs));
-
+
/* fill it in */
chp = property_value;
for (reg_nr = 0; reg_nr < nr_regs; reg_nr++)
{
- chp = parse_address (current, hw_parent(current),
+ chp = parse_address (current, hw_parent (current),
chp, ®s[reg_nr].address);
- chp = parse_size (current, hw_parent(current),
+ chp = parse_size (current, hw_parent (current),
chp, ®s[reg_nr].size);
}
-
+
/* create it */
hw_add_reg_array_property (current, property_name,
regs, nr_regs);
-
- zfree (regs);
+
+ free (regs);
}
int range_nr;
range_property_spec *ranges;
const char *chp;
-
+
/* determine the number of ranges specified */
nr_ranges = count_entries (current, property_name, property_value, 3);
-
+
/* create a property of that size */
- ranges = zalloc (nr_ranges * sizeof(*ranges));
-
+ ranges = zalloc (nr_ranges * sizeof (*ranges));
+
/* fill it in */
chp = property_value;
for (range_nr = 0; range_nr < nr_ranges; range_nr++)
{
chp = parse_address (current, current,
chp, &ranges[range_nr].child_address);
- chp = parse_address (current, hw_parent(current),
+ chp = parse_address (current, hw_parent (current),
chp, &ranges[range_nr].parent_address);
chp = parse_size (current, current,
chp, &ranges[range_nr].size);
}
-
+
/* create it */
hw_add_range_array_property (current, property_name, ranges, nr_ranges);
-
- zfree (ranges);
+
+ free (ranges);
}
}
/* perhaps integer array property is better */
hw_add_array_property (current, property_name, words,
- sizeof(words[0]) * nr_entries);
+ sizeof (words[0]) * nr_entries);
}
}
const char *chp;
int nr_strings;
int approx_nr_strings;
-
+
/* get an estimate as to the number of strings by counting double
quotes */
approx_nr_strings = 2;
approx_nr_strings++;
}
approx_nr_strings = (approx_nr_strings) / 2;
-
+
/* create a string buffer for that many (plus a null) */
- strings = (char**) zalloc ((approx_nr_strings + 1) * sizeof(char*));
-
+ strings = (char**) zalloc ((approx_nr_strings + 1) * sizeof (char*));
+
/* now find all the strings */
chp = property_value;
nr_strings = 0;
while (1)
{
-
+
/* skip leading space */
while (*chp != '\0' && isspace (*chp))
chp += 1;
if (*chp == '\0')
break;
-
+
/* copy it in */
if (*chp == '"')
{
pos = 0;
while (*chp != '\0' && *chp != '"')
{
- if (*chp == '\\' && *(chp+1) != '\0') {
- strings[nr_strings][pos] = *(chp+1);
- chp += 2;
- pos++;
- }
+ if (*chp == '\\' && *(chp+1) != '\0')
+ {
+ strings[nr_strings][pos] = *(chp+1);
+ chp += 2;
+ pos++;
+ }
else
{
strings[nr_strings][pos] = *chp;
{
/* copy over a single unquoted token */
int len = 0;
- while (chp[len] != '\0' && !isspace(chp[len]))
+ while (chp[len] != '\0' && !isspace (chp[len]))
len++;
- strings[nr_strings] = zalloc(len + 1);
- strncpy(strings[nr_strings], chp, len);
+ strings[nr_strings] = zalloc (len + 1);
+ strncpy (strings[nr_strings], chp, len);
strings[nr_strings][len] = '\0';
chp += len;
}
property_name);
}
ASSERT (strings[nr_strings] == NULL); /* from zalloc */
-
+
/* install it */
if (nr_strings == 0)
hw_add_string_property (current, property_name, "");
hw_add_string_array_property (current, property_name,
specs, nr_strings);
}
-
+
/* flush the created string */
while (nr_strings > 0)
{
nr_strings--;
- zfree (strings[nr_strings]);
+ free (strings[nr_strings]);
}
- zfree(strings);
+ free (strings);
}
const char *value)
{
ihandle_runtime_property_spec ihandle;
-
+
/* pass the full path */
ihandle.full_path = value;
-
+
/* save this ready for the ihandle create */
hw_add_ihandle_runtime_property (current, property,
&ihandle);
va_end (ap);
return current;
}
-
+
struct hw *
hw_tree_vparse (struct hw *current,
const char *fmt,
{
char device_specifier[1024];
name_specifier spec;
-
+
/* format the path */
vsprintf (device_specifier, fmt, ap);
if (strlen (device_specifier) >= sizeof (device_specifier))
hw_abort (NULL, "device_tree_add_deviced: buffer overflow\n");
-
+
/* construct the tree down to the final struct hw */
current = split_fill_path (current, device_specifier, &spec);
-
+
/* is there an interrupt spec */
if (spec.property == NULL
&& spec.value != NULL)
break;
}
}
-
+
/* is there a property */
if (spec.property != NULL)
{
nr_words += 1;
}
hw_add_array_property (current, spec.property,
- words, sizeof(words[0]) * nr_words);
+ words, sizeof (words[0]) * nr_words);
break;
}
case '"':
{
parse_ranges_property (current, spec.property, spec.value);
}
- else if (isdigit(spec.value[0])
- || (spec.value[0] == '-' && isdigit(spec.value[1]))
- || (spec.value[0] == '+' && isdigit(spec.value[1])))
+ else if (isdigit (spec.value[0])
+ || (spec.value[0] == '-' && isdigit (spec.value[1]))
+ || (spec.value[0] == '+' && isdigit (spec.value[1])))
{
- parse_integer_property(current, spec.property, spec.value);
+ parse_integer_property (current, spec.property, spec.value);
}
else
- parse_string_property(current, spec.property, spec.value);
+ parse_string_property (current, spec.property, spec.value);
break;
}
}
\f
-struct printer {
+struct printer
+{
hw_tree_print_callback *print;
void *file;
};
struct printer *p)
{
char unit[32];
- hw_unit_encode (bus, phys, unit, sizeof(unit));
+ hw_unit_encode (bus, phys, unit, sizeof (unit));
p->print (p->file, " %s", unit);
}
for (i = 0; i < size->nr_cells; i++)
if (size->cells[i] != 0)
break;
- if (i < size->nr_cells) {
- p->print (p->file, " 0x%lx", (unsigned long) size->cells[i]);
- i++;
- for (; i < size->nr_cells; i++)
- p->print (p->file, ",0x%lx", (unsigned long) size->cells[i]);
- }
+ if (i < size->nr_cells)
+ {
+ p->print (p->file, " 0x%lx", (unsigned long) size->cells[i]);
+ i++;
+ for (; i < size->nr_cells; i++)
+ p->print (p->file, ",0x%lx", (unsigned long) size->cells[i]);
+ }
else
p->print (p->file, " 0");
}
reg_property_spec reg;
for (reg_nr = 0;
hw_find_reg_array_property (me, property->name, reg_nr, ®);
- reg_nr++) {
- print_address (hw_parent (me), ®.address, p);
- print_size (me, ®.size, p);
- }
+ reg_nr++)
+ {
+ print_address (hw_parent (me), ®.address, p);
+ print_size (me, ®.size, p);
+ }
}
static void
struct printer *p)
{
p->print (p->file, " \"");
- while (*string != '\0') {
- switch (*string) {
- case '"':
- p->print (p->file, "\\\"");
- break;
- case '\\':
- p->print (p->file, "\\\\");
- break;
- default:
- p->print (p->file, "%c", *string);
- break;
+ while (*string != '\0')
+ {
+ switch (*string)
+ {
+ case '"':
+ p->print (p->file, "\\\"");
+ break;
+ case '\\':
+ p->print (p->file, "\\\\");
+ break;
+ default:
+ p->print (p->file, "%c", *string);
+ break;
+ }
+ string++;
}
- string++;
- }
p->print (p->file, "\"");
}
if (property->original != NULL)
{
p->print (p->file, " !");
- p->print (p->file, "%s/%s",
+ p->print (p->file, "%s/%s",
hw_path (property->original->owner),
property->original->name);
}
{
unsigned8 *w = (unsigned8*)property->array;
p->print (p->file, " [");
- while ((char*)w - (char*)property->array < property->sizeof_array) {
- p->print (p->file, " 0x%2x", BE2H_1 (*w));
- w++;
- }
+ while ((char*)w - (char*)property->array < property->sizeof_array)
+ {
+ p->print (p->file, " 0x%2x", BE2H_1 (*w));
+ w++;
+ }
}
break;
}
case boolean_property:
{
- int b = hw_find_boolean_property(me, property->name);
+ int b = hw_find_boolean_property (me, property->name);
p->print (p->file, " %s", b ? "true" : "false");
break;
}
if (property->array != NULL)
{
device_instance *instance = hw_find_ihandle_property (me, property->name);
- p->print (p->file, " *%s", device_instance_path(instance));
+ p->print (p->file, " *%s", device_instance_path (instance));
}
else
{
struct printer *p = data;
char src[32];
char dst[32];
- hw_port_encode (me, my_port, src, sizeof(src), output_port);
- hw_port_encode (dest, dest_port, dst, sizeof(dst), input_port);
+ hw_port_encode (me, my_port, src, sizeof (src), output_port);
+ hw_port_encode (dest, dest_port, dst, sizeof (dst), input_port);
p->print (p->file,
"%s > %s %s %s\n",
hw_path (me),
\f
#if NOT_YET
device_instance *
-tree_instance(struct hw *root,
- const char *device_specifier)
+tree_instance (struct hw *root,
+ const char *device_specifier)
{
/* find the device node */
struct hw *me;
name_specifier spec;
- if (!split_device_specifier(root, device_specifier, &spec))
+ if (!split_device_specifier (root, device_specifier, &spec))
return NULL;
- me = split_find_device(root, &spec);
+ me = split_find_device (root, &spec);
if (spec.name != NULL)
return NULL;
/* create the instance */
- return device_create_instance(me, device_specifier, spec.last_args);
+ return device_create_instance (me, device_specifier, spec.last_args);
}
#endif
{
struct hw *node;
name_specifier spec;
-
+
/* parse the path */
split_device_specifier (root, path_to_device, &spec);
if (spec.value != NULL)
return NULL; /* something wierd */
-
+
/* now find it */
node = split_find_device (root, &spec);
if (spec.name != NULL)
return NULL; /* not a leaf */
-
+
return node;
}