Add AP startup assembly trampoline for i686
All checks were successful
All checks were successful
This commit is contained in:
@@ -54,4 +54,13 @@ GenerateAssemblyDefinitions(VOID)
|
||||
/* Generate KTRAP_FRAME size and REGISTERS_SIZE */
|
||||
ADK_SIZE(KTRAP_FRAME);
|
||||
ADK_SIZE_FROM(REGISTERS_SIZE, KTRAP_FRAME, Eax);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
@@ -137,8 +137,8 @@
|
||||
#define KERNEL_STACK_GUARD_PAGES 1
|
||||
|
||||
/* Processor structures size */
|
||||
#define KPROCESSOR_STRUCTURES_SIZE ((2 * KERNEL_STACK_SIZE) + (GDT_ENTRIES * sizeof(KGDTENTRY)) + sizeof(KTSS) + \
|
||||
sizeof(KPROCESSOR_BLOCK) + MM_PAGE_SIZE)
|
||||
#define KPROCESSOR_STRUCTURES_SIZE ((KERNEL_STACKS * KERNEL_STACK_SIZE) + (GDT_ENTRIES * sizeof(KGDTENTRY)) + \
|
||||
sizeof(KTSS) + sizeof(KPROCESSOR_BLOCK) + MM_PAGE_SIZE)
|
||||
|
||||
/* Kernel frames */
|
||||
#define KTRAP_FRAME_ALIGN 0x08
|
||||
@@ -431,6 +431,18 @@ typedef struct _KSPECIAL_REGISTERS
|
||||
ULONG Reserved[6];
|
||||
} 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 */
|
||||
typedef struct _KPROCESSOR_STATE
|
||||
{
|
||||
|
||||
@@ -234,7 +234,7 @@ _ArHandleSpuriousInterrupt:
|
||||
iret
|
||||
|
||||
/**
|
||||
* Starts an application processor (AP). This is just a stub.
|
||||
* Starts an application processor (AP).
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
@@ -242,6 +242,93 @@ _ArHandleSpuriousInterrupt:
|
||||
*/
|
||||
.global _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
|
||||
movw $0x1000, %sp
|
||||
|
||||
/* Calculate absolute physical base address */
|
||||
xorl %ebx, %ebx
|
||||
movw %cs, %bx
|
||||
shll $4, %ebx
|
||||
|
||||
/* 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 $0x10, %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 $~0x00020080, %eax
|
||||
movl %eax, %cr4
|
||||
|
||||
/* Load the Kernel Page Directory Base from BSP */
|
||||
movl PROCESSOR_START_BLOCK_Cr3(%edi), %eax
|
||||
movl %eax, %cr3
|
||||
|
||||
/* Enable Paging */
|
||||
movl %cr0, %eax
|
||||
orl $0x80000000, %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
/* Load dedicated Stack for AP */
|
||||
movl PROCESSOR_START_BLOCK_Stack(%edi), %esp
|
||||
|
||||
/* Save the pointer to PROCESSOR_START_BLOCK */
|
||||
movl %edi, %ecx
|
||||
pushl %edi
|
||||
|
||||
/* Call the EntryPoint routine */
|
||||
movl PROCESSOR_START_BLOCK_EntryPoint(%edi), %eax
|
||||
call *%eax
|
||||
|
||||
/* 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: .long 0x00000000
|
||||
ApTemporaryGdtDesc: .quad 0x0000000000000000, 0x00CF9A000000FFFF, 0x00CF92000000FFFF
|
||||
|
||||
.global _ArStartApplicationProcessorEnd
|
||||
_ArStartApplicationProcessorEnd:
|
||||
|
||||
Reference in New Issue
Block a user