revision 826:69f2c9f1e608
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 826:69f2c9f1e608 |
parent | 825:2ac7ceccd775 |
child | 827:d333f4248727 |
author | nkeynes |
date | Sun Aug 24 02:43:28 2008 +0000 (15 years ago) |
Fix mask correctness of MMU/general IO registers, add unknown/undoced
register at FF00002C
register at FF00002C
src/sh4/mmu.c | view | annotate | diff | log | ||
src/sh4/sh4mmio.h | view | annotate | diff | log | ||
test/testregs.c | view | annotate | diff | log |
1.1 --- a/src/sh4/mmu.c Sun Aug 24 01:58:09 2008 +00001.2 +++ b/src/sh4/mmu.c Sun Aug 24 02:43:28 2008 +00001.3 @@ -1,6 +1,6 @@1.4 /**1.5 * $Id$1.6 - *1.7 + *1.8 * MMU implementation1.9 *1.10 * Copyright (c) 2005 Nathan Keynes.1.11 @@ -153,6 +153,13 @@1.12 case PTEA:1.13 val &= 0x0000000F;1.14 break;1.15 + case TRA:1.16 + val &= 0x000003FC;1.17 + break;1.18 + case EXPEVT:1.19 + case INTEVT:1.20 + val &= 0x00000FFF;1.21 + break;1.22 case MMUCR:1.23 if( val & MMUCR_TI ) {1.24 mmu_invalidate_tlb();1.25 @@ -174,6 +181,16 @@1.26 mmu_set_cache_mode( val & (CCR_OIX|CCR_ORA|CCR_OCE) );1.27 val &= 0x81A7;1.28 break;1.29 + case MMUUNK1:1.30 + /* Note that if the high bit is set, this appears to reset the machine.1.31 + * Not emulating this behaviour yet until we know why...1.32 + */1.33 + val &= 0x00010007;1.34 + break;1.35 + case QACR0:1.36 + case QACR1:1.37 + val &= 0x0000001C;1.38 + break;1.39 case PMCR1:1.40 case PMCR2:1.41 if( val != 0 ) {1.42 @@ -187,7 +204,7 @@1.43 }1.46 -void MMU_init()1.47 +void MMU_init()1.48 {1.49 cache = mem_alloc_pages(2);1.50 }1.51 @@ -344,7 +361,7 @@1.52 unsigned int i;1.53 for( i = 0; i < UTLB_ENTRY_COUNT; i++ ) {1.54 if( (mmu_utlb[i].flags & TLB_VALID) &&1.55 - ((mmu_utlb[i].flags & TLB_SHARE) || asid == mmu_utlb[i].asid) &&1.56 + ((mmu_utlb[i].flags & TLB_SHARE) || asid == mmu_utlb[i].asid) &&1.57 ((mmu_utlb[i].vpn ^ vpn) & mmu_utlb[i].mask) == 0 ) {1.58 if( result != -1 ) {1.59 fprintf( stderr, "TLB Multi hit: %d %d\n", result, i );1.60 @@ -366,7 +383,7 @@1.61 unsigned int i;1.62 for( i = 0; i < ITLB_ENTRY_COUNT; i++ ) {1.63 if( (mmu_itlb[i].flags & TLB_VALID) &&1.64 - ((mmu_itlb[i].flags & TLB_SHARE) || asid == mmu_itlb[i].asid) &&1.65 + ((mmu_itlb[i].flags & TLB_SHARE) || asid == mmu_itlb[i].asid) &&1.66 ((mmu_itlb[i].vpn ^ vpn) & mmu_itlb[i].mask) == 0 ) {1.67 if( result != -1 ) {1.68 return -2;1.69 @@ -460,7 +477,7 @@1.70 /******************************************************************************/1.72 /**1.73 - * The translations are excessively complicated, but unfortunately it's a1.74 + * The translations are excessively complicated, but unfortunately it's a1.75 * complicated system. TODO: make this not be painfully slow.1.76 */1.78 @@ -485,7 +502,7 @@1.80 for( i = 0; i < UTLB_ENTRY_COUNT; i++ ) {1.81 if( (mmu_utlb[i].flags & TLB_VALID) &&1.82 - ((mmu_utlb[i].flags & TLB_SHARE) || mmu_asid == mmu_utlb[i].asid) &&1.83 + ((mmu_utlb[i].flags & TLB_SHARE) || mmu_asid == mmu_utlb[i].asid) &&1.84 ((mmu_utlb[i].vpn ^ vpn) & mmu_utlb[i].mask) == 0 ) {1.85 if( result != -1 ) {1.86 return -2;1.87 @@ -548,7 +565,7 @@1.88 } else { // Note - gets invalid entries too1.89 replace = 3;1.90 mmu_lrui = (mmu_lrui | 0x0B);1.91 - }1.92 + }1.94 mmu_itlb[replace].vpn = mmu_utlb[entryNo].vpn;1.95 mmu_itlb[replace].mask = mmu_utlb[entryNo].mask;1.96 @@ -574,7 +591,7 @@1.98 for( i = 0; i < ITLB_ENTRY_COUNT; i++ ) {1.99 if( (mmu_itlb[i].flags & TLB_VALID) &&1.100 - ((mmu_itlb[i].flags & TLB_SHARE) || mmu_asid == mmu_itlb[i].asid) &&1.101 + ((mmu_itlb[i].flags & TLB_SHARE) || mmu_asid == mmu_itlb[i].asid) &&1.102 ((mmu_itlb[i].vpn ^ vpn) & mmu_itlb[i].mask) == 0 ) {1.103 if( result != -1 ) {1.104 return -2;1.105 @@ -695,9 +712,9 @@1.106 }1.108 /* finally generate the target address */1.109 - sh4addr_t pma = (mmu_utlb[entryNo].ppn & mmu_utlb[entryNo].mask) |1.110 + sh4addr_t pma = (mmu_utlb[entryNo].ppn & mmu_utlb[entryNo].mask) |1.111 (addr & (~mmu_utlb[entryNo].mask));1.112 - if( pma > 0x1C000000 ) // Remap 1Cxx .. 1Fxx region to P41.113 + if( pma > 0x1C000000 ) // Remap 1Cxx .. 1Fxx region to P41.114 pma |= 0xE0000000;1.115 return pma;1.116 }1.117 @@ -758,9 +775,9 @@1.118 }1.120 /* finally generate the target address */1.121 - sh4addr_t pma = (mmu_utlb[entryNo].ppn & mmu_utlb[entryNo].mask) |1.122 + sh4addr_t pma = (mmu_utlb[entryNo].ppn & mmu_utlb[entryNo].mask) |1.123 (addr & (~mmu_utlb[entryNo].mask));1.124 - if( pma > 0x1C000000 ) // Remap 1Cxx .. 1Fxx region to P41.125 + if( pma > 0x1C000000 ) // Remap 1Cxx .. 1Fxx region to P41.126 pma |= 0xE0000000;1.127 return pma;1.128 }1.129 @@ -822,7 +839,7 @@1.130 return TRUE;1.131 }1.133 - if( (mmucr & MMUCR_SV) == 0 )1.134 + if( (mmucr & MMUCR_SV) == 0 )1.135 entryNo = mmu_itlb_lookup_vpn_asid( addr );1.136 else1.137 entryNo = mmu_itlb_lookup_vpn( addr );1.138 @@ -867,10 +884,10 @@1.139 }1.141 /**1.142 - * Translate address for disassembly purposes (ie performs an instruction1.143 + * Translate address for disassembly purposes (ie performs an instruction1.144 * lookup) - does not raise exceptions or modify any state, and ignores1.145 * protection bits. Returns the translated address, or MMU_VMA_ERROR1.146 - * on translation failure.1.147 + * on translation failure.1.148 */1.149 sh4addr_t mmu_vma_to_phys_disasm( sh4vma_t vma )1.150 {1.151 @@ -896,8 +913,8 @@1.152 if( entryNo < 0 ) {1.153 return MMU_VMA_ERROR;1.154 } else {1.155 - return (mmu_itlb[entryNo].ppn & mmu_itlb[entryNo].mask) |1.156 - (vma & (~mmu_itlb[entryNo].mask));1.157 + return (mmu_itlb[entryNo].ppn & mmu_itlb[entryNo].mask) |1.158 + (vma & (~mmu_itlb[entryNo].mask));1.159 }1.160 }1.162 @@ -936,7 +953,7 @@1.163 }1.165 /* finally generate the target address */1.166 - target = ((mmu_utlb[entryNo].ppn & mmu_utlb[entryNo].mask) |1.167 + target = ((mmu_utlb[entryNo].ppn & mmu_utlb[entryNo].mask) |1.168 (addr & (~mmu_utlb[entryNo].mask))) & 0xFFFFFFE0;1.169 }1.170 } else {
2.1 --- a/src/sh4/sh4mmio.h Sun Aug 24 01:58:09 2008 +00002.2 +++ b/src/sh4/sh4mmio.h Sun Aug 24 02:43:28 2008 +00002.3 @@ -1,6 +1,6 @@2.4 /**2.5 * $Id$2.6 - *2.7 + *2.8 * MMIO region and supporting function declarations. Private to the sh42.9 * module.2.10 *2.11 @@ -46,6 +46,7 @@2.12 LONG_PORT( 0x020, TRA, PORT_MRW, UNDEFINED, "TRAPA exception register" )2.13 LONG_PORT( 0x024, EXPEVT,PORT_MRW, 0, "Exception event register" )2.14 LONG_PORT( 0x028, INTEVT,PORT_MRW, UNDEFINED, "Interrupt event register" )2.15 + LONG_PORT( 0x02C, MMUUNK1, PORT_MRW, 0, "Unknown MMU/general register" )2.16 LONG_PORT( 0x030, SH4VER, PORT_MRW, 0x040205C1, "SH4 version register (PVR)" ) /* Renamed to avoid naming conflict */2.17 LONG_PORT( 0x034, PTEA, PORT_MRW, UNDEFINED, "Page table entry assistance" )2.18 LONG_PORT( 0x038, QACR0,PORT_MRW, UNDEFINED, "Queue address control 0" )2.19 @@ -56,10 +57,10 @@2.21 /* Performance counter values (undocumented) */2.22 MMIO_REGION_BEGIN( 0xFF100000, PMM, "Performance monitoring" )2.23 - LONG_PORT (0x004, PMCTR1H, PORT_MR, 0, "Performance counter 1 High" )2.24 - LONG_PORT (0x008, PMCTR1L, PORT_MR, 0, "Performance counter 1 Low" )2.25 - LONG_PORT (0x00C, PMCTR2H, PORT_MR, 0, "Performance counter 2 High" )2.26 - LONG_PORT (0x010, PMCTR2L, PORT_MR, 0, "Performance counter 2 Low" )2.27 + LONG_PORT( 0x004, PMCTR1H, PORT_MR, 0, "Performance counter 1 High" )2.28 + LONG_PORT( 0x008, PMCTR1L, PORT_MR, 0, "Performance counter 1 Low" )2.29 + LONG_PORT( 0x00C, PMCTR2H, PORT_MR, 0, "Performance counter 2 High" )2.30 + LONG_PORT( 0x010, PMCTR2L, PORT_MR, 0, "Performance counter 2 Low" )2.31 MMIO_REGION_END2.33 /* User Break Controller (Page 717 [757] of sh7750h manual) */2.34 @@ -173,7 +174,7 @@2.35 BYTE_PORT( 0x004, SCBRR2, PORT_MRW, 0xFF, "Bit rate register (FIFO)" )2.36 WORD_PORT( 0x008, SCSCR2, PORT_MRW, 0x0000, "Serial control register" )2.37 BYTE_PORT( 0x00C, SCFTDR2, PORT_W, UNDEFINED, "Transmit FIFO data register" )2.38 - WORD_PORT( 0x010, SCFSR2, PORT_MRW, 0x0060, "Serial status register (FIFO)")2.39 + WORD_PORT( 0x010, SCFSR2, PORT_MRW, 0x0060, "Serial status register (FIFO)" )2.40 BYTE_PORT( 0x014, SCFRDR2, PORT_R, UNDEFINED, "Receive FIFO data register" )2.41 WORD_PORT( 0x018, SCFCR2, PORT_MRW, 0x0000, "FIFO control register" )2.42 WORD_PORT( 0x01C, SCFDR2, PORT_MR, 0x0000, "FIFO data count register" )
3.1 --- a/test/testregs.c Sun Aug 24 01:58:09 2008 +00003.2 +++ b/test/testregs.c Sun Aug 24 02:43:28 2008 +00003.3 @@ -192,9 +192,23 @@3.4 { 0xA05F81F4, 0xFFFFFFFF, 0 },3.5 { 0xA05F81F8, 0xFFFFFFFF, 0 },3.6 { 0xA05F81FC, 0xFFFFFFFF, 0 },3.7 + /* SH4 control regs */3.8 + { 0xFF000000, 0xFFFFFFFF, 0xFFFFFCFF },3.9 + { 0xFF000004, 0xFFFFFFFF, 0x1FFFFDFF },3.10 + { 0xFF000008, 0xFFFFFFFF, 0xFFFFFFFF },3.11 + { 0xFF00000C, 0xFFFFFFFF, 0xFFFFFFFF },3.12 + { 0xFF000010, 0xFFFFFFFF, 0xFCFCFF01 },3.13 + { 0xFF000010, 0, 0 },3.14 { 0xFF00001C, 0xFFFFFFFF, 0x000081A7 },3.15 + { 0xFF000020, 0xFFFFFFFF, 0x000003FC },3.16 + { 0xFF000024, 0xFFFFFFFF, 0x00000FFF },3.17 + { 0xFF000028, 0xFFFFFFFF, 0x00000FFF },3.18 + { 0xFF00002C, 0x7FFFFFFF, 0x00010007 },3.19 { 0xFF000030, 0xFFFFFFFF, 0x040205C1 },3.20 { 0xFF000030, 0, 0x040205C1 },3.21 + { 0xFF000034, 0xFFFFFFFF, 0x0000000F },3.22 + { 0xFF000038, 0xFFFFFFFF, 0x0000001C },3.23 + { 0xFF00003C, 0xFFFFFFFF, 0x0000001C },3.24 { 0, 0, 0 } };3.26 int main( int argc, char *argv[] )
.