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); }
void delete_hw_alloc_data (struct hw *me) { while (me->alloc_of_hw != NULL) { hw_free (me, me->alloc_of_hw->alloc); } }
int net_free(session_t *session) { if(session->protocol == IP_PROTOCOL_TCP) tcp_close(session); const int err = hw_free(session->session_id); free(session->interface); free(session); return err; }
static void bounce_hw_event (SIM_DESC sd, void *data) { /* save the data */ struct hw_event_data *entry = (struct hw_event_data *) data; struct hw *me = entry->event.me; void *event_data = entry->event.data; hw_event_callback *callback = entry->event.callback; struct hw_event_data **prev = &me->events_of_hw; while ((*prev) != entry) prev = &(*prev)->next; (*prev) = entry->next; hw_free (me, entry); callback (me, event_data); /* may not return */ }
void hw_event_queue_deschedule (struct hw *me, struct hw_event *event_to_remove) { /* ZAP the event but only if it is still in the event queue. Note that event_to_remove is only de-referenced after its validity has been confirmed. */ struct hw_event_data **prev; for (prev = &me->events_of_hw; (*prev) != NULL; prev = &(*prev)->next) { struct hw_event_data *entry = (*prev); if (&entry->event == event_to_remove) { sim_events_deschedule (hw_system (me), entry->event.real); (*prev) = entry->next; hw_free (me, entry); return; } } }
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); } }
static void attach_nvram_regs (struct hw *me, struct nvram *controller) { unsigned_word attach_address; int attach_space; unsigned attach_size; reg_property_spec reg; int result, oerrno; /* Get ram bank description (base and size). */ if (hw_find_property (me, "reg") == NULL) hw_abort (me, "Missing \"reg\" property"); if (!hw_find_reg_array_property (me, "reg", 0, ®)) hw_abort (me, "\"reg\" property must contain one addr/size entry"); hw_unit_address_to_attach_address (hw_parent (me), ®.address, &attach_space, &attach_address, me); hw_unit_size_to_attach_size (hw_parent (me), ®.size, &attach_size, me); hw_attach_address (hw_parent (me), 0, attach_space, attach_address, attach_size, me); controller->mode = NVRAM_SAVE_ALL; controller->base_address = attach_address; controller->size = attach_size; controller->fd = -1; /* Get the file where the ram content must be loaded/saved. */ if(hw_find_property (me, "file") == NULL) hw_abort (me, "Missing \"file\" property"); controller->file_name = hw_find_string_property (me, "file"); /* Get the mode which defines how to save the memory. */ if(hw_find_property (me, "mode") != NULL) { const char *value = hw_find_string_property (me, "mode"); if (strcmp (value, "map") == 0) controller->mode = NVRAM_MAP_FILE; else if (strcmp (value, "save-modified") == 0) controller->mode = NVRAM_SAVE_MODIFIED; else if (strcmp (value, "save-all") == 0) controller->mode = NVRAM_SAVE_ALL; else hw_abort (me, "illegal value for mode parameter `%s': " "use map, save-modified or save-all", value); } /* Initialize the ram by loading/mapping the file in memory. If the file does not exist, create and give it some content. */ switch (controller->mode) { case NVRAM_MAP_FILE: hw_abort (me, "'map' mode is not yet implemented, use 'save-modified'"); break; case NVRAM_SAVE_MODIFIED: case NVRAM_SAVE_ALL: controller->data = (char*) hw_malloc (me, attach_size); if (controller->data == 0) hw_abort (me, "Not enough memory, try to use the mode 'map'"); memset (controller->data, 0, attach_size); controller->fd = open (controller->file_name, O_RDWR); if (controller->fd < 0) { controller->fd = open (controller->file_name, O_RDWR | O_CREAT, 0644); if (controller->fd < 0) hw_abort (me, "Cannot open or create file '%s'", controller->file_name); result = write (controller->fd, controller->data, attach_size); if (result != attach_size) { oerrno = errno; hw_free (me, controller->data); close (controller->fd); errno = oerrno; hw_abort (me, "Failed to save the ram content"); } } else { result = read (controller->fd, controller->data, attach_size); if (result != attach_size) { oerrno = errno; hw_free (me, controller->data); close (controller->fd); errno = oerrno; hw_abort (me, "Failed to load the ram content"); } } if (controller->mode == NVRAM_SAVE_ALL) { close (controller->fd); controller->fd = -1; } break; default: break; } }
int main (int argc, char **argv) { host_callback *cb = ZALLOC (host_callback); struct sim_state *sd = sim_state_alloc (0, cb); struct hw *me = ZALLOC (struct hw); sim_pre_argv_init (sd, "test-hw-events"); sim_post_argv_init (sd); me->system_of_hw = sd; printf ("Create hw-event-data\n"); { create_hw_alloc_data (me); create_hw_event_data (me); delete_hw_event_data (me); delete_hw_alloc_data (me); } printf ("Create hw-events\n"); { struct hw_event *a; struct hw_event *b; struct hw_event *c; struct hw_event *d; create_hw_alloc_data (me); create_hw_event_data (me); a = hw_event_queue_schedule (me, 0, NULL, NULL); b = hw_event_queue_schedule (me, 1, NULL, NULL); c = hw_event_queue_schedule (me, 2, NULL, NULL); d = hw_event_queue_schedule (me, 1, NULL, NULL); hw_event_queue_deschedule (me, c); hw_event_queue_deschedule (me, b); hw_event_queue_deschedule (me, a); hw_event_queue_deschedule (me, d); c = HW_ZALLOC (me, struct hw_event); hw_event_queue_deschedule (me, b); /* OOPS! */ hw_free (me, c); delete_hw_event_data (me); delete_hw_alloc_data (me); } printf ("Schedule hw-events\n"); { struct hw_event **e; int *n; int i; int nr = 4; e = HW_NZALLOC (me, struct hw_event *, nr); n = HW_NZALLOC (me, int, nr); create_hw_alloc_data (me); create_hw_event_data (me); for (i = 0; i < nr; i++) { n[i] = i; e[i] = hw_event_queue_schedule (me, i, test_handler, &n[i]); } sim_events_preprocess (sd, 1, 1); for (i = 0; i < nr; i++) { if (sim_events_tick (sd)) sim_events_process (sd); } for (i = 0; i < nr; i++) { if (n[i] != -i) abort (); hw_event_queue_deschedule (me, e[i]); } hw_free (me, n); hw_free (me, e); delete_hw_event_data (me); delete_hw_alloc_data (me); } return 0; }
void hw_free_debug(void* p) { hw_free(p); }