patch-2.4.22 linux-2.4.22/arch/mips64/mm/tlb-r4k.c
Next file: linux-2.4.22/arch/mips64/mm/tlb-sb1.c
Previous file: linux-2.4.22/arch/mips64/mm/tlb-glue-sb1.S
Back to the patch index
Back to the overall index
- Lines: 441
- Date:
2003-08-25 04:44:40.000000000 -0700
- Orig file:
linux-2.4.21/arch/mips64/mm/tlb-r4k.c
- Orig date:
2002-11-28 15:53:10.000000000 -0800
diff -urN linux-2.4.21/arch/mips64/mm/tlb-r4k.c linux-2.4.22/arch/mips64/mm/tlb-r4k.c
@@ -33,7 +33,7 @@
#undef DEBUG_TLB
#undef DEBUG_TLBUPDATE
-extern char except_vec1_r4k;
+extern void except_vec1_r4k(void);
/* CP0 hazard avoidance. */
#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
@@ -50,66 +50,62 @@
printk("[tlball]");
#endif
- __save_and_cli(flags);
+ local_irq_save(flags);
/* Save old context and create impossible VPN2 value */
- old_ctx = (get_entryhi() & 0xff);
- set_entryhi(KSEG0);
- set_entrylo0(0);
- set_entrylo1(0);
+ old_ctx = (read_c0_entryhi() & ASID_MASK);
+ write_c0_entryhi(XKPHYS);
+ write_c0_entrylo0(0);
+ write_c0_entrylo1(0);
BARRIER;
- entry = get_wired();
+ entry = read_c0_wired();
/* Blast 'em all away. */
- while(entry < mips_cpu.tlbsize) {
+ while(entry < current_cpu_data.tlbsize) {
/* Make sure all entries differ. */
- set_entryhi(KSEG0+entry*0x2000);
- set_index(entry);
+ write_c0_entryhi(XKPHYS+entry*0x2000);
+ write_c0_index(entry);
BARRIER;
tlb_write_indexed();
BARRIER;
entry++;
}
BARRIER;
- set_entryhi(old_ctx);
- __restore_flags(flags);
+ write_c0_entryhi(old_ctx);
+ local_irq_restore(flags);
}
void local_flush_tlb_mm(struct mm_struct *mm)
{
- if (CPU_CONTEXT(smp_processor_id(), mm) != 0) {
- unsigned long flags;
+ int cpu = smp_processor_id();
+ if (cpu_context(cpu, mm) != 0) {
#ifdef DEBUG_TLB
printk("[tlbmm<%d>]", mm->context);
#endif
- __save_and_cli(flags);
- get_new_mmu_context(mm, smp_processor_id());
- if (mm == current->active_mm)
- set_entryhi(CPU_CONTEXT(smp_processor_id(), mm) &
- 0xff);
- __restore_flags(flags);
+ drop_mmu_context(mm,cpu);
}
}
void local_flush_tlb_range(struct mm_struct *mm, unsigned long start,
unsigned long end)
{
- if (CPU_CONTEXT(smp_processor_id(), mm) != 0) {
+ int cpu = smp_processor_id();
+
+ if (cpu_context(cpu, mm) != 0) {
unsigned long flags;
int size;
#ifdef DEBUG_TLB
- printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff),
+ printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & ASID_MASK),
start, end);
#endif
- __save_and_cli(flags);
+ local_irq_save(flags);
size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
size = (size + 1) >> 1;
- if(size <= mips_cpu.tlbsize/2) {
- int oldpid = (get_entryhi() & 0xff);
- int newpid = (CPU_CONTEXT(smp_processor_id(), mm) &
- 0xff);
+ if(size <= current_cpu_data.tlbsize/2) {
+ int oldpid = read_c0_entryhi() & ASID_MASK;
+ int newpid = cpu_asid(cpu, mm);
start &= (PAGE_MASK << 1);
end += ((PAGE_SIZE << 1) - 1);
@@ -117,71 +113,69 @@
while(start < end) {
int idx;
- set_entryhi(start | newpid);
+ write_c0_entryhi(start | newpid);
start += (PAGE_SIZE << 1);
BARRIER;
tlb_probe();
BARRIER;
- idx = get_index();
- set_entrylo0(0);
- set_entrylo1(0);
+ idx = read_c0_index();
+ write_c0_entrylo0(0);
+ write_c0_entrylo1(0);
if(idx < 0)
continue;
/* Make sure all entries differ. */
- set_entryhi(KSEG0+idx*0x2000);
+ write_c0_entryhi(XKPHYS+idx*0x2000);
BARRIER;
tlb_write_indexed();
BARRIER;
}
- set_entryhi(oldpid);
+ write_c0_entryhi(oldpid);
} else {
- get_new_mmu_context(mm, smp_processor_id());
- if (mm == current->active_mm)
- set_entryhi(CPU_CONTEXT(smp_processor_id(),
- mm) & 0xff);
+ drop_mmu_context(mm, cpu);
}
- __restore_flags(flags);
+ local_irq_restore(flags);
}
}
void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
{
- if (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) != 0) {
+ int cpu = smp_processor_id();
+
+ if (cpu_context(cpu, vma->vm_mm) != 0) {
unsigned long flags;
unsigned long oldpid, newpid, idx;
#ifdef DEBUG_TLB
printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page);
#endif
- newpid = (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) & 0xff);
+ newpid = cpu_asid(cpu, vma->vm_mm);
page &= (PAGE_MASK << 1);
- __save_and_cli(flags);
- oldpid = (get_entryhi() & 0xff);
- set_entryhi(page | newpid);
+ local_irq_save(flags);
+ oldpid = (read_c0_entryhi() & ASID_MASK);
+ write_c0_entryhi(page | newpid);
BARRIER;
tlb_probe();
BARRIER;
- idx = get_index();
- set_entrylo0(0);
- set_entrylo1(0);
+ idx = read_c0_index();
+ write_c0_entrylo0(0);
+ write_c0_entrylo1(0);
if(idx < 0)
goto finish;
/* Make sure all entries differ. */
- set_entryhi(KSEG0+idx*0x2000);
+ write_c0_entryhi(XKPHYS+idx*0x2000);
BARRIER;
tlb_write_indexed();
finish:
BARRIER;
- set_entryhi(oldpid);
- __restore_flags(flags);
+ write_c0_entryhi(oldpid);
+ local_irq_restore(flags);
}
}
/*
* Updates the TLB with the new pte(s).
*/
-void mips64_update_mmu_cache(struct vm_area_struct * vma,
- unsigned long address, pte_t pte)
+void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
{
unsigned long flags;
pgd_t *pgdp;
@@ -195,31 +189,31 @@
if (current->active_mm != vma->vm_mm)
return;
- pid = get_entryhi() & 0xff;
+ pid = read_c0_entryhi() & ASID_MASK;
#ifdef DEBUG_TLB
- if((pid != (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) & 0xff)) ||
- (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) == 0)) {
- printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d
- tlbpid=%d\n", (int) (CPU_CONTEXT(smp_processor_id(),
- vma->vm_mm) & 0xff), pid);
+ if ((pid != (cpu_asid(smp_processor_id(), vma->vm_mm))) ||
+ (cpu_context(smp_processor_id(), vma->vm_mm) == 0)) {
+ printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d"
+ "tlbpid=%d\n", (int) (cpu_context(smp_processor_id(),
+ vma->vm_mm) & ASID_MASK), pid);
}
#endif
- __save_and_cli(flags);
+ local_irq_save(flags);
address &= (PAGE_MASK << 1);
- set_entryhi(address | (pid));
+ write_c0_entryhi(address | (pid));
pgdp = pgd_offset(vma->vm_mm, address);
BARRIER;
tlb_probe();
BARRIER;
pmdp = pmd_offset(pgdp, address);
- idx = get_index();
+ idx = read_c0_index();
ptep = pte_offset(pmdp, address);
BARRIER;
- set_entrylo0(pte_val(*ptep++) >> 6);
- set_entrylo1(pte_val(*ptep) >> 6);
- set_entryhi(address | (pid));
+ write_c0_entrylo0(pte_val(*ptep++) >> 6);
+ write_c0_entrylo1(pte_val(*ptep) >> 6);
+ write_c0_entryhi(address | (pid));
BARRIER;
if(idx < 0) {
tlb_write_random();
@@ -227,70 +221,9 @@
tlb_write_indexed();
}
BARRIER;
- set_entryhi(pid);
- BARRIER;
- __restore_flags(flags);
-}
-
-void dump_mm_page(unsigned long addr)
-{
- pgd_t *page_dir, *pgd;
- pmd_t *pmd;
- pte_t *pte, page;
- unsigned long val;
-
- page_dir = pgd_offset(current->mm, 0);
- pgd = pgd_offset(current->mm, addr);
- pmd = pmd_offset(pgd, addr);
- pte = pte_offset(pmd, addr);
- page = *pte;
- printk("Memory Mapping: VA = %08x, PA = %08x ", addr, (unsigned int) pte_val(page));
- val = pte_val(page);
- if (val & _PAGE_PRESENT) printk("present ");
- if (val & _PAGE_READ) printk("read ");
- if (val & _PAGE_WRITE) printk("write ");
- if (val & _PAGE_ACCESSED) printk("accessed ");
- if (val & _PAGE_MODIFIED) printk("modified ");
- if (val & _PAGE_R4KBUG) printk("r4kbug ");
- if (val & _PAGE_GLOBAL) printk("global ");
- if (val & _PAGE_VALID) printk("valid ");
- printk("\n");
-}
-
-void show_tlb(void)
-{
- unsigned int flags;
- unsigned int old_ctx;
- unsigned int entry;
- unsigned int entrylo0, entrylo1, entryhi;
-
- __save_and_cli(flags);
-
- /* Save old context */
- old_ctx = (get_entryhi() & 0xff);
-
- printk("TLB content:\n");
- entry = 0;
- while(entry < mips_cpu.tlbsize) {
- set_index(entry);
- BARRIER;
- tlb_read();
- BARRIER;
- entryhi = get_entryhi();
- entrylo0 = get_entrylo0();
- entrylo1 = get_entrylo1();
- printk("%02d: ASID=%02d%s VA=0x%08x ", entry, entryhi & ASID_MASK, (entrylo0 & entrylo1 & 1) ? "(G)" : " ", entryhi & ~ASID_MASK);
- printk("PA0=0x%08x C0=%x %s%s%s\n", (entrylo0>>6)<<12, (entrylo0>>3) & 7, (entrylo0 & 4) ? "Dirty " : "", (entrylo0 & 2) ? "Valid " : "Invalid ", (entrylo0 & 1) ? "Global" : "");
- printk("\t\t\t PA1=0x%08x C1=%x %s%s%s\n", (entrylo1>>6)<<12, (entrylo1>>3) & 7, (entrylo1 & 4) ? "Dirty " : "", (entrylo1 & 2) ? "Valid " : "Invalid ", (entrylo1 & 1) ? "Global" : "");
-
- dump_mm_page(entryhi & ~0xff);
- dump_mm_page((entryhi & ~0xff) | 0x1000);
- entry++;
- }
+ write_c0_entryhi(pid);
BARRIER;
- set_entryhi(old_ctx);
-
- __restore_flags(flags);
+ local_irq_restore(flags);
}
void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
@@ -301,27 +234,27 @@
unsigned long old_pagemask;
unsigned long old_ctx;
- __save_and_cli(flags);
+ local_irq_save(flags);
/* Save old context and create impossible VPN2 value */
- old_ctx = (get_entryhi() & 0xff);
- old_pagemask = get_pagemask();
- wired = get_wired();
- set_wired (wired + 1);
- set_index (wired);
+ old_ctx = (read_c0_entryhi() & ASID_MASK);
+ old_pagemask = read_c0_pagemask();
+ wired = read_c0_wired();
+ write_c0_wired(wired + 1);
+ write_c0_index(wired);
BARRIER;
- set_pagemask (pagemask);
- set_entryhi(entryhi);
- set_entrylo0(entrylo0);
- set_entrylo1(entrylo1);
+ write_c0_pagemask(pagemask);
+ write_c0_entryhi(entryhi);
+ write_c0_entrylo0(entrylo0);
+ write_c0_entrylo1(entrylo1);
BARRIER;
tlb_write_indexed();
BARRIER;
- set_entryhi(old_ctx);
+ write_c0_entryhi(old_ctx);
BARRIER;
- set_pagemask (old_pagemask);
+ write_c0_pagemask(old_pagemask);
local_flush_tlb_all();
- __restore_flags(flags);
+ local_irq_restore(flags);
}
/*
@@ -341,67 +274,66 @@
unsigned long old_pagemask;
unsigned long old_ctx;
- __save_and_cli(flags);
+ local_irq_save(flags);
/* Save old context and create impossible VPN2 value */
- old_ctx = get_entryhi() & 0xff;
- old_pagemask = get_pagemask();
- wired = get_wired();
+ old_ctx = read_c0_entryhi() & ASID_MASK;
+ old_pagemask = read_c0_pagemask();
+ wired = read_c0_wired();
if (--temp_tlb_entry < wired) {
printk(KERN_WARNING "No TLB space left for add_temporary_entry\n");
ret = -ENOSPC;
goto out;
}
- set_index(temp_tlb_entry);
+ write_c0_index(temp_tlb_entry);
BARRIER;
- set_pagemask(pagemask);
- set_entryhi(entryhi);
- set_entrylo0(entrylo0);
- set_entrylo1(entrylo1);
+ write_c0_pagemask(pagemask);
+ write_c0_entryhi(entryhi);
+ write_c0_entrylo0(entrylo0);
+ write_c0_entrylo1(entrylo1);
BARRIER;
tlb_write_indexed();
BARRIER;
- set_entryhi(old_ctx);
+ write_c0_entryhi(old_ctx);
BARRIER;
- set_pagemask(old_pagemask);
+ write_c0_pagemask(old_pagemask);
out:
- __restore_flags(flags);
+ local_irq_restore(flags);
return ret;
}
static void __init probe_tlb(unsigned long config)
{
- unsigned long config1;
-
if (!(config & (1 << 31))) {
/*
* Not a MIPS64 complainant CPU.
* Config 1 register not supported, we assume R4k style.
*/
- mips_cpu.tlbsize = 48;
+ current_cpu_data.tlbsize = 48;
} else {
- config1 = read_mips32_cp0_config1();
+ unsigned long config1;
+
+ config1 = read_c0_config1();
if (!((config >> 7) & 3))
panic("No MMU present");
else
- mips_cpu.tlbsize = ((config1 >> 25) & 0x3f) + 1;
+ current_cpu_data.tlbsize = ((config1 >> 25) & 0x3f) + 1;
}
- printk("Number of TLB entries %d.\n", mips_cpu.tlbsize);
+ printk("Number of TLB entries %d.\n", current_cpu_data.tlbsize);
}
void __init r4k_tlb_init(void)
{
- unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
+ unsigned long config = read_c0_config();
probe_tlb(config);
- _update_mmu_cache = mips64_update_mmu_cache;
- set_pagemask(PM_4K);
- write_32bit_cp0_register(CP0_WIRED, 0);
- temp_tlb_entry = mips_cpu.tlbsize - 1;
+ write_c0_pagemask(PM_4K);
+ write_c0_wired(0);
+ temp_tlb_entry = current_cpu_data.tlbsize - 1;
local_flush_tlb_all();
- memcpy((void *)(KSEG0 + 0x80), &except_vec1_r4k, 0x80);
+ memcpy((void *)(KSEG0 + 0x80), except_vec1_r4k, 0x80);
flush_icache_range(KSEG0, KSEG0 + 0x80);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)