Patches b03c1b through 3f00b5
[barrelfish] / tools / weever / boot.S
1 /**
2  * \file
3  * \brief X-Loader for the Intel Xeon Phi
4  */
5
6 /*
7  * Copyright (c) 2014 ETH Zurich.
8  * All rights reserved.
9  *
10  * This file is distributed under the terms in the attached LICENSE file.
11  * If you do not find this file, copies can be found by writing to:
12  * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
13  */
14
15  /*
16   * Parts of this code comes from the Linux distribution shipped with the
17   * MPSS 3.2 for the Xeon Phi.
18   */
19
20 #include <../kernel/include/target/k1om/offsets_target.h>
21
22 /* Boot Magic */
23 #define K1OM_BOOT_MAGIC               0xB001B001
24
25 /* The long mode code segment */
26 #define LONG_MODE_CS                  0x0010
27
28 /* the boot stack size (16 kb)*/
29 #define BOOT_STACK_SIZE               0x4000
30
31 /* X86 Registers */
32 #define MSR_EFER                      0xc0000080
33 #define X86_EFER_LONG_MODE_ENABLE     8
34 #define X86_CR0_PROTECTION_ENABLE     0x00000001
35 #define X86_CR0_PAGING_ENABLE         0x80000000
36 #define X86_CR4_PADDREXT_ENABLE       0x00000020
37
38 /*
39  * scratch field in struct boot_params supplied by the bootloader
40  * this is used for a mini stack to determine the load address
41  */
42 #define BP_SCRATCH                     484
43
44
45 #define ENTRY(name) \
46   .globl name; \
47   .align 4,0x90; \
48   name:
49
50 #ifndef ENDPROC
51 #define ENDPROC(name) \
52   .type name, @function; \
53   .size name, .-name
54 #endif
55
56
57 /*
58  * ===========================================================================
59  * Begin of 32 bit entry code
60  * ===========================================================================
61  */
62
63           .section  ".head.text","ax"
64           .code32
65 ENTRY(startup_32)
66
67           /* clear direction and interrupts */
68           cld
69           cli
70
71           leal      (BP_SCRATCH+4)(%esi), %esp
72           call      1f
73 1:        popl      %ebp
74           subl      $1b, %ebp
75           movl      %ebp, %ebx
76
77                   leal      prepare_long_mode(%ebx), %eax
78                   jmp           *%eax
79 ENDPROC(startup_32)
80
81           /* Prepare for the long mode */
82 .section  ".head32.text","ax"
83
84 ENTRY(prepare_long_mode)
85           /* Load new GDT with the 64bit segments using 32bit descriptor */
86           leal      gdt(%ebx), %eax
87           movl      %eax, gdt+2(%ebx)
88           lgdt      gdt(%ebx)
89
90           /* Enable physical address extension */
91           mov       %cr4,%eax
92           orl       $X86_CR4_PADDREXT_ENABLE,%eax
93           mov       %eax,%cr4
94
95          /* Building the boot page tables for long mode */
96
97           /* Initialize Page tables to 0 */
98           leal      pgtable(%ebx), %edi
99           xorl      %eax, %eax
100           movl      $((4096*6)/4), %ecx
101           rep       stosl
102
103           /* Build Level 4 */
104           leal      pgtable + 0(%ebx), %edi
105           leal      0x1007 (%edi), %eax
106           movl      %eax, 0(%edi)
107
108           /* Build Level 3 */
109           leal      pgtable + 0x1000(%ebx), %edi
110           leal      0x1007(%edi), %eax
111           movl      $4, %ecx
112 1:        movl      %eax, 0x00(%edi)
113           addl      $0x00001000, %eax
114           addl      $8, %edi
115           decl      %ecx
116           jnz       1b
117
118           /* Build Level 2 */
119           leal      pgtable + 0x2000(%ebx), %edi
120           movl      $0x00000183, %eax
121           movl      $2048, %ecx
122 1:        movl      %eax, 0(%edi)
123           addl      $0x00200000, %eax
124           addl      $8, %edi
125           decl      %ecx
126           jnz       1b
127
128           /* Adding mappings for the "serial out" */
129
130           /* Build Level 3 */
131           leal      pgtable + 0x1000(%ebx), %edi
132           leal      0x5007(%edi), %eax
133           addl      $256, %edi                    //31st entry
134           movl      %eax, 0x00(%edi)
135
136           /* Build Level 2 */
137           leal      pgtable + 0x6000(%ebx), %edi
138           movl      $0x00000183, %eax
139           movl      $512, %ecx
140 1:        movl      %eax, 0(%edi)
141           addl      $0x00200000, %eax
142           addl      $8, %edi
143           decl      %ecx
144           jnz       1b
145
146           /* Build Level 2 - high part*/
147           leal    pgtable + 0x6000(%ebx), %edi
148           addl    $4, %edi
149           movl    $512, %ecx
150 1:        movl    $0x8, 0(%edi)
151           addl    $8, %edi
152           decl    %ecx
153           jnz     1b
154
155           /* Enable the boot page tables */
156           leal      pgtable(%ebx), %eax
157           movl      %eax, %cr3
158
159           /* Enable the long mode */
160           movl      $MSR_EFER, %ecx
161           rdmsr
162           btsl      $X86_EFER_LONG_MODE_ENABLE, %eax
163           wrmsr
164
165             /* prepare the long mode jump */
166           pushl     $LONG_MODE_CS
167           leal      startup_64(%ebx), %eax
168           pushl     %eax
169
170           /* Activate protected mode and paging*/
171           movl        %cr0, %eax
172           orl      $(X86_CR0_PAGING_ENABLE | X86_CR0_PROTECTION_ENABLE), %eax
173           movl      %eax, %cr0
174
175           /* Jump from 32bit compatibility mode into 64bit mode. */
176           lret
177
178 ENDPROC(prepare_long_mode)
179
180 /*
181  * ===========================================================================
182  * Begin of 64 bit code
183  * ===========================================================================
184  */
185         .section  ".head64.text","ax"
186           .code64
187 ENTRY(startup_64)
188
189           /* Setup data segments. */
190           xorl      %eax, %eax
191           movl      %eax, %ds
192           movl      %eax, %es
193           movl      %eax, %ss
194           movl      %eax, %fs
195           movl      %eax, %gs
196           lldt      %ax
197           movl      $0x20, %eax
198           ltr       %ax
199
200           /* a little "printf" to show that we are running */
201           movabsq $0x08007DAB5C, %r14
202           movl    $0x0A58553E, (%r14)
203           movabsq $0x08007DAB40, %r14
204           movl    $2054847098, (%r14)
205
206
207           /* Set up the stack */
208           leaq      boot_stack_end(%rbx), %rsp
209
210
211           /* Reset EFLAGS */
212           pushq     $0
213           popf
214
215           /*
216            * store the boot param struct pointer and the magic value
217            * Note: %rsi holds already a pointer to the boot params
218            */
219           movq      $K1OM_BOOT_MAGIC, %rdi
220           call      loader
221
222            /* jump to the kernel entry point */
223           movq      $K1OM_BOOT_MAGIC, %rax
224           movq      multiboot_info, %rbx
225           movq      kernel_entry, %rcx
226           jmp       *%rcx
227
228           .data
229           .align 16
230 gdt:
231           .word     gdt_end - gdt
232           .long     gdt
233           .word     0
234           .quad     0x0000000000000000  /* NULL descriptor */
235           .quad     0x00af9a000000ffff  /* __KERNEL_CS */
236           .quad     0x00cf92000000ffff  /* __KERNEL_DS */
237           .quad     0x0080890000000000  /* TS descriptor */
238           .quad     0x0000000000000000    /* TS continued */
239 gdt_end:
240
241           .align 16
242 boot_stack:
243           .fill BOOT_STACK_SIZE, 1, 0
244 boot_stack_end:
245
246           .section ".pgtable","a",@nobits
247           .align 4096
248 pgtable:
249           .fill 7*4096, 1, 0
250
251