static unsigned hw_vm_io_write_buffer_callback(device *me, const void *source, int space, unsigned_word addr, unsigned nr_bytes, cpu *processor, unsigned_word cia) { if (hw_vm_add_space(me, addr, nr_bytes, processor, cia) >= nr_bytes) { return device_dma_write_buffer(device_parent(me), source, space, addr, nr_bytes, 0/*violate_read_only*/); } else return 0; }
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); }
/* DMA a file into memory */ static int dma_file(device *me, const char *file_name, unsigned_word addr) { int count; int inc; FILE *image; char buf[1024]; /* get it open */ image = fopen(file_name, "r"); if (image == NULL) return -1; /* read it in slowly */ count = 0; while (1) { inc = fread(buf, 1, sizeof(buf), image); if (inc <= 0) break; if (device_dma_write_buffer(device_parent(me), buf, 0 /*address-space*/, addr+count, inc /*nr-bytes*/, 1 /*violate ro*/) != inc) { fclose(image); return -1; } count += inc; } /* close down again */ fclose(image); return count; }
static void update_for_binary_section(bfd *abfd, asection *the_section, PTR obj) { unsigned_word section_vma; unsigned_word section_size; access_type access; device *me = (device*)obj; /* skip the section if no memory to allocate */ if (! (bfd_get_section_flags(abfd, the_section) & SEC_ALLOC)) return; /* check/ignore any sections of size zero */ section_size = bfd_get_section_size_before_reloc(the_section); if (section_size == 0) return; /* find where it is to go */ section_vma = bfd_get_section_vma(abfd, the_section); DTRACE(binary, ("name=%-7s, vma=0x%.8lx, size=%6ld, flags=%3lx(%s%s%s%s%s )\n", bfd_get_section_name(abfd, the_section), (long)section_vma, (long)section_size, (long)bfd_get_section_flags(abfd, the_section), bfd_get_section_flags(abfd, the_section) & SEC_LOAD ? " LOAD" : "", bfd_get_section_flags(abfd, the_section) & SEC_CODE ? " CODE" : "", bfd_get_section_flags(abfd, the_section) & SEC_DATA ? " DATA" : "", bfd_get_section_flags(abfd, the_section) & SEC_ALLOC ? " ALLOC" : "", bfd_get_section_flags(abfd, the_section) & SEC_READONLY ? " READONLY" : "" )); /* If there is an .interp section, it means it needs a shared library interpreter. */ if (strcmp(".interp", bfd_get_section_name(abfd, the_section)) == 0) error("Shared libraries are not yet supported.\n"); /* determine the devices access */ access = access_read; if (bfd_get_section_flags(abfd, the_section) & SEC_CODE) access |= access_exec; if (!(bfd_get_section_flags(abfd, the_section) & SEC_READONLY)) access |= access_write; /* if claim specified, allocate region from the memory device */ if (device_find_property(me, "claim") != NULL) { device_instance *memory = tree_find_ihandle_property(me, "/chosen/memory"); unsigned_cell mem_in[3]; unsigned_cell mem_out[1]; mem_in[0] = 0; /*alignment - top-of-stack*/ mem_in[1] = section_size; mem_in[2] = section_vma; if (device_instance_call_method(memory, "claim", 3, mem_in, 1, mem_out) < 0) device_error(me, "failed to claim memory for section at 0x%lx (0x%lx", section_vma, section_size); if (mem_out[0] != section_vma) device_error(me, "section address not as requested"); } /* if a map, pass up a request to create the memory in core */ if (strncmp(device_name(me), "map-binary", strlen("map-binary")) == 0) device_attach_address(device_parent(me), attach_raw_memory, 0 /*address space*/, section_vma, section_size, access, me); /* if a load dma in the required data */ if (bfd_get_section_flags(abfd, the_section) & SEC_LOAD) { void *section_init = zalloc(section_size); if (!bfd_get_section_contents(abfd, the_section, section_init, 0, section_size)) { bfd_perror("binary"); device_error(me, "load of data failed"); return; } if (device_dma_write_buffer(device_parent(me), section_init, 0 /*space*/, section_vma, section_size, 1 /*violate_read_only*/) != section_size) device_error(me, "broken transfer\n"); zfree(section_init); /* only free if load */ } }