1.1 --- a/src/sh4/cache.c Tue Dec 23 05:48:05 2008 +0000
1.2 +++ b/src/sh4/cache.c Wed Dec 24 06:06:23 2008 +0000
1.3 @@ -163,11 +163,118 @@
1.4 ocram_page1_read_byte, ocram_page1_write_byte,
1.5 ocram_page1_read_burst, ocram_page1_write_burst };
1.7 +/************************** Cache direct access ******************************/
1.9 +static int32_t ccn_icache_addr_read( sh4addr_t addr )
1.11 + int entry = (addr & 0x00001FE0);
1.12 + return ccn_icache[entry>>5].tag;
1.15 +static void ccn_icache_addr_write( sh4addr_t addr, uint32_t val )
1.17 + int entry = (addr & 0x00003FE0);
1.18 + struct cache_line *line = &ccn_ocache[entry>>5];
1.19 + if( addr & 0x08 ) { // Associative
1.20 + /* FIXME: implement this - requires ITLB lookups, with exception in case of multi-hit */
1.22 + line->tag = val & 0x1FFFFC01;
1.23 + line->key = (val & 0x1FFFFC00)|(entry & 0x000003E0);
1.27 +struct mem_region_fn p4_region_icache_addr = {
1.28 + ccn_icache_addr_read, ccn_icache_addr_write,
1.29 + unmapped_read_long, unmapped_write_long,
1.30 + unmapped_read_long, unmapped_write_long,
1.31 + unmapped_read_burst, unmapped_write_burst };
1.34 +static int32_t ccn_icache_data_read( sh4addr_t addr )
1.36 + int entry = (addr & 0x00001FFC);
1.37 + return *(uint32_t *)&ccn_icache_data[entry];
1.40 +static void ccn_icache_data_write( sh4addr_t addr, uint32_t val )
1.42 + int entry = (addr & 0x00001FFC);
1.43 + *(uint32_t *)&ccn_icache_data[entry] = val;
1.46 +struct mem_region_fn p4_region_icache_data = {
1.47 + ccn_icache_data_read, ccn_icache_data_write,
1.48 + unmapped_read_long, unmapped_write_long,
1.49 + unmapped_read_long, unmapped_write_long,
1.50 + unmapped_read_burst, unmapped_write_burst };
1.53 +static int32_t ccn_ocache_addr_read( sh4addr_t addr )
1.55 + int entry = (addr & 0x00003FE0);
1.56 + return ccn_ocache[entry>>5].tag;
1.59 +static void ccn_ocache_addr_write( sh4addr_t addr, uint32_t val )
1.61 + int entry = (addr & 0x00003FE0);
1.62 + struct cache_line *line = &ccn_ocache[entry>>5];
1.63 + if( addr & 0x08 ) { // Associative
1.65 + if( (line->tag & (CACHE_VALID|CACHE_DIRTY)) == (CACHE_VALID|CACHE_DIRTY) ) {
1.66 + char *cache_data = &ccn_ocache_data[entry&0x00003FE0];
1.67 + // Cache line is dirty - writeback.
1.68 + ext_address_space[line->tag>>12]->write_burst(line->key, cache_data);
1.70 + line->tag = val & 0x1FFFFC03;
1.71 + line->key = (val & 0x1FFFFC00)|(entry & 0x000003E0);
1.75 +struct mem_region_fn p4_region_ocache_addr = {
1.76 + ccn_ocache_addr_read, ccn_ocache_addr_write,
1.77 + unmapped_read_long, unmapped_write_long,
1.78 + unmapped_read_long, unmapped_write_long,
1.79 + unmapped_read_burst, unmapped_write_burst };
1.82 +static int32_t ccn_ocache_data_read( sh4addr_t addr )
1.84 + int entry = (addr & 0x00003FFC);
1.85 + return *(uint32_t *)&ccn_ocache_data[entry];
1.88 +static void ccn_ocache_data_write( sh4addr_t addr, uint32_t val )
1.90 + int entry = (addr & 0x00003FFC);
1.91 + *(uint32_t *)&ccn_ocache_data[entry] = val;
1.94 +struct mem_region_fn p4_region_ocache_data = {
1.95 + ccn_ocache_data_read, ccn_ocache_data_write,
1.96 + unmapped_read_long, unmapped_write_long,
1.97 + unmapped_read_long, unmapped_write_long,
1.98 + unmapped_read_burst, unmapped_write_burst };
1.101 /****************** Cache control *********************/
1.103 void CCN_set_cache_control( int reg )
1.107 + if( reg & CCR_ICI ) { /* icache invalidate */
1.108 + for( i=0; i<ICACHE_ENTRY_COUNT; i++ ) {
1.109 + ccn_icache[i].tag &= ~CACHE_VALID;
1.113 + if( reg & CCR_OCI ) { /* ocache invalidate */
1.114 + for( i=0; i<OCACHE_ENTRY_COUNT; i++ ) {
1.115 + ccn_ocache[i].tag &= ~(CACHE_VALID|CACHE_DIRTY);
1.119 switch( reg & (CCR_OIX|CCR_ORA|CCR_OCE) ) {
1.120 case MEM_OC_INDEX0: /* OIX=0 */
1.121 for( i=OCRAM_START; i<OCRAM_END; i+=4 ) {