Search
lxdream.org :: lxdream/src/sh4/sh4mem.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4mem.c
changeset 559:06714bc64271
prev550:a27e31340147
next561:533f6b478071
author nkeynes
date Tue Jan 01 04:58:57 2008 +0000 (12 years ago)
branchlxdream-mmu
permissions -rw-r--r--
last change Commit first pass at full TLB support - still needs a lot more work
file annotate diff log raw
1.1 --- a/src/sh4/sh4mem.c Thu Dec 06 10:43:30 2007 +0000
1.2 +++ b/src/sh4/sh4mem.c Tue Jan 01 04:58:57 2008 +0000
1.3 @@ -156,16 +156,22 @@
1.4 (((int64_t)((uint32_t)sh4_read_long(addr+4))) << 32);
1.5 }
1.6
1.7 -int32_t sh4_read_long( sh4addr_t addr )
1.8 +int64_t sh4_read_long( sh4addr_t vma )
1.9 {
1.10 sh4ptr_t page;
1.11
1.12 CHECK_READ_WATCH(addr,4);
1.13
1.14 + uint64_t ppa = mmu_vma_to_phys_read(vma);
1.15 + if( ppa>>32 ) {
1.16 + return ppa;
1.17 + }
1.18 + sh4addr_t addr = (sh4addr_t)ppa;
1.19 +
1.20 if( addr >= 0xE0000000 ) { /* P4 Area, handled specially */
1.21 - return sh4_read_p4( addr );
1.22 + return ZEROEXT32(sh4_read_p4( addr ));
1.23 } else if( (addr&0x1C000000) == 0x0C000000 ) {
1.24 - return *(int32_t *)(sh4_main_ram + (addr&0x00FFFFFF));
1.25 + return ZEROEXT32(*(int32_t *)(sh4_main_ram + (addr&0x00FFFFFF)));
1.26 } else if( (addr&0x1F800000) == 0x04000000 ) {
1.27 addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr);
1.28 pvr2_render_buffer_invalidate(addr, FALSE);
1.29 @@ -182,22 +188,28 @@
1.30 }
1.31 val = io_rgn[(uintptr_t)page]->io_read(addr&0xFFF);
1.32 TRACE_IO( "Long read %08X <= %08X", page, (addr&0xFFF), val, addr );
1.33 - return val;
1.34 + return ZEROEXT32(val);
1.35 } else {
1.36 - return *(int32_t *)(page+(addr&0xFFF));
1.37 + return ZEROEXT32(*(int32_t *)(page+(addr&0xFFF)));
1.38 }
1.39 }
1.40
1.41 -int32_t sh4_read_word( sh4addr_t addr )
1.42 +int64_t sh4_read_word( sh4addr_t vma )
1.43 {
1.44 sh4ptr_t page;
1.45
1.46 CHECK_READ_WATCH(addr,2);
1.47
1.48 + uint64_t ppa = mmu_vma_to_phys_read(vma);
1.49 + if( ppa>>32 ) {
1.50 + return ppa;
1.51 + }
1.52 + sh4addr_t addr = (sh4addr_t)ppa;
1.53 +
1.54 if( addr >= 0xE0000000 ) { /* P4 Area, handled specially */
1.55 - return SIGNEXT16(sh4_read_p4( addr ));
1.56 + return ZEROEXT32(SIGNEXT16(sh4_read_p4( addr )));
1.57 } else if( (addr&0x1C000000) == 0x0C000000 ) {
1.58 - return SIGNEXT16(*(int16_t *)(sh4_main_ram + (addr&0x00FFFFFF)));
1.59 + return ZEROEXT32(SIGNEXT16(*(int16_t *)(sh4_main_ram + (addr&0x00FFFFFF))));
1.60 } else if( (addr&0x1F800000) == 0x04000000 ) {
1.61 addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr);
1.62 pvr2_render_buffer_invalidate(addr, FALSE);
1.63 @@ -214,22 +226,28 @@
1.64 }
1.65 val = SIGNEXT16(io_rgn[(uintptr_t)page]->io_read(addr&0xFFF));
1.66 TRACE_IO( "Word read %04X <= %08X", page, (addr&0xFFF), val&0xFFFF, addr );
1.67 - return val;
1.68 + return ZEROEXT32(val);
1.69 } else {
1.70 - return SIGNEXT16(*(int16_t *)(page+(addr&0xFFF)));
1.71 + return ZEROEXT32(SIGNEXT16(*(int16_t *)(page+(addr&0xFFF))));
1.72 }
1.73 }
1.74
1.75 -int32_t sh4_read_byte( sh4addr_t addr )
1.76 +int64_t sh4_read_byte( sh4addr_t vma )
1.77 {
1.78 sh4ptr_t page;
1.79
1.80 CHECK_READ_WATCH(addr,1);
1.81
1.82 + uint64_t ppa = mmu_vma_to_phys_read(vma);
1.83 + if( ppa>>32 ) {
1.84 + return ppa;
1.85 + }
1.86 + sh4addr_t addr = (sh4addr_t)ppa;
1.87 +
1.88 if( addr >= 0xE0000000 ) { /* P4 Area, handled specially */
1.89 - return SIGNEXT8(sh4_read_p4( addr ));
1.90 + return ZEROEXT32(SIGNEXT8(sh4_read_p4( addr )));
1.91 } else if( (addr&0x1C000000) == 0x0C000000 ) {
1.92 - return SIGNEXT8(*(int8_t *)(sh4_main_ram + (addr&0x00FFFFFF)));
1.93 + return ZEROEXT32(SIGNEXT8(*(int8_t *)(sh4_main_ram + (addr&0x00FFFFFF))));
1.94 } else if( (addr&0x1F800000) == 0x04000000 ) {
1.95 addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr);
1.96 pvr2_render_buffer_invalidate(addr, FALSE);
1.97 @@ -247,9 +265,9 @@
1.98 }
1.99 val = SIGNEXT8(io_rgn[(uintptr_t)page]->io_read(addr&0xFFF));
1.100 TRACE_IO( "Byte read %02X <= %08X", page, (addr&0xFFF), val&0xFF, addr );
1.101 - return val;
1.102 + return ZEROEXT32(val);
1.103 } else {
1.104 - return SIGNEXT8(*(int8_t *)(page+(addr&0xFFF)));
1.105 + return ZEROEXT32(SIGNEXT8(*(int8_t *)(page+(addr&0xFFF))));
1.106 }
1.107 }
1.108
1.109 @@ -262,19 +280,25 @@
1.110 sh4_write_long( addr+4, (uint32_t)(val>>32) );
1.111 }
1.112
1.113 -void sh4_write_long( sh4addr_t addr, uint32_t val )
1.114 +int32_t sh4_write_long( sh4addr_t vma, uint32_t val )
1.115 {
1.116 sh4ptr_t page;
1.117
1.118 + uint64_t ppa = mmu_vma_to_phys_write(vma);
1.119 + if( ppa>>32 ) {
1.120 + return ppa>>32;
1.121 + }
1.122 + sh4addr_t addr = (sh4addr_t)ppa;
1.123 +
1.124 CHECK_WRITE_WATCH(addr,4,val);
1.125
1.126 if( addr >= 0xE0000000 ) {
1.127 sh4_write_p4( addr, val );
1.128 - return;
1.129 + return 0;
1.130 } else if( (addr&0x1C000000) == 0x0C000000 ) {
1.131 *(uint32_t *)(sh4_main_ram + (addr&0x00FFFFFF)) = val;
1.132 xlat_invalidate_long(addr);
1.133 - return;
1.134 + return 0;
1.135 } else if( (addr&0x1F800000) == 0x04000000 ||
1.136 (addr&0x1F800000) == 0x11000000 ) {
1.137 texcache_invalidate_page(addr& 0x7FFFFF);
1.138 @@ -287,7 +311,7 @@
1.139 if( (addr&0x1FFFFFFF) < 0x200000 ) {
1.140 WARN( "Attempted write to read-only memory: %08X => %08X", val, addr);
1.141 sh4_stop();
1.142 - return;
1.143 + return 0;
1.144 }
1.145 if( (addr&0x1F800000) == 0x00800000 )
1.146 asic_g2_write_word();
1.147 @@ -297,30 +321,37 @@
1.148 if( page == NULL ) {
1.149 if( (addr & 0x1F000000) >= 0x04000000 &&
1.150 (addr & 0x1F000000) < 0x07000000 )
1.151 - return;
1.152 + return 0;
1.153 WARN( "Long write to missing page: %08X => %08X", val, addr );
1.154 - return;
1.155 + return 0;
1.156 }
1.157 TRACE_IO( "Long write %08X => %08X", page, (addr&0xFFF), val, addr );
1.158 io_rgn[(uintptr_t)page]->io_write(addr&0xFFF, val);
1.159 } else {
1.160 *(uint32_t *)(page+(addr&0xFFF)) = val;
1.161 }
1.162 + return 0;
1.163 }
1.164
1.165 -void sh4_write_word( sh4addr_t addr, uint32_t val )
1.166 +int32_t sh4_write_word( sh4addr_t vma, uint32_t val )
1.167 {
1.168 sh4ptr_t page;
1.169
1.170 + uint64_t ppa = mmu_vma_to_phys_write(vma);
1.171 + if( ppa>>32 ) {
1.172 + return ppa>>32;
1.173 + }
1.174 + sh4addr_t addr = (sh4addr_t)ppa;
1.175 +
1.176 CHECK_WRITE_WATCH(addr,2,val);
1.177
1.178 if( addr >= 0xE0000000 ) {
1.179 sh4_write_p4( addr, (int16_t)val );
1.180 - return;
1.181 + return 0;
1.182 } else if( (addr&0x1C000000) == 0x0C000000 ) {
1.183 *(uint16_t *)(sh4_main_ram + (addr&0x00FFFFFF)) = val;
1.184 xlat_invalidate_word(addr);
1.185 - return;
1.186 + return 0;
1.187 } else if( (addr&0x1F800000) == 0x04000000 ||
1.188 (addr&0x1F800000) == 0x11000000 ) {
1.189 texcache_invalidate_page(addr& 0x7FFFFF);
1.190 @@ -333,34 +364,41 @@
1.191 if( (addr&0x1FFFFFFF) < 0x200000 ) {
1.192 WARN( "Attempted write to read-only memory: %08X => %08X", val, addr);
1.193 sh4_stop();
1.194 - return;
1.195 + return 0;
1.196 }
1.197 page = page_map[ (addr & 0x1FFFFFFF) >> 12 ];
1.198 if( ((uintptr_t)page) < MAX_IO_REGIONS ) { /* IO Region */
1.199 if( page == NULL ) {
1.200 WARN( "Attempted word write to missing page: %08X", addr );
1.201 - return;
1.202 + return 0;
1.203 }
1.204 TRACE_IO( "Word write %04X => %08X", page, (addr&0xFFF), val&0xFFFF, addr );
1.205 io_rgn[(uintptr_t)page]->io_write(addr&0xFFF, val);
1.206 } else {
1.207 *(uint16_t *)(page+(addr&0xFFF)) = val;
1.208 }
1.209 + return 0;
1.210 }
1.211
1.212 -void sh4_write_byte( sh4addr_t addr, uint32_t val )
1.213 +int32_t sh4_write_byte( sh4addr_t vma, uint32_t val )
1.214 {
1.215 sh4ptr_t page;
1.216 +
1.217 + uint64_t ppa = mmu_vma_to_phys_write(vma);
1.218 + if( ppa>>32 ) {
1.219 + return ppa>>32;
1.220 + }
1.221 + sh4addr_t addr = (sh4addr_t)ppa;
1.222
1.223 CHECK_WRITE_WATCH(addr,1,val);
1.224
1.225 if( addr >= 0xE0000000 ) {
1.226 sh4_write_p4( addr, (int8_t)val );
1.227 - return;
1.228 + return 0;
1.229 } else if( (addr&0x1C000000) == 0x0C000000 ) {
1.230 *(uint8_t *)(sh4_main_ram + (addr&0x00FFFFFF)) = val;
1.231 xlat_invalidate_word(addr);
1.232 - return;
1.233 + return 0;
1.234 } else if( (addr&0x1F800000) == 0x04000000 ||
1.235 (addr&0x1F800000) == 0x11000000 ) {
1.236 texcache_invalidate_page(addr& 0x7FFFFF);
1.237 @@ -373,19 +411,20 @@
1.238 if( (addr&0x1FFFFFFF) < 0x200000 ) {
1.239 WARN( "Attempted write to read-only memory: %08X => %08X", val, addr);
1.240 sh4_stop();
1.241 - return;
1.242 + return 0;
1.243 }
1.244 page = page_map[ (addr & 0x1FFFFFFF) >> 12 ];
1.245 if( ((uintptr_t)page) < MAX_IO_REGIONS ) { /* IO Region */
1.246 if( page == NULL ) {
1.247 WARN( "Attempted byte write to missing page: %08X", addr );
1.248 - return;
1.249 + return 0;
1.250 }
1.251 TRACE_IO( "Byte write %02X => %08X", page, (addr&0xFFF), val&0xFF, addr );
1.252 io_rgn[(uintptr_t)page]->io_write( (addr&0xFFF), val);
1.253 } else {
1.254 *(uint8_t *)(page+(addr&0xFFF)) = val;
1.255 }
1.256 + return 0;
1.257 }
1.258
1.259
1.260 @@ -434,3 +473,20 @@
1.261 uint32_t target = (addr&0x03FFFFE0) | hi;
1.262 mem_copy_to_sh4( target, src, 32 );
1.263 }
1.264 +
1.265 +sh4ptr_t sh4_get_region_by_vma( sh4addr_t vma )
1.266 +{
1.267 + uint64_t ppa = mmu_vma_to_phys_read(vma);
1.268 + if( ppa>>32 ) {
1.269 + return 0;
1.270 + }
1.271 +
1.272 + sh4addr_t addr = (sh4addr_t)ppa;
1.273 + sh4ptr_t page = page_map[ (addr & 0x1FFFFFFF) >> 12 ];
1.274 + if( ((uintptr_t)page) < MAX_IO_REGIONS ) { /* IO Region */
1.275 + return NULL;
1.276 + } else {
1.277 + return page+(addr&0xFFF);
1.278 + }
1.279 +}
1.280 +
.