From: James S. <jsi...@us...> - 2002-02-26 17:34:25
|
Update of /cvsroot/linux-mips/linux/arch/mips64/mm In directory usw-pr-cvs1:/tmp/cvs-serv23204/arch/mips64/mm Modified Files: c-sb1.c fault.c pg-sb1.c Log Message: Most of it was a collection of fixes and cleanups for mips64 and SMP stuff Index: c-sb1.c =================================================================== RCS file: /cvsroot/linux-mips/linux/arch/mips64/mm/c-sb1.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- c-sb1.c 14 Feb 2002 20:48:25 -0000 1.3 +++ c-sb1.c 26 Feb 2002 17:34:15 -0000 1.4 @@ -56,7 +56,7 @@ { } -static void local_sb1___flush_cache_all(void) +static inline void local_sb1___flush_dcache_all(void) { /* * Haven't worried too much about speed here; given that we're flushing @@ -90,7 +90,10 @@ "sync \n" #endif ".set pop \n"); +} +static inline void local_sb1___flush_icache_all(void) +{ __asm__ __volatile__ ( ".set push \n" ".set noreorder \n" @@ -107,6 +110,12 @@ "r" (KSEG0), "i" (Index_Invalidate_I)); } +static void local_sb1___flush_cache_all(void) +{ + local_sb1___flush_dcache_all(); + local_sb1___flush_icache_all(); +} + #ifdef CONFIG_SMP extern void sb1___flush_cache_all_ipi(void *ignored); asm("sb1___flush_cache_all_ipi = local_sb1___flush_cache_all"); @@ -228,10 +237,17 @@ /* * If there's no context yet, or the page isn't executable, no icache flush * is needed + * + * This is broken. If there is no context yet we still have to writeback + * the d-cache to memory. */ -static void sb1_flush_icache_page(struct vm_area_struct *vma, struct page *page) +static void sb1_flush_icache_page(struct vm_area_struct *vma, + struct page *page) { - if ((vma->vm_mm->context == 0) || !(vma->vm_flags & VM_EXEC)) { + unsigned int cpu = smp_processor_id(); + + if (!(vma->vm_flags & VM_EXEC)) { +// printk("sb1_flush_icache_page(): not exec\n"); return; } @@ -239,7 +255,10 @@ * We're not sure of the virtual address(es) involved here, so * conservatively flush the entire caches on all processors * (ouch). + * + * Bumping the ASID may well be cheaper, need to experiment ... */ +//printk("sb1_flush_icache_page(): flushing exec page\n"); sb1___flush_cache_all(); } @@ -252,11 +271,10 @@ "1: cache %1, (%0) \n" "2: .set pop \n" " .section __ex_table,\"a\"\n" - " .word 1b, 2b \n" + " .dword 1b, 2b \n" " .previous" : - : "r" (addr), - "i" (Hit_Invalidate_I)); + : "r" (addr), "i" (Hit_Invalidate_I)); } static inline void protected_writeback_dcache_line(unsigned long addr) @@ -273,12 +291,15 @@ " .set push \n" " .set noreorder \n" " .set mips4 \n" - "1: \n" + " \n" #ifdef CONFIG_SB1_PASS_1_WORKAROUNDS - " lw $0, (%0) \n" - " sync \n" + "1: lw $0, (%0) \n" + " sync \n" + " .section __ex_table,\"a\"\n" + " .dword 1b, 3f \n" + " .previous \n" #endif - " cache %1, 0(%0) \n" /* Hit-WB{-inval} this address */ + "2: cache %1, 0(%0) \n" /* Hit-WB{-inval} this address */ /* XXX: should be able to do this after both dcache cache ops, but there's no guarantee that this will be inlined, and the pass1 restriction checker can't detect syncs @@ -288,9 +309,9 @@ #ifdef CONFIG_SB1_PASS_1_WORKAROUNDS /* Bug 1384 */ " sync \n" #endif - "2: .set pop \n" + "3: .set pop \n" " .section __ex_table,\"a\"\n" - " .word 1b, 2b \n" + " .dword 2b, 3b \n" " .previous" : : "r" (addr), @@ -305,15 +326,10 @@ #endif } -/* - * XXX - Still need to really understand this. This is mostly just - * derived from the r10k and r4k implementations, and seems to work - * but things that "seem to work" when I don't understand *why* they - * "seem to work" disturb me greatly...JDC - */ static void local_sb1_flush_cache_sigtramp(unsigned long addr) { unsigned long daddr, iaddr; + daddr = addr & ~(dcache_line_size - 1); protected_writeback_dcache_line(daddr); Index: fault.c =================================================================== RCS file: /cvsroot/linux-mips/linux/arch/mips64/mm/fault.c,v retrieving revision 1.10 retrieving revision 1.11 diff -u -d -r1.10 -r1.11 --- fault.c 19 Feb 2002 17:51:29 -0000 1.10 +++ fault.c 26 Feb 2002 17:34:15 -0000 1.11 @@ -196,6 +196,7 @@ address, (unsigned long) regs->cp0_epc, (unsigned long) regs->regs[31]); +while(1); #endif info.si_signo = SIGSEGV; info.si_errno = 0; Index: pg-sb1.c =================================================================== RCS file: /cvsroot/linux-mips/linux/arch/mips64/mm/pg-sb1.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- pg-sb1.c 28 Jan 2002 20:31:57 -0000 1.1 +++ pg-sb1.c 26 Feb 2002 17:34:15 -0000 1.2 @@ -34,13 +34,15 @@ /* These are the functions hooked by the memory management function pointers */ void sb1_clear_page(void *page) { - /* JDCXXX - This should be bottlenecked by the write buffer, but these - things tend to be mildly unpredictable...should check this on the - performance model */ - - /* We prefetch 4 lines ahead. We're also "cheating" slightly here... - since we know we're on an SB1, we force the assembler to take - 64-bit operands to speed things up */ + /* + * JDCXXX - This should be bottlenecked by the write buffer, but these + * things tend to be mildly unpredictable...should check this on the + * performance model + * + * We prefetch 4 lines ahead. We're also "cheating" slightly here... + * since we know we're on an SB1, we force the assembler to take + * 64-bit operands to speed things up + */ __asm__ __volatile__( ".set push \n" ".set noreorder \n" @@ -57,24 +59,22 @@ " sd $0, 24(%0) \n" " pref " SB1_PREF_STORE_STREAMED_HINT ",128(%0) \n" /* Prefetch 4 lines ahead */ " bne $1, %0, 1b \n" - " daddiu %0, %0, 32 \n" /* Next cacheline (This instruction better be short piped!) */ + " daddiu %0, %0, 32\n" /* Next cacheline (This instruction better be short piped!) */ ".set pop \n" - :"=r" (page) - :"0" (page), - "I" (PAGE_SIZE-32) - :"$1","memory"); + : "=r" (page) + : "0" (page), "I" (PAGE_SIZE-32) + : "memory"); } void sb1_copy_page(void *to, void *from) { - - /* This should be optimized in assembly...can't use ld/sd, though, + /* + * This should be optimized in assembly...can't use ld/sd, though, * because the top 32 bits could be nuked if we took an interrupt * during the routine. And this is not a good place to be cli()'ing - */ - - /* The pref's used here are using "streaming" hints, which cause the + * + * The pref's used here are using "streaming" hints, which cause the * copied data to be kicked out of the cache sooner. A page copy often * ends up copying a lot more data than is commonly used, so this seems * to make sense in terms of reducing cache pollution, but I've no real @@ -117,19 +117,7 @@ " bne $1, %0, 1b \n" " daddiu %0, %0, 32 \n" /* Next cacheline */ ".set pop \n" - :"=r" (to), - "=r" (from) - : - "0" (from), - "1" (to), - "I" (PAGE_SIZE-32) - :"$1","$2","$3","$4","$5","$6","$7","$8","$9","memory"); -/* - unsigned long *src = from; - unsigned long *dest = to; - unsigned long *target = (unsigned long *) (((unsigned long)src) + PAGE_SIZE); - while (src != target) { - *dest++ = *src++; - } -*/ + : "=r" (to), "=r" (from) + : "0" (from), "1" (to), "I" (PAGE_SIZE-32) + : "$2","$3","$4","$5","$6","$7","$8","$9","memory"); } |