Port-sparc archive

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

re: partially working SMP again




OK, this one doesn't require a /boot change simply by not accessing
the cpuinfo data until we change to the kernel pagetables instead of
the prom ones.

(it also includes some #if'ed code to uncache cpuinfo pages, but
i have no intention of commiting this part.)


.mrg.


Index: sparc/cpu.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc/sparc/cpu.c,v
retrieving revision 1.216
diff -p -r1.216 cpu.c
*** sparc/cpu.c 30 May 2009 01:19:29 -0000      1.216
--- sparc/cpu.c 31 May 2009 02:47:43 -0000
*************** char    cpu_model[100];                 /* machine model 
*** 102,108 ****
  extern char machine_model[];
  
  int   sparc_ncpus;                    /* # of CPUs detected by PROM */
! struct cpu_info *cpus[_MAXNCPU];      /* we only support 4 CPUs. */
  
  /* The CPU configuration driver. */
  static void cpu_mainbus_attach(struct device *, struct device *, void *);
--- 102,108 ----
  extern char machine_model[];
  
  int   sparc_ncpus;                    /* # of CPUs detected by PROM */
! struct cpu_info *cpus[_MAXNCPU+1];    /* we only support 4 CPUs. */
  
  /* The CPU configuration driver. */
  static void cpu_mainbus_attach(struct device *, struct device *, void *);
*************** getcacheinfo_obp(struct cpu_info *sc, in
*** 1123,1128 ****
--- 1123,1157 ----
        struct cacheinfo *ci = &sc->cacheinfo;
        int i, l;
  
+ #if defined(MULTIPROCESSOR)
+       /*
+        * We really really want the cache info early for MP systems,
+        * so figure out the boot node, if we can.
+        *
+        * XXX this loop stolen from mainbus_attach()
+        */
+       if (node == 0 && CPU_ISSUN4M && bootmid != 0) {
+               const char *cp;
+               char namebuf[32];
+               int mid, node2;
+ 
+               for (node2 = firstchild(findroot());
+                    node2;
+                    node2 = nextsibling(node2)) {
+                       cp = prom_getpropstringA(node2, "device_type",
+                                           namebuf, sizeof namebuf);
+                       if (strcmp(cp, "cpu") != 0)
+                               continue;
+ 
+                       mid = prom_getpropint(node2, "mid", -1);
+                       if (mid == bootmid) {
+                               node = node2;
+                               break;
+                       }
+               }
+       }
+ #endif
+ 
        if (node == 0)
                /* Bootstrapping */
                return;
*************** getcpuinfo(struct cpu_info *sc, int node
*** 1862,1867 ****
--- 1891,1899 ----
                if (sc->cacheinfo.c_vactype == VAC_UNKNOWN)
                        sc->cacheinfo.c_vactype = mp->minfo->vactype;
  
+               if (sc->master && mp->minfo->getmid != NULL)
+                       bootmid = mp->minfo->getmid();
+ 
                mp->minfo->getcacheinfo(sc, node);
  
                if (node && sc->hz == 0 && !CPU_ISSUN4/*XXX*/) {
*************** getcpuinfo(struct cpu_info *sc, int node
*** 1875,1883 ****
                        }
                }
  
-               if (sc->master && mp->minfo->getmid != NULL)
-                       bootmid = mp->minfo->getmid();
- 
                /*
                 * Copy CPU/MMU/Cache specific routines into cpu_info.
                 */
--- 1907,1912 ----
Index: sparc/cpuvar.h
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc/sparc/cpuvar.h,v
retrieving revision 1.78
diff -p -r1.78 cpuvar.h
*** sparc/cpuvar.h      27 May 2009 02:19:49 -0000      1.78
--- sparc/cpuvar.h      31 May 2009 02:47:43 -0000
*************** struct cpu_info {
*** 325,330 ****
--- 325,336 ----
        /*bus_space_handle_t*/ long ci_mxccregs;
  
        u_int   ci_tt;                  /* Last trap (if tracing) */
+ 
+       /*
+        * Start/End VA's of this cpu_info region; we upload the other pages
+        * in this region that aren't part of the cpu_info to uvm.
+        */
+       vaddr_t ci_free_sva1, ci_free_eva1, ci_free_sva2, ci_free_eva2;
  };
  
  /*
Index: sparc/intr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc/sparc/intr.c,v
retrieving revision 1.104
diff -p -r1.104 intr.c
*** sparc/intr.c        27 May 2009 02:19:50 -0000      1.104
--- sparc/intr.c        31 May 2009 02:47:43 -0000
*************** void    bogusintr(struct clockframe *);
*** 94,99 ****
--- 94,100 ----
  void
  strayintr(struct clockframe *fp)
  {
+ #if 0
        static int straytime, nstray;
        char bits[64];
        int timesince;
*************** strayintr(struct clockframe *fp)
*** 110,115 ****
--- 111,117 ----
                straytime = time_uptime;
                nstray = 1;
        }
+ #endif
  }
  
  
Index: sparc/locore.s
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc/sparc/locore.s,v
retrieving revision 1.246
diff -p -r1.246 locore.s
*** sparc/locore.s      29 May 2009 22:06:55 -0000      1.246
--- sparc/locore.s      31 May 2009 02:47:43 -0000
*************** _C_LABEL(cpu_hatch):
*** 4601,4612 ****
        wr      %g6, 0, %tbr
        nop; nop; nop                   ! paranoia
  
-       /* Set up a stack. We use the bottom half of the interrupt stack */
        set     USRSTACK - CCFSZ, %fp   ! as if called from user code
        sethi   %hi(_EINTSTACKP), %o0
        ld      [%o0 + %lo(_EINTSTACKP)], %o0
        set     (INT_STACK_SIZE/2) + CCFSZ + 80, %sp
        sub     %o0, %sp, %sp
  
        /* Enable traps */
        rd      %psr, %l0
--- 4601,4623 ----
        wr      %g6, 0, %tbr
        nop; nop; nop                   ! paranoia
  
        set     USRSTACK - CCFSZ, %fp   ! as if called from user code
+ 
+ #if 0
+       /* Set up a stack. We use the bottom half of the interrupt stack */
        sethi   %hi(_EINTSTACKP), %o0
        ld      [%o0 + %lo(_EINTSTACKP)], %o0
        set     (INT_STACK_SIZE/2) + CCFSZ + 80, %sp
        sub     %o0, %sp, %sp
+ #else
+       /*
+        * Use this CPUs idlelwp's stack
+        */
+       sethi   %hi(cpcb), %o0
+       ld      [%o0 + %lo(cpcb)], %o0
+       set     USPACE - 80 - CCFSZ, %sp
+       add     %o0, %sp, %sp
+ #endif
  
        /* Enable traps */
        rd      %psr, %l0
Index: sparc/pmap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc/sparc/pmap.c,v
retrieving revision 1.329
diff -p -r1.329 pmap.c
*** sparc/pmap.c        27 May 2009 02:19:50 -0000      1.329
--- sparc/pmap.c        31 May 2009 02:47:43 -0000
*************** pmap_page_upload(void)
*** 1148,1153 ****
--- 1148,1175 ----
                        atop(start),
                        atop(end), VM_FREELIST_DEFAULT);
        }
