spin_unlock_irqrestore(&domain->lock, flags);
}
+
+static unsigned int dump_set_associative_tlb(void __iomem *sfrbase,
+ int idx_way, int idx_set)
+{
+ if (MMU_TLB_ENTRY_VALID(__raw_readl(sfrbase + REG_TLB_ATTR))) {
+ pr_crit("[%02d][%02d] VPN: %#010x, PPN: %#010x, ATTR: %#010x\n",
+ idx_way, idx_set,
+ __raw_readl(sfrbase + REG_TLB_VPN),
+ __raw_readl(sfrbase + REG_TLB_PPN),
+ __raw_readl(sfrbase + REG_TLB_ATTR));
+ return 1;
+ }
+ return 0;
+}
+
+#define MMU_NUM_TLB_SUBLINE 4
+static void dump_sysmmu_tlb(void __iomem *sfrbase)
+{
+ int i, j, k;
+ u32 capa = __raw_readl(sfrbase + REG_MMU_CAPA_V7);
+ unsigned int cnt;
+
+ pr_crit("TLB has %d way, %d set. SBB has %d entries.\n",
+ MMU_CAPA_NUM_TLB_WAY(capa),
+ (1 << MMU_CAPA_NUM_TLB_SET(capa)),
+ (1 << MMU_CAPA_NUM_SBB_ENTRY(capa)));
+ pr_crit("------------- TLB[WAY][SET][ENTRY] -------------\n");
+ for (i = 0, cnt = 0; i < MMU_CAPA_NUM_TLB_WAY(capa); i++) {
+ for (j = 0; j < (1 << MMU_CAPA_NUM_TLB_SET(capa)); j++) {
+ for (k = 0; k < MMU_NUM_TLB_SUBLINE; k++) {
+ __raw_writel(MMU_SET_TLB_READ_ENTRY(j, i, k),
+ sfrbase + REG_TLB_READ);
+ cnt += dump_set_associative_tlb(sfrbase, i, j);
+ }
+ }
+ }
+ if (!cnt)
+ pr_crit(">> No Valid TLB Entries\n");
+
+ pr_crit("--- SBB(Second-Level Page Table Base Address Buffer ---\n");
+ for (i = 0, cnt = 0; i < (1 << MMU_CAPA_NUM_SBB_ENTRY(capa)); i++) {
+ __raw_writel(i, sfrbase + REG_SBB_READ);
+ if (MMU_SBB_ENTRY_VALID(__raw_readl(sfrbase + REG_SBB_VPN))) {
+ pr_crit("[%02d] VPN: %#010x, PPN: %#010x, ATTR: %#010x\n",
+ i, __raw_readl(sfrbase + REG_SBB_VPN),
+ __raw_readl(sfrbase + REG_SBB_LINK),
+ __raw_readl(sfrbase + REG_SBB_ATTR));
+ cnt++;
+ }
+ }
+ if (!cnt)
+ pr_crit(">> No Valid SBB Entries\n");
+}
+
static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = {
"PTW ACCESS FAULT",
"PAGE FAULT",
void dump_sysmmu_status(void __iomem *sfrbase)
{
- int capa, info;
+ int info;
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
return;
}
- capa = __raw_readl(sfrbase + REG_MMU_CAPA);
info = MMU_RAW_VER(__raw_readl(sfrbase + REG_MMU_VERSION));
phys = pte_pfn(*pte) << PAGE_SHIFT;
MMU_MAJ_VER(info), MMU_MIN_VER(info), MMU_REV_VER(info),
__raw_readl(sfrbase + REG_MMU_CFG),
__raw_readl(sfrbase + REG_MMU_STATUS));
+
+ dump_sysmmu_tlb(sfrbase);
}
static void show_fault_information(struct sysmmu_drvdata *drvdata,
#define REG_PRIVATE_ID(n) (0x20C + ((n) * 0x10))
#define REG_FAULT_ADDR 0x070
#define REG_FAULT_TRANS_INFO 0x078
-
+#define REG_TLB_READ 0x1000
+#define REG_TLB_VPN 0x1004
+#define REG_TLB_PPN 0x1008
+#define REG_TLB_ATTR 0x100C
+#define REG_SBB_READ 0x1100
+#define REG_SBB_VPN 0x1104
+#define REG_SBB_LINK 0x1108
+#define REG_SBB_ATTR 0x110C
+
+#define MMU_CAPA_NUM_SBB_ENTRY(reg) ((reg >> 12) & 0xF)
#define MMU_CAPA_NUM_TLB_SET(reg) ((reg >> 8) & 0xF)
#define MMU_CAPA_NUM_TLB_WAY(reg) ((reg) & 0xFF)
+#define MMU_SET_TLB_READ_ENTRY(set, way, line) \
+ ((set) | ((way) << 8) | ((line) << 16))
+#define MMU_TLB_ENTRY_VALID(reg) ((reg) >> 28)
+#define MMU_SBB_ENTRY_VALID(reg) ((reg) >> 28)
#define MMU_FAULT_INFO_READ_REQUEST 0
#define MMU_FAULT_INFO_WRITE_REQUEST 1