3 * sh4mem.c is responsible for interfacing between the SH4's internal memory
5 * Copyright (c) 2005 Nathan Keynes.
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.
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.
18 #define MODULE sh4_module
25 #include "dreamcast.h"
26 #include "sh4/sh4core.h"
27 #include "sh4/sh4mmio.h"
28 #include "sh4/xltcache.h"
29 #include "pvr2/pvr2.h"
31 /* System regions (probably should be defined elsewhere) */
32 extern struct mem_region_fn mem_region_unmapped;
33 extern struct mem_region_fn mem_region_sdram;
34 extern struct mem_region_fn mem_region_vram32;
35 extern struct mem_region_fn mem_region_vram64;
36 extern struct mem_region_fn mem_region_audioram;
37 extern struct mem_region_fn mem_region_flashram;
38 extern struct mem_region_fn mem_region_bootrom;
40 /* On-chip regions other than defined MMIO regions */
41 extern struct mem_region_fn mem_region_storequeue;
42 extern struct mem_region_fn mem_region_icache_addr;
43 extern struct mem_region_fn mem_region_icache_data;
44 extern struct mem_region_fn mem_region_ocache_addr;
45 extern struct mem_region_fn mem_region_ocache_data;
46 extern struct mem_region_fn mem_region_itlb_addr;
47 extern struct mem_region_fn mem_region_itlb_data;
48 extern struct mem_region_fn mem_region_utlb_addr;
49 extern struct mem_region_fn mem_region_utlb_data;
51 /********************* The main ram address space **********************/
52 static int32_t FASTCALL ext_sdram_read_long( sh4addr_t addr )
54 return *((int32_t *)(sh4_main_ram + (addr&0x00FFFFFF)));
56 static int32_t FASTCALL ext_sdram_read_word( sh4addr_t addr )
58 return SIGNEXT16(*((int16_t *)(sh4_main_ram + (addr&0x00FFFFFF))));
60 static int32_t FASTCALL ext_sdram_read_byte( sh4addr_t addr )
62 return SIGNEXT8(*((int16_t *)(sh4_main_ram + (addr&0x00FFFFFF))));
64 static void FASTCALL ext_sdram_write_long( sh4addr_t addr, uint32_t val )
66 *(uint32_t *)(sh4_main_ram + (addr&0x00FFFFFF)) = val;
67 xlat_invalidate_long(addr);
69 static void FASTCALL ext_sdram_write_word( sh4addr_t addr, uint32_t val )
71 *(uint16_t *)(sh4_main_ram + (addr&0x00FFFFFF)) = (uint16_t)val;
72 xlat_invalidate_word(addr);
74 static void FASTCALL ext_sdram_write_byte( sh4addr_t addr, uint32_t val )
76 *(uint8_t *)(sh4_main_ram + (addr&0x00FFFFFF)) = (uint8_t)val;
77 xlat_invalidate_word(addr);
79 static void FASTCALL ext_sdram_read_burst( unsigned char *dest, sh4addr_t addr )
81 memcpy( dest, sh4_main_ram+(addr&0x00FFFFFF), 32 );
83 static void FASTCALL ext_sdram_write_burst( sh4addr_t addr, unsigned char *src )
85 memcpy( sh4_main_ram+(addr&0x00FFFFFF), src, 32 );
88 struct mem_region_fn mem_region_sdram = { ext_sdram_read_long, ext_sdram_write_long,
89 ext_sdram_read_word, ext_sdram_write_word,
90 ext_sdram_read_byte, ext_sdram_write_byte,
91 ext_sdram_read_burst, ext_sdram_write_burst };
94 /********************* The Boot ROM address space **********************/
95 extern sh4ptr_t dc_boot_rom;
96 extern sh4ptr_t dc_flash_ram;
97 extern sh4ptr_t dc_audio_ram;
98 static int32_t FASTCALL ext_bootrom_read_long( sh4addr_t addr )
100 return *((int32_t *)(dc_boot_rom + (addr&0x001FFFFF)));
102 static int32_t FASTCALL ext_bootrom_read_word( sh4addr_t addr )
104 return SIGNEXT16(*((int16_t *)(dc_boot_rom + (addr&0x001FFFFF))));
106 static int32_t FASTCALL ext_bootrom_read_byte( sh4addr_t addr )
108 return SIGNEXT8(*((int16_t *)(dc_boot_rom + (addr&0x001FFFFF))));
110 static void FASTCALL ext_bootrom_read_burst( unsigned char *dest, sh4addr_t addr )
112 memcpy( dest, sh4_main_ram+(addr&0x001FFFFF), 32 );
115 struct mem_region_fn mem_region_bootrom = {
116 ext_bootrom_read_long, unmapped_write_long,
117 ext_bootrom_read_word, unmapped_write_long,
118 ext_bootrom_read_byte, unmapped_write_long,
119 ext_bootrom_read_burst, unmapped_write_burst };
121 /********************* The Flash RAM address space **********************/
122 static int32_t FASTCALL ext_flashram_read_long( sh4addr_t addr )
124 return *((int32_t *)(dc_flash_ram + (addr&0x0001FFFF)));
126 static int32_t FASTCALL ext_flashram_read_word( sh4addr_t addr )
128 return SIGNEXT16(*((int16_t *)(dc_flash_ram + (addr&0x0001FFFF))));
130 static int32_t FASTCALL ext_flashram_read_byte( sh4addr_t addr )
132 return SIGNEXT8(*((int16_t *)(dc_flash_ram + (addr&0x0001FFFF))));
134 static void FASTCALL ext_flashram_write_long( sh4addr_t addr, uint32_t val )
136 *(uint32_t *)(dc_flash_ram + (addr&0x0001FFFF)) = val;
137 asic_g2_write_word();
139 static void FASTCALL ext_flashram_write_word( sh4addr_t addr, uint32_t val )
141 *(uint16_t *)(dc_flash_ram + (addr&0x0001FFFF)) = (uint16_t)val;
142 asic_g2_write_word();
144 static void FASTCALL ext_flashram_write_byte( sh4addr_t addr, uint32_t val )
146 *(uint8_t *)(dc_flash_ram + (addr&0x0001FFFF)) = (uint8_t)val;
147 asic_g2_write_word();
149 static void FASTCALL ext_flashram_read_burst( unsigned char *dest, sh4addr_t addr )
151 memcpy( dest, dc_flash_ram+(addr&0x0001FFFF), 32 );
153 static void FASTCALL ext_flashram_write_burst( sh4addr_t addr, unsigned char *src )
155 memcpy( dc_flash_ram+(addr&0x0001FFFF), src, 32 );
158 struct mem_region_fn mem_region_flashram = { ext_flashram_read_long, ext_flashram_write_long,
159 ext_flashram_read_word, ext_flashram_write_word,
160 ext_flashram_read_byte, ext_flashram_write_byte,
161 ext_flashram_read_burst, ext_flashram_write_burst };
163 /***************************** P4 Regions ************************************/
165 /* Store-queue (long-write only?) */
166 static void FASTCALL p4_storequeue_write_long( sh4addr_t addr, uint32_t val )
168 sh4r.store_queue[(addr>>2)&0xF] = val;
170 static int32_t FASTCALL p4_storequeue_read_long( sh4addr_t addr )
172 return sh4r.store_queue[(addr>>2)&0xF];
175 struct mem_region_fn p4_region_storequeue = {
176 p4_storequeue_read_long, p4_storequeue_write_long,
177 p4_storequeue_read_long, p4_storequeue_write_long,
178 p4_storequeue_read_long, p4_storequeue_write_long,
179 unmapped_read_burst, unmapped_write_burst }; // No burst access.
182 struct mem_region_fn p4_region_icache_addr = {
183 mmu_icache_addr_read, mmu_icache_addr_write,
184 mmu_icache_addr_read, mmu_icache_addr_write,
185 mmu_icache_addr_read, mmu_icache_addr_write,
186 unmapped_read_burst, unmapped_write_burst };
187 struct mem_region_fn p4_region_icache_data = {
188 mmu_icache_data_read, mmu_icache_data_write,
189 mmu_icache_data_read, mmu_icache_data_write,
190 mmu_icache_data_read, mmu_icache_data_write,
191 unmapped_read_burst, unmapped_write_burst };
192 struct mem_region_fn p4_region_ocache_addr = {
193 mmu_ocache_addr_read, mmu_ocache_addr_write,
194 mmu_ocache_addr_read, mmu_ocache_addr_write,
195 mmu_ocache_addr_read, mmu_ocache_addr_write,
196 unmapped_read_burst, unmapped_write_burst };
197 struct mem_region_fn p4_region_ocache_data = {
198 mmu_ocache_data_read, mmu_ocache_data_write,
199 mmu_ocache_data_read, mmu_ocache_data_write,
200 mmu_ocache_data_read, mmu_ocache_data_write,
201 unmapped_read_burst, unmapped_write_burst };
204 struct mem_region_fn p4_region_itlb_addr = {
205 mmu_itlb_addr_read, mmu_itlb_addr_write,
206 mmu_itlb_addr_read, mmu_itlb_addr_write,
207 mmu_itlb_addr_read, mmu_itlb_addr_write,
208 unmapped_read_burst, unmapped_write_burst };
209 struct mem_region_fn p4_region_itlb_data = {
210 mmu_itlb_data_read, mmu_itlb_data_write,
211 mmu_itlb_data_read, mmu_itlb_data_write,
212 mmu_itlb_data_read, mmu_itlb_data_write,
213 unmapped_read_burst, unmapped_write_burst };
214 struct mem_region_fn p4_region_utlb_addr = {
215 mmu_utlb_addr_read, mmu_utlb_addr_write,
216 mmu_utlb_addr_read, mmu_utlb_addr_write,
217 mmu_utlb_addr_read, mmu_utlb_addr_write,
218 unmapped_read_burst, unmapped_write_burst };
219 struct mem_region_fn p4_region_utlb_data = {
220 mmu_utlb_data_read, mmu_utlb_data_write,
221 mmu_utlb_data_read, mmu_utlb_data_write,
222 mmu_utlb_data_read, mmu_utlb_data_write,
223 unmapped_read_burst, unmapped_write_burst };
225 /********************** Initialization *************************/
227 mem_region_fn_t *sh4_address_space;
229 static void sh4_register_mem_region( uint32_t start, uint32_t end, mem_region_fn_t fn )
231 int count = (end - start) >> 12;
232 mem_region_fn_t *ptr = &sh4_address_space[start>>12];
233 while( count-- > 0 ) {
238 static gboolean sh4_ext_page_remapped( sh4addr_t page, mem_region_fn_t fn, void *user_data )
241 for( i=0; i<= 0xC0000000; i+= 0x20000000 ) {
242 sh4_address_space[(page|i)>>12] = fn;
250 mem_region_fn_t *ptr;
251 sh4_address_space = mem_alloc_pages( sizeof(mem_region_fn_t) * 256 );
252 for( i=0, ptr = sh4_address_space; i<7; i++, ptr += LXDREAM_PAGE_TABLE_ENTRIES ) {
253 memcpy( ptr, ext_address_space, sizeof(mem_region_fn_t) * LXDREAM_PAGE_TABLE_ENTRIES );
256 /* Setup main P4 regions */
257 sh4_register_mem_region( 0xE0000000, 0xE4000000, &p4_region_storequeue );
258 sh4_register_mem_region( 0xE4000000, 0xF0000000, &mem_region_unmapped );
259 sh4_register_mem_region( 0xF0000000, 0xF1000000, &p4_region_icache_addr );
260 sh4_register_mem_region( 0xF1000000, 0xF2000000, &p4_region_icache_data );
261 sh4_register_mem_region( 0xF2000000, 0xF3000000, &p4_region_itlb_addr );
262 sh4_register_mem_region( 0xF3000000, 0xF4000000, &p4_region_itlb_data );
263 sh4_register_mem_region( 0xF4000000, 0xF5000000, &p4_region_ocache_addr );
264 sh4_register_mem_region( 0xF5000000, 0xF6000000, &p4_region_ocache_data );
265 sh4_register_mem_region( 0xF6000000, 0xF7000000, &p4_region_utlb_addr );
266 sh4_register_mem_region( 0xF7000000, 0xF8000000, &p4_region_utlb_data );
267 sh4_register_mem_region( 0xF8000000, 0x00000000, &mem_region_unmapped );
269 /* Setup P4 control region */
270 sh4_register_mem_region( 0xFF000000, 0xFF001000, &mmio_region_MMU.fn );
271 sh4_register_mem_region( 0xFF100000, 0xFF101000, &mmio_region_PMM.fn );
272 sh4_register_mem_region( 0xFF200000, 0xFF201000, &mmio_region_UBC.fn );
273 sh4_register_mem_region( 0xFF800000, 0xFF801000, &mmio_region_BSC.fn );
274 sh4_register_mem_region( 0xFF900000, 0xFFA00000, &mem_region_unmapped ); // SDMR2 + SDMR3
275 sh4_register_mem_region( 0xFFA00000, 0xFFA01000, &mmio_region_DMAC.fn );
276 sh4_register_mem_region( 0xFFC00000, 0xFFC01000, &mmio_region_CPG.fn );
277 sh4_register_mem_region( 0xFFC80000, 0xFFC81000, &mmio_region_RTC.fn );
278 sh4_register_mem_region( 0xFFD00000, 0xFFD01000, &mmio_region_INTC.fn );
279 sh4_register_mem_region( 0xFFD80000, 0xFFD81000, &mmio_region_TMU.fn );
280 sh4_register_mem_region( 0xFFE00000, 0xFFE01000, &mmio_region_SCI.fn );
281 sh4_register_mem_region( 0xFFE80000, 0xFFE81000, &mmio_region_SCIF.fn );
282 sh4_register_mem_region( 0xFFF00000, 0xFFF01000, &mem_region_unmapped ); // H-UDI
284 register_mem_page_remapped_hook( sh4_ext_page_remapped, NULL );
287 /************** Access methods ***************/
288 #ifdef HAVE_FRAME_ADDRESS
289 #define RETURN_VIA(exc) do{ *(((void **)__builtin_frame_address(0))+1) = exc; return; } while(0)
291 #define RETURN_VIA(exc) return NULL
295 int32_t FASTCALL sh4_read_long( sh4addr_t addr )
297 return sh4_address_space[addr>>12]->read_long(addr);
300 int32_t FASTCALL sh4_read_word( sh4addr_t addr )
302 return sh4_address_space[addr>>12]->read_word(addr);
305 int32_t FASTCALL sh4_read_byte( sh4addr_t addr )
307 return sh4_address_space[addr>>12]->read_byte(addr);
310 void FASTCALL sh4_write_long( sh4addr_t addr, uint32_t val )
312 sh4_address_space[addr>>12]->write_long(addr, val);
315 void FASTCALL sh4_write_word( sh4addr_t addr, uint32_t val )
317 sh4_address_space[addr>>12]->write_word(addr,val);
320 void FASTCALL sh4_write_byte( sh4addr_t addr, uint32_t val )
322 sh4_address_space[addr>>12]->write_byte(addr, val);
325 /* FIXME: Handle all the many special cases when the range doesn't fall cleanly
326 * into the same memory block
328 void mem_copy_from_sh4( sh4ptr_t dest, sh4addr_t srcaddr, size_t count ) {
329 if( srcaddr >= 0x04000000 && srcaddr < 0x05000000 ) {
330 pvr2_vram64_read( dest, srcaddr, count );
332 sh4ptr_t src = mem_get_region(srcaddr);
334 WARN( "Attempted block read from unknown address %08X", srcaddr );
336 memcpy( dest, src, count );
341 void mem_copy_to_sh4( sh4addr_t destaddr, sh4ptr_t src, size_t count ) {
342 if( destaddr >= 0x10000000 && destaddr < 0x14000000 ) {
343 pvr2_dma_write( destaddr, src, count );
345 } else if( (destaddr & 0x1F800000) == 0x05000000 ) {
346 pvr2_render_buffer_invalidate( destaddr, TRUE );
347 } else if( (destaddr & 0x1F800000) == 0x04000000 ) {
348 pvr2_vram64_write( destaddr, src, count );
351 sh4ptr_t dest = mem_get_region(destaddr);
353 WARN( "Attempted block write to unknown address %08X", destaddr );
355 xlat_invalidate_block( destaddr, count );
356 memcpy( dest, src, count );
.