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(®ion, pentium_idt, NIDT * sizeof(idt[0]) - 1);
+#else
+ setregion(®ion, idt, NIDT * sizeof(idt[0]) - 1);
+#endif
+ lidt(®ion);
+}
+
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