static void engine_run_n (SIM_DESC sd, int next_cpu_nr, int nr_cpus, int max_insns, int fast_p) { int i; ENGINE_FN *engine_fns[MAX_NR_PROCESSORS]; for (i = 0; i < nr_cpus; ++i) { SIM_CPU *cpu = STATE_CPU (sd, i); engine_fns[i] = fast_p ? CPU_FAST_ENGINE_FN (cpu) : CPU_FULL_ENGINE_FN (cpu); prime_cpu (cpu, max_insns); } while (1) { SIM_ENGINE_PREFIX_HOOK (sd); /* FIXME: proper cycling of all of them, blah blah blah. */ while (next_cpu_nr != nr_cpus) { SIM_CPU *cpu = STATE_CPU (sd, next_cpu_nr); (* engine_fns[next_cpu_nr]) (cpu); ++next_cpu_nr; } SIM_ENGINE_POSTFIX_HOOK (sd); /* process any events */ if (sim_events_tick (sd)) sim_events_process (sd); } }
int is_condition_ok (SIM_DESC sd, address_word cia, int cond) { switch (cond) { case 0x0: return 1; case 0x1: return PSW_VAL(PSW_F0); case 0x2: return !PSW_VAL(PSW_F0); case 0x3: return PSW_VAL(PSW_F1); case 0x4: return !PSW_VAL(PSW_F1); case 0x5: return PSW_VAL(PSW_F0) && PSW_VAL(PSW_F1); case 0x6: return PSW_VAL(PSW_F0) && !PSW_VAL(PSW_F1); case 0x7: sim_engine_abort (sd, STATE_CPU (sd, 0), cia, "is_condition_ok - bad instruction condition bits"); return 0; default: sim_engine_abort (sd, STATE_CPU (sd, 0), cia, "internal error - is_condition_ok - bad switch"); return -1; } }
void sim_cpu_free_all (SIM_DESC sd) { int c; for (c = 0; c < MAX_NR_PROCESSORS; ++c) if (STATE_CPU (sd, c)) sim_cpu_free (STATE_CPU (sd, c)); }
static void attach_bfin_cec_regs (struct hw *me, struct bfin_cec *cec) { address_word attach_address; int attach_space; unsigned attach_size; reg_property_spec reg; if (hw_find_property (me, "reg") == NULL) hw_abort (me, "Missing \"reg\" property"); if (!hw_find_reg_array_property (me, "reg", 0, ®)) hw_abort (me, "\"reg\" property must contain three addr/size entries"); hw_unit_address_to_attach_address (hw_parent (me), ®.address, &attach_space, &attach_address, me); hw_unit_size_to_attach_size (hw_parent (me), ®.size, &attach_size, me); if (attach_size != BFIN_COREMMR_CEC_SIZE) hw_abort (me, "\"reg\" size must be %#x", BFIN_COREMMR_CEC_SIZE); hw_attach_address (hw_parent (me), 0, attach_space, attach_address, attach_size, me); cec->base = attach_address; /* XXX: should take from the device tree. */ cec->cpu = STATE_CPU (hw_system (me), 0); cec->me = me; }
/* Get the memory bank parameters by looking at the global symbols defined by the linker. */ static int sim_get_bank_parameters (SIM_DESC sd) { sim_cpu *cpu; unsigned size; bfd_vma addr; cpu = STATE_CPU (sd, 0); addr = trace_sym_value (sd, BFD_M68HC11_BANK_START_NAME); if (addr != -1) cpu->bank_start = addr; size = trace_sym_value (sd, BFD_M68HC11_BANK_SIZE_NAME); if (size == -1) size = 0; addr = trace_sym_value (sd, BFD_M68HC11_BANK_VIRTUAL_NAME); if (addr != -1) cpu->bank_virtual = addr; cpu->bank_end = cpu->bank_start + size; cpu->bank_shift = 0; for (; size > 1; size >>= 1) cpu->bank_shift++; return 0; }
static void m68hc11sio_info (struct hw *me) { SIM_DESC sd; uint16 base = 0; sim_cpu *cpu; struct m68hc11sio *controller; uint8 val; long clock_cycle; sd = hw_system (me); cpu = STATE_CPU (sd, 0); controller = hw_data (me); sim_io_printf (sd, "M68HC11 SIO:\n"); base = cpu_get_io_base (cpu); val = cpu->ios[M6811_BAUD]; print_io_byte (sd, "BAUD ", baud_desc, val, base + M6811_BAUD); sim_io_printf (sd, " (%ld baud)\n", (cpu->cpu_frequency / 4) / controller->baud_cycle); val = cpu->ios[M6811_SCCR1]; print_io_byte (sd, "SCCR1", sccr1_desc, val, base + M6811_SCCR1); sim_io_printf (sd, " (%d bits) (%dN1)\n", controller->data_length, controller->data_length - 2); val = cpu->ios[M6811_SCCR2]; print_io_byte (sd, "SCCR2", sccr2_desc, val, base + M6811_SCCR2); sim_io_printf (sd, "\n"); val = cpu->ios[M6811_SCSR]; print_io_byte (sd, "SCSR ", scsr_desc, val, base + M6811_SCSR); sim_io_printf (sd, "\n"); clock_cycle = controller->data_length * controller->baud_cycle; if (controller->tx_poll_event) { signed64 t; int n; t = hw_event_remain_time (me, controller->tx_poll_event); n = (clock_cycle - t) / controller->baud_cycle; n = controller->data_length - n; sim_io_printf (sd, " Transmit finished in %s (%d bit%s)\n", cycle_to_string (cpu, t, PRINT_TIME | PRINT_CYCLE), n, (n > 1 ? "s" : "")); } if (controller->rx_poll_event) { signed64 t; t = hw_event_remain_time (me, controller->rx_poll_event); sim_io_printf (sd, " Receive finished in %s\n", cycle_to_string (cpu, t, PRINT_TIME | PRINT_CYCLE)); } }
do_syscall () { /* We use this for simulated system calls; we may need to change it to a reserved instruction if we conflict with uses at Matsushita. */ int save_errno = errno; errno = 0; /* Registers passed to trap 0 */ /* Function number. */ #define FUNC (State.regs[0]) /* Parameters. */ #define PARM1 (State.regs[1]) #define PARM2 (load_word (State.regs[REG_SP] + 12)) #define PARM3 (load_word (State.regs[REG_SP] + 16)) /* Registers set by trap 0 */ #define RETVAL State.regs[0] /* return value */ #define RETERR State.regs[1] /* return error code */ /* Turn a pointer in a register into a pointer into real memory. */ #define MEMPTR(x) (State.mem + x) if ( FUNC == TARGET_SYS_exit ) { /* EXIT - caller can look in PARM1 to work out the reason */ if (PARM1 == 0xdead) State.exception = SIGABRT; else { sim_engine_halt (simulator, STATE_CPU (simulator, 0), NULL, PC, sim_exited, PARM1); State.exception = SIGQUIT; } State.exited = 1; } else { CB_SYSCALL syscall; CB_SYSCALL_INIT (&syscall); syscall.arg1 = PARM1; syscall.arg2 = PARM2; syscall.arg3 = PARM3; syscall.func = FUNC; syscall.p1 = (PTR) simulator; syscall.read_mem = syscall_read_mem; syscall.write_mem = syscall_write_mem; cb_syscall (STATE_CALLBACK (simulator), &syscall); RETERR = syscall.errcode; RETVAL = syscall.result; } errno = save_errno; }
void sim_model_set (SIM_DESC sd, sim_cpu *cpu, const MODEL *model) { if (! cpu) { int c; for (c = 0; c < MAX_NR_PROCESSORS; ++c) if (STATE_CPU (sd, c)) model_set (STATE_CPU (sd, c), model); } else { model_set (cpu, model); } }
void sim_engine_run (SIM_DESC sd, int next_cpu_nr, int nr_cpus, int signal) { micromips_m32_instruction_word instruction_0; sim_cpu *cpu = STATE_CPU (sd, next_cpu_nr); micromips32_instruction_address cia = CPU_PC_GET (cpu); sd->isa_mode = ISA_MODE_MIPS32; while (1) { micromips32_instruction_address nia; /* Allow us to switch back from MIPS32 to microMIPS This covers two cases: 1. Setting the correct isa mode based on the start address from the elf header. 2. Setting the correct isa mode after a MIPS32 jump or branch instruction. */ if ((sd->isa_mode == ISA_MODE_MIPS32) && ((cia & 0x1) == ISA_MODE_MICROMIPS)) { sd->isa_mode = ISA_MODE_MICROMIPS; cia = cia & ~0x1; } #if defined (ENGINE_ISSUE_PREFIX_HOOK) ENGINE_ISSUE_PREFIX_HOOK (); #endif switch (sd->isa_mode) { case ISA_MODE_MICROMIPS: nia = micromips_instruction_decode (sd, cpu, cia, MICROMIPS_DELAYSLOT_SIZE_ANY); break; case ISA_MODE_MIPS32: instruction_0 = IMEM32 (cia); nia = micromips_m32_idecode_issue (sd, instruction_0, cia); break; default: nia = NULL_CIA; } #if defined (ENGINE_ISSUE_POSTFIX_HOOK) ENGINE_ISSUE_POSTFIX_HOOK (); #endif /* Update the instruction address */ cia = nia; /* process any events */ if (sim_events_tick (sd)) { CPU_PC_SET (cpu, cia); sim_events_process (sd); cia = CPU_PC_GET (cpu); } } }
void sim_do_command (SIM_DESC sd, char *cmd) { char *mm_cmd = "memory-map"; char *int_cmd = "interrupt"; sim_cpu *cpu; cpu = STATE_CPU (sd, 0); /* Commands available from GDB: */ if (sim_args_command (sd, cmd) != SIM_RC_OK) { if (strncmp (cmd, "info", sizeof ("info") - 1) == 0) sim_get_info (sd, &cmd[4]); else if (strncmp (cmd, mm_cmd, strlen (mm_cmd) == 0)) sim_io_eprintf (sd, "`memory-map' command replaced by `sim memory'\n"); else if (strncmp (cmd, int_cmd, strlen (int_cmd)) == 0) sim_io_eprintf (sd, "`interrupt' command replaced by `sim watch'\n"); else sim_io_eprintf (sd, "Unknown command `%s'\n", cmd); } /* If the architecture changed, re-configure. */ if (STATE_ARCHITECTURE (sd) != cpu->cpu_configured_arch) sim_hw_configure (sd); }
static void parse_cache_option (SIM_DESC sd, char *arg, char *cache_name, int is_data_cache) { int i; address_word ways = 0, sets = 0, linesize = 0; if (arg != NULL) { char *chp = arg; /* parse the arguments */ chp = parse_size (chp, &ways); ways = check_pow2 (ways, "WAYS", cache_name, sd); if (*chp == ',') { chp = parse_size (chp + 1, &sets); sets = check_pow2 (sets, "SETS", cache_name, sd); if (*chp == ',') { chp = parse_size (chp + 1, &linesize); linesize = check_pow2 (linesize, "LINESIZE", cache_name, sd); } } } for (i = 0; i < MAX_NR_PROCESSORS; ++i) { SIM_CPU *current_cpu = STATE_CPU (sd, i); FRV_CACHE *cache = is_data_cache ? CPU_DATA_CACHE (current_cpu) : CPU_INSN_CACHE (current_cpu); cache->ways = ways; cache->sets = sets; cache->line_size = linesize; frv_cache_init (current_cpu, cache); } }
void sim_board_reset (SIM_DESC sd) { struct hw *hw_cpu; sim_cpu *cpu; const struct bfd_arch_info *arch; const char *cpu_type; cpu = STATE_CPU (sd, 0); arch = STATE_ARCHITECTURE (sd); /* hw_cpu = sim_hw_parse (sd, "/"); */ if (arch->arch == bfd_arch_m68hc11) { cpu->cpu_type = CPU_M6811; cpu_type = "/m68hc11"; } else { cpu->cpu_type = CPU_M6812; cpu_type = "/m68hc12"; } hw_cpu = sim_hw_parse (sd, cpu_type); if (hw_cpu == 0) { sim_io_eprintf (sd, "%s cpu not found in device tree.", cpu_type); return; } cpu_reset (cpu); hw_port_event (hw_cpu, 3, 0); cpu_restart (cpu); }
void cgen_init (SIM_DESC sd) { int i, c; /* If no profiling or tracing has been enabled, run in fast mode. */ { int run_fast_p = 1; for (c = 0; c < MAX_NR_PROCESSORS; ++c) { SIM_CPU *cpu = STATE_CPU (sd, c); for (i = 0; i < MAX_PROFILE_VALUES; ++i) if (CPU_PROFILE_FLAGS (cpu) [i]) { run_fast_p = 0; break; } for (i = 0; i < MAX_TRACE_VALUES; ++i) if (CPU_TRACE_FLAGS (cpu) [i]) { run_fast_p = 0; break; } if (! run_fast_p) break; } STATE_RUN_FAST_P (sd) = run_fast_p; } }
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 sim_resume (SIM_DESC sd, int step, int siggnal) { sim_engine *engine = STATE_ENGINE (sd); jmp_buf buf; int jmpval; ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); /* we only want to be single stepping the simulator once */ if (engine->stepper != NULL) { sim_events_deschedule (sd, engine->stepper); engine->stepper = NULL; } if (step) engine->stepper = sim_events_schedule (sd, 1, has_stepped, sd); sim_module_resume (sd); /* run/resume the simulator */ engine->jmpbuf = &buf; jmpval = setjmp (buf); if (jmpval == sim_engine_start_jmpval || jmpval == sim_engine_restart_jmpval) { int last_cpu_nr = sim_engine_last_cpu_nr (sd); int next_cpu_nr = sim_engine_next_cpu_nr (sd); int nr_cpus = sim_engine_nr_cpus (sd); int sig_to_deliver; sim_events_preprocess (sd, last_cpu_nr >= nr_cpus, next_cpu_nr >= nr_cpus); if (next_cpu_nr >= nr_cpus) next_cpu_nr = 0; /* Only deliver the SIGGNAL [sic] the first time through - don't re-deliver any SIGGNAL during a restart. NOTE: A new local variable is used to avoid problems with the automatic variable ``siggnal'' being trashed by a long jump. */ if (jmpval == sim_engine_start_jmpval) sig_to_deliver = siggnal; else sig_to_deliver = 0; #ifdef SIM_CPU_EXCEPTION_RESUME { sim_cpu* cpu = STATE_CPU (sd, next_cpu_nr); SIM_CPU_EXCEPTION_RESUME(sd, cpu, sig_to_deliver); } #endif sim_engine_run (sd, next_cpu_nr, nr_cpus, sig_to_deliver); } engine->jmpbuf = NULL; sim_module_suspend (sd); }
syscall_write_mem (host_callback *cb, struct cb_syscall *sc, unsigned long taddr, const char *buf, int bytes) { SIM_DESC sd = (SIM_DESC) sc->p1; sim_cpu *cpu = STATE_CPU(sd, 0); return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes); }
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); }
int sim_engine_last_cpu_nr (SIM_DESC sd) { sim_engine *engine = STATE_ENGINE (sd); if (engine->last_cpu != NULL) return engine->last_cpu - STATE_CPU (sd, 0); else return MAX_NR_PROCESSORS; }
void m68hc11sio_tx_poll (struct hw *me, void *data) { SIM_DESC sd; struct m68hc11sio *controller; sim_cpu *cpu; controller = hw_data (me); sd = hw_system (me); cpu = STATE_CPU (sd, 0); cpu->ios[M6811_SCSR] |= M6811_TDRE; cpu->ios[M6811_SCSR] |= M6811_TC; /* Transmitter is enabled and we have something to send. */ if ((cpu->ios[M6811_SCCR2] & M6811_TE) && controller->tx_has_char) { cpu->ios[M6811_SCSR] &= ~M6811_TDRE; cpu->ios[M6811_SCSR] &= ~M6811_TC; controller->tx_has_char = 0; switch (controller->backend) { case sio_tcp: dv_sockser_write (sd, controller->tx_char); break; case sio_stdio: sim_io_write_stdout (sd, &controller->tx_char, 1); sim_io_flush_stdout (sd); break; default: break; } } if (controller->tx_poll_event) { hw_event_queue_deschedule (me, controller->tx_poll_event); controller->tx_poll_event = 0; } if ((cpu->ios[M6811_SCCR2] & M6811_TE) && ((cpu->ios[M6811_SCSR] & M6811_TC) == 0)) { unsigned long clock_cycle; /* Compute CPU clock cycles to wait for the next character. */ clock_cycle = controller->data_length * controller->baud_cycle; controller->tx_poll_event = hw_event_queue_schedule (me, clock_cycle, m68hc11sio_tx_poll, NULL); } interrupts_update_pending (&cpu->cpu_interrupts); }
SIM_RC sim_cpu_alloc_all (SIM_DESC sd, int ncpus, int extra_bytes) { int c; for (c = 0; c < ncpus; ++c) STATE_CPU (sd, c) = sim_cpu_alloc (sd, extra_bytes); return SIM_RC_OK; }
int sim_engine_next_cpu_nr (SIM_DESC sd) { sim_engine *engine = STATE_ENGINE (sd); if (engine->next_cpu != NULL) return engine->next_cpu - STATE_CPU (sd, 0); else return sim_engine_last_cpu_nr (sd) + 1; }
int sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length) { uint16 val; sim_cpu *cpu; cpu = STATE_CPU (sd, 0); val = *memory++; if (length == 2) val = (val << 8) | *memory; switch (rn) { case D_REGNUM: cpu_set_d (cpu, val); break; case A_REGNUM: cpu_set_a (cpu, val); return 1; case B_REGNUM: cpu_set_b (cpu, val); return 1; case X_REGNUM: cpu_set_x (cpu, val); break; case Y_REGNUM: cpu_set_y (cpu, val); break; case SP_REGNUM: cpu_set_sp (cpu, val); break; case PC_REGNUM: cpu_set_pc (cpu, val); break; case PSW_REGNUM: cpu_set_ccr (cpu, val); return 1; case PAGE_REGNUM: cpu_set_page (cpu, val); return 1; default: break; } return 2; }
int is_wrong_slot (SIM_DESC sd, address_word cia, itable_index index) { switch (STATE_CPU (sd, 0)->unit) { case memory_unit: return !itable[index].option[itable_option_mu]; case integer_unit: return !itable[index].option[itable_option_iu]; case any_unit: return 0; default: sim_engine_abort (sd, STATE_CPU (sd, 0), cia, "internal error - is_wrong_slot - bad switch"); return -1; } }
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; }
static int sim_prepare_for_program (SIM_DESC sd, bfd* abfd) { sim_cpu *cpu; int elf_flags = 0; cpu = STATE_CPU (sd, 0); if (abfd != NULL) { asection *s; if (bfd_get_flavour (abfd) == bfd_target_elf_flavour) elf_flags = elf_elfheader (abfd)->e_flags; cpu->cpu_elf_start = bfd_get_start_address (abfd); /* See if any section sets the reset address */ cpu->cpu_use_elf_start = 1; for (s = abfd->sections; s && cpu->cpu_use_elf_start; s = s->next) { if (s->flags & SEC_LOAD) { bfd_size_type size; size = bfd_get_section_size (s); if (size > 0) { bfd_vma lma; if (STATE_LOAD_AT_LMA_P (sd)) lma = bfd_section_lma (abfd, s); else lma = bfd_section_vma (abfd, s); if (lma <= 0xFFFE && lma+size >= 0x10000) cpu->cpu_use_elf_start = 0; } } } if (elf_flags & E_M68HC12_BANKS) { if (sim_get_bank_parameters (sd, abfd) != 0) sim_io_eprintf (sd, "Memory bank parameters are not initialized\n"); } } if (!sim_hw_configure (sd)) return SIM_RC_FAIL; /* reset all state information */ sim_board_reset (sd); return SIM_RC_OK; }
static SIM_RC sim_model_init (SIM_DESC sd) { SIM_CPU *cpu; /* If both cpu model and state architecture are set, ensure they're compatible. If only one is set, set the other. If neither are set, use the default model. STATE_ARCHITECTURE is the bfd_arch_info data for the selected "mach" (bfd terminology). */ /* Only check cpu 0. STATE_ARCHITECTURE is for that one only. */ /* ??? At present this only supports homogeneous multiprocessors. */ cpu = STATE_CPU (sd, 0); if (! STATE_ARCHITECTURE (sd) && ! CPU_MACH (cpu)) { /* Set the default model. */ const MODEL *model = sim_model_lookup (WITH_DEFAULT_MODEL); sim_model_set (sd, NULL, model); } if (STATE_ARCHITECTURE (sd) && CPU_MACH (cpu)) { if (strcmp (STATE_ARCHITECTURE (sd)->printable_name, MACH_BFD_NAME (CPU_MACH (cpu))) != 0) { sim_io_eprintf (sd, "invalid model `%s' for `%s'\n", MODEL_NAME (CPU_MODEL (cpu)), STATE_ARCHITECTURE (sd)->printable_name); return SIM_RC_FAIL; } } else if (STATE_ARCHITECTURE (sd)) { /* Use the default model for the selected machine. The default model is the first one in the list. */ const MACH *mach = sim_mach_lookup_bfd_name (STATE_ARCHITECTURE (sd)->printable_name); if (mach == NULL) { sim_io_eprintf (sd, "unsupported machine `%s'\n", STATE_ARCHITECTURE (sd)->printable_name); return SIM_RC_FAIL; } sim_model_set (sd, NULL, MACH_MODELS (mach)); } else { STATE_ARCHITECTURE (sd) = bfd_scan_arch (MACH_BFD_NAME (CPU_MACH (cpu))); } return SIM_RC_OK; }
void scache_flush (SIM_DESC sd) { int c; for (c = 0; c < MAX_NR_PROCESSORS; ++c) { SIM_CPU *cpu = STATE_CPU (sd, c); scache_flush_cpu (cpu); } }
/* Get the memory bank parameters by looking at the global symbols defined by the linker. */ static int sim_get_bank_parameters (SIM_DESC sd, bfd* abfd) { sim_cpu *cpu; long symsize; long symbol_count, i; unsigned size; asymbol** asymbols; asymbol** current; cpu = STATE_CPU (sd, 0); symsize = bfd_get_symtab_upper_bound (abfd); if (symsize < 0) { sim_io_eprintf (sd, "Cannot read symbols of program"); return 0; } asymbols = (asymbol **) xmalloc (symsize); symbol_count = bfd_canonicalize_symtab (abfd, asymbols); if (symbol_count < 0) { sim_io_eprintf (sd, "Cannot read symbols of program"); return 0; } size = 0; for (i = 0, current = asymbols; i < symbol_count; i++, current++) { const char* name = bfd_asymbol_name (*current); if (strcmp (name, BFD_M68HC11_BANK_START_NAME) == 0) { cpu->bank_start = bfd_asymbol_value (*current); } else if (strcmp (name, BFD_M68HC11_BANK_SIZE_NAME) == 0) { size = bfd_asymbol_value (*current); } else if (strcmp (name, BFD_M68HC11_BANK_VIRTUAL_NAME) == 0) { cpu->bank_virtual = bfd_asymbol_value (*current); } } free (asymbols); cpu->bank_end = cpu->bank_start + size; cpu->bank_shift = 0; for (; size > 1; size >>= 1) cpu->bank_shift++; return 0; }
static unsigned m68hc11eepr_io_read_buffer (struct hw *me, void *dest, int space, unsigned_word base, unsigned nr_bytes) { SIM_DESC sd; struct m68hc11eepr *controller; sim_cpu *cpu; HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes)); sd = hw_system (me); controller = hw_data (me); cpu = STATE_CPU (sd, 0); if (space == io_map) { unsigned cnt = 0; while (nr_bytes != 0) { switch (base) { case M6811_PPROG: case M6811_CONFIG: *((uint8*) dest) = cpu->ios[base]; break; default: hw_abort (me, "reading wrong register 0x%04x", base); } dest = (uint8*) (dest) + 1; base++; nr_bytes--; cnt++; } return cnt; } /* In theory, we can't read the EEPROM when it's being programmed. */ if ((cpu->ios[M6811_PPROG] & M6811_EELAT) != 0 && cpu_is_running (cpu)) { sim_memory_error (cpu, SIM_SIGBUS, base, "EEprom not configured for reading"); } base = base - controller->base_address; memcpy (dest, &controller->eeprom[base], nr_bytes); return nr_bytes; }
static unsigned m68hc11tim_io_read_buffer (struct hw *me, void *dest, int space, unsigned_word base, unsigned nr_bytes) { SIM_DESC sd; struct m68hc11tim *controller; sim_cpu *cpu; unsigned8 val; unsigned cnt = 0; HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes)); sd = hw_system (me); cpu = STATE_CPU (sd, 0); controller = hw_data (me); while (nr_bytes) { switch (base) { /* The cpu_absolute_cycle is updated after each instruction. Reading in a 16-bit register will be split in two accesses but this will be atomic within the simulator. */ case M6811_TCTN_H: val = (uint8) ((cpu->cpu_absolute_cycle - controller->tcnt_adjust) / (controller->clock_prescaler * 256)); break; case M6811_TCTN_L: val = (uint8) ((cpu->cpu_absolute_cycle - controller->tcnt_adjust) / controller->clock_prescaler); break; default: val = cpu->ios[base]; break; } *((unsigned8*) dest) = val; dest = (char*) dest + 1; base++; nr_bytes--; cnt++; } return cnt; }