static void hw_iobus_attach_address_callback(device *me, attach_type type, int space, unsigned_word addr, unsigned nr_bytes, access_type access, device *client) /*callback/default*/ { int attach_space; unsigned_word attach_address; /* sanity check */ if (space != 0) device_error(me, "invalid space (%d) specified by %s", space, device_path(client)); /* get the bus address */ device_address_to_attach_address(device_parent(me), device_unit_address(me), &attach_space, &attach_address, me); if (addr < attach_address) device_error(me, "Invalid attach address 0x%lx", (unsigned long)addr); device_attach_address(device_parent(me), type, attach_space, addr, nr_bytes, access, client); }
static void hw_disk_init_address(device *me) { hw_disk_device *disk = device_data(me); unsigned_word address; int space; const char *name; /* attach to the parent. Since the bus is logical, attach using just the unit-address (size must be zero) */ device_address_to_attach_address(device_parent(me), device_unit_address(me), &space, &address, me); device_attach_address(device_parent(me), attach_callback, space, address, 0/*size*/, access_read_write_exec, me); /* Tell the world we are a disk. */ device_add_string_property(me, "device_type", "block"); /* get the name of the file specifying the disk image */ disk->name_index = 0; disk->nr_names = device_find_string_array_property(me, "file", disk->name_index, &name); if (!disk->nr_names) device_error(me, "invalid file property"); /* is it a RO device? */ disk->read_only = (strcmp(device_name(me), "disk") != 0 && strcmp(device_name(me), "floppy") != 0 && device_find_property(me, "read-only") == NULL); /* now open it */ open_disk_image(me, disk, name); }
static unsigned hw_vm_add_space(device *me, unsigned_word addr, unsigned nr_bytes, cpu *processor, unsigned_word cia) { hw_vm_device *vm = (hw_vm_device*)device_data(me); unsigned_word block_addr; unsigned block_nr_bytes; /* an address in the stack area, allocate just down to the addressed page */ if (addr >= vm->stack_base && addr < vm->stack_lower_limit) { block_addr = FLOOR_PAGE(addr); block_nr_bytes = vm->stack_lower_limit - block_addr; vm->stack_lower_limit = block_addr; } /* an address in the heap area, allocate all of the required heap */ else if (addr >= vm->heap_upper_limit && addr < vm->heap_bound) { block_addr = vm->heap_upper_limit; block_nr_bytes = vm->heap_bound - vm->heap_upper_limit; vm->heap_upper_limit = vm->heap_bound; } /* oops - an invalid address - abort the cpu */ else if (processor != NULL) { cpu_halt(processor, cia, was_signalled, SIGSEGV); return 0; } /* 2*oops - an invalid address and no processor */ else { return 0; } /* got the parameters, allocate the space */ device_attach_address(device_parent(me), attach_raw_memory, 0 /*address space*/, block_addr, block_nr_bytes, access_read_write, me); return block_nr_bytes; }
static void hw_vm_init_address_callback(device *me) { hw_vm_device *vm = (hw_vm_device*)device_data(me); /* revert the stack/heap variables to their defaults */ vm->stack_base = device_find_integer_property(me, "stack-base"); vm->stack_bound = (vm->stack_base + device_find_integer_property(me, "nr-bytes")); vm->stack_lower_limit = vm->stack_bound; vm->heap_base = 0; vm->heap_bound = 0; vm->heap_upper_limit = 0; /* establish this device as the default memory handler */ device_attach_address(device_parent(me), attach_callback + 1, 0 /*address space - ignore*/, 0 /*addr - ignore*/, (((unsigned)0)-1) /*nr_bytes - ignore*/, access_read_write /*access*/, me); }
static void hw_vm_attach_address(device *me, attach_type attach, int space, unsigned_word addr, unsigned nr_bytes, access_type access, device *client) /*callback/default*/ { hw_vm_device *vm = (hw_vm_device*)device_data(me); /* update end of bss if necessary */ if (vm->heap_base < addr + nr_bytes) { vm->heap_base = addr + nr_bytes; vm->heap_bound = addr + nr_bytes; vm->heap_upper_limit = addr + nr_bytes; } device_attach_address(device_parent(me), attach_raw_memory, 0 /*address space*/, addr, nr_bytes, access, me); }
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 */ } }