mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 18:21:39 +01:00
Now that we're using hypercalls to start APs, we can replace the 'ap_cpuid' global with a regular function parameter. This requires telling the compiler that we'd like the parameter in a register rather than on the stack. While adjusting, rename to cpu_setup(). It's always been used on the BSP, making the name ap_start() specifically misleading. Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> Reviewed-by: Alejandro Vallejo <alejandro.vallejo@cloud.com>
123 lines
2.9 KiB
C
123 lines
2.9 KiB
C
/*
|
|
* smp.c: Secondary processor bringup and initialisation.
|
|
*
|
|
* Copyright (c) 2008, Citrix Systems, Inc.
|
|
*
|
|
* Authors:
|
|
* Keir Fraser <keir@xen.org>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms and conditions of the GNU General Public License,
|
|
* version 2, as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with
|
|
* this program; If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "util.h"
|
|
#include "config.h"
|
|
#include "apic_regs.h"
|
|
#include "hypercall.h"
|
|
|
|
#include <xen/asm/x86-defns.h>
|
|
#include <xen/hvm/hvm_vcpu.h>
|
|
|
|
#include <xen/vcpu.h>
|
|
|
|
static int ap_callin;
|
|
|
|
static void __attribute__((regparm(1))) cpu_setup(unsigned int cpu)
|
|
{
|
|
printf(" - CPU%d ... ", cpu);
|
|
cacheattr_init();
|
|
printf("done.\n");
|
|
|
|
if ( !cpu ) /* Used on the BSP too */
|
|
return;
|
|
|
|
wmb();
|
|
ap_callin = 1;
|
|
|
|
/* After this point, the BSP will shut us down. */
|
|
|
|
for ( ;; )
|
|
asm volatile ( "hlt" );
|
|
}
|
|
|
|
static void boot_cpu(unsigned int cpu)
|
|
{
|
|
static uint8_t ap_stack[PAGE_SIZE] __attribute__ ((aligned (16)));
|
|
static struct vcpu_hvm_context ap;
|
|
|
|
/* Initialise shared variables. */
|
|
ap_callin = 0;
|
|
wmb();
|
|
|
|
/* Wake up the secondary processor */
|
|
ap = (struct vcpu_hvm_context) {
|
|
.mode = VCPU_HVM_MODE_32B,
|
|
.cpu_regs.x86_32 = {
|
|
.eip = (unsigned long)cpu_setup,
|
|
.esp = (unsigned long)ap_stack + ARRAY_SIZE(ap_stack),
|
|
|
|
.eax = cpu,
|
|
|
|
/* Protected Mode, no paging. */
|
|
.cr0 = X86_CR0_PE,
|
|
|
|
/* 32bit Flat Mode */
|
|
.cs_limit = -1U,
|
|
.ds_limit = -1U,
|
|
.ss_limit = -1U,
|
|
.es_limit = -1U,
|
|
.tr_limit = 0x67,
|
|
.cs_ar = 0xc9b,
|
|
.ds_ar = 0xc93,
|
|
.es_ar = 0xc93,
|
|
.ss_ar = 0xc93,
|
|
.tr_ar = 0x8b,
|
|
},
|
|
};
|
|
|
|
if ( hypercall_vcpu_op(VCPUOP_initialise, cpu, &ap) )
|
|
BUG();
|
|
if ( hypercall_vcpu_op(VCPUOP_up, cpu, NULL) )
|
|
BUG();
|
|
|
|
/*
|
|
* Wait for the secondary processor to complete initialisation.
|
|
* Do not touch shared resources meanwhile.
|
|
*/
|
|
while ( !ap_callin )
|
|
cpu_relax();
|
|
|
|
/* Take the secondary processor offline. */
|
|
if ( hypercall_vcpu_op(VCPUOP_down, cpu, NULL) )
|
|
BUG();
|
|
}
|
|
|
|
void smp_initialise(void)
|
|
{
|
|
unsigned int i, nr_cpus = hvm_info->nr_vcpus;
|
|
|
|
printf("Multiprocessor initialisation:\n");
|
|
cpu_setup(0);
|
|
for ( i = 1; i < nr_cpus; i++ )
|
|
boot_cpu(i);
|
|
}
|
|
|
|
/*
|
|
* Local variables:
|
|
* mode: C
|
|
* c-file-style: "BSD"
|
|
* c-basic-offset: 4
|
|
* tab-width: 4
|
|
* indent-tabs-mode: nil
|
|
* End:
|
|
*/
|