Splits x86 into 32 and 64 bit (XCC)
[akaros.git] / kern / arch / x86 / entry64.S
1 /* Copyright (c) 2009-13 The Regents of the University of California
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * See LICENSE for details. */
4
5 #include <arch/mmu.h>
6 #include <arch/trap.h>
7 #include <ros/memlayout.h>
8
9 # Shift Right Logical 
10 #define SRL(val, shamt)         (((val) >> (shamt)) & ~(-1 << (32 - (shamt))))
11
12 .set CODE_SEL,0x8               # index of code seg within mygdt
13 .set DATA_SEL,0x10              # index of data seg within mygdt
14
15 #define MULTIBOOT_PAGE_ALIGN  (1<<0)
16 #define MULTIBOOT_MEMORY_INFO (1<<1)
17 #define MULTIBOOT_HEADER_MAGIC (0x1BADB002)
18 #define MULTIBOOT_HEADER_FLAGS (MULTIBOOT_MEMORY_INFO | MULTIBOOT_PAGE_ALIGN)
19 #define CHECKSUM (-(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS))
20
21 # The kernel bootstrap (this code) is linked and loaded at physical address
22 # 0x00100000 (1MB), which is the start of extended memory.  (See kernel.ld)
23
24 # Flagging boottext to be text.  Check out:
25 # http://sourceware.org/binutils/docs/as/Section.html
26 .section .boottext, "awx"
27
28 .code32
29 .align 4
30 multiboot_header:
31 .long MULTIBOOT_HEADER_MAGIC
32 .long MULTIBOOT_HEADER_FLAGS
33 .long CHECKSUM
34
35 .globl          _start
36 _start:
37         movw    $0x1234,0x472                   # warm boot
38         # Reload all segment registers (including CS!) with flag segment selectors
39         # from our boot GDT.
40         lgdt    mygdtdesc
41         movl    $DATA_SEL, %eax
42         movw    %ax,%ds
43         movw    %ax,%es
44         movw    %ax,%ss
45         ljmp    $CODE_SEL,$newcs                # reload CS by jumping
46 newcs:
47         # build page table.  need a mapping for current code at 0x00100000 and a
48         # basic kernbase mapping.  we're using the 32 bit second PT (aka, pg_dir),
49         # which covers 4MB per entry
50         movl    $boot_pdt, %edx
51         # identity map the first jumbo PTE from 0x0 -> 0x0
52         movl    $(PTE_P | PTE_W | PTE_PS), (%edx)
53         # map KERNBASE -> 0 for 200 MB
54         movl    $50, %ecx
55         # init loop, eax at paddr 0, and edx is advanced by KERNBASE mapping slots
56         # (with 4 bytes per PTE).
57         # XXX addl      $((KERNBASE >> PTSHIFT) << 2), %edx
58         movl    $(PTE_P | PTE_W | PTE_PS), %eax
59 loop:
60         movl    %eax, (%edx)
61         addl    $PTSIZE, %eax
62         addl    $4, %edx
63         decl    %ecx
64         jnz             loop
65
66 # hack to compile / link
67 spin2:
68         jmp spin2
69
70         # load cr3 and turn on paging.  note we assume PSE support.  if we didn't
71         # have it, then our jumbo page mappings are going to fail.
72         movl    $boot_pdt, %eax
73         movl    %eax, %cr3
74         movl    %cr4, %eax
75         orl             $(CR4_PSE | CR4_PGE), %eax
76         movl    %eax, %cr4
77         movl    %cr0, %eax
78         orl             $(CR0_PE | CR0_PG | CR0_AM | CR0_WP | CR0_NE | CR0_MP), %eax  
79         andl    $(~(CR0_TS | CR0_EM | CR0_CD | CR0_NW)), %eax  
80         movl    %eax, %cr0
81         # paging is on, and our code is still running at 0x00100000 do some
82         # miscellaneous OS setup.  the coreid stuff is so we can call core_id()
83         # before smp_boot.  this is the only arch-dependent code called before then.
84 .code64 # temp hack for linkage.  also, this symbol is too far at link time
85         movabs  $(os_coreid_lookup), %rax
86         movl    $0x0, (%rax)
87         movabs  $(hw_coreid_lookup), %rax
88         movl    $0x0, (%rax)
89         # Clear the frame pointer register (EBP)
90         # so that once we get into debugging C code,
91         # stack backtraces will be terminated properly.
92         movl    $0x0,%ebp
93         movabs  $(bootstacktop),%rsp
94         # Save multiboot info
95         push    %rbx
96         movabs  $(num_cpus), %rax
97         movl    $0x1, (%rax)
98
99         movabs  $(kernel_init), %rax
100         call    *%rax
101         # Should never get here, but in case we do, just spin.
102 spin:   jmp     spin
103
104 .section .bootdata, "aw"
105         .p2align        2               # force 4 byte alignment
106 mygdt:
107         SEG_NULL                        # null seg
108         SEG(STA_X|STA_R, 0, 0xffffffff) # code seg
109         SEG(STA_W, 0, 0xffffffff)       # data seg
110 mygdtdesc:
111         .word   0x17            # sizeof(mygdt) - 1
112         .long   mygdt           # address mygdt
113 # boot page directory.  going to use jumbo page entries
114         .align PGSIZE
115 boot_pdt:
116         .space  PGSIZE
117
118
119 # From here down is linked for KERNBASE
120
121 ###################################################################     
122 # See <inc/memlayout.h> for a complete description of these two symbols.
123 ###################################################################
124 .data
125         .globl  vpt
126         .quad   vpt
127         .set    vpt, VPT
128         .globl  vpd
129         .quad   vpd
130         .set    vpd, (VPT + SRL(VPT, 10))
131
132 ###################################################################
133 # boot stack
134 ###################################################################
135         .p2align        PGSHIFT         # force page alignment
136         .globl          bootstack
137 bootstack:
138         .space          KSTKSIZE
139         .globl          bootstacktop   
140 bootstacktop:
141