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 ITLB_USTATES 2
|
#define ITLB_USTATES 2
|
|
|
void itlb_info()
|
void itlb_info()
|
{
|
{
|
if (!getsprbits(SPR_UPR, SPR_UPR_IMP)) {
|
if (!testsprbits(SPR_UPR, SPR_UPR_IMP)) {
|
printf("IMMU not implemented. Set UPR[IMP].\n");
|
printf("IMMU not implemented. Set UPR[IMP].\n");
|
return;
|
return;
|
}
|
}
|
|
|
printf("Insn MMU %dKB: ", ITLB_SETS * ITLB_ENTRY_SIZE * ITLB_WAYS / 1024);
|
printf("Insn MMU %dKB: ", ITLB_SETS * ITLB_ENTRY_SIZE * ITLB_WAYS / 1024);
|
Line 77... |
Line 77... |
{
|
{
|
int set;
|
int set;
|
int way;
|
int way;
|
int end_set = ITLB_SETS;
|
int end_set = ITLB_SETS;
|
|
|
if (!getsprbits(SPR_UPR, SPR_UPR_IMP)) {
|
if (!testsprbits(SPR_UPR, SPR_UPR_IMP)) {
|
printf("IMMU not implemented. Set UPR[IMP].\n");
|
printf("IMMU not implemented. Set UPR[IMP].\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_IME) || !(getsprbits(SPR_UPR, SPR_UPR_IMP)))
|
if (!(mfspr(SPR_SR) & SPR_SR_IME) || !(testsprbits(SPR_UPR, SPR_UPR_IMP)))
|
return virtaddr;
|
return virtaddr;
|
|
|
/* Which set to check out? */
|
/* Which set to check out? */
|
set = (virtaddr / PAGE_SIZE) % ITLB_SETS;
|
set = (virtaddr / PAGE_SIZE) % ITLB_SETS;
|
tagaddr = (virtaddr / PAGE_SIZE) / ITLB_SETS;
|
tagaddr = (virtaddr / PAGE_SIZE) / ITLB_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 < ITLB_WAYS; i++)
|
for (i = 0; i < ITLB_WAYS; i++)
|
if ((getsprbits(SPR_ITLBMR_BASE(i) + set, SPR_ITLBMR_VPN) == vpn) &&
|
if ((getsprbits(SPR_ITLBMR_BASE(i) + set, SPR_ITLBMR_VPN) == vpn) &&
|
getsprbits(SPR_ITLBMR_BASE(i) + set, SPR_ITLBMR_V))
|
testsprbits(SPR_ITLBMR_BASE(i) + set, SPR_ITLBMR_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. */
|
immu_stats.fetch_tlbhit++;
|
immu_stats.fetch_tlbhit++;
|
debug("ITLB hit (virtaddr=%x).\n", virtaddr);
|
debug("ITLB hit (virtaddr=%x).\n", virtaddr);
|
|
|
/* Set LRUs */
|
/* Set LRUs */
|
for (i = 0; i < ITLB_WAYS; i++)
|
for (i = 0; i < ITLB_WAYS; i++)
|
if (getsprbits(SPR_ITLBMR_BASE(i) + set, SPR_ITLBMR_LRU))
|
if (testsprbits(SPR_ITLBMR_BASE(i) + set, SPR_ITLBMR_LRU))
|
setsprbits(SPR_ITLBMR_BASE(i) + set, SPR_ITLBMR_LRU, getsprbits(SPR_ITLBMR_BASE(i) + set, SPR_ITLBMR_LRU) - 1);
|
setsprbits(SPR_ITLBMR_BASE(i) + set, SPR_ITLBMR_LRU, getsprbits(SPR_ITLBMR_BASE(i) + set, SPR_ITLBMR_LRU) - 1);
|
setsprbits(SPR_ITLBMR_BASE(way) + set, SPR_ITLBMR_LRU, ITLB_USTATES - 1);
|
setsprbits(SPR_ITLBMR_BASE(way) + set, SPR_ITLBMR_LRU, ITLB_USTATES - 1);
|
|
|
return getsprbits(SPR_ITLBTR_BASE(way) + set, SPR_ITLBTR_PPN) * PAGE_SIZE + (virtaddr % PAGE_SIZE);
|
return getsprbits(SPR_ITLBTR_BASE(way) + set, SPR_ITLBTR_PPN) * PAGE_SIZE + (virtaddr % PAGE_SIZE);
|
}
|
}
|
Line 157... |
Line 157... |
if (getsprbits(SPR_ITLBMR_BASE(i) + set, SPR_ITLBMR_LRU) < minlru)
|
if (getsprbits(SPR_ITLBMR_BASE(i) + set, SPR_ITLBMR_LRU) < minlru)
|
minway = i;
|
minway = i;
|
|
|
setsprbits(SPR_ITLBMR_BASE(minway) + set, SPR_ITLBMR_VPN, vpn);
|
setsprbits(SPR_ITLBMR_BASE(minway) + set, SPR_ITLBMR_VPN, vpn);
|
for (i = 0; i < ITLB_WAYS; i++)
|
for (i = 0; i < ITLB_WAYS; i++)
|
if (getsprbits(SPR_ITLBMR_BASE(i) + set, SPR_ITLBMR_LRU))
|
if (testsprbits(SPR_ITLBMR_BASE(i) + set, SPR_ITLBMR_LRU))
|
setsprbits(SPR_ITLBMR_BASE(i) + set, SPR_ITLBMR_LRU, getsprbits(SPR_ITLBMR_BASE(i) + set, SPR_ITLBMR_LRU) - 1);
|
setsprbits(SPR_ITLBMR_BASE(i) + set, SPR_ITLBMR_LRU, getsprbits(SPR_ITLBMR_BASE(i) + set, SPR_ITLBMR_LRU) - 1);
|
setsprbits(SPR_ITLBMR_BASE(minway) + set, SPR_ITLBMR_LRU, ITLB_USTATES - 1);
|
setsprbits(SPR_ITLBMR_BASE(minway) + set, SPR_ITLBMR_LRU, ITLB_USTATES - 1);
|
setsprbits(SPR_ITLBTR_BASE(minway) + set, SPR_ITLBTR_PPN, vpn); /* 1 to 1 */
|
setsprbits(SPR_ITLBTR_BASE(minway) + set, SPR_ITLBTR_PPN, vpn); /* 1 to 1 */
|
setsprbits(SPR_ITLBMR_BASE(minway) + set, SPR_ITLBMR_V, 1);
|
setsprbits(SPR_ITLBMR_BASE(minway) + set, SPR_ITLBMR_V, 1);
|
#endif
|
#endif
|