Source-Changes-HG archive

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

[src/sommerfeld_i386mp_1]: src/sys/arch/i386/i386 MP: assorted changes to cpu...



details:   https://anonhg.NetBSD.org/src/rev/b0aa9e261ddc
branches:  sommerfeld_i386mp_1
changeset: 482169:b0aa9e261ddc
user:      sommerfeld <sommerfeld%NetBSD.org@localhost>
date:      Sun Feb 20 18:01:05 2000 +0000

description:
MP: assorted changes to cpu identification code.
IDT vector allocation.
split out various things which need to happen per-CPU or per-idle-PCB so
they can be called on aux processors at an appropriate time.

diffstat:

 sys/arch/i386/i386/machdep.c |  204 ++++++++++++++++++++++++++++++++++--------
 1 files changed, 165 insertions(+), 39 deletions(-)

diffs (truncated from 400 to 300 lines):

diff -r 03d3fbcff62e -r b0aa9e261ddc sys/arch/i386/i386/machdep.c
--- a/sys/arch/i386/i386/machdep.c      Sun Feb 20 17:55:13 2000 +0000
+++ b/sys/arch/i386/i386/machdep.c      Sun Feb 20 18:01:05 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: machdep.c,v 1.376 2000/02/04 14:21:33 minoura Exp $    */
+/*     $NetBSD: machdep.c,v 1.376.2.1 2000/02/20 18:01:05 sommerfeld Exp $     */
 
 /*-
  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@@ -119,6 +119,7 @@
 
 #include <machine/cpu.h>
 #include <machine/cpufunc.h>
+#include <machine/cpuvar.h>
 #include <machine/gdt.h>
 #include <machine/pio.h>
 #include <machine/psl.h>
@@ -198,6 +199,10 @@
 extern paddr_t avail_start, avail_end;
 extern paddr_t hole_start, hole_end;
 
+void (*delay_func) __P((int)) = i8254_delay;
+void (*microtime_func) __P((struct timeval *)) = i8254_microtime;
+void (*initclock_func) __P((void)) = i8254_initclocks;
+
 /*
  * Size of memory segments, before any memory is stolen.
  */
@@ -208,7 +213,6 @@
 int    cpu_dumpsize __P((void));
 u_long cpu_dump_mempagecnt __P((void));
 void   dumpsys __P((void));
-void   identifycpu __P((void));
 void   init386 __P((paddr_t));
 
 #ifdef COMPAT_NOMID
@@ -262,8 +266,6 @@
        initmsgbuf((caddr_t)msgbuf_vaddr, round_page(MSGBUFSIZE));
 
        printf(version);
-       identifycpu();
-
        format_bytes(pbuf, sizeof(pbuf), ctob(physmem));
        printf("total memory = %s\n", pbuf);
 
@@ -367,10 +369,31 @@
 i386_proc0_tss_ldt_init()
 {
        struct pcb *pcb;
-       int x;
 
        gdt_init();
        curpcb = pcb = &proc0.p_addr->u_pcb;
+
+       pcb->pcb_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL);
+       pcb->pcb_tss.tss_esp0 = (int)proc0.p_addr + USPACE - 16;
+
+       i386_init_pcb_tss_ldt(pcb);
+       
+       ltr(pcb->pcb_tss_sel);
+       lldt(pcb->pcb_ldt_sel);
+
+       proc0.p_md.md_regs = (struct trapframe *)pcb->pcb_tss.tss_esp0 - 1;
+}
+
+/*
+ * Set up TSS and LDT for a new PCB.
+ */
+
+void
+i386_init_pcb_tss_ldt(pcb)
+       struct pcb *pcb;
+{
+       int x;
+
        pcb->pcb_flags = 0;
        pcb->pcb_tss.tss_ioopt =
            ((caddr_t)pcb->pcb_iomap - (caddr_t)&pcb->pcb_tss) << 16;
@@ -379,15 +402,10 @@
 
        pcb->pcb_ldt_sel = GSEL(GLDT_SEL, SEL_KPL);
        pcb->pcb_cr0 = rcr0();
-       pcb->pcb_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL);
-       pcb->pcb_tss.tss_esp0 = (int)proc0.p_addr + USPACE - 16;
        tss_alloc(pcb);
+}
 
-       ltr(pcb->pcb_tss_sel);
-       lldt(pcb->pcb_ldt_sel);
 
-       proc0.p_md.md_regs = (struct trapframe *)pcb->pcb_tss.tss_esp0 - 1;
-}
 
 /*
  * XXX Finish up the deferred buffer cache allocation and initialization.
@@ -652,17 +670,32 @@
        cyrix_write_reg(0xC3, cyrix_read_reg(0xC3) & ~0x10);
 }
 
+/*
+ * Print identification for the given CPU.
+ * XXX XXX
+ * This is not as clean as one might like, because it references
+ *
+ * the "cpuid_level" and "cpu_vendor" globals.
+ * cpuid_level isn't so bad, since both CPU's will hopefully
+ * be of the same level.
+ *
+ * The Intel multiprocessor spec doesn't give us the cpu_vendor
+ * information; however, the chance of multi-vendor SMP actually
+ * ever *working* is sufficiently low that it's probably safe to assume
+ * all processors are of the same vendor.
+ */
+ 
 void
-identifycpu()
+identifycpu(ci)
+       struct cpu_info *ci;
 {
        extern char cpu_vendor[];
-       extern int cpu_id;
        const char *name, *modifier, *vendorname;
        int class = CPUCLASS_386, vendor, i, max;
        int family, model, step, modif;
        struct cpu_cpuid_nameclass *cpup = NULL;
-       void (*cpu_setup) __P((void));
-
+       char *cpuname = ci->ci_dev.dv_xname;
+       
        if (cpuid_level == -1) {
 #ifdef DIAGNOSTIC
                if (cpu < 0 || cpu >=
@@ -673,19 +706,19 @@
                vendor = i386_nocpuid_cpus[cpu].cpu_vendor;
                vendorname = i386_nocpuid_cpus[cpu].cpu_vendorname;
                class = i386_nocpuid_cpus[cpu].cpu_class;
-               cpu_setup = i386_nocpuid_cpus[cpu].cpu_setup;
+               ci->cpu_setup = i386_nocpuid_cpus[cpu].cpu_setup;
                modifier = "";
        } else {
                max = sizeof (i386_cpuid_cpus) / sizeof (i386_cpuid_cpus[0]);
-               modif = (cpu_id >> 12) & 3;
-               family = (cpu_id >> 8) & 15;
+               modif = (ci->ci_signature >> 12) & 0x3;
+               family = (ci->ci_signature >> 8) & 0xf;
                if (family < CPU_MINFAMILY)
                        panic("identifycpu: strange family value");
-               model = (cpu_id >> 4) & 15;
-               step = cpu_id & 15;
+               model = (ci->ci_signature >> 4) & 0xf;
+               step = ci->ci_signature & 0xf;
 #ifdef CPUDEBUG
-               printf("cpu0: family %x model %x step %x\n", family, model,
-                       step);
+               printf("%s: family %x model %x step %x\n", cpuname, family, 
+                       model, step);
 #endif
 
                for (i = 0; i < max; i++) {
@@ -707,7 +740,7 @@
                        class = family - 3;
                        modifier = "";
                        name = "";
-                       cpu_setup = NULL;
+                       ci->cpu_setup = NULL;
                } else {
                        vendor = cpup->cpu_vendor;
                        vendorname = cpup->cpu_vendorname;
@@ -722,16 +755,27 @@
                        if (name == NULL)
                            name = cpup->cpu_family[i].cpu_models[CPU_DEFMODEL];
                        class = cpup->cpu_family[i].cpu_class;
-                       cpu_setup = cpup->cpu_family[i].cpu_setup;
+                       ci->cpu_setup = cpup->cpu_family[i].cpu_setup;
                }
        }
 
        sprintf(cpu_model, "%s %s%s (%s-class)", vendorname, modifier, name,
                classnames[class]);
-       printf("cpu0: %s\n", cpu_model);
+       printf("%s: %s\n", cpuname, cpu_model);
 
+       if (ci->ci_feature_flags) {
+               char buf[1024];
+               bitmask_snprintf(ci->ci_feature_flags, CPUID_FLAGS1,
+                   buf, sizeof(buf));
+               printf("%s: features %s\n", cpuname, buf);
+               bitmask_snprintf(ci->ci_feature_flags, CPUID_FLAGS2,
+                   buf, sizeof(buf));
+               printf("%s: features %s\n", cpuname, buf);
+       }
+       
        cpu_class = class;
-
+       ci->cpu_class = class;
+       
        /*
         * Now that we have told the user what they have,
         * let them know if that machine type isn't configured.
@@ -776,9 +820,6 @@
                break;
        }
 
-       /* configure the CPU if needed */
-       if (cpu_setup != NULL)
-               cpu_setup();
        if (cpu == CPU_486DLC) {
 #ifndef CYRIX_CACHE_WORKS
                printf("WARNING: CYRIX 486DLC CACHE UNCHANGED.\n");
@@ -790,14 +831,6 @@
 #endif
 #endif
        }
-
-#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU)
-       /*
-        * On a 486 or above, enable ring 0 write protection.
-        */
-       if (cpu_class >= CPUCLASS_486)
-               lcr0(rcr0() | CR0_WP);
-#endif
 }
 
 /*  
@@ -1461,6 +1494,21 @@
 }
 
 void
+unsetgate(gd)
+       struct gate_descriptor *gd;
+{
+       gd->gd_p = 0;
+       gd->gd_hioffset = 0;
+       gd->gd_looffset = 0;
+       gd->gd_selector = 0;
+       gd->gd_xx = 0;
+       gd->gd_stkcpy = 0;
+       gd->gd_type = 0;
+       gd->gd_dpl = 0;
+}
+
+
+void
 setregion(rd, base, limit)
        struct region_descriptor *rd;
        void *base;
@@ -1500,6 +1548,17 @@
 extern vector IDTVEC(svr4_fasttrap);
 #endif /* COMPAT_SVR4 */
 
+void cpu_init_idt()
+{
+       struct region_descriptor region;
+#ifdef I586_CPU
+       setregion(&region, pentium_idt, NIDT * sizeof(idt[0]) - 1);
+#else
+       setregion(&region, idt, NIDT * sizeof(idt[0]) - 1);
+#endif
+        lidt(&region);
+}
+
 void
 init386(first_avail)
        vaddr_t first_avail;
@@ -1552,6 +1611,11 @@
        }
 #endif
 
