Changeset View
Changeset View
Standalone View
Standalone View
sys/x86/xen/pv.c
Show First 20 Lines • Show All 89 Lines • ▼ Show 20 Lines | |||||
uint64_t hammer_time_xen(vm_paddr_t); | uint64_t hammer_time_xen(vm_paddr_t); | ||||
#define MAX_E820_ENTRIES 128 | #define MAX_E820_ENTRIES 128 | ||||
/*--------------------------- Forward Declarations ---------------------------*/ | /*--------------------------- Forward Declarations ---------------------------*/ | ||||
static caddr_t xen_pvh_parse_preload_data(uint64_t); | static caddr_t xen_pvh_parse_preload_data(uint64_t); | ||||
static void xen_pvh_parse_memmap(caddr_t, vm_paddr_t *, int *); | static void xen_pvh_parse_memmap(caddr_t, vm_paddr_t *, int *); | ||||
#ifdef SMP | |||||
static int xen_pv_start_all_aps(void); | |||||
#endif | |||||
/*---------------------------- Extern Declarations ---------------------------*/ | /*---------------------------- Extern Declarations ---------------------------*/ | ||||
#ifdef SMP | #ifdef SMP | ||||
/* Variables used by amd64 mp_machdep to start APs */ | /* Variables used by amd64 mp_machdep to start APs */ | ||||
extern char *doublefault_stack; | extern char *doublefault_stack; | ||||
extern char *mce_stack; | extern char *mce_stack; | ||||
extern char *nmi_stack; | extern char *nmi_stack; | ||||
extern char *dbg_stack; | extern char *dbg_stack; | ||||
#endif | #endif | ||||
▲ Show 20 Lines • Show All 93 Lines • ▼ Show 20 Lines | hammer_time_xen(vm_paddr_t start_info_paddr) | ||||
init_ops = xen_pvh_init_ops; | init_ops = xen_pvh_init_ops; | ||||
hvm_start_flags = start_info->flags; | hvm_start_flags = start_info->flags; | ||||
/* Now we can jump into the native init function */ | /* Now we can jump into the native init function */ | ||||
return (hammer_time(0, physfree)); | return (hammer_time(0, physfree)); | ||||
} | } | ||||
/*-------------------------------- PV specific -------------------------------*/ | /*-------------------------------- PV specific -------------------------------*/ | ||||
#ifdef SMP | |||||
static bool | |||||
start_xen_ap(int cpu) | |||||
{ | |||||
struct vcpu_guest_context *ctxt; | |||||
int ms, cpus = mp_naps; | |||||
const size_t stacksize = kstack_pages * PAGE_SIZE; | |||||
/* allocate and set up an idle stack data page */ | |||||
bootstacks[cpu] = (void *)kmem_malloc(stacksize, M_WAITOK | M_ZERO); | |||||
doublefault_stack = (char *)kmem_malloc(PAGE_SIZE, M_WAITOK | M_ZERO); | |||||
mce_stack = (char *)kmem_malloc(PAGE_SIZE, M_WAITOK | M_ZERO); | |||||
nmi_stack = (char *)kmem_malloc(PAGE_SIZE, M_WAITOK | M_ZERO); | |||||
dbg_stack = (void *)kmem_malloc(PAGE_SIZE, M_WAITOK | M_ZERO); | |||||
dpcpu = (void *)kmem_malloc(DPCPU_SIZE, M_WAITOK | M_ZERO); | |||||
bootSTK = (char *)bootstacks[cpu] + kstack_pages * PAGE_SIZE - 8; | |||||
bootAP = cpu; | |||||
ctxt = malloc(sizeof(*ctxt), M_TEMP, M_WAITOK | M_ZERO); | |||||
ctxt->flags = VGCF_IN_KERNEL; | |||||
ctxt->user_regs.rip = (unsigned long) init_secondary; | |||||
ctxt->user_regs.rsp = (unsigned long) bootSTK; | |||||
/* Set the AP to use the same page tables */ | |||||
ctxt->ctrlreg[3] = KPML4phys; | |||||
if (HYPERVISOR_vcpu_op(VCPUOP_initialise, cpu, ctxt)) | |||||
panic("unable to initialize AP#%d", cpu); | |||||
free(ctxt, M_TEMP); | |||||
/* Launch the vCPU */ | |||||
if (HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL)) | |||||
panic("unable to start AP#%d", cpu); | |||||
/* Wait up to 5 seconds for it to start. */ | |||||
for (ms = 0; ms < 5000; ms++) { | |||||
if (mp_naps > cpus) | |||||
return (true); | |||||
DELAY(1000); | |||||
} | |||||
return (false); | |||||
} | |||||
static int | |||||
xen_pv_start_all_aps(void) | |||||
{ | |||||
int cpu; | |||||
mtx_init(&ap_boot_mtx, "ap boot", NULL, MTX_SPIN); | |||||
for (cpu = 1; cpu < mp_ncpus; cpu++) { | |||||
/* attempt to start the Application Processor */ | |||||
if (!start_xen_ap(cpu)) | |||||
panic("AP #%d failed to start!", cpu); | |||||
CPU_SET(cpu, &all_cpus); /* record AP in CPU map */ | |||||
} | |||||
return (mp_naps); | |||||
} | |||||
#endif /* SMP */ | |||||
/* | /* | ||||
* When booted as a PVH guest FreeBSD needs to avoid using the RSDP address | * When booted as a PVH guest FreeBSD needs to avoid using the RSDP address | ||||
* hint provided by the loader because it points to the native set of ACPI | * hint provided by the loader because it points to the native set of ACPI | ||||
* tables instead of the ones crafted by Xen. The acpi.rsdp env variable is | * tables instead of the ones crafted by Xen. The acpi.rsdp env variable is | ||||
* removed from kenv if present, and a new acpi.rsdp is added to kenv that | * removed from kenv if present, and a new acpi.rsdp is added to kenv that | ||||
* points to the address of the Xen crafted RSDP. | * points to the address of the Xen crafted RSDP. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 207 Lines • Show Last 20 Lines |