Author: ros-arm-bringup Date: Tue Feb 12 22:01:48 2008 New Revision: 32330
URL: http://svn.reactos.org/svn/reactos?rev=32330&view=rev Log: QEMU doesn't support TLB Lockdown, so we now use a hack for QEMU and broken CPUs [albeit a portable one ;-)]. PCR access in usermode/kernelmode works. We now have HalSweepI/Dcache APIs exported and stubbed in the ARM HAL (great, since UNIMPLEMENTED macro now works). We now setup more of the PCR, including all the cache values required, then we call the HAL sweep functions (TBD).
Modified: trunk/reactos/hal/hal/hal_arm.def trunk/reactos/hal/halarm/generic/hal.c trunk/reactos/ntoskrnl/ke/arm/kiinit.c
Modified: trunk/reactos/hal/hal/hal_arm.def URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/hal/hal_arm.def?rev=323... ============================================================================== --- trunk/reactos/hal/hal/hal_arm.def (original) +++ trunk/reactos/hal/hal/hal_arm.def Tue Feb 12 22:01:48 2008 @@ -64,6 +64,8 @@ HalStartNextProcessor HalStartProfileInterrupt HalStopProfileInterrupt +HalSweepIcache +HalSweepDcache HalTranslateBusAddress IoAssignDriveLetters=HalpAssignDriveLetters IoFlushAdapterBuffers
Modified: trunk/reactos/hal/halarm/generic/hal.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halarm/generic/hal.c?re... ============================================================================== --- trunk/reactos/hal/halarm/generic/hal.c (original) +++ trunk/reactos/hal/halarm/generic/hal.c Tue Feb 12 22:01:48 2008 @@ -1089,4 +1089,17 @@ UNIMPLEMENTED; return 0; } + +VOID +HalSweepDcache(VOID) +{ + UNIMPLEMENTED; +} + +VOID +HalSweepIcache(VOID) +{ + UNIMPLEMENTED; +} + /* EOF */
Modified: trunk/reactos/ntoskrnl/ke/arm/kiinit.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/arm/kiinit.c?re... ============================================================================== --- trunk/reactos/ntoskrnl/ke/arm/kiinit.c (original) +++ trunk/reactos/ntoskrnl/ke/arm/kiinit.c Tue Feb 12 22:01:48 2008 @@ -19,6 +19,9 @@ ULONG KeNumberProcessIds; ULONG KeNumberTbEntries;
+VOID HalSweepDcache(VOID); +VOID HalSweepIcache(VOID); + #define __ARMV6__ KeIsArmV6
// @@ -99,17 +102,34 @@ Temp = *(PULONG)Virtual;
// - // Read lockdown register and clear the preserve bit + // Read lockdown register // LockdownRegister = KeArmLockdownRegisterGet(); - LockdownRegister.Preserve = FALSE; - ASSERT(LockdownRegister.Victim == OldVictimCount + 1); - KeArmLockdownRegisterSet(LockdownRegister); - - // - // Clear the PTE - // - TranslationTable->Pte[(ULONG)Virtual >> TTB_SHIFT].AsUlong = 0; + if (LockdownRegister.Victim == 0) + { + // + // This can only happen on QEMU or broken CPUs since there *has* + // to have been at least a miss since the system started. For example, + // QEMU doesn't support TLB lockdown. + // + // On these systems, we'll just keep the PTE mapped + // + DPRINT1("TLB Lockdown Failure (%p). Running on QEMU?\n", Virtual); + } + else + { + // + // Clear the preserve bits + // + LockdownRegister.Preserve = FALSE; + ASSERT(LockdownRegister.Victim == OldVictimCount + 1); + KeArmLockdownRegisterSet(LockdownRegister); + + // + // Clear the PTE + // + TranslationTable->Pte[(ULONG)Virtual >> TTB_SHIFT].AsUlong = 0; + } }
VOID @@ -188,10 +208,78 @@ KeFillFixedEntryTb(Pte, (PVOID)USPCR, PCR_ENTRY + 1);
// - // Now we should be able to use the PCR... set the cache policies + // Now we should be able to use the PCR... // Pcr = (PKPCR)KeGetPcr(); + + // + // Set the cache policy (HACK) + // Pcr->CachePolicy = 0; Pcr->AlignedCachePolicy = 0; + + // + // Copy cache information from the loader block + // + Pcr->FirstLevelDcacheSize = LoaderBlock->u.Arm.FirstLevelDcacheSize; + Pcr->SecondLevelDcacheSize = LoaderBlock->u.Arm.SecondLevelDcacheSize; + Pcr->FirstLevelIcacheSize = LoaderBlock->u.Arm.FirstLevelIcacheSize; + Pcr->SecondLevelIcacheSize = LoaderBlock->u.Arm.SecondLevelIcacheSize; + Pcr->FirstLevelDcacheFillSize = LoaderBlock->u.Arm.FirstLevelDcacheFillSize; + Pcr->SecondLevelDcacheFillSize = LoaderBlock->u.Arm.SecondLevelDcacheFillSize; + Pcr->FirstLevelIcacheFillSize = LoaderBlock->u.Arm.FirstLevelIcacheFillSize; + Pcr->SecondLevelIcacheFillSize = LoaderBlock->u.Arm.SecondLevelIcacheFillSize; + + // + // Set global d-cache fill and alignment values + // + if (Pcr->SecondLevelDcacheSize) + { + // + // Use the first level + // + Pcr->DcacheFillSize = Pcr->SecondLevelDcacheSize; + } + else + { + // + // Use the second level + // + Pcr->DcacheFillSize = Pcr->SecondLevelDcacheSize; + } + + // + // Set the alignment + // + Pcr->DcacheAlignment = Pcr->DcacheFillSize - 1; + + // + // Set global i-cache fill and alignment values + // + if (Pcr->SecondLevelIcacheSize) + { + // + // Use the first level + // + Pcr->IcacheFillSize = Pcr->SecondLevelIcacheSize; + } + else + { + // + // Use the second level + // + Pcr->IcacheFillSize = Pcr->SecondLevelIcacheSize; + } + + // + // Set the alignment + // + Pcr->IcacheAlignment = Pcr->IcacheFillSize - 1; + + // + // Now sweep caches + // + HalSweepIcache(); + HalSweepDcache(); while (TRUE); }