+#ifdef MULTIPROCESSOR
+       /* leave room for bioscall just to avoid too much chaos */
+       avail_start = 4*NBPG;   /* save us a page for trampoline code and
+                                one additional PT page! */
+#else
 #if NBIOSCALL > 0
        avail_start = 3*NBPG;   /* save us a page for trampoline code and
                                 one additional PT page! */
@@ -1559,6 +1623,7 @@
        avail_start = NBPG;     /* BIOS leaves data in low memory */
                                /* and VM system doesn't work with phys 0 */
 #endif
+#endif
        avail_end = IOM_END + trunc_page(biosextmem * 1024);
 
        hole_start = trunc_page(biosbasemem * 1024);
@@ -1568,7 +1633,7 @@
        /* Call pmap initialization to make new kernel address space. */
        pmap_bootstrap((vaddr_t)atdevbase + IOM_SIZE);
 
-#if NBIOSCALL > 0
+#if NBIOSCALL > 0 || defined(MULTIPROCESSOR)
        /* install page 2 (reserved above) as PT page for first 4M */
        pmap_enter(pmap_kernel(), (u_long)vtopte(0), 2*NBPG,
            VM_PROT_READ|VM_PROT_WRITE, PMAP_WIRED|VM_PROT_READ|VM_PROT_WRITE);
@@ -1578,11 +1643,13 @@
        pmap_enter(pmap_kernel(), idt_vaddr, idt_paddr,
            VM_PROT_READ|VM_PROT_WRITE, PMAP_WIRED|VM_PROT_READ|VM_PROT_WRITE);
        idt = (union descriptor *)idt_vaddr;
+       
 #ifdef I586_CPU
        pmap_enter(pmap_kernel(), pentium_idt_vaddr, idt_paddr,



Home | Main Index | Thread Index | Old Index