Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 375200
b: refs/heads/master
c: d532f3d
h: refs/heads/master
v: v3
  • Loading branch information
Steven J. Hill authored and Ralf Baechle committed May 8, 2013
1 parent f8b31db commit 165b9ba
Show file tree
Hide file tree
Showing 11 changed files with 138 additions and 62 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: 49bffbdc88fdd8f5eac40306a617252625a0fa35
refs/heads/master: d532f3d26716a39dfd4b88d687bd344fbe77e390
95 changes: 59 additions & 36 deletions trunk/arch/mips/include/asm/mmu_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,53 +62,76 @@ extern unsigned long pgd_current[];
TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
#endif
#endif /* CONFIG_MIPS_PGD_C0_CONTEXT*/
#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)

#define ASID_INC 0x40
#define ASID_MASK 0xfc0

#elif defined(CONFIG_CPU_R8000)

#define ASID_INC 0x10
#define ASID_MASK 0xff0

#elif defined(CONFIG_MIPS_MT_SMTC)

#define ASID_INC 0x1
extern unsigned long smtc_asid_mask;
#define ASID_MASK (smtc_asid_mask)
#define HW_ASID_MASK 0xff
/* End SMTC/34K debug hack */
#else /* FIXME: not correct for R6000 */

#define ASID_INC 0x1
#define ASID_MASK 0xff
#define ASID_INC(asid) \
({ \
unsigned long __asid = asid; \
__asm__("1:\taddiu\t%0,1\t\t\t\t# patched\n\t" \
".section\t__asid_inc,\"a\"\n\t" \
".word\t1b\n\t" \
".previous" \
:"=r" (__asid) \
:"0" (__asid)); \
__asid; \
})
#define ASID_MASK(asid) \
({ \
unsigned long __asid = asid; \
__asm__("1:\tandi\t%0,%1,0xfc0\t\t\t# patched\n\t" \
".section\t__asid_mask,\"a\"\n\t" \
".word\t1b\n\t" \
".previous" \
:"=r" (__asid) \
:"r" (__asid)); \
__asid; \
})
#define ASID_VERSION_MASK \
({ \
unsigned long __asid; \
__asm__("1:\taddiu\t%0,$0,0xff00\t\t\t\t# patched\n\t" \
".section\t__asid_version_mask,\"a\"\n\t" \
".word\t1b\n\t" \
".previous" \
:"=r" (__asid)); \
__asid; \
})
#define ASID_FIRST_VERSION \
({ \
unsigned long __asid = asid; \
__asm__("1:\tli\t%0,0x100\t\t\t\t# patched\n\t" \
".section\t__asid_first_version,\"a\"\n\t" \
".word\t1b\n\t" \
".previous" \
:"=r" (__asid)); \
__asid; \
})

#define ASID_FIRST_VERSION_R3000 0x1000
#define ASID_FIRST_VERSION_R4000 0x100
#define ASID_FIRST_VERSION_R8000 0x1000
#define ASID_FIRST_VERSION_RM9000 0x1000

#ifdef CONFIG_MIPS_MT_SMTC
#define SMTC_HW_ASID_MASK 0xff
extern unsigned int smtc_asid_mask;
#endif

#define cpu_context(cpu, mm) ((mm)->context.asid[cpu])
#define cpu_asid(cpu, mm) (cpu_context((cpu), (mm)) & ASID_MASK)
#define cpu_asid(cpu, mm) ASID_MASK(cpu_context((cpu), (mm)))
#define asid_cache(cpu) (cpu_data[cpu].asid_cache)

static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
{
}

/*
* All unused by hardware upper bits will be considered
* as a software asid extension.
*/
#define ASID_VERSION_MASK ((unsigned long)~(ASID_MASK|(ASID_MASK-1)))
#define ASID_FIRST_VERSION ((unsigned long)(~ASID_VERSION_MASK) + 1)

