Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch MP probing and startup code
details: https://anonhg.NetBSD.org/src/rev/5042770203b9
branches: trunk
changeset: 768264:5042770203b9
user: cherry <cherry%NetBSD.org@localhost>
date: Sat Aug 13 12:37:30 2011 +0000
description:
MP probing and startup code
diffstat:
sys/arch/x86/include/cpuvar.h | 6 +-
sys/arch/xen/x86/cpu.c | 619 ++++++++++++++++++++++++-----------------
sys/arch/xen/xen/hypervisor.c | 44 ++-
3 files changed, 402 insertions(+), 267 deletions(-)
diffs (truncated from 1057 to 300 lines):
diff -r 51cd9699b72a -r 5042770203b9 sys/arch/x86/include/cpuvar.h
--- a/sys/arch/x86/include/cpuvar.h Sat Aug 13 12:18:54 2011 +0000
+++ b/sys/arch/x86/include/cpuvar.h Sat Aug 13 12:37:30 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpuvar.h,v 1.44 2011/06/12 03:35:50 rmind Exp $ */
+/* $NetBSD: cpuvar.h,v 1.45 2011/08/13 12:37:30 cherry Exp $ */
/*-
* Copyright (c) 2000, 2007 The NetBSD Foundation, Inc.
@@ -67,7 +67,11 @@
#define _X86_CPUVAR_H_
struct cpu_functions {
+#ifndef XEN
int (*start)(struct cpu_info *, paddr_t);
+#else /* XEN */
+ int (*start)(struct cpu_info *, vaddr_t);
+#endif /* XEN */
int (*stop)(struct cpu_info *);
void (*cleanup)(struct cpu_info *);
};
diff -r 51cd9699b72a -r 5042770203b9 sys/arch/xen/x86/cpu.c
--- a/sys/arch/xen/x86/cpu.c Sat Aug 13 12:18:54 2011 +0000
+++ b/sys/arch/xen/x86/cpu.c Sat Aug 13 12:37:30 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.c,v 1.61 2011/08/11 18:11:17 cherry Exp $ */
+/* $NetBSD: cpu.c,v 1.62 2011/08/13 12:37:30 cherry Exp $ */
/* NetBSD: cpu.c,v 1.18 2004/02/20 17:35:01 yamt Exp */
/*-
@@ -66,7 +66,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.61 2011/08/11 18:11:17 cherry Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.62 2011/08/13 12:37:30 cherry Exp $");
#include "opt_ddb.h"
#include "opt_multiprocessor.h"
@@ -85,6 +85,7 @@
#include <sys/cpu.h>
#include <sys/atomic.h>
#include <sys/reboot.h>
+#include <sys/idle.h>
#include <uvm/uvm.h>
@@ -100,6 +101,14 @@
#include <machine/mtrr.h>
#include <machine/pio.h>
+#ifdef i386
+#include <machine/npx.h>
+#else
+#include <machine/fpu.h>
+#endif
+
+#include <xen/xen.h>
+#include <xen/xen3-public/vcpu.h>
#include <xen/vcpuvar.h>
#if NLAPIC > 0
@@ -131,7 +140,7 @@
bool sc_wasonline;
};
-int mp_cpu_start(struct cpu_info *, paddr_t);
+int mp_cpu_start(struct cpu_info *, vaddr_t);
void mp_cpu_start_cleanup(struct cpu_info *);
const struct cpu_functions mp_cpu_funcs = { mp_cpu_start, NULL,
mp_cpu_start_cleanup };
@@ -171,8 +180,6 @@
struct cpu_info *cpu_info_list = &cpu_info_primary;
struct cpu_info *phycpu_info_list = &phycpu_info_primary;
-static void cpu_set_tss_gates(struct cpu_info *ci);
-
uint32_t cpus_attached = 1;
uint32_t cpus_running = 1;
@@ -194,21 +201,6 @@
void cpu_hatch(void *);
static void cpu_boot_secondary(struct cpu_info *ci);
static void cpu_start_secondary(struct cpu_info *ci);
-static void cpu_copy_trampoline(void);
-
-/*
- * Runs once per boot once multiprocessor goo has been detected and
- * the local APIC on the boot processor has been mapped.
- *
- * Called from lapic_boot_init() (from mpbios_scan()).
- */
-void
-cpu_init_first(void)
-{
-
- cpu_info_primary.ci_cpuid = lapic_cpu_number();
- cpu_copy_trampoline();
-}
#endif /* MULTIPROCESSOR */
static int
@@ -317,9 +309,23 @@
vcpu_match(device_t parent, cfdata_t match, void *aux)
{
struct vcpu_attach_args *vcaa = aux;
+ struct vcpu_runstate_info vcr;
+ int error;
- if (strcmp(vcaa->vcaa_name, match->cf_name) == 0)
- return 1;
+ if (strcmp(vcaa->vcaa_name, match->cf_name) == 0) {
+ error = HYPERVISOR_vcpu_op(VCPUOP_get_runstate_info,
+ vcaa->vcaa_caa.cpu_number,
+ &vcr);
+ switch (error) {
+ case 0:
+ return 1;
+ case -ENOENT:
+ return 0;
+ default:
+ panic("Unknown hypervisor error %d returned on vcpu runstate probe\n", error);
+ }
+ }
+
return 0;
}
@@ -328,9 +334,18 @@
{
struct vcpu_attach_args *vcaa = aux;
+ KASSERT(vcaa->vcaa_caa.cpu_func == NULL);
+ vcaa->vcaa_caa.cpu_func = &mp_cpu_funcs;
cpu_attach_common(parent, self, &vcaa->vcaa_caa);
}
+static int
+vcpu_is_up(struct cpu_info *ci)
+{
+ KASSERT(ci != NULL);
+ return HYPERVISOR_vcpu_op(VCPUOP_is_up, ci->ci_cpuid, NULL);
+}
+
static void
cpu_vm_init(struct cpu_info *ci)
{
@@ -395,22 +410,6 @@
aprint_naive(": %s Processor\n",
caa->cpu_role == CPU_ROLE_SP ? "Single" : "Boot");
ci = &cpu_info_primary;
-#if NLAPIC > 0
- if (cpunum != lapic_cpu_number()) {
- /* XXX should be done earlier */
- uint32_t reg;
- aprint_verbose("\n");
- aprint_verbose_dev(self, "running CPU at apic %d"
- " instead of at expected %d", lapic_cpu_number(),
- cpunum);
- reg = i82489_readreg(LAPIC_ID);
- i82489_writereg(LAPIC_ID, (reg & ~LAPIC_ID_MASK) |
- (cpunum << LAPIC_ID_SHIFT));
- }
- if (cpunum != lapic_cpu_number()) {
- aprint_error_dev(self, "unable to reset apic id\n");
- }
-#endif
}
ci->ci_self = ci;
@@ -421,6 +420,7 @@
KASSERT(HYPERVISOR_shared_info != NULL);
ci->ci_vcpu = &HYPERVISOR_shared_info->vcpu_info[cpunum];
+ KASSERT(ci->ci_func == 0);
ci->ci_func = caa->cpu_func;
/* Must be called before mi_cpu_attach(). */
@@ -430,12 +430,15 @@
int error;
error = mi_cpu_attach(ci);
+
+ KASSERT(ci->ci_data.cpu_idlelwp != NULL);
if (error != 0) {
aprint_normal("\n");
aprint_error_dev(self,
"mi_cpu_attach failed with %d\n", error);
return;
}
+
} else {
KASSERT(ci->ci_data.cpu_idlelwp != NULL);
}
@@ -455,15 +458,12 @@
cpu_intr_init(ci);
cpu_get_tsc_freq(ci);
cpu_init(ci);
- cpu_set_tss_gates(ci);
-#if NLAPIC > 0
- if (caa->cpu_role != CPU_ROLE_SP) {
- /* Enable lapic. */
- lapic_enable();
- lapic_set_lvt();
- lapic_calibrate_timer();
- }
-#endif
+ pmap_cpu_init_late(ci); /* XXX: cosmetic */
+
+ /* Every processor needs to init it's own ipi h/w (similar to lapic) */
+ xen_ipi_init();
+ /* XXX: clock_init() */
+
/* Make sure DELAY() is initialized. */
DELAY(1);
again = true;
@@ -479,6 +479,7 @@
x86_errata();
#endif
x86_cpu_idle_init();
+
break;
case CPU_ROLE_BP:
@@ -489,22 +490,30 @@
x86_errata();
#endif
x86_cpu_idle_init();
+
break;
case CPU_ROLE_AP:
+ atomic_or_32(&ci->ci_flags, CPUF_AP);
+
/*
* report on an AP
*/
#if defined(MULTIPROCESSOR)
+ /* interrupt handler stack */
cpu_intr_init(ci);
+
+ /* Setup per-cpu memory for gdt */
gdt_alloc_cpu(ci);
- cpu_set_tss_gates(ci);
+
+ pmap_cpu_init_late(ci);
cpu_start_secondary(ci);
+
if (ci->ci_flags & CPUF_PRESENT) {
struct cpu_info *tmp;
- identifycpu(ci);
+ cpu_identify(ci);
tmp = cpu_info_list;
while (tmp->ci_next)
tmp = tmp->ci_next;
@@ -512,7 +521,7 @@
tmp->ci_next = ci;
}
#else
- aprint_error_dev(self, "not started\n");
+ aprint_error(": not started\n");
#endif
break;
@@ -529,7 +538,7 @@
aprint_error_dev(self, "couldn't establish power handler\n");
#endif
-#if defined(MULTIPROCESSOR)
+#ifdef MPVERBOSE
if (mp_verbose) {
struct lwp *l = ci->ci_data.cpu_idlelwp;
struct pcb *pcb = lwp_getpcb(l);
@@ -539,13 +548,13 @@
l,
#ifdef i386
(void *)pcb->pcb_esp
-#else
+#else /* i386 */
(void *)pcb->pcb_rsp
-#endif
+#endif /* i386 */
);
}
-#endif
+#endif /* MPVERBOSE */
}
/*
@@ -593,16 +602,18 @@
atomic_or_32(&cpus_running, ci->ci_cpumask);
atomic_or_32(&ci->ci_flags, CPUF_RUNNING);
+
+ /* XXX: register vcpu_register_runstate_memory_area, and figure out how to make sure this VCPU is running ? */
}
Home |
Main Index |
Thread Index |
Old Index