Port-powerpc archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: 20020313+0314 time warp version works on kbd/screen



For the folks on port-powerpc, there is a change to
lib/libkern/arch/powerpc around 3/13 that broke booting on some powermacs
under certain circumstances.

On Sat, 15 Jun 2002, Makoto Fujiwara wrote:

> Bill> Can someone try Manuel's time warp, with most of the kernel at 3/14
> Bill> source, but lib/libkern/arch/powerpc at 3/13? The author of this change
> Bill> says it *should* compile.
>
> I did that. The kernel compiled works fine with kbd/screen.

Ok. We're making progress.

I've attached the diffs I find in cvs covering these files in this time
frame. Makoto, do you agree that these are the relevant diffs?

These diffs touch two files, sys/lib/libkern/arch/powerpc/bzero.S and
sys/lib/libkern/arch/powerpc/syncicache.c.

I believe we need only look at the KERNEL case code.

One weird thing about this change is that you need version 1.3 of
sys/arch/powerpc/mpc6xx/genassym.cf for it to work right. CPU_CI, used on
line 206 of bzero.S, isn't defined w/o the above file. I'm not sure why
bzero.S would compile.

The only other thing I can think of is that we're calling one of these
routines before the cache info has gotten filled in.

Try applying the diffs one at a time & see what's the problem.

Thanks!

Take care,

Bill
Index: syssrc/sys/lib/libkern/arch/powerpc/bzero.S
diff -u syssrc/sys/lib/libkern/arch/powerpc/bzero.S:1.2 
syssrc/sys/lib/libkern/arch/powerpc/bzero.S:1.3
--- syssrc/sys/lib/libkern/arch/powerpc/bzero.S:1.2     Fri Nov 30 04:25:50 2001
+++ syssrc/sys/lib/libkern/arch/powerpc/bzero.S Wed Mar 13 02:59:29 2002
@@ -1,4 +1,4 @@
-/*     $NetBSD: bzero.S,v 1.2 2001/11/30 02:25:50 mjl Exp $ */
+/*     $NetBSD: bzero.S,v 1.3 2002/03/13 00:59:29 eeh Exp $ */
 
 /*-
  * Copyright (C) 2001  Martin J. Laubach <mjl%netbsd.org@localhost>
@@ -72,18 +72,19 @@
                bl      _GLOBAL_OFFSET_TABLE_@local-4
                mflr    r10
                mtlr    r9
-               lwz     r5,cache_size@got(r10)
+               lwz     r5,cache_info@got(r10)
 #else
-               lis     r5,cache_size@h
-               ori     r5,r5,cache_size@l
+               lis     r5,cache_info@h
+               ori     r5,r5,cache_info@l
 #endif
-               lwz     r6, 0(r5)
+               lwz     r6, 4(r5)
                cmpwi   r6, -1
                bne+    cb_cacheline_known
 
 /*----------------------------------------------------------------------*/
 #define CTL_MACHDEP    7
 #define CPU_CACHELINE  1
+#define        CPU_CACHEINFO   5
 
 #define STKFRAME_SZ    48
 #define MIB            8
@@ -102,6 +103,29 @@
                stw     r4, R4_SAVE(r1)
                stw     r0, R0_SAVE(r1)
 
+       
+
+               li      r0, CTL_MACHDEP         /* Construct MIB */
+               stw     r0, MIB(r1)
+               li      r0, CPU_CACHEINFO
+               stw     r0, MIB+4(r1)
+
+               li      r0, 4*4                 /* Oldlenp := 4*4 */
+               stw     r0, OLDPLEN(r1)
+
+               addi    r3, r1, MIB
+               li      r4, 2                   /* namelen */
+               /* r5 already contains &cache_info */
+               addi    r6, r1, OLDPLEN
+               li      r7, 0
+               li      r8, 0
+               bl      PIC_PLT(_C_LABEL(sysctl))
+       
+               cmpwi   r3, 0                   /* Check result */
+               beq     1f
+
+               /* Failure, try older sysctl */
+       
                li      r0, CTL_MACHDEP         /* Construct MIB */
                stw     r0, MIB(r1)
                li      r0, CPU_CACHELINE
