[parisc-linux-cvs] Re: DIFF 2.6.7-pa10 iosapic/debug/rp3440 boot

Grant Grundler grundler at parisc-linux.org
Sat Jul 10 02:01:58 MDT 2004


On Sat, Jul 10, 2004 at 01:51:16AM -0600, Grant Grundler wrote:
> Log message:
> 2.6.7-pa10 iosapic patch from Bjorn Helgaas and two fixes from James Bottomley
> 
> Disable panic in cache.c regarding systems that indicate they don't
> support equivalent aliases.
> 
> Boots on rp3440 (pa8800) with NFS root but CONFIG_DEBUG_SPINLOCK=n.
> System would panic if DEBUG_SPINLOCK was Y.
> Both cases are with SMP=n.

I'm still not convinced DEBUG_SPINLOCK=y was the only thing
that prevented the rp3440 from booting. But it's the only
thing I changed (to N) and rebuilt. *shrug*.

Apologies and thanks to Bjorn. The iosapic patch was long overdue.
Thanks to James Bottomley for pointing out two obvious
(to him) fixes: pdc.c breaking pdc_lock in the panic path and
changing KERNEL_INITIAL_ORDER so we get 16MB on 64BIT
kernels (and 8MB as before on 32-bit kernels).

thanks,
grant


Index: Makefile
===================================================================
RCS file: /var/cvs/linux-2.6/Makefile,v
retrieving revision 1.216
diff -u -p -r1.216 Makefile
--- Makefile	9 Jul 2004 20:25:41 -0000	1.216
+++ Makefile	10 Jul 2004 07:42:32 -0000
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 7
-EXTRAVERSION = -pa9
+EXTRAVERSION = -pa10
 NAME=Zonked Quokka
 
 # *DOCUMENTATION*
Index: arch/parisc/kernel/cache.c
===================================================================
RCS file: /var/cvs/linux-2.6/arch/parisc/kernel/cache.c,v
retrieving revision 1.18
diff -u -p -r1.18 cache.c
--- arch/parisc/kernel/cache.c	9 Jul 2004 19:04:20 -0000	1.18
+++ arch/parisc/kernel/cache.c	10 Jul 2004 07:42:33 -0000
@@ -124,51 +124,60 @@ parisc_cache_init(void)
 		panic("parisc_cache_init: pdc_cache_info failed");
 
 #if 0
