Author: marcel
Date: Sat Dec 12 05:14:40 2009
New Revision: 200431
URL: http://svn.freebsd.org/changeset/base/200431

Log:
  MFC rev 199893, 199941, 200200 and 200207:
  o   Eliminate MAXCPU.
  o   Revamp the PCPU structure.

Modified:
  stable/8/sys/ia64/ia64/clock.c
  stable/8/sys/ia64/ia64/genassym.c
  stable/8/sys/ia64/ia64/interrupt.c
  stable/8/sys/ia64/ia64/machdep.c
  stable/8/sys/ia64/ia64/mp_machdep.c
  stable/8/sys/ia64/ia64/pmap.c
  stable/8/sys/ia64/include/kdb.h
  stable/8/sys/ia64/include/param.h
  stable/8/sys/ia64/include/pcpu.h
  stable/8/sys/ia64/include/pmap.h
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/ia64/ia64/clock.c
==============================================================================
--- stable/8/sys/ia64/ia64/clock.c      Sat Dec 12 04:50:04 2009        
(r200430)
+++ stable/8/sys/ia64/ia64/clock.c      Sat Dec 12 05:14:40 2009        
(r200431)
@@ -64,9 +64,9 @@ void
 pcpu_initclock(void)
 {
 
-       PCPU_SET(clockadj, 0);
-       PCPU_SET(clock, ia64_get_itc());
-       ia64_set_itm(PCPU_GET(clock) + ia64_clock_reload);
+       PCPU_SET(md.clockadj, 0);
+       PCPU_SET(md.clock, ia64_get_itc());
+       ia64_set_itm(PCPU_GET(md.clock) + ia64_clock_reload);
        ia64_set_itv(CLOCK_VECTOR);     /* highest priority class */
        ia64_srlz_d();
 }

