1/* 2 * PROJECT: ReactOS HAL 3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) 4 * PURPOSE: i386 Application Processor (AP) spinup setup 5 * COPYRIGHT: Copyright 2021 Victor Perevertkin <victor.perevertkin@reactos.org> 6 * Copyright 2021-2023 Justin Miller <justin.miller@reactos.org> 7 */ 8 9#include <asm.inc> 10#include <ks386.inc> 11 12#define ZERO_OFFSET(f) (f - _HalpAPEntry16) 13#define PS(f) (f - _HalpAPEntryData) 14 15PUBLIC _HalpAPEntry16 16PUBLIC _HalpAPEntryData 17PUBLIC _HalpAPEntry32 18PUBLIC _HalpAPEntry16End 19 20.code16 21_HalpAPEntry16: 22 cli 23 24 /* Calculate the flat base address */ 25 mov ebp, cs 26 shl ebp, 4 27 28 /* Use flat addressing */ 29 xor eax, eax 30 mov ds, eax 31 32#ifdef _USE_ML 33 data32 lgdt fword ptr cs:[ZERO_OFFSET(Gdtr)] 34 data32 lidt fword ptr cs:[ZERO_OFFSET(Idtr)] 35#else 36 data32 lgdt cs:[ZERO_OFFSET(Gdtr)] 37 data32 lidt cs:[ZERO_OFFSET(Idtr)] 38#endif 39 40 /* Load temp page table */ 41 mov eax, cs:[ZERO_OFFSET(PageTableRoot)] 42 mov cr3, eax 43 44 mov eax, cr0 45 or eax, HEX(80000001) /* CR0_PG | CR0_PE */ 46 mov cr0, eax 47 48.align 4 49 /* Long jump, 32bit address */ 50 .byte HEX(66) 51 .byte HEX(EA) 52_HalpAPEntryData: 53_APEntryJump32Offset: 54 .long 0 55_APEntryJump32Segment: 56 .long 8 57SelfPtr: 58 .long 0 59PageTableRoot: 60 .long 0 61ProcessorState: 62 .long 0 63Gdtr_Pad: 64 .short 0 // Pad 65Gdtr: 66 .short 0 // Limit 67 .long 0 // Base 68Idtr_Pad: 69 .short 0 // Pad 70Idtr: 71 .short 0 // Limit 72 .long 0 // Base 73_HalpAPEntry16End: 74.endcode16 75 76.code32 77_HalpAPEntry32: 78 /* Set the Ring 0 DS/ES/SS Segment */ 79 mov ax, HEX(10) 80 mov ds, ax 81 mov es, ax 82 mov ss, ax 83 mov gs, ax 84 85 /* Load ProcessorState pointer */ 86 mov esi, [ebp + ZERO_OFFSET(ProcessorState)] 87 88 mov eax, [esi + PsContextFrame + CsSegDs] 89 mov ds, eax 90 mov eax, [esi + PsContextFrame + CsSegEs] 91 mov es, eax 92 mov eax, [esi + PsContextFrame + CsSegSs] 93 mov ss, eax 94 mov eax, [esi + PsContextFrame + CsSegFs] 95 mov fs, eax 96 mov eax, [esi + PsContextFrame + CsSegGs] 97 mov gs, eax 98 99 /* Write CR registers with ProcessorState values */ 100 mov eax, [esi + PsSpecialRegisters + SrCr3] 101 mov cr3, eax 102 mov eax, [esi + PsSpecialRegisters + SrCr4] 103 mov cr4, eax 104 105 /* Load debug registers */ 106 mov eax, [esi + PsSpecialRegisters + SrKernelDr0] 107 mov dr0, eax 108 mov eax, [esi + PsSpecialRegisters + SrKernelDr1] 109 mov dr1, eax 110 mov eax, [esi + PsSpecialRegisters + SrKernelDr2] 111 mov dr2, eax 112 mov eax, [esi + PsSpecialRegisters + SrKernelDr3] 113 mov dr3, eax 114 mov eax, [esi + PsSpecialRegisters + SrKernelDr6] 115 mov dr6, eax 116 mov eax, [esi + PsSpecialRegisters + SrKernelDr7] 117 mov dr7, eax 118 119 /* Load TSS */ 120 ltr word ptr [esi + PsSpecialRegisters + SrTr] 121 122 /* Load AP Stack */ 123 mov esp, [esi + PsContextFrame + CsEsp] 124 125 /* Load Eip and push it as a "return" address */ 126 mov eax, [esi + PsContextFrame + CsEip] 127 push eax 128 129 /* Load flags */ 130 mov eax, [esi + PsContextFrame + CsEflags] 131 sahf 132 133 /* Set up all GP registers */ 134 xor edi, edi 135 xor esi, esi 136 xor ebp, ebp 137 xor ebx, ebx 138 xor edx, edx 139 xor ecx, ecx 140 xor eax, eax 141 142 /* Jump into the kernel */ 143 ret 144END 145