Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Merge branch 'devel'
[palacios.git] / kitten / arch / x86_64 / kernel / mpboot.c
1 #include <lwk/kernel.h>
2 #include <lwk/init.h>
3 #include <lwk/cpuinfo.h>
4 #include <lwk/smp.h>
5 #include <lwk/delay.h>
6 #include <lwk/bootmem.h>
7 #include <lwk/task.h>
8 #include <lwk/sched.h>
9 #include <arch/atomic.h>
10 #include <arch/apicdef.h>
11 #include <arch/apic.h>
12 #include <arch/desc.h>
13
14 /**
15  * MP boot trampoline 80x86 program as an array.
16  */
17 extern unsigned char trampoline_data[];
18 extern unsigned char trampoline_end[];
19
20 /**
21  * These specify the initial stack pointer and instruction pointer for a
22  * newly booted CPU.
23  */
24 extern volatile unsigned long init_rsp;
25 extern void (*initial_code)(void);
26
27 void __init
28 start_secondary(void)
29 {
30         cpu_init();
31         cpu_set(this_cpu, cpu_online_map);
32         schedule(); /* runs idle_task, since that's the only task
33                      * on the CPU's run queue at this point */
34 }
35
36 void __init
37 arch_boot_cpu(unsigned int cpu)
38 {
39         union task_union *new_task_union;
40         struct task_struct *new_task;
41
42         /*
43          * Setup the 'trampoline' cpu boot code. The trampoline contains the
44          * first code executed by the CPU being booted. x86 CPUs boot in
45          * pre-historic 16-bit 'real mode'... the trampoline does the messy
46          * work to get us to 64-bit long mode and then calls the *initial_code
47          * kernel entry function.
48          */
49         memcpy(__va(SMP_TRAMPOLINE_BASE), trampoline_data,
50                                           trampoline_end - trampoline_data
51         );
52
53         /*
54          * Allocate memory for the new CPU's GDT.
55          */
56         cpu_gdt_descr[cpu].address = (unsigned long) kmem_get_pages(0);
57
58         /*
59          * Allocate memory for the new CPU's bootstrap task.
60          */
61         new_task_union = kmem_get_pages(TASK_ORDER);
62         new_task = &new_task_union->task_info;
63
64         /*
65          * Initialize the bare minimum info needed to bootstrap the new CPU.
66          */
67         new_task->id      = 0;
68         new_task->aspace  = &bootstrap_aspace;
69         new_task->cpu_id  = cpu;
70         strcpy(new_task->name, "bootstrap");
71         list_head_init(&new_task->sched_link);
72
73         /*
74          * Set the initial kernel entry point and stack pointer for the new CPU.
75          */
76         initial_code = start_secondary;
77         init_rsp     = (unsigned long)new_task_union
78                                           + sizeof(union task_union) - 1;
79
80         /*
81          * Boot it!
82          */
83         lapic_send_init_ipi(cpu);
84         lapic_send_startup_ipi(cpu, SMP_TRAMPOLINE_BASE);
85         lapic_send_startup_ipi(cpu, SMP_TRAMPOLINE_BASE);
86 }
87