Line 49... |
Line 49... |
/* Number of usage states (2, 3, 4 etc., max is 4). */
|
/* Number of usage states (2, 3, 4 etc., max is 4). */
|
#define DTLB_USTATES 2
|
#define DTLB_USTATES 2
|
|
|
void dtlb_info()
|
void dtlb_info()
|
{
|
{
|
if (!getsprbits(SPR_UPR, SPR_UPR_DMP)) {
|
if (!testsprbits(SPR_UPR, SPR_UPR_DMP)) {
|
printf("DMMU not implemented. Set UPR[DMP].\n");
|
printf("DMMU not implemented. Set UPR[DMP].\n");
|
return;
|
return;
|
}
|
}
|
|
|
printf("Data MMU %dKB: ", DTLB_SETS * DTLB_ENTRY_SIZE * DTLB_WAYS / 1024);
|
printf("Data MMU %dKB: ", DTLB_SETS * DTLB_ENTRY_SIZE * DTLB_WAYS / 1024);
|
Line 77... |
Line 77... |
{
|
{
|
int set;
|
int set;
|
int way;
|
int way;
|
int end_set = DTLB_SETS;
|
int end_set = DTLB_SETS;
|
|
|
if (!getsprbits(SPR_UPR, SPR_UPR_DMP)) {
|
if (!testsprbits(SPR_UPR, SPR_UPR_DMP)) {
|
printf("DMMU not implemented. Set UPR[DMP].\n");
|
printf("DMMU not implemented. Set UPR[DMP].\n");
|
return;
|
return;
|
}
|
}
|
|
|
if ((start_set >= 0) && (start_set < end_set))
|
if ((start_set >= 0) && (start_set < end_set))
|
Line 117... |
Line 117... |
int set, way = -1;
|
int set, way = -1;
|
int i;
|
int i;
|
unsigned long tagaddr;
|
unsigned long tagaddr;
|
unsigned long vpn;
|
unsigned long vpn;
|
|
|
if (!(mfspr(SPR_SR) & SPR_SR_DME) || (!getsprbits(SPR_SR, SPR_SR_DME)))
|
if (!(mfspr(SPR_SR) & SPR_SR_DME) || (!testsprbits(SPR_SR, SPR_SR_DME)))
|
return virtaddr;
|
return virtaddr;
|
|
|
/* Which set to check out? */
|
/* Which set to check out? */
|
set = (virtaddr / PAGE_SIZE) % DTLB_SETS;
|
set = (virtaddr / PAGE_SIZE) % DTLB_SETS;
|
tagaddr = (virtaddr / PAGE_SIZE) / DTLB_SETS;
|
tagaddr = (virtaddr / PAGE_SIZE) / DTLB_SETS;
|
vpn = virtaddr / PAGE_SIZE;
|
vpn = virtaddr / PAGE_SIZE;
|
|
|
/* Scan all ways and try to find a matching way. */
|
/* Scan all ways and try to find a matching way. */
|
for (i = 0; i < DTLB_WAYS; i++)
|
for (i = 0; i < DTLB_WAYS; i++)
|
if ((getsprbits(SPR_DTLBMR_BASE(i) + set, SPR_DTLBMR_VPN) == vpn) &&
|
if ((getsprbits(SPR_DTLBMR_BASE(i) + set, SPR_DTLBMR_VPN) == vpn) &&
|
getsprbits(SPR_DTLBMR_BASE(i) + set, SPR_DTLBMR_V))
|
testsprbits(SPR_DTLBMR_BASE(i) + set, SPR_DTLBMR_V))
|
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("DTLB hit (virtaddr=%x).\n", virtaddr);
|
debug("DTLB hit (virtaddr=%x).\n", virtaddr);
|
|
|
/* Set LRUs */
|
/* Set LRUs */
|
for (i = 0; i < DTLB_WAYS; i++)
|
for (i = 0; i < DTLB_WAYS; i++)
|
if (getsprbits(SPR_DTLBMR_BASE(i) + set, SPR_DTLBMR_LRU))
|
if (testsprbits(SPR_DTLBMR_BASE(i) + set, SPR_DTLBMR_LRU))
|
setsprbits(SPR_DTLBMR_BASE(i) + set, SPR_DTLBMR_LRU, getsprbits(SPR_DTLBMR_BASE(i) + set, SPR_DTLBMR_LRU) - 1);
|
setsprbits(SPR_DTLBMR_BASE(i) + set, SPR_DTLBMR_LRU, getsprbits(SPR_DTLBMR_BASE(i) + set, SPR_DTLBMR_LRU) - 1);
|
setsprbits(SPR_DTLBMR_BASE(way) + set, SPR_DTLBMR_LRU, DTLB_USTATES - 1);
|
setsprbits(SPR_DTLBMR_BASE(way) + set, SPR_DTLBMR_LRU, DTLB_USTATES - 1);
|
|
|
return getsprbits(SPR_DTLBTR_BASE(way) + set, SPR_DTLBTR_PPN) * PAGE_SIZE + (virtaddr % PAGE_SIZE);
|
return getsprbits(SPR_DTLBTR_BASE(way) + set, SPR_DTLBTR_PPN) * PAGE_SIZE + (virtaddr % PAGE_SIZE);
|
}
|
}
|