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=32…
==============================================================================
--- 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?r…
==============================================================================
--- 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?r…
==============================================================================
--- 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);
}