From b1ecdc3439d42b0308468c8197e62d7e03c05ef9 Mon Sep 17 00:00:00 2001 From: Aiken Harris Date: Wed, 13 May 2026 20:31:30 +0200 Subject: [PATCH] Add AP startup assembly trampoline for i686 --- sdk/xtadk/i686/ke.cc | 9 ++++ sdk/xtdk/i686/ketypes.h | 16 ++++++- xtoskrnl/ar/i686/archsup.S | 89 +++++++++++++++++++++++++++++++++++++- 3 files changed, 111 insertions(+), 3 deletions(-) diff --git a/sdk/xtadk/i686/ke.cc b/sdk/xtadk/i686/ke.cc index e266c23..bc3db83 100644 --- a/sdk/xtadk/i686/ke.cc +++ b/sdk/xtadk/i686/ke.cc @@ -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); } diff --git a/sdk/xtdk/i686/ketypes.h b/sdk/xtdk/i686/ketypes.h index 37a0d4d..b02b98b 100644 --- a/sdk/xtdk/i686/ketypes.h +++ b/sdk/xtdk/i686/ketypes.h @@ -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 { diff --git a/xtoskrnl/ar/i686/archsup.S b/xtoskrnl/ar/i686/archsup.S index aa24d5c..fd36c15 100644 --- a/xtoskrnl/ar/i686/archsup.S +++ b/xtoskrnl/ar/i686/archsup.S @@ -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: