Search
lxdream.org :: lxdream/src/sh4/cache.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/cache.c
changeset 933:880c37bb1909
prev931:430048ea8b71
next939:6f2302afeb89
author nkeynes
date Wed Dec 24 06:06:23 2008 +0000 (11 years ago)
branchlxdream-mem
permissions -rw-r--r--
last change Start putting cache together
file annotate diff log raw
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.6
1.7 +/************************** Cache direct access ******************************/
1.8 +
1.9 +static int32_t ccn_icache_addr_read( sh4addr_t addr )
1.10 +{
1.11 + int entry = (addr & 0x00001FE0);
1.12 + return ccn_icache[entry>>5].tag;
1.13 +}
1.14 +
1.15 +static void ccn_icache_addr_write( sh4addr_t addr, uint32_t val )
1.16 +{
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.21 + } else {
1.22 + line->tag = val & 0x1FFFFC01;
1.23 + line->key = (val & 0x1FFFFC00)|(entry & 0x000003E0);
1.24 + }
1.25 +}
1.26 +
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.32 +
1.33 +
1.34 +static int32_t ccn_icache_data_read( sh4addr_t addr )
1.35 +{
1.36 + int entry = (addr & 0x00001FFC);
1.37 + return *(uint32_t *)&ccn_icache_data[entry];
1.38 +}
1.39 +
1.40 +static void ccn_icache_data_write( sh4addr_t addr, uint32_t val )
1.41 +{
1.42 + int entry = (addr & 0x00001FFC);
1.43 + *(uint32_t *)&ccn_icache_data[entry] = val;
1.44 +}
1.45 +
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.51 +
1.52 +
1.53 +static int32_t ccn_ocache_addr_read( sh4addr_t addr )
1.54 +{
1.55 + int entry = (addr & 0x00003FE0);
1.56 + return ccn_ocache[entry>>5].tag;
1.57 +}
1.58 +
1.59 +static void ccn_ocache_addr_write( sh4addr_t addr, uint32_t val )
1.60 +{
1.61 + int entry = (addr & 0x00003FE0);
1.62 + struct cache_line *line = &ccn_ocache[entry>>5];
1.63 + if( addr & 0x08 ) { // Associative
1.64 + } else {
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.69 + }
1.70 + line->tag = val & 0x1FFFFC03;
1.71 + line->key = (val & 0x1FFFFC00)|(entry & 0x000003E0);
1.72 + }
1.73 +}
1.74 +
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.80 +
1.81 +
1.82 +static int32_t ccn_ocache_data_read( sh4addr_t addr )
1.83 +{
1.84 + int entry = (addr & 0x00003FFC);
1.85 + return *(uint32_t *)&ccn_ocache_data[entry];
1.86 +}
1.87 +
1.88 +static void ccn_ocache_data_write( sh4addr_t addr, uint32_t val )
1.89 +{
1.90 + int entry = (addr & 0x00003FFC);
1.91 + *(uint32_t *)&ccn_ocache_data[entry] = val;
1.92 +}
1.93 +
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.99 +
1.100 +
1.101 /****************** Cache control *********************/
1.102
1.103 void CCN_set_cache_control( int reg )
1.104 {
1.105 uint32_t i;
1.106 +
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.110 + }
1.111 + }
1.112 +
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.116 + }
1.117 + }
1.118 +
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 ) {
.