From e5ed1afb69550a9673036d5f3d315aab1407df78 Mon Sep 17 00:00:00 2001 From: ReactOS Portable Systems Group Date: Tue, 12 Feb 2008 09:41:21 +0000 Subject: [PATCH] We now define the cache and id registers in CP15 (C0 Opcode 0 and 1). 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 --- .../boot/freeldr/freeldr/arch/arm/loader.c | 87 ++++++++++++++++++- .../ntoskrnl/include/internal/arm/intrin_i.h | 20 +++++ reactos/ntoskrnl/include/internal/arm/ke.h | 34 ++++++++ 3 files changed, 140 insertions(+), 1 deletion(-) 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,