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 Significant rewrite of slave CPU...



details:   https://anonhg.NetBSD.org/src/rev/bb7f115bf468
branches:  sommerfeld_i386mp_1
changeset: 482365:bb7f115bf468
user:      sommerfeld <sommerfeld%NetBSD.org@localhost>
date:      Wed Jan 10 04:38:31 2001 +0000

description:
Significant rewrite of slave CPU attach and initialization, centering
on identifycpu() and spreading outward.

Separate feature probes (cpuid invocation), which runs on the cpu
being attached, from the display of this information, which runs on
the boot cpu; remove some of the probe code from locore as it doesn't
need to run that early.

We now spin up secondary cpu's during cpu_attach, have them do a cpu
feature probe, and then have them spin waiting for a "go" signal.

We no longer pay attention to the cpu signature and cpuid features
reported by the MP BIOS since those are known to be truncated for at
least some bioses.

We now do npx initialization (including FDIV bug detection) on all
cpus.

XXX Change some of the cyrix bug workarounds to fit the new
identifycpu() system; this is untested.

diffstat:

 sys/arch/i386/MP-TODO          |   24 ++-
 sys/arch/i386/i386/cpu.c       |   87 +++++++++++---
 sys/arch/i386/i386/genassym.cf |   11 +-
 sys/arch/i386/i386/locore.s    |   32 +----
 sys/arch/i386/i386/machdep.c   |  244 ++++++++++++++++++++++------------------
 sys/arch/i386/i386/mainbus.c   |    4 +-
 sys/arch/i386/i386/mpbios.c    |   21 +--
 sys/arch/i386/include/cpu.h    |   24 ++-
 sys/arch/i386/include/cpuvar.h |    4 +-
 sys/arch/i386/include/npx.h    |    3 +-
 sys/arch/i386/isa/clock.c      |   28 +----
 sys/arch/i386/isa/npx.c        |   43 ++++--
 12 files changed, 286 insertions(+), 239 deletions(-)

diffs (truncated from 1064 to 300 lines):

diff -r a6ae2a28fa74 -r bb7f115bf468 sys/arch/i386/MP-TODO
--- a/sys/arch/i386/MP-TODO     Tue Jan 09 03:34:01 2001 +0000
+++ b/sys/arch/i386/MP-TODO     Wed Jan 10 04:38:31 2001 +0000
@@ -5,13 +5,6 @@
  - rewrite interrupt dispatch so that multi-level shared interrupts
    are no longer broken.
 
- - Sort out:
-       - cpu feature probes [runs on new cpu]
-       - identify_cpu() output [runs on BSP] 
-       - cpu initialization [runs on new cpu];
-   finish banishing most global variables containing cpu configuration 
-   information to struct cpu_info
-
  - figure out why ahc on serverworks fails to find its interrupt.
 
  - careful code review of all diffs from -current
@@ -20,6 +13,14 @@
 
 "would be nice":
 
+ - use atomic ops to modify ci_flags and cpu_feature to avoid losing bits.
+
+ - verify that cyrix 486 isn't blown out of the water by machdep changes.
+
+ - verify that cyrix clock chip bug fix isn't broken.
+
+ - make sure BSP always attaches first!
+
  - stop all cpu's on shutdown.
 
  - try out mpbios+ioapic w/o MULTIPROCESSOR
@@ -41,4 +42,11 @@
 [2001/01/08  22:29:56  sommerfeld]
 fixed three bugs; !MP kernel now comes up multiuser.
 
-       
+ - Sort out:
+       - cpu feature probes [runs on new cpu]
+       - identify_cpu() output [runs on BSP] 
+       - cpu initialization [runs on new cpu];
+   finish banishing most global variables containing cpu configuration 
+   information to struct cpu_info
+[2001/01/09  22:27:38  sommerfeld]
+completed.  significant rewrite of cpu spinup required.
diff -r a6ae2a28fa74 -r bb7f115bf468 sys/arch/i386/i386/cpu.c
--- a/sys/arch/i386/i386/cpu.c  Tue Jan 09 03:34:01 2001 +0000
+++ b/sys/arch/i386/i386/cpu.c  Wed Jan 10 04:38:31 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.c,v 1.1.2.18 2001/01/07 22:59:23 sommerfeld Exp $ */
+/* $NetBSD: cpu.c,v 1.1.2.19 2001/01/10 04:38:32 sommerfeld Exp $ */
 
 /*-
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -139,6 +139,7 @@
 
 void           cpu_hatch __P((void *));
 static void            cpu_boot_secondary __P((struct cpu_info *ci));
+static void            cpu_start_secondary __P((struct cpu_info *ci));
 static void    cpu_copy_trampoline __P((void));
 
 /*
@@ -215,8 +216,6 @@
 
        ci->ci_dev = self;
        ci->ci_cpuid = caa->cpu_number;
-       ci->ci_signature = caa->cpu_signature;
-       ci->ci_feature_flags = caa->feature_flags;
        ci->ci_func = caa->cpu_func;
 
 #if defined(MULTIPROCESSOR)
@@ -242,6 +241,7 @@
        pcb->pcb_tss.tss_esp =
            kstack + USPACE - 16 - sizeof (struct trapframe);
        pcb->pcb_pmap = pmap_kernel();
+       pcb->pcb_cr0 = rcr0();
        pcb->pcb_cr3 = pcb->pcb_pmap->pm_pdirpa;
 #endif
 
@@ -280,10 +280,17 @@
                 * report on an AP
                 */
                printf("apid %d (application processor)\n", caa->cpu_number);
