xref: /reactos/hal/halx86/smp/i386/apentry.S (revision 516ccad3)
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