Skip to content

Commit

Permalink
[NTOS:KE][HALX86] Implement AP startup code
Browse files Browse the repository at this point in the history
Co-authored-by: Victor Perevertkin <[email protected]>
  • Loading branch information
DarkFire01 and Extravert-ir committed Nov 18, 2023
1 parent e627c3b commit ae0311d
Show file tree
Hide file tree
Showing 30 changed files with 765 additions and 136 deletions.
75 changes: 0 additions & 75 deletions boot/freeldr/freeldr/ntldr/arch/i386/winldr.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,81 +64,6 @@ typedef struct
#define TYPE_CODE (0x10 | DESCRIPTOR_CODE | DESCRIPTOR_EXECUTE_READ)
#define TYPE_DATA (0x10 | DESCRIPTOR_READ_WRITE)

FORCEINLINE
PKGDTENTRY
KiGetGdtEntry(
IN PVOID pGdt,
IN USHORT Selector)
{
return (PKGDTENTRY)((ULONG_PTR)pGdt + (Selector & ~RPL_MASK));
}

FORCEINLINE
VOID
KiSetGdtDescriptorBase(
IN OUT PKGDTENTRY Entry,
IN ULONG32 Base)
{
Entry->BaseLow = (USHORT)(Base & 0xffff);
Entry->HighWord.Bytes.BaseMid = (UCHAR)((Base >> 16) & 0xff);
Entry->HighWord.Bytes.BaseHi = (UCHAR)((Base >> 24) & 0xff);
// Entry->BaseUpper = (ULONG)(Base >> 32);
}

FORCEINLINE
VOID
KiSetGdtDescriptorLimit(
IN OUT PKGDTENTRY Entry,
IN ULONG Limit)
{
if (Limit < 0x100000)
{
Entry->HighWord.Bits.Granularity = 0;
}
else
{
Limit >>= 12;
Entry->HighWord.Bits.Granularity = 1;
}
Entry->LimitLow = (USHORT)(Limit & 0xffff);
Entry->HighWord.Bits.LimitHi = ((Limit >> 16) & 0x0f);
}

VOID
KiSetGdtEntryEx(
IN OUT PKGDTENTRY Entry,
IN ULONG32 Base,
IN ULONG Limit,
IN UCHAR Type,
IN UCHAR Dpl,
IN BOOLEAN Granularity,
IN UCHAR SegMode) // 0: 16-bit, 1: 32-bit, 2: 64-bit
{
KiSetGdtDescriptorBase(Entry, Base);
KiSetGdtDescriptorLimit(Entry, Limit);
Entry->HighWord.Bits.Type = (Type & 0x1f);
Entry->HighWord.Bits.Dpl = (Dpl & 0x3);
Entry->HighWord.Bits.Pres = (Type != 0); // Present, must be 1 when the GDT entry is valid.
Entry->HighWord.Bits.Sys = 0; // System
Entry->HighWord.Bits.Reserved_0 = 0; // LongMode = !!(SegMode & 1);
Entry->HighWord.Bits.Default_Big = !!(SegMode & 2);
Entry->HighWord.Bits.Granularity |= !!Granularity; // The flag may have been already set by KiSetGdtDescriptorLimit().
// Entry->MustBeZero = 0;
}

FORCEINLINE
VOID
KiSetGdtEntry(
IN OUT PKGDTENTRY Entry,
IN ULONG32 Base,
IN ULONG Limit,
IN UCHAR Type,
IN UCHAR Dpl,
IN UCHAR SegMode) // 0: 16-bit, 1: 32-bit, 2: 64-bit
{
KiSetGdtEntryEx(Entry, Base, Limit, Type, Dpl, FALSE, SegMode);
}

#if 0
VOID
DumpGDTEntry(ULONG_PTR Base, ULONG Selector)
Expand Down
4 changes: 2 additions & 2 deletions hal/halx86/acpi/halacpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -851,12 +851,12 @@ HalpSetupAcpiPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
/* Allocate it */
HalpLowStubPhysicalAddress.QuadPart = HalpAllocPhysicalMemory(LoaderBlock,
0x100000,
1,
HALP_LOW_STUB_SIZE_IN_PAGES,
FALSE);
if (HalpLowStubPhysicalAddress.QuadPart)
{
/* Map it */
HalpLowStub = HalpMapPhysicalMemory64(HalpLowStubPhysicalAddress, 1);
HalpLowStub = HalpMapPhysicalMemory64(HalpLowStubPhysicalAddress, HALP_LOW_STUB_SIZE_IN_PAGES);
}
}

