SIM_RC sim_pre_argv_init (SIM_DESC sd, const char *myname) { SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); SIM_ASSERT (STATE_MODULES (sd) == NULL); STATE_MY_NAME (sd) = lbasename (myname); /* Set the cpu names to default values. */ { int i; for (i = 0; i < MAX_NR_PROCESSORS; ++i) { char *name; if (asprintf (&name, "cpu%d", i) < 0) return SIM_RC_FAIL; CPU_NAME (STATE_CPU (sd, i)) = name; } } sim_config_default (sd); /* Install all configured in modules. */ if (sim_module_install (sd) != SIM_RC_OK) return SIM_RC_FAIL; return SIM_RC_OK; }
void UDP_Recv(sint32 fd, MSG_Q_ID id) { sint32 recvNum; uint32 rst; recvNum = UDP_ReadData(fd); // if receive enougth data, then unpack if (recvNum >= UDP_RECV_BUF_LEN_MIN) { rst = UDP_UnpackRecvData(); SIM_ASSERT(rst == UDP_MSG_HEAD_LEN); // todo only for test //show_udp_recv_head_data(); switch (udpRecvMsgHead.msgId) { case SIM_RECV_SPD_MSG_ID: rst = UDP_UnpackRecvSpdInfoData(); SIM_ASSERT(rst == UDP_MSG_SPD_PACKAGE_LEN); // todo only for test //show_udp_recv_spd_data(); break; case SIM_RECV_INIT_MSG_ID: rst = UDP_UnpackRecvInitInfoData(id); SIM_ASSERT(rst == UDP_MSG_INIT_PACKAGE_LEN); // todo only for test //show_udp_recv_velocity_data(); break; case SIM_RECV_BTM_MSG_ID: rst = UDP_UnpackRecvBtmInfoData(id); SIM_ASSERT(rst >= UDP_MSG_BTM_PACKAGE_LEN_MIN); // todo only for test //show_udp_recv_btm_data(); break; case SIM_RECV_TMS_MSG_ID: rst = UDP_UnpackRecvTmsInfoData(); //SIM_ASSERT(rst >= UDP_MSG_TMS_PACKAGE_LEN_MIN); semGive(udpSendTmsSemID); // todo only for test //show_udp_recv_tms_data(); break; default: DBG_ERRO("[UDP] receive msg head id ERROR %x!\n", udpRecvMsgHead.msgId); break; } } else { DBG_WARN("[UDP] receive udp data less or timeout!\n"); } }
void sim_module_add_uninstall_fn (SIM_DESC sd, MODULE_UNINSTALL_FN fn) { struct module_list *modules = STATE_MODULES (sd); MODULE_UNINSTALL_LIST *l = ZALLOC (MODULE_UNINSTALL_LIST); SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); SIM_ASSERT (STATE_MODULES (sd) != NULL); l->fn = fn; l->next = modules->uninstall_list; modules->uninstall_list = l; }
void sim_module_info (SIM_DESC sd, int verbose) { struct module_list *modules = STATE_MODULES (sd); MODULE_INFO_LIST *modp; SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); SIM_ASSERT (STATE_MODULES (sd) != NULL); for (modp = modules->info_list; modp != NULL; modp = modp->next) { (*modp->fn) (sd, verbose); } }
int sim_read (SIM_DESC sd, SIM_ADDR mem, unsigned char *buf, int length) { SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); return sim_core_read_buffer (sd, NULL, read_map, buf, mem, length); }
int sim_write (SIM_DESC sd, SIM_ADDR mem, const unsigned char *buf, int length) { SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); return sim_core_write_buffer (sd, NULL, write_map, buf, mem, length); }
SIM_RC sim_module_suspend (SIM_DESC sd) { struct module_list *modules = STATE_MODULES (sd); MODULE_SUSPEND_LIST *modp; SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); SIM_ASSERT (STATE_MODULES (sd) != NULL); for (modp = modules->suspend_list; modp != NULL; modp = modp->next) { if ((*modp->fn) (sd) != SIM_RC_OK) return SIM_RC_FAIL; } return SIM_RC_OK; }
void sim_stop_reason (SIM_DESC sd, enum sim_stop *reason, int *sigrc) { sim_engine *engine = NULL; SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); engine = STATE_ENGINE (sd); *reason = engine->reason; switch (*reason) { case sim_exited : *sigrc = engine->sigrc; break; case sim_signalled : /* ??? See the comment below case `sim_signalled' in gdb/remote-sim.c:gdbsim_wait. ??? Consider the case of the target requesting that it kill(2) itself with SIGNAL. That SIGNAL, being target specific, will not correspond to either of the SIM_SIGNAL enum nor the HOST_SIGNAL. A mapping from TARGET_SIGNAL to HOST_SIGNAL is needed. */ *sigrc = sim_signal_to_host (sd, engine->sigrc); break; case sim_stopped : /* The gdb/simulator interface calls for us to return the host version of the signal which gdb then converts into the target's version. This is obviously a bit clumsy. */ *sigrc = sim_signal_to_host (sd, engine->sigrc); break; default : abort (); } }
SIM_RC sim_engine_install (SIM_DESC sd) { SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); sim_module_add_init_fn (sd, sim_engine_init); return SIM_RC_OK; }
int sim_store_register (SIM_DESC sd, int rn, unsigned char *buf, int length) { SIM_CPU *cpu = STATE_CPU (sd, 0); SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); return (* CPU_REG_STORE (cpu)) (cpu, rn, buf, length); }
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; }
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; }
void sim_module_add_info_fn (SIM_DESC sd, MODULE_INFO_FN fn) { struct module_list *modules = STATE_MODULES (sd); MODULE_INFO_LIST *l = ZALLOC (MODULE_INFO_LIST); MODULE_INFO_LIST **last; SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); SIM_ASSERT (STATE_MODULES (sd) != NULL); last = &modules->info_list; while (*last != NULL) last = &((*last)->next); l->fn = fn; l->next = NULL; *last = l; }
void sim_module_add_suspend_fn (SIM_DESC sd, MODULE_SUSPEND_FN fn) { struct module_list *modules = STATE_MODULES (sd); MODULE_SUSPEND_LIST *l = ZALLOC (MODULE_SUSPEND_LIST); MODULE_SUSPEND_LIST **last; SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); SIM_ASSERT (STATE_MODULES (sd) != NULL); last = &modules->suspend_list; while (*last != NULL) last = &((*last)->next); l->fn = fn; l->next = modules->suspend_list; modules->suspend_list = l; }
SIM_RC sim_post_argv_init (SIM_DESC sd) { int i; SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); SIM_ASSERT (STATE_MODULES (sd) != NULL); /* Set the cpu->state backlinks for each cpu. */ for (i = 0; i < MAX_NR_PROCESSORS; ++i) { CPU_STATE (STATE_CPU (sd, i)) = sd; CPU_INDEX (STATE_CPU (sd, i)) = i; } if (sim_module_init (sd) != SIM_RC_OK) return SIM_RC_FAIL; 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; }
/* Break an option number into its op/int-nr */ static watchpoint_type option_to_type (SIM_DESC sd, int option) { sim_watchpoints *watch = STATE_WATCHPOINTS (sd); watchpoint_type type = ((option - OPTION_WATCH_OP) / (watch->nr_interrupts + 1)); SIM_ASSERT (type >= 0 && type < nr_watchpoint_types); return type; }
SIM_RC sim_module_install (SIM_DESC sd) { MODULE_INSTALL_FN * const *modp; SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); SIM_ASSERT (STATE_MODULES (sd) == NULL); STATE_MODULES (sd) = ZALLOC (struct module_list); for (modp = modules; *modp != NULL; ++modp) { if ((*modp) (sd) != SIM_RC_OK) { sim_module_uninstall (sd); SIM_ASSERT (STATE_MODULES (sd) == NULL); return SIM_RC_FAIL; } } 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 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_core_install (SIM_DESC sd) { SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); /* establish the other handlers */ sim_module_add_uninstall_fn (sd, sim_core_uninstall); sim_module_add_init_fn (sd, sim_core_init); /* establish any initial data structures - none */ return SIM_RC_OK; }
static void sim_core_uninstall (SIM_DESC sd) { sim_core *core = STATE_CORE (sd); unsigned map; /* blow away any mappings */ for (map = 0; map < nr_maps; map++) { sim_core_mapping *curr = core->common.map[map].first; while (curr != NULL) { sim_core_mapping *tbd = curr; curr = curr->next; if (tbd->free_buffer != NULL) { SIM_ASSERT (tbd->buffer != NULL); free (tbd->free_buffer); } free (tbd); } core->common.map[map].first = NULL; } }
void sim_stop_reason (SIM_DESC sd, enum sim_stop *reason, int *sigrc) { sim_engine *engine = NULL; SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); engine = STATE_ENGINE (sd); *reason = engine->reason; switch (*reason) { case sim_exited : *sigrc = engine->sigrc; break; case sim_stopped : case sim_signalled : *sigrc = sim_signal_to_gdb_signal (sd, engine->sigrc); break; default : abort (); } }
void sim_engine_run (SIM_DESC sd, int next_cpu_nr, /* ignore */ int nr_cpus, /* ignore */ int siggnal) /* ignore */ { sim_cpu *cpu; SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); cpu = STATE_CPU (sd, 0); while (1) { cpu_single_step (cpu); /* process any events */ if (sim_events_tickn (sd, cpu->cpu_current_cycle)) { sim_events_process (sd); } } }
void sim_engine_run (SIM_DESC sd, int next_cpu_nr, /* ignore */ int nr_cpus, /* ignore */ int siggnal) /* ignore */ { bu32 ticks; SIM_CPU *cpu; SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); cpu = STATE_CPU (sd, 0); while (1) { step_once (cpu); /* Process any events -- can't use tickn because it may advance right over the next event. */ for (ticks = 0; ticks < CYCLE_DELAY; ++ticks) if (sim_events_tick (sd)) sim_events_process (sd); } }
void sim_engine_run (SIM_DESC sd, int next_cpu_nr, /* ignore */ int nr_cpus, /* ignore */ int siggnal) /* ignore */ { sim_cia cia; sim_cpu *cpu; SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); cpu = STATE_CPU (sd, 0); cia = CIA_GET (cpu); while (1) { instruction_word insn = IMEM32 (cia); cia = idecode_issue (sd, insn, cia); /* process any events */ if (sim_events_tick (sd)) { CIA_SET (cpu, cia); sim_events_process (sd); } } }
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; }
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; }
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 *callback, bfd *abfd, char **argv) { SIM_DESC sd; sim_cpu *cpu; sd = sim_state_alloc (kind, callback); cpu = STATE_CPU (sd, 0); SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); /* for compatibility */ current_alignment = NONSTRICT_ALIGNMENT; current_target_byte_order = BIG_ENDIAN; cpu_initialize (sd, cpu); if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK) { free_state (sd); return 0; } /* 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. */ free_state (sd); 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) { free_state (sd); return 0; } /* Establish any remaining configuration options. */ if (sim_config (sd) != SIM_RC_OK) { free_state (sd); return 0; } if (sim_post_argv_init (sd) != SIM_RC_OK) { /* Uninstall the modules to avoid memory leaks, file descriptor leaks, etc. */ free_state (sd); return 0; } if (sim_prepare_for_program (sd, abfd) != SIM_RC_OK) { free_state (sd); return 0; } /* Fudge our descriptor. */ return sd; }