xv6

port of xv6 to x86-64
git clone http://frotz.net/git/xv6.git
Log | Files | Refs | README | LICENSE

entry64.S (3882B)


      1 /* entry64.S 
      2  *
      3  * Copyright (c) 2013 Brian Swetland
      4  * 
      5  * Permission is hereby granted, free of charge, to any person obtaining
      6  * a copy of this software and associated documentation files (the
      7  * "Software"), to deal in the Software without restriction, including
      8  * without limitation the rights to use, copy, modify, merge, publish,
      9  * distribute, sublicense, and/or sell copies of the Software, and to
     10  * permit persons to whom the Software is furnished to do so, subject to
     11  * the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be
     14  * included in all copies or substantial portions of the Software.
     15  * 
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     19  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
     20  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
     21  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     22  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     23  *
     24  */
     25 
     26 #define mboot_magic 0x1badb002
     27 #define mboot_flags 0x00010000
     28 
     29 .code32
     30 .global mboot_header
     31 .global mboot_entry
     32 
     33 mboot_header:
     34   .long mboot_magic
     35   .long mboot_flags
     36   .long (-mboot_magic -mboot_flags)	# checksum
     37   .long mboot_load_addr			# header_addr
     38   .long mboot_load_addr
     39   .long mboot_load_end
     40   .long mboot_bss_end
     41   .long mboot_entry_addr
     42 
     43 mboot_entry:
     44 
     45 # zero 4 pages for our bootstrap page tables
     46   xor %eax, %eax
     47   mov $0x1000, %edi
     48   mov $0x5000, %ecx
     49   rep stosb
     50 
     51 # P4ML[0] -> 0x2000 (PDPT-A)
     52   mov $(0x2000 | 3), %eax
     53   mov %eax, 0x1000
     54 
     55 # P4ML[511] -> 0x3000 (PDPT-B)
     56   mov $(0x3000 | 3), %eax
     57   mov %eax, 0x1FF8
     58 
     59 # PDPT-A[0] -> 0x4000 (PD)
     60   mov $(0x4000 | 3), %eax
     61   mov %eax, 0x2000
     62 
     63 # PDPT-B[510] -> 0x4000 (PD)
     64   mov $(0x4000 | 3), %eax
     65   mov %eax, 0x3FF0
     66 
     67 # PD[0..511] -> 0..1022MB
     68   mov $0x83, %eax
     69   mov $0x4000, %ebx
     70   mov $512, %ecx
     71 ptbl_loop:
     72   mov %eax, (%ebx)
     73   add $0x200000, %eax
     74   add $0x8, %ebx
     75   dec %ecx
     76   jnz ptbl_loop
     77 
     78 # Clear ebx for initial processor boot.
     79 # When secondary processors boot, they'll call through
     80 # entry32mp (from entryother), but with a nonzero ebx.
     81 # We'll reuse these bootstrap pagetables and GDT.
     82   xor %ebx, %ebx
     83 
     84 .global entry32mp
     85 entry32mp:
     86 # CR3 -> 0x1000 (P4ML)
     87   mov $0x1000, %eax
     88   mov %eax, %cr3
     89 
     90   lgdt (gdtr64 - mboot_header + mboot_load_addr)
     91 
     92 # Enable PAE - CR4.PAE=1
     93   mov %cr4, %eax
     94   bts $5, %eax
     95   mov %eax, %cr4
     96 
     97 # enable long mode - EFER.LME=1
     98   mov $0xc0000080, %ecx
     99   rdmsr
    100   bts $8, %eax
    101   wrmsr
    102 
    103 # enable paging
    104   mov %cr0, %eax
    105   bts $31, %eax
    106   mov %eax, %cr0
    107 
    108 # shift to 64bit segment
    109   ljmp $8,$(entry64low - mboot_header + mboot_load_addr)
    110 
    111 .align 16
    112 gdtr64:
    113   .word gdt64_end - gdt64_begin - 1;
    114   .quad gdt64_begin - mboot_header + mboot_load_addr
    115 
    116 .align 16
    117 gdt64_begin:
    118   .long 0x00000000 # 0: null desc
    119   .long 0x00000000
    120   .long 0x00000000 # 1: Code, R/X, Nonconforming
    121   .long 0x00209800
    122   .long 0x00000000 # 2: Data, R/W, Expand Down
    123   .long 0x00009000
    124 gdt64_end:
    125 
    126 .align 16
    127 .code64
    128 entry64low:
    129   movq $entry64high, %rax
    130   jmp *%rax
    131 
    132 .global _start
    133 _start:
    134 entry64high:
    135 
    136 # ensure data segment registers are sane
    137   xor %rax, %rax
    138   mov %ax, %ss
    139   mov %ax, %ds
    140   mov %ax, %es
    141   mov %ax, %fs
    142   mov %ax, %gs
    143 
    144 # check to see if we're booting a secondary core
    145   test %ebx, %ebx
    146   jnz entry64mp
    147 
    148 # setup initial stack
    149   mov $0xFFFFFFFF80010000, %rax
    150   mov %rax, %rsp
    151 
    152 # enter main()
    153   jmp main
    154 
    155 .global __deadloop
    156 __deadloop:
    157 # we should never return here...
    158   jmp .
    159 
    160 entry64mp:
    161 # obtain kstack from data block before entryother
    162   mov $0x7000, %rax
    163   mov -16(%rax), %rsp
    164   jmp mpenter
    165 
    166 .global wrmsr
    167 wrmsr:
    168   mov %rdi, %rcx     # arg0 -> msrnum
    169   mov %rsi, %rax     # val.low -> eax
    170   shr $32, %rsi
    171   mov %rsi, %rdx     # val.high -> edx
    172   wrmsr
    173   retq
    174