/* ------------------------------------------------------------------------- */ SIM_DESC sim_open (SIM_OPEN_KIND kind, struct host_callback_struct *callback, struct bfd *abfd, char *argv[]) { /*!A global record of the simulator description */ static SIM_DESC static_sd = NULL; #ifdef OR32_SIM_DEBUG printf ("sim_open called\n", (int) kind); #endif /* If static_sd is not yet allocated, we allocate it and mark the simulator as not yet open. This is the only time we can process any custom arguments and only time we initialize the simulator. */ if (NULL == static_sd) { int local_argc; /* Our local argv with extra args */ char **local_argv; int argc; /* How many args originally */ int i, j; /* For local argv */ int mem_defined_p = 0; /* Have we requested a memory size? */ int sysroot_defined_p = 0; /* Have we requested --sysroot ?*/ int res; /* Result of initialization */ static_sd = (SIM_DESC) malloc (sizeof (*static_sd)); static_sd->sim_open = 0; /* Count the number of arguments and see if we have specified either a config file or a memory size. */ for (argc = 1; NULL != argv[argc]; argc++) { #ifdef OR32_SIM_DEBUG printf ("argv[%d] = %s\n", argc, argv[argc]); #endif if ((0 == strcmp (argv[argc], "-f")) || (0 == strcmp (argv[argc], "-file")) || (0 == strcmp (argv[argc], "-m")) || (0 == strcmp (argv[argc], "-memory"))) { mem_defined_p = 1; } if (0 == strncmp (argv[argc], "--sysroot", 9)) sysroot_defined_p = argc; } /* If we have no memory defined, we give it a default 8MB. We also always run quiet. So we must define our own argument vector */ local_argc = mem_defined_p ? argc + 1 : argc + 3; /* We don't support --sysroot argument, so if we asked, remove it from the list. */ local_argc = sysroot_defined_p ? local_argc - 1 : local_argc; local_argv = malloc ((local_argc + 1) * sizeof (char *)); j = 0; for (i = 0 ; i < argc; i++) { if (i != sysroot_defined_p) local_argv[j++] = argv[i]; } local_argv[j++] = "--quiet"; if (!mem_defined_p) { local_argv[j++] = "--memory"; local_argv[j++] = "8M"; } local_argv[j] = NULL; /* Try to initialize, then we can free the local argument vector. If we fail to initialize return NULL to indicate that failure. */ res = or1ksim_init (local_argc, local_argv, NULL, NULL, NULL); free (local_argv); if (res) { return NULL; /* Failure */ } } /* We have either initialized a new simulator, or already have an intialized simulator. Populate the descriptor and stall the processor, the return the descriptor. */ static_sd->callback = callback; static_sd->is_debug = (kind == SIM_OPEN_DEBUG); static_sd->myname = (char *)xstrdup (argv[0]); static_sd->sim_open = 1; static_sd->last_reason = sim_running; static_sd->last_rc = TARGET_SIGNAL_NONE; static_sd->entry_point = OR32_RESET_EXCEPTION; static_sd->resume_npc = OR32_RESET_EXCEPTION; or1ksim_set_stall_state (0); return static_sd; } /* sim_open () */
/* --------------------------------------------------------------------------*/ int main (int argc, char *argv[]) { char *reg_file; /* Parse args */ switch (argc) { case 5: reg_file = NULL; break; case 6: reg_file = argv[5]; break; default: printf ("usage: lib-upcalls <config-file> <image> " "<upcall_count> <reg_bytes> [<reg_file>]\n"); return 1; } upcall_count = atoi (argv[3]); if (upcall_count <= 0) { printf ("ERROR: Upcall count must be positive\n"); return 1; } regc = atoi (argv[4]); if (regc < 0) { printf ("ERROR: Register memory size must be positive\n"); return 1; } /* Read the register file if provided. */ regv = malloc (regc * sizeof (unsigned char)); if (NULL == regv) { printf ("ERROR: Failed to allocate register memory\n"); return 1; } int next_free_byte = 0; if (NULL != reg_file) { FILE *fd = fopen (reg_file, "r"); if (NULL == fd) { printf ("ERROR: Failed to open register file: %s\n", strerror (errno)); free (regv); return 1; } for (; next_free_byte < regc; next_free_byte++) { unsigned char byte; if (1 == fscanf (fd, "%2hhx ", &byte)) { regv[next_free_byte] = byte; } else { break; } } /* Should have read the whole file successfully. */ if (ferror (fd)) { printf ("ERROR: Reading register file: %s\n", strerror (errno)); free (regv); return 1; } if (!feof (fd)) { printf ("Warning: additional register file data ignored.\n"); } if (0 != fclose (fd)) { printf ("ERROR: Failed to close register file: %s\n", strerror (errno)); free (regv); return 1; } } /* Fill in any remaining bytes with zero */ if (next_free_byte < regc) { (void)memset (&(regv[next_free_byte]), 0, regc - next_free_byte); } /* Dummy argv array to pass arguments to or1ksim_init. Varies depending on whether an image file is specified. */ int dummy_argc; char *dummy_argv[5]; dummy_argv[0] = "libsim"; dummy_argv[1] = "-q"; dummy_argv[2] = "-f"; dummy_argv[3] = argv[1]; dummy_argv[4] = argv[2]; dummy_argc = 5; /* Initialize the program. Put the initialization message afterwards, or it will get swamped by the Or1ksim header. */ if (0 == or1ksim_init (dummy_argc, dummy_argv, NULL, &read_upcall, &write_upcall)) { printf ("Initalization succeeded.\n"); } else { printf ("Initalization failed.\n"); return 1; } /* Run repeatedly for 1 millisecond until we hit a breakpoint or all upcalls are done. */ do { switch (or1ksim_run (1.0e-3)) { case OR1KSIM_RC_OK: break; case OR1KSIM_RC_HALTED: printf ("Test completed successfully: hit exit l.nop.\n"); return 0; case OR1KSIM_RC_BRKPT: printf ("Test completed successfully: hit breakpoint.\n"); return 0; default: printf ("ERROR: run failed\n"); return 1; } } while (upcall_count > 0); /* A little longer to allow response to last upcall to be handled. */ switch (or1ksim_run (1.0e-3)) { case OR1KSIM_RC_OK: printf ("Test completed successfully: All upcalls processed.\n"); return 0; case OR1KSIM_RC_HALTED: printf ("Test completed successfully: hit exit l.nop.\n"); return 0; case OR1KSIM_RC_BRKPT: printf ("Test completed successfully: hit breakpoint.\n"); return 0; default: printf ("ERROR: run failed\n"); return 1; } } /* main () */
/* --------------------------------------------------------------------------*/ int main (int argc, char *argv[]) { /* Parse args */ if (4 != argc) { fprintf (stderr, "usage: lib-iftest <config-file> <image> <duration_ms>\n"); return 1; } int duration_ms = atoi (argv[3]); double duration = (double) duration_ms / 1.0e3; if (duration_ms <= 0) { fprintf (stderr, "ERROR. Duration must be positive number of ms\n"); return 1; } /* Dummy argv array to pass arguments to or1ksim_init. Varies depending on whether an image file is specified. */ int dummy_argc; char *dummy_argv[5]; dummy_argv[0] = "libsim"; dummy_argv[1] = "-q"; dummy_argv[2] = "-f"; dummy_argv[3] = argv[1]; dummy_argv[4] = argv[2]; dummy_argc = 5; /* Put the initialization message afterwards, or it will get swamped by the Or1ksim header. */ if (0 == or1ksim_init (dummy_argc, dummy_argv, NULL, NULL, NULL)) { printf ("Initalization succeeded.\n"); } else { printf ("Initalization failed.\n"); return 1; } /* Test of running */ printf ("Running code..."); switch (or1ksim_run (duration)) { case OR1KSIM_RC_OK: printf ("done.\n"); break; case OR1KSIM_RC_BRKPT: printf ("hit breakpoint.\n"); break; default: printf ("failed.\n"); return 1; } /* Test of timing. Set a time point, run for the duration, then check the timing matches. */ or1ksim_set_time_point (); printf ("Set time point.\n"); printf ("Running code..."); switch (or1ksim_run (duration)) { case OR1KSIM_RC_OK: printf ("done.\n"); break; case OR1KSIM_RC_BRKPT: printf ("hit breakpoint.\n"); break; default: printf ("failed.\n"); return 1; } /* All done OK (within 1ps) */ double measured_duration = or1ksim_get_time_period (); if (fabs (duration - measured_duration) < 1e-12) { printf ("Measured time period correctly.\n"); } else { printf ("Failed. Requested period %.12f, but measured %.12f\n", duration, measured_duration); return 1; } /* Test endianness */ if (or1ksim_is_le ()) { printf ("Little endian architecture.\n"); } else { printf ("Big endian architecture.\n"); } /* Check for clock rate */ unsigned long int clock_rate = or1ksim_clock_rate (); if (clock_rate > 0) { printf ("Clock rate %ld Hz.\n", clock_rate); } else { printf ("Invalid clock rate %ld Hz.\n", clock_rate); return 1; } printf ("Test completed successfully.\n"); return 0; } /* main () */