diff --git a/reactos/boot/freeldr/freeldr/arch/arm/loader.c b/reactos/boot/freeldr/freeldr/arch/arm/loader.c index d065290f9a7..e922b62ad36 100644 --- a/reactos/boot/freeldr/freeldr/arch/arm/loader.c +++ b/reactos/boot/freeldr/freeldr/arch/arm/loader.c @@ -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); } diff --git a/reactos/ntoskrnl/include/internal/arm/intrin_i.h b/reactos/ntoskrnl/include/internal/arm/intrin_i.h index 05a00a28d7a..b84f40efff7 100644 --- a/reactos/ntoskrnl/include/internal/arm/intrin_i.h +++ b/reactos/ntoskrnl/include/internal/arm/intrin_i.h @@ -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) diff --git a/reactos/ntoskrnl/include/internal/arm/ke.h b/reactos/ntoskrnl/include/internal/arm/ke.h index 62ec28e3db1..03e5c4a9201 100644 --- a/reactos/ntoskrnl/include/internal/arm/ke.h +++ b/reactos/ntoskrnl/include/internal/arm/ke.h @@ -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,