HelenOS sources
This source file includes following definitions.
- tlb_refill
- tlb_arch_init
- tlb_invalidate_all
- tlb_invalidate_asid
- tlb_invalidate_pages
- tlb_print
#include <arch/mm/tlb.h>
#include <interrupt.h>
#include <typedefs.h>
void tlb_refill(unsigned int n, istate_t *istate)
{
uint32_t tlbmiss;
ptehi_t ptehi;
ptelo_t ptelo;
asm volatile (
"mfspr %[tlbmiss], 980\n"
"mfspr %[ptehi], 981\n"
"mfspr %[ptelo], 982\n"
: [tlbmiss] "=r" (tlbmiss),
[ptehi] "=r" (ptehi),
[ptelo] "=r" (ptelo)
);
uint32_t badvaddr = tlbmiss & 0xfffffffc;
uint32_t physmem = physmem_top();
if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem)))
return;
ptelo.rpn = KA2PA(badvaddr) >> 12;
ptelo.wimg = 0;
ptelo.pp = 2;
uint32_t index = 0;
asm volatile (
"mtspr 981, %[ptehi]\n"
"mtspr 982, %[ptelo]\n"
"tlbld %[index]\n"
"tlbli %[index]\n"
: [index] "=r" (index)
: [ptehi] "r" (ptehi),
[ptelo] "r" (ptelo)
);
}
void tlb_arch_init(void)
{
tlb_invalidate_all();
}
void tlb_invalidate_all(void)
{
asm volatile (
"sync\n"
);
for (unsigned int i = 0; i < 0x00040000; i += 0x00001000) {
asm volatile (
"tlbie %[i]\n"
:: [i] "r" (i)
);
}
asm volatile (
"eieio\n"
"tlbsync\n"
"sync\n"
);
}
void tlb_invalidate_asid(asid_t asid)
{
tlb_invalidate_all();
}
void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt)
{
tlb_invalidate_all();
}
#define PRINT_BAT(name, ureg, lreg) \
asm volatile ( \
"mfspr %[upper], " #ureg "\n" \
"mfspr %[lower], " #lreg "\n" \
: [upper] "=r" (upper), \
[lower] "=r" (lower) \
); \
\
mask = (upper & 0x1ffc) >> 2; \
if (upper & 3) { \
uint32_t tmp = mask; \
length = 128; \
\
while (tmp) { \
if ((tmp & 1) == 0) { \
printf("ibat[0]: error in mask\n"); \
break; \
} \
length <<= 1; \
tmp >>= 1; \
} \
} else \
length = 0; \
\
printf(name ": page=%#0" PRIx32 " frame=%#0" PRIx32 \
" length=%#0" PRIx32 " KB (mask=%#0" PRIx32 ")%s%s\n", \
upper & UINT32_C(0xffff0000), lower & UINT32_C(0xffff0000), \
length, mask, \
((upper >> 1) & 1) ? " supervisor" : "", \
(upper & 1) ? " user" : "");
void tlb_print(void)
{
uint32_t sr;
for (sr = 0; sr < 16; sr++) {
uint32_t vsid = sr_get(sr << 28);
printf("sr[%02" PRIu32 "]: vsid=%#0" PRIx32 " (asid=%" PRIu32 ")"
"%s%s\n", sr, vsid & UINT32_C(0x00ffffff),
(vsid & UINT32_C(0x00ffffff)) >> 4,
((vsid >> 30) & 1) ? " supervisor" : "",
((vsid >> 29) & 1) ? " user" : "");
}
uint32_t upper;
uint32_t lower;
uint32_t mask;
uint32_t length;
PRINT_BAT("ibat[0]", 528, 529);
PRINT_BAT("ibat[1]", 530, 531);
PRINT_BAT("ibat[2]", 532, 533);
PRINT_BAT("ibat[3]", 534, 535);
PRINT_BAT("dbat[0]", 536, 537);
PRINT_BAT("dbat[1]", 538, 539);
PRINT_BAT("dbat[2]", 540, 541);
PRINT_BAT("dbat[3]", 542, 543);
}
HelenOS homepage, sources at GitHub