Write initialization code in assembly -- we load the kernel stack from FreeLDR and...
authorReactOS Portable Systems Group <ros-arm-bringup@svn.reactos.org>
Tue, 12 Feb 2008 16:22:01 +0000 (16:22 +0000)
committerReactOS Portable Systems Group <ros-arm-bringup@svn.reactos.org>
Tue, 12 Feb 2008 16:22:01 +0000 (16:22 +0000)
We now have a file for C-code initialization (no reason to use assembly).
We now have some basic TLB routines and intrinsics (not tested).
We also detect if we are running on V4 or V6, and set the TLB and ASID counts respectively.

svn path=/trunk/; revision=32323

reactos/ntoskrnl/include/internal/arm/intrin_i.h
reactos/ntoskrnl/include/internal/arm/ke.h
reactos/ntoskrnl/include/internal/arm/ksarm.h
reactos/ntoskrnl/ke/arm/boot.s
reactos/ntoskrnl/ke/arm/kiinit.c [new file with mode: 0644]
reactos/ntoskrnl/ntoskrnl.rbuild

index b84f40e..abeec31 100644 (file)
@@ -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
index 03e5c4a..d0c1bbd 100644 (file)
@@ -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,
index 43bfe6d..9dc9706 100644 (file)
@@ -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
index 04a4941..0729645 100644 (file)
     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 (file)
index 0000000..388b90d
--- /dev/null
@@ -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 <ntoskrnl.h>
+#define NDEBUG
+#include <debug.h>
+
+/* 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);
+}
index 7e750fb..020affa 100644 (file)
@@ -60,6 +60,7 @@
                <if property="ARCH" value="arm">
                        <directory name="arm">
                                <file first="true">boot.s</file>
+                               <file>kiinit.c</file>
                                <file>stubs_asm.s</file>
                                <file>stubs.c</file>
                        </directory>