@@ -112,12 +136,22 @@
 
                addi    r3, r1, MIB
                li      r4, 2                   /* namelen */
-               /* r5 already contains &cache_size */
+#ifdef PIC
+               mflr    r9
+               bl      _GLOBAL_OFFSET_TABLE_@local-4
+               mflr    r10
+               mtlr    r9
+               lwz     r5,cache_info@got(r10)
+               addi    r5, r5, 4
+#else
+               lis     r5,cache_info+4@h
+               ori     r5,r5,cache_info+4@l
+#endif
                addi    r6, r1, OLDPLEN
                li      r7, 0
                li      r8, 0
                bl      PIC_PLT(_C_LABEL(sysctl))
-
+1:
                lwz     r8, R8_SAVE(r1)
                lwz     r3, R3_SAVE(r1)
                lwz     r4, R4_SAVE(r1)
@@ -126,11 +160,11 @@
 #ifdef PIC
                bl      _GLOBAL_OFFSET_TABLE_@local-4
                mflr    r10
-               lwz     r9, cache_size@got(r10)
-               lwz     r9, 0(r9)
+               lwz     r9, cache_info@got(r10)
+               lwz     r9, 4(r9)
 #else
-               lis     r5, cache_size@ha
-               lwz     r9, cache_size@l(r5)
+               lis     r5, cache_info+4@ha
+               lwz     r9, cache_info+4@l(r5)
 #endif
                la      r1, STKFRAME_SZ(r1)
                lwz     r5, 4(r1)
@@ -151,25 +185,28 @@
 /* Okay, we know the cache line size (r9) and shift value (r10) */
 cb_cacheline_known:
 #ifdef PIC
-               lwz     r5, cache_size@got(r10)
-               lwz     r9, 0(r5)
+               lwz     r5, cache_info@got(r10)
+               lwz     r9, 4(r5)
                lwz     r5, cache_sh@got(r10)
                lwz     r10, 0(r5)
 #else
-               lis     r9, cache_size@ha
-               lwz     r9, cache_size@l(r9)
+               lis     r9, cache_info+4@ha
+               lwz     r9, cache_info+4@l(r9)
                lis     r10, cache_sh@ha
                lwz     r10, cache_sh@l(r10)
 #endif
 
 #else /* _KERNEL */
-               li      r9, CACHELINESIZE
-#if CACHELINESIZE == 32
-#define CACHELINESHIFT 5
+#ifdef MULTIPROCESSOR
+               mfspr   r10, 0                  /* Get cpu_info pointer */
 #else
-#error Define CACHELINESHIFT for your CACHELINESIZE
+               lis     r10, cpu_info_store@ha
+               addi    r10, r10, cpu_info_store@l
 #endif
-               li      r10, CACHELINESHIFT
+               lwz     r9, CPU_CI+4(r10)       /* Load D$ line size */
+               cntlzw  r10, r9                 /* Calculate shift.. */
+               li      r6, 31
+               subf    r10, r10, r6
 #endif /* _KERNEL */
                /* Back in memory filling business */
                
@@ -328,7 +365,7 @@
 /*----------------------------------------------------------------------*/
 #ifndef _KERNEL
                .data
-cache_size:    .long   -1
+cache_info:    .long   -1, -1, -1, -1
 cache_sh:      .long   0
 
 #endif
