Add AP startup assembly trampoline for AMD64
All checks were successful
All checks were successful
This commit is contained in:
@@ -80,4 +80,13 @@ GenerateAssemblyDefinitions(VOID)
|
|||||||
/* Generate KTRAP_FRAME size and REGISTERS_SIZE */
|
/* Generate KTRAP_FRAME size and REGISTERS_SIZE */
|
||||||
ADK_SIZE(KTRAP_FRAME);
|
ADK_SIZE(KTRAP_FRAME);
|
||||||
ADK_SIZE_FROM(REGISTERS_SIZE, KTRAP_FRAME, Rax);
|
ADK_SIZE_FROM(REGISTERS_SIZE, KTRAP_FRAME, Rax);
|
||||||
|
|
||||||
|
/* Generate PROCESSOR_START_BLOCK offsets */
|
||||||
|
ADK_OFFSET(PROCESSOR_START_BLOCK, Cr3);
|
||||||
|
ADK_OFFSET(PROCESSOR_START_BLOCK, Cr4);
|
||||||
|
ADK_OFFSET(PROCESSOR_START_BLOCK, EntryPoint);
|
||||||
|
ADK_OFFSET(PROCESSOR_START_BLOCK, ProcessorBlock);
|
||||||
|
ADK_OFFSET(PROCESSOR_START_BLOCK, ProcessorNumber);
|
||||||
|
ADK_OFFSET(PROCESSOR_START_BLOCK, Stack);
|
||||||
|
ADK_OFFSET(PROCESSOR_START_BLOCK, Started);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,8 +118,8 @@
|
|||||||
#define KERNEL_STACK_GUARD_PAGES 1
|
#define KERNEL_STACK_GUARD_PAGES 1
|
||||||
|
|
||||||
/* Processor structures size */
|
/* Processor structures size */
|
||||||
#define KPROCESSOR_STRUCTURES_SIZE ((2 * KERNEL_STACK_SIZE) + (GDT_ENTRIES * sizeof(KGDTENTRY)) + sizeof(KTSS) + \
|
#define KPROCESSOR_STRUCTURES_SIZE ((KERNEL_STACKS * KERNEL_STACK_SIZE) + (GDT_ENTRIES * sizeof(KGDTENTRY)) + \
|
||||||
sizeof(KPROCESSOR_BLOCK) + MM_PAGE_SIZE)
|
sizeof(KTSS) + sizeof(KPROCESSOR_BLOCK) + MM_PAGE_SIZE)
|
||||||
|
|
||||||
/* Kernel frames */
|
/* Kernel frames */
|
||||||
#define KEXCEPTION_FRAME_SIZE sizeof(KEXCEPTION_FRAME)
|
#define KEXCEPTION_FRAME_SIZE sizeof(KEXCEPTION_FRAME)
|
||||||
@@ -470,11 +470,23 @@ typedef struct _KSPECIAL_REGISTERS
|
|||||||
ULONG64 MsrSyscallMask;
|
ULONG64 MsrSyscallMask;
|
||||||
} KSPECIAL_REGISTERS, *PKSPECIAL_REGISTERS;
|
} KSPECIAL_REGISTERS, *PKSPECIAL_REGISTERS;
|
||||||
|
|
||||||
|
/* Processor start block structure definition */
|
||||||
|
typedef struct _PROCESSOR_START_BLOCK
|
||||||
|
{
|
||||||
|
ULONG_PTR Cr3;
|
||||||
|
ULONG_PTR Cr4;
|
||||||
|
PVOID EntryPoint;
|
||||||
|
PVOID ProcessorBlock;
|
||||||
|
ULONG ProcessorNumber;
|
||||||
|
PVOID Stack;
|
||||||
|
BOOLEAN Started;
|
||||||
|
} PROCESSOR_START_BLOCK, *PPROCESSOR_START_BLOCK;
|
||||||
|
|
||||||
/* Processor state frame structure definition */
|
/* Processor state frame structure definition */
|
||||||
typedef struct _KPROCESSOR_STATE
|
typedef struct _KPROCESSOR_STATE
|
||||||
{
|
{
|
||||||
KSPECIAL_REGISTERS SpecialRegisters;
|
|
||||||
CONTEXT ContextFrame;
|
CONTEXT ContextFrame;
|
||||||
|
KSPECIAL_REGISTERS SpecialRegisters;
|
||||||
} KPROCESSOR_STATE, *PKPROCESSOR_STATE;
|
} KPROCESSOR_STATE, *PKPROCESSOR_STATE;
|
||||||
|
|
||||||
/* Processor Control Block (PRCB) structure definition */
|
/* Processor Control Block (PRCB) structure definition */
|
||||||
|
|||||||
@@ -359,7 +359,7 @@ ArHandleSpuriousInterrupt:
|
|||||||
iretq
|
iretq
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts an application processor (AP). This is just a stub.
|
* Starts an application processor (AP).
|
||||||
*
|
*
|
||||||
* @return This routine does not return any value.
|
* @return This routine does not return any value.
|
||||||
*
|
*
|
||||||
@@ -367,6 +367,123 @@ ArHandleSpuriousInterrupt:
|
|||||||
*/
|
*/
|
||||||
.global ArStartApplicationProcessor
|
.global ArStartApplicationProcessor
|
||||||
ArStartApplicationProcessor:
|
ArStartApplicationProcessor:
|
||||||
|
/* Enter 16-bit real mode */
|
||||||
|
.code16
|
||||||
|
|
||||||
|
/* Disable interrupts and clear direction flag */
|
||||||
|
cli
|
||||||
|
cld
|
||||||
|
|
||||||
|
/* Establish a flat addressing baseline */
|
||||||
|
movw %cs, %ax
|
||||||
|
movw %ax, %ds
|
||||||
|
movw %ax, %es
|
||||||
|
movw %ax, %ss
|
||||||
|
|
||||||
|
/* Calculate absolute physical base address */
|
||||||
|
xorl %ebx, %ebx
|
||||||
|
movw %cs, %bx
|
||||||
|
shll $4, %ebx
|
||||||
|
|
||||||
|
/* Set up a temporary stack for the AP initialization */
|
||||||
|
movl %ebx, %esp
|
||||||
|
addl $0x1000, %esp
|
||||||
|
|
||||||
|
/* Load the temporary Global Descriptor Table */
|
||||||
|
leal (ApTemporaryGdtDesc - ArStartApplicationProcessor)(%ebx), %eax
|
||||||
|
movl %eax, (ApTemporaryGdtBase - ArStartApplicationProcessor)
|
||||||
|
lgdtl (ApTemporaryGdtSize - ArStartApplicationProcessor)
|
||||||
|
|
||||||
|
/* Enable Protected Mode */
|
||||||
|
movl %cr0, %eax
|
||||||
|
orl $0x01, %eax
|
||||||
|
movl %eax, %cr0
|
||||||
|
|
||||||
|
/* Far return to enter 32-bit protected mode */
|
||||||
|
leal (ApEnterProtectedMode - ArStartApplicationProcessor)(%ebx), %eax
|
||||||
|
pushl $0x08
|
||||||
|
pushl %eax
|
||||||
|
lretl
|
||||||
|
|
||||||
|
ApEnterProtectedMode:
|
||||||
|
/* Enter 32-bit protected mode */
|
||||||
|
.code32
|
||||||
|
|
||||||
|
/* Setup all data segment registers */
|
||||||
|
movw $0x18, %ax
|
||||||
|
movw %ax, %ds
|
||||||
|
movw %ax, %es
|
||||||
|
movw %ax, %ss
|
||||||
|
xorw %ax, %ax
|
||||||
|
movw %ax, %fs
|
||||||
|
movw %ax, %gs
|
||||||
|
|
||||||
|
/* Locate PROCESSOR_START_BLOCK structure */
|
||||||
|
leal (ArStartApplicationProcessorEnd - ArStartApplicationProcessor)(%ebx), %edi
|
||||||
|
|
||||||
|
/* Load CR4 from BSP, but mask PCIDE and PGE */
|
||||||
|
movl PROCESSOR_START_BLOCK_Cr4(%edi), %eax
|
||||||
|
andl $~(CR4_PGE | CR4_PCIDE), %eax
|
||||||
|
movl %eax, %cr4
|
||||||
|
|
||||||
|
/* Load the Kernel Page Directory Base from BSP */
|
||||||
|
movl PROCESSOR_START_BLOCK_Cr3(%edi), %eax
|
||||||
|
movl %eax, %cr3
|
||||||
|
|
||||||
|
/* Enable Long Mode and No-Execute */
|
||||||
|
movl $0xC0000080, %ecx
|
||||||
|
rdmsr
|
||||||
|
orl $0x00000900, %eax
|
||||||
|
wrmsr
|
||||||
|
|
||||||
|
/* Enable Paging */
|
||||||
|
movl %cr0, %eax
|
||||||
|
orl $0x80000000, %eax
|
||||||
|
movl %eax, %cr0
|
||||||
|
|
||||||
|
/* Far return to enter 64-bit long mode */
|
||||||
|
leal (ApEnterLongMode - ArStartApplicationProcessor)(%ebx), %eax
|
||||||
|
pushl $0x10
|
||||||
|
pushl %eax
|
||||||
|
lretl
|
||||||
|
|
||||||
|
ApEnterLongMode:
|
||||||
|
/* Enter 64-bit long mode */
|
||||||
|
.code64
|
||||||
|
|
||||||
|
/* Clear all segment registers */
|
||||||
|
xorw %ax, %ax
|
||||||
|
movw %ax, %ds
|
||||||
|
movw %ax, %es
|
||||||
|
movw %ax, %ss
|
||||||
|
movw %ax, %fs
|
||||||
|
movw %ax, %gs
|
||||||
|
|
||||||
|
/* Zero-extend EDI into RDI to ensure safe 64-bit pointer usage */
|
||||||
|
movl %edi, %edi
|
||||||
|
|
||||||
|
/* Load dedicated Stack for AP */
|
||||||
|
movq PROCESSOR_START_BLOCK_Stack(%rdi), %rsp
|
||||||
|
|
||||||
|
/* Save the pointer to PROCESSOR_START_BLOCK */
|
||||||
|
movq %rdi, %rcx
|
||||||
|
pushq %rdi
|
||||||
|
|
||||||
|
/* Call the EntryPoint routine */
|
||||||
|
movq PROCESSOR_START_BLOCK_EntryPoint(%rdi), %rax
|
||||||
|
call *%rax
|
||||||
|
|
||||||
|
/* Fire the breakpoint and halt if the entry point returns */
|
||||||
|
.ApNoReturnPoint:
|
||||||
|
int $0x03
|
||||||
|
hlt
|
||||||
|
jmp .ApNoReturnPoint
|
||||||
|
|
||||||
|
/* Data section for temporary GDT */
|
||||||
|
.align 8
|
||||||
|
ApTemporaryGdtSize: .short ArStartApplicationProcessorEnd - ApTemporaryGdtDesc - 1
|
||||||
|
ApTemporaryGdtBase: .quad 0x0000000000000000
|
||||||
|
ApTemporaryGdtDesc: .quad 0x0000000000000000, 0x00CF9A000000FFFF, 0x00AF9A000000FFFF, 0x00CF92000000FFFF
|
||||||
|
|
||||||
.global ArStartApplicationProcessorEnd
|
.global ArStartApplicationProcessorEnd
|
||||||
ArStartApplicationProcessorEnd:
|
ArStartApplicationProcessorEnd:
|
||||||
|
|||||||
Reference in New Issue
Block a user