Expand Down
45 changes: 39 additions & 6 deletions hal/halx86/apic/apicsmp.c
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
/*
* PROJECT: ReactOS HAL
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* FILE: hal/halx86/apic/apicsmp.c
* PURPOSE: SMP specific APIC code
* PROGRAMMERS: Copyright 2021 Timo Kreuzer ([email protected])
* COPYRIGHT: Copyright 2021 Timo Kreuzer <[email protected]>
* Copyright 2023 Justin Miller <[email protected]>
*/

/* INCLUDES *******************************************************************/

#include <hal.h>
#include "apicp.h"
#include <smp.h>

#define NDEBUG
#include <debug.h>


extern PPROCESSOR_IDENTITY HalpProcessorIdentity;

/* INTERNAL FUNCTIONS *********************************************************/

/*!
Expand All @@ -36,7 +41,7 @@
local APIC(s) specified in Destination field. Vector specifies
the startup address.
APIC_MT_ExtInt - Delivers an external interrupt to the target local
APIC specified in Destination field.
APIC specified in Destination field.
\param TriggerMode - The trigger mode of the interrupt. Can be:
APIC_TGM_Edge - The interrupt is edge triggered.
Expand Down Expand Up @@ -64,6 +69,12 @@ ApicRequestGlobalInterrupt(
{
APIC_INTERRUPT_COMMAND_REGISTER Icr;

/* Wait for the APIC to be idle */
do
{
Icr.Long0 = ApicRead(APIC_ICR0);
} while (Icr.DeliveryStatus);

/* Setup the command register */
Icr.LongLong = 0;
Icr.Vector = Vector;
Expand All @@ -84,13 +95,35 @@ ApicRequestGlobalInterrupt(

/* SMP SUPPORT FUNCTIONS ******************************************************/

// Should be called by SMP version of HalRequestIpi
VOID
NTAPI
HalpRequestIpi(KAFFINITY TargetProcessors)
HalpRequestIpi(_In_ KAFFINITY TargetProcessors)
{
UNIMPLEMENTED;
__debugbreak();
}

// APIC specific SMP code here
VOID
ApicStartApplicationProcessor(
_In_ ULONG NTProcessorNumber,
_In_ PHYSICAL_ADDRESS StartupLoc)
{
ASSERT(StartupLoc.HighPart == 0);
ASSERT((StartupLoc.QuadPart & 0xFFF) == 0);
ASSERT((StartupLoc.QuadPart & 0xFFF00FFF) == 0);

/* Init IPI */
ApicRequestGlobalInterrupt(HalpProcessorIdentity[NTProcessorNumber].LapicId, 0,
APIC_MT_INIT, APIC_TGM_Edge, APIC_DSH_Destination);

/* De-Assert Init IPI */
ApicRequestGlobalInterrupt(HalpProcessorIdentity[NTProcessorNumber].LapicId, 0,
APIC_MT_INIT, APIC_TGM_Level, APIC_DSH_Destination);

/* Stall execution for a bit to give APIC time: MPS Spec - B.4 */
KeStallExecutionProcessor(200);

/* Startup IPI */
ApicRequestGlobalInterrupt(HalpProcessorIdentity[NTProcessorNumber].LapicId, (StartupLoc.LowPart) >> 12,
APIC_MT_Startup, APIC_TGM_Edge, APIC_DSH_Destination);
}
23 changes: 0 additions & 23 deletions hal/halx86/apic/processor.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,6 @@ HalAllProcessorsStarted(VOID)
return TRUE;
}

/*
* @implemented
*/
BOOLEAN
NTAPI
HalStartNextProcessor(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
IN PKPROCESSOR_STATE ProcessorState)
{
/* Ready to start */
return FALSE;
}

/*
* @implemented
*/
Expand All @@ -62,15 +50,4 @@ HalProcessorIdle(VOID)
__halt();
}

/*
* @implemented
*/
VOID
NTAPI
HalRequestIpi(KAFFINITY TargetProcessors)
{
UNIMPLEMENTED;
__debugbreak();
}

/* EOF */
34 changes: 34 additions & 0 deletions hal/halx86/generic/up.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: Core source file for Uniprocessor (UP) alternative functions
* COPYRIGHT: Copyright 2021 Justin Miller <[email protected]>
*/

/* INCLUDES ******************************************************************/

#include <hal.h>

#define NDEBUG
#include <debug.h>

