Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 231865
b: refs/heads/master
c: cc33ae4
h: refs/heads/master
i:
  231863: 93cadde
v: v3
  • Loading branch information
David Daney authored and Ralf Baechle committed Jan 18, 2011
1 parent 935a7dd commit 8871606
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 30 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: afc7c9864a2d1b0c398425aac84b8a095c8dfa7c
refs/heads/master: cc33ae437975416a1b78f99e2715e91ab643526a
119 changes: 90 additions & 29 deletions trunk/arch/mips/mm/tlbex.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,18 @@ static inline int __maybe_unused r10000_llsc_war(void)
return R10000_LLSC_WAR;
}

static int use_bbit_insns(void)
{
switch (current_cpu_type()) {
case CPU_CAVIUM_OCTEON:
case CPU_CAVIUM_OCTEON_PLUS:
case CPU_CAVIUM_OCTEON2:
return 1;
default:
return 0;
}
}

/*
* Found by experiment: At least some revisions of the 4kc throw under
* some circumstances a machine check exception, triggered by invalid
Expand Down Expand Up @@ -511,8 +523,12 @@ build_is_huge_pte(u32 **p, struct uasm_reloc **r, unsigned int tmp,
unsigned int pmd, int lid)
{
UASM_i_LW(p, tmp, 0, pmd);
uasm_i_andi(p, tmp, tmp, _PAGE_HUGE);
uasm_il_bnez(p, r, tmp, lid);
if (use_bbit_insns()) {
uasm_il_bbit1(p, r, tmp, ilog2(_PAGE_HUGE), lid);
} else {
uasm_i_andi(p, tmp, tmp, _PAGE_HUGE);
uasm_il_bnez(p, r, tmp, lid);
}
}

static __cpuinit void build_huge_update_entries(u32 **p,
Expand Down Expand Up @@ -1187,14 +1203,20 @@ build_pte_present(u32 **p, struct uasm_reloc **r,
unsigned int pte, unsigned int ptr, enum label_id lid)
{
if (kernel_uses_smartmips_rixi) {
uasm_i_andi(p, pte, pte, _PAGE_PRESENT);
uasm_il_beqz(p, r, pte, lid);
if (use_bbit_insns()) {
uasm_il_bbit0(p, r, pte, ilog2(_PAGE_PRESENT), lid);
uasm_i_nop(p);
} else {
uasm_i_andi(p, pte, pte, _PAGE_PRESENT);
uasm_il_beqz(p, r, pte, lid);
iPTE_LW(p, pte, ptr);
}
} else {
uasm_i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
uasm_i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
uasm_il_bnez(p, r, pte, lid);
iPTE_LW(p, pte, ptr);
}
iPTE_LW(p, pte, ptr);
}

/* Make PTE valid, store result in PTR. */
Expand All @@ -1215,10 +1237,17 @@ static void __cpuinit
build_pte_writable(u32 **p, struct uasm_reloc **r,
unsigned int pte, unsigned int ptr, enum label_id lid)
{
uasm_i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
uasm_i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
uasm_il_bnez(p, r, pte, lid);
iPTE_LW(p, pte, ptr);
if (use_bbit_insns()) {
uasm_il_bbit0(p, r, pte, ilog2(_PAGE_PRESENT), lid);
uasm_i_nop(p);
uasm_il_bbit0(p, r, pte, ilog2(_PAGE_WRITE), lid);
uasm_i_nop(p);
} else {
uasm_i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
uasm_i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
uasm_il_bnez(p, r, pte, lid);
iPTE_LW(p, pte, ptr);
}
}

/* Make PTE writable, update software status bits as well, then store
Expand All @@ -1242,9 +1271,14 @@ static void __cpuinit
build_pte_modifiable(u32 **p, struct uasm_reloc **r,
unsigned int pte, unsigned int ptr, enum label_id lid)
{
uasm_i_andi(p, pte, pte, _PAGE_WRITE);
uasm_il_beqz(p, r, pte, lid);
iPTE_LW(p, pte, ptr);
if (use_bbit_insns()) {
uasm_il_bbit0(p, r, pte, ilog2(_PAGE_WRITE), lid);
uasm_i_nop(p);
} else {
uasm_i_andi(p, pte, pte, _PAGE_WRITE);
uasm_il_beqz(p, r, pte, lid);
iPTE_LW(p, pte, ptr);
}
}

#ifndef CONFIG_MIPS_PGD_C0_CONTEXT
Expand Down Expand Up @@ -1491,27 +1525,42 @@ static void __cpuinit build_r4000_tlb_load_handler(void)
* If the page is not _PAGE_VALID, RI or XI could not
* have triggered it. Skip the expensive test..
*/
uasm_i_andi(&p, K0, K0, _PAGE_VALID);
uasm_il_beqz(&p, &r, K0, label_tlbl_goaround1);
if (use_bbit_insns()) {
uasm_il_bbit0(&p, &r, K0, ilog2(_PAGE_VALID),
label_tlbl_goaround1);
} else {
uasm_i_andi(&p, K0, K0, _PAGE_VALID);
uasm_il_beqz(&p, &r, K0, label_tlbl_goaround1);
}
uasm_i_nop(&p);

