Search
lxdream.org :: lxdream/src/sh4/sh4mem.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4mem.c
changeset 953:f4a156508ad1
prev927:17b6b9e245d8
next991:60c7fab9c880
author nkeynes
date Tue Jan 13 11:56:28 2009 +0000 (12 years ago)
permissions -rw-r--r--
last change Merge lxdream-mem branch back to trunk
file annotate diff log raw
1.1 --- a/src/sh4/sh4mem.c Mon Dec 15 10:44:56 2008 +0000
1.2 +++ b/src/sh4/sh4mem.c Tue Jan 13 11:56:28 2009 +0000
1.3 @@ -1,7 +1,8 @@
1.4 /**
1.5 * $Id$
1.6 - * sh4mem.c is responsible for the SH4's access to memory (including memory
1.7 - * mapped I/O), using the page maps created in mem.c
1.8 + *
1.9 + * This is a deprecated module that is not yet completely extricated from the
1.10 + * surrounding code.
1.11 *
1.12 * Copyright (c) 2005 Nathan Keynes.
1.13 *
1.14 @@ -27,375 +28,10 @@
1.15 #include "sh4/sh4core.h"
1.16 #include "sh4/sh4mmio.h"
1.17 #include "sh4/xltcache.h"
1.18 +#include "sh4/mmu.h"
1.19 #include "pvr2/pvr2.h"
1.20 -#include "asic.h"
1.21
1.22 -#define OC_BASE 0x1C000000
1.23 -#define OC_TOP 0x20000000
1.24 -
1.25 -#define TRANSLATE_VIDEO_64BIT_ADDRESS(a) ( (((a)&0x00FFFFF8)>>1)|(((a)&0x00000004)<<20)|((a)&0x03)|0x05000000 )
1.26 -
1.27 -#ifdef ENABLE_WATCH
1.28 -#define CHECK_READ_WATCH( addr, size ) \
1.29 - if( mem_is_watched(addr,size,WATCH_READ) != NULL ) { \
1.30 - WARN( "Watch triggered at %08X by %d byte read", addr, size ); \
1.31 - sh4_core_exit(CORE_EXIT_HALT); \
1.32 - }
1.33 -#define CHECK_WRITE_WATCH( addr, size, val ) \
1.34 - if( mem_is_watched(addr,size,WATCH_WRITE) != NULL ) { \
1.35 - WARN( "Watch triggered at %08X by %d byte write <= %0*X", addr, size, size*2, val ); \
1.36 - sh4_core_exit(CORE_EXIT_HALT); \
1.37 - }
1.38 -#else
1.39 -#define CHECK_READ_WATCH( addr, size )
1.40 -#define CHECK_WRITE_WATCH( addr, size, val )
1.41 -#endif
1.42 -
1.43 -#ifdef ENABLE_TRACE_IO
1.44 -#define TRACE_IO( str, p, r, ... ) if(io_rgn[(uint32_t)p]->trace_flag && !MMIO_NOTRACE_BYNUM((uint32_t)p,r)) \
1.45 - TRACE( str " [%s.%s: %s]", __VA_ARGS__, \
1.46 - MMIO_NAME_BYNUM((uint32_t)p), MMIO_REGID_BYNUM((uint32_t)p, r), \
1.47 - MMIO_REGDESC_BYNUM((uint32_t)p, r) )
1.48 -#define TRACE_P4IO( str, io, r, ... ) if(io->trace_flag && !MMIO_NOTRACE_IOBYNUM(io,r)) \
1.49 - TRACE( str " [%s.%s: %s]", __VA_ARGS__, \
1.50 - io->id, MMIO_REGID_IOBYNUM(io, r), \
1.51 - MMIO_REGDESC_IOBYNUM(io, r) )
1.52 -#else
1.53 -#define TRACE_IO( str, p, r, ... )
1.54 -#define TRACE_P4IO( str, io, r, ... )
1.55 -#endif
1.56 -
1.57 -extern struct mem_region mem_rgn[];
1.58 -extern struct mmio_region *P4_io[];
1.59 -
1.60 -int32_t FASTCALL sh4_read_p4( sh4addr_t addr )
1.61 -{
1.62 - struct mmio_region *io = P4_io[(addr&0x1FFFFFFF)>>19];
1.63 - if( !io ) {
1.64 - switch( addr & 0x1F000000 ) {
1.65 - case 0x00000000: case 0x01000000: case 0x02000000: case 0x03000000:
1.66 - /* Store queue - readable? */
1.67 - return 0;
1.68 - break;
1.69 - case 0x10000000: return mmu_icache_addr_read( addr );
1.70 - case 0x11000000: return mmu_icache_data_read( addr );
1.71 - case 0x12000000: return mmu_itlb_addr_read( addr );
1.72 - case 0x13000000: return mmu_itlb_data_read( addr );
1.73 - case 0x14000000: return mmu_ocache_addr_read( addr );
1.74 - case 0x15000000: return mmu_ocache_data_read( addr );
1.75 - case 0x16000000: return mmu_utlb_addr_read( addr );
1.76 - case 0x17000000: return mmu_utlb_data_read( addr );
1.77 - default:
1.78 - WARN( "Attempted read from unknown or invalid P4 region: %08X", addr );
1.79 - return 0;
1.80 - }
1.81 - } else {
1.82 - int32_t val = io->io_read( addr&0xFFF );
1.83 - TRACE_P4IO( "Long read %08X <= %08X", io, (addr&0xFFF), val, addr );
1.84 - return val;
1.85 - }
1.86 -}
1.87 -
1.88 -void FASTCALL sh4_write_p4( sh4addr_t addr, int32_t val )
1.89 -{
1.90 - struct mmio_region *io = P4_io[(addr&0x1FFFFFFF)>>19];
1.91 - if( !io ) {
1.92 - switch( addr & 0x1F000000 ) {
1.93 - case 0x00000000: case 0x01000000: case 0x02000000: case 0x03000000:
1.94 - /* Store queue */
1.95 - SH4_WRITE_STORE_QUEUE( addr, val );
1.96 - break;
1.97 - case 0x10000000: mmu_icache_addr_write( addr, val ); break;
1.98 - case 0x11000000: mmu_icache_data_write( addr, val ); break;
1.99 - case 0x12000000: mmu_itlb_addr_write( addr, val ); break;
1.100 - case 0x13000000: mmu_itlb_data_write( addr, val ); break;
1.101 - case 0x14000000: mmu_ocache_addr_write( addr, val ); break;
1.102 - case 0x15000000: mmu_ocache_data_write( addr, val ); break;
1.103 - case 0x16000000: mmu_utlb_addr_write( addr, val ); break;
1.104 - case 0x17000000: mmu_utlb_data_write( addr, val ); break;
1.105 - default:
1.106 - if( (addr & 0xFFFF0000 ) == 0xFF940000 ||
1.107 - (addr & 0xFFFF0000 ) == 0xFF900000 ) {
1.108 - // SDRAM configuration, ignore for now
1.109 - } else {
1.110 - WARN( "Attempted write to unknown P4 region: %08X", addr );
1.111 - }
1.112 - }
1.113 - } else {
1.114 - TRACE_P4IO( "Long write %08X => %08X", io, (addr&0xFFF), val, addr );
1.115 - io->io_write( addr&0xFFF, val );
1.116 - }
1.117 -}
1.118 -
1.119 -int32_t sh4_read_phys_word( sh4addr_t addr )
1.120 -{
1.121 - sh4ptr_t page;
1.122 - if( addr >= 0xE0000000 ) /* P4 Area, handled specially */
1.123 - return SIGNEXT16(sh4_read_p4( addr ));
1.124 -
1.125 - if( (addr&0x1F800000) == 0x04000000 ) {
1.126 - addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr);
1.127 - }
1.128 -
1.129 - page = page_map[ (addr & 0x1FFFFFFF) >> 12 ];
1.130 - if( ((uintptr_t)page) < MAX_IO_REGIONS ) { /* IO Region */
1.131 - if( page == NULL ) {
1.132 - WARN( "Attempted word read to missing page: %08X",
1.133 - addr );
1.134 - return 0;
1.135 - }
1.136 - return SIGNEXT16(io_rgn[(uintptr_t)page]->io_read(addr&0xFFF));
1.137 - } else {
1.138 - return SIGNEXT16(*(int16_t *)(page+(addr&0xFFF)));
1.139 - }
1.140 -}
1.141 -
1.142 -/**
1.143 - * Convenience function to read a quad-word (implemented as two long reads).
1.144 - */
1.145 -int64_t FASTCALL sh4_read_quad( sh4addr_t addr )
1.146 -{
1.147 - return ((int64_t)((uint32_t)sh4_read_long(addr))) |
1.148 - (((int64_t)((uint32_t)sh4_read_long(addr+4))) << 32);
1.149 -}
1.150 -
1.151 -int32_t FASTCALL sh4_read_long( sh4addr_t addr )
1.152 -{
1.153 - sh4ptr_t page;
1.154 -
1.155 - CHECK_READ_WATCH(addr,4);
1.156 -
1.157 - if( addr >= 0xE0000000 ) { /* P4 Area, handled specially */
1.158 - return ZEROEXT32(sh4_read_p4( addr ));
1.159 - } else if( (addr&0x1C000000) == 0x0C000000 ) {
1.160 - return ZEROEXT32(*(int32_t *)(sh4_main_ram + (addr&0x00FFFFFF)));
1.161 - } else if( (addr&0x1F800000) == 0x04000000 ) {
1.162 - addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr);
1.163 - pvr2_render_buffer_invalidate(addr, FALSE);
1.164 - } else if( (addr&0x1F800000) == 0x05000000 ) {
1.165 - pvr2_render_buffer_invalidate(addr, FALSE);
1.166 - }
1.167 -
1.168 - page = page_map[ (addr & 0x1FFFFFFF) >> 12 ];
1.169 - if( ((uintptr_t)page) < MAX_IO_REGIONS ) { /* IO Region */
1.170 - int32_t val;
1.171 - if( page == NULL ) {
1.172 - WARN( "Attempted long read to missing page: %08X", addr );
1.173 - return 0;
1.174 - }
1.175 - val = io_rgn[(uintptr_t)page]->io_read(addr&0xFFF);
1.176 - TRACE_IO( "Long read %08X <= %08X", page, (addr&0xFFF), val, addr );
1.177 - return ZEROEXT32(val);
1.178 - } else {
1.179 - return ZEROEXT32(*(int32_t *)(page+(addr&0xFFF)));
1.180 - }
1.181 -}
1.182 -
1.183 -int32_t FASTCALL sh4_read_word( sh4addr_t addr )
1.184 -{
1.185 - sh4ptr_t page;
1.186 -
1.187 - CHECK_READ_WATCH(addr,2);
1.188 -
1.189 - if( addr >= 0xE0000000 ) { /* P4 Area, handled specially */
1.190 - return ZEROEXT32(SIGNEXT16(sh4_read_p4( addr )));
1.191 - } else if( (addr&0x1C000000) == 0x0C000000 ) {
1.192 - return ZEROEXT32(SIGNEXT16(*(int16_t *)(sh4_main_ram + (addr&0x00FFFFFF))));
1.193 - } else if( (addr&0x1F800000) == 0x04000000 ) {
1.194 - addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr);
1.195 - pvr2_render_buffer_invalidate(addr, FALSE);
1.196 - } else if( (addr&0x1F800000) == 0x05000000 ) {
1.197 - pvr2_render_buffer_invalidate(addr, FALSE);
1.198 - }
1.199 -
1.200 - page = page_map[ (addr & 0x1FFFFFFF) >> 12 ];
1.201 - if( ((uintptr_t)page) < MAX_IO_REGIONS ) { /* IO Region */
1.202 - int32_t val;
1.203 - if( page == NULL ) {
1.204 - WARN( "Attempted word read to missing page: %08X", addr );
1.205 - return 0;
1.206 - }
1.207 - val = SIGNEXT16(io_rgn[(uintptr_t)page]->io_read(addr&0xFFF));
1.208 - TRACE_IO( "Word read %04X <= %08X", page, (addr&0xFFF), val&0xFFFF, addr );
1.209 - return ZEROEXT32(val);
1.210 - } else {
1.211 - return ZEROEXT32(SIGNEXT16(*(int16_t *)(page+(addr&0xFFF))));
1.212 - }
1.213 -}
1.214 -
1.215 -int32_t FASTCALL sh4_read_byte( sh4addr_t addr )
1.216 -{
1.217 - sh4ptr_t page;
1.218 -
1.219 - CHECK_READ_WATCH(addr,1);
1.220 -
1.221 - if( addr >= 0xE0000000 ) { /* P4 Area, handled specially */
1.222 - return ZEROEXT32(SIGNEXT8(sh4_read_p4( addr )));
1.223 - } else if( (addr&0x1C000000) == 0x0C000000 ) {
1.224 - return ZEROEXT32(SIGNEXT8(*(int8_t *)(sh4_main_ram + (addr&0x00FFFFFF))));
1.225 - } else if( (addr&0x1F800000) == 0x04000000 ) {
1.226 - addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr);
1.227 - pvr2_render_buffer_invalidate(addr, FALSE);
1.228 - } else if( (addr&0x1F800000) == 0x05000000 ) {
1.229 - pvr2_render_buffer_invalidate(addr, FALSE);
1.230 - }
1.231 -
1.232 -
1.233 - page = page_map[ (addr & 0x1FFFFFFF) >> 12 ];
1.234 - if( ((uintptr_t)page) < MAX_IO_REGIONS ) { /* IO Region */
1.235 - int32_t val;
1.236 - if( page == NULL ) {
1.237 - WARN( "Attempted byte read to missing page: %08X", addr );
1.238 - return 0;
1.239 - }
1.240 - val = SIGNEXT8(io_rgn[(uintptr_t)page]->io_read(addr&0xFFF));
1.241 - TRACE_IO( "Byte read %02X <= %08X", page, (addr&0xFFF), val&0xFF, addr );
1.242 - return ZEROEXT32(val);
1.243 - } else {
1.244 - return ZEROEXT32(SIGNEXT8(*(int8_t *)(page+(addr&0xFFF))));
1.245 - }
1.246 -}
1.247 -
1.248 -/**
1.249 - * Convenience function to write a quad-word (implemented as two long writes).
1.250 - */
1.251 -void FASTCALL sh4_write_quad( sh4addr_t addr, uint64_t val )
1.252 -{
1.253 - sh4_write_long( addr, (uint32_t)val );
1.254 - sh4_write_long( addr+4, (uint32_t)(val>>32) );
1.255 -}
1.256 -
1.257 -void FASTCALL sh4_write_long( sh4addr_t addr, uint32_t val )
1.258 -{
1.259 - sh4ptr_t page;
1.260 -
1.261 - CHECK_WRITE_WATCH(addr,4,val);
1.262 -
1.263 - if( addr >= 0xE0000000 ) {
1.264 - if( addr < 0xE4000000 ) { // Shortcut for the extremely common case
1.265 - SH4_WRITE_STORE_QUEUE( addr, val );
1.266 - } else {
1.267 - sh4_write_p4( addr, val );
1.268 - }
1.269 - return;
1.270 - } else if( (addr&0x1C000000) == 0x0C000000 ) {
1.271 - *(uint32_t *)(sh4_main_ram + (addr&0x00FFFFFF)) = val;
1.272 - xlat_invalidate_long(addr);
1.273 - return;
1.274 - } else if( (addr&0x1F800000) == 0x04000000 ||
1.275 - (addr&0x1F800000) == 0x11000000 ) {
1.276 - texcache_invalidate_page(addr& 0x7FFFFF);
1.277 - addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr);
1.278 - pvr2_render_buffer_invalidate(addr, TRUE);
1.279 - } else if( (addr&0x1F800000) == 0x05000000 ) {
1.280 - pvr2_render_buffer_invalidate(addr, TRUE);
1.281 - }
1.282 -
1.283 - if( (addr&0x1FFFFFFF) < 0x200000 ) {
1.284 - WARN( "Attempted write to read-only memory: %08X => %08X", val, addr);
1.285 - sh4_stop();
1.286 - return;
1.287 - }
1.288 - if( (addr&0x1F800000) == 0x00800000 )
1.289 - asic_g2_write_word();
1.290 -
1.291 - page = page_map[ (addr & 0x1FFFFFFF) >> 12 ];
1.292 - if( ((uintptr_t)page) < MAX_IO_REGIONS ) { /* IO Region */
1.293 - if( page == NULL ) {
1.294 - if( (addr & 0x1F000000) >= 0x04000000 &&
1.295 - (addr & 0x1F000000) < 0x07000000 )
1.296 - return;
1.297 - WARN( "Long write to missing page: %08X => %08X", val, addr );
1.298 - return;
1.299 - }
1.300 - TRACE_IO( "Long write %08X => %08X", page, (addr&0xFFF), val, addr );
1.301 - io_rgn[(uintptr_t)page]->io_write(addr&0xFFF, val);
1.302 - } else {
1.303 - *(uint32_t *)(page+(addr&0xFFF)) = val;
1.304 - }
1.305 -}
1.306 -
1.307 -void FASTCALL sh4_write_word( sh4addr_t addr, uint32_t val )
1.308 -{
1.309 - sh4ptr_t page;
1.310 -
1.311 - CHECK_WRITE_WATCH(addr,2,val);
1.312 -
1.313 - if( addr >= 0xE0000000 ) {
1.314 - sh4_write_p4( addr, (int16_t)val );
1.315 - return;
1.316 - } else if( (addr&0x1C000000) == 0x0C000000 ) {
1.317 - *(uint16_t *)(sh4_main_ram + (addr&0x00FFFFFF)) = val;
1.318 - xlat_invalidate_word(addr);
1.319 - return;
1.320 - } else if( (addr&0x1F800000) == 0x04000000 ||
1.321 - (addr&0x1F800000) == 0x11000000 ) {
1.322 - texcache_invalidate_page(addr& 0x7FFFFF);
1.323 - addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr);
1.324 - pvr2_render_buffer_invalidate(addr, TRUE);
1.325 - } else if( (addr&0x1F800000) == 0x05000000 ) {
1.326 - pvr2_render_buffer_invalidate(addr, TRUE);
1.327 - }
1.328 -
1.329 - if( (addr&0x1FFFFFFF) < 0x200000 ) {
1.330 - WARN( "Attempted write to read-only memory: %08X => %08X", val, addr);
1.331 - sh4_stop();
1.332 - return;
1.333 - }
1.334 - page = page_map[ (addr & 0x1FFFFFFF) >> 12 ];
1.335 - if( ((uintptr_t)page) < MAX_IO_REGIONS ) { /* IO Region */
1.336 - if( page == NULL ) {
1.337 - WARN( "Attempted word write to missing page: %08X", addr );
1.338 - return;
1.339 - }
1.340 - TRACE_IO( "Word write %04X => %08X", page, (addr&0xFFF), val&0xFFFF, addr );
1.341 - io_rgn[(uintptr_t)page]->io_write(addr&0xFFF, val);
1.342 - } else {
1.343 - *(uint16_t *)(page+(addr&0xFFF)) = val;
1.344 - }
1.345 -}
1.346 -
1.347 -void FASTCALL sh4_write_byte( sh4addr_t addr, uint32_t val )
1.348 -{
1.349 - sh4ptr_t page;
1.350 -
1.351 - CHECK_WRITE_WATCH(addr,1,val);
1.352 -
1.353 - if( addr >= 0xE0000000 ) {
1.354 - sh4_write_p4( addr, (int8_t)val );
1.355 - return;
1.356 - } else if( (addr&0x1C000000) == 0x0C000000 ) {
1.357 - *(uint8_t *)(sh4_main_ram + (addr&0x00FFFFFF)) = val;
1.358 - xlat_invalidate_word(addr);
1.359 - return;
1.360 - } else if( (addr&0x1F800000) == 0x04000000 ||
1.361 - (addr&0x1F800000) == 0x11000000 ) {
1.362 - texcache_invalidate_page(addr& 0x7FFFFF);
1.363 - addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr);
1.364 - pvr2_render_buffer_invalidate(addr, TRUE);
1.365 - } else if( (addr&0x1F800000) == 0x05000000 ) {
1.366 - pvr2_render_buffer_invalidate(addr, TRUE);
1.367 - }
1.368 -
1.369 - if( (addr&0x1FFFFFFF) < 0x200000 ) {
1.370 - WARN( "Attempted write to read-only memory: %08X => %08X", val, addr);
1.371 - sh4_stop();
1.372 - return;
1.373 - }
1.374 - page = page_map[ (addr & 0x1FFFFFFF) >> 12 ];
1.375 - if( ((uintptr_t)page) < MAX_IO_REGIONS ) { /* IO Region */
1.376 - if( page == NULL ) {
1.377 - WARN( "Attempted byte write to missing page: %08X", addr );
1.378 - return;
1.379 - }
1.380 - TRACE_IO( "Byte write %02X => %08X", page, (addr&0xFFF), val&0xFF, addr );
1.381 - io_rgn[(uintptr_t)page]->io_write( (addr&0xFFF), val);
1.382 - } else {
1.383 - *(uint8_t *)(page+(addr&0xFFF)) = val;
1.384 - }
1.385 -}
1.386 -
1.387 -
1.388 +/************** Obsolete methods ***************/
1.389
1.390 /* FIXME: Handle all the many special cases when the range doesn't fall cleanly
1.391 * into the same memory block
1.392 @@ -431,4 +67,3 @@
1.393 memcpy( dest, src, count );
1.394 }
1.395 }
1.396 -
.