static void hw_add_property (struct hw *me, const char *property, hw_property_type type, const void *init_array, unsigned sizeof_init_array, const void *array, unsigned sizeof_array, const struct hw_property *original, object_disposition disposition) { struct hw_property_data *new_entry = NULL; struct hw_property *new_value = NULL; /* find the list end */ struct hw_property_data **insertion_point = &me->properties_of_hw; while (*insertion_point != NULL) { if (strcmp ((*insertion_point)->property->name, property) == 0) return; insertion_point = &(*insertion_point)->next; } /* create a new value */ new_value = HW_ZALLOC (me, struct hw_property); new_value->name = (char *) strdup (property); new_value->type = type; if (sizeof_array > 0) { void *new_array = hw_zalloc (me, sizeof_array); memcpy (new_array, array, sizeof_array); new_value->array = new_array; new_value->sizeof_array = sizeof_array; } new_value->owner = me; new_value->original = original; new_value->disposition = disposition; /* insert the value into the list */ new_entry = HW_ZALLOC (me, struct hw_property_data); *insertion_point = new_entry; if (sizeof_init_array > 0) { void *new_init_array = hw_zalloc (me, sizeof_init_array); memcpy (new_init_array, init_array, sizeof_init_array); new_entry->init_array = new_init_array; new_entry->sizeof_init_array = sizeof_init_array; } new_entry->property = new_value; }
void hw_add_reg_array_property (struct hw *me, const char *property, const reg_property_spec *regs, unsigned nr_regs) { unsigned sizeof_cells = (nr_reg_property_cells (me, nr_regs) * sizeof (unsigned_cell)); unsigned_cell *cells = hw_zalloc (me, sizeof_cells); unsigned_cell *cell; int i; /* copy the property elements over */ cell = cells; for (i = 0; i < nr_regs; i++) { const reg_property_spec *reg = ®s[i]; /* copy the address */ cell = unit_address_to_cells (®->address, cell, hw_unit_nr_address_cells (hw_parent (me))); /* copy the size */ cell = unit_address_to_cells (®->size, cell, hw_unit_nr_size_cells (hw_parent (me))); } ASSERT (cell == &cells[nr_reg_property_cells (me, nr_regs)]); /* add it */ hw_add_property (me, property, reg_array_property, cells, sizeof_cells, cells, sizeof_cells, NULL, permenant_object); hw_free (me, cells); }
char * hw_strdup (struct hw *me, const char *str) { if (str != NULL) { char *dup = hw_zalloc (me, strlen (str) + 1); strcpy (dup, str); return dup; } else { return NULL; } }
static void hw_set_property (struct hw *me, const char *property, hw_property_type type, const void *array, int sizeof_array) { /* find the property */ struct hw_property_data *entry = find_property_data (me, property); if (entry != NULL) { /* existing property - update it */ void *new_array = 0; struct hw_property *value = entry->property; /* check the type matches */ if (value->type != type) hw_abort (me, "conflict between type of new and old value for property %s", property); /* replace its value */ if (value->array != NULL) hw_free (me, (void*)value->array); new_array = (sizeof_array > 0 ? hw_zalloc (me, sizeof_array) : (void*)0); value->array = new_array; value->sizeof_array = sizeof_array; if (sizeof_array > 0) memcpy (new_array, array, sizeof_array); return; } else { /* new property - create it */ hw_add_property (me, property, type, NULL, 0, array, sizeof_array, NULL, temporary_object); } }
void hw_add_string_array_property (struct hw *me, const char *property, const string_property_spec *strings, unsigned nr_strings) { int sizeof_array; int string_nr; char *array; char *chp; if (nr_strings == 0) hw_abort (me, "property \"%s\" must be non-null", property); /* total up the size of the needed array */ for (sizeof_array = 0, string_nr = 0; string_nr < nr_strings; string_nr ++) { sizeof_array += strlen (strings[string_nr]) + 1; } /* create the array */ array = (char*) hw_zalloc (me, sizeof_array); chp = array; for (string_nr = 0; string_nr < nr_strings; string_nr++) { strcpy (chp, strings[string_nr]); chp += strlen (chp) + 1; } ASSERT (chp == array + sizeof_array); /* now enter it */ hw_add_property (me, property, string_array_property, array, sizeof_array, array, sizeof_array, NULL, permenant_object); }