summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorKanoj Sarcar <kanoj@engr.sgi.com>2000-04-23 19:50:48 +0000
committerKanoj Sarcar <kanoj@engr.sgi.com>2000-04-23 19:50:48 +0000
commit2bba74b71906107e5bce42b542b862f90cf048b3 (patch)
tree9d21eec33efcbabb5666ac9fc4daa6fcc396089f /arch
parentb9e55bb180a44f990e201c771c103469f6fb08ca (diff)
scall_64.S: Move to kernel mode and enable intrs properly.
r4k_tlb_glue.S: The fast handlers must work with intrs disabled, since we can not risk changes in entryhi/lo/tlbregisters. do_page_fault() _must_ work with intrs enabled, to prevent deadlocks in the intercpu tlbflush code. andes.c/r4xx0.c: Make tlb register accesses conservatively safe from intrs coming in and changing register contents.
Diffstat (limited to 'arch')
-rw-r--r--arch/mips64/kernel/r4k_tlb_glue.S22
-rw-r--r--arch/mips64/kernel/scall_64.S1
-rw-r--r--arch/mips64/mm/andes.c14
-rw-r--r--arch/mips64/mm/r4xx0.c16
-rw-r--r--arch/mips64/sgi-ip27/TODO6
5 files changed, 36 insertions, 23 deletions
diff --git a/arch/mips64/kernel/r4k_tlb_glue.S b/arch/mips64/kernel/r4k_tlb_glue.S
index 81d457fda..87b97d30d 100644
--- a/arch/mips64/kernel/r4k_tlb_glue.S
+++ b/arch/mips64/kernel/r4k_tlb_glue.S
@@ -23,10 +23,18 @@ NESTED(__tlb_refill_debug_tramp, PT_SIZE, sp)
END(__tlb_refill_debug_tramp)
__FINIT
- .macro tlb_handler name
+ .macro __BUILD_cli
+ CLI
+ .endm
+
+ .macro __BUILD_sti
+ STI
+ .endm
+
+ .macro tlb_handler name interruptible
NESTED(__\name, PT_SIZE, sp)
SAVE_ALL
- CLI
+ __BUILD_\interruptible
dmfc0 t0, CP0_BADVADDR
sd t0, PT_BVADDR(sp)
move a0, sp
@@ -35,8 +43,8 @@ NESTED(__tlb_refill_debug_tramp, PT_SIZE, sp)
END(__\name)
.endm
- tlb_handler tlb_refill_debug
- tlb_handler xtlb_refill_debug
- tlb_handler xtlb_mod_debug
- tlb_handler xtlb_tlbl_debug
- tlb_handler xtlb_tlbs_debug
+ tlb_handler tlb_refill_debug cli
+ tlb_handler xtlb_refill_debug cli
+ tlb_handler xtlb_mod_debug sti
+ tlb_handler xtlb_tlbl_debug sti
+ tlb_handler xtlb_tlbs_debug sti
diff --git a/arch/mips64/kernel/scall_64.S b/arch/mips64/kernel/scall_64.S
index 07b8ff7c0..6a7a59551 100644
--- a/arch/mips64/kernel/scall_64.S
+++ b/arch/mips64/kernel/scall_64.S
@@ -32,6 +32,7 @@ NESTED(handle_sys64, PT_SIZE, sp)
#ifndef CONFIG_MIPS32_COMPAT
.set noat
SAVE_SOME
+ STI
.set at
#endif
ld t1, PT_EPC(sp) # skip syscall on return
diff --git a/arch/mips64/mm/andes.c b/arch/mips64/mm/andes.c
index 91244d64c..aad9bbb23 100644
--- a/arch/mips64/mm/andes.c
+++ b/arch/mips64/mm/andes.c
@@ -250,11 +250,11 @@ static void andes_flush_tlb_mm(struct mm_struct *mm)
#ifdef DEBUG_TLB
printk("[tlbmm<%d>]", mm->context);
#endif
- save_and_cli(flags);
+ __save_and_cli(flags);
get_new_mmu_context(mm);
if(mm == current->mm)
set_entryhi(CPU_CONTEXT(smp_processor_id(), mm) & 0xff);
- restore_flags(flags);
+ __restore_flags(flags);
}
}
@@ -270,7 +270,7 @@ andes_flush_tlb_range(struct mm_struct *mm, unsigned long start,
printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff),
start, end);
#endif
- save_and_cli(flags);
+ __save_and_cli(flags);
size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
size = (size + 1) >> 1;
if(size <= NTLB_ENTRIES_HALF) {
@@ -305,7 +305,7 @@ andes_flush_tlb_range(struct mm_struct *mm, unsigned long start,
set_entryhi(CPU_CONTEXT(smp_processor_id(), mm) &
0xff);
}
- restore_flags(flags);
+ __restore_flags(flags);
}
}
@@ -321,7 +321,7 @@ andes_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
#endif
newpid = (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) & 0xff);
page &= (PAGE_MASK << 1);
- save_and_cli(flags);
+ __save_and_cli(flags);
oldpid = (get_entryhi() & 0xff);
set_entryhi(page | newpid);
BARRIER;
@@ -339,7 +339,7 @@ andes_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
finish:
BARRIER;
set_entryhi(oldpid);
- restore_flags(flags);
+ __restore_flags(flags);
}
}
@@ -355,6 +355,7 @@ static void andes_update_mmu_cache(struct vm_area_struct * vma,
pte_t *ptep;
int idx, pid;
+ __save_and_cli(flags);
pid = get_entryhi() & 0xff;
if((pid != (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) & 0xff)) ||
@@ -364,7 +365,6 @@ static void andes_update_mmu_cache(struct vm_area_struct * vma,
vma->vm_mm) & 0xff), pid);
}
- __save_and_cli(flags);
address &= (PAGE_MASK << 1);
set_entryhi(address | (pid));
pgdp = pgd_offset(vma->vm_mm, address);
diff --git a/arch/mips64/mm/r4xx0.c b/arch/mips64/mm/r4xx0.c
index 059774231..d2bd99982 100644
--- a/arch/mips64/mm/r4xx0.c
+++ b/arch/mips64/mm/r4xx0.c
@@ -2024,7 +2024,7 @@ static inline void r4k_flush_tlb_all(void)
printk("[tlball]");
#endif
- save_and_cli(flags);
+ __save_and_cli(flags);
/* Save old context and create impossible VPN2 value */
old_ctx = (get_entryhi() & 0xff);
set_entryhi(KSEG0);
@@ -2044,7 +2044,7 @@ static inline void r4k_flush_tlb_all(void)
}
BARRIER;
set_entryhi(old_ctx);
- restore_flags(flags);
+ __restore_flags(flags);
}
static void r4k_flush_tlb_mm(struct mm_struct *mm)
@@ -2055,11 +2055,11 @@ static void r4k_flush_tlb_mm(struct mm_struct *mm)
#ifdef DEBUG_TLB
printk("[tlbmm<%d>]", mm->context);
#endif
- save_and_cli(flags);
+ __save_and_cli(flags);
get_new_mmu_context(mm);
if(mm == current->mm)
set_entryhi(CPU_CONTEXT(smp_processor_id(), mm) & 0xff);
- restore_flags(flags);
+ __restore_flags(flags);
}
}
@@ -2074,7 +2074,7 @@ static void r4k_flush_tlb_range(struct mm_struct *mm, unsigned long start,
printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff),
start, end);
#endif
- save_and_cli(flags);
+ __save_and_cli(flags);
size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
size = (size + 1) >> 1;
if(size <= NTLB_ENTRIES_HALF) {
@@ -2124,7 +2124,7 @@ static void r4k_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
#endif
newpid = (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) & 0xff);
page &= (PAGE_MASK << 1);
- save_and_cli(flags);
+ __save_and_cli(flags);
oldpid = (get_entryhi() & 0xff);
set_entryhi(page | newpid);
BARRIER;
@@ -2142,7 +2142,7 @@ static void r4k_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
finish:
BARRIER;
set_entryhi(oldpid);
- restore_flags(flags);
+ __restore_flags(flags);
}
}
@@ -2165,6 +2165,7 @@ static void r4k_update_mmu_cache(struct vm_area_struct * vma,
pte_t *ptep;
int idx, pid;
+ __save_and_cli(flags);
pid = (get_entryhi() & 0xff);
#ifdef DEBUG_TLB
@@ -2176,7 +2177,6 @@ static void r4k_update_mmu_cache(struct vm_area_struct * vma,
}
#endif
- __save_and_cli(flags);
address &= (PAGE_MASK << 1);
set_entryhi(address | (pid));
pgdp = pgd_offset(vma->vm_mm, address);
diff --git a/arch/mips64/sgi-ip27/TODO b/arch/mips64/sgi-ip27/TODO
index 7fc35a844..78451283f 100644
--- a/arch/mips64/sgi-ip27/TODO
+++ b/arch/mips64/sgi-ip27/TODO
@@ -9,7 +9,10 @@ ip27-init.c:find_lbaord_real. DONE
in irix?
6. Investigate why things do not work without the setup_test() call
being invoked on all nodes in ip27-memory.c.
-7. Too many CLIs in the locore handlers.
+7. Too many CLIs in the locore handlers :
+For the low level handlers set up by set_except_vector(),
+__tlb_refill_debug_tramp, __xtlb_refill_debug_tramp and cacheerror,
+investigate whether the code should do CLI, STI or KMODE.
8. Too many do_page_faults invoked - investigate.
9. start_thread must turn off UX64 ... and define tlb_refill_debug.
10. Need a bad pmd table, bad pte table. __bad_pmd_table/__bad_pagetable
@@ -17,3 +20,4 @@ does not agree with pgd_bad/pmd_bad.
11. All intrs (ip27_do_irq handlers) are targetted at cpu A on the node.
This might need to change later. Only the timer intr is set up to be
received on both Cpu A and B. (ip27_do_irq()/bridge_startup())
+13. Cache flushing (specially the SMP version) has to be investigated.