Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 3439 → Rev 3440

/branches/sparc/kernel/arch/sparc64/src/mm/tlb.c
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);
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);
}
}
 
#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,22 → 475,57
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.
*
* The kernel doesn't use global mappings so any locked global mappings
* found must have been created by someone else. Their only purpose now
* found must have been created by someone else. Their only purpose now
* is to collide with proper mappings. Invalidate immediately. It should
* 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) {
444,7 → 535,7
itlb_data_access_write(i, d.value);
}
}
 
for (i = 0; i < DTLB_ENTRY_COUNT; i++) {
d.value = dtlb_data_access_read(i);
if (!d.l || d.g) {
454,7 → 545,21
dtlb_data_access_write(i, d.value);
}
}
 
#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
513,4 → 618,4
}
 
/** @}
*/
*/