/* FUNCTIONS *****************************************************************/

VOID
NTAPI
HalRequestIpi(
_In_ KAFFINITY TargetProcessors)
{
/* This should never be called in UP mode */
__debugbreak();
}

BOOLEAN
NTAPI
HalStartNextProcessor(
_In_ PLOADER_PARAMETER_BLOCK LoaderBlock,
_In_ PKPROCESSOR_STATE ProcessorState)
{
/* Always return false on UP systems */
return FALSE;
}
6 changes: 6 additions & 0 deletions hal/halx86/include/halp.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ VOID
#define IDT_INTERNAL 0x11
#define IDT_DEVICE 0x21

#if _M_AMD64
#define HALP_LOW_STUB_SIZE_IN_PAGES 5
#else
#define HALP_LOW_STUB_SIZE_IN_PAGES 3
#endif

/* Conversion functions */
#define BCD_INT(bcd) \
(((bcd & 0xF0) >> 4) * 10 + (bcd & 0x0F))
Expand Down
12 changes: 12 additions & 0 deletions hal/halx86/include/smp.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,15 @@ HalpSetupProcessorsTable(

VOID
HalpPrintApicTables(VOID);

/* APIC specific functions inside apic/apicsmp.c */

VOID
ApicStartApplicationProcessor(
_In_ ULONG NTProcessorNumber,
_In_ PHYSICAL_ADDRESS StartupLoc);

VOID
NTAPI
HalpRequestIpi(
_In_ KAFFINITY TargetProcessors);
23 changes: 0 additions & 23 deletions hal/halx86/pic/processor.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,6 @@ HalAllProcessorsStarted(VOID)
return TRUE;
}

/*
* @implemented
*/
BOOLEAN
NTAPI
HalStartNextProcessor(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
IN PKPROCESSOR_STATE ProcessorState)
{
/* Ready to start */
return FALSE;
}

/*
* @implemented
*/
Expand All @@ -62,15 +50,4 @@ HalProcessorIdle(VOID)
__halt();
}

/*
* @implemented
*/
VOID
NTAPI
HalRequestIpi(KAFFINITY TargetProcessors)
{
/* Not implemented on UP */
__debugbreak();
}

/* EOF */
20 changes: 17 additions & 3 deletions hal/halx86/smp.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,22 @@
list(APPEND HAL_SMP_SOURCE
generic/buildtype.c
generic/spinlock.c
smp/smp.c)
smp/smp.c
smp/ipi.c)

add_library(lib_hal_smp OBJECT ${HAL_SMP_SOURCE})
add_dependencies(lib_hal_smp bugcodes xdk)
if(ARCH STREQUAL "i386")
list(APPEND HAL_SMP_ASM_SOURCE
smp/i386/apentry.S)
list(APPEND HAL_SMP_SOURCE
smp/i386/spinup.c)
elseif(ARCH STREQUAL "amd64")
list(APPEND HAL_SMP_ASM_SOURCE
smp/amd64/apentry.S)
list(APPEND HAL_SMP_SOURCE
smp/amd64/spinup.c)
endif()

add_asm_files(lib_hal_smp_asm ${HAL_SMP_ASM_SOURCE})
add_library(lib_hal_smp OBJECT ${HAL_SMP_SOURCE} ${lib_hal_smp_asm})
add_dependencies(lib_hal_smp bugcodes asm xdk)
target_compile_definitions(lib_hal_smp PRIVATE CONFIG_SMP)
43 changes: 43 additions & 0 deletions hal/halx86/smp/amd64/apentry.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: AMD64 Application Processor (AP) spinup setup
* COPYRIGHT: Copyright 2023 Justin Miller <[email protected]>
*/

#include <asm.inc>

PUBLIC APEntry16
PUBLIC APEntry16End
PUBLIC APEntry32
PUBLIC APEntryJump32Offset
PUBLIC APEntryJump32Segment
PUBLIC TempPageTableAddr
PUBLIC APEntryCpuState

.code
APEntry16:
cli

xor ax, ax
mov ds, ax
mov ss, ax
mov fs, ax
mov gs, ax

hlt

APEntry16End:
.long HEX(0)
APEntry32:
.long HEX(0)
APEntryJump32Offset:
.long HEX(0)
APEntryJump32Segment:
.long HEX(0)
TempPageTableAddr:
.long HEX(0)
APEntryCpuState:
.long HEX(0)

END
Loading

0 comments on commit ae0311d

Please sign in to comment.