We now define the cache and id registers in CP15 (C0 Opcode 0 and 1).
authorReactOS Portable Systems Group <ros-arm-bringup@svn.reactos.org>
Tue, 12 Feb 2008 09:41:21 +0000 (09:41 +0000)
committerReactOS Portable Systems Group <ros-arm-bringup@svn.reactos.org>
Tue, 12 Feb 2008 09:41:21 +0000 (09:41 +0000)
We now setup ARM cache information in the loader block.
We now allocate the kernel, interrupt and abort stacks, as well as the idle thread and process, and boot PRCB.
We now allocate the PCR and PDR pages.
We now send the command line to the kernel in the LoaderBlock's load options.

svn path=/trunk/; revision=32318

reactos/boot/freeldr/freeldr/arch/arm/loader.c
reactos/ntoskrnl/include/internal/arm/intrin_i.h
reactos/ntoskrnl/include/internal/arm/ke.h

index d065290..e922b62 100644 (file)
@@ -21,6 +21,32 @@ LOADER_PARAMETER_EXTENSION ArmExtension;
 extern ARM_TRANSLATION_TABLE ArmTranslationTable;
 extern ROS_KERNEL_ENTRY_POINT KernelEntryPoint;
 
+ULONG SizeBits[] =
+{
+    -1,      // INVALID
+    -1,      // INVALID
+    1 << 12, // 4KB
+    1 << 13, // 8KB
+    1 << 14, // 16KB
+    1 << 15, // 32KB
+    1 << 16, // 64KB
+    1 << 17  // 128KB
+};
+
+ULONG AssocBits[] =
+{
+    -1,      // INVALID
+    -1,      // INVALID
+    4        // 4-way associative
+};
+
+ULONG LenBits[] =
+{
+    -1,      // INVALID
+    -1,      // INVALID
+    8        // 8 words per line (32 bytes)
+};
+
 /* FUNCTIONS ******************************************************************/
 
 VOID
@@ -115,6 +141,9 @@ ArmSetupPagingAndJump(IN ULONG Magic)
 VOID
 ArmPrepareForReactOS(IN BOOLEAN Setup)
 {   
+    ARM_CACHE_REGISTER CacheReg;
+    PVOID Base;
+
     //
     // Initialize the loader block
     //
@@ -153,8 +182,63 @@ ArmPrepareForReactOS(IN BOOLEAN Setup)
     //
     
     //
-    // TODO: Setup ARM-specific block
+    // Send the command line
+    //
+    ArmLoaderBlock.LoadOptions = reactos_kernel_cmdline;
+    
+    //
+    // Setup cache information
+    //
+    CacheReg = KeArmCacheRegisterGet();   
+    ArmLoaderBlock.u.Arm.FirstLevelDcacheSize = SizeBits[CacheReg.DSize];
+    ArmLoaderBlock.u.Arm.FirstLevelDcacheFillSize = LenBits[CacheReg.DLength];
+    ArmLoaderBlock.u.Arm.FirstLevelDcacheFillSize <<= 2;
+    ArmLoaderBlock.u.Arm.FirstLevelIcacheSize = SizeBits[CacheReg.ISize];
+    ArmLoaderBlock.u.Arm.FirstLevelIcacheFillSize = LenBits[CacheReg.ILength];
+    ArmLoaderBlock.u.Arm.FirstLevelIcacheFillSize <<= 2;
+    ArmLoaderBlock.u.Arm.SecondLevelDcacheSize =
+    ArmLoaderBlock.u.Arm.SecondLevelDcacheFillSize =
+    ArmLoaderBlock.u.Arm.SecondLevelIcacheSize =
+    ArmLoaderBlock.u.Arm.SecondLevelIcacheFillSize = 0;
+    
+    //
+    // Allocate the Interrupt stack
+    //
+    Base = MmAllocateMemoryWithType(KERNEL_STACK_SIZE, LoaderStartupDpcStack);
+    ArmLoaderBlock.u.Arm.InterruptStack = KSEG0_BASE | (ULONG)Base;
+    
+    //
+    // Allocate the Kernel Boot stack
+    //
+    Base = MmAllocateMemoryWithType(KERNEL_STACK_SIZE, LoaderStartupKernelStack);
+    ArmLoaderBlock.KernelStack = KSEG0_BASE | (ULONG)Base;
+    
+    //
+    // Allocate the Abort stack
+    //
+    Base = MmAllocateMemoryWithType(KERNEL_STACK_SIZE, LoaderStartupPanicStack);
+    ArmLoaderBlock.u.Arm.PanicStack = KSEG0_BASE | (ULONG)Base;
+
+    //
+    // Allocate the PCRs (1MB each for now!)
+    //
+    Base = MmAllocateMemoryWithType(2 * 1024 * 1024, LoaderStartupPcrPage);
+    ArmLoaderBlock.u.Arm.PcrPage = (ULONG)Base >> TTB_SHIFT;
+    ArmLoaderBlock.u.Arm.PcrPage2 = ArmLoaderBlock.u.Arm.PcrPage + 1;
+
+    //
+    // Allocate PDR pages
+    //
+    Base = MmAllocateMemoryWithType(3 * 1024 * 1024, LoaderStartupPdrPage);
+    ArmLoaderBlock.u.Arm.PdrPage = (ULONG)Base >> TTB_SHIFT;
+    
+    //
+    // Set initial PRCB, Thread and Process on the last PDR page
     //
+    Base = (PVOID)((ULONG)Base + 2 * 1024 * 1024);
+    ArmLoaderBlock.Prcb = KSEG0_BASE | (ULONG)Base;
+    ArmLoaderBlock.Process = ArmLoaderBlock.Prcb + sizeof(KPRCB);
+    ArmLoaderBlock.Thread = ArmLoaderBlock.Process + sizeof(EPROCESS);
 }
 
 VOID
