Exemplo n.º 1
0
SIM_RC
sim_config (SIM_DESC sd)
{
  enum bfd_endian prefered_target_byte_order;
  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);

  /* extract all relevant information */
  if (STATE_PROG_BFD (sd) == NULL
      /* If we have a binary input file (presumably with specified
	 "--architecture"), it'll have no endianness.  */
      || (!bfd_little_endian (STATE_PROG_BFD (sd))
	  && !bfd_big_endian (STATE_PROG_BFD (sd))))
    prefered_target_byte_order = BFD_ENDIAN_UNKNOWN;
  else
    prefered_target_byte_order = (bfd_little_endian (STATE_PROG_BFD (sd))
				  ? BFD_ENDIAN_LITTLE
				  : BFD_ENDIAN_BIG);

  /* set the target byte order */
#if (WITH_TREE_PROPERTIES)
  if (current_target_byte_order == BFD_ENDIAN_UNKNOWN)
    current_target_byte_order
      = (tree_find_boolean_property (root, "/options/little-endian?")
	 ? BFD_ENDIAN_LITTLE
	 : BFD_ENDIAN_BIG);
#endif
  if (current_target_byte_order == BFD_ENDIAN_UNKNOWN
      && prefered_target_byte_order != BFD_ENDIAN_UNKNOWN)
    current_target_byte_order = prefered_target_byte_order;
  if (current_target_byte_order == BFD_ENDIAN_UNKNOWN)
    current_target_byte_order = WITH_TARGET_BYTE_ORDER;
  if (current_target_byte_order == BFD_ENDIAN_UNKNOWN)
    current_target_byte_order = WITH_DEFAULT_TARGET_BYTE_ORDER;

  /* verify the target byte order */
  if (CURRENT_TARGET_BYTE_ORDER == BFD_ENDIAN_UNKNOWN)
    {
      sim_io_eprintf (sd, "Target byte order unspecified\n");
      return SIM_RC_FAIL;
    }
  if (CURRENT_TARGET_BYTE_ORDER != current_target_byte_order)
    sim_io_eprintf (sd, "Target (%s) and configured (%s) byte order in conflict\n",
		  config_byte_order_to_a (current_target_byte_order),
		  config_byte_order_to_a (CURRENT_TARGET_BYTE_ORDER));
  if (prefered_target_byte_order != BFD_ENDIAN_UNKNOWN
      && CURRENT_TARGET_BYTE_ORDER != prefered_target_byte_order)
    sim_io_eprintf (sd, "Target (%s) and specified (%s) byte order in conflict\n",
		  config_byte_order_to_a (CURRENT_TARGET_BYTE_ORDER),
		  config_byte_order_to_a (prefered_target_byte_order));


  /* set the stdio */
  if (current_stdio == 0)
    current_stdio = WITH_STDIO;
  if (current_stdio == 0)
    current_stdio = DO_USE_STDIO;

  /* verify the stdio */
  if (CURRENT_STDIO == 0)
    {
      sim_io_eprintf (sd, "Target standard IO unspecified\n");
      return SIM_RC_FAIL;
    }
  if (CURRENT_STDIO != current_stdio)
    {
      sim_io_eprintf (sd, "Target (%s) and configured (%s) standard IO in conflict\n",
		      config_stdio_to_a (CURRENT_STDIO),
		      config_stdio_to_a (current_stdio));
      return SIM_RC_FAIL;
    }


  /* check the value of MSB */
  if (WITH_TARGET_WORD_MSB != 0
      && WITH_TARGET_WORD_MSB != (WITH_TARGET_WORD_BITSIZE - 1))
    {
      sim_io_eprintf (sd, "Target bitsize (%d) contradicts target most significant bit (%d)\n",
		      WITH_TARGET_WORD_BITSIZE, WITH_TARGET_WORD_MSB);
      return SIM_RC_FAIL;
    }


  /* set the environment */
#if (WITH_TREE_PROPERTIES)
  if (STATE_ENVIRONMENT (sd) == ALL_ENVIRONMENT)
    {
      const char *env =
	tree_find_string_property (root, "/openprom/options/env");
      STATE_ENVIRONMENT (sd) = ((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
				: ALL_ENVIRONMENT);
    }
#endif
  if (STATE_ENVIRONMENT (sd) == ALL_ENVIRONMENT)
    STATE_ENVIRONMENT (sd) = (WITH_ENVIRONMENT != ALL_ENVIRONMENT ?
			      WITH_ENVIRONMENT : USER_ENVIRONMENT);


  /* set the alignment */
#if (WITH_TREE_PROPERTIES)
  if (current_alignment == 0)
    current_alignment =
      (tree_find_boolean_property (root, "/openprom/options/strict-alignment?")
       ? STRICT_ALIGNMENT
       : NONSTRICT_ALIGNMENT);
#endif
  if (current_alignment == 0)
    current_alignment = WITH_ALIGNMENT;
  if (current_alignment == 0)
    current_alignment = WITH_DEFAULT_ALIGNMENT;

  /* verify the alignment */
  if (CURRENT_ALIGNMENT == 0)
    {
      sim_io_eprintf (sd, "Target alignment unspecified\n");
      return SIM_RC_FAIL;
    }
  if (CURRENT_ALIGNMENT != current_alignment)
    {
      sim_io_eprintf (sd, "Target (%s) and configured (%s) alignment in conflict\n",
		      config_alignment_to_a (CURRENT_ALIGNMENT),
		      config_alignment_to_a (current_alignment));
      return SIM_RC_FAIL;
    }

#if defined (WITH_FLOATING_POINT)

  /* set the floating point */
  if (current_floating_point == 0)
    current_floating_point = WITH_FLOATING_POINT;

  /* verify the floating point */
  if (CURRENT_FLOATING_POINT == 0)
    {
      sim_io_eprintf (sd, "Target floating-point unspecified\n");
      return SIM_RC_FAIL;
    }
  if (CURRENT_FLOATING_POINT != current_floating_point)
    {
      sim_io_eprintf (sd, "Target (%s) and configured (%s) floating-point in conflict\n",
		      config_alignment_to_a (CURRENT_FLOATING_POINT),
		      config_alignment_to_a (current_floating_point));
      return SIM_RC_FAIL;
    }

#endif
  return SIM_RC_OK;
}
Exemplo n.º 2
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;
}