#ifndef CONFIG_MIPS_MT_SMTC
/* Normal, classic MIPS get_new_mmu_context */
static inline void
get_new_mmu_context(struct mm_struct *mm, unsigned long cpu)
{
unsigned long asid = asid_cache(cpu);

if (! ((asid += ASID_INC) & ASID_MASK) ) {
if (!ASID_MASK((asid = ASID_INC(asid)))) {
if (cpu_has_vtag_icache)
flush_icache_all();
local_flush_tlb_all(); /* start new asid cycle */
Expand Down Expand Up @@ -166,7 +189,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
* free up the ASID value for use and flush any old
* instances of it from the TLB.
*/
oldasid = (read_c0_entryhi() & ASID_MASK);
oldasid = ASID_MASK(read_c0_entryhi());
if(smtc_live_asid[mytlb][oldasid]) {
smtc_live_asid[mytlb][oldasid] &= ~(0x1 << cpu);
if(smtc_live_asid[mytlb][oldasid] == 0)
Expand All @@ -177,7 +200,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
* having ASID_MASK smaller than the hardware maximum,
* make sure no "soft" bits become "hard"...
*/
write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) |
write_c0_entryhi((read_c0_entryhi() & ~SMTC_HW_ASID_MASK) |
cpu_asid(cpu, next));
ehb(); /* Make sure it propagates to TCStatus */
evpe(mtflags);
Expand Down Expand Up @@ -230,15 +253,15 @@ activate_mm(struct mm_struct *prev, struct mm_struct *next)
#ifdef CONFIG_MIPS_MT_SMTC
/* See comments for similar code above */
mtflags = dvpe();
oldasid = read_c0_entryhi() & ASID_MASK;
oldasid = ASID_MASK(read_c0_entryhi());
if(smtc_live_asid[mytlb][oldasid]) {
smtc_live_asid[mytlb][oldasid] &= ~(0x1 << cpu);
if(smtc_live_asid[mytlb][oldasid] == 0)
smtc_flush_tlb_asid(oldasid);
}
/* See comments for similar code above */
write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) |
cpu_asid(cpu, next));
write_c0_entryhi((read_c0_entryhi() & ~SMTC_HW_ASID_MASK) |
cpu_asid(cpu, next));
ehb(); /* Make sure it propagates to TCStatus */
evpe(mtflags);
#else
Expand Down Expand Up @@ -275,14 +298,14 @@ drop_mmu_context(struct mm_struct *mm, unsigned cpu)
#ifdef CONFIG_MIPS_MT_SMTC
/* See comments for similar code above */
prevvpe = dvpe();
oldasid = (read_c0_entryhi() & ASID_MASK);
oldasid = ASID_MASK(read_c0_entryhi());
if (smtc_live_asid[mytlb][oldasid]) {
smtc_live_asid[mytlb][oldasid] &= ~(0x1 << cpu);
if(smtc_live_asid[mytlb][oldasid] == 0)
smtc_flush_tlb_asid(oldasid);
}
/* See comments for similar code above */
write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK)
write_c0_entryhi((read_c0_entryhi() & ~SMTC_HW_ASID_MASK)
| cpu_asid(cpu, mm));
ehb(); /* Make sure it propagates to TCStatus */
evpe(prevvpe);
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/mips/kernel/genex.S
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ NESTED(nmi_handler, PT_SIZE, sp)
.set noreorder
/* check if TLB contains a entry for EPC */
MFC0 k1, CP0_ENTRYHI
andi k1, 0xff /* ASID_MASK */
andi k1, 0xff /* ASID_MASK patched at run-time!! */
MFC0 k0, CP0_EPC
PTR_SRL k0, _PAGE_SHIFT + 1
PTR_SLL k0, _PAGE_SHIFT + 1
Expand Down
10 changes: 5 additions & 5 deletions trunk/arch/mips/kernel/smtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ static int vpe0limit;
static int ipibuffers;
static int nostlb;
static int asidmask;
unsigned long smtc_asid_mask = 0xff;
unsigned int smtc_asid_mask = 0xff;

static int __init vpe0tcs(char *str)
{
Expand Down Expand Up @@ -1395,7 +1395,7 @@ void smtc_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu)
asid = asid_cache(cpu);

