331,6 → 331,26 |
} |
} |
|
/** Print TLB entry (for debugging purposes). |
* |
* The diag field has been left out in order to make this function more generic |
* (there is no diag field in US3 architeture). |
* |
* @param i TLB entry number |
* @param t TLB entry tag |
* @param d TLB entry data |
*/ |
static void print_tlb_entry(int i, tlb_tag_read_reg_t t, tlb_data_t d) |
{ |
printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, " |
"ie=%d, soft2=%#x, pfn=%#x, soft=%#x, l=%d, " |
"cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn, |
t.context, d.v, d.size, d.nfo, d.ie, d.soft2, |
d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g); |
} |
|
#if defined (US) |
|
/** Print contents of both TLBs. */ |
void tlb_print(void) |
{ |
342,12 → 362,7 |
for (i = 0; i < ITLB_ENTRY_COUNT; i++) { |
d.value = itlb_data_access_read(i); |
t.value = itlb_tag_read_read(i); |
|
printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, " |
"ie=%d, soft2=%#x, diag=%#x, pfn=%#x, soft=%#x, l=%d, " |
"cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn, |
t.context, d.v, d.size, d.nfo, d.ie, d.soft2, d.diag, |
d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g); |
print_tlb_entry(i, t, d); |
} |
|
printf("D-TLB contents:\n"); |
354,16 → 369,57 |
for (i = 0; i < DTLB_ENTRY_COUNT; i++) { |
d.value = dtlb_data_access_read(i); |
t.value = dtlb_tag_read_read(i); |
print_tlb_entry(i, t, d); |
} |
} |
|
printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, " |
"ie=%d, soft2=%#x, diag=%#x, pfn=%#x, soft=%#x, l=%d, " |
"cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn, |
t.context, d.v, d.size, d.nfo, d.ie, d.soft2, d.diag, |
d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g); |
#elif defined (US3) |
|
/** Print contents of all TLBs. */ |
void tlb_print(void) |
{ |
int i; |
tlb_data_t d; |
tlb_tag_read_reg_t t; |
|
printf("IT16 contents:\n"); |
for (i = 0; i < 16; i++) { |
d.value = dtlb_data_access_read(TLB_IT16, i); |
t.value = dtlb_tag_read_read(TLB_IT16, i); |
print_tlb_entry(i, t, d); |
} |
|
printf("IT128 contents:\n"); |
for (i = 0; i < 128; i++) { |
d.value = dtlb_data_access_read(TLB_IT128, i); |
t.value = dtlb_tag_read_read(TLB_IT128, i); |
print_tlb_entry(i, t, d); |
} |
|
printf("DT16 contents:\n"); |
for (i = 0; i < 16; i++) { |
d.value = dtlb_data_access_read(TLB_DT16, i); |
t.value = dtlb_tag_read_read(TLB_DT16, i); |
print_tlb_entry(i, t, d); |
} |
|
printf("DT512_1 contents:\n"); |
for (i = 0; i < 512; i++) { |
d.value = dtlb_data_access_read(TLB_DT512_1, i); |
t.value = dtlb_tag_read_read(TLB_DT512_1, i); |
print_tlb_entry(i, t, d); |
} |
|
printf("DT512_2 contents:\n"); |
for (i = 0; i < 512; i++) { |
d.value = dtlb_data_access_read(TLB_DT512_2, i); |
t.value = dtlb_tag_read_read(TLB_DT512_2, i); |
print_tlb_entry(i, t, d); |
} |
} |
|
#endif |
|
void do_fast_instruction_access_mmu_miss_fault(istate_t *istate, |
const char *str) |
{ |
419,12 → 475,43 |
dtlb_sfsr_write(0); |
} |
|
#if defined (US3) |
/** Invalidates given TLB entry if and only if it is non-locked or global. |
* |
* @param tlb |
* TLB number (one of TLB_DT16, TLB_DT512_1, TLB_DT512_2, |
* TLB_IT16, TLB_IT128) |
* @param entry entry index within the given TLB |
*/ |
static void tlb_invalidate_entry(int tlb, index_t entry) |
{ |
tlb_data_t d; |
tlb_tag_read_reg_t t; |
|
if (tlb == TLB_DT16 || tlb == TLB_DT512_1 || tlb == TLB_DT512_2) { |
d.value = dtlb_data_access_read(tlb, entry); |
if (!d.l || d.g) { |
t.value = dtlb_tag_read_read(tlb, entry); |
d.v = false; |
dtlb_tag_access_write(t.value); |
dtlb_data_access_write(tlb, entry, d.value); |
} |
} else if (tlb == TLB_IT16 || tlb == TLB_IT128) { |
d.value = itlb_data_access_read(tlb, entry); |
if (!d.l || d.g) { |
t.value = itlb_tag_read_read(tlb, entry); |
d.v = false; |
itlb_tag_access_write(t.value); |
itlb_data_access_write(tlb, entry, d.value); |
} |
} |
} |
#endif |
|
/** Invalidate all unlocked ITLB and DTLB entries. */ |
void tlb_invalidate_all(void) |
{ |
int i; |
tlb_data_t d; |
tlb_tag_read_reg_t t; |
|
/* |
* Walk all ITLB and DTLB entries and remove all unlocked mappings. |
435,6 → 522,10 |
* be safe to invalidate them as late as now. |
*/ |
|
#if defined (US) |
tlb_data_t d; |
tlb_tag_read_reg_t t; |
|
for (i = 0; i < ITLB_ENTRY_COUNT; i++) { |
d.value = itlb_data_access_read(i); |
if (!d.l || d.g) { |
455,6 → 546,20 |
} |
} |
|
#elif defined (US3) |
|
for (i = 0; i < 16; i++) |
tlb_invalidate_entry(TLB_IT16, i); |
for (i = 0; i < 128; i++) |
tlb_invalidate_entry(TLB_IT128, i); |
for (i = 0; i < 16; i++) |
tlb_invalidate_entry(TLB_DT16, i); |
for (i = 0; i < 512; i++) |
tlb_invalidate_entry(TLB_DT512_1, i); |
for (i = 0; i < 512; i++) |
tlb_invalidate_entry(TLB_DT512_2, i); |
#endif |
|
} |
|
/** Invalidate all ITLB and DTLB entries that belong to specified ASID |