169 lines
2.8 KiB
NASM
169 lines
2.8 KiB
NASM
|
|
title "Amd64 startup"
|
|
|
|
;++
|
|
;
|
|
; Copyright (c) 2001 Microsoft Corporation
|
|
;
|
|
; Module Name:
|
|
;
|
|
; xmstub.asm
|
|
;
|
|
; Abstract:
|
|
;
|
|
; This module implements the code that starts secondary processors. This
|
|
; module is unique in that it is assembled by the i386 32-bit assembler,
|
|
; because the Amd64 assembler does not assemble 16- or 32-bit x86 code.
|
|
;
|
|
; The .obj file that is the result of assembling this module is fed
|
|
; through a tool, DMPOBJ.EXE, that stores the contents of the relevant
|
|
; section and generates a c file (startup.c) that can be included in the
|
|
; 64-bit compilation process.
|
|
;
|
|
; Author:
|
|
;
|
|
; Forrest Foltz (forrestf) March 6, 2001
|
|
;
|
|
; Environment:
|
|
;
|
|
; Kernel mode only.
|
|
;
|
|
; Revision History:
|
|
;
|
|
;--
|
|
|
|
.586p
|
|
|
|
include ksamd64.inc
|
|
|
|
RMSTUB SEGMENT DWORD PUBLIC USE16 'CODE'
|
|
|
|
;++
|
|
;
|
|
; VOID
|
|
; StartPx_RMStub
|
|
;
|
|
; When a new processor is started, it starts in real mode and is sent to a
|
|
; copy of this function which resides in low (<1MB) memory.
|
|
;
|
|
; When this function is complete, it jumps to StartPx_PMStub.
|
|
;
|
|
; Arguments:
|
|
; None
|
|
;
|
|
; Return Value:
|
|
; Does not return, jumps to StartPx_PMStub
|
|
;--
|
|
|
|
StartPx_RMStub:
|
|
|
|
jmp spr10 ; skip the processor start block
|
|
|
|
db (ProcessorStartBlockLength - ($ - StartPx_RMStub)) dup (0)
|
|
|
|
spr10: cli
|
|
mov ax, cs
|
|
mov ds, ax
|
|
|
|
;
|
|
; Load the 32-bit GDT.
|
|
;
|
|
|
|
db 066h
|
|
lgdt fword ptr ds:[PsbGdt32]
|
|
|
|
;
|
|
; Load edi with the linear address of the processor start block.
|
|
;
|
|
|
|
sub eax, eax
|
|
mov ax, ds
|
|
shl eax, 4
|
|
mov edi, eax
|
|
|
|
;
|
|
; Enter protected mode. Note paging is still off.
|
|
;
|
|
|
|
mov eax, cr0
|
|
or eax, CR0_PE OR CR0_ET
|
|
mov cr0, eax
|
|
|
|
;
|
|
; Load CS by performing a far jump to the protected mode target
|
|
; address
|
|
;
|
|
|
|
db 066h
|
|
jmp DWORD PTR ds:[PsbPmTarget]
|
|
|
|
RMSTUB ENDS
|
|
|
|
;++
|
|
;
|
|
; VOID
|
|
; StartPx_PMStub
|
|
;
|
|
; When a new processor is started, it starts in real mode and is sent to a
|
|
; copy of this function which resides in low (<1MB) memory.
|
|
;
|
|
; When this function is complete, it jumps to StartPx_PMStub.
|
|
;
|
|
; Arguments:
|
|
; None
|
|
;
|
|
; Return Value:
|
|
; Does not return, jumps to StartPx_LMStub
|
|
;--
|
|
|
|
|
|
PMSTUB SEGMENT PARA PUBLIC 'CODE'
|
|
|
|
StartPx_PMStub:
|
|
|
|
;
|
|
; 32-bit protected-mode boot code goes here. We are still executing
|
|
; the low-memory, identity-mapped copy of this code.
|
|
;
|
|
; edi -> linear address of PROCESSOR_START_BLOCK
|
|
;
|
|
|
|
;
|
|
; Enable PAE mode (requisite for LongMode), load the tiled CR3
|
|
;
|
|
|
|
mov eax, cr4
|
|
or eax, CR4_PAE
|
|
mov cr4, eax
|
|
|
|
mov eax, DWORD PTR [edi] + PsbTiledCr3
|
|
mov cr3, eax
|
|
|
|
;
|
|
; Set the long mode enable bit in the EFER msr
|
|
;
|
|
|
|
mov ecx, MSR_EFER
|
|
rdmsr
|
|
or eax, MSR_LMA
|
|
wrmsr
|
|
|
|
;
|
|
; Enable paging and activate long mode
|
|
;
|
|
|
|
mov eax, cr0
|
|
or eax, CR0_PG
|
|
mov cr0, eax
|
|
|
|
;
|
|
; Still in 32-bit legacy mode until we branch to a long mode
|
|
; code selector
|
|
;
|
|
|
|
jmp FAR PTR [edi] + PsbLmTarget
|
|
|
|
PMSTUB ENDS
|
|
|
|
END
|