Index: syssrc/sys/lib/libkern/arch/powerpc/syncicache.c
diff -u syssrc/sys/lib/libkern/arch/powerpc/syncicache.c:1.4 
syssrc/sys/lib/libkern/arch/powerpc/syncicache.c:1.5
--- syssrc/sys/lib/libkern/arch/powerpc/syncicache.c:1.4        Thu Aug 23 
00:19:58 2001
+++ syssrc/sys/lib/libkern/arch/powerpc/syncicache.c    Wed Mar 13 02:59:29 2002
@@ -1,4 +1,4 @@
-/*     $NetBSD: syncicache.c,v 1.4 2001/08/22 21:19:58 matt Exp $      */
+/*     $NetBSD: syncicache.c,v 1.5 2002/03/13 00:59:29 eeh Exp $       */
 
 /*
  * Copyright (C) 1995-1997, 1999 Wolfgang Solfrank.
@@ -40,54 +40,89 @@
 
 #include <machine/cpu.h>
 
-#if    defined(_KERNEL) || defined(_STANDALONE)
+
+#if defined(_STANDALONE)
 #ifndef        CACHELINESIZE
 #error "Must know the size of a cache line"
 #endif
+static struct _cache_info {
+       CACHELINESIZE,
+       CACHELINESIZE,
+       CACHELINESIZE,
+       CACHELINESIZE
+};
+#define CACHEINFO      _cache_info
+#elif defined(_KERNEL)
+#define        CACHEINFO       (curcpu()->ci_ci)
 #else
-static void getcachelinesize __P((void));
+static void getcachelinesize (void);
 
-static int _cachelinesize;
-#define        CACHELINESIZE   _cachelinesize
+static int _cachelinesize = 0;
 
+static struct cache_info _cache_info;
+#define CACHEINFO      _cache_info
+
 static void
-getcachelinesize()
+getcachelinesize(void)
 {
        static int cachemib[] = { CTL_MACHDEP, CPU_CACHELINE };
-       int clen = sizeof(_cachelinesize);
+       static int cacheinfomib[] = { CTL_MACHDEP, CPU_CACHEINFO };
+       size_t clen = sizeof(_cache_info);
+
+       if (sysctl(cacheinfomib, sizeof(cacheinfomib) / sizeof(cacheinfomib[0]),
+               &_cache_info, &clen, NULL, 0) == 0) {
+               _cachelinesize = _cache_info.dcache_line_size;
+               return;
+       }
 
+       /* Try older deprecated sysctl */
+       clen = sizeof(_cachelinesize);
        if (sysctl(cachemib, sizeof(cachemib) / sizeof(cachemib[0]),
                   &_cachelinesize, &clen, NULL, 0) < 0
            || !_cachelinesize)
                abort();
+
+       _cache_info.dcache_size = _cachelinesize;
+       _cache_info.dcache_line_size = _cachelinesize;
+       _cache_info.icache_size = _cachelinesize;
+       _cache_info.icache_line_size = _cachelinesize;
+       /* If there is no cache, indicate we have issued the sysctl. */
+       if (!_cachelinesize) _cachelinesize = 1;
 }
 #endif
 
 void
-__syncicache(from, len)
-       void *from;
-       int len;
+__syncicache(void *from, int len)
 {
        int l, off;
        char *p;
+       int linesz;
 
 #if    !defined(_KERNEL) && !defined(_STANDALONE)
        if (!_cachelinesize)
                getcachelinesize();
 #endif 
-       off = (u_int)from & (CACHELINESIZE - 1);
-       l = len += off;
-       p = (char *)from - off;
-       do {
-               __asm__ __volatile ("dcbst 0,%0" :: "r"(p));
-               p += CACHELINESIZE;
-       } while ((l -= CACHELINESIZE) > 0);
+
+       if (CACHEINFO.dcache_size > 0) {
+               linesz = CACHEINFO.dcache_line_size;
+               off = (u_int)from & (linesz - 1);
+               l = len += off;
+               p = (char *)from - off;
+               do {
+                       __asm__ __volatile ("dcbst 0,%0" :: "r"(p));
+                       p += linesz;
+               } while ((l -= linesz) > 0);
+       }
        __asm__ __volatile ("sync");
-       p = (char *)from - off;
-       do {
-               __asm__ __volatile ("icbi 0,%0" :: "r"(p));
-               p += CACHELINESIZE;
-       } while ((len -= CACHELINESIZE) > 0);
-       __asm__ __volatile ("sync");    /* required on 7450 */
+
+       if (CACHEINFO.icache_size > 0 ) {
+               linesz = CACHEINFO.icache_line_size;
+               off = (u_int)from & (linesz - 1);
+               p = (char *)from - off;
+               do {
+                       __asm__ __volatile ("icbi 0,%0" :: "r"(p));
+                       p += linesz;
+               } while ((len -= linesz) > 0);
+       }
        __asm__ __volatile ("isync");
 }


Home | Main Index | Thread Index | Old Index