+ 
+ #if defined(MULTIPROCESSOR)
+       {
+               CPU_INFO_ITERATOR cpunum;
+               struct cpu_info *cpi;
+ 
+               for (CPU_INFO_FOREACH(cpunum, cpi)) {
+                       if (cpi->ci_free_sva1)
+                               
uvm_page_physload(atop(PMAP_BOOTSTRAP_VA2PA(cpi->ci_free_sva1)),
+                                                 
atop(PMAP_BOOTSTRAP_VA2PA(cpi->ci_free_eva1)),
+                                                 
atop(PMAP_BOOTSTRAP_VA2PA(cpi->ci_free_sva1)),
+                                                 
atop(PMAP_BOOTSTRAP_VA2PA(cpi->ci_free_eva1)),
+                                                 VM_FREELIST_DEFAULT);
+                       if (cpi->ci_free_sva2)
+                               
uvm_page_physload(atop(PMAP_BOOTSTRAP_VA2PA(cpi->ci_free_sva2)),
+                                                 
atop(PMAP_BOOTSTRAP_VA2PA(cpi->ci_free_eva2)),
+                                                 
atop(PMAP_BOOTSTRAP_VA2PA(cpi->ci_free_sva2)),
+                                                 
atop(PMAP_BOOTSTRAP_VA2PA(cpi->ci_free_eva2)),
+                                                 VM_FREELIST_DEFAULT);
+               }
+       }
+ #endif
  }
  
  /*
*************** pmap_bootstrap4m(void *top)
*** 3467,3474 ****
        vaddr_t va;
  #ifdef MULTIPROCESSOR
        vsize_t off;
!       size_t cpuinfo_len;
        uint8_t *cpuinfo_data;
  #endif
  
        /*
--- 3489,3499 ----
        vaddr_t va;
  #ifdef MULTIPROCESSOR
        vsize_t off;
!       size_t cpuinfo_len = sizeof(struct cpu_info);
        uint8_t *cpuinfo_data;
+       int align = PAGE_SIZE;
+       vaddr_t sva, cpuinfo_va;
+       vsize_t sz;
  #endif
  
        /*
*************** pmap_bootstrap4m(void *top)
*** 3502,3523 ****
         */
        p = (vaddr_t)top;
  
