static void free_state (SIM_DESC sd) { if (STATE_MODULES (sd) != NULL) sim_module_uninstall (sd); sim_cpu_free_all (sd); sim_state_free (sd); }
void sim_close (SIM_DESC sd, int quitting) { /* shut down modules */ sim_module_uninstall (sd); /* Ensure that any resources allocated through the callback mechanism are released: */ sim_io_shutdown (sd); /* FIXME - free SD */ sim_state_free (sd); return; }
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; }
void sim_close (SIM_DESC sd, int quitting) { sim_module_uninstall (sd); }
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; }