Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/amd64/src/boot/multiboot2.S

    r17aa6d1 rbae43dc  
    3535#include <genarch/multiboot/multiboot2.h>
    3636
     37#define START_STACK  (BOOT_OFFSET - BOOT_STACK_SIZE)
     38
    3739.section K_TEXT_START, "ax"
    3840
     
    7880                .word MULTIBOOT2_FLAGS_REQUIRED
    7981                .long tag_entry_address_end - tag_entry_address_start
    80                 .long multiboot_image_start
     82                .long multiboot2_image_start
    8183        tag_entry_address_end:
    8284
     
    120122        tag_terminator_end:
    121123multiboot2_header_end:
     124
     125SYMBOL(multiboot2_image_start)
     126        cli
     127        cld
     128
     129        /* Initialize stack pointer */
     130        movl $START_STACK, %esp
     131
     132        /*
     133         * Initialize Global Descriptor Table and
     134         * Interrupt Descriptor Table registers
     135         */
     136        lgdtl bootstrap_gdtr
     137        lidtl bootstrap_idtr
     138
     139        /* Kernel data + stack */
     140        movw $GDT_SELECTOR(KDATA_DES), %cx
     141        movw %cx, %es
     142        movw %cx, %ds
     143        movw %cx, %ss
     144
     145        /*
     146         * Simics seems to remove hidden part of GS on entering user mode
     147         * when _visible_ part of GS does not point to user-mode segment.
     148         */
     149        movw $GDT_SELECTOR(UDATA_DES), %cx
     150        movw %cx, %fs
     151        movw %cx, %gs
     152
     153        jmpl $GDT_SELECTOR(KTEXT32_DES), $multiboot2_meeting_point
     154        multiboot2_meeting_point:
     155
     156        /*
     157         * Protected 32-bit. We want to reuse the code-seg descriptor,
     158         * the Default operand size must not be 1 when entering long mode.
     159         */
     160
     161        /* Save multiboot arguments */
     162        movl %eax, multiboot_eax
     163        movl %ebx, multiboot_ebx
     164
     165        movl $(INTEL_CPUID_EXTENDED), %eax
     166        cpuid
     167        cmp $(INTEL_CPUID_EXTENDED), %eax
     168        ja extended_cpuid_supported
     169
     170                jmp pm_error_halt
     171
     172        extended_cpuid_supported:
     173
     174        movl $(AMD_CPUID_EXTENDED), %eax
     175        cpuid
     176        bt $(AMD_EXT_LONG_MODE), %edx
     177        jc long_mode_supported
     178
     179                jmp pm_error_halt
     180
     181        long_mode_supported:
     182
     183        bt $(AMD_EXT_NOEXECUTE), %edx
     184        jc noexecute_supported
     185
     186                jmp pm_error_halt
     187
     188        noexecute_supported:
     189
     190        movl $(INTEL_CPUID_STANDARD), %eax
     191        cpuid
     192        bt $(INTEL_FXSAVE), %edx
     193        jc fx_supported
     194
     195                jmp pm_error_halt
     196
     197        fx_supported:
     198
     199        bt $(INTEL_SSE2), %edx
     200        jc sse2_supported
     201
     202                jmp pm_error_halt
     203
     204        sse2_supported:
     205
     206        /*
     207         * Enable 64-bit page translation entries - CR4.PAE = 1.
     208         * Paging is not enabled until after long mode is enabled.
     209         */
     210
     211        movl %cr4, %eax
     212        orl $CR4_PAE, %eax
     213        movl %eax, %cr4
     214
     215        /* Set up paging tables */
     216        leal ptl_0, %eax
     217        movl %eax, %cr3
     218
     219        /* Enable long mode */
     220        movl $AMD_MSR_EFER, %ecx
     221        rdmsr                     /* read EFER */
     222        orl $AMD_LME, %eax        /* set LME = 1 */
     223        wrmsr
     224
     225        /* Enable paging to activate long mode (set CR0.PG = 1) */
     226        movl %cr0, %eax
     227        orl $CR0_PG, %eax
     228        movl %eax, %cr0
     229
     230        /* At this point we are in compatibility mode */
     231        jmpl $GDT_SELECTOR(KTEXT_DES), $start64
     232
     233pm_error_halt:
     234        cli
     235        hlt1:
     236                hlt
     237                jmp hlt1
     238
     239.code64
     240
     241start64:
     242
     243        /*
     244         * Long mode.
     245         */
     246
     247        movq $(PA2KA(START_STACK)), %rsp
     248
     249        /* Create the first stack frame */
     250        pushq $0
     251        movq %rsp, %rbp
     252
     253        /* Call amd64_pre_main(multiboot_eax, multiboot_ebx) */
     254        movl multiboot_eax, %edi
     255        movl multiboot_ebx, %esi
     256
     257#ifdef MEMORY_MODEL_large
     258        movabsq $amd64_pre_main, %rax
     259        callq *%rax
     260#else
     261        callq amd64_pre_main
     262#endif
     263
     264        /* Call main_bsp() */
     265#ifdef MEMORY_MODEL_large
     266        movabsq $main_bsp, %rax
     267        callq *%rax
     268#else
     269        callq main_bsp
     270#endif
     271
     272        /* Not reached */
     273        cli
     274        hlt0:
     275                hlt
     276                jmp hlt0
Note: See TracChangeset for help on using the changeset viewer.