ia64/xen-unstable

changeset 17463:08e010c3f251

hvmloader: Framework for multiprocessor initialisation.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Apr 15 16:39:00 2008 +0100 (2008-04-15)
parents a00355b306bd
children 2b3d3aaf8be4 e2d9fbede4ed
files tools/firmware/hvmloader/Makefile tools/firmware/hvmloader/hvmloader.c tools/firmware/hvmloader/smp.c tools/firmware/hvmloader/util.h
line diff
     1.1 --- a/tools/firmware/hvmloader/Makefile	Tue Apr 15 16:38:25 2008 +0100
     1.2 +++ b/tools/firmware/hvmloader/Makefile	Tue Apr 15 16:39:00 2008 +0100
     1.3 @@ -28,7 +28,7 @@ LOADADDR = 0x100000
     1.4  
     1.5  CFLAGS += $(CFLAGS_include) -I.
     1.6  
     1.7 -SRCS = hvmloader.c mp_tables.c util.c smbios.c 32bitbios_support.c
     1.8 +SRCS = hvmloader.c mp_tables.c util.c smbios.c 32bitbios_support.c smp.c
     1.9  OBJS = $(patsubst %.c,%.o,$(SRCS))
    1.10  
    1.11  .PHONY: all
     2.1 --- a/tools/firmware/hvmloader/hvmloader.c	Tue Apr 15 16:38:25 2008 +0100
     2.2 +++ b/tools/firmware/hvmloader/hvmloader.c	Tue Apr 15 16:39:00 2008 +0100
     2.3 @@ -32,7 +32,7 @@
     2.4  #include <xen/version.h>
     2.5  #include <xen/hvm/params.h>
     2.6  
     2.7 -asm(
     2.8 +asm (
     2.9      "    .text                       \n"
    2.10      "    .globl _start               \n"
    2.11      "_start:                         \n"
    2.12 @@ -98,6 +98,7 @@ asm(
    2.13      "stack_top:                      \n"
    2.14      );
    2.15  
    2.16 +void smp_initialise(void);
    2.17  void create_mp_tables(void);
    2.18  int hvm_write_smbios_tables(void);
    2.19  
    2.20 @@ -444,6 +445,8 @@ int main(void)
    2.21  
    2.22      printf("CPU speed is %u MHz\n", get_cpu_mhz());
    2.23  
    2.24 +    smp_initialise();
    2.25 +
    2.26      printf("Writing SMBIOS tables ...\n");
    2.27      smbios_sz = hvm_write_smbios_tables();
    2.28  
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/tools/firmware/hvmloader/smp.c	Tue Apr 15 16:39:00 2008 +0100
     3.3 @@ -0,0 +1,132 @@
     3.4 +/*
     3.5 + * smp.c: Secondary processor bringup and initialisation.
     3.6 + *
     3.7 + * Copyright (c) 2008, Citrix Systems, Inc.
     3.8 + * 
     3.9 + * Authors:
    3.10 + *    Keir Fraser <keir.fraser@citrix.com>
    3.11 + * 
    3.12 + * This program is free software; you can redistribute it and/or modify it
    3.13 + * under the terms and conditions of the GNU General Public License,
    3.14 + * version 2, as published by the Free Software Foundation.
    3.15 + *
    3.16 + * This program is distributed in the hope it will be useful, but WITHOUT
    3.17 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    3.18 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
    3.19 + * more details.
    3.20 + *
    3.21 + * You should have received a copy of the GNU General Public License along with
    3.22 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
    3.23 + * Place - Suite 330, Boston, MA 02111-1307 USA.
    3.24 + */
    3.25 +
    3.26 +#include "util.h"
    3.27 +#include "config.h"
    3.28 +#include "apic_regs.h"
    3.29 +
    3.30 +#define AP_BOOT_EIP 0x1000
    3.31 +extern char ap_boot_start[], ap_boot_end[];
    3.32 +
    3.33 +static int ap_callin, ap_cpuid;
    3.34 +
    3.35 +asm (
    3.36 +    "    .text                       \n"
    3.37 +    "    .code16                     \n"
    3.38 +    "ap_boot_start: .code16          \n"
    3.39 +    "    mov   %cs,%ax               \n"
    3.40 +    "    mov   %ax,%ds               \n"
    3.41 +    "    lgdt  gdt_desr-ap_boot_start\n"
    3.42 +    "    xor   %ax, %ax              \n"
    3.43 +    "    inc   %ax                   \n"
    3.44 +    "    lmsw  %ax                   \n"
    3.45 +    "    ljmpl $0x08,$1f             \n"
    3.46 +    "gdt_desr:                       \n"
    3.47 +    "    .word gdt_end - gdt - 1     \n"
    3.48 +    "    .long gdt                   \n"
    3.49 +    "ap_boot_end: .code32            \n"
    3.50 +    "1:  mov   $0x10,%eax            \n"
    3.51 +    "    mov   %eax,%ds              \n"
    3.52 +    "    mov   %eax,%es              \n"
    3.53 +    "    mov   %eax,%ss              \n"
    3.54 +    "    movl  $stack_top,%esp       \n"
    3.55 +    "    movl  %esp,%ebp             \n"
    3.56 +    "    call  ap_start              \n"
    3.57 +    "1:  hlt                         \n"
    3.58 +    "    jmp  1b                     \n"
    3.59 +    "                                \n"
    3.60 +    "    .align 8                    \n"
    3.61 +    "gdt:                            \n"
    3.62 +    "    .quad 0x0000000000000000    \n"
    3.63 +    "    .quad 0x00cf9a000000ffff    \n" /* 0x08: Flat code segment */
    3.64 +    "    .quad 0x00cf92000000ffff    \n" /* 0x10: Flat data segment */
    3.65 +    "gdt_end:                        \n"
    3.66 +    "                                \n"
    3.67 +    "    .bss                        \n"
    3.68 +    "    .align    8                 \n"
    3.69 +    "stack:                          \n"
    3.70 +    "    .skip    0x4000             \n"
    3.71 +    "stack_top:                      \n"
    3.72 +    );
    3.73 +
    3.74 +/*static*/ void ap_start(void)
    3.75 +{
    3.76 +    printf(" - CPU%d ... ", ap_cpuid);
    3.77 +
    3.78 +    printf("done.\n");
    3.79 +    wmb();
    3.80 +    ap_callin = 1;
    3.81 +}
    3.82 +
    3.83 +static void lapic_wait_ready(void)
    3.84 +{
    3.85 +    while ( lapic_read(APIC_ICR) & APIC_ICR_BUSY )
    3.86 +        cpu_relax();
    3.87 +}
    3.88 +
    3.89 +static void boot_cpu(unsigned int cpu)
    3.90 +{
    3.91 +    unsigned int icr2 = SET_APIC_DEST_FIELD(LAPIC_ID(cpu));
    3.92 +
    3.93 +    /* Initialise shared variables. */
    3.94 +    ap_cpuid = cpu;
    3.95 +    ap_callin = 0;
    3.96 +    wmb();
    3.97 +
    3.98 +    /* Wake up the secondary processor: INIT-SIPI-SIPI... */
    3.99 +    lapic_wait_ready();
   3.100 +    lapic_write(APIC_ICR2, icr2);
   3.101 +    lapic_write(APIC_ICR, APIC_DM_INIT);
   3.102 +    lapic_wait_ready();
   3.103 +    lapic_write(APIC_ICR2, icr2);
   3.104 +    lapic_write(APIC_ICR, APIC_DM_STARTUP | (AP_BOOT_EIP >> 12));
   3.105 +    lapic_wait_ready();
   3.106 +    lapic_write(APIC_ICR2, icr2);
   3.107 +    lapic_write(APIC_ICR, APIC_DM_STARTUP | (AP_BOOT_EIP >> 12));
   3.108 +    lapic_wait_ready();
   3.109 +
   3.110 +    /*
   3.111 +     * Wait for the secondary processor to complete initialisation.
   3.112 +     * Do not touch shared resources meanwhile.
   3.113 +     */
   3.114 +    while ( !ap_callin )
   3.115 +        cpu_relax();
   3.116 +
   3.117 +    /* Take the secondary processor offline. */
   3.118 +    lapic_write(APIC_ICR2, icr2);
   3.119 +    lapic_write(APIC_ICR, APIC_DM_INIT);
   3.120 +    lapic_wait_ready();    
   3.121 +}
   3.122 +
   3.123 +void smp_initialise(void)
   3.124 +{
   3.125 +    unsigned int i, nr_cpus = get_vcpu_nr();
   3.126 +
   3.127 +    if ( nr_cpus <= 1 )
   3.128 +        return;
   3.129 +
   3.130 +    memcpy((void *)AP_BOOT_EIP, ap_boot_start, ap_boot_end - ap_boot_start);
   3.131 +
   3.132 +    printf("Multiprocessor initialisation:\n");
   3.133 +    for ( i = 1; i < nr_cpus; i++ )
   3.134 +        boot_cpu(i);
   3.135 +}
     4.1 --- a/tools/firmware/hvmloader/util.h	Tue Apr 15 16:38:25 2008 +0100
     4.2 +++ b/tools/firmware/hvmloader/util.h	Tue Apr 15 16:39:00 2008 +0100
     4.3 @@ -78,6 +78,7 @@ static inline void cpu_relax(void)
     4.4  #define barrier() asm volatile ( "" : : : "memory" )
     4.5  #define rmb()     barrier()
     4.6  #define wmb()     barrier()
     4.7 +#define mb()      asm volatile ( "lock; addl $0,0(%%esp)" : : : "memory" )
     4.8  
     4.9  /*
    4.10   * Divide a 64-bit dividend by a 32-bit divisor.