-	printk(KERN_DEBUG "ic_size %lx dc_size %lx it_size %lx pdc_cache_info %d*long pdc_cache_cf %d\n",
-	    cache_info.ic_size,
-	    cache_info.dc_size,
-	    cache_info.it_size,
-	    sizeof (struct pdc_cache_info) / sizeof (long),
-	    sizeof (struct pdc_cache_cf)
-	);
-
-	printk(KERN_DEBUG "dc base %x dc stride %x dc count %x dc loop %d\n",
-	    cache_info.dc_base,
-	    cache_info.dc_stride,
-	    cache_info.dc_count,
-	    cache_info.dc_loop);
-
-	printk(KERN_DEBUG "dc conf: alias %d block %d line %d wt %d sh %d cst %d assoc %d\n",
-	    cache_info.dc_conf.cc_alias,
-	    cache_info.dc_conf.cc_block,
-	    cache_info.dc_conf.cc_line,
-	    cache_info.dc_conf.cc_wt,
-	    cache_info.dc_conf.cc_sh,
-	    cache_info.dc_conf.cc_cst,
-	    cache_info.dc_conf.cc_assoc);
-
-	printk(KERN_DEBUG "ic conf: alias %d block %d line %d wt %d sh %d cst %d assoc %d\n",
-	    cache_info.ic_conf.cc_alias,
-	    cache_info.ic_conf.cc_block,
-	    cache_info.ic_conf.cc_line,
-	    cache_info.ic_conf.cc_wt,
-	    cache_info.ic_conf.cc_sh,
-	    cache_info.ic_conf.cc_cst,
-	    cache_info.ic_conf.cc_assoc);
-
-	printk(KERN_DEBUG "dt conf: sh %d page %d cst %d aid %d pad1 %d \n",
-	    cache_info.dt_conf.tc_sh,
-	    cache_info.dt_conf.tc_page,
-	    cache_info.dt_conf.tc_cst,
-	    cache_info.dt_conf.tc_aid,
-	    cache_info.dt_conf.tc_pad1);
-
-	printk(KERN_DEBUG "it conf: sh %d page %d cst %d aid %d pad1 %d \n",
-	    cache_info.it_conf.tc_sh,
-	    cache_info.it_conf.tc_page,
-	    cache_info.it_conf.tc_cst,
-	    cache_info.it_conf.tc_aid,
-	    cache_info.it_conf.tc_pad1);
+	printk("ic_size %lx dc_size %lx it_size %lx\n",
+		cache_info.ic_size,
+		cache_info.dc_size,
+		cache_info.it_size);
+
+	printk("DC  base 0x%lx stride 0x%lx count 0x%lx loop 0x%lx\n",
+		cache_info.dc_base,
+		cache_info.dc_stride,
+		cache_info.dc_count,
+		cache_info.dc_loop);
+
+	printk("dc_conf = 0x%lx  alias %d blk %d line %d shift %d\n",
+		*(unsigned long *) (&cache_info.dc_conf),
+		cache_info.dc_conf.cc_alias,
+		cache_info.dc_conf.cc_block,
+		cache_info.dc_conf.cc_line,
+		cache_info.dc_conf.cc_shift);
+	printk("	wt %d sh %d cst %d assoc %d\n",
+		cache_info.dc_conf.cc_wt,
+		cache_info.dc_conf.cc_sh,
+		cache_info.dc_conf.cc_cst,
+		cache_info.dc_conf.cc_assoc);
+
+	printk("IC  base 0x%lx stride 0x%lx count 0x%lx loop 0x%lx\n",
+		cache_info.ic_base,
+		cache_info.ic_stride,
+		cache_info.ic_count,
+		cache_info.ic_loop);
+
+	printk("ic_conf = 0x%lx  alias %d blk %d line %d shift %d\n",
+		*(unsigned long *) (&cache_info.ic_conf),
+		cache_info.ic_conf.cc_alias,
+		cache_info.ic_conf.cc_block,
+		cache_info.ic_conf.cc_line,
+		cache_info.ic_conf.cc_shift);
+	printk("	wt %d sh %d cst %d assoc %d\n",
+		cache_info.ic_conf.cc_wt,
+		cache_info.ic_conf.cc_sh,
+		cache_info.ic_conf.cc_cst,
+		cache_info.ic_conf.cc_assoc);
+
+	printk("D-TLB conf: sh %d page %d cst %d aid %d pad1 %d \n",
+		cache_info.dt_conf.tc_sh,
+		cache_info.dt_conf.tc_page,
+		cache_info.dt_conf.tc_cst,
+		cache_info.dt_conf.tc_aid,
+		cache_info.dt_conf.tc_pad1);
+
+	printk("I-TLB conf: sh %d page %d cst %d aid %d pad1 %d \n",
+		cache_info.it_conf.tc_sh,
+		cache_info.it_conf.tc_page,
+		cache_info.it_conf.tc_cst,
+		cache_info.it_conf.tc_aid,
+		cache_info.it_conf.tc_pad1);
 #endif
 
 	split_tlb = 0;
@@ -180,10 +189,14 @@ parisc_cache_init(void)
 		split_tlb = 1;
 	}
 