! #if defined(MULTIPROCESSOR)
!       /*
!        * allocate the rest of the cpu_info{} area.  note we waste the
!        * first one to get a VA space.
!        */
!       cpuinfo_len = ((sizeof(struct cpu_info) + NBPG - 1) & ~PGOFSET);
!       if (sparc_ncpus > 1) {
!               p = (p + NBPG - 1) & ~PGOFSET;
!               cpuinfo_data = (uint8_t *)p;
!               p += (cpuinfo_len * sparc_ncpus);
! 
!               /* XXX we waste the first one */
!               memset(cpuinfo_data + cpuinfo_len, 0, cpuinfo_len * 
(sparc_ncpus - 1));
!       } else
!               cpuinfo_data = (uint8_t *)CPUINFO_VA;
! #endif
  
        /*
         * Intialize the kernel pmap.
--- 3527,3533 ----
         */
        p = (vaddr_t)top;
  
!       p = (p + NBPG - 1) & ~PGOFSET;
  
        /*
         * Intialize the kernel pmap.
*************** pmap_bootstrap4m(void *top)
*** 3616,3621 ****
--- 3626,3660 ----
        p = (p + NBPG - 1) & ~PGOFSET;
        pagetables_end = p;
  
+ #if defined(MULTIPROCESSOR)
+       /*
+        * Allocate aligned KVA.  `cpuinfo' resides at a fixed virtual
+        * address. Since we need to access an other CPU's cpuinfo
+        * structure occasionally, this must be done at a virtual address
+        * that's cache congruent to the fixed address CPUINFO_VA.
+        *
+        * NOTE: we're using the cache properties of the boot CPU to
+        * determine the alignment (XXX).
+        */
+       if (sparc_ncpus > 1) {
+               if (CACHEINFO.c_totalsize > align) {
+                       /* Need a power of two */
+                       while (align <= CACHEINFO.c_totalsize)
+                               align <<= 1;
+               //      align >>= 1;
+               }
+               sz = sizeof(struct cpu_info);
+ 
+               sz = (sz + PAGE_SIZE - 1) & -PAGE_SIZE;
+               cpuinfo_len = sz + align - PAGE_SIZE;
+ 
+               /* Grab as much space as we need */
+               cpuinfo_data = (uint8_t *)p;
+               p += (cpuinfo_len * sparc_ncpus);
+       } else
+               cpuinfo_data = (uint8_t *)CPUINFO_VA;
+ #endif
+ 
        avail_start = PMAP_BOOTSTRAP_VA2PA(p);
  
        /*
*************** pmap_bootstrap4m(void *top)
*** 3755,3760 ****
--- 3794,3806 ----
                pte |= PPROT_N_RX | SRMMU_TEPTE;
  
                /* Deal with the cacheable bit for pagetable memory */
+ #undef PMAP_UNCACHE_CPUINFO
+ #if defined(MULTIPROCESSOR) && defined(PMAP_UNCACHE_CPUINFO)
+               if (q == (vaddr_t)CPUINFO_VA ||
+                   (q >= (vaddr_t)cpuinfo_data && q < (vaddr_t)(cpuinfo_data + 
sparc_ncpus * cpuinfo_len)))
+                       ;
+               else
+ #endif
                if ((cpuinfo.flags & CPUFLG_CACHEPAGETABLES) != 0 ||
                    q < pagetables_start || q >= pagetables_end)
                        pte |= SRMMU_PG_C;
*************** pmap_bootstrap4m(void *top)
*** 3798,3832 ****
         */
        mmu_install_tables(&cpuinfo);
  
! #ifdef MULTIPROCESSOR
        /*
         * Initialise any cpu-specific data now.
         */
        cpu_init_system();
  
        /*
-        * Remap cpu0 from CPUINFO_VA to the new correct value, wasting the
-        * backing page we allocated above XXX.
-        */
-       for (off = 0, va = (vaddr_t)cpuinfo_data;
-            sparc_ncpus > 1 && off < sizeof(struct cpu_info);
-            va += NBPG, off += NBPG) {
-               paddr_t pa = PMAP_BOOTSTRAP_VA2PA(CPUINFO_VA + off);
-               prom_printf("going to pmap_kenter_pa(va=%p, pa=%p)\n", va, pa);
-               pmap_kremove(va, NBPG);
-               pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE);
-               cache_flush_page(va, 0);
-               cache_flush_page(CPUINFO_VA, 0);
-       }
- 
-       /*
         * Setup the cpus[] array and the ci_self links.
         */
        prom_printf("setting cpus self reference\n");
        for (i = 0; i < sparc_ncpus; i++) {
!               cpus[i] = (struct cpu_info *)(cpuinfo_data + (cpuinfo_len * i));
                cpus[i]->ci_self = cpus[i];
                prom_printf("set cpu%d ci_self address: %p\n", i, cpus[i]);
        }
  #else
        cpus[0] = (struct cpu_info *)CPUINFO_VA;