uasm_i_tlbr(&p);
/* Examine entrylo 0 or 1 based on ptr. */
uasm_i_andi(&p, K0, K1, sizeof(pte_t));
uasm_i_beqz(&p, K0, 8);
if (use_bbit_insns()) {
uasm_i_bbit0(&p, K1, ilog2(sizeof(pte_t)), 8);
} else {
uasm_i_andi(&p, K0, K1, sizeof(pte_t));
uasm_i_beqz(&p, K0, 8);
}

UASM_i_MFC0(&p, K0, C0_ENTRYLO0); /* load it in the delay slot*/
UASM_i_MFC0(&p, K0, C0_ENTRYLO1); /* load it if ptr is odd */
/*
* If the entryLo (now in K0) is valid (bit 1), RI or
* XI must have triggered it.
*/
uasm_i_andi(&p, K0, K0, 2);
uasm_il_bnez(&p, &r, K0, label_nopage_tlbl);

uasm_l_tlbl_goaround1(&l, p);
/* Reload the PTE value */
iPTE_LW(&p, K0, K1);
if (use_bbit_insns()) {
uasm_il_bbit1(&p, &r, K0, 1, label_nopage_tlbl);
/* Reload the PTE value */
iPTE_LW(&p, K0, K1);
uasm_l_tlbl_goaround1(&l, p);
} else {
uasm_i_andi(&p, K0, K0, 2);
uasm_il_bnez(&p, &r, K0, label_nopage_tlbl);
uasm_l_tlbl_goaround1(&l, p);
/* Reload the PTE value */
iPTE_LW(&p, K0, K1);
}
}
build_make_valid(&p, &r, K0, K1);
build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
Expand All @@ -1531,23 +1580,35 @@ static void __cpuinit build_r4000_tlb_load_handler(void)
* If the page is not _PAGE_VALID, RI or XI could not
* have triggered it. Skip the expensive test..
*/
uasm_i_andi(&p, K0, K0, _PAGE_VALID);
uasm_il_beqz(&p, &r, K0, label_tlbl_goaround2);
if (use_bbit_insns()) {
uasm_il_bbit0(&p, &r, K0, ilog2(_PAGE_VALID),
label_tlbl_goaround2);
} else {
uasm_i_andi(&p, K0, K0, _PAGE_VALID);
uasm_il_beqz(&p, &r, K0, label_tlbl_goaround2);
}
uasm_i_nop(&p);

uasm_i_tlbr(&p);
/* Examine entrylo 0 or 1 based on ptr. */
uasm_i_andi(&p, K0, K1, sizeof(pte_t));
uasm_i_beqz(&p, K0, 8);

if (use_bbit_insns()) {
uasm_i_bbit0(&p, K1, ilog2(sizeof(pte_t)), 8);
} else {
uasm_i_andi(&p, K0, K1, sizeof(pte_t));
uasm_i_beqz(&p, K0, 8);
}
UASM_i_MFC0(&p, K0, C0_ENTRYLO0); /* load it in the delay slot*/
UASM_i_MFC0(&p, K0, C0_ENTRYLO1); /* load it if ptr is odd */
/*
* If the entryLo (now in K0) is valid (bit 1), RI or
* XI must have triggered it.
*/
uasm_i_andi(&p, K0, K0, 2);
uasm_il_beqz(&p, &r, K0, label_tlbl_goaround2);
if (use_bbit_insns()) {
uasm_il_bbit0(&p, &r, K0, 1, label_tlbl_goaround2);
} else {
uasm_i_andi(&p, K0, K0, 2);
uasm_il_beqz(&p, &r, K0, label_tlbl_goaround2);
}
/* Reload the PTE value */
iPTE_LW(&p, K0, K1);

Expand Down

0 comments on commit 8871606

Please sign in to comment.