Modified: stable/8/sys/ia64/ia64/genassym.c
==============================================================================
--- stable/8/sys/ia64/ia64/genassym.c   Sat Dec 12 04:50:04 2009        
(r200430)
+++ stable/8/sys/ia64/ia64/genassym.c   Sat Dec 12 05:14:40 2009        
(r200431)
@@ -91,7 +91,7 @@ ASSYM(MC_SPECIAL_RNAT,        offsetof(mcontext
 ASSYM(PAGE_SHIFT,      PAGE_SHIFT);
 ASSYM(PAGE_SIZE,       PAGE_SIZE);
 
-ASSYM(PC_CURRENT_PMAP, offsetof(struct pcpu, pc_current_pmap));
+ASSYM(PC_CURRENT_PMAP, offsetof(struct pcpu, pc_md.current_pmap));
 ASSYM(PC_CURTHREAD,    offsetof(struct pcpu, pc_curthread));
 ASSYM(PC_IDLETHREAD,   offsetof(struct pcpu, pc_idlethread));
 

Modified: stable/8/sys/ia64/ia64/interrupt.c
==============================================================================
--- stable/8/sys/ia64/ia64/interrupt.c  Sat Dec 12 04:50:04 2009        
(r200430)
+++ stable/8/sys/ia64/ia64/interrupt.c  Sat Dec 12 05:14:40 2009        
(r200431)
@@ -84,28 +84,6 @@ dummy_perf(unsigned long vector, struct 
 
 void (*perf_irq)(unsigned long, struct trapframe *) = dummy_perf;
 
-static unsigned int ints[MAXCPU];
-SYSCTL_OPAQUE(_debug, OID_AUTO, ints, CTLFLAG_RW, &ints, sizeof(ints), "IU",
-    "");
-
-static unsigned int clks[MAXCPU];
-#ifdef SMP
-SYSCTL_OPAQUE(_debug, OID_AUTO, clks, CTLFLAG_RW, &clks, sizeof(clks), "IU",
-    "");
-#else
-SYSCTL_INT(_debug, OID_AUTO, clks, CTLFLAG_RW, clks, 0, "");
-#endif
-
-#ifdef SMP
-static unsigned int asts[MAXCPU];
-SYSCTL_OPAQUE(_debug, OID_AUTO, asts, CTLFLAG_RW, &asts, sizeof(asts), "IU",
-    "");
-
-static unsigned int rdvs[MAXCPU];
-SYSCTL_OPAQUE(_debug, OID_AUTO, rdvs, CTLFLAG_RW, &rdvs, sizeof(rdvs), "IU",
-    "");
-#endif
-
 SYSCTL_NODE(_debug, OID_AUTO, clock, CTLFLAG_RW, 0, "clock statistics");
 
 static int adjust_edges = 0;
@@ -139,6 +117,8 @@ interrupt(struct trapframe *tf)
 
        td = curthread;
 
+       PCPU_INC(cnt.v_intr);
+
        vector = tf->tf_special.ifa;
 
  next:
@@ -149,33 +129,35 @@ interrupt(struct trapframe *tf)
         * to add it to this switch-like construct.
         */
        if (vector == 0) {
+               PCPU_INC(md.stats.pcs_nextints);
                inta = ib->ib_inta;
-               printf("ExtINT interrupt: vector=%u\n", (int)inta);
                if (inta == 15) {
+                       PCPU_INC(md.stats.pcs_nstrays);
                        __asm __volatile("mov cr.eoi = r0;; srlz.d");
                        goto stray;
                }
                vector = (int)inta;
-       } else if (vector == 15)
+       } else if (vector == 15) {
+               PCPU_INC(md.stats.pcs_nstrays);
                goto stray;
+       }
 
        if (vector == CLOCK_VECTOR) {/* clock interrupt */
                /* CTR0(KTR_INTR, "clock interrupt"); */
 
                itc = ia64_get_itc();
 
-               PCPU_INC(cnt.v_intr);
+               PCPU_INC(md.stats.pcs_nclks);
 #ifdef EVCNT_COUNTERS
                clock_intr_evcnt.ev_count++;
 #else
                intrcnt[INTRCNT_CLOCK]++;
 #endif
-               clks[PCPU_GET(cpuid)]++;
 
                critical_enter();
 
-               adj = PCPU_GET(clockadj);
-               clk = PCPU_GET(clock);
+               adj = PCPU_GET(md.clockadj);
+               clk = PCPU_GET(md.clock);
                delta = itc - clk;
                count = 0;
                while (delta >= ia64_clock_reload) {
@@ -206,33 +188,36 @@ interrupt(struct trapframe *tf)
                        adj = 0;
                        adjust_excess++;
                }
-               PCPU_SET(clock, clk);
-               PCPU_SET(clockadj, adj);
+               PCPU_SET(md.clock, clk);
+               PCPU_SET(md.clockadj, adj);
                critical_exit();
                ia64_srlz_d();
 
 #ifdef SMP
        } else if (vector == ipi_vector[IPI_AST]) {
-               asts[PCPU_GET(cpuid)]++;
+               PCPU_INC(md.stats.pcs_nasts);
                CTR1(KTR_SMP, "IPI_AST, cpuid=%d", PCPU_GET(cpuid));
        } else if (vector == ipi_vector[IPI_HIGH_FP]) {
+               PCPU_INC(md.stats.pcs_nhighfps);
                ia64_highfp_save_ipi();
        } else if (vector == ipi_vector[IPI_RENDEZVOUS]) {
-               rdvs[PCPU_GET(cpuid)]++;
+               PCPU_INC(md.stats.pcs_nrdvs);
                CTR1(KTR_SMP, "IPI_RENDEZVOUS, cpuid=%d", PCPU_GET(cpuid));
                enable_intr();
                smp_rendezvous_action();
                disable_intr();
        } else if (vector == ipi_vector[IPI_STOP]) {
+               PCPU_INC(md.stats.pcs_nstops);
                cpumask_t mybit = PCPU_GET(cpumask);
 
-               savectx(PCPU_PTR(pcb));
+               savectx(PCPU_PTR(md.pcb));
                atomic_set_int(&stopped_cpus, mybit);
                while ((started_cpus & mybit) == 0)
                        cpu_spinwait();
                atomic_clear_int(&started_cpus, mybit);
                atomic_clear_int(&stopped_cpus, mybit);
        } else if (vector == ipi_vector[IPI_PREEMPT]) {
+               PCPU_INC(md.stats.pcs_npreempts);
                CTR1(KTR_SMP, "IPI_PREEMPT, cpuid=%d", PCPU_GET(cpuid));
                __asm __volatile("mov cr.eoi = r0;; srlz.d");
                enable_intr();
@@ -241,7 +226,7 @@ interrupt(struct trapframe *tf)
                goto stray;
 #endif
        } else {
-               ints[PCPU_GET(cpuid)]++;
+               PCPU_INC(md.stats.pcs_nhwints);
                atomic_add_int(&td->td_intr_nesting_level, 1);
                ia64_dispatch_intr(tf, vector);
                atomic_subtract_int(&td->td_intr_nesting_level, 1);

Modified: stable/8/sys/ia64/ia64/machdep.c
==============================================================================
--- stable/8/sys/ia64/ia64/machdep.c    Sat Dec 12 04:50:04 2009        
(r200430)
+++ stable/8/sys/ia64/ia64/machdep.c    Sat Dec 12 05:14:40 2009        
(r200431)
@@ -101,6 +101,8 @@ __FBSDID("$FreeBSD$");
 
 #include <i386/include/specialreg.h>
 
+SYSCTL_NODE(_machdep, OID_AUTO, cpu, CTLFLAG_RD, 0, "");
+
 u_int64_t processor_frequency;
 u_int64_t bus_frequency;
 u_int64_t itc_frequency;
@@ -139,8 +141,6 @@ SYSCTL_STRING(_hw, OID_AUTO, family, CTL
 extern vm_offset_t ksym_start, ksym_end;
 #endif
 
-static void cpu_startup(void *);
-SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL);
 
 struct msgbuf *msgbufp = NULL;
 
@@ -247,9 +247,11 @@ identifycpu(void)
 }
 
 static void
-cpu_startup(dummy)
-       void *dummy;
+cpu_startup(void *dummy)
 {
+       char nodename[16];
+       struct pcpu *pc;
+       struct pcpu_stats *pcs;
 
        /*
         * Good {morning,afternoon,evening,night}.
@@ -302,7 +304,68 @@ cpu_startup(dummy)
         */
        ia64_probe_sapics();
        ia64_mca_init();
+
+       /*
+        * Create sysctl tree for per-CPU information.
+        */
+       SLIST_FOREACH(pc, &cpuhead, pc_allcpu) {
+               snprintf(nodename, sizeof(nodename), "%u", pc->pc_cpuid);
+               sysctl_ctx_init(&pc->pc_md.sysctl_ctx);
+               pc->pc_md.sysctl_tree = SYSCTL_ADD_NODE(&pc->pc_md.sysctl_ctx,
+                   SYSCTL_STATIC_CHILDREN(_machdep_cpu), OID_AUTO, nodename,
+                   CTLFLAG_RD, NULL, "");
+               if (pc->pc_md.sysctl_tree == NULL)
+                       continue;
+
+               pcs = &pc->pc_md.stats;
+
+               SYSCTL_ADD_ULONG(&pc->pc_md.sysctl_ctx,
+                   SYSCTL_CHILDREN(pc->pc_md.sysctl_tree), OID_AUTO,
+                   "nasts", CTLFLAG_RD, &pcs->pcs_nasts,
+                   "Number of IPI_AST interrupts");
+
+               SYSCTL_ADD_ULONG(&pc->pc_md.sysctl_ctx,
+                   SYSCTL_CHILDREN(pc->pc_md.sysctl_tree), OID_AUTO,
+                   "nclks", CTLFLAG_RD, &pcs->pcs_nclks,
+                   "Number of clock interrupts");
+
+               SYSCTL_ADD_ULONG(&pc->pc_md.sysctl_ctx,
+                   SYSCTL_CHILDREN(pc->pc_md.sysctl_tree), OID_AUTO,
+                   "nextints", CTLFLAG_RD, &pcs->pcs_nextints,
+                   "Number of ExtINT interrupts");
+
+               SYSCTL_ADD_ULONG(&pc->pc_md.sysctl_ctx,
+                   SYSCTL_CHILDREN(pc->pc_md.sysctl_tree), OID_AUTO,
+                   "nhighfps", CTLFLAG_RD, &pcs->pcs_nhighfps,
+                   "Number of IPI_HIGH_FP interrupts");
+
+               SYSCTL_ADD_ULONG(&pc->pc_md.sysctl_ctx,
+                   SYSCTL_CHILDREN(pc->pc_md.sysctl_tree), OID_AUTO,
+                   "nhwints", CTLFLAG_RD, &pcs->pcs_nhwints,
+                   "Number of hardware (device) interrupts");
+
+               SYSCTL_ADD_ULONG(&pc->pc_md.sysctl_ctx,
+                   SYSCTL_CHILDREN(pc->pc_md.sysctl_tree), OID_AUTO,
+                   "npreempts", CTLFLAG_RD, &pcs->pcs_npreempts,
+                   "Number of IPI_PREEMPT interrupts");
+
+               SYSCTL_ADD_ULONG(&pc->pc_md.sysctl_ctx,
+                   SYSCTL_CHILDREN(pc->pc_md.sysctl_tree), OID_AUTO,
+                   "nrdvs", CTLFLAG_RD, &pcs->pcs_nrdvs,
+                   "Number of IPI_RENDEZVOUS interrupts");
+
+               SYSCTL_ADD_ULONG(&pc->pc_md.sysctl_ctx,
+                   SYSCTL_CHILDREN(pc->pc_md.sysctl_tree), OID_AUTO,
+                   "nstops", CTLFLAG_RD, &pcs->pcs_nstops,
+                   "Number of IPI_STOP interrupts");
+
+               SYSCTL_ADD_ULONG(&pc->pc_md.sysctl_ctx,
+                   SYSCTL_CHILDREN(pc->pc_md.sysctl_tree), OID_AUTO,
+                   "nstrays", CTLFLAG_RD, &pcs->pcs_nstrays,
+                   "Number of stray vectors");
+       }
 }
+SYSINIT(cpu_startup, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL);
 
 void
 cpu_boot(int howto)

Modified: stable/8/sys/ia64/ia64/mp_machdep.c
==============================================================================
--- stable/8/sys/ia64/ia64/mp_machdep.c Sat Dec 12 04:50:04 2009        
(r200430)
+++ stable/8/sys/ia64/ia64/mp_machdep.c Sat Dec 12 05:14:40 2009        
(r200431)
@@ -76,7 +76,6 @@ void ia64_ap_startup(void);
 /* Variables used by os_boot_rendez and ia64_ap_startup */
 struct pcpu *ap_pcpu;
 void *ap_stack;
-uint64_t ap_vhpt;
 volatile int ap_delay;
 volatile int ap_awake;
 volatile int ap_spin;
@@ -116,13 +115,15 @@ void
 ia64_ap_startup(void)
 {
        volatile struct ia64_interrupt_block *ib = IA64_INTERRUPT_BLOCK;
+       uint64_t vhpt;
        int vector;
 
        pcpup = ap_pcpu;
        ia64_set_k4((intptr_t)pcpup);
 
-       map_vhpt(ap_vhpt);
-       ia64_set_pta(ap_vhpt + (1 << 8) + (pmap_vhpt_log2size << 2) + 1);
+       vhpt = PCPU_GET(md.vhpt);
+       map_vhpt(vhpt);
+       ia64_set_pta(vhpt + (1 << 8) + (pmap_vhpt_log2size << 2) + 1);
        ia64_srlz_i();
 
        ap_awake = 1;
@@ -225,7 +226,7 @@ cpu_mp_add(u_int acpiid, u_int apicid, u
                pc = pcpup;
 
        pc->pc_acpi_id = acpiid;
-       pc->pc_lid = lid;
+       pc->pc_md.lid = lid;
        all_cpus |= (1UL << cpuid);
 }
 
@@ -239,8 +240,8 @@ cpu_mp_announce()
                pc = pcpu_find(i);
                if (pc != NULL) {
                        printf("cpu%d: ACPI Id=%x, SAPIC Id=%x, SAPIC Eid=%x",
-                           i, pc->pc_acpi_id, LID_SAPIC_ID(pc->pc_lid),
-                           LID_SAPIC_EID(pc->pc_lid));
+                           i, pc->pc_acpi_id, LID_SAPIC_ID(pc->pc_md.lid),
+                           LID_SAPIC_EID(pc->pc_md.lid));
                        if (i == 0)
                                printf(" (BSP)\n");
                        else
@@ -257,13 +258,18 @@ cpu_mp_start()
        ap_spin = 1;
 
        SLIST_FOREACH(pc, &cpuhead, pc_allcpu) {
-               pc->pc_current_pmap = kernel_pmap;
+               pc->pc_md.current_pmap = kernel_pmap;
                pc->pc_other_cpus = all_cpus & ~pc->pc_cpumask;
                if (pc->pc_cpuid > 0) {
                        ap_pcpu = pc;
+                       pc->pc_md.vhpt = pmap_alloc_vhpt();
+                       if (pc->pc_md.vhpt == 0) {
+                               printf("SMP: WARNING: unable to allocate VHPT"
+                                   " for cpu%d", pc->pc_cpuid);
+                               continue;
+                       }
                        ap_stack = malloc(KSTACK_PAGES * PAGE_SIZE, M_SMP,
                            M_WAITOK);
-                       ap_vhpt = pmap_vhpt_base[pc->pc_cpuid];
                        ap_delay = 2000;
                        ap_awake = 0;
 
@@ -275,13 +281,13 @@ cpu_mp_start()
                        do {
                                DELAY(1000);
                        } while (--ap_delay > 0);
-                       pc->pc_awake = ap_awake;
+                       pc->pc_md.awake = ap_awake;
 
                        if (!ap_awake)
                                printf("SMP: WARNING: cpu%d did not wake up\n",
                                    pc->pc_cpuid);
                } else
-                       pc->pc_awake = 1;
+                       pc->pc_md.awake = 1;
        }
 }
 
@@ -298,7 +304,7 @@ cpu_mp_unleash(void *dummy)
        smp_cpus = 0;
        SLIST_FOREACH(pc, &cpuhead, pc_allcpu) {
                cpus++;
-               if (pc->pc_awake) {
+               if (pc->pc_md.awake) {
                        kproc_create(ia64_store_mca_state,
                            (void*)((uintptr_t)pc->pc_cpuid), NULL, 0, 0,
                            "mca %u", pc->pc_cpuid);
@@ -361,7 +367,7 @@ ipi_send(struct pcpu *cpu, int ipi)
        uint64_t vector;
 
        pipi = __MEMIO_ADDR(ia64_lapic_address |
-           ((cpu->pc_lid & LID_SAPIC_MASK) >> 12));
+           ((cpu->pc_md.lid & LID_SAPIC_MASK) >> 12));
        vector = (uint64_t)(ipi_vector[ipi] & 0xff);
        KASSERT(vector != 0, ("IPI %d is not assigned a vector", ipi));
        *pipi = vector;

Modified: stable/8/sys/ia64/ia64/pmap.c
==============================================================================
--- stable/8/sys/ia64/ia64/pmap.c       Sat Dec 12 04:50:04 2009        
(r200430)
+++ stable/8/sys/ia64/ia64/pmap.c       Sat Dec 12 05:14:40 2009        
(r200431)
@@ -217,8 +217,6 @@ int pmap_vhpt_nbuckets;
 SYSCTL_INT(_machdep_vhpt, OID_AUTO, nbuckets, CTLFLAG_RD,
     &pmap_vhpt_nbuckets, 0, "");
 
-uint64_t pmap_vhpt_base[MAXCPU];
-
 int pmap_vhpt_log2size = 0;
 TUNABLE_INT("machdep.vhpt.log2size", &pmap_vhpt_log2size);
 SYSCTL_INT(_machdep_vhpt, OID_AUTO, log2size, CTLFLAG_RD,
@@ -277,6 +275,40 @@ pmap_steal_memory(vm_size_t size)
        return va;
 }
 
+static void
+pmap_initialize_vhpt(vm_offset_t vhpt)
+{
+       struct ia64_lpte *pte;
+       u_int i;
+
+       pte = (struct ia64_lpte *)vhpt;
+       for (i = 0; i < pmap_vhpt_nbuckets; i++) {
+               pte[i].pte = 0;
+               pte[i].itir = 0;
+               pte[i].tag = 1UL << 63; /* Invalid tag */
+               pte[i].chain = (uintptr_t)(pmap_vhpt_bucket + i);
+       }
+}
+
+#ifdef SMP
+MALLOC_DECLARE(M_SMP);
+
+vm_offset_t
+pmap_alloc_vhpt(void)
+{
+       vm_offset_t vhpt;
+       vm_size_t size;
+
+       size = 1UL << pmap_vhpt_log2size;
+       vhpt = (uintptr_t)contigmalloc(size, M_SMP, 0, 0UL, ~0UL, size, 0UL);
+       if (vhpt != 0) {
+               vhpt = IA64_PHYS_TO_RR7(ia64_tpa(vhpt));
+               pmap_initialize_vhpt(vhpt);
+       }
+       return (vhpt);
+}
+#endif
+
 /*
  *     Bootstrap the system enough to run with virtual memory.
  */
@@ -284,8 +316,7 @@ void
 pmap_bootstrap()
 {
        struct ia64_pal_result res;
-       struct ia64_lpte *pte;
-       vm_offset_t base, limit;
+       vm_offset_t base;
        size_t size;
        int i, j, count, ridbits;
 
@@ -365,94 +396,52 @@ pmap_bootstrap()
                ;
        count = i+2;
 
-       /*
-        * Figure out a useful size for the VHPT, based on the size of
-        * physical memory and try to locate a region which is large
-        * enough to contain the VHPT (which must be a power of two in
-        * size and aligned to a natural boundary).
-        * We silently bump up the VHPT size to the minimum size if the
-        * user has set the tunable too small. Likewise, the VHPT size
-        * is silently capped to the maximum allowed.
-        */
        TUNABLE_INT_FETCH("machdep.vhpt.log2size", &pmap_vhpt_log2size);
-       if (pmap_vhpt_log2size == 0) {
-               pmap_vhpt_log2size = 15;
-               size = 1UL << pmap_vhpt_log2size;
-               while (size < Maxmem * 32) {
-                       pmap_vhpt_log2size++;
-                       size <<= 1;
-               }
-       } else if (pmap_vhpt_log2size < 15)
+       if (pmap_vhpt_log2size == 0)
+               pmap_vhpt_log2size = 20;
+       else if (pmap_vhpt_log2size < 15)
                pmap_vhpt_log2size = 15;
-       if (pmap_vhpt_log2size > 61)
+       else if (pmap_vhpt_log2size > 61)
                pmap_vhpt_log2size = 61;
 
-       pmap_vhpt_base[0] = 0;
-       base = limit = 0;
+       base = 0;
        size = 1UL << pmap_vhpt_log2size;
-       while (pmap_vhpt_base[0] == 0) {
-               if (bootverbose)
-                       printf("Trying VHPT size 0x%lx\n", size);
-               for (i = 0; i < count; i += 2) {
-                       base = (phys_avail[i] + size - 1) & ~(size - 1);
-                       limit = base + MAXCPU * size;
-                       if (limit <= phys_avail[i+1])
-                               /*
-                                * VHPT can fit in this region
-                                */
-                               break;
-               }
-               if (!phys_avail[i]) {
-                       /* Can't fit, try next smaller size. */
-                       pmap_vhpt_log2size--;
-                       size >>= 1;
-               } else
-                       pmap_vhpt_base[0] = IA64_PHYS_TO_RR7(base);
+       for (i = 0; i < count; i += 2) {
+               base = (phys_avail[i] + size - 1) & ~(size - 1);
+               if (base + size <= phys_avail[i+1])
+                       break;
        }
-       if (pmap_vhpt_log2size < 15)
-               panic("Can't find space for VHPT");
-
-       if (bootverbose)
-               printf("Putting VHPT at 0x%lx\n", base);
+       if (!phys_avail[i])
+               panic("Unable to allocate VHPT");
 
        if (base != phys_avail[i]) {
                /* Split this region. */
-               if (bootverbose)
-                       printf("Splitting [%p-%p]\n", (void *)phys_avail[i],
-                           (void *)phys_avail[i+1]);
                for (j = count; j > i; j -= 2) {
                        phys_avail[j] = phys_avail[j-2];
                        phys_avail[j+1] = phys_avail[j-2+1];
                }
                phys_avail[i+1] = base;
-               phys_avail[i+2] = limit;
+               phys_avail[i+2] = base + size;
        } else
-               phys_avail[i] = limit;
+               phys_avail[i] = base + size;
 
-       pmap_vhpt_nbuckets = size / sizeof(struct ia64_lpte);
+       base = IA64_PHYS_TO_RR7(base);
+       PCPU_SET(md.vhpt, base);
+       if (bootverbose)
+               printf("VHPT: address=%#lx, size=%#lx\n", base, size);
 
+       pmap_vhpt_nbuckets = size / sizeof(struct ia64_lpte);
        pmap_vhpt_bucket = (void *)pmap_steal_memory(pmap_vhpt_nbuckets *
            sizeof(struct ia64_bucket));
-       pte = (struct ia64_lpte *)pmap_vhpt_base[0];
        for (i = 0; i < pmap_vhpt_nbuckets; i++) {
-               pte[i].pte = 0;
-               pte[i].itir = 0;
-               pte[i].tag = 1UL << 63; /* Invalid tag */
-               pte[i].chain = (uintptr_t)(pmap_vhpt_bucket + i);
-               /* Stolen memory is zeroed! */
+               /* Stolen memory is zeroed. */
                mtx_init(&pmap_vhpt_bucket[i].mutex, "VHPT bucket lock", NULL,
                    MTX_NOWITNESS | MTX_SPIN);
        }
 
-       for (i = 1; i < MAXCPU; i++) {
-               pmap_vhpt_base[i] = pmap_vhpt_base[i - 1] + size;
-               bcopy((void *)pmap_vhpt_base[i - 1], (void *)pmap_vhpt_base[i],
-                   size);
-       }
-
-       map_vhpt(pmap_vhpt_base[0]);
-       ia64_set_pta(pmap_vhpt_base[0] + (1 << 8) +
-           (pmap_vhpt_log2size << 2) + 1);
+       pmap_initialize_vhpt(base);
+       map_vhpt(base);
+       ia64_set_pta(base + (1 << 8) + (pmap_vhpt_log2size << 2) + 1);
        ia64_srlz_i();
 
        virtual_avail = VM_MIN_KERNEL_ADDRESS;
@@ -466,7 +455,7 @@ pmap_bootstrap()
                kernel_pmap->pm_rid[i] = 0;
        kernel_pmap->pm_active = 1;
        TAILQ_INIT(&kernel_pmap->pm_pvlist);
-       PCPU_SET(current_pmap, kernel_pmap);
+       PCPU_SET(md.current_pmap, kernel_pmap);
 
        /*
         * Region 5 is mapped via the vhpt.
@@ -551,15 +540,16 @@ static void
 pmap_invalidate_page(pmap_t pmap, vm_offset_t va)
 {
        struct ia64_lpte *pte;
-       int i, vhpt_ofs;
+       struct pcpu *pc;
+       u_int vhpt_ofs;
 
-       KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(current_pmap)),
+       KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(md.current_pmap)),
                ("invalidating TLB for non-current pmap"));
 
-       vhpt_ofs = ia64_thash(va) - pmap_vhpt_base[PCPU_GET(cpuid)];
+       vhpt_ofs = ia64_thash(va) - PCPU_GET(md.vhpt);
        critical_enter();
-       for (i = 0; i < MAXCPU; i++) {
-               pte = (struct ia64_lpte *)(pmap_vhpt_base[i] + vhpt_ofs);
+       SLIST_FOREACH(pc, &cpuhead, pc_allcpu) {
+               pte = (struct ia64_lpte *)(pc->pc_md.vhpt + vhpt_ofs);
                if (pte->tag == ia64_ttag(va))
                        pte->tag = 1UL << 63;
        }
@@ -591,7 +581,7 @@ static void
 pmap_invalidate_all(pmap_t pmap)
 {
 
-       KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(current_pmap)),
+       KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(md.current_pmap)),
                ("invalidating TLB for non-current pmap"));
 
 #ifdef SMP
@@ -1172,7 +1162,7 @@ pmap_remove_pte(pmap_t pmap, struct ia64
        int error;
        vm_page_t m;
 
-       KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(current_pmap)),
+       KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(md.current_pmap)),
                ("removing pte for non-current pmap"));
 
        /*
@@ -1340,7 +1330,7 @@ pmap_remove_page(pmap_t pmap, vm_offset_
 {
        struct ia64_lpte *pte;
 
-       KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(current_pmap)),
+       KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(md.current_pmap)),
                ("removing page for non-current pmap"));
 
        pte = pmap_find_vhpt(va);
@@ -2251,7 +2241,7 @@ pmap_switch(pmap_t pm)
        int i;
 
        critical_enter();
-       prevpm = PCPU_GET(current_pmap);
+       prevpm = PCPU_GET(md.current_pmap);
        if (prevpm == pm)
                goto out;
        if (prevpm != NULL)
@@ -2268,7 +2258,7 @@ pmap_switch(pmap_t pm)
                }
                atomic_set_32(&pm->pm_active, PCPU_GET(cpumask));
        }
-       PCPU_SET(current_pmap, pm);
+       PCPU_SET(md.current_pmap, pm);
        ia64_srlz_d();
 
 out:

Modified: stable/8/sys/ia64/include/kdb.h
==============================================================================
--- stable/8/sys/ia64/include/kdb.h     Sat Dec 12 04:50:04 2009        
(r200430)
+++ stable/8/sys/ia64/include/kdb.h     Sat Dec 12 05:14:40 2009        
(r200431)
@@ -33,7 +33,7 @@
 #include <machine/frame.h>
 #include <machine/ia64_cpu.h>
 
-#define        KDB_STOPPEDPCB(pc)      (&(pc)->pc_pcb)
+#define        KDB_STOPPEDPCB(pc)      (&(pc)->pc_md.pcb)
 
 static __inline void
 kdb_cpu_clear_singlestep(void)

Modified: stable/8/sys/ia64/include/param.h
==============================================================================
--- stable/8/sys/ia64/include/param.h   Sat Dec 12 04:50:04 2009        
(r200430)
+++ stable/8/sys/ia64/include/param.h   Sat Dec 12 05:14:40 2009        
(r200431)
@@ -70,7 +70,7 @@
 #endif
 
 #if defined(SMP) || defined(KLD_MODULE)
-#define        MAXCPU          4
+#define        MAXCPU          32
 #else
 #define MAXCPU         1
 #endif

Modified: stable/8/sys/ia64/include/pcpu.h
==============================================================================
--- stable/8/sys/ia64/include/pcpu.h    Sat Dec 12 04:50:04 2009        
(r200430)
+++ stable/8/sys/ia64/include/pcpu.h    Sat Dec 12 05:14:40 2009        
(r200431)
@@ -30,16 +30,39 @@
 #ifndef        _MACHINE_PCPU_H_
 #define        _MACHINE_PCPU_H_
 
+#include <sys/sysctl.h>
 #include <machine/pcb.h>
 
+struct pcpu_stats {
+       u_long          pcs_nasts;              /* IPI_AST counter. */
+       u_long          pcs_nclks;              /* Clock interrupt counter. */
+       u_long          pcs_nextints;           /* ExtINT counter. */
+       u_long          pcs_nhighfps;           /* IPI_HIGH_FP counter. */
+       u_long          pcs_nhwints;            /* Hardware int. counter. */
+       u_long          pcs_npreempts;          /* IPI_PREEMPT counter. */
+       u_long          pcs_nrdvs;              /* IPI_RENDEZVOUS counter. */
+       u_long          pcs_nstops;             /* IPI_STOP counter. */
+       u_long          pcs_nstrays;            /* Stray interrupt counter. */
+};
+
+struct pcpu_md {
+       struct pcb      pcb;                    /* Used by IPI_STOP */
+       struct pmap     *current_pmap;          /* active pmap */
+       vm_offset_t     vhpt;                   /* Address of VHPT */
+       uint64_t        lid;                    /* local CPU ID */
+       uint64_t        clock;                  /* Clock counter. */
+       uint64_t        clockadj;               /* Clock adjust. */
+       uint32_t        awake:1;                /* CPU is awake? */
+       struct pcpu_stats stats;                /* Interrupt stats. */
+#ifdef _KERNEL
+       struct sysctl_ctx_list sysctl_ctx;
+       struct sysctl_oid *sysctl_tree;
+#endif
+};
+
 #define        PCPU_MD_FIELDS                                                  
\
-       struct pcb      pc_pcb;                 /* Used by IPI_STOP */  \
-       struct pmap     *pc_current_pmap;       /* active pmap */       \
-       uint64_t        pc_lid;                 /* local CPU ID */      \
-       uint64_t        pc_clock;               /* Clock counter. */    \
-       uint64_t        pc_clockadj;            /* Clock adjust. */     \
-       uint32_t        pc_awake:1;             /* CPU is awake? */     \
-       uint32_t        pc_acpi_id              /* ACPI CPU id. */
+       uint32_t        pc_acpi_id;             /* ACPI CPU id. */      \
+       struct pcpu_md  pc_md                   /* MD fields. */
 
 #ifdef _KERNEL
 

Modified: stable/8/sys/ia64/include/pmap.h
==============================================================================
--- stable/8/sys/ia64/include/pmap.h    Sat Dec 12 04:50:04 2009        
(r200430)
+++ stable/8/sys/ia64/include/pmap.h    Sat Dec 12 05:14:40 2009        
(r200431)
@@ -125,6 +125,7 @@ extern int pmap_vhpt_log2size;
 #define        pmap_unmapbios(va, sz)  pmap_unmapdev(va, sz)
 
 vm_offset_t pmap_steal_memory(vm_size_t);
+vm_offset_t pmap_alloc_vhpt(void);
 void   pmap_bootstrap(void);
 void   pmap_kenter(vm_offset_t va, vm_offset_t pa);
 vm_paddr_t pmap_kextract(vm_offset_t va);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to