--- 3844,3909 ----
         */
        mmu_install_tables(&cpuinfo);
  
! #if defined(MULTIPROCESSOR)
        /*
         * Initialise any cpu-specific data now.
         */
        cpu_init_system();
  
        /*
         * Setup the cpus[] array and the ci_self links.
         */
        prom_printf("setting cpus self reference\n");
        for (i = 0; i < sparc_ncpus; i++) {
!               sva = (vaddr_t) (cpuinfo_data + (cpuinfo_len * i));
!               cpuinfo_va = sva +
!                  (((CPUINFO_VA & (align - 1)) + align - sva) & (align - 1));
! 
!               /*
!                * Either remap from CPUINFO_VA to the new correct value
!                * or clear out this cpuinfo.
!                */
!               if (i == 0) {
!                       for (off = 0, va = cpuinfo_va;
!                            sparc_ncpus > 1 && off < sizeof(struct cpu_info);
!                            va += NBPG, off += NBPG) {
!                               paddr_t pa =
!                                   PMAP_BOOTSTRAP_VA2PA(CPUINFO_VA + off);
! 
!                               prom_printf("going to pmap_kenter_pa"
!                                           "(va=%p, pa=%p)\n", va, pa);
!                               pmap_kremove(va, NBPG);
!                               pmap_kenter_pa(va, pa
! #if defined(PMAP_UNCACHE_CPUINFO)
!                                                     | PMAP_NC
! #endif
!                                              , VM_PROT_READ | VM_PROT_WRITE);
!                       }
! 
!               } else
!                       memset((void *)cpuinfo_va, 0, sizeof(struct cpu_info));
! 
!               cpus[i] = (struct cpu_info *)cpuinfo_va;
                cpus[i]->ci_self = cpus[i];
                prom_printf("set cpu%d ci_self address: %p\n", i, cpus[i]);
+ 
+               /* Unmap and prepare to return unused pages */
+               if (cpuinfo_va != sva) {
+                       cpus[i]->ci_free_sva1 = sva;
+                       cpus[i]->ci_free_eva1 = cpuinfo_va;
+                       for (va = cpus[i]->ci_free_sva1;
+                            va < cpus[i]->ci_free_eva1;
+                            va += NBPG)
+                               setpte4m(va, 0);
+               }
+               if (cpuinfo_va + sz != sva + cpuinfo_len) {
+                       cpus[i]->ci_free_sva2 = cpuinfo_va + sz;
+                       cpus[i]->ci_free_eva2 = sva + cpuinfo_len;
+                       for (va = cpus[i]->ci_free_sva2;
+                            va < cpus[i]->ci_free_eva2;
+                            va += NBPG)
+                               setpte4m(va, 0);
+               }
        }
  #else
        cpus[0] = (struct cpu_info *)CPUINFO_VA;
*************** pmap_alloc_cpu(struct cpu_info *sc)
*** 3984,3990 ****
                 ((u_long)pagtable_pa >> SRMMU_PPNPASHIFT) | SRMMU_TEPTD);
        setpgt4m(&pagtable[vpg],
                (VA2PA((void *)sc) >> SRMMU_PPNPASHIFT) |
!               (SRMMU_TEPTE | PPROT_N_RWX | SRMMU_PG_C));
  
        /* Install this CPU's context table */
        sc->ctx_tbl = ctxtable;
--- 4061,4071 ----
                 ((u_long)pagtable_pa >> SRMMU_PPNPASHIFT) | SRMMU_TEPTD);
        setpgt4m(&pagtable[vpg],
                (VA2PA((void *)sc) >> SRMMU_PPNPASHIFT) |
!               (SRMMU_TEPTE | PPROT_N_RWX
! #if !defined(PMAP_UNCACHE_CPUINFO)
!                                          | SRMMU_PG_C
! #endif
!               ));
  
        /* Install this CPU's context table */
        sc->ctx_tbl = ctxtable;


Home | Main Index | Thread Index | Old Index