-               ci->ci_flags |= CPUF_PRESENT | CPUF_AP;
-               identifycpu(ci);
-               ci->ci_next = cpu_info_list->ci_next;
-               cpu_info_list->ci_next = ci;
+
+#if defined(MULTIPROCESSOR)
+               cpu_start_secondary(ci);
+               if (ci->ci_flags & CPUF_PRESENT) {
+                       identifycpu(ci);
+                       ci->ci_next = cpu_info_list->ci_next;
+                       cpu_info_list->ci_next = ci;
+               }
+#else
+               printf("%s: not started\n", sc->sc_dev.dv_xname);
+#endif
                break;
                
        default:
@@ -310,13 +317,13 @@
 {
        /* configure the CPU if needed */
        if (ci->cpu_setup != NULL)
-               (*ci->cpu_setup)();
+               (*ci->cpu_setup)(ci);
 
 #if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU)
        /*
         * On a 486 or above, enable ring 0 write protection.
         */
-       if (ci->cpu_class >= CPUCLASS_486)
+       if (ci->ci_cpu_class >= CPUCLASS_486)
                lcr0(rcr0() | CR0_WP);
 #endif
 #if defined(I686_CPU)
@@ -384,7 +391,7 @@
 }
 
 void
-cpu_boot_secondary (ci)
+cpu_start_secondary (ci)
        struct cpu_info *ci;
 {
        struct pcb *pcb;
@@ -396,6 +403,8 @@
        
        pcb = ci->ci_idle_pcb;
 
+       ci->ci_flags |= CPUF_AP;
+       
        printf("%s: starting\n", ci->ci_dev->dv_xname);
 
        CPU_STARTUP(ci);
@@ -403,11 +412,11 @@
        /*
         * wait for it to become ready
         */
-       for (i = 100000; (!(ci->ci_flags & CPUF_RUNNING)) && i>0;i--) {
+       for (i = 100000; (!(ci->ci_flags & CPUF_PRESENT)) && i>0;i--) {
                delay(10);
        }
-       if (! (ci->ci_flags & CPUF_RUNNING)) {
-               printf("cpu failed to become ready\n");
+       if (! (ci->ci_flags & CPUF_PRESENT)) {
+               printf("%s: failed to become ready\n", ci->ci_dev->dv_xname);
 #if defined(MPDEBUG) && defined(DDB)
                printf("dropping into debugger; continue from here to resume boot\n");
                Debugger();
@@ -417,6 +426,28 @@
        CPU_START_CLEANUP(ci);
 }
 
+void
+cpu_boot_secondary(ci)
+       struct cpu_info *ci;
+{
+       int i;
+       
+       ci->ci_flags |= CPUF_GO; /* XXX atomic */
+
+       for (i = 100000; (!(ci->ci_flags & CPUF_RUNNING)) && i>0;i--) {
+               delay(10);
+       }
+       if (! (ci->ci_flags & CPUF_RUNNING)) {
+               printf("cpu failed to start\n");
+#if defined(MPDEBUG) && defined(DDB)
+               printf("dropping into debugger; continue from here to resume boot\n");
+               Debugger();
+#endif
+       }
+}
+
+       
+
 /*
  * The CPU ends up here when its ready to run
  * This is called from code in mptramp.s; at this point, we are running
@@ -431,20 +462,38 @@
        struct cpu_info *ci = (struct cpu_info *)v;
        int s;
        
+       cpu_probe_features(ci);
+       cpu_feature &= ci->ci_feature_flags;
+       
+#ifdef DEBUG
+       if (ci->ci_flags & CPUF_PRESENT)
+               panic("%s: already running!?", ci->ci_dev->dv_xname);
+#endif
+
+       ci->ci_flags |= CPUF_PRESENT;
+
+       lapic_enable();
+       lapic_initclocks();
+       
+       while ((ci->ci_flags & CPUF_GO) == 0)
+               delay(10);
+#ifdef DEBUG
+       if (ci->ci_flags & CPUF_RUNNING)
+               panic("%s: already running!?", ci->ci_dev->dv_xname);
+#endif
+
+       lcr0(ci->ci_idle_pcb->pcb_cr0);
+       lapic_set_lvt();
+       npxinit(ci);
        cpu_init_idt();
        gdt_init_cpu();
+
        lldt(GSEL(GLDT_SEL, SEL_KPL));
-       if (ci->ci_flags & CPUF_RUNNING) {
-               panic("%s: already running!?", ci->ci_dev->dv_xname);
-       }
-       lapic_enable();
-       lapic_set_lvt();
 
        cpu_init(ci);
 
        s = splhigh();
        enable_intr();
-       lapic_initclocks();
        printf("%s: CPU %d running\n",ci->ci_dev->dv_xname, cpu_number());
        microtime(&ci->ci_schedstate.spc_runtime);
        splx(s);
diff -r a6ae2a28fa74 -r bb7f115bf468 sys/arch/i386/i386/genassym.cf
--- a/sys/arch/i386/i386/genassym.cf    Tue Jan 09 03:34:01 2001 +0000
+++ b/sys/arch/i386/i386/genassym.cf    Wed Jan 10 04:38:31 2001 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: genassym.cf,v 1.17.10.8 2001/01/07 22:12:41 sommerfeld Exp $
+#      $NetBSD: genassym.cf,v 1.17.10.9 2001/01/10 04:38:32 sommerfeld Exp $
 
 #
 # Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -232,18 +232,17 @@
 
 define CPU_INFO_RESCHED        offsetof(struct cpu_info, ci_want_resched)
 
-ifdef MULTIPROCESSOR
-
 define CPU_INFO_CURPROC        offsetof(struct cpu_info, ci_curproc)
 define CPU_INFO_CURPCB         offsetof(struct cpu_info, ci_curpcb)
 define CPU_INFO_IDLE_PCB       offsetof(struct cpu_info, ci_idle_pcb)
 define  CPU_INFO_IDLE_TSS_SEL  offsetof(struct cpu_info, ci_idle_tss_sel)
-define CPU_INFO_LEVEL          offsetof(struct cpu_info, ci_level)
+define CPU_INFO_ASTPENDING     offsetof(struct cpu_info, ci_astpending)
+
+define CPU_INFO_LEVEL          offsetof(struct cpu_info, ci_cpuid_level)
 define CPU_INFO_VENDOR         offsetof(struct cpu_info, ci_vendor[0])
 define CPU_INFO_SIGNATURE      offsetof(struct cpu_info, ci_signature)
 define CPU_INFO_FEATURES       offsetof(struct cpu_info, ci_feature_flags)
-define CPU_INFO_ASTPENDING     offsetof(struct cpu_info, ci_astpending)
+define CPU_INFO_BRAND          offsetof(struct cpu_info, ci_brand_id)
 
 define SIZEOF_CPU_INFO         sizeof(struct cpu_info)
 
-endif
diff -r a6ae2a28fa74 -r bb7f115bf468 sys/arch/i386/i386/locore.s
--- a/sys/arch/i386/i386/locore.s       Tue Jan 09 03:34:01 2001 +0000
+++ b/sys/arch/i386/i386/locore.s       Wed Jan 10 04:38:31 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: locore.s,v 1.215.2.21 2001/01/09 03:29:51 sommerfeld Exp $     */
+/*     $NetBSD: locore.s,v 1.215.2.22 2001/01/10 04:38:32 sommerfeld Exp $     */
 
 /*-
  * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@@ -270,9 +270,8 @@
  */
        .data
 
-       .globl  _C_LABEL(cpu),_C_LABEL(cpu_id),_C_LABEL(cpu_vendor)
-       .globl  _C_LABEL(cpuid_level),_C_LABEL(cpu_feature)
-       .globl  _C_LABEL(cpu_brand_id)
+       .globl  _C_LABEL(cpu)
+       .globl  _C_LABEL(cpu_feature)
        .globl  _C_LABEL(esym),_C_LABEL(boothowto)
        .globl  _C_LABEL(bootinfo),_C_LABEL(atdevbase)
 #ifdef COMPAT_OLDBOOT
@@ -315,14 +314,8 @@
 
 _C_LABEL(cpu):         .long   0       # are we 386, 386sx, or 486,
                                        #   or Pentium, or..
-_C_LABEL(cpu_id):      .long   0       # saved from `cpuid' instruction
 _C_LABEL(cpu_feature): .long   0       # feature flags from 'cpuid'
                                        #   instruction
-_C_LABEL(cpuid_level): .long   -1      # max. level accepted by 'cpuid'
-                                       #   instruction
-_C_LABEL(cpu_vendor):  .space  16      # vendor string returned by `cpuid'
-                                       #   instruction
-_C_LABEL(cpu_brand_id):        .long   0       # brand ID from 'cpuid' instruction
 _C_LABEL(esym):                .long   0       # ptr to end of syms
 _C_LABEL(atdevbase):   .long   0       # location of start of iomem in virtual
 _C_LABEL(proc0paddr):  .long   0
@@ -418,6 +411,10 @@
 
        /* Find out our CPU type. */
 
+       xorl    %eax,%eax
+       decl    %eax
+       movl    %eax,RELOC(cpu_info_primary)+CPU_INFO_LEVEL
+



Home | Main Index | Thread Index | Old Index