示例#1
0
文件: emul_generic.c 项目: 5kg/gdb
INLINE_EMUL_GENERIC void
emul_add_tree_hardware(device *root)
{
  int i;
  int nr_cpus = tree_find_integer_property(root, "/openprom/options/smp");

  /* sanity check the number of processors */
  if (nr_cpus > MAX_NR_PROCESSORS)
    error("Specified number of processors (%d) exceeds the number configured (%d).\n",
	  nr_cpus, MAX_NR_PROCESSORS);

  /* set the number of address cells (1 or 2) */
  tree_parse(root, "#address-cells %d", WITH_TARGET_WORD_BITSIZE / 32);

  /* add some memory */
  if (tree_find_device(root, "/memory") == NULL) {
    unsigned_word memory_size =
      tree_find_integer_property(root, "/openprom/options/oea-memory-size");
    const unsigned_word avail_start = 0x3000;
    tree_parse(root, "/memory@0/reg 0x0 0x%lx",
	       (unsigned long)memory_size);
    /* reserve the first 0x3000 for the PowerPC interrupt table */
    tree_parse(root, "/memory@0/available 0x%lx  0x%lx",
	       (unsigned long)avail_start,
	       (unsigned long)memory_size - avail_start);
  }

  /* our processors */
  for (i = 0; i < nr_cpus; i++) {
    tree_parse(root, "/cpus/cpu@%d/cpu-nr %d", i, i);
  }

  /* the debugging pal - hide it in the openprom and don't attach it
     to any bus */
  tree_parse(root, "/openprom/pal");

  /* chosen etc */
  tree_parse(root, "/chosen/stdin */openprom/pal");
  tree_parse(root, "/chosen/stdout !/chosen/stdin");
  tree_parse(root, "/chosen/memory */memory");
}
示例#2
0
文件: hw_pal.c 项目: 5kg/gdb
static unsigned
hw_pal_io_read_buffer_callback(device *me,
			       void *dest,
			       int space,
			       unsigned_word addr,
			       unsigned nr_bytes,
			       cpu *processor,
			       unsigned_word cia)
{
  hw_pal_device *hw_pal = (hw_pal_device*)device_data(me);
  unsigned_1 val;
  switch (addr & hw_pal_address_mask) {
  case hw_pal_cpu_nr_register:
    val = cpu_nr(processor);
    DTRACE(pal, ("read - cpu-nr %d\n", val));
    break;
  case hw_pal_nr_cpu_register:
    val = tree_find_integer_property(me, "/openprom/options/smp");
    DTRACE(pal, ("read - nr-cpu %d\n", val));
    break;
  case hw_pal_read_fifo:
    val = hw_pal->input.buffer;
    DTRACE(pal, ("read - input-fifo %d\n", val));
    break;
  case hw_pal_read_status:
    scan_hw_pal(hw_pal);
    val = hw_pal->input.status;
    DTRACE(pal, ("read - input-status %d\n", val));
    break;
  case hw_pal_write_fifo:
    val = hw_pal->output.buffer;
    DTRACE(pal, ("read - output-fifo %d\n", val));
    break;
  case hw_pal_write_status:
    val = hw_pal->output.status;
    DTRACE(pal, ("read - output-status %d\n", val));
    break;
  default:
    val = 0;
    DTRACE(pal, ("read - ???\n"));
  }
  memset(dest, 0, nr_bytes);
  *(unsigned_1*)dest = val;
  return nr_bytes;
}
示例#3
0
psim_init(psim *system)
{
    int cpu_nr;

    /* scrub the monitor */
    mon_init(system->monitor, system->nr_cpus);

    /* trash any pending events */
    event_queue_init(system->events);

    /* if needed, schedule a halt event.  FIXME - In the future this
       will be replaced by a more generic change to psim_command().  A
       new command `schedule NNN halt' being added. */
    if (tree_find_property(system->devices, "/openprom/options/max-iterations")) {
        event_queue_schedule(system->events,
                             tree_find_integer_property(system->devices,
                                     "/openprom/options/max-iterations") - 2,
                             psim_max_iterations_exceeded,
                             system);
    }

    /* scrub all the cpus */
    for (cpu_nr = 0; cpu_nr < system->nr_cpus; cpu_nr++)
        cpu_init(system->processors[cpu_nr]);

    /* init all the devices (which updates the cpus) */
    tree_init(system->devices, system);

    /* and the emulation (which needs an initialized device tree) */
    os_emul_init(system->os_emulation, system->nr_cpus);

    /* now sync each cpu against the initialized state of its registers */
    for (cpu_nr = 0; cpu_nr < system->nr_cpus; cpu_nr++) {
        cpu *processor = system->processors[cpu_nr];
        cpu_synchronize_context(processor, cpu_get_program_counter(processor));
        cpu_page_tlb_invalidate_all(processor);
    }

    /* force loop to start with first cpu */
    system->last_cpu = -1;
}
static os_emul_data *
emul_bugapi_create(device *root,
		   bfd *image,
		   const char *name)
{
  device *node;
  os_emul_data *bugapi;
  char *filename;

  /* check it really is for us */
  if (name != NULL
      && strcmp(name, "bugapi") != 0
      && strcmp(name, "bug") != 0)
    return NULL;
  if (image != NULL
      && name == NULL
      && bfd_get_start_address(image) >= BUGAPI_END_ADDRESS)
    return NULL;

  bugapi = ZALLOC(os_emul_data);

  /* options */
  emul_add_tree_options(root, image, "bug", "oea",
			1 /*oea-interrupt-prefix*/);

  /* add some real hardware, include eeprom memory for the eeprom trap
     addresses */
  emul_add_tree_hardware(root);
  node = tree_parse(root, "/openprom/memory@0xfff00000");
  tree_parse(node, "./psim,description \"eeprom trap addresses");
  tree_parse(node, "./reg 0xfff00000 0x3000");

  bugapi->root = root;

  bugapi->memory_size
    = tree_find_integer_property(root, "/openprom/options/oea-memory-size");
  bugapi->interrupt_prefix =
    tree_find_integer_property(root, "/openprom/options/oea-interrupt-prefix");
  bugapi->interrupt_vector_address = (bugapi->interrupt_prefix
				      ? MASK(0, 43)
				      : 0);
  bugapi->system_call_address = (bugapi->interrupt_vector_address + 0x00c00);
  bugapi->stall_cpu_loop_address = (bugapi->system_call_address + 0x000f0);
  bugapi->top_of_stack = bugapi->memory_size - 0x1000;
  bugapi->little_endian
    = tree_find_boolean_property(root, "/options/little-endian?");
  bugapi->floating_point_available
    = tree_find_boolean_property(root, "/openprom/options/floating-point?");
  bugapi->input = NULL;
  bugapi->output = NULL;

  /* initialization */
  if (image != NULL)
    tree_parse(root, "/openprom/init/register/0.pc 0x%lx",
	       (unsigned long)bfd_get_start_address(image));
  tree_parse(root, "/openprom/init/register/pc 0x%lx",
	     (unsigned long)bugapi->stall_cpu_loop_address);
  tree_parse(root, "/openprom/init/register/sp 0x%lx",
	     (unsigned long)(bugapi->top_of_stack - 16));
  tree_parse(root, "/openprom/init/register/msr 0x%x",
	     (msr_recoverable_interrupt
	      | (bugapi->little_endian
		 ? (msr_little_endian_mode
		    | msr_interrupt_little_endian_mode)
		 : 0)
	      | (bugapi->floating_point_available
		 ? msr_floating_point_available
		 : 0)
	      | (bugapi->interrupt_prefix
		 ? msr_interrupt_prefix
		 : 0)
	      ));

  /* patch the system call instruction to call this emulation and then
     do an rfi */
  node = tree_parse(root, "/openprom/init/data@0x%lx",
		    (unsigned long)bugapi->system_call_address);
  tree_parse(node, "./psim,description \"system-call trap instruction");
  tree_parse(node, "./real-address 0x%lx",
	     (unsigned long)bugapi->system_call_address);
  tree_parse(node, "./data 0x%x", emul_call_instruction);
  node = tree_parse(root, "/openprom/init/data@0x%lx",
		    (unsigned long)bugapi->system_call_address + 4);
  tree_parse(node, "./psim,description \"return from interrupt instruction");
  tree_parse(node, "./real-address 0x%lx",
	     (unsigned long)bugapi->system_call_address + 4);
  tree_parse(node, "./data 0x%x",
	     emul_rfi_instruction);

  /* patch the end of the system call instruction so that it contains
     a loop to self instruction and point all the cpu's at this */
  node = tree_parse(root, "/openprom/init/data@0x%lx",
		    (unsigned long)bugapi->stall_cpu_loop_address);
  tree_parse(node, "./psim,description \"cpu-loop instruction");
  tree_parse(node, "./real-address 0x%lx",
	     (unsigned long)bugapi->stall_cpu_loop_address);
  tree_parse(node, "./data 0x%lx",
	     (unsigned long)emul_loop_instruction);

  if (image != NULL)
    tree_parse(root, "/openprom/init/stack/stack-type %s",
	       (image->xvec->flavour == bfd_target_elf_flavour
		? "ppc-elf"
		: "ppc-xcoff"));

  if (image != NULL)
    {
      filename = tree_quote_property (bfd_get_filename(image));
      tree_parse(root, "/openprom/init/load-binary/file-name %s",
		 filename);
      free (filename);
    }

  return bugapi;
}
示例#5
0
psim_create(const char *file_name,
            device *root)
{
    int cpu_nr;
    const char *env;
    psim *system;
    os_emul *os_emulation;
    int nr_cpus;

    /* given this partially populated device tree, os_emul_create() uses
       it and file_name to determine the selected emulation and hence
       further populate the tree with any other required nodes. */

    os_emulation = os_emul_create(file_name, root);
    if (os_emulation == NULL)
        error("psim: either file %s was not reconized or unreconized or unknown os-emulation type\n", file_name);

    /* fill in the missing real number of CPU's */
    nr_cpus = tree_find_integer_property(root, "/openprom/options/smp");
    if (MAX_NR_PROCESSORS < nr_cpus)
        error("target and configured number of cpus conflict\n");

    /* fill in the missing TARGET BYTE ORDER information */
    current_target_byte_order
        = (tree_find_boolean_property(root, "/options/little-endian?")
           ? LITTLE_ENDIAN
           : BIG_ENDIAN);
    if (CURRENT_TARGET_BYTE_ORDER != current_target_byte_order)
        error("target and configured byte order conflict\n");

    /* fill in the missing HOST BYTE ORDER information */
    current_host_byte_order = (current_host_byte_order = 1,
                               (*(char*)(&current_host_byte_order)
                                ? LITTLE_ENDIAN
                                : BIG_ENDIAN));
    if (CURRENT_HOST_BYTE_ORDER != current_host_byte_order)
        error("host and configured byte order conflict\n");

    /* fill in the missing OEA/VEA information */
    env = tree_find_string_property(root, "/openprom/options/env");
    current_environment = ((strcmp(env, "user") == 0
                            || strcmp(env, "uea") == 0)
                           ? USER_ENVIRONMENT
                           : (strcmp(env, "virtual") == 0
                              || strcmp(env, "vea") == 0)
                           ? VIRTUAL_ENVIRONMENT
                           : (strcmp(env, "operating") == 0
                              || strcmp(env, "oea") == 0)
                           ? OPERATING_ENVIRONMENT
                           : 0);
    if (current_environment == 0)
        error("unreconized /options env property\n");
    if (CURRENT_ENVIRONMENT != current_environment)
        error("target and configured environment conflict\n");

    /* fill in the missing ALLIGNMENT information */
    current_alignment
        = (tree_find_boolean_property(root, "/openprom/options/strict-alignment?")
           ? STRICT_ALIGNMENT
           : NONSTRICT_ALIGNMENT);
    if (CURRENT_ALIGNMENT != current_alignment)
        error("target and configured alignment conflict\n");

    /* fill in the missing FLOATING POINT information */
    current_floating_point
        = (tree_find_boolean_property(root, "/openprom/options/floating-point?")
           ? HARD_FLOATING_POINT
           : SOFT_FLOATING_POINT);
    if (CURRENT_FLOATING_POINT != current_floating_point)
        error("target and configured floating-point conflict\n");

    /* fill in the missing STDIO information */
    current_stdio
        = (tree_find_boolean_property(root, "/openprom/options/use-stdio?")
           ? DO_USE_STDIO
           : DONT_USE_STDIO);
    if (CURRENT_STDIO != current_stdio)
        error("target and configured stdio interface conflict\n");

    /* sort out the level of detail for issue modeling */
    current_model_issue
        = tree_find_integer_property(root, "/openprom/options/model-issue");
    if (CURRENT_MODEL_ISSUE != current_model_issue)
        error("target and configured model-issue conflict\n");

    /* sort out our model architecture - wrong.

       FIXME: this should be obtaining the required information from the
       device tree via the "/chosen" property "cpu" which is an instance
       (ihandle) for the only executing processor. By converting that
       ihandle into the corresponding cpu's phandle and then querying
       the "name" property, the cpu type can be determined. Ok? */

    model_set(tree_find_string_property(root, "/openprom/options/model"));

    /* create things */
    system = ZALLOC(psim);
    system->events = event_queue_create();
    system->memory = core_from_device(root);
    system->monitor = mon_create();
    system->nr_cpus = nr_cpus;
    system->os_emulation = os_emulation;
    system->devices = root;

    /* now all the processors attaching to each their per-cpu information */
    for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; cpu_nr++) {
        system->processors[cpu_nr] = cpu_create(system,
                                                system->memory,
                                                mon_cpu(system->monitor,
                                                        cpu_nr),
                                                system->os_emulation,
                                                cpu_nr);
    }

    /* dump out the contents of the device tree */
    if (ppc_trace[trace_print_device_tree] || ppc_trace[trace_dump_device_tree])
        tree_print(root);
    if (ppc_trace[trace_dump_device_tree])
        error("");

    return system;
}