do {
if (!((asid += ASID_INC) & ASID_MASK) ) {
if (!ASID_MASK(ASID_INC(asid))) {
if (cpu_has_vtag_icache)
flush_icache_all();
/* Traverse all online CPUs (hack requires contiguous range) */
Expand All @@ -1414,7 +1414,7 @@ void smtc_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu)
mips_ihb();
}
tcstat = read_tc_c0_tcstatus();
smtc_live_asid[tlb][(tcstat & ASID_MASK)] |= (asiduse)(0x1 << i);
smtc_live_asid[tlb][ASID_MASK(tcstat)] |= (asiduse)(0x1 << i);
if (!prevhalt)
write_tc_c0_tchalt(0);
}
Expand All @@ -1423,7 +1423,7 @@ void smtc_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu)
asid = ASID_FIRST_VERSION;
local_flush_tlb_all(); /* start new asid cycle */
}
} while (smtc_live_asid[tlb][(asid & ASID_MASK)]);
} while (smtc_live_asid[tlb][ASID_MASK(asid)]);

/*
* SMTC shares the TLB within VPEs and possibly across all VPEs.
Expand Down Expand Up @@ -1461,7 +1461,7 @@ void smtc_flush_tlb_asid(unsigned long asid)
tlb_read();
ehb();
ehi = read_c0_entryhi();
if ((ehi & ASID_MASK) == asid) {
if (ASID_MASK(ehi) == asid) {
/*
* Invalidate only entries with specified ASID,
* makiing sure all entries differ.
Expand Down
6 changes: 4 additions & 2 deletions trunk/arch/mips/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -1547,6 +1547,7 @@ void __cpuinit per_cpu_trap_init(bool is_boot_cpu)
unsigned int cpu = smp_processor_id();
unsigned int status_set = ST0_CU0;
unsigned int hwrena = cpu_hwrena_impl_bits;
unsigned long asid = 0;
#ifdef CONFIG_MIPS_MT_SMTC
int secondaryTC = 0;
int bootTC = (cpu == 0);
Expand Down Expand Up @@ -1630,8 +1631,9 @@ void __cpuinit per_cpu_trap_init(bool is_boot_cpu)
}
#endif /* CONFIG_MIPS_MT_SMTC */

if (!cpu_data[cpu].asid_cache)
cpu_data[cpu].asid_cache = ASID_FIRST_VERSION;
asid = ASID_FIRST_VERSION;
cpu_data[cpu].asid_cache = asid;
TLBMISS_HANDLER_SETUP();

atomic_inc(&init_mm.mm_count);
current->active_mm = &init_mm;
Expand Down
5 changes: 3 additions & 2 deletions trunk/arch/mips/lib/dump_tlb.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/tlbdebug.h>
#include <asm/mmu_context.h>

