filename | src/sh4/cache.c |
changeset | 931:430048ea8b71 |
next | 933:880c37bb1909 |
author | nkeynes |
date | Tue Dec 23 05:48:05 2008 +0000 (15 years ago) |
branch | lxdream-mem |
permissions | -rw-r--r-- |
last change | More refactoring and general cleanup. Most things should be working again now. Split off cache and start real implementation, breaking save states in the process |
view | annotate | diff | log | raw |
1 /**
2 * $Id$
3 * Implements the on-chip operand cache and instruction caches
4 *
5 * Copyright (c) 2008 Nathan Keynes.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
18 #define MODULE sh4_module
20 #include <string.h>
21 #include "dream.h"
22 #include "mem.h"
23 #include "mmio.h"
24 #include "sh4/sh4core.h"
25 #include "sh4/sh4mmio.h"
26 #include "sh4/xltcache.h"
28 #define OCRAM_START (0x7C000000>>LXDREAM_PAGE_BITS)
29 #define OCRAM_MID (0x7E000000>>LXDREAM_PAGE_BITS)
30 #define OCRAM_END (0x80000000>>LXDREAM_PAGE_BITS)
32 #define CACHE_VALID 1
33 #define CACHE_DIRTY 2
35 #define ICACHE_ENTRY_COUNT 256
36 #define OCACHE_ENTRY_COUNT 512
38 struct cache_line {
39 uint32_t key; // Fast address match - bits 5..28 for valid entry, -1 for invalid entry
40 uint32_t tag; // tag + flags value from the address field
41 };
44 static struct cache_line ccn_icache[ICACHE_ENTRY_COUNT];
45 static struct cache_line ccn_ocache[OCACHE_ENTRY_COUNT];
46 static unsigned char ccn_icache_data[ICACHE_ENTRY_COUNT*32];
47 static unsigned char ccn_ocache_data[OCACHE_ENTRY_COUNT*32];
50 /*********************** General module requirements ********************/
52 void CCN_save_state( FILE *f )
53 {
54 fwrite( &ccn_icache, sizeof(ccn_icache), 1, f );
55 fwrite( &ccn_icache_data, sizeof(ccn_icache_data), 1, f );
56 fwrite( &ccn_ocache, sizeof(ccn_ocache), 1, f);
57 fwrite( &ccn_ocache_data, sizeof(ccn_ocache_data), 1, f);
58 }
60 int CCN_load_state( FILE *f )
61 {
62 /* Setup the cache mode according to the saved register value
63 * (mem_load runs before this point to load all MMIO data)
64 */
65 mmio_region_MMU_write( CCR, MMIO_READ(MMU, CCR) );
67 if( fread( &ccn_icache, sizeof(ccn_icache), 1, f ) != 1 ) {
68 return 1;
69 }
70 if( fread( &ccn_icache_data, sizeof(ccn_icache_data), 1, f ) != 1 ) {
71 return 1;
72 }
73 if( fread( &ccn_ocache, sizeof(ccn_ocache), 1, f ) != 1 ) {
74 return 1;
75 }
76 if( fread( &ccn_ocache_data, sizeof(ccn_ocache_data), 1, f ) != 1 ) {
77 return 1;
78 }
79 return 0;
80 }
83 /************************* OCRAM memory address space ************************/
85 #define OCRAMPAGE0 (&ccn_ocache_data[4096]) /* Lines 128-255 */
86 #define OCRAMPAGE1 (&ccn_ocache_data[12288]) /* Lines 384-511 */
88 static int32_t FASTCALL ocram_page0_read_long( sh4addr_t addr )
89 {
90 return *((int32_t *)(OCRAMPAGE0 + (addr&0x00000FFF)));
91 }
92 static int32_t FASTCALL ocram_page0_read_word( sh4addr_t addr )
93 {
94 return SIGNEXT16(*((int16_t *)(OCRAMPAGE0 + (addr&0x00000FFF))));
95 }
96 static int32_t FASTCALL ocram_page0_read_byte( sh4addr_t addr )
97 {
98 return SIGNEXT8(*((int16_t *)(OCRAMPAGE0 + (addr&0x00000FFF))));
99 }
100 static void FASTCALL ocram_page0_write_long( sh4addr_t addr, uint32_t val )
101 {
102 *(uint32_t *)(OCRAMPAGE0 + (addr&0x00000FFF)) = val;
103 }
104 static void FASTCALL ocram_page0_write_word( sh4addr_t addr, uint32_t val )
105 {
106 *(uint16_t *)(OCRAMPAGE0 + (addr&0x00000FFF)) = (uint16_t)val;
107 }
108 static void FASTCALL ocram_page0_write_byte( sh4addr_t addr, uint32_t val )
109 {
110 *(uint8_t *)(OCRAMPAGE0 + (addr&0x00000FFF)) = (uint8_t)val;
111 }
112 static void FASTCALL ocram_page0_read_burst( unsigned char *dest, sh4addr_t addr )
113 {
114 memcpy( dest, OCRAMPAGE0+(addr&0x00000FFF), 32 );
115 }
116 static void FASTCALL ocram_page0_write_burst( sh4addr_t addr, unsigned char *src )
117 {
118 memcpy( OCRAMPAGE0+(addr&0x00000FFF), src, 32 );
119 }
121 struct mem_region_fn mem_region_ocram_page0 = {
122 ocram_page0_read_long, ocram_page0_write_long,
123 ocram_page0_read_word, ocram_page0_write_word,
124 ocram_page0_read_byte, ocram_page0_write_byte,
125 ocram_page0_read_burst, ocram_page0_write_burst };
127 static int32_t FASTCALL ocram_page1_read_long( sh4addr_t addr )
128 {
129 return *((int32_t *)(OCRAMPAGE1 + (addr&0x00000FFF)));
130 }
131 static int32_t FASTCALL ocram_page1_read_word( sh4addr_t addr )
132 {
133 return SIGNEXT16(*((int16_t *)(OCRAMPAGE1 + (addr&0x00000FFF))));
134 }
135 static int32_t FASTCALL ocram_page1_read_byte( sh4addr_t addr )
136 {
137 return SIGNEXT8(*((int16_t *)(OCRAMPAGE1 + (addr&0x00000FFF))));
138 }
139 static void FASTCALL ocram_page1_write_long( sh4addr_t addr, uint32_t val )
140 {
141 *(uint32_t *)(OCRAMPAGE1 + (addr&0x00000FFF)) = val;
142 }
143 static void FASTCALL ocram_page1_write_word( sh4addr_t addr, uint32_t val )
144 {
145 *(uint16_t *)(OCRAMPAGE1 + (addr&0x00000FFF)) = (uint16_t)val;
146 }
147 static void FASTCALL ocram_page1_write_byte( sh4addr_t addr, uint32_t val )
148 {
149 *(uint8_t *)(OCRAMPAGE1 + (addr&0x00000FFF)) = (uint8_t)val;
150 }
151 static void FASTCALL ocram_page1_read_burst( unsigned char *dest, sh4addr_t addr )
152 {
153 memcpy( dest, OCRAMPAGE1+(addr&0x00000FFF), 32 );
154 }
155 static void FASTCALL ocram_page1_write_burst( sh4addr_t addr, unsigned char *src )
156 {
157 memcpy( OCRAMPAGE1+(addr&0x00000FFF), src, 32 );
158 }
160 struct mem_region_fn mem_region_ocram_page1 = {
161 ocram_page1_read_long, ocram_page1_write_long,
162 ocram_page1_read_word, ocram_page1_write_word,
163 ocram_page1_read_byte, ocram_page1_write_byte,
164 ocram_page1_read_burst, ocram_page1_write_burst };
166 /****************** Cache control *********************/
168 void CCN_set_cache_control( int reg )
169 {
170 uint32_t i;
171 switch( reg & (CCR_OIX|CCR_ORA|CCR_OCE) ) {
172 case MEM_OC_INDEX0: /* OIX=0 */
173 for( i=OCRAM_START; i<OCRAM_END; i+=4 ) {
174 sh4_address_space[i] = &mem_region_ocram_page0;
175 sh4_address_space[i+1] = &mem_region_ocram_page0;
176 sh4_address_space[i+2] = &mem_region_ocram_page1;
177 sh4_address_space[i+3] = &mem_region_ocram_page1;
178 }
179 break;
180 case MEM_OC_INDEX1: /* OIX=1 */
181 for( i=OCRAM_START; i<OCRAM_MID; i++ )
182 sh4_address_space[i] = &mem_region_ocram_page0;
183 for( i=OCRAM_MID; i<OCRAM_END; i++ )
184 sh4_address_space[i] = &mem_region_ocram_page1;
185 break;
186 default: /* disabled */
187 for( i=OCRAM_START; i<OCRAM_END; i++ )
188 sh4_address_space[i] = &mem_region_unmapped;
189 break;
190 }
191 }
.