[parisc-linux-cvs] linux rhirst

Richard Hirst rhirst@linuxcare.com
Wed, 29 May 2002 16:03:49 +0100


On Wed, May 29, 2002 at 09:11:36AM -0600, Richard Hirst wrote:
> Log message:
> Implement flush_icache_{page,range}, which makes gdb stepping work.
> Remove flushing hack from module loading code, not needed now.
> Add flushing to free initmem debug code, patch from Grant.



Index: Makefile
===================================================================
RCS file: /var/cvs/linux/Makefile,v
retrieving revision 1.300
diff -u -r1.300 Makefile
--- Makefile	2002/05/28 14:28:28	1.300
+++ Makefile	2002/05/29 15:06:06
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 18
-EXTRAVERSION = -pa29
+EXTRAVERSION = -pa30
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
Index: arch/parisc/kernel/pacache.S
===================================================================
RCS file: /var/cvs/linux/arch/parisc/kernel/pacache.S,v
retrieving revision 1.10
diff -u -r1.10 pacache.S
--- arch/parisc/kernel/pacache.S	2001/09/06 09:44:07	1.10
+++ arch/parisc/kernel/pacache.S	2002/05/29 15:06:07
@@ -747,6 +747,50 @@
 
 	.procend
 
+	.export flush_kernel_icache_page
+
+flush_kernel_icache_page:
+	.proc
+	.callinfo NO_CALLS
+	.entry
+
+	ldil    L%icache_stride,%r1
+	ldw     R%icache_stride(%r1),%r23
+
+#ifdef __LP64__
+	depdi,z 1,63-PAGE_SHIFT,1,%r25
+#else
+	depwi,z 1,31-PAGE_SHIFT,1,%r25
+#endif
+	add     %r26,%r25,%r25
+	sub     %r25,%r23,%r25
+
+
+1:      fic,m   %r23(%r26)
+	fic,m   %r23(%r26)
+	fic,m   %r23(%r26)
+	fic,m   %r23(%r26)
+	fic,m   %r23(%r26)
+	fic,m   %r23(%r26)
+	fic,m   %r23(%r26)
+	fic,m   %r23(%r26)
+	fic,m   %r23(%r26)
+	fic,m   %r23(%r26)
+	fic,m   %r23(%r26)
+	fic,m   %r23(%r26)
+	fic,m   %r23(%r26)
+	fic,m   %r23(%r26)
+	fic,m   %r23(%r26)
+	CMPB<<  %r26,%r25,1b
+	fic,m   %r23(%r26)
+
+	sync
+	bv      %r0(%r2)
+	nop
+	.exit
+
+	.procend
+
 	.export flush_kernel_icache_range_asm
 
 flush_kernel_icache_range_asm:
Index: arch/parisc/mm/init.c
===================================================================
RCS file: /var/cvs/linux/arch/parisc/mm/init.c,v
retrieving revision 1.48
diff -u -r1.48 init.c
--- arch/parisc/mm/init.c	2002/04/15 23:49:12	1.48
+++ arch/parisc/mm/init.c	2002/05/29 15:06:09
@@ -381,10 +381,23 @@
 	printk(KERN_INFO "Freeing unused kernel memory: ");
 
 #if 1
-	cli();	/* disable all interrupts */
-	memset(&__init_begin, 0xff, 
+	/* Attempt to catch anyone trying to execute code here
+	 * by filling the page with BRK insns.
+	 * 
+	 * If we disable interrupts for all CPUs, then IPI stops working.
+	 * Kinda breaks the global cache flushing.
+	 */
+	local_irq_disable();
+
+	memset(&__init_begin, 0x00, 
 		(unsigned long)&__init_end - (unsigned long)&__init_begin);
-	sti();	/* re-enable all interrupts */
+
+	flush_data_cache();
+	asm volatile("sync" : : );
+	flush_icache_range((unsigned long)&__init_begin, (unsigned long)&__init_end);
+	asm volatile("sync" : : );
+
+	local_irq_enable();
 #endif
 	
 	addr = (unsigned long)(&__init_begin);
@@ -395,7 +408,7 @@
 		num_physpages++;
 	}
 
-	printk("%dk freed\n", (&__init_end - &__init_begin) >> 10);
+	printk("%luk freed\n", (unsigned long)(&__init_end - &__init_begin) >> 10);
 }
 
 /*
Index: include/asm-parisc/cache.h
===================================================================
RCS file: /var/cvs/linux/include/asm-parisc/cache.h,v
retrieving revision 1.15
diff -u -r1.15 cache.h
--- include/asm-parisc/cache.h	2001/11/29 20:54:37	1.15
+++ include/asm-parisc/cache.h	2002/05/29 15:06:09
@@ -45,6 +45,7 @@
 extern void flush_user_dcache_range_asm(unsigned long, unsigned long);
 extern void flush_kernel_dcache_range_asm(unsigned long, unsigned long);
 extern void flush_kernel_dcache_page(void *);
+extern void flush_kernel_icache_page(void *);
 extern void disable_sr_hashing(void);   /* turns off space register hashing */
 extern void disable_sr_hashing_asm(int); /* low level support for above */
 extern void free_sid(unsigned long);
Index: include/asm-parisc/pgalloc.h
===================================================================
RCS file: /var/cvs/linux/include/asm-parisc/pgalloc.h,v
retrieving revision 1.34
diff -u -r1.34 pgalloc.h
--- include/asm-parisc/pgalloc.h	2001/09/30 06:06:47	1.34
+++ include/asm-parisc/pgalloc.h	2002/05/29 15:06:10
@@ -121,9 +121,9 @@
 	}
 }
 
-#define flush_icache_page(vma,page)
+#define flush_icache_page(vma,page)	do { flush_kernel_dcache_page(page_address(page)); flush_kernel_icache_page(page_address(page)); } while (0)
 
-#define flush_icache_range flush_kernel_icache_range_asm
+#define flush_icache_range(s,e)		do { flush_kernel_dcache_range_asm(s,e); flush_kernel_icache_range_asm(s,e); } while (0)
 
 /* TLB flushing routines.... */
 
Index: kernel/module.c
===================================================================
RCS file: /var/cvs/linux/kernel/module.c,v
retrieving revision 1.11
diff -u -r1.11 module.c
--- kernel/module.c	2001/11/29 15:50:02	1.11
+++ kernel/module.c	2002/05/29 15:06:12
@@ -503,15 +503,6 @@
 
 	/* On some machines it is necessary to do something here
 	   to make the I and D caches consistent.  */
-#ifdef __hppa__
-	/* I guess we have a problem here because copy_from_user() has left
-	 * the new module code in the data cache, so we need to flush it
-	 * through.  Our copy_from_user() used to do cache flushing, but 
-	 * it has been removed.  Puzzled as to why other archs might want
-	 * to flush icache at this point.  rhirst@linuxcare.com
-	 */
-	flush_data_cache();
-#endif
 	flush_icache_range((unsigned long)mod, (unsigned long)mod + mod->size);
 
 	/* Update module references.  */