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);
}
Beispiel #2
0
Datei: hw_disk.c Projekt: 5kg/gdb
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);
}
Beispiel #3
0
Datei: hw_vm.c Projekt: 5kg/gdb
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;
}
Beispiel #4
0
Datei: hw_vm.c Projekt: 5kg/gdb
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);
}
Beispiel #5
0
Datei: hw_vm.c Projekt: 5kg/gdb
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);
}
Beispiel #6
0
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 */
  }
}