diff --git a/reactos/ntoskrnl/include/internal/arm/intrin_i.h b/reactos/ntoskrnl/include/internal/arm/intrin_i.h index b84f40efff7..abeec315c5c 100644 --- a/reactos/ntoskrnl/include/internal/arm/intrin_i.h +++ b/reactos/ntoskrnl/include/internal/arm/intrin_i.h @@ -29,6 +29,15 @@ KeArmIdCodeRegisterGet(VOID) return Value; } +FORCEINLINE +ARM_LOCKDOWN_REGISTER +KeArmLockdownRegisterGet(VOID) +{ + ARM_LOCKDOWN_REGISTER Value; + __asm__ __volatile__ ("mrc p15, 0, %0, c10, c0, 0" : "=r"(Value.AsUlong) : : "cc"); + return Value; +} + FORCEINLINE ARM_CACHE_REGISTER @@ -61,4 +70,26 @@ KeArmDomainRegisterSet(IN ARM_DOMAIN_REGISTER DomainRegister) __asm__ __volatile__ ("mcr p15, 0, %0, c3, c0, 0" : : "r"(DomainRegister.AsUlong) : "cc"); } +FORCEINLINE +VOID +KeArmLockdownRegisterSet(IN ARM_LOCKDOWN_REGISTER LockdownRegister) +{ + __asm__ __volatile__ ("mcr p15, 0, %0, c10, c0, 0" : : "r"(LockdownRegister.AsUlong) : "cc"); +} + +FORCEINLINE +VOID +KeArmFlushTlb(VOID) +{ + __asm__ __volatile__ ("mcr p15, 0, %0, c8, c7, 0" : : "r"(0) : "cc"); +} + +FORCEINLINE +VOID +KeArmInvalidateTlbEntry(IN PVOID Address) +{ + __asm__ __volatile__ ("mcr p15, 0, %0, c8, c7, 1" : : "r"(Address) : "cc"); +} + + #endif diff --git a/reactos/ntoskrnl/include/internal/arm/ke.h b/reactos/ntoskrnl/include/internal/arm/ke.h index 03e5c4a9201..d0c1bbd6c15 100644 --- a/reactos/ntoskrnl/include/internal/arm/ke.h +++ b/reactos/ntoskrnl/include/internal/arm/ke.h @@ -99,6 +99,18 @@ typedef union _ARM_CACHE_REGISTER ULONG AsUlong; } ARM_CACHE_REGISTER, *PARM_CACHE_REGISTER; +typedef union _ARM_LOCKDOWN_REGISTER +{ + struct + { + ULONG Preserve:1; + ULONG Ignored:25; + ULONG Victim:3; + ULONG Reserved:3; + }; + ULONG AsUlong; +} ARM_LOCKDOWN_REGISTER, *PARM_LOCKDOWN_REGISTER; + typedef enum _ARM_DOMAINS { Domain0, diff --git a/reactos/ntoskrnl/include/internal/arm/ksarm.h b/reactos/ntoskrnl/include/internal/arm/ksarm.h index 43bfe6de651..9dc9706f318 100644 --- a/reactos/ntoskrnl/include/internal/arm/ksarm.h +++ b/reactos/ntoskrnl/include/internal/arm/ksarm.h @@ -1,9 +1,31 @@ +// +// CPSR Values +// .equ CPSR_IRQ_DISABLE, 0x80 .equ CPSR_FIQ_DISABLE, 0x40 .equ CPSR_THUMB_ENABLE, 0x20 +// +// C1 Register Values +// .equ C1_MMU_CONTROL, 0x01 .equ C1_ALIGNMENT_CONTROL, 0x02 .equ C1_DCACHE_CONTROL, 0x04 .equ C1_ICACHE_CONTROL, 0x1000 .equ C1_VECTOR_CONTROL, 0x2000 + +// +// Loader Parameter Block Offsets +// +.equ LpbKernelStack, 0x18 + +// +// PCR +// +.equ KiPcr, 0xFFFFF000 + +// +// Lockdown TLB entries +// +.equ PCR_ENTRY 0 +.equ PDR_ENTRY 2 \ No newline at end of file diff --git a/reactos/ntoskrnl/ke/arm/boot.s b/reactos/ntoskrnl/ke/arm/boot.s index 04a49411457..0729645593d 100644 --- a/reactos/ntoskrnl/ke/arm/boot.s +++ b/reactos/ntoskrnl/ke/arm/boot.s @@ -15,8 +15,13 @@ PROLOG_END KiSystemStartup // - // Do stuff! + // Switch to boot kernel stack // - b . + ldr sp, [a2, #LpbKernelStack] + + // + // Go to C code + // + b KiInitializeSystem ENTRY_END KiSystemStartup diff --git a/reactos/ntoskrnl/ke/arm/kiinit.c b/reactos/ntoskrnl/ke/arm/kiinit.c new file mode 100644 index 00000000000..388b90df4f0 --- /dev/null +++ b/reactos/ntoskrnl/ke/arm/kiinit.c @@ -0,0 +1,128 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/ke/arm/kiinit.c + * PURPOSE: Implements the kernel entry point for ARM machines + * PROGRAMMERS: ReactOS Portable Systems Group + */ + +/* INCLUDES *******************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS ********************************************************************/ + +BOOLEAN KeIsArmV6; +ULONG KeFixedTbEntries; +ULONG KeNumberProcessIds; +ULONG KeNumberTbEntries; + +#define __ARMV6__ KeIsArmV6 + +/* FUNCTIONS ******************************************************************/ + +VOID +KiFlushSingleTb(IN BOOLEAN Invalid, + IN PVOID Virtual) +{ + // + // Just invalidate it + // + KeArmInvalidateTlbEntry(Virtual); +} + +VOID +KeFillFixedEntryTb(IN ARM_PTE Pte, + IN PVOID Virtual, + IN ULONG Index) +{ + ARM_LOCKDOWN_REGISTER LockdownRegister; + ULONG OldVictimCount; + ULONG Temp; + UNREFERENCED_PARAMETER(Pte); + UNREFERENCED_PARAMETER(Index); + + // + // On ARM, we can't set the index ourselves, so make sure that we are not + // locking down more than 8 entries. + // + KeFixedTbEntries++; + ASSERT(KeFixedTbEntries <= 8); + + // + // Flush the address + // + KiFlushSingleTb(TRUE, Virtual); + + // + // Read lockdown register and set the preserve bit + // + LockdownRegister = KeArmLockdownRegisterGet(); + LockdownRegister.Preserve = TRUE; + OldVictimCount = LockdownRegister.Victim; + KeArmLockdownRegisterSet(LockdownRegister); + + // + // Now force a miss + // + Temp = *(PULONG)Virtual; + + // + // Read lockdown register and clear the preserve bit + // + LockdownRegister = KeArmLockdownRegisterGet(); + LockdownRegister.Preserve = FALSE; + ASSERT(LockdownRegister.Victim == OldVictimCount + 1); + KeArmLockdownRegisterSet(LockdownRegister); +} + +VOID +KeFlushTb(VOID) +{ + // + // Flush the entire TLB + // + KeArmFlushTlb(); +} + +VOID +KiInitializeSystem(IN ULONG Magic, + IN PLOADER_PARAMETER_BLOCK LoaderBlock) +{ + // + // Detect ARM version (Architecture 6 is the ARMv5TE-J, go figure!) + // + KeIsArmV6 = KeArmIdCodeRegisterGet().Architecture == 7; + + // + // Set the number of TLB entries and ASIDs + // + KeNumberTbEntries = 64; + if (__ARMV6__) + { + // + // 256 ASIDs on v6/v7 + // + KeNumberProcessIds = 256; + } + else + { + // + // The TLB is VIVT on v4/v5 + // + KeNumberProcessIds = 0; + } + + // + // Flush the TLB + // + KeFlushTb(); + + // + // + // + + while (TRUE); +} diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index 7e750fb837f..020affa69dc 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -60,6 +60,7 @@ boot.s + kiinit.c stubs_asm.s stubs.c