static inline const char *msk2str(unsigned int mask)
{
Expand Down Expand Up @@ -55,7 +56,7 @@ static void dump_tlb(int first, int last)
s_pagemask = read_c0_pagemask();
s_entryhi = read_c0_entryhi();
s_index = read_c0_index();
asid = s_entryhi & 0xff;
asid = ASID_MASK(s_entryhi);

for (i = first; i <= last; i++) {
write_c0_index(i);
Expand Down Expand Up @@ -85,7 +86,7 @@ static void dump_tlb(int first, int last)

printk("va=%0*lx asid=%02lx\n",
width, (entryhi & ~0x1fffUL),
entryhi & 0xff);
ASID_MASK(entryhi));
printk("\t[pa=%0*llx c=%d d=%d v=%d g=%d] ",
width,
(entrylo0 << 6) & PAGE_MASK, c0,
Expand Down
7 changes: 4 additions & 3 deletions trunk/arch/mips/lib/r3k_dump_tlb.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <linux/mm.h>

#include <asm/mipsregs.h>
#include <asm/mmu_context.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/tlbdebug.h>
Expand All @@ -21,7 +22,7 @@ static void dump_tlb(int first, int last)
unsigned int asid;
unsigned long entryhi, entrylo0;

asid = read_c0_entryhi() & 0xfc0;
asid = ASID_MASK(read_c0_entryhi());

for (i = first; i <= last; i++) {
write_c0_index(i<<8);
Expand All @@ -35,7 +36,7 @@ static void dump_tlb(int first, int last)

/* Unused entries have a virtual address of KSEG0. */
if ((entryhi & 0xffffe000) != 0x80000000
&& (entryhi & 0xfc0) == asid) {
&& (ASID_MASK(entryhi) == asid)) {
/*
* Only print entries in use
*/
Expand All @@ -44,7 +45,7 @@ static void dump_tlb(int first, int last)
printk("va=%08lx asid=%08lx"
" [pa=%06lx n=%d d=%d v=%d g=%d]",
(entryhi & 0xffffe000),
entryhi & 0xfc0,
ASID_MASK(entryhi),
entrylo0 & PAGE_MASK,
(entrylo0 & (1 << 11)) ? 1 : 0,
(entrylo0 & (1 << 10)) ? 1 : 0,
Expand Down
20 changes: 10 additions & 10 deletions trunk/arch/mips/mm/tlb-r3k.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ void local_flush_tlb_all(void)
#endif

local_irq_save(flags);
old_ctx = read_c0_entryhi() & ASID_MASK;
old_ctx = ASID_MASK(read_c0_entryhi());
write_c0_entrylo0(0);
entry = r3k_have_wired_reg ? read_c0_wired() : 8;
for (; entry < current_cpu_data.tlbsize; entry++) {
Expand Down Expand Up @@ -87,13 +87,13 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,

#ifdef DEBUG_TLB
printk("[tlbrange<%lu,0x%08lx,0x%08lx>]",
cpu_context(cpu, mm) & ASID_MASK, start, end);
ASID_MASK(cpu_context(cpu, mm)), start, end);
#endif
local_irq_save(flags);
size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
if (size <= current_cpu_data.tlbsize) {
int oldpid = read_c0_entryhi() & ASID_MASK;
int newpid = cpu_context(cpu, mm) & ASID_MASK;
int oldpid = ASID_MASK(read_c0_entryhi());
int newpid = ASID_MASK(cpu_context(cpu, mm));

start &= PAGE_MASK;
end += PAGE_SIZE - 1;
Expand Down Expand Up @@ -166,10 +166,10 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
#ifdef DEBUG_TLB
printk("[tlbpage<%lu,0x%08lx>]", cpu_context(cpu, vma->vm_mm), page);
#endif
newpid = cpu_context(cpu, vma->vm_mm) & ASID_MASK;
newpid = ASID_MASK(cpu_context(cpu, vma->vm_mm));
page &= PAGE_MASK;
local_irq_save(flags);
oldpid = read_c0_entryhi() & ASID_MASK;
oldpid = ASID_MASK(read_c0_entryhi());
write_c0_entryhi(page | newpid);
BARRIER;
tlb_probe();
Expand Down Expand Up @@ -197,10 +197,10 @@ void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
if (current->active_mm != vma->vm_mm)
return;

pid = read_c0_entryhi() & ASID_MASK;
pid = ASID_MASK(read_c0_entryhi());

#ifdef DEBUG_TLB
if ((pid != (cpu_context(cpu, vma->vm_mm) & ASID_MASK)) || (cpu_context(cpu, vma->vm_mm) == 0)) {
if ((pid != ASID_MASK(cpu_context(cpu, vma->vm_mm))) || (cpu_context(cpu, vma->vm_mm) == 0)) {
printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%lu tlbpid=%d\n",
(cpu_context(cpu, vma->vm_mm)), pid);
}
Expand Down Expand Up @@ -241,7 +241,7 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,

local_irq_save(flags);
/* Save old context and create impossible VPN2 value */
old_ctx = read_c0_entryhi() & ASID_MASK;
old_ctx = ASID_MASK(read_c0_entryhi());
old_pagemask = read_c0_pagemask();
w = read_c0_wired();
write_c0_wired(w + 1);
Expand All @@ -264,7 +264,7 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
#endif

local_irq_save(flags);
old_ctx = read_c0_entryhi() & ASID_MASK;
old_ctx = ASID_MASK(read_c0_entryhi());
write_c0_entrylo0(entrylo0);
write_c0_entryhi(entryhi);
write_c0_index(wired);
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/mips/mm/tlb-r4k.c
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)

ENTER_CRITICAL(flags);

pid = read_c0_entryhi() & ASID_MASK;
pid = ASID_MASK(read_c0_entryhi());
address &= (PAGE_MASK << 1);
write_c0_entryhi(address | pid);
pgdp = pgd_offset(vma->vm_mm, address);
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/mips/mm/tlb-r8k.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
if (current->active_mm != vma->vm_mm)
return;

pid = read_c0_entryhi() & ASID_MASK;
pid = ASID_MASK(read_c0_entryhi());

local_irq_save(flags);
address &= PAGE_MASK;
Expand Down
Loading

0 comments on commit 165b9ba

Please sign in to comment.