* Carsten Langgaard, carstenl@mips.com
* Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved.
*/
+#include <linux/config.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/mm.h>
"nop; nop; nop; nop; nop; nop;\n\t" \
".set reorder\n\t")
-/* Atomicity and interruptability */
-#ifdef CONFIG_MIPS_MT_SMTC
-
-#include <asm/smtc.h>
-#include <asm/mipsmtregs.h>
-
-#define ENTER_CRITICAL(flags) \
- { \
- unsigned int mvpflags; \
- local_irq_save(flags);\
- mvpflags = dvpe()
-#define EXIT_CRITICAL(flags) \
- evpe(mvpflags); \
- local_irq_restore(flags); \
- }
-#else
-
-#define ENTER_CRITICAL(flags) local_irq_save(flags)
-#define EXIT_CRITICAL(flags) local_irq_restore(flags)
-
-#endif /* CONFIG_MIPS_MT_SMTC */
-
void local_flush_tlb_all(void)
{
unsigned long flags;
unsigned long old_ctx;
int entry;
- ENTER_CRITICAL(flags);
+ local_irq_save(flags);
/* Save old context and create impossible VPN2 value */
old_ctx = read_c0_entryhi();
write_c0_entrylo0(0);
}
tlbw_use_hazard();
write_c0_entryhi(old_ctx);
- EXIT_CRITICAL(flags);
+ local_irq_restore(flags);
}
/* All entries common to a mm share an asid. To effectively flush
unsigned long flags;
int size;
- ENTER_CRITICAL(flags);
size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
size = (size + 1) >> 1;
local_irq_save(flags);
} else {
drop_mmu_context(mm, cpu);
}
- EXIT_CRITICAL(flags);
+ local_irq_restore(flags);
}
}
unsigned long flags;
int size;
- ENTER_CRITICAL(flags);
size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
size = (size + 1) >> 1;
+ local_irq_save(flags);
if (size <= current_cpu_data.tlbsize / 2) {
int pid = read_c0_entryhi();
} else {
local_flush_tlb_all();
}
- EXIT_CRITICAL(flags);
+ local_irq_restore(flags);
}
void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
newpid = cpu_asid(cpu, vma->vm_mm);
page &= (PAGE_MASK << 1);
- ENTER_CRITICAL(flags);
+ local_irq_save(flags);
oldpid = read_c0_entryhi();
write_c0_entryhi(page | newpid);
mtc0_tlbw_hazard();
finish:
write_c0_entryhi(oldpid);
- EXIT_CRITICAL(flags);
+ local_irq_restore(flags);
}
}
unsigned long flags;
int oldpid, idx;
- ENTER_CRITICAL(flags);
+ local_irq_save(flags);
oldpid = read_c0_entryhi();
page &= (PAGE_MASK << 1);
write_c0_entryhi(page);
}
write_c0_entryhi(oldpid);
- EXIT_CRITICAL(flags);
+ local_irq_restore(flags);
}
/*
if (current->active_mm != vma->vm_mm)
return;
- ENTER_CRITICAL(flags);
+ local_irq_save(flags);
pid = read_c0_entryhi() & ASID_MASK;
address &= (PAGE_MASK << 1);
else
tlb_write_indexed();
tlbw_use_hazard();
- EXIT_CRITICAL(flags);
+ local_irq_restore(flags);
}
#if 0
pte_t *ptep;
int idx;
- ENTER_CRITICAL(flags);
+ local_irq_save(flags);
address &= (PAGE_MASK << 1);
asid = read_c0_entryhi() & ASID_MASK;
write_c0_entryhi(address | asid);
else
tlb_write_indexed();
tlbw_use_hazard();
- EXIT_CRITICAL(flags);
+ local_irq_restore(flags);
}
#endif
unsigned long old_pagemask;
unsigned long old_ctx;
- ENTER_CRITICAL(flags);
+ local_irq_save(flags);
/* Save old context and create impossible VPN2 value */
old_ctx = read_c0_entryhi();
old_pagemask = read_c0_pagemask();
BARRIER;
write_c0_pagemask(old_pagemask);
local_flush_tlb_all();
- EXIT_CRITICAL(flags);
+ local_irq_restore(flags);
}
/*
unsigned long old_pagemask;
unsigned long old_ctx;
- ENTER_CRITICAL(flags);
+ local_irq_save(flags);
/* Save old context and create impossible VPN2 value */
old_ctx = read_c0_entryhi();
old_pagemask = read_c0_pagemask();
write_c0_entryhi(old_ctx);
write_c0_pagemask(old_pagemask);
out:
- EXIT_CRITICAL(flags);
+ local_irq_restore(flags);
return ret;
}
*/
if ((c->processor_id & 0xff0000) == PRID_COMP_LEGACY)
return;
-#ifdef CONFIG_MIPS_MT_SMTC
- /*
- * If TLB is shared in SMTC system, total size already
- * has been calculated and written into cpu_data tlbsize
- */
- if((smtc_status & SMTC_TLB_SHARED) == SMTC_TLB_SHARED)
- return;
-#endif /* CONFIG_MIPS_MT_SMTC */
reg = read_c0_config1();
if (!((config >> 7) & 3))
c->tlbsize = ((reg >> 25) & 0x3f) + 1;
}
-static int __initdata ntlb = 0;
-static int __init set_ntlb(char *str)
-{
- get_option(&str, &ntlb);
- return 1;
-}
-
-__setup("ntlb=", set_ntlb);
-
void __init tlb_init(void)
{
unsigned int config = read_c0_config();
probe_tlb(config);
write_c0_pagemask(PM_DEFAULT_MASK);
write_c0_wired(0);
- write_c0_framemask(0);
temp_tlb_entry = current_cpu_data.tlbsize - 1;
-
- /* From this point on the ARC firmware is dead. */
local_flush_tlb_all();
- /* Did I tell you that ARC SUCKS? */
-
- if (ntlb) {
- if (ntlb > 1 && ntlb <= current_cpu_data.tlbsize) {
- int wired = current_cpu_data.tlbsize - ntlb;
- write_c0_wired(wired);
- write_c0_index(wired-1);
- printk ("Restricting TLB to %d entries\n", ntlb);
- } else
- printk("Ignoring invalid argument ntlb=%d\n", ntlb);
- }
-
build_tlb_refill_handler();
}