static void hw_eeprom_init_data(device *me) { hw_eeprom_device *eeprom = (hw_eeprom_device*)device_data(me); /* have we any input or output files */ if (device_find_property(me, "input-file") != NULL) eeprom->input_file_name = device_find_string_property(me, "input-file"); if (device_find_property(me, "output-file") != NULL) eeprom->input_file_name = device_find_string_property(me, "output-file"); /* figure out the sectors in the eeprom */ if (eeprom->sectors == NULL) { eeprom->nr_sectors = device_find_integer_property(me, "nr-sectors"); eeprom->sizeof_sector = device_find_integer_property(me, "sector-size"); eeprom->sectors = zalloc(eeprom->nr_sectors); } else memset(eeprom->sectors, 0, eeprom->nr_sectors); /* initialize the eeprom */ if (eeprom->memory == NULL) { eeprom->sizeof_memory = eeprom->sizeof_sector * eeprom->nr_sectors; eeprom->memory = zalloc(eeprom->sizeof_memory); } else memset(eeprom->memory, 0, eeprom->sizeof_memory); if (eeprom->input_file_name != NULL) { int i; FILE *input_file = fopen(eeprom->input_file_name, "r"); if (input_file == NULL) { perror("eeprom"); device_error(me, "Failed to open input file %s\n", eeprom->input_file_name); } for (i = 0; i < eeprom->sizeof_memory; i++) { if (fread(&eeprom->memory[i], 1, 1, input_file) != 1) break; } fclose(input_file); } /* timing */ eeprom->byte_write_delay = device_find_integer_property(me, "byte-write-delay"); eeprom->sector_start_delay = device_find_integer_property(me, "sector-start-delay"); eeprom->erase_delay = device_find_integer_property(me, "erase-delay"); /* misc */ eeprom->manufacture_code = device_find_integer_property(me, "manufacture-code"); eeprom->device_code = device_find_integer_property(me, "device-code"); }
static void hw_com_device_init_data(device *me) { hw_com_device *com = (hw_com_device*)device_data(me); /* clean up */ if (com->output.file != NULL) fclose(com->output.file); if (com->input.file != NULL) fclose(com->input.file); memset(com, 0, sizeof(hw_com_device)); /* the fifo speed */ com->output.delay = (device_find_property(me, "output-delay") != NULL ? device_find_integer_property(me, "output-delay") : 0); com->input.delay = (device_find_property(me, "input-delay") != NULL ? device_find_integer_property(me, "input-delay") : 0); /* the data source/sink */ if (device_find_property(me, "input-file") != NULL) { const char *input_file = device_find_string_property(me, "input-file"); com->input.file = fopen(input_file, "r"); if (com->input.file == NULL) device_error(me, "Problem opening input file %s\n", input_file); if (device_find_property(me, "input-buffering") != NULL) { const char *buffering = device_find_string_property(me, "input-buffering"); if (strcmp(buffering, "unbuffered") == 0) setbuf(com->input.file, NULL); } } if (device_find_property(me, "output-file") != NULL) { const char *output_file = device_find_string_property(me, "output-file"); com->output.file = fopen(output_file, "w"); if (com->output.file == NULL) device_error(me, "Problem opening output file %s\n", output_file); if (device_find_property(me, "output-buffering") != NULL) { const char *buffering = device_find_string_property(me, "output-buffering"); if (strcmp(buffering, "unbuffered") == 0) setbuf(com->output.file, NULL); } } /* ready from the start */ com->input.ready = 1; com->modem.carrier = 1; com->output.ready = 1; }
static void hw_binary_init_data_callback(device *me) { /* get the file name */ const char *file_name = device_find_string_property(me, "file-name"); bfd *image; /* open the file */ image = bfd_openr(file_name, NULL); if (image == NULL) { bfd_perror("binary"); device_error(me, "Failed to open file %s\n", file_name); } /* check it is valid */ if (!bfd_check_format(image, bfd_object)) { bfd_close(image); device_error(me, "The file %s has an invalid binary format\n", file_name); } /* and the data sections */ bfd_map_over_sections(image, update_for_binary_section, (PTR)me); bfd_close(image); }
tree_find_string_property(device *root, const char *path_to_property) { name_specifier spec; if (!split_property_specifier(root, path_to_property, &spec)) device_error(root, "Invalid property path %s", path_to_property); root = split_find_device(root, &spec); return device_find_string_property(root, spec.property); }
static void hw_file_init_data_callback(device *me) { int count; const char *file_name = device_find_string_property(me, "file-name"); unsigned_word addr = device_find_integer_property(me, "real-address"); /* load the file */ count = dma_file(me, file_name, addr); if (count < 0) device_error(me, "Problem loading file %s\n", file_name); }
static void hw_data_init_data_callback(device *me) { unsigned_word addr = device_find_integer_property(me, "real-address"); const device_property *data = device_find_property(me, "data"); const char *instance_spec = (device_find_property(me, "instance") != NULL ? device_find_string_property(me, "instance") : NULL); device_instance *instance = NULL; if (data == NULL) device_error(me, "missing property <data>\n"); if (instance_spec != NULL) instance = tree_instance(me, instance_spec); switch (data->type) { case integer_property: { unsigned_cell buf = device_find_integer_property(me, "data"); H2T(buf); if (instance == NULL) { if (device_dma_write_buffer(device_parent(me), &buf, 0 /*address-space*/, addr, sizeof(buf), /*nr-bytes*/ 1 /*violate ro*/) != sizeof(buf)) device_error(me, "Problem storing integer 0x%x at 0x%lx\n", (unsigned)buf, (unsigned long)addr); } else { if (device_instance_seek(instance, 0, addr) < 0 || device_instance_write(instance, &buf, sizeof(buf)) != sizeof(buf)) device_error(me, "Problem storing integer 0x%x at 0x%lx of instance %s\n", (unsigned)buf, (unsigned long)addr, instance_spec); } } break; default: device_error(me, "Write of this data is not yet implemented\n"); break; } if (instance != NULL) device_instance_delete(instance); }
static int hw_stack_ioctl(device *me, cpu *processor, unsigned_word cia, device_ioctl_request request, va_list ap) { switch (request) { case device_ioctl_create_stack: { unsigned_word stack_pointer = va_arg(ap, unsigned_word); char **argv = va_arg(ap, char **); char **envp = va_arg(ap, char **); const char *stack_type; DTRACE(stack, ("stack_ioctl_callback(me=0x%lx:%s processor=0x%lx cia=0x%lx argv=0x%lx envp=0x%lx)\n", (long)me, device_name(me), (long)processor, (long)cia, (long)argv, (long)envp)); stack_type = device_find_string_property(me, "stack-type"); if (strcmp(stack_type, "ppc-elf") == 0) create_ppc_elf_stack_frame(me, stack_pointer, argv, envp); else if (strcmp(stack_type, "ppc-xcoff") == 0) create_ppc_aix_stack_frame(me, stack_pointer, argv, envp); else if (strcmp(stack_type, "chirp") == 0) create_ppc_chirp_bootargs(me, argv); else if (strcmp(stack_type, "none") != 0) device_error(me, "Unknown initial stack frame type %s", stack_type); DTRACE(stack, ("stack_ioctl_callback() = void\n")); break; } default: device_error(me, "Unsupported ioctl requested"); break; } return 0; }
print_properties(device *me) { const device_property *property; for (property = device_find_property(me, NULL); property != NULL; property = device_next_property(property)) { printf_filtered("%s/%s", device_path(me), property->name); if (property->original != NULL) { printf_filtered(" !"); printf_filtered("%s/%s", device_path(property->original->owner), property->original->name); } else { switch (property->type) { case array_property: if ((property->sizeof_array % sizeof(signed_cell)) == 0) { unsigned_cell *w = (unsigned_cell*)property->array; int cell_nr; for (cell_nr = 0; cell_nr < (property->sizeof_array / sizeof(unsigned_cell)); cell_nr++) { printf_filtered(" 0x%lx", (unsigned long)BE2H_cell(w[cell_nr])); } } else { unsigned8 *w = (unsigned8*)property->array; printf_filtered(" ["); while ((char*)w - (char*)property->array < property->sizeof_array) { printf_filtered(" 0x%2x", BE2H_1(*w)); w++; } } break; case boolean_property: { int b = device_find_boolean_property(me, property->name); printf_filtered(" %s", b ? "true" : "false"); } break; case ihandle_property: { if (property->array != NULL) { device_instance *instance = device_find_ihandle_property(me, property->name); printf_filtered(" *%s", device_instance_path(instance)); } else { /* not yet initialized, ask the device for the path */ ihandle_runtime_property_spec spec; device_find_ihandle_runtime_property(me, property->name, &spec); printf_filtered(" *%s", spec.full_path); } } break; case integer_property: { unsigned_word w = device_find_integer_property(me, property->name); printf_filtered(" 0x%lx", (unsigned long)w); } break; case range_array_property: print_ranges_property(me, property); break; case reg_array_property: print_reg_property(me, property); break; case string_property: { const char *s = device_find_string_property(me, property->name); print_string(s); } break; case string_array_property: print_string_array_property(me, property); break; } } printf_filtered("\n"); } }
split_device_specifier(device *current, const char *device_specifier, name_specifier *spec) { char *chp = NULL; /* expand any leading alias if present */ if (current != NULL && *device_specifier != '\0' && *device_specifier != '.' && *device_specifier != '/') { device *aliases = tree_find_device(current, "/aliases"); char alias[32]; int len = 0; while (device_specifier[len] != '\0' && device_specifier[len] != '/' && device_specifier[len] != ':' && !isspace(device_specifier[len])) { alias[len] = device_specifier[len]; len++; if (len >= sizeof(alias)) error("split_device_specifier: buffer overflow"); } alias[len] = '\0'; if (aliases != NULL && device_find_property(aliases, alias)) { strcpy(spec->buf, device_find_string_property(aliases, alias)); strcat(spec->buf, device_specifier + len); } else { strcpy(spec->buf, device_specifier); } } else { strcpy(spec->buf, device_specifier); } /* check no overflow */ if (strlen(spec->buf) >= sizeof(spec->buf)) error("split_device_specifier: buffer overflow\n"); /* strip leading spaces */ chp = spec->buf; 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)) chp++; if (*chp != '\0') { *chp = '\0'; chp++; } /* and any value */ 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') { spec->property = NULL; /*not a property*/ spec->value = NULL; } else if (spec->value[0] == '>' || spec->value[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; } } /* and mark the rest as invalid */ spec->name = NULL; spec->base = NULL; spec->unit = NULL; spec->args = NULL; spec->last_name = NULL; spec->last_base = NULL; spec->last_unit = NULL; spec->last_args = NULL; return 1; }