SIM_RC cris_option_install (SIM_DESC sd) { SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); if (sim_add_option_table (sd, NULL, cris_options) != SIM_RC_OK) return SIM_RC_FAIL; return SIM_RC_OK; }
/* Initialize the interrupts module. */ void interrupts_initialize (SIM_DESC sd, struct _sim_cpu *proc) { struct interrupts *interrupts = &proc->cpu_interrupts; interrupts->cpu = proc; sim_add_option_table (sd, 0, interrupt_options); }
SIM_RC sim_memopt_install (SIM_DESC sd) { SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); sim_add_option_table (sd, NULL, memory_options); sim_module_add_uninstall_fn (sd, sim_memory_uninstall); sim_module_add_init_fn (sd, sim_memory_init); return SIM_RC_OK; }
SIM_RC dv_sockser_install (SIM_DESC sd) { SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); if (sim_add_option_table (sd, NULL, sockser_options) != SIM_RC_OK) return SIM_RC_FAIL; sim_module_add_init_fn (sd, dv_sockser_init); sim_module_add_uninstall_fn (sd, dv_sockser_uninstall); return SIM_RC_OK; }
SIM_RC standard_install (SIM_DESC sd) { SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); if (sim_add_option_table (sd, NULL, standard_options) != SIM_RC_OK) return SIM_RC_FAIL; #ifdef SIM_HANDLES_LMA STATE_LOAD_AT_LMA_P (sd) = SIM_HANDLES_LMA; #endif return SIM_RC_OK; }
SIM_RC sim_hw_install (struct sim_state *sd) { SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); sim_add_option_table (sd, NULL, hw_options); sim_module_add_uninstall_fn (sd, sim_hw_uninstall); sim_module_add_init_fn (sd, sim_hw_init); STATE_HW (sd) = ZALLOC (struct sim_hw); STATE_HW (sd)->tree = hw_tree_create (sd, "core"); return SIM_RC_OK; }
SIM_RC scache_install (SIM_DESC sd) { sim_add_option_table (sd, NULL, scache_options); sim_module_add_init_fn (sd, scache_init); sim_module_add_uninstall_fn (sd, scache_uninstall); /* This is the default, it may be overridden on the command line. */ STATE_SCACHE_SIZE (sd) = WITH_SCACHE; return SIM_RC_OK; }
SIM_RC sim_watchpoint_install (SIM_DESC sd) { sim_watchpoints *watch = STATE_WATCHPOINTS (sd); SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); /* the basic command set */ sim_module_add_init_fn (sd, sim_watchpoint_init); sim_add_option_table (sd, NULL, watchpoint_options); /* fill in some details */ if (watch->interrupt_names == NULL) watch->interrupt_names = default_interrupt_names; watch->nr_interrupts = 0; while (watch->interrupt_names[watch->nr_interrupts] != NULL) watch->nr_interrupts++; /* generate more advansed commands */ { OPTION *int_options = NZALLOC (OPTION, 1 + (watch->nr_interrupts + 1) * nr_watchpoint_types); int interrupt_nr; for (interrupt_nr = 0; interrupt_nr <= watch->nr_interrupts; interrupt_nr++) { watchpoint_type type; for (type = 0; type < nr_watchpoint_types; type++) { char *name; int nr = interrupt_nr * nr_watchpoint_types + type; OPTION *option = &int_options[nr]; if (asprintf (&name, "watch-%s-%s", watchpoint_type_to_str (sd, type), interrupt_nr_to_str (sd, interrupt_nr)) < 0) return SIM_RC_FAIL; option->opt.name = name; option->opt.has_arg = required_argument; option->opt.val = type_to_option (sd, type, interrupt_nr); option->doc = ""; option->doc_name = ""; option->handler = watchpoint_option_handler; } } /* adjust first few entries so that they contain real documentation, the first entry includes a list of actions. */ { const char *prefix = "Watch the simulator, take ACTION in COUNT cycles (`+' for every COUNT cycles), ACTION is"; char *doc; int len = strlen (prefix) + 1; for (interrupt_nr = 0; interrupt_nr <= watch->nr_interrupts; interrupt_nr++) len += strlen (interrupt_nr_to_str (sd, interrupt_nr)) + 1; doc = NZALLOC (char, len); strcpy (doc, prefix); for (interrupt_nr = 0; interrupt_nr <= watch->nr_interrupts; interrupt_nr++) { strcat (doc, " "); strcat (doc, interrupt_nr_to_str (sd, interrupt_nr)); } int_options[0].doc_name = "watch-cycles-ACTION"; int_options[0].arg = "[+]COUNT"; int_options[0].doc = doc; } int_options[1].doc_name = "watch-pc-ACTION"; int_options[1].arg = "[!]ADDRESS"; int_options[1].doc = "Watch the PC, take ACTION when matches ADDRESS (in range ADDRESS,ADDRESS), `!' negates test"; int_options[2].doc_name = "watch-clock-ACTION"; int_options[2].arg = "[+]MILLISECONDS"; int_options[2].doc = "Watch the clock, take ACTION after MILLISECONDS (`+' for every MILLISECONDS)"; sim_add_option_table (sd, NULL, int_options); } return SIM_RC_OK; }
SIM_DESC sim_open (SIM_OPEN_KIND kind, host_callback *cb, struct bfd *abfd, char **argv) { int i; SIM_DESC sd = sim_state_alloc (kind, cb); mn10300_callback = cb; SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); /* The cpu data is kept in a separately allocated chunk of memory. */ if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK) return 0; /* for compatibility */ simulator = sd; /* FIXME: should be better way of setting up interrupts. For moment, only support watchpoints causing a breakpoint (gdb halt). */ STATE_WATCHPOINTS (sd)->pc = &(PC); STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC); STATE_WATCHPOINTS (sd)->interrupt_handler = NULL; STATE_WATCHPOINTS (sd)->interrupt_names = NULL; if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK) return 0; sim_add_option_table (sd, NULL, mn10300_options); /* Allocate core managed memory */ sim_do_command (sd, "memory region 0,0x100000"); sim_do_command (sd, "memory region 0x40000000,0x200000"); /* getopt will print the error message so we just have to exit if this fails. FIXME: Hmmm... in the case of gdb we need getopt to call print_filtered. */ if (sim_parse_args (sd, argv) != SIM_RC_OK) { /* Uninstall the modules to avoid memory leaks, file descriptor leaks, etc. */ sim_module_uninstall (sd); return 0; } if ( NULL != board && (strcmp(board, BOARD_AM32) == 0 ) ) { /* environment */ STATE_ENVIRONMENT (sd) = OPERATING_ENVIRONMENT; sim_do_command (sd, "memory region 0x44000000,0x40000"); sim_do_command (sd, "memory region 0x48000000,0x400000"); /* device support for mn1030002 */ /* interrupt controller */ sim_hw_parse (sd, "/mn103int@0x34000100/reg 0x34000100 0x7C 0x34000200 0x8 0x34000280 0x8"); /* DEBUG: NMI input's */ sim_hw_parse (sd, "/glue@0x30000000/reg 0x30000000 12"); sim_hw_parse (sd, "/glue@0x30000000 > int0 nmirq /mn103int"); sim_hw_parse (sd, "/glue@0x30000000 > int1 watchdog /mn103int"); sim_hw_parse (sd, "/glue@0x30000000 > int2 syserr /mn103int"); /* DEBUG: ACK input */ sim_hw_parse (sd, "/glue@0x30002000/reg 0x30002000 4"); sim_hw_parse (sd, "/glue@0x30002000 > int ack /mn103int"); /* DEBUG: LEVEL output */ sim_hw_parse (sd, "/glue@0x30004000/reg 0x30004000 8"); sim_hw_parse (sd, "/mn103int > nmi int0 /glue@0x30004000"); sim_hw_parse (sd, "/mn103int > level int1 /glue@0x30004000"); /* DEBUG: A bunch of interrupt inputs */ sim_hw_parse (sd, "/glue@0x30006000/reg 0x30006000 32"); sim_hw_parse (sd, "/glue@0x30006000 > int0 irq-0 /mn103int"); sim_hw_parse (sd, "/glue@0x30006000 > int1 irq-1 /mn103int"); sim_hw_parse (sd, "/glue@0x30006000 > int2 irq-2 /mn103int"); sim_hw_parse (sd, "/glue@0x30006000 > int3 irq-3 /mn103int"); sim_hw_parse (sd, "/glue@0x30006000 > int4 irq-4 /mn103int"); sim_hw_parse (sd, "/glue@0x30006000 > int5 irq-5 /mn103int"); sim_hw_parse (sd, "/glue@0x30006000 > int6 irq-6 /mn103int"); sim_hw_parse (sd, "/glue@0x30006000 > int7 irq-7 /mn103int"); /* processor interrupt device */ /* the device */ sim_hw_parse (sd, "/mn103cpu@0x20000000"); sim_hw_parse (sd, "/mn103cpu@0x20000000/reg 0x20000000 0x42"); /* DEBUG: ACK output wired upto a glue device */ sim_hw_parse (sd, "/glue@0x20002000"); sim_hw_parse (sd, "/glue@0x20002000/reg 0x20002000 4"); sim_hw_parse (sd, "/mn103cpu > ack int0 /glue@0x20002000"); /* DEBUG: RESET/NMI/LEVEL wired up to a glue device */ sim_hw_parse (sd, "/glue@0x20004000"); sim_hw_parse (sd, "/glue@0x20004000/reg 0x20004000 12"); sim_hw_parse (sd, "/glue@0x20004000 > int0 reset /mn103cpu"); sim_hw_parse (sd, "/glue@0x20004000 > int1 nmi /mn103cpu"); sim_hw_parse (sd, "/glue@0x20004000 > int2 level /mn103cpu"); /* REAL: The processor wired up to the real interrupt controller */ sim_hw_parse (sd, "/mn103cpu > ack ack /mn103int"); sim_hw_parse (sd, "/mn103int > level level /mn103cpu"); sim_hw_parse (sd, "/mn103int > nmi nmi /mn103cpu"); /* PAL */ /* the device */ sim_hw_parse (sd, "/pal@0x31000000"); sim_hw_parse (sd, "/pal@0x31000000/reg 0x31000000 64"); sim_hw_parse (sd, "/pal@0x31000000/poll? true"); /* DEBUG: PAL wired up to a glue device */ sim_hw_parse (sd, "/glue@0x31002000"); sim_hw_parse (sd, "/glue@0x31002000/reg 0x31002000 16"); sim_hw_parse (sd, "/pal@0x31000000 > countdown int0 /glue@0x31002000"); sim_hw_parse (sd, "/pal@0x31000000 > timer int1 /glue@0x31002000"); sim_hw_parse (sd, "/pal@0x31000000 > int int2 /glue@0x31002000"); sim_hw_parse (sd, "/glue@0x31002000 > int0 int3 /glue@0x31002000"); sim_hw_parse (sd, "/glue@0x31002000 > int1 int3 /glue@0x31002000"); sim_hw_parse (sd, "/glue@0x31002000 > int2 int3 /glue@0x31002000"); /* REAL: The PAL wired up to the real interrupt controller */ sim_hw_parse (sd, "/pal@0x31000000 > countdown irq-0 /mn103int"); sim_hw_parse (sd, "/pal@0x31000000 > timer irq-1 /mn103int"); sim_hw_parse (sd, "/pal@0x31000000 > int irq-2 /mn103int"); /* 8 and 16 bit timers */ sim_hw_parse (sd, "/mn103tim@0x34001000/reg 0x34001000 36 0x34001080 100 0x34004000 16"); /* Hook timer interrupts up to interrupt controller */ sim_hw_parse (sd, "/mn103tim > timer-0-underflow timer-0-underflow /mn103int"); sim_hw_parse (sd, "/mn103tim > timer-1-underflow timer-1-underflow /mn103int"); sim_hw_parse (sd, "/mn103tim > timer-2-underflow timer-2-underflow /mn103int"); sim_hw_parse (sd, "/mn103tim > timer-3-underflow timer-3-underflow /mn103int"); sim_hw_parse (sd, "/mn103tim > timer-4-underflow timer-4-underflow /mn103int"); sim_hw_parse (sd, "/mn103tim > timer-5-underflow timer-5-underflow /mn103int"); sim_hw_parse (sd, "/mn103tim > timer-6-underflow timer-6-underflow /mn103int"); sim_hw_parse (sd, "/mn103tim > timer-6-compare-a timer-6-compare-a /mn103int"); sim_hw_parse (sd, "/mn103tim > timer-6-compare-b timer-6-compare-b /mn103int"); /* Serial devices 0,1,2 */ sim_hw_parse (sd, "/mn103ser@0x34000800/reg 0x34000800 48"); sim_hw_parse (sd, "/mn103ser@0x34000800/poll? true"); /* Hook serial interrupts up to interrupt controller */ sim_hw_parse (sd, "/mn103ser > serial-0-receive serial-0-receive /mn103int"); sim_hw_parse (sd, "/mn103ser > serial-0-transmit serial-0-transmit /mn103int"); sim_hw_parse (sd, "/mn103ser > serial-1-receive serial-1-receive /mn103int"); sim_hw_parse (sd, "/mn103ser > serial-1-transmit serial-1-transmit /mn103int"); sim_hw_parse (sd, "/mn103ser > serial-2-receive serial-2-receive /mn103int"); sim_hw_parse (sd, "/mn103ser > serial-2-transmit serial-2-transmit /mn103int"); sim_hw_parse (sd, "/mn103iop@0x36008000/reg 0x36008000 8 0x36008020 8 0x36008040 0xc 0x36008060 8 0x36008080 8"); /* Memory control registers */ sim_do_command (sd, "memory region 0x32000020,0x30"); /* Cache control register */ sim_do_command (sd, "memory region 0x20000070,0x4"); /* Cache purge regions */ sim_do_command (sd, "memory region 0x28400000,0x800"); sim_do_command (sd, "memory region 0x28401000,0x800"); /* DMA registers */ sim_do_command (sd, "memory region 0x32000100,0xF"); sim_do_command (sd, "memory region 0x32000200,0xF"); sim_do_command (sd, "memory region 0x32000400,0xF"); sim_do_command (sd, "memory region 0x32000800,0xF"); } else { if (board != NULL) { sim_io_eprintf (sd, "Error: Board `%s' unknown.\n", board); return 0; } } /* check for/establish the a reference program image */ if (sim_analyze_program (sd, (STATE_PROG_ARGV (sd) != NULL ? *STATE_PROG_ARGV (sd) : NULL), abfd) != SIM_RC_OK) { sim_module_uninstall (sd); return 0; } /* establish any remaining configuration options */ if (sim_config (sd) != SIM_RC_OK) { sim_module_uninstall (sd); return 0; } if (sim_post_argv_init (sd) != SIM_RC_OK) { /* Uninstall the modules to avoid memory leaks, file descriptor leaks, etc. */ sim_module_uninstall (sd); return 0; } /* set machine specific configuration */ /* STATE_CPU (sd, 0)->psw_mask = (PSW_NP | PSW_EP | PSW_ID | PSW_SAT */ /* | PSW_CY | PSW_OV | PSW_S | PSW_Z); */ /* CPU specific initialization. */ for (i = 0; i < MAX_NR_PROCESSORS; ++i) { SIM_CPU *cpu = STATE_CPU (sd, i); CPU_PC_FETCH (cpu) = mn10300_pc_get; CPU_PC_STORE (cpu) = mn10300_pc_set; } return sd; }