static exception_type_t operation(conf_object_t *obj, generic_transaction_t *mop, map_info_t info) { byte_dump_device_t *bdd = (byte_dump_device_t *)obj; int offset = mop->physical_address + info.start - info.base; if (SIM_mem_op_is_read(mop)) { if (mop->inquiry) return Sim_PE_Inquiry_Unhandled; SIM_log_error(&bdd->log, 0,"Only write accesses allowed."); SIM_set_mem_op_value_le(mop, 0); } else { uint8 value = SIM_get_mem_op_value_le(mop); if (mop->size != 1) { SIM_log_error(&bdd->log, 0, "Only byte accesses allowed."); } SIM_log_info(2, &bdd->log, 0, "Write to offset %d, value 0x%x: '%c'", offset, value, isprint(value) ? value : ' '); if (bdd->fd >= 0) write(bdd->fd, &value, 1); } return Sim_PE_No_Exception; }
/* Dummy function that doesn't really do anything. */ static void simple_function(conf_object_t *obj) { sample_device_t *dev = (sample_device_t *) obj; SIM_log_info(1, &dev->log, 0, "'simple_function' called."); }
static exception_type_t sample_operation(conf_object_t *obj, generic_transaction_t *mop, map_info_t info) { sample_device_t *sample = (sample_device_t *)obj; int offset = (int)(mop->physical_address + info.start - info.base); if (SIM_mem_op_is_read(mop)) { SIM_log_info(1, &sample->log, 0, "Read from offset %d.", offset); SIM_set_mem_op_value_le(mop, 0); } else { SIM_log_info(1, &sample->log, 0, "Write to offset %d.", offset); } return Sim_PE_No_Exception; }
static set_error_t set_add_log_attribute(void *arg, conf_object_t *obj, attr_value_t *val, attr_value_t *idx) { sample_device_t *sample = (sample_device_t *)obj; SIM_log_info(1, &sample->log, 0, val->u.string); return Sim_Set_Ok; }
static void write_data(conf_object_t *obj, uint8 value) { sample_i2c_device_t *dev = (sample_i2c_device_t *)obj; SIM_log_info(1, &dev->log, 0, "writing 0x%x", (int)value); dev->written_value = value; }
static uint8 read_data(conf_object_t *obj) { sample_i2c_device_t *dev = (sample_i2c_device_t *)obj; uint8 value = dev->read_value; /* handle read operations */ SIM_log_info(1, &dev->log, 0, "reading 0x%x", (int)value); return value; }
int gc_set_config_repl(generic_cache_t *gc, const char *repl) { repl_interface_t *ri; int i = 0; if (!VLEN(repl_policies)) { SIM_log_error(&gc->log, GC_Log_Repl, "Cache has no replacement policies registered."); return -1; } ri = VGET(repl_policies, i); while (ri != NULL) { if (strcmp(repl, ri->get_name()) == 0) { MM_FREE(gc->config.repl_data); memcpy(&gc->config.repl_fun, ri, sizeof(*ri)); gc->config.repl_data = gc->config.repl_fun.new_instance(gc); gc->config.repl_fun.update_config( gc->config.repl_data, gc); return 0; } i++; ri = VGET(repl_policies, i); } SIM_log_info(1, &gc->log, GC_Log_Repl, "replacement: possible values are :"); i = 0; ri = VGET(repl_policies, i); while (ri != NULL) { SIM_log_info(1, &gc->log, GC_Log_Repl, " %s", ri->get_name()); i++; ri = VGET(repl_policies, i); } return -1; }
static cycles_t operate(conf_object_t *self, conf_object_t *mem_space, map_list_t *map_list, generic_transaction_t *mem_op) { uart_sampler_t *s = (uart_sampler_t *)self; uart_sampler_conf_t *c = (uart_sampler_conf_t *)s->conf; usf_access_t ref; if (!s->active) return 0; if (SIM_mem_op_is_prefetch(mem_op)) { SIM_log_info(4, &s->log, 0, "Ignoring prefetch"); return 0; } if (SIM_mem_op_is_control(mem_op)) { SIM_log_info(4, &s->log, 0, "Ignoring control"); return 0; } assert(SIM_mem_op_is_data(mem_op)); assert(SIM_mem_op_is_from_cpu(mem_op)); ref.pc = eip((mem_op)->ini_ptr); ref.addr = mem_op->physical_address; ref.time = s->time; ref.tid = cpuid((mem_op)->ini_ptr); ref.len = mem_op->size; ref.type = SIM_mem_op_is_read(mem_op) ? USF_ATYPE_RD : USF_ATYPE_WR; if (c->master) operate_master(s, c, &ref); else operate_slave(s, c, &ref); s->time++; return 0; }
cycles_t consistency_controller_operate(conf_object_t *obj, conf_object_t *space, map_list_t *map, generic_transaction_t *mem_op) { instruction_id_t current, ii; instr_type_t type; log_object_t *log = (log_object_t *)obj; conf_object_t *cpu = mem_op->ini_ptr; instruction_phase_t phase; consistency_controller_object_t *cc = (consistency_controller_object_t *)obj; if (!SIM_mem_op_is_from_cpu(mem_op) || SIM_mem_op_is_instruction(mem_op)) { if (cc->next_level_timing_interface) { return cc->next_level_timing_interface->operate(cc->next_level_object, space, map, mem_op); } else { return 0; } } if (SIM_instruction_nth_id(cpu, 0)) { if (!(current = SIM_instruction_id_from_mem_op_id(cpu, mem_op->id))) { /* No entry -> dangling transaction - pass on */ SIM_log_info(3, log, 0, "Passing dangling transaction on (id = %d)", mem_op->id); return cc->next_level_timing_interface->operate(cc->next_level_object, space, map, mem_op); } if (SIM_instruction_type(current) & It_Load) { for(ii = SIM_instruction_parent(current); ii; ii = SIM_instruction_parent(ii)) { type = SIM_instruction_type(ii); phase = SIM_instruction_phase(ii); /* if the instruction is retired, skip */ if (phase >= Sim_Phase_Retired) continue; if (((type & It_Store) && cc->store_load && phase < Sim_Phase_Retired) || ((type & It_Load) && cc->load_load && phase < Sim_Phase_Executed)) { if (!mem_op->may_stall) ASSERT_MSG(0,"Must stall but can not."); SIM_log_info(2, log, 0, "Obeying %s#load consistency @ %lld for %s", (type & It_Store) ? "store":"load", SIM_cycle_count(cpu), cpu->name); goto stall; } } } if (SIM_instruction_type(current) & It_Store) { for(ii = SIM_instruction_parent(current); ii; ii = SIM_instruction_parent(ii)) { type = SIM_instruction_type(ii); phase = SIM_instruction_phase(ii); /* if the instruction is executed, skip */ if (phase >= Sim_Phase_Retired) continue; if (((type & It_Load) && cc->load_store && phase < Sim_Phase_Executed) || ((type & It_Store) && cc->store_store && phase < Sim_Phase_Retired)) { if (!mem_op->may_stall) ASSERT_MSG(0,"Must stall but can not."); SIM_log_info(2, log, 0, "Obeying %s#store consistency @ %lld for %s", (type & It_Store) ? "store":"load", SIM_cycle_count(cpu), cpu->name); goto stall; } } } if (SIM_get_pending_exception()) SIM_log_error(log, 0, "*** Exception in consistency_controller_operate *** %lld", SIM_cycle_count(cpu)); } mem_op->ma_no_reissue = 0; if (cc->next_level_timing_interface) { return cc->next_level_timing_interface->operate(cc->next_level_object, space, map, mem_op); } else { return 0; } stall: /* if ma_no_reissue is 0 it is the first time we CC-stall this op, we will only prefetch once */ if (cc->prefetch && !mem_op->ma_no_reissue && cc->next_level_timing_interface) { mem_op_type_t type; cycles_t time; int may_stall; v9_memory_transaction_t *v9_mem_op = 0; uint16 p_fcn = 0; if (SIM_mem_op_is_from_cpu_arch(mem_op, Sim_Initiator_CPU_V9)) { v9_mem_op = (v9_memory_transaction_t *)mem_op; p_fcn = v9_mem_op->prefetch_fcn; v9_mem_op->prefetch_fcn = SIM_mem_op_is_write(mem_op) ? 3 : 1; } type = mem_op->type; mem_op->type = Sim_Trans_Prefetch; may_stall = mem_op->may_stall; mem_op->may_stall = 0; /* Prefetches may not stall */ SIM_log_info(2, log, 0, "Sending prefetch for id %d", (int)mem_op->id); time = cc->next_level_timing_interface->operate(cc->next_level_object, space, map, mem_op); if (v9_mem_op) v9_mem_op->prefetch_fcn = p_fcn; mem_op->type = type; mem_op->may_stall = may_stall; } /* do not reissue if squashed */ mem_op->ma_no_reissue = 1; return 1; }