Search
lxdream.org :: lxdream/src/sh4/mmu.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/mmu.c
changeset 826:69f2c9f1e608
prev819:ef4fec10a63a
next841:808d64b05073
author nkeynes
date Sun Aug 24 02:43:28 2008 +0000 (12 years ago)
permissions -rw-r--r--
last change Fix mask correctness of MMU/general IO registers, add unknown/undoced
register at FF00002C
file annotate diff log raw
1.1 --- a/src/sh4/mmu.c Tue Aug 19 22:58:05 2008 +0000
1.2 +++ b/src/sh4/mmu.c Sun Aug 24 02:43:28 2008 +0000
1.3 @@ -1,6 +1,6 @@
1.4 /**
1.5 * $Id$
1.6 - *
1.7 + *
1.8 * MMU implementation
1.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.44
1.45
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.71
1.72 /**
1.73 - * The translations are excessively complicated, but unfortunately it's a
1.74 + * The translations are excessively complicated, but unfortunately it's a
1.75 * complicated system. TODO: make this not be painfully slow.
1.76 */
1.77
1.78 @@ -485,7 +502,7 @@
1.79
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 too
1.89 replace = 3;
1.90 mmu_lrui = (mmu_lrui | 0x0B);
1.91 - }
1.92 + }
1.93
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.97
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.107
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 P4
1.113 + if( pma > 0x1C000000 ) // Remap 1Cxx .. 1Fxx region to P4
1.114 pma |= 0xE0000000;
1.115 return pma;
1.116 }
1.117 @@ -758,9 +775,9 @@
1.118 }
1.119
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 P4
1.125 + if( pma > 0x1C000000 ) // Remap 1Cxx .. 1Fxx region to P4
1.126 pma |= 0xE0000000;
1.127 return pma;
1.128 }
1.129 @@ -822,7 +839,7 @@
1.130 return TRUE;
1.131 }
1.132
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 else
1.137 entryNo = mmu_itlb_lookup_vpn( addr );
1.138 @@ -867,10 +884,10 @@
1.139 }
1.140
1.141 /**
1.142 - * Translate address for disassembly purposes (ie performs an instruction
1.143 + * Translate address for disassembly purposes (ie performs an instruction
1.144 * lookup) - does not raise exceptions or modify any state, and ignores
1.145 * protection bits. Returns the translated address, or MMU_VMA_ERROR
1.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.161
1.162 @@ -936,7 +953,7 @@
1.163 }
1.164
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 {
.