Search
lxdream.org :: lxdream/src/sh4/mmu.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/mmu.c
changeset 911:2f6ba75b84d1
prev905:4c17ebd9ef5e
next915:c989eb4c22d8
author nkeynes
date Fri Oct 31 02:57:59 2008 +0000 (13 years ago)
permissions -rw-r--r--
last change Declare mem_copy_* functions as FASTCALL
Split sh4_flush_store_queue into TLB/non-TLB versions, and optimize
slightly based on that
file annotate diff log raw
1.1 --- a/src/sh4/mmu.c Wed Oct 29 23:51:58 2008 +0000
1.2 +++ b/src/sh4/mmu.c Fri Oct 31 02:57:59 2008 +0000
1.3 @@ -920,48 +920,54 @@
1.4 }
1.5 }
1.6
1.7 -gboolean FASTCALL sh4_flush_store_queue( sh4addr_t addr )
1.8 +void FASTCALL sh4_flush_store_queue( sh4addr_t addr )
1.9 +{
1.10 + int queue = (addr&0x20)>>2;
1.11 + uint32_t hi = MMIO_READ( MMU, QACR0 + (queue>>1)) << 24;
1.12 + sh4ptr_t src = (sh4ptr_t)&sh4r.store_queue[queue];
1.13 + sh4addr_t target = (addr&0x03FFFFE0) | hi;
1.14 + mem_copy_to_sh4( target, src, 32 );
1.15 +}
1.16 +
1.17 +gboolean FASTCALL sh4_flush_store_queue_mmu( sh4addr_t addr )
1.18 {
1.19 uint32_t mmucr = MMIO_READ(MMU,MMUCR);
1.20 int queue = (addr&0x20)>>2;
1.21 sh4ptr_t src = (sh4ptr_t)&sh4r.store_queue[queue];
1.22 sh4addr_t target;
1.23 /* Store queue operation */
1.24 - if( mmucr & MMUCR_AT ) {
1.25 - int entryNo;
1.26 - if( ((mmucr & MMUCR_SV) == 0) || !IS_SH4_PRIVMODE() ) {
1.27 - entryNo = mmu_utlb_lookup_vpn_asid( addr );
1.28 - } else {
1.29 - entryNo = mmu_utlb_lookup_vpn( addr );
1.30 - }
1.31 - switch(entryNo) {
1.32 - case -1:
1.33 - MMU_TLB_WRITE_MISS_ERROR(addr);
1.34 - return FALSE;
1.35 - case -2:
1.36 - MMU_TLB_MULTI_HIT_ERROR(addr);
1.37 - return FALSE;
1.38 - default:
1.39 - if( IS_SH4_PRIVMODE() ? ((mmu_utlb[entryNo].flags & TLB_WRITABLE) == 0)
1.40 - : ((mmu_utlb[entryNo].flags & TLB_USERWRITABLE) != TLB_USERWRITABLE) ) {
1.41 - /* protection violation */
1.42 - MMU_TLB_WRITE_PROT_ERROR(addr);
1.43 - return FALSE;
1.44 - }
1.45
1.46 - if( (mmu_utlb[entryNo].flags & TLB_DIRTY) == 0 ) {
1.47 - MMU_TLB_INITIAL_WRITE_ERROR(addr);
1.48 - return FALSE;
1.49 - }
1.50 + int entryNo;
1.51 + if( ((mmucr & MMUCR_SV) == 0) || !IS_SH4_PRIVMODE() ) {
1.52 + entryNo = mmu_utlb_lookup_vpn_asid( addr );
1.53 + } else {
1.54 + entryNo = mmu_utlb_lookup_vpn( addr );
1.55 + }
1.56 + switch(entryNo) {
1.57 + case -1:
1.58 + MMU_TLB_WRITE_MISS_ERROR(addr);
1.59 + return FALSE;
1.60 + case -2:
1.61 + MMU_TLB_MULTI_HIT_ERROR(addr);
1.62 + return FALSE;
1.63 + default:
1.64 + if( IS_SH4_PRIVMODE() ? ((mmu_utlb[entryNo].flags & TLB_WRITABLE) == 0)
1.65 + : ((mmu_utlb[entryNo].flags & TLB_USERWRITABLE) != TLB_USERWRITABLE) ) {
1.66 + /* protection violation */
1.67 + MMU_TLB_WRITE_PROT_ERROR(addr);
1.68 + return FALSE;
1.69 + }
1.70
1.71 - /* finally generate the target address */
1.72 - target = ((mmu_utlb[entryNo].ppn & mmu_utlb[entryNo].mask) |
1.73 - (addr & (~mmu_utlb[entryNo].mask))) & 0xFFFFFFE0;
1.74 - }
1.75 - } else {
1.76 - uint32_t hi = (MMIO_READ( MMU, (queue == 0 ? QACR0 : QACR1) ) & 0x1C) << 24;
1.77 - target = (addr&0x03FFFFE0) | hi;
1.78 + if( (mmu_utlb[entryNo].flags & TLB_DIRTY) == 0 ) {
1.79 + MMU_TLB_INITIAL_WRITE_ERROR(addr);
1.80 + return FALSE;
1.81 + }
1.82 +
1.83 + /* finally generate the target address */
1.84 + target = ((mmu_utlb[entryNo].ppn & mmu_utlb[entryNo].mask) |
1.85 + (addr & (~mmu_utlb[entryNo].mask))) & 0xFFFFFFE0;
1.86 }
1.87 +
1.88 mem_copy_to_sh4( target, src, 32 );
1.89 return TRUE;
1.90 }
.