void interrupts_info (SIM_DESC sd, struct interrupts *interrupts) { signed64 t; sim_io_printf (sd, "Interrupts Info:\n"); sim_io_printf (sd, " Interrupts raised: %lu\n", interrupts->nb_interrupts_raised); if (interrupts->start_mask_cycle >= 0) { t = cpu_current_cycle (interrupts->cpu); t -= interrupts->start_mask_cycle; if (t > interrupts->max_mask_cycles) interrupts->max_mask_cycles = t; sim_io_printf (sd, " Current interrupts masked sequence: %s\n", cycle_to_string (interrupts->cpu, t)); } t = interrupts->min_mask_cycles == CYCLES_MAX ? interrupts->max_mask_cycles : interrupts->min_mask_cycles; sim_io_printf (sd, " Shortest interrupts masked sequence: %s\n", cycle_to_string (interrupts->cpu, t)); t = interrupts->max_mask_cycles; sim_io_printf (sd, " Longest interrupts masked sequence: %s\n", cycle_to_string (interrupts->cpu, t)); t = interrupts->last_mask_cycles; sim_io_printf (sd, " Last interrupts masked sequence: %s\n", cycle_to_string (interrupts->cpu, t)); if (interrupts->xirq_start_mask_cycle >= 0) { t = cpu_current_cycle (interrupts->cpu); t -= interrupts->xirq_start_mask_cycle; if (t > interrupts->xirq_max_mask_cycles) interrupts->xirq_max_mask_cycles = t; sim_io_printf (sd, " XIRQ Current interrupts masked sequence: %s\n", cycle_to_string (interrupts->cpu, t)); } t = interrupts->xirq_min_mask_cycles == CYCLES_MAX ? interrupts->xirq_max_mask_cycles : interrupts->xirq_min_mask_cycles; sim_io_printf (sd, " XIRQ Min interrupts masked sequence: %s\n", cycle_to_string (interrupts->cpu, t)); t = interrupts->xirq_max_mask_cycles; sim_io_printf (sd, " XIRQ Max interrupts masked sequence: %s\n", cycle_to_string (interrupts->cpu, t)); t = interrupts->xirq_last_mask_cycles; sim_io_printf (sd, " XIRQ Last interrupts masked sequence: %s\n", cycle_to_string (interrupts->cpu, t)); }
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)); } }
static void m68hc11tim_print_timer (struct hw *me, const char *name, struct hw_event *event) { SIM_DESC sd; sd = hw_system (me); if (event == 0) { sim_io_printf (sd, " No %s interrupt will be raised.\n", name); } else { signed64 t; sim_cpu *cpu; cpu = STATE_CPU (sd, 0); t = hw_event_remain_time (me, event); sim_io_printf (sd, " Next %s interrupt in %s\n", name, cycle_to_string (cpu, t, PRINT_TIME | PRINT_CYCLE)); } }
static SIM_RC model_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt, char *arg, int is_command) { switch (opt) { case OPTION_MODEL : { const MODEL *model = sim_model_lookup (arg); if (! model) { sim_io_eprintf (sd, "unknown model `%s'\n", arg); return SIM_RC_FAIL; } sim_model_set (sd, cpu, model); break; } case OPTION_MODEL_INFO : { const MACH **machp; const MODEL *model; for (machp = & sim_machs[0]; *machp != NULL; ++machp) { sim_io_printf (sd, "Models for architecture `%s':\n", MACH_NAME (*machp)); for (model = MACH_MODELS (*machp); MODEL_NAME (model) != NULL; ++model) sim_io_printf (sd, " %s", MODEL_NAME (model)); sim_io_printf (sd, "\n"); } break; } } return SIM_RC_OK; }
/* Describe the state of the EEPROM device. */ static void m68hc11eepr_info (struct hw *me) { SIM_DESC sd; uint16 base = 0; sim_cpu *cpu; struct m68hc11eepr *controller; uint8 val; sd = hw_system (me); cpu = STATE_CPU (sd, 0); controller = hw_data (me); base = cpu_get_io_base (cpu); sim_io_printf (sd, "M68HC11 EEprom:\n"); val = cpu->ios[M6811_PPROG]; print_io_byte (sd, "PPROG ", pprog_desc, val, base + M6811_PPROG); sim_io_printf (sd, "\n"); val = cpu->ios[M6811_CONFIG]; print_io_byte (sd, "CONFIG ", config_desc, val, base + M6811_CONFIG); sim_io_printf (sd, "\n"); val = controller->eeprom[controller->size - 1]; print_io_byte (sd, "(*NEXT*) ", config_desc, val, base + M6811_CONFIG); sim_io_printf (sd, "\n"); /* Describe internal state of EEPROM. */ if (controller->eeprom_wmode) { if (controller->eeprom_waddr == controller->size - 1) sim_io_printf (sd, " Programming CONFIG register "); else sim_io_printf (sd, " Programming: 0x%04x ", controller->eeprom_waddr + controller->base_address); sim_io_printf (sd, "with 0x%02x\n", controller->eeprom_wbyte); } sim_io_printf (sd, " EEProm file: %s\n", controller->file_name); }
void program_interrupt (SIM_DESC sd, sim_cpu *cpu, sim_cia cia, SIM_SIGNAL sig) { int status; struct hw *device; static int in_interrupt = 0; #ifdef SIM_CPU_EXCEPTION_TRIGGER SIM_CPU_EXCEPTION_TRIGGER(sd,cpu,cia); #endif /* avoid infinite recursion */ if (in_interrupt) sim_io_printf (sd, "ERROR: recursion in program_interrupt during software exception dispatch."); else { in_interrupt = 1; /* copy NMI handler code from dv-mn103cpu.c */ store_word (SP - 4, CPU_PC_GET (cpu)); store_half (SP - 8, PSW); /* Set the SYSEF flag in NMICR by backdoor method. See dv-mn103int.c:write_icr(). This is necessary because software exceptions are not modelled by actually talking to the interrupt controller, so it cannot set its own SYSEF flag. */ if ((NULL != board) && (strcmp(board, BOARD_AM32) == 0)) store_byte (0x34000103, 0x04); } PSW &= ~PSW_IE; SP = SP - 8; CPU_PC_SET (cpu, 0x40000008); in_interrupt = 0; sim_engine_halt(sd, cpu, NULL, cia, sim_stopped, sig); }
USI MY (f_break_handler) (SIM_CPU *cpu, USI breaknum, USI pc) { SIM_DESC sd = CPU_STATE (cpu); USI ret = pc + 2; MY (f_h_pc_set) (cpu, ret); /* FIXME: Error out if IBR or ERP set. */ switch (breaknum) { case 13: MY (f_h_gr_set (cpu, 10, cris_break_13_handler (cpu, MY (f_h_gr_get (cpu, 9)), MY (f_h_gr_get (cpu, 10)), MY (f_h_gr_get (cpu, 11)), MY (f_h_gr_get (cpu, 12)), MY (f_h_gr_get (cpu, 13)), MY (f_h_sr_get (cpu, 7)), MY (f_h_sr_get (cpu, 11)), pc))); break; case 14: sim_io_printf (sd, "%x\n", MY (f_h_gr_get (cpu, 3))); break; case 15: /* Re-use the Linux exit call. */ cris_break_13_handler (cpu, /* TARGET_SYS_exit */ 1, 0, 0, 0, 0, 0, 0, pc); default: abort (); } return MY (f_h_pc_get) (cpu); }
static void do_watchpoint_info (SIM_DESC sd) { sim_watchpoints *watch = STATE_WATCHPOINTS (sd); sim_watch_point *point; sim_io_printf (sd, "Watchpoints:\n"); for (point = watch->points; point != NULL; point = point->next) { sim_io_printf (sd, "%3d: watch %s %s ", point->ident, watchpoint_type_to_str (sd, point->type), interrupt_nr_to_str (sd, point->interrupt_nr)); if (point->is_periodic) sim_io_printf (sd, "+"); if (!point->is_within) sim_io_printf (sd, "!"); sim_io_printf (sd, "0x%lx", point->arg0); if (point->arg1 != point->arg0) sim_io_printf (sd, ",0x%lx", point->arg1); sim_io_printf (sd, "\n"); } }
static void m68hc11spi_info (struct hw *me) { SIM_DESC sd; uint16 base = 0; sim_cpu *cpu; struct m68hc11spi *controller; uint8 val; sd = hw_system (me); cpu = STATE_CPU (sd, 0); controller = hw_data (me); sim_io_printf (sd, "M68HC11 SPI:\n"); base = cpu_get_io_base (cpu); val = cpu->ios[M6811_SPCR]; print_io_byte (sd, "SPCR", spcr_desc, val, base + M6811_SPCR); sim_io_printf (sd, "\n"); val = cpu->ios[M6811_SPSR]; print_io_byte (sd, "SPSR", spsr_desc, val, base + M6811_SPSR); sim_io_printf (sd, "\n"); if (controller->spi_event) { signed64 t; sim_io_printf (sd, " SPI has %d bits to send\n", controller->tx_bit + 1); t = hw_event_remain_time (me, controller->spi_event); sim_io_printf (sd, " SPI current bit-cycle finished in %s\n", cycle_to_string (cpu, t, PRINT_TIME | PRINT_CYCLE)); t += (controller->tx_bit + 1) * 2 * controller->clock; sim_io_printf (sd, " SPI operation finished in %s\n", cycle_to_string (cpu, t, PRINT_TIME | PRINT_CYCLE)); } }
void print_sim_config (SIM_DESC sd) { sim_io_printf (sd, "WITH_TARGET_BYTE_ORDER = %s\n", config_byte_order_to_a (WITH_TARGET_BYTE_ORDER)); sim_io_printf (sd, "WITH_DEFAULT_TARGET_BYTE_ORDER = %s\n", config_byte_order_to_a (WITH_DEFAULT_TARGET_BYTE_ORDER)); sim_io_printf (sd, "HOST_BYTE_ORDER = %s\n", config_byte_order_to_a (HOST_BYTE_ORDER)); sim_io_printf (sd, "WITH_STDIO = %s\n", config_stdio_to_a (WITH_STDIO)); sim_io_printf (sd, "WITH_TARGET_WORD_MSB = %d\n", WITH_TARGET_WORD_MSB); sim_io_printf (sd, "WITH_TARGET_WORD_BITSIZE = %d\n", WITH_TARGET_WORD_BITSIZE); sim_io_printf (sd, "WITH_TARGET_ADDRESS_BITSIZE = %d\n", WITH_TARGET_ADDRESS_BITSIZE); sim_io_printf (sd, "WITH_TARGET_CELL_BITSIZE = %d\n", WITH_TARGET_CELL_BITSIZE); sim_io_printf (sd, "WITH_TARGET_FLOATING_POINT_BITSIZE = %d\n", WITH_TARGET_FLOATING_POINT_BITSIZE); sim_io_printf (sd, "WITH_ENVIRONMENT = %s\n", config_environment_to_a (WITH_ENVIRONMENT)); sim_io_printf (sd, "WITH_ALIGNMENT = %s\n", config_alignment_to_a (WITH_ALIGNMENT)); #if defined (WITH_DEFAULT_ALIGNMENT) sim_io_printf (sd, "WITH_DEFAULT_ALIGNMENT = %s\n", config_alignment_to_a (WITH_DEFAULT_ALIGNMENT)); #endif #if defined (WITH_XOR_ENDIAN) sim_io_printf (sd, "WITH_XOR_ENDIAN = %d\n", WITH_XOR_ENDIAN); #endif #if defined (WITH_FLOATING_POINT) sim_io_printf (sd, "WITH_FLOATING_POINT = %s\n", config_floating_point_to_a (WITH_FLOATING_POINT)); #endif #if defined (WITH_SMP) sim_io_printf (sd, "WITH_SMP = %d\n", WITH_SMP); #endif #if defined (WITH_RESERVED_BITS) sim_io_printf (sd, "WITH_RESERVED_BITS = %d\n", WITH_RESERVED_BITS); #endif #if defined (WITH_PROFILE) sim_io_printf (sd, "WITH_PROFILE = %d\n", WITH_PROFILE); #endif }
static SIM_RC standard_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt, char *arg, int is_command) { int i,n; switch ((STANDARD_OPTIONS) opt) { case OPTION_VERBOSE: STATE_VERBOSE_P (sd) = 1; break; #ifdef SIM_HAVE_BIENDIAN case OPTION_ENDIAN: if (strcmp (arg, "big") == 0) { if (WITH_TARGET_BYTE_ORDER == LITTLE_ENDIAN) { sim_io_eprintf (sd, "Simulator compiled for little endian only.\n"); return SIM_RC_FAIL; } /* FIXME:wip: Need to set something in STATE_CONFIG. */ current_target_byte_order = BIG_ENDIAN; } else if (strcmp (arg, "little") == 0) { if (WITH_TARGET_BYTE_ORDER == BIG_ENDIAN) { sim_io_eprintf (sd, "Simulator compiled for big endian only.\n"); return SIM_RC_FAIL; } /* FIXME:wip: Need to set something in STATE_CONFIG. */ current_target_byte_order = LITTLE_ENDIAN; } else { sim_io_eprintf (sd, "Invalid endian specification `%s'\n", arg); return SIM_RC_FAIL; } break; #endif case OPTION_ENVIRONMENT: if (strcmp (arg, "user") == 0) STATE_ENVIRONMENT (sd) = USER_ENVIRONMENT; else if (strcmp (arg, "virtual") == 0) STATE_ENVIRONMENT (sd) = VIRTUAL_ENVIRONMENT; else if (strcmp (arg, "operating") == 0) STATE_ENVIRONMENT (sd) = OPERATING_ENVIRONMENT; else { sim_io_eprintf (sd, "Invalid environment specification `%s'\n", arg); return SIM_RC_FAIL; } if (WITH_ENVIRONMENT != ALL_ENVIRONMENT && WITH_ENVIRONMENT != STATE_ENVIRONMENT (sd)) { char *type; switch (WITH_ENVIRONMENT) { case USER_ENVIRONMENT: type = "user"; break; case VIRTUAL_ENVIRONMENT: type = "virtual"; break; case OPERATING_ENVIRONMENT: type = "operating"; break; } sim_io_eprintf (sd, "Simulator compiled for the %s environment only.\n", type); return SIM_RC_FAIL; } break; case OPTION_ALIGNMENT: if (strcmp (arg, "strict") == 0) { if (WITH_ALIGNMENT == 0 || WITH_ALIGNMENT == STRICT_ALIGNMENT) { current_alignment = STRICT_ALIGNMENT; break; } } else if (strcmp (arg, "nonstrict") == 0) { if (WITH_ALIGNMENT == 0 || WITH_ALIGNMENT == NONSTRICT_ALIGNMENT) { current_alignment = NONSTRICT_ALIGNMENT; break; } } else if (strcmp (arg, "forced") == 0) { if (WITH_ALIGNMENT == 0 || WITH_ALIGNMENT == FORCED_ALIGNMENT) { current_alignment = FORCED_ALIGNMENT; break; } } else { sim_io_eprintf (sd, "Invalid alignment specification `%s'\n", arg); return SIM_RC_FAIL; } switch (WITH_ALIGNMENT) { case STRICT_ALIGNMENT: sim_io_eprintf (sd, "Simulator compiled for strict alignment only.\n"); break; case NONSTRICT_ALIGNMENT: sim_io_eprintf (sd, "Simulator compiled for nonstrict alignment only.\n"); break; case FORCED_ALIGNMENT: sim_io_eprintf (sd, "Simulator compiled for forced alignment only.\n"); break; } return SIM_RC_FAIL; case OPTION_DEBUG: if (! WITH_DEBUG) sim_io_eprintf (sd, "Debugging not compiled in, `-D' ignored\n"); else { for (n = 0; n < MAX_NR_PROCESSORS; ++n) for (i = 0; i < MAX_DEBUG_VALUES; ++i) CPU_DEBUG_FLAGS (STATE_CPU (sd, n))[i] = 1; } break; case OPTION_DEBUG_INSN : if (! WITH_DEBUG) sim_io_eprintf (sd, "Debugging not compiled in, `--debug-insn' ignored\n"); else { for (n = 0; n < MAX_NR_PROCESSORS; ++n) CPU_DEBUG_FLAGS (STATE_CPU (sd, n))[DEBUG_INSN_IDX] = 1; } break; case OPTION_DEBUG_FILE : if (! WITH_DEBUG) sim_io_eprintf (sd, "Debugging not compiled in, `--debug-file' ignored\n"); else { FILE *f = fopen (arg, "w"); if (f == NULL) { sim_io_eprintf (sd, "Unable to open debug output file `%s'\n", arg); return SIM_RC_FAIL; } for (n = 0; n < MAX_NR_PROCESSORS; ++n) CPU_DEBUG_FILE (STATE_CPU (sd, n)) = f; } break; #ifdef SIM_H8300 /* FIXME: Can be moved to h8300 dir. */ case OPTION_H8300: set_h8300h (1,0); break; case OPTION_H8300S: set_h8300h (1,1); break; #endif #ifdef SIM_HAVE_FLATMEM case OPTION_MEM_SIZE: { unsigned long ul = strtol (arg, NULL, 0); /* 16384: some minimal amount */ if (! isdigit (arg[0]) || ul < 16384) { sim_io_eprintf (sd, "Invalid memory size `%s'", arg); return SIM_RC_FAIL; } STATE_MEM_SIZE (sd) = ul; } break; #endif case OPTION_DO_COMMAND: sim_do_command (sd, arg); break; case OPTION_ARCHITECTURE: { const struct bfd_arch_info *ap = bfd_scan_arch (arg); if (ap == NULL) { sim_io_eprintf (sd, "Architecture `%s' unknown\n", arg); return SIM_RC_FAIL; } STATE_ARCHITECTURE (sd) = ap; break; } case OPTION_ARCHITECTURE_INFO: { const char **list = bfd_arch_list(); const char **lp; if (list == NULL) abort (); sim_io_printf (sd, "Possible architectures:"); for (lp = list; *lp != NULL; lp++) sim_io_printf (sd, " %s", *lp); sim_io_printf (sd, "\n"); free (list); break; } case OPTION_TARGET: { STATE_TARGET (sd) = xstrdup (arg); break; } case OPTION_LOAD_LMA: { STATE_LOAD_AT_LMA_P (sd) = 1; break; } case OPTION_LOAD_VMA: { STATE_LOAD_AT_LMA_P (sd) = 0; break; } case OPTION_HELP: sim_print_help (sd, is_command); if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE) exit (0); /* FIXME: 'twould be nice to do something similar if gdb. */ break; } return SIM_RC_OK; }
void interrupts_info (SIM_DESC sd, struct interrupts *interrupts) { signed64 t, prev_interrupt; int i; sim_io_printf (sd, "Interrupts Info:\n"); sim_io_printf (sd, " Interrupts raised: %lu\n", interrupts->nb_interrupts_raised); if (interrupts->start_mask_cycle >= 0) { t = cpu_current_cycle (interrupts->cpu); t -= interrupts->start_mask_cycle; if (t > interrupts->max_mask_cycles) interrupts->max_mask_cycles = t; sim_io_printf (sd, " Current interrupts masked sequence: %s\n", cycle_to_string (interrupts->cpu, t, PRINT_TIME | PRINT_CYCLE)); } t = interrupts->min_mask_cycles == CYCLES_MAX ? interrupts->max_mask_cycles : interrupts->min_mask_cycles; sim_io_printf (sd, " Shortest interrupts masked sequence: %s\n", cycle_to_string (interrupts->cpu, t, PRINT_TIME | PRINT_CYCLE)); t = interrupts->max_mask_cycles; sim_io_printf (sd, " Longest interrupts masked sequence: %s\n", cycle_to_string (interrupts->cpu, t, PRINT_TIME | PRINT_CYCLE)); t = interrupts->last_mask_cycles; sim_io_printf (sd, " Last interrupts masked sequence: %s\n", cycle_to_string (interrupts->cpu, t, PRINT_TIME | PRINT_CYCLE)); if (interrupts->xirq_start_mask_cycle >= 0) { t = cpu_current_cycle (interrupts->cpu); t -= interrupts->xirq_start_mask_cycle; if (t > interrupts->xirq_max_mask_cycles) interrupts->xirq_max_mask_cycles = t; sim_io_printf (sd, " XIRQ Current interrupts masked sequence: %s\n", cycle_to_string (interrupts->cpu, t, PRINT_TIME | PRINT_CYCLE)); } t = interrupts->xirq_min_mask_cycles == CYCLES_MAX ? interrupts->xirq_max_mask_cycles : interrupts->xirq_min_mask_cycles; sim_io_printf (sd, " XIRQ Min interrupts masked sequence: %s\n", cycle_to_string (interrupts->cpu, t, PRINT_TIME | PRINT_CYCLE)); t = interrupts->xirq_max_mask_cycles; sim_io_printf (sd, " XIRQ Max interrupts masked sequence: %s\n", cycle_to_string (interrupts->cpu, t, PRINT_TIME | PRINT_CYCLE)); t = interrupts->xirq_last_mask_cycles; sim_io_printf (sd, " XIRQ Last interrupts masked sequence: %s\n", cycle_to_string (interrupts->cpu, t, PRINT_TIME | PRINT_CYCLE)); if (interrupts->pending_mask) { sim_io_printf (sd, " Pending interrupts : "); for (i = 0; i < M6811_INT_NUMBER; i++) { enum M6811_INT int_number = interrupts->interrupt_order[i]; if (interrupts->pending_mask & (1 << int_number)) { sim_io_printf (sd, "%s ", interrupt_names[int_number]); } } sim_io_printf (sd, "\n"); } prev_interrupt = 0; sim_io_printf (sd, "N Interrupt Cycle Taken Latency" " Delta between interrupts\n"); for (i = 0; i < MAX_INT_HISTORY; i++) { int which; struct interrupt_history *h; signed64 dt; which = interrupts->history_index - i - 1; if (which < 0) which += MAX_INT_HISTORY; h = &interrupts->interrupts_history[which]; if (h->taken_cycle == 0) break; dt = h->taken_cycle - h->raised_cycle; sim_io_printf (sd, "%2d %-9.9s %15.15s ", i, interrupt_names[h->type], cycle_to_string (interrupts->cpu, h->taken_cycle, 0)); sim_io_printf (sd, "%15.15s", cycle_to_string (interrupts->cpu, dt, 0)); if (prev_interrupt) { dt = prev_interrupt - h->taken_cycle; sim_io_printf (sd, " %s", cycle_to_string (interrupts->cpu, dt, PRINT_TIME)); } sim_io_printf (sd, "\n"); prev_interrupt = h->taken_cycle; } }
/* Process the current interrupt if there is one. This operation must be called after each instruction to handle the interrupts. If interrupts are masked, it does nothing. */ int interrupts_process (struct interrupts *interrupts) { int id; uint8 ccr; /* See if interrupts are enabled/disabled and keep track of the number of cycles the interrupts are masked. Such information is then reported by the info command. */ ccr = cpu_get_ccr (interrupts->cpu); if (ccr & M6811_I_BIT) { if (interrupts->start_mask_cycle < 0) interrupts->start_mask_cycle = cpu_current_cycle (interrupts->cpu); } else if (interrupts->start_mask_cycle >= 0 && (ccr & M6811_I_BIT) == 0) { signed64 t = cpu_current_cycle (interrupts->cpu); t -= interrupts->start_mask_cycle; if (t < interrupts->min_mask_cycles) interrupts->min_mask_cycles = t; if (t > interrupts->max_mask_cycles) interrupts->max_mask_cycles = t; interrupts->start_mask_cycle = -1; interrupts->last_mask_cycles = t; } if (ccr & M6811_X_BIT) { if (interrupts->xirq_start_mask_cycle < 0) interrupts->xirq_start_mask_cycle = cpu_current_cycle (interrupts->cpu); } else if (interrupts->xirq_start_mask_cycle >= 0 && (ccr & M6811_X_BIT) == 0) { signed64 t = cpu_current_cycle (interrupts->cpu); t -= interrupts->xirq_start_mask_cycle; if (t < interrupts->xirq_min_mask_cycles) interrupts->xirq_min_mask_cycles = t; if (t > interrupts->xirq_max_mask_cycles) interrupts->xirq_max_mask_cycles = t; interrupts->xirq_start_mask_cycle = -1; interrupts->xirq_last_mask_cycles = t; } id = interrupts_get_current (interrupts); if (id >= 0) { uint16 addr; struct interrupt_history *h; /* Implement the breakpoint-on-interrupt. */ if (interrupts->interrupts[id].stop_mode & SIM_STOP_WHEN_TAKEN) { sim_io_printf (CPU_STATE (interrupts->cpu), "Interrupt %s will be handled\n", interrupt_names[id]); sim_engine_halt (CPU_STATE (interrupts->cpu), interrupts->cpu, 0, cpu_get_pc (interrupts->cpu), sim_stopped, SIM_SIGTRAP); } cpu_push_all (interrupts->cpu); addr = memory_read16 (interrupts->cpu, interrupts->vectors_addr + id * 2); cpu_call (interrupts->cpu, addr); /* Now, protect from nested interrupts. */ if (id == M6811_INT_XIRQ) { cpu_set_ccr_X (interrupts->cpu, 1); } else { cpu_set_ccr_I (interrupts->cpu, 1); } /* Update the interrupt history table. */ h = &interrupts->interrupts_history[interrupts->history_index]; h->type = id; h->taken_cycle = cpu_current_cycle (interrupts->cpu); h->raised_cycle = interrupts->interrupts[id].cpu_cycle; if (interrupts->history_index >= MAX_INT_HISTORY-1) interrupts->history_index = 0; else interrupts->history_index++; interrupts->nb_interrupts_raised++; cpu_add_cycles (interrupts->cpu, 14); return 1; } return 0; }
/* Update the mask of pending interrupts. This operation must be called when the state of some 68HC11 IO register changes. It looks the different registers that indicate a pending interrupt (timer, SCI, SPI, ...) and records the interrupt if it's there and enabled. */ void interrupts_update_pending (struct interrupts *interrupts) { int i; uint8 *ioregs; unsigned long clear_mask; unsigned long set_mask; clear_mask = 0; set_mask = 0; ioregs = &interrupts->cpu->ios[0]; for (i = 0; i < TableSize(idefs); i++) { struct interrupt_def *idef = &idefs[i]; uint8 data; /* Look if the interrupt is enabled. */ if (idef->enable_paddr) { data = ioregs[idef->enable_paddr]; if (!(data & idef->enabled_mask)) { /* Disable it. */ clear_mask |= (1 << idef->int_number); continue; } } /* Interrupt is enabled, see if it's there. */ data = ioregs[idef->int_paddr]; if (!(data & idef->int_mask)) { /* Disable it. */ clear_mask |= (1 << idef->int_number); continue; } /* Ok, raise it. */ set_mask |= (1 << idef->int_number); } /* Some interrupts are shared (M6811_INT_SCI) so clear the interrupts before setting the new ones. */ interrupts->pending_mask &= ~clear_mask; interrupts->pending_mask |= set_mask; /* Keep track of when the interrupt is raised by the device. Also implements the breakpoint-on-interrupt. */ if (set_mask) { signed64 cycle = cpu_current_cycle (interrupts->cpu); int must_stop = 0; for (i = 0; i < M6811_INT_NUMBER; i++) { if (!(set_mask & (1 << i))) continue; interrupts->interrupts[i].cpu_cycle = cycle; if (interrupts->interrupts[i].stop_mode & SIM_STOP_WHEN_RAISED) { must_stop = 1; sim_io_printf (CPU_STATE (interrupts->cpu), "Interrupt %s raised\n", interrupt_names[i]); } } if (must_stop) sim_engine_halt (CPU_STATE (interrupts->cpu), interrupts->cpu, 0, cpu_get_pc (interrupts->cpu), sim_stopped, SIM_SIGTRAP); } }
static bool bfin_fdpic_load (SIM_DESC sd, SIM_CPU *cpu, struct bfd *abfd, bu32 *sp, bu32 *elf_addrs, char **ldso_path) { bool ret; int i; Elf_Internal_Ehdr *iehdr; Elf32_External_Ehdr ehdr; Elf_Internal_Phdr *phdrs; unsigned char *data; long phdr_size; int phdrc; bu32 nsegs; bu32 max_load_addr; unsigned char null[4] = { 0, 0, 0, 0 }; ret = false; *ldso_path = NULL; /* See if this an FDPIC ELF. */ phdrs = NULL; if (!abfd) goto skip_fdpic_init; if (bfd_seek (abfd, 0, SEEK_SET) != 0) goto skip_fdpic_init; if (bfd_bread (&ehdr, sizeof (ehdr), abfd) != sizeof (ehdr)) goto skip_fdpic_init; iehdr = elf_elfheader (abfd); if (!(iehdr->e_flags & EF_BFIN_FDPIC)) goto skip_fdpic_init; if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG) sim_io_printf (sd, "Loading FDPIC ELF %s\n Load base: %#x\n ELF entry: %#x\n", bfd_get_filename (abfd), fdpic_load_offset, elf_addrs[0]); /* Grab the Program Headers to set up the loadsegs on the stack. */ phdr_size = bfd_get_elf_phdr_upper_bound (abfd); if (phdr_size == -1) goto skip_fdpic_init; phdrs = xmalloc (phdr_size); phdrc = bfd_get_elf_phdrs (abfd, phdrs); if (phdrc == -1) goto skip_fdpic_init; /* Push the Ehdr onto the stack. */ *sp -= sizeof (ehdr); elf_addrs[3] = *sp; sim_write (sd, *sp, (void *)&ehdr, sizeof (ehdr)); if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG) sim_io_printf (sd, " Elf_Ehdr: %#x\n", *sp); /* Since we're relocating things ourselves, we need to relocate the start address as well. */ elf_addrs[0] = bfd_get_start_address (abfd) + fdpic_load_offset; /* And the Exec's Phdrs onto the stack. */ if (STATE_PROG_BFD (sd) == abfd) { elf_addrs[4] = elf_addrs[0]; phdr_size = iehdr->e_phentsize * iehdr->e_phnum; if (bfd_seek (abfd, iehdr->e_phoff, SEEK_SET) != 0) goto skip_fdpic_init; data = xmalloc (phdr_size); if (bfd_bread (data, phdr_size, abfd) != phdr_size) goto skip_fdpic_init; *sp -= phdr_size; elf_addrs[1] = *sp; elf_addrs[2] = phdrc; sim_write (sd, *sp, data, phdr_size); free (data); if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG) sim_io_printf (sd, " Elf_Phdrs: %#x\n", *sp); } /* Now push all the loadsegs. */ nsegs = 0; max_load_addr = 0; for (i = phdrc; i >= 0; --i) if (phdrs[i].p_type == PT_LOAD) { Elf_Internal_Phdr *p = &phdrs[i]; bu32 paddr, vaddr, memsz, filesz; paddr = p->p_paddr + fdpic_load_offset; vaddr = p->p_vaddr; memsz = p->p_memsz; filesz = p->p_filesz; if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG) sim_io_printf (sd, " PHDR %i: vma %#x lma %#x filesz %#x memsz %#x\n", i, vaddr, paddr, filesz, memsz); data = xmalloc (memsz); if (memsz != filesz) memset (data + filesz, 0, memsz - filesz); if (bfd_seek (abfd, p->p_offset, SEEK_SET) == 0 && bfd_bread (data, filesz, abfd) == filesz) sim_write (sd, paddr, data, memsz); free (data); max_load_addr = MAX (paddr + memsz, max_load_addr); *sp -= 12; sim_write (sd, *sp+0, (void *)&paddr, 4); /* loadseg.addr */ sim_write (sd, *sp+4, (void *)&vaddr, 4); /* loadseg.p_vaddr */ sim_write (sd, *sp+8, (void *)&memsz, 4); /* loadseg.p_memsz */ ++nsegs; } else if (phdrs[i].p_type == PT_DYNAMIC) { elf_addrs[5] = phdrs[i].p_paddr + fdpic_load_offset; if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG) sim_io_printf (sd, " PT_DYNAMIC: %#x\n", elf_addrs[5]); } else if (phdrs[i].p_type == PT_INTERP) { uint32_t off = phdrs[i].p_offset; uint32_t len = phdrs[i].p_filesz; *ldso_path = xmalloc (len); if (bfd_seek (abfd, off, SEEK_SET) != 0 || bfd_bread (*ldso_path, len, abfd) != len) { free (*ldso_path); *ldso_path = NULL; } else if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG) sim_io_printf (sd, " PT_INTERP: %s\n", *ldso_path); } /* Update the load offset with a few extra pages. */ fdpic_load_offset = ALIGN (MAX (max_load_addr, fdpic_load_offset), 0x10000); fdpic_load_offset += 0x10000; /* Push the summary loadmap info onto the stack last. */ *sp -= 4; sim_write (sd, *sp+0, null, 2); /* loadmap.version */ sim_write (sd, *sp+2, (void *)&nsegs, 2); /* loadmap.nsegs */ ret = true; skip_fdpic_init: free (phdrs); return ret; }
/* Handle TRA and TIRA insns. */ void frv_itrap (SIM_CPU *current_cpu, PCADDR pc, USI base, SI offset) { SIM_DESC sd = CPU_STATE (current_cpu); host_callback *cb = STATE_CALLBACK (sd); USI num = ((base + offset) & 0x7f) + 0x80; #ifdef SIM_HAVE_BREAKPOINTS /* Check for breakpoints "owned" by the simulator first, regardless of --environment. */ if (num == TRAP_BREAKPOINT) { /* First try sim-break.c. If it's a breakpoint the simulator "owns" it doesn't return. Otherwise it returns and let's us try. */ sim_handle_breakpoint (sd, current_cpu, pc); /* Fall through. */ } #endif if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT) { frv_queue_software_interrupt (current_cpu, num); return; } switch (num) { case TRAP_SYSCALL : { CB_SYSCALL s; CB_SYSCALL_INIT (&s); s.func = GET_H_GR (7); s.arg1 = GET_H_GR (8); s.arg2 = GET_H_GR (9); s.arg3 = GET_H_GR (10); if (s.func == TARGET_SYS_exit) { sim_engine_halt (sd, current_cpu, NULL, pc, sim_exited, s.arg1); } s.p1 = (PTR) sd; s.p2 = (PTR) current_cpu; s.read_mem = syscall_read_mem; s.write_mem = syscall_write_mem; cb_syscall (cb, &s); SET_H_GR (8, s.result); SET_H_GR (9, s.result2); SET_H_GR (10, s.errcode); break; } case TRAP_BREAKPOINT: sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP); break; /* Add support for dumping registers, either at fixed traps, or all unknown traps if configured with --enable-sim-trapdump. */ default: #if !TRAPDUMP frv_queue_software_interrupt (current_cpu, num); return; #endif #ifdef TRAP_REGDUMP1 case TRAP_REGDUMP1: #endif #ifdef TRAP_REGDUMP2 case TRAP_REGDUMP2: #endif #if TRAPDUMP || (defined (TRAP_REGDUMP1)) || (defined (TRAP_REGDUMP2)) { char buf[256]; int i, j; buf[0] = 0; if (STATE_TEXT_SECTION (sd) && pc >= STATE_TEXT_START (sd) && pc < STATE_TEXT_END (sd)) { const char *pc_filename = (const char *)0; const char *pc_function = (const char *)0; unsigned int pc_linenum = 0; if (bfd_find_nearest_line (STATE_PROG_BFD (sd), STATE_TEXT_SECTION (sd), (struct bfd_symbol **) 0, pc - STATE_TEXT_START (sd), &pc_filename, &pc_function, &pc_linenum) && (pc_function || pc_filename)) { char *p = buf+2; buf[0] = ' '; buf[1] = '('; if (pc_function) { strcpy (p, pc_function); p += strlen (p); } else { char *q = (char *) strrchr (pc_filename, '/'); strcpy (p, (q) ? q+1 : pc_filename); p += strlen (p); } if (pc_linenum) { sprintf (p, " line %d", pc_linenum); p += strlen (p); } p[0] = ')'; p[1] = '\0'; if ((p+1) - buf > sizeof (buf)) abort (); } } sim_io_printf (sd, "\nRegister dump, pc = 0x%.8x%s, base = %u, offset = %d\n", (unsigned)pc, buf, (unsigned)base, (int)offset); for (i = 0; i < 64; i += 8) { long g0 = (long)GET_H_GR (i); long g1 = (long)GET_H_GR (i+1); long g2 = (long)GET_H_GR (i+2); long g3 = (long)GET_H_GR (i+3); long g4 = (long)GET_H_GR (i+4); long g5 = (long)GET_H_GR (i+5); long g6 = (long)GET_H_GR (i+6); long g7 = (long)GET_H_GR (i+7); if ((g0 | g1 | g2 | g3 | g4 | g5 | g6 | g7) != 0) sim_io_printf (sd, "\tgr%02d - gr%02d: 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx\n", i, i+7, g0, g1, g2, g3, g4, g5, g6, g7); } for (i = 0; i < 64; i += 8) { long f0 = (long)GET_H_FR (i); long f1 = (long)GET_H_FR (i+1); long f2 = (long)GET_H_FR (i+2); long f3 = (long)GET_H_FR (i+3); long f4 = (long)GET_H_FR (i+4); long f5 = (long)GET_H_FR (i+5); long f6 = (long)GET_H_FR (i+6); long f7 = (long)GET_H_FR (i+7); if ((f0 | f1 | f2 | f3 | f4 | f5 | f6 | f7) != 0) sim_io_printf (sd, "\tfr%02d - fr%02d: 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx\n", i, i+7, f0, f1, f2, f3, f4, f5, f6, f7); } sim_io_printf (sd, "\tlr/lcr/cc/ccc: 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx\n", (long)GET_H_SPR (272), (long)GET_H_SPR (273), (long)GET_H_SPR (256), (long)GET_H_SPR (263)); } break; #endif } }
static void m68hc11tim_info (struct hw *me) { SIM_DESC sd; uint16 base = 0; sim_cpu *cpu; struct m68hc11tim *controller; uint8 val; uint16 val16; sd = hw_system (me); cpu = STATE_CPU (sd, 0); controller = hw_data (me); sim_io_printf (sd, "M68HC11 Timer:\n"); base = cpu_get_io_base (cpu); /* Info for TIC1 */ val16 = (cpu->ios[M6811_TIC1_H] << 8) + cpu->ios[M6811_TIC1_L]; print_io_word (sd, "TIC1 ", 0, val16, base + M6811_TIC1); sim_io_printf (sd, "\n"); /* Info for TIC2 */ val16 = (cpu->ios[M6811_TIC2_H] << 8) + cpu->ios[M6811_TIC2_L]; print_io_word (sd, "TIC2 ", 0, val16, base + M6811_TIC2); sim_io_printf (sd, "\n"); /* Info for TIC3 */ val16 = (cpu->ios[M6811_TIC3_H] << 8) + cpu->ios[M6811_TIC3_L]; print_io_word (sd, "TIC3 ", 0, val16, base + M6811_TIC3); sim_io_printf (sd, "\n"); /* Info for TOC1 */ val16 = (cpu->ios[M6811_TOC1_H] << 8) + cpu->ios[M6811_TOC1_L]; print_io_word (sd, "TOC1 ", 0, val16, base + M6811_TOC1); sim_io_printf (sd, "\n"); /* Info for TOC2 */ val16 = (cpu->ios[M6811_TOC2_H] << 8) + cpu->ios[M6811_TOC2_L]; print_io_word (sd, "TOC2 ", 0, val16, base + M6811_TOC2); sim_io_printf (sd, "\n"); /* Info for TOC3 */ val16 = (cpu->ios[M6811_TOC3_H] << 8) + cpu->ios[M6811_TOC3_L]; print_io_word (sd, "TOC3 ", 0, val16, base + M6811_TOC3); sim_io_printf (sd, "\n"); /* Info for TOC4 */ val16 = (cpu->ios[M6811_TOC4_H] << 8) + cpu->ios[M6811_TOC4_L]; print_io_word (sd, "TOC4 ", 0, val16, base + M6811_TOC4); sim_io_printf (sd, "\n"); /* Info for TOC5 */ val16 = (cpu->ios[M6811_TOC5_H] << 8) + cpu->ios[M6811_TOC5_L]; print_io_word (sd, "TOC5 ", 0, val16, base + M6811_TOC5); sim_io_printf (sd, "\n"); /* Info for TMSK1 */ val = cpu->ios[M6811_TMSK1]; print_io_byte (sd, "TMSK1 ", tmsk1_desc, val, base + M6811_TMSK1); sim_io_printf (sd, "\n"); /* Info for TFLG1 */ val = cpu->ios[M6811_TFLG1]; print_io_byte (sd, "TFLG1", tflg1_desc, val, base + M6811_TFLG1); sim_io_printf (sd, "\n"); val = cpu->ios[M6811_TMSK2]; print_io_byte (sd, "TMSK2 ", tmsk2_desc, val, base + M6811_TMSK2); sim_io_printf (sd, "\n"); val = cpu->ios[M6811_TFLG2]; print_io_byte (sd, "TFLG2", tflg2_desc, val, base + M6811_TFLG2); sim_io_printf (sd, "\n"); val = cpu->ios[M6811_PACTL]; print_io_byte (sd, "PACTL", pactl_desc, val, base + M6811_PACTL); sim_io_printf (sd, "\n"); val = cpu->ios[M6811_PACNT]; print_io_byte (sd, "PACNT", 0, val, base + M6811_PACNT); sim_io_printf (sd, "\n"); /* Give info about the next timer interrupts. */ m68hc11tim_print_timer (me, "RTI", controller->rti_timer_event); m68hc11tim_print_timer (me, "COP", controller->cop_timer_event); m68hc11tim_print_timer (me, "OVERFLOW", controller->tof_timer_event); m68hc11tim_print_timer (me, "COMPARE", controller->cmp_timer_event); }
static SIM_RC memory_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt, char *arg, int is_command) { switch (opt) { case OPTION_MEMORY_DELETE: if (strcasecmp (arg, "all") == 0) { while (STATE_MEMOPT (sd) != NULL) do_memopt_delete (sd, STATE_MEMOPT (sd)->level, STATE_MEMOPT (sd)->space, STATE_MEMOPT (sd)->addr); return SIM_RC_OK; } else { int level = 0; int space = 0; address_word addr = 0; parse_addr (arg, &level, &space, &addr); return do_memopt_delete (sd, level, space, addr); } case OPTION_MEMORY_REGION: { char *chp = arg; int level = 0; int space = 0; address_word addr = 0; address_word nr_bytes = 0; unsigned modulo = 0; /* parse the arguments */ chp = parse_addr (chp, &level, &space, &addr); if (*chp != ',') { sim_io_eprintf (sd, "Missing size for memory-region\n"); return SIM_RC_FAIL; } chp = parse_size (chp + 1, &nr_bytes, &modulo); /* old style */ if (*chp == ',') modulo = strtoul (chp + 1, &chp, 0); /* try to attach/insert it */ do_memopt_add (sd, level, space, addr, nr_bytes, modulo, &STATE_MEMOPT (sd), NULL); return SIM_RC_OK; } case OPTION_MEMORY_ALIAS: { char *chp = arg; int level = 0; int space = 0; address_word addr = 0; address_word nr_bytes = 0; unsigned modulo = 0; sim_memopt *entry; /* parse the arguments */ chp = parse_addr (chp, &level, &space, &addr); if (*chp != ',') { sim_io_eprintf (sd, "Missing size for memory-region\n"); return SIM_RC_FAIL; } chp = parse_size (chp + 1, &nr_bytes, &modulo); /* try to attach/insert the main record */ entry = do_memopt_add (sd, level, space, addr, nr_bytes, modulo, &STATE_MEMOPT (sd), NULL); /* now attach all the aliases */ while (*chp == ',') { int a_level = level; int a_space = space; address_word a_addr = addr; chp = parse_addr (chp + 1, &a_level, &a_space, &a_addr); do_memopt_add (sd, a_level, a_space, a_addr, nr_bytes, modulo, &entry->alias, entry->buffer); } return SIM_RC_OK; } case OPTION_MEMORY_SIZE: { int level = 0; int space = 0; address_word addr = 0; address_word nr_bytes = 0; unsigned modulo = 0; /* parse the arguments */ parse_size (arg, &nr_bytes, &modulo); /* try to attach/insert it */ do_memopt_add (sd, level, space, addr, nr_bytes, modulo, &STATE_MEMOPT (sd), NULL); return SIM_RC_OK; } case OPTION_MEMORY_CLEAR: { fill_byte_value = (unsigned8) 0; fill_byte_flag = 1; return SIM_RC_OK; break; } case OPTION_MEMORY_FILL: { unsigned long fill_value; parse_ulong_value (arg, &fill_value); if (fill_value > 255) { sim_io_eprintf (sd, "Missing fill value between 0 and 255\n"); return SIM_RC_FAIL; } fill_byte_value = (unsigned8) fill_value; fill_byte_flag = 1; return SIM_RC_OK; break; } case OPTION_MEMORY_INFO: { sim_memopt *entry; sim_io_printf (sd, "Memory maps:\n"); for (entry = STATE_MEMOPT (sd); entry != NULL; entry = entry->next) { sim_memopt *alias; sim_io_printf (sd, " memory"); if (entry->alias == NULL) sim_io_printf (sd, " region "); else sim_io_printf (sd, " alias "); if (entry->space != 0) sim_io_printf (sd, "0x%lx:", (long) entry->space); sim_io_printf (sd, "0x%08lx", (long) entry->addr); if (entry->level != 0) sim_io_printf (sd, "@0x%lx", (long) entry->level); sim_io_printf (sd, ",0x%lx", (long) entry->nr_bytes); if (entry->modulo != 0) sim_io_printf (sd, "%%0x%lx", (long) entry->modulo); for (alias = entry->alias; alias != NULL; alias = alias->next) { if (alias->space != 0) sim_io_printf (sd, "0x%lx:", (long) alias->space); sim_io_printf (sd, ",0x%08lx", (long) alias->addr); if (alias->level != 0) sim_io_printf (sd, "@0x%lx", (long) alias->level); } sim_io_printf (sd, "\n"); } return SIM_RC_OK; break; } default: sim_io_eprintf (sd, "Unknown memory option %d\n", opt); return SIM_RC_FAIL; } return SIM_RC_FAIL; }
void print_sim_config (SIM_DESC sd) { #if defined (__GNUC__) && defined (__VERSION__) sim_io_printf (sd, "Compiled by GCC %s on %s %s\n", __VERSION__, __DATE__, __TIME__); #else sim_io_printf (sd, "Compiled on %s %s\n", __DATE__, __TIME__); #endif sim_io_printf (sd, "WITH_TARGET_BYTE_ORDER = %s\n", config_byte_order_to_a (WITH_TARGET_BYTE_ORDER)); sim_io_printf (sd, "WITH_DEFAULT_TARGET_BYTE_ORDER = %s\n", config_byte_order_to_a (WITH_DEFAULT_TARGET_BYTE_ORDER)); sim_io_printf (sd, "WITH_HOST_BYTE_ORDER = %s\n", config_byte_order_to_a (WITH_HOST_BYTE_ORDER)); sim_io_printf (sd, "WITH_STDIO = %s\n", config_stdio_to_a (WITH_STDIO)); sim_io_printf (sd, "WITH_TARGET_WORD_MSB = %d\n", WITH_TARGET_WORD_MSB); sim_io_printf (sd, "WITH_TARGET_WORD_BITSIZE = %d\n", WITH_TARGET_WORD_BITSIZE); sim_io_printf (sd, "WITH_TARGET_ADDRESS_BITSIZE = %d\n", WITH_TARGET_ADDRESS_BITSIZE); sim_io_printf (sd, "WITH_TARGET_CELL_BITSIZE = %d\n", WITH_TARGET_CELL_BITSIZE); sim_io_printf (sd, "WITH_TARGET_FLOATING_POINT_BITSIZE = %d\n", WITH_TARGET_FLOATING_POINT_BITSIZE); sim_io_printf (sd, "WITH_ENVIRONMENT = %s\n", config_environment_to_a (WITH_ENVIRONMENT)); sim_io_printf (sd, "WITH_ALIGNMENT = %s\n", config_alignment_to_a (WITH_ALIGNMENT)); #if defined (WITH_DEFAULT_ALIGNMENT) sim_io_printf (sd, "WITH_DEFAULT_ALIGNMENT = %s\n", config_alignment_to_a (WITH_DEFAULT_ALIGNMENT)); #endif #if defined (WITH_XOR_ENDIAN) sim_io_printf (sd, "WITH_XOR_ENDIAN = %d\n", WITH_XOR_ENDIAN); #endif #if defined (WITH_FLOATING_POINT) sim_io_printf (sd, "WITH_FLOATING_POINT = %s\n", config_floating_point_to_a (WITH_FLOATING_POINT)); #endif #if defined (WITH_SMP) sim_io_printf (sd, "WITH_SMP = %d\n", WITH_SMP); #endif #if defined (WITH_RESERVED_BITS) sim_io_printf (sd, "WITH_RESERVED_BITS = %d\n", WITH_RESERVED_BITS); #endif #if defined (WITH_PROFILE) sim_io_printf (sd, "WITH_PROFILE = %d\n", WITH_PROFILE); #endif }
void scache_print_profile (SIM_CPU *cpu, int verbose) { SIM_DESC sd = CPU_STATE (cpu); unsigned long hits = CPU_SCACHE_HITS (cpu); unsigned long misses = CPU_SCACHE_MISSES (cpu); char buf[20]; unsigned long max_val; unsigned long *lengths; int i; if (CPU_SCACHE_SIZE (cpu) == 0) return; sim_io_printf (sd, "Simulator Cache Statistics\n\n"); /* One could use PROFILE_LABEL_WIDTH here. I chose not to. */ sim_io_printf (sd, " Cache size: %s\n", sim_add_commas (buf, sizeof (buf), CPU_SCACHE_SIZE (cpu))); sim_io_printf (sd, " Hits: %s\n", sim_add_commas (buf, sizeof (buf), hits)); sim_io_printf (sd, " Misses: %s\n", sim_add_commas (buf, sizeof (buf), misses)); if (hits + misses != 0) sim_io_printf (sd, " Hit rate: %.2f%%\n", ((double) hits / ((double) hits + (double) misses)) * 100); #if WITH_SCACHE_PBB sim_io_printf (sd, "\n"); sim_io_printf (sd, " Hash table size: %s\n", sim_add_commas (buf, sizeof (buf), CPU_SCACHE_NUM_HASH_CHAINS (cpu))); sim_io_printf (sd, " Max hash list length: %s\n", sim_add_commas (buf, sizeof (buf), CPU_SCACHE_NUM_HASH_CHAIN_ENTRIES (cpu))); sim_io_printf (sd, " Max insn chain length: %s\n", sim_add_commas (buf, sizeof (buf), CPU_SCACHE_MAX_CHAIN_LENGTH (cpu))); sim_io_printf (sd, " Cache full flushes: %s\n", sim_add_commas (buf, sizeof (buf), CPU_SCACHE_FULL_FLUSHES (cpu))); sim_io_printf (sd, "\n"); if (verbose) { sim_io_printf (sd, " Insn chain lengths:\n\n"); max_val = 0; lengths = CPU_SCACHE_CHAIN_LENGTHS (cpu); for (i = 1; i < CPU_SCACHE_MAX_CHAIN_LENGTH (cpu); ++i) if (lengths[i] > max_val) max_val = lengths[i]; for (i = 1; i < CPU_SCACHE_MAX_CHAIN_LENGTH (cpu); ++i) { sim_io_printf (sd, " %2d: %*s: ", i, max_val < 10000 ? 5 : 10, sim_add_commas (buf, sizeof (buf), lengths[i])); sim_profile_print_bar (sd, cpu, PROFILE_HISTOGRAM_WIDTH, lengths[i], max_val); sim_io_printf (sd, "\n"); } sim_io_printf (sd, "\n"); } #endif /* WITH_SCACHE_PBB */ }
static SIM_RC memory_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt, char *arg, int is_command) { switch (opt) { case OPTION_MEMORY_DELETE: if (strcasecmp (arg, "all") == 0) { while (STATE_MEMOPT (sd) != NULL) do_memopt_delete (sd, STATE_MEMOPT (sd)->level, STATE_MEMOPT (sd)->space, STATE_MEMOPT (sd)->addr); return SIM_RC_OK; } else { int level = 0; int space = 0; address_word addr = 0; parse_addr (arg, &level, &space, &addr); return do_memopt_delete (sd, level, space, addr); } case OPTION_MEMORY_REGION: { char *chp = arg; int level = 0; int space = 0; address_word addr = 0; address_word nr_bytes = 0; unsigned modulo = 0; /* parse the arguments */ chp = parse_addr (chp, &level, &space, &addr); if (*chp != ',') { /* let the file autosize */ if (mmap_next_fd == -1) { sim_io_eprintf (sd, "Missing size for memory-region\n"); return SIM_RC_FAIL; } } else chp = parse_size (chp + 1, &nr_bytes, &modulo); /* old style */ if (*chp == ',') modulo = strtoul (chp + 1, &chp, 0); /* try to attach/insert it */ do_memopt_add (sd, level, space, addr, nr_bytes, modulo, &STATE_MEMOPT (sd), NULL); return SIM_RC_OK; } case OPTION_MEMORY_ALIAS: { char *chp = arg; int level = 0; int space = 0; address_word addr = 0; address_word nr_bytes = 0; unsigned modulo = 0; sim_memopt *entry; /* parse the arguments */ chp = parse_addr (chp, &level, &space, &addr); if (*chp != ',') { sim_io_eprintf (sd, "Missing size for memory-region\n"); return SIM_RC_FAIL; } chp = parse_size (chp + 1, &nr_bytes, &modulo); /* try to attach/insert the main record */ entry = do_memopt_add (sd, level, space, addr, nr_bytes, modulo, &STATE_MEMOPT (sd), NULL); /* now attach all the aliases */ while (*chp == ',') { int a_level = level; int a_space = space; address_word a_addr = addr; chp = parse_addr (chp + 1, &a_level, &a_space, &a_addr); do_memopt_add (sd, a_level, a_space, a_addr, nr_bytes, modulo, &entry->alias, entry->buffer); } return SIM_RC_OK; } case OPTION_MEMORY_SIZE: { int level = 0; int space = 0; address_word addr = 0; address_word nr_bytes = 0; unsigned modulo = 0; /* parse the arguments */ parse_size (arg, &nr_bytes, &modulo); /* try to attach/insert it */ do_memopt_add (sd, level, space, addr, nr_bytes, modulo, &STATE_MEMOPT (sd), NULL); return SIM_RC_OK; } case OPTION_MEMORY_CLEAR: { fill_byte_value = (unsigned8) 0; fill_byte_flag = 1; return SIM_RC_OK; break; } case OPTION_MEMORY_FILL: { unsigned long fill_value; parse_ulong_value (arg, &fill_value); if (fill_value > 255) { sim_io_eprintf (sd, "Missing fill value between 0 and 255\n"); return SIM_RC_FAIL; } fill_byte_value = (unsigned8) fill_value; fill_byte_flag = 1; return SIM_RC_OK; break; } case OPTION_MEMORY_MAPFILE: { if (mmap_next_fd >= 0) { sim_io_eprintf (sd, "Duplicate memory-mapfile option\n"); return SIM_RC_FAIL; } mmap_next_fd = open (arg, O_RDWR); if (mmap_next_fd < 0) { sim_io_eprintf (sd, "Cannot open file `%s': %s\n", arg, strerror (errno)); return SIM_RC_FAIL; } return SIM_RC_OK; } case OPTION_MEMORY_INFO: { sim_memopt *entry; sim_io_printf (sd, "Memory maps:\n"); for (entry = STATE_MEMOPT (sd); entry != NULL; entry = entry->next) { sim_memopt *alias; sim_io_printf (sd, " memory"); if (entry->alias == NULL) sim_io_printf (sd, " region "); else sim_io_printf (sd, " alias "); if (entry->space != 0) sim_io_printf (sd, "0x%lx:", (long) entry->space); sim_io_printf (sd, "0x%08lx", (long) entry->addr); if (entry->level != 0) sim_io_printf (sd, "@0x%lx", (long) entry->level); sim_io_printf (sd, ",0x%lx", (long) entry->nr_bytes); if (entry->modulo != 0) sim_io_printf (sd, "%%0x%lx", (long) entry->modulo); for (alias = entry->alias; alias != NULL; alias = alias->next) { if (alias->space != 0) sim_io_printf (sd, "0x%lx:", (long) alias->space); sim_io_printf (sd, ",0x%08lx", (long) alias->addr); if (alias->level != 0) sim_io_printf (sd, "@0x%lx", (long) alias->level); } sim_io_printf (sd, "\n"); } return SIM_RC_OK; break; } case OPTION_MAP_INFO: { sim_core *memory = STATE_CORE (sd); unsigned nr_map; for (nr_map = 0; nr_map < nr_maps; ++nr_map) { sim_core_map *map = &memory->common.map[nr_map]; sim_core_mapping *mapping = map->first; if (!mapping) continue; sim_io_printf (sd, "%s maps:\n", map_to_str (nr_map)); do { unsigned modulo; sim_io_printf (sd, " map "); if (mapping->space != 0) sim_io_printf (sd, "0x%x:", mapping->space); sim_io_printf (sd, "0x%08lx", (long) mapping->base); if (mapping->level != 0) sim_io_printf (sd, "@0x%x", mapping->level); sim_io_printf (sd, ",0x%lx", (long) mapping->nr_bytes); modulo = mapping->mask + 1; if (modulo != 0) sim_io_printf (sd, "%%0x%x", modulo); sim_io_printf (sd, "\n"); mapping = mapping->next; } while (mapping); } return SIM_RC_OK; break; } default: sim_io_eprintf (sd, "Unknown memory option %d\n", opt); return SIM_RC_FAIL; } return SIM_RC_FAIL; }