ia64/xen-unstable

view tools/firmware/hvmloader/smp.c @ 19709:011948e1b5a7

hvmloader: Scan for gpxe-capable NICs until one is found.

Signed-off-by: Akio Takebe <takebe_akio@jp.fujitsu.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Jun 03 16:12:34 2009 +0100 (2009-06-03)
parents f20e5039b168
children
line source
1 /*
2 * smp.c: Secondary processor bringup and initialisation.
3 *
4 * Copyright (c) 2008, Citrix Systems, Inc.
5 *
6 * Authors:
7 * Keir Fraser <keir.fraser@citrix.com>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms and conditions of the GNU General Public License,
11 * version 2, as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
20 * Place - Suite 330, Boston, MA 02111-1307 USA.
21 */
23 #include "util.h"
24 #include "config.h"
25 #include "apic_regs.h"
27 #define AP_BOOT_EIP 0x1000
28 extern char ap_boot_start[], ap_boot_end[];
30 static int ap_callin, ap_cpuid;
32 asm (
33 " .text \n"
34 " .code16 \n"
35 "ap_boot_start: .code16 \n"
36 " mov %cs,%ax \n"
37 " mov %ax,%ds \n"
38 " lgdt gdt_desr-ap_boot_start\n"
39 " xor %ax, %ax \n"
40 " inc %ax \n"
41 " lmsw %ax \n"
42 " ljmpl $0x08,$1f \n"
43 "gdt_desr: \n"
44 " .word gdt_end - gdt - 1 \n"
45 " .long gdt \n"
46 "ap_boot_end: .code32 \n"
47 "1: mov $0x10,%eax \n"
48 " mov %eax,%ds \n"
49 " mov %eax,%es \n"
50 " mov %eax,%ss \n"
51 " movl $stack_top,%esp \n"
52 " movl %esp,%ebp \n"
53 " call ap_start \n"
54 "1: hlt \n"
55 " jmp 1b \n"
56 " \n"
57 " .align 8 \n"
58 "gdt: \n"
59 " .quad 0x0000000000000000 \n"
60 " .quad 0x00cf9a000000ffff \n" /* 0x08: Flat code segment */
61 " .quad 0x00cf92000000ffff \n" /* 0x10: Flat data segment */
62 "gdt_end: \n"
63 " \n"
64 " .bss \n"
65 " .align 8 \n"
66 "stack: \n"
67 " .skip 0x4000 \n"
68 "stack_top: \n"
69 " .text \n"
70 );
72 void ap_start(void); /* non-static avoids unused-function compiler warning */
73 /*static*/ void ap_start(void)
74 {
75 printf(" - CPU%d ... ", ap_cpuid);
76 cacheattr_init();
77 printf("done.\n");
78 wmb();
79 ap_callin = 1;
80 }
82 static void lapic_wait_ready(void)
83 {
84 while ( lapic_read(APIC_ICR) & APIC_ICR_BUSY )
85 cpu_relax();
86 }
88 static void boot_cpu(unsigned int cpu)
89 {
90 unsigned int icr2 = SET_APIC_DEST_FIELD(LAPIC_ID(cpu));
92 /* Initialise shared variables. */
93 ap_cpuid = cpu;
94 ap_callin = 0;
95 wmb();
97 /* Wake up the secondary processor: INIT-SIPI-SIPI... */
98 lapic_wait_ready();
99 lapic_write(APIC_ICR2, icr2);
100 lapic_write(APIC_ICR, APIC_DM_INIT);
101 lapic_wait_ready();
102 lapic_write(APIC_ICR2, icr2);
103 lapic_write(APIC_ICR, APIC_DM_STARTUP | (AP_BOOT_EIP >> 12));
104 lapic_wait_ready();
105 lapic_write(APIC_ICR2, icr2);
106 lapic_write(APIC_ICR, APIC_DM_STARTUP | (AP_BOOT_EIP >> 12));
107 lapic_wait_ready();
109 /*
110 * Wait for the secondary processor to complete initialisation.
111 * Do not touch shared resources meanwhile.
112 */
113 while ( !ap_callin )
114 cpu_relax();
116 /* Take the secondary processor offline. */
117 lapic_write(APIC_ICR2, icr2);
118 lapic_write(APIC_ICR, APIC_DM_INIT);
119 lapic_wait_ready();
120 }
122 void smp_initialise(void)
123 {
124 unsigned int i, nr_cpus = hvm_info->nr_vcpus;
126 memcpy((void *)AP_BOOT_EIP, ap_boot_start, ap_boot_end - ap_boot_start);
128 printf("Multiprocessor initialisation:\n");
129 ap_start();
130 for ( i = 1; i < nr_cpus; i++ )
131 boot_cpu(i);
132 }