Line 34... |
Line 34... |
#include "sprs.h"
|
#include "sprs.h"
|
#include "except.h"
|
#include "except.h"
|
#include "sim-config.h"
|
#include "sim-config.h"
|
#include "debug.h"
|
#include "debug.h"
|
|
|
|
DEFAULT_DEBUG_CHANNEL(dmmu);
|
|
|
extern int cont_run;
|
extern int cont_run;
|
|
|
/* Data MMU */
|
/* Data MMU */
|
|
|
inline oraddr_t dmmu_simulate_tlb(oraddr_t virtaddr, int write_access)
|
inline oraddr_t dmmu_simulate_tlb(oraddr_t virtaddr, int write_access)
|
Line 64... |
Line 66... |
way = i;
|
way = i;
|
|
|
/* Did we find our tlb entry? */
|
/* Did we find our tlb entry? */
|
if (way >= 0) { /* Yes, we did. */
|
if (way >= 0) { /* Yes, we did. */
|
dmmu_stats.loads_tlbhit++;
|
dmmu_stats.loads_tlbhit++;
|
debug(5, "DTLB hit (virtaddr=%"PRIxADDR").\n", virtaddr);
|
TRACE("DTLB hit (virtaddr=%"PRIxADDR") at %lli.\n", virtaddr,
|
|
runtime.sim.cycles);
|
|
|
/* Test for page fault */
|
/* Test for page fault */
|
if (mfspr (SPR_SR) & SPR_SR_SM) {
|
if (mfspr (SPR_SR) & SPR_SR_SM) {
|
if ( write_access && !(mfspr (SPR_DTLBTR_BASE(way) + set) & SPR_DTLBTR_SWE)
|
if ( write_access && !(mfspr (SPR_DTLBTR_BASE(way) + set) & SPR_DTLBTR_SWE)
|
|| !write_access && !(mfspr (SPR_DTLBTR_BASE(way) + set) & SPR_DTLBTR_SRE))
|
|| !write_access && !(mfspr (SPR_DTLBTR_BASE(way) + set) & SPR_DTLBTR_SRE))
|
Line 106... |
Line 109... |
setsprbits(SPR_DTLBMR_BASE(minway) + set, SPR_DTLBMR_LRU, config.dmmu.ustates - 1);
|
setsprbits(SPR_DTLBMR_BASE(minway) + set, SPR_DTLBMR_LRU, config.dmmu.ustates - 1);
|
setsprbits(SPR_DTLBTR_BASE(minway) + set, SPR_DTLBTR_PPN, vpn); /* 1 to 1 */
|
setsprbits(SPR_DTLBTR_BASE(minway) + set, SPR_DTLBTR_PPN, vpn); /* 1 to 1 */
|
setsprbits(SPR_DTLBMR_BASE(minway) + set, SPR_DTLBMR_V, 1);
|
setsprbits(SPR_DTLBMR_BASE(minway) + set, SPR_DTLBMR_V, 1);
|
#endif
|
#endif
|
except_handle(EXCEPT_DTLBMISS, virtaddr);
|
except_handle(EXCEPT_DTLBMISS, virtaddr);
|
|
TRACE("DTLB miss (virtaddr=%"PRIxADDR") at %lli.\n", virtaddr,
|
|
runtime.sim.cycles);
|
/* if tlb refill implemented in HW */
|
/* if tlb refill implemented in HW */
|
/* return getsprbits(SPR_DTLBTR_BASE(minway) + set, SPR_DTLBTR_PPN) * config.dmmu.pagesize + (virtaddr % config.dmmu.pagesize); */
|
/* return getsprbits(SPR_DTLBTR_BASE(minway) + set, SPR_DTLBTR_PPN) * config.dmmu.pagesize + (virtaddr % config.dmmu.pagesize); */
|
runtime.sim.mem_cycles += config.dmmu.missdelay;
|
runtime.sim.mem_cycles += config.dmmu.missdelay;
|
return 0;
|
return 0;
|
}
|
}
|
Line 157... |
Line 162... |
way = i;
|
way = i;
|
|
|
/* Did we find our tlb entry? */
|
/* Did we find our tlb entry? */
|
if (way >= 0) { /* Yes, we did. */
|
if (way >= 0) { /* Yes, we did. */
|
dmmu_stats.loads_tlbhit++;
|
dmmu_stats.loads_tlbhit++;
|
debug(5, "DTLB hit (virtaddr=%"PRIxADDR").\n", virtaddr);
|
TRACE("DTLB hit (virtaddr=%"PRIxADDR") at %lli.\n", virtaddr,
|
|
runtime.sim.cycles);
|
|
|
/* Test for page fault */
|
/* Test for page fault */
|
if (mfspr (SPR_SR) & SPR_SR_SM) {
|
if (mfspr (SPR_SR) & SPR_SR_SM) {
|
if ( write_access && !(mfspr (SPR_DTLBTR_BASE(way) + set) & SPR_DTLBTR_SWE)
|
if ( write_access && !(mfspr (SPR_DTLBTR_BASE(way) + set) & SPR_DTLBTR_SWE)
|
|| !write_access && !(mfspr (SPR_DTLBTR_BASE(way) + set) & SPR_DTLBTR_SRE))
|
|| !write_access && !(mfspr (SPR_DTLBTR_BASE(way) + set) & SPR_DTLBTR_SRE))
|
Line 186... |
Line 192... |
}
|
}
|
else { /* No, we didn't. */
|
else { /* No, we didn't. */
|
return(0);
|
return(0);
|
}
|
}
|
|
|
PRINTF("ERR, should never have happened\n");
|
ERR("ERR, should never have happened\n");
|
return(0);
|
return(0);
|
}
|
}
|
|
|
|
|
oraddr_t dmmu_translate(oraddr_t virtaddr, int write_access)
|
oraddr_t dmmu_translate(oraddr_t virtaddr, int write_access)
|