1e6544e62c74b0369675003a19a2e6419d51da83
[akaros.git] / kern / arch / x86 / entry32.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 1GB (1/4 of the 1024 entries)
54         movl    $256, %ecx
55         # init loop, eax at paddr 0, and edx is advanced by KERNBASE mapping slots
56         # (with 4 bytes per PTE).
57         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         # load cr3 and turn on paging.  note we assume PSE support.  if we didn't
66         # have it, then our jumbo page mappings are going to fail.
67         movl    $boot_pdt, %eax
68         movl    %eax, %cr3
69         movl    %cr4, %eax
70         orl             $(CR4_PSE | CR4_PGE), %eax
71         movl    %eax, %cr4
72         movl    %cr0, %eax
73         orl             $(CR0_PE | CR0_PG | CR0_AM | CR0_WP | CR0_NE | CR0_MP), %eax  
74         andl    $(~(CR0_TS | CR0_EM | CR0_CD | CR0_NW)), %eax  
75         movl    %eax, %cr0
76         # paging is on, and our code is still running at 0x00100000 do some
77         # miscellaneous OS setup.  the coreid stuff is so we can call core_id()
78         # before smp_boot.  this is the only arch-dependent code called before then.
79         movl    $0x0, os_coreid_lookup
80         movl    $0x0, hw_coreid_lookup
81         # Clear the frame pointer register (EBP)
82         # so that once we get into debugging C code,
83         # stack backtraces will be terminated properly.
84         movl    $0x0,%ebp
85         movl    $(bootstacktop),%esp
86         # Save multiboot info
87         push    %ebx
88         movl    $0x1,num_cpus           # init global var, for now
89         call    kernel_init
90         # Should never get here, but in case we do, just spin.
91 spin:   jmp     spin
92
93 .section .bootdata, "aw"
94         .p2align        2               # force 4 byte alignment
95 mygdt:
96         SEG_NULL                        # null seg
97         SEG(STA_X|STA_R, 0, 0xffffffff) # code seg
98         SEG(STA_W, 0, 0xffffffff)       # data seg
99 mygdtdesc:
100         .word   0x17            # sizeof(mygdt) - 1
101         .long   mygdt           # address mygdt
102 # boot page directory.  going to use jumbo page entries
103         .align PGSIZE
104 boot_pdt:
105         .space  PGSIZE
106
107
108 # From here down is linked for KERNBASE
109
110 ###################################################################     
111 # See <inc/memlayout.h> for a complete description of these two symbols.
112 ###################################################################
113 .data
114         .globl  vpt
115         .set    vpt, VPT
116         .globl  vpd
117         .set    vpd, (VPT + SRL(VPT, 10))
118
119 ###################################################################
120 # boot stack
121 ###################################################################
122         .p2align        PGSHIFT         # force page alignment
123         .globl          bootstack
124 bootstack:
125         .space          KSTKSIZE
126         .globl          bootstacktop   
127 bootstacktop:
128