static unsigned tx3904irc_io_write_buffer (struct hw *me, const void *source, int space, unsigned_word base, unsigned nr_bytes) { struct tx3904irc *controller = hw_data (me); unsigned byte; HW_TRACE ((me, "write 0x%08lx %d", (long) base, (int) nr_bytes)); for (byte = 0; byte < nr_bytes; byte++) { address_word address = base + byte; int reg_number = (address - controller->base_address) / 4; int reg_offset = (address - controller->base_address) % 4; unsigned_4* register_ptr; unsigned_4 register_value; /* fill in entire register_value word */ switch (reg_number) { case ISR_REG: register_ptr = & controller->isr; break; case IMR_REG: register_ptr = & controller->imr; break; case ILR0_REG: register_ptr = & controller->ilr[0]; break; case ILR1_REG: register_ptr = & controller->ilr[1]; break; case ILR2_REG: register_ptr = & controller->ilr[2]; break; case ILR3_REG: register_ptr = & controller->ilr[3]; break; default: register_ptr = & register_value; /* used as a dummy */ } /* HW_TRACE ((me, "reg %d pre: %08lx", reg_number, (long) *register_ptr)); */ /* overwrite requested byte */ register_value = H2T_4(* register_ptr); memcpy (((char*)®ister_value)+reg_offset, (const char*)source + byte, 1); * register_ptr = T2H_4(register_value); /* HW_TRACE ((me, "post: %08lx", (long) *register_ptr)); */ } return nr_bytes; }
/* Read a SI which spans two cache lines */ static SI read_mem_unaligned_SI (SIM_CPU *current_cpu, IADDR pc, SI address) { FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu); unsigned hi_len = cache->line_size - (address & (cache->line_size - 1)); char valarray[4]; SI SIvalue; HI HIvalue; switch (hi_len) { case 1: valarray[0] = frvbf_read_mem_QI (current_cpu, pc, address); SIvalue = frvbf_read_mem_SI (current_cpu, pc, address + 1); SIvalue = H2T_4 (SIvalue); memcpy (valarray + 1, (char*)&SIvalue, 3); break; case 2: HIvalue = frvbf_read_mem_HI (current_cpu, pc, address); HIvalue = H2T_2 (HIvalue); memcpy (valarray, (char*)&HIvalue, 2); HIvalue = frvbf_read_mem_HI (current_cpu, pc, address + 2); HIvalue = H2T_2 (HIvalue); memcpy (valarray + 2, (char*)&HIvalue, 2); break; case 3: SIvalue = frvbf_read_mem_SI (current_cpu, pc, address - 1); SIvalue = H2T_4 (SIvalue); memcpy (valarray, (char*)&SIvalue, 3); valarray[3] = frvbf_read_mem_QI (current_cpu, pc, address + 3); break; default: abort (); /* can't happen */ } return T2H_4 (*(SI*)valarray); }
int frv_cache_read_passive_SI (FRV_CACHE *cache, SI address, SI *value) { SI offset; FRV_CACHE_TAG *tag; if (non_cache_access (cache, address)) return 0; { FRV_CACHE_STATISTICS save_stats = cache->statistics; int found = get_tag (cache, address, &tag); cache->statistics = save_stats; if (! found) return 0; /* Indicate non-cache-access. */ } /* A cache line was available for the data. Extract the target data from the line. */ offset = address & (cache->line_size - 1); *value = T2H_4 (*(SI *)(tag->line + offset)); return 1; }