@@ -176,5 +260,6 @@ FrLdrStartup(IN ULONG Magic)
     //
     // Initialize paging and load NTOSKRNL
     //
+    TuiPrintf("Kernel Command Line: %s\n", ArmLoaderBlock.LoadOptions);
     ArmSetupPagingAndJump(Magic);
 }
index 05a00a2..b84f40e 100644 (file)
@@ -20,6 +20,26 @@ KeArmControlRegisterGet(VOID)
     return Value;
 }
 
+FORCEINLINE
+ARM_ID_CODE_REGISTER
+KeArmIdCodeRegisterGet(VOID)
+{
+    ARM_ID_CODE_REGISTER Value;
+    __asm__ __volatile__ ("mrc p15, 0, %0, c0, c0, 0" : "=r"(Value.AsUlong) : : "cc");
+    return Value;
+}
+
+
+FORCEINLINE
+ARM_CACHE_REGISTER
+KeArmCacheRegisterGet(VOID)
+{
+    ARM_CACHE_REGISTER Value;
+    __asm__ __volatile__ ("mrc p15, 0, %0, c0, c0, 1" : "=r"(Value.AsUlong) : : "cc");
+    return Value;
+}
+
+
 FORCEINLINE
 VOID
 KeArmControlRegisterSet(IN ARM_CONTROL_REGISTER ControlRegister)
index 62ec28e..03e5c4a 100644 (file)
@@ -65,6 +65,40 @@ typedef union _ARM_CONTROL_REGISTER
     ULONG AsUlong;
 } ARM_CONTROL_REGISTER, *PARM_CONTROL_REGISTER;
 
+typedef union _ARM_ID_CODE_REGISTER
+{
+    struct
+    {
+        ULONG Revision:4;
+        ULONG PartNumber:12;
+        ULONG Architecture:4;
+        ULONG Variant:4;
+        ULONG Identifier:8;
+    };
+    ULONG AsUlong;
+} ARM_ID_CODE_REGISTER, *PARM_ID_CODE_REGISTER;
+
+typedef union _ARM_CACHE_REGISTER
+{
+    struct
+    {
+        ULONG ILength:2;
+        ULONG IMultipler:1;
+        ULONG IAssociativty:3;
+        ULONG ISize:4;
+        ULONG IReserved:2;
+        ULONG DLength:2;
+        ULONG DMultipler:1;
+        ULONG DAssociativty:3;
+        ULONG DSize:4;
+        ULONG DReserved:2;  
+        ULONG Separate:1;
+        ULONG CType:4;
+        ULONG Reserved:3;
+    };
+    ULONG AsUlong;
+} ARM_CACHE_REGISTER, *PARM_CACHE_REGISTER;
+
 typedef enum _ARM_DOMAINS
 {
     Domain0,