-	dcache_stride = (1 << (cache_info.dc_conf.cc_block + 3)) *
-						cache_info.dc_conf.cc_line;
-	icache_stride = (1 << (cache_info.ic_conf.cc_block + 3)) *
-						cache_info.ic_conf.cc_line;
+	/* "New and Improved" version from Jim Hull 
+	 *	(1 << (cc_block-1)) * (cc_line << (4 + cnf.cc_shift))
+	 */
+#define CAFL_STRIDE(cnf) (cnf.cc_line << (3 + cnf.cc_block + cnf.cc_shift))
+	dcache_stride = CAFL_STRIDE(cache_info.dc_conf);
+	icache_stride = CAFL_STRIDE(cache_info.ic_conf);
+#undef CAFL_STRIDE
+
 #ifndef CONFIG_PA20
 	if (pdc_btlb_info(&btlb_info) < 0) {
 		memset(&btlb_info, 0, sizeof btlb_info);
@@ -192,8 +205,8 @@ parisc_cache_init(void)
 
 	if ((boot_cpu_data.pdc.capabilities & PDC_MODEL_NVA_MASK) ==
 						PDC_MODEL_NVA_UNSUPPORTED) {
-		printk(KERN_WARNING "Only equivalent aliasing supported\n");
-#ifndef CONFIG_SMP
+		printk(KERN_WARNING "parisc_cache_init: Only equivalent aliasing supported!\n");
+#if 0
 		panic("SMP kernel required to avoid non-equivalent aliasing");
 #endif
 	}
Index: arch/parisc/kernel/firmware.c
===================================================================
RCS file: /var/cvs/linux-2.6/arch/parisc/kernel/firmware.c,v
retrieving revision 1.8
diff -u -p -r1.8 firmware.c
--- arch/parisc/kernel/firmware.c	4 Jun 2004 19:36:53 -0000	1.8
+++ arch/parisc/kernel/firmware.c	10 Jul 2004 07:42:34 -0000
@@ -177,7 +177,8 @@ void __init set_firmware_width(void)
  */
 void pdc_emergency_unlock(void)
 {
-        spin_unlock(&pdc_lock);
+        spin_trylock(&pdc_lock);  /* get pdc_lock before spinlock */
+        spin_unlock(&pdc_lock);   /* DEBUG code freaks out here. */
 }
 
 
Index: drivers/parisc/iosapic.c
===================================================================
RCS file: /var/cvs/linux-2.6/drivers/parisc/iosapic.c,v
retrieving revision 1.6
diff -u -p -r1.6 iosapic.c
--- drivers/parisc/iosapic.c	4 Jun 2004 19:36:53 -0000	1.6
+++ drivers/parisc/iosapic.c	10 Jul 2004 07:42:34 -0000
@@ -233,6 +233,18 @@ assert_failed (char *a, char *f, int l)
 #define IOSAPIC_IRDT_ENTRY(idx)		(0x10+(idx)*2)
 #define IOSAPIC_IRDT_ENTRY_HI(idx)	(0x11+(idx)*2)
 
+static inline unsigned int iosapic_read(unsigned long iosapic, unsigned int reg)
+{
+	writel(reg, iosapic + IOSAPIC_REG_SELECT);
+	return readl(iosapic + IOSAPIC_REG_WINDOW);
+}
+
+static inline void iosapic_write(unsigned long iosapic, unsigned int reg, u32 val)
+{
+	writel(reg, iosapic + IOSAPIC_REG_SELECT);
+	writel(val, iosapic + IOSAPIC_REG_WINDOW);
+}
+
 /*
 **     GFP_KERNEL includes __GFP_WAIT flag and that may not
 **     be acceptable. Since this is boot time, we shouldn't have
@@ -718,13 +730,8 @@ iosapic_rd_irt_entry(struct vector_info 
 	struct iosapic_info *isp = vi->iosapic;
 	u8 idx = vi->irqline;
 
-	/* point the window register to the lower word */
-	writel(IOSAPIC_IRDT_ENTRY(idx), isp->isi_hpa+IOSAPIC_REG_SELECT);
-	*dp0 = readl(isp->isi_hpa+IOSAPIC_REG_WINDOW);
-
-	/* point the window register to the higher word */
-	writel(IOSAPIC_IRDT_ENTRY_HI(idx), isp->isi_hpa+IOSAPIC_REG_SELECT);
-	*dp1 = readl(isp->isi_hpa+IOSAPIC_REG_WINDOW);
+	*dp0 = iosapic_read(isp->isi_hpa, IOSAPIC_IRDT_ENTRY(idx));
+	*dp1 = iosapic_read(isp->isi_hpa, IOSAPIC_IRDT_ENTRY_HI(idx));
 }
 
 
@@ -740,16 +747,12 @@ iosapic_wr_irt_entry(struct vector_info 
 		isp->isi_hpa,
 		dp0, dp1);
 
-	/* point the window register to the lower word */
-	writel(IOSAPIC_IRDT_ENTRY(vi->irqline), isp->isi_hpa+IOSAPIC_REG_SELECT);
-	writel( dp0, isp->isi_hpa+IOSAPIC_REG_WINDOW);
+	iosapic_write(isp->isi_hpa, IOSAPIC_IRDT_ENTRY(vi->irqline), dp0);
 
 	/* Read the window register to flush the writes down to HW  */
 	dp0 = readl(isp->isi_hpa+IOSAPIC_REG_WINDOW);
 
-	/* point the window register to the higher word */
-	writel(IOSAPIC_IRDT_ENTRY_HI(vi->irqline), isp->isi_hpa+IOSAPIC_REG_SELECT);
-	writel( dp1, isp->isi_hpa+IOSAPIC_REG_WINDOW);
+	iosapic_write(isp->isi_hpa, IOSAPIC_IRDT_ENTRY_HI(vi->irqline), dp1);
 
 	/* Read the window register to flush the writes down to HW  */
 	dp1 = readl(isp->isi_hpa+IOSAPIC_REG_WINDOW);
@@ -881,11 +884,7 @@ printk("iosapic_enable_irq(): sel ");
 	struct iosapic_info *isp = vi->iosapic;
 
 	for (d0=0x10; d0<0x1e; d0++) {
-		/* point the window register to the lower word */
-		writel(d0, isp->isi_hpa+IOSAPIC_REG_SELECT);
-
-		/* read the word */
-		d1 = readl(isp->isi_hpa+IOSAPIC_REG_WINDOW);
+		d1 = iosapic_read(isp->isi_hpa, d0);
 		printk(" %x", d1);
 	}
 }
@@ -933,11 +932,7 @@ iosapic_rd_version(struct iosapic_info *
 	ASSERT(isi);
 	ASSERT(isi->isi_hpa);
 
-	/* point window to the version register */
-	writel(IOSAPIC_REG_VERSION, isi->isi_hpa+IOSAPIC_REG_SELECT);
-
-	/* now read the version register */
-	return (readl(isi->isi_hpa+IOSAPIC_REG_WINDOW));
+	return iosapic_read(isi->isi_hpa, IOSAPIC_REG_VERSION);
 }
 
 
Index: include/asm-parisc/pdc.h
===================================================================
RCS file: /var/cvs/linux-2.6/include/asm-parisc/pdc.h,v
retrieving revision 1.7
diff -u -p -r1.7 pdc.h
--- include/asm-parisc/pdc.h	4 Jun 2004 19:36:53 -0000	1.7
+++ include/asm-parisc/pdc.h	10 Jul 2004 07:42:35 -0000
@@ -346,10 +346,10 @@ struct pdc_cache_cf {		/* for PDC_CACHE 
 #ifdef __LP64__
 		cc_padW:32,
 #endif
-		cc_alias:4,	/* alias boundaries for virtual addresses   */
+		cc_alias: 4,	/* alias boundaries for virtual addresses   */
 		cc_block: 4,	/* to determine most efficient stride */
 		cc_line	: 3,	/* maximum amount written back as a result of store (multiple of 16 bytes) */
-		cc_pad0 : 2,	/* reserved */
+		cc_shift: 2,	/* how much to shift cc_block left */
 		cc_wt	: 1,	/* 0 = WT-Dcache, 1 = WB-Dcache */
 		cc_sh	: 2,	/* 0 = separate I/D-cache, else shared I/D-cache */
 		cc_cst  : 3,	/* 0 = incoherent D-cache, 1=coherent D-cache */
Index: include/asm-parisc/pgtable.h
===================================================================
RCS file: /var/cvs/linux-2.6/include/asm-parisc/pgtable.h,v
retrieving revision 1.14
diff -u -p -r1.14 pgtable.h
--- include/asm-parisc/pgtable.h	9 Jul 2004 19:04:21 -0000	1.14
+++ include/asm-parisc/pgtable.h	10 Jul 2004 07:42:35 -0000
@@ -57,10 +57,14 @@
 
 /* This is the size of the initially mapped kernel memory (i.e. currently
  * 0 to 1<<23 == 8MB */
+#ifdef CONFIG_64BIT
+#define KERNEL_INITIAL_ORDER	24
+#else
 #define KERNEL_INITIAL_ORDER	23
+#endif
 #define KERNEL_INITIAL_SIZE	(1 << KERNEL_INITIAL_ORDER)
 
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 #define PT_NLEVELS	3
 #define PGD_ORDER	1 /* Number of pages per pgd */
 #define PMD_ORDER	1 /* Number of pages per pmd */
@@ -264,7 +268,7 @@ extern unsigned long *empty_zero_page;
 #define pgd_flag(x)	(pgd_val(x) & PxD_FLAG_MASK)
 #define pgd_address(x)	((unsigned long)(pgd_val(x) &~ PxD_FLAG_MASK) << PxD_VALUE_SHIFT)
 
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 /* The first entry of the permanent pmd is not there if it contains
  * the gateway marker */
 #define pmd_none(x)	(!pmd_val(x) || pmd_flag(x) == PxD_FLAG_ATTACHED)
@@ -274,7 +278,7 @@ extern unsigned long *empty_zero_page;
 #define pmd_bad(x)	(!(pmd_flag(x) & PxD_FLAG_VALID))
 #define pmd_present(x)	(pmd_flag(x) & PxD_FLAG_PRESENT)
 static inline void pmd_clear(pmd_t *pmd) {
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 	if (pmd_flag(*pmd) & PxD_FLAG_ATTACHED)
 		/* This is the entry pointing to the permanent pmd
 		 * attached to the pgd; cannot clear it */
@@ -295,7 +299,7 @@ static inline void pmd_clear(pmd_t *pmd)
 #define pgd_bad(x)      (!(pgd_flag(x) & PxD_FLAG_VALID))
 #define pgd_present(x)  (pgd_flag(x) & PxD_FLAG_PRESENT)
 static inline void pgd_clear(pgd_t *pgd) {
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
 	if(pgd_flag(*pgd) & PxD_FLAG_ATTACHED)
 		/* This is the permanent pmd attached to the pgd; cannot
 		 * free it */


More information about the parisc-linux-cvs mailing list