kernel/arm/paging: implement Modified Flag
* Introduce SWDBM flag similarly to the arm64 port * Reuse TEX[2] for SWDBM flag which should be availble to be used by the operating system if TEX remap is enabled. * Introduce SetAndClearPageTableEntryFlags for updating accessed and modified flags atomically * Startup sequence is handled similarly to accessed flag, i.e. set Modified flag in initially mapped pages in bootloader and early map. * Once the kernel initialization has progressed enough, pages are mapped as read-only and modified flag handling is done in the page fault handler. Change-Id: I8f761e2c6325d1b91481abd569d5e8befded0761 Reviewed-on: https://review.haiku-os.org/c/haiku/+/6518 Tested-by: Commit checker robot <[email protected]> Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
committed by
Adrien Destugues
parent
73c451087f
commit
b799d160f2
@@ -60,11 +60,13 @@
|
|||||||
#define ARM_MMU_L2_FLAG_S 0x400
|
#define ARM_MMU_L2_FLAG_S 0x400
|
||||||
#define ARM_MMU_L2_FLAG_NG 0x800
|
#define ARM_MMU_L2_FLAG_NG 0x800
|
||||||
|
|
||||||
#define ARM_MMU_L2_FLAG_AP_KRW 0x010
|
#define ARM_MMU_L2_FLAG_HAIKU_SWDBM ARM_MMU_L2_FLAG_TEX2
|
||||||
// allow read and write for kernel only
|
// reuse TEX[2] for software-emulated Dirty Bit Modifier
|
||||||
|
|
||||||
#define ARM_MMU_L2_FLAG_AP_RW 0x030
|
#define ARM_MMU_L2_FLAG_HAIKU_KERNEL_RW (ARM_MMU_L2_FLAG_TEX2 | ARM_MMU_L2_FLAG_AP0)
|
||||||
// allow read and write for user and system
|
// allow read and write for kernel only
|
||||||
|
// set Accessed and Modified flag during early page mapping
|
||||||
|
// as the exception handler may be not available yet
|
||||||
|
|
||||||
#define ARM_MMU_L1_TABLE_ENTRY_COUNT 4096
|
#define ARM_MMU_L1_TABLE_ENTRY_COUNT 4096
|
||||||
#define ARM_MMU_L1_TABLE_SIZE (ARM_MMU_L1_TABLE_ENTRY_COUNT \
|
#define ARM_MMU_L1_TABLE_SIZE (ARM_MMU_L1_TABLE_ENTRY_COUNT \
|
||||||
@@ -97,7 +99,7 @@
|
|||||||
#define ARM_PTE_ADDRESS_MASK 0xfffff000
|
#define ARM_PTE_ADDRESS_MASK 0xfffff000
|
||||||
#define ARM_PTE_TYPE_MASK 0x00000003
|
#define ARM_PTE_TYPE_MASK 0x00000003
|
||||||
|
|
||||||
#define ARM_PTE_PROTECTION_MASK 0x00000221 // AP[2:1], XN
|
#define ARM_PTE_PROTECTION_MASK 0x00000121 // SWDBM, AP[1], XN
|
||||||
#define ARM_PTE_MEMORY_TYPE_MASK 0x000001cc // TEX, B, C
|
#define ARM_PTE_MEMORY_TYPE_MASK 0x0000004c // TEX[0], B, C
|
||||||
|
|
||||||
#endif /* _ARCH_ARM_ARM_MMU_H */
|
#endif /* _ARCH_ARM_ARM_MMU_H */
|
||||||
|
|||||||
@@ -34,4 +34,7 @@
|
|||||||
#define FSR_FS_PERMISSION_FAULT_L1 0x0d
|
#define FSR_FS_PERMISSION_FAULT_L1 0x0d
|
||||||
#define FSR_FS_PERMISSION_FAULT_L2 0x0f
|
#define FSR_FS_PERMISSION_FAULT_L2 0x0f
|
||||||
|
|
||||||
|
#define FSR_FS_MASK 0x040f
|
||||||
|
#define FSR_LPAE_MASK 0x0200
|
||||||
|
|
||||||
#endif /* _SYSTEM_ARCH_ARM_DEFS_H */
|
#endif /* _SYSTEM_ARCH_ARM_DEFS_H */
|
||||||
|
|||||||
@@ -263,7 +263,7 @@ arch_mmu_generate_post_efi_page_tables(size_t memoryMapSize,
|
|||||||
(efi_memory_descriptor *)(memoryMapAddr + i * descriptorSize);
|
(efi_memory_descriptor *)(memoryMapAddr + i * descriptorSize);
|
||||||
if ((entry->Attribute & EFI_MEMORY_RUNTIME) != 0) {
|
if ((entry->Attribute & EFI_MEMORY_RUNTIME) != 0) {
|
||||||
map_range_to_new_area(entry,
|
map_range_to_new_area(entry,
|
||||||
ARM_MMU_L2_FLAG_B | ARM_MMU_L2_FLAG_C | ARM_MMU_L2_FLAG_AP_KRW);
|
ARM_MMU_L2_FLAG_B | ARM_MMU_L2_FLAG_C | ARM_MMU_L2_FLAG_HAIKU_KERNEL_RW);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,11 +273,11 @@ arch_mmu_generate_post_efi_page_tables(size_t memoryMapSize,
|
|||||||
size_t size;
|
size_t size;
|
||||||
while (mmu_next_region(&cookie, &vaddr, &paddr, &size)) {
|
while (mmu_next_region(&cookie, &vaddr, &paddr, &size)) {
|
||||||
map_range(vaddr, paddr, size,
|
map_range(vaddr, paddr, size,
|
||||||
ARM_MMU_L2_FLAG_B | ARM_MMU_L2_FLAG_C | ARM_MMU_L2_FLAG_AP_KRW);
|
ARM_MMU_L2_FLAG_B | ARM_MMU_L2_FLAG_C | ARM_MMU_L2_FLAG_HAIKU_KERNEL_RW);
|
||||||
}
|
}
|
||||||
|
|
||||||
map_range_to_new_area(gKernelArgs.arch_args.uart.regs,
|
map_range_to_new_area(gKernelArgs.arch_args.uart.regs,
|
||||||
ARM_MMU_L2_FLAG_B | ARM_MMU_L2_FLAG_AP_KRW | ARM_MMU_L2_FLAG_XN);
|
ARM_MMU_L2_FLAG_B | ARM_MMU_L2_FLAG_HAIKU_KERNEL_RW | ARM_MMU_L2_FLAG_XN);
|
||||||
|
|
||||||
sort_address_ranges(gKernelArgs.virtual_allocated_range,
|
sort_address_ranges(gKernelArgs.virtual_allocated_range,
|
||||||
gKernelArgs.num_virtual_allocated_ranges);
|
gKernelArgs.num_virtual_allocated_ranges);
|
||||||
|
|||||||
@@ -311,7 +311,7 @@ arch_arm_handle_access_flag_fault(addr_t far, uint32 fsr, bool isWrite, bool isE
|
|||||||
|
|
||||||
ARMVMTranslationMap *map = (ARMVMTranslationMap *)addressSpace->TranslationMap();
|
ARMVMTranslationMap *map = (ARMVMTranslationMap *)addressSpace->TranslationMap();
|
||||||
|
|
||||||
if ((fsr & 0x060f) == FSR_FS_ACCESS_FLAG_FAULT) {
|
if ((fsr & (FSR_FS_MASK | FSR_LPAE_MASK)) == FSR_FS_ACCESS_FLAG_FAULT) {
|
||||||
phys_addr_t physAddr;
|
phys_addr_t physAddr;
|
||||||
uint32 pageFlags;
|
uint32 pageFlags;
|
||||||
|
|
||||||
@@ -326,6 +326,21 @@ arch_arm_handle_access_flag_fault(addr_t far, uint32 fsr, bool isWrite, bool isE
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isWrite && ((fsr & (FSR_FS_MASK | FSR_LPAE_MASK)) == FSR_FS_PERMISSION_FAULT_L2)) {
|
||||||
|
phys_addr_t physAddr;
|
||||||
|
uint32 pageFlags;
|
||||||
|
|
||||||
|
map->QueryInterrupt(far, &physAddr, &pageFlags);
|
||||||
|
|
||||||
|
if ((PAGE_PRESENT & pageFlags) == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (((pageFlags & B_KERNEL_WRITE_AREA) && ((pageFlags & PAGE_MODIFIED) == 0))) {
|
||||||
|
map->SetFlags(far, PAGE_MODIFIED);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ ARMPagingMethod32Bit::PhysicalPageSlotPool::Map(phys_addr_t physicalAddress,
|
|||||||
pte = (physicalAddress & ARM_PTE_ADDRESS_MASK)
|
pte = (physicalAddress & ARM_PTE_ADDRESS_MASK)
|
||||||
| ARM_MMU_L2_TYPE_SMALLNEW
|
| ARM_MMU_L2_TYPE_SMALLNEW
|
||||||
| ARM_MMU_L2_FLAG_B | ARM_MMU_L2_FLAG_C
|
| ARM_MMU_L2_FLAG_B | ARM_MMU_L2_FLAG_C
|
||||||
| ARM_MMU_L2_FLAG_AP_KRW | ARM_MMU_L2_FLAG_XN;
|
| ARM_MMU_L2_FLAG_HAIKU_KERNEL_RW | ARM_MMU_L2_FLAG_XN;
|
||||||
|
|
||||||
arch_cpu_invalidate_TLB_page(virtualAddress);
|
arch_cpu_invalidate_TLB_page(virtualAddress);
|
||||||
}
|
}
|
||||||
@@ -408,7 +408,8 @@ ARMPagingMethod32Bit::MapEarly(kernel_args* args, addr_t virtualAddress,
|
|||||||
|
|
||||||
// now, fill in the pentry
|
// now, fill in the pentry
|
||||||
PutPageTableEntryInTable(ptEntry,
|
PutPageTableEntryInTable(ptEntry,
|
||||||
physicalAddress, attributes | PAGE_ACCESSED, 0, IS_KERNEL_ADDRESS(virtualAddress));
|
physicalAddress, attributes | PAGE_ACCESSED | PAGE_MODIFIED, 0,
|
||||||
|
IS_KERNEL_ADDRESS(virtualAddress));
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,6 +70,8 @@ public:
|
|||||||
static page_table_entry ClearPageTableEntry(page_table_entry* entry);
|
static page_table_entry ClearPageTableEntry(page_table_entry* entry);
|
||||||
static page_table_entry ClearPageTableEntryFlags(
|
static page_table_entry ClearPageTableEntryFlags(
|
||||||
page_table_entry* entry, uint32 flags);
|
page_table_entry* entry, uint32 flags);
|
||||||
|
static page_table_entry SetAndClearPageTableEntryFlags(page_table_entry* entry,
|
||||||
|
uint32 flagsToSet, uint32 flagsToClear);
|
||||||
|
|
||||||
static uint32 AttributesToPageTableEntryFlags(
|
static uint32 AttributesToPageTableEntryFlags(
|
||||||
uint32 attributes);
|
uint32 attributes);
|
||||||
@@ -145,6 +147,23 @@ ARMPagingMethod32Bit::ClearPageTableEntryFlags(page_table_entry* entry, uint32 f
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*static*/ inline page_table_entry
|
||||||
|
ARMPagingMethod32Bit::SetAndClearPageTableEntryFlags(page_table_entry* entry, uint32 flagsToSet, uint32 flagsToClear)
|
||||||
|
{
|
||||||
|
page_table_entry originalValue = *entry;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
page_table_entry oldEntry = atomic_test_and_set((int32*)entry,
|
||||||
|
(originalValue & ~flagsToClear) | flagsToSet, originalValue);
|
||||||
|
if (oldEntry == originalValue)
|
||||||
|
break;
|
||||||
|
originalValue = oldEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
return originalValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*static*/ inline uint32
|
/*static*/ inline uint32
|
||||||
ARMPagingMethod32Bit::AttributesToPageTableEntryFlags(uint32 attributes)
|
ARMPagingMethod32Bit::AttributesToPageTableEntryFlags(uint32 attributes)
|
||||||
{
|
{
|
||||||
@@ -153,15 +172,16 @@ ARMPagingMethod32Bit::AttributesToPageTableEntryFlags(uint32 attributes)
|
|||||||
if ((attributes & B_READ_AREA) != 0) {
|
if ((attributes & B_READ_AREA) != 0) {
|
||||||
// user accessible
|
// user accessible
|
||||||
apFlags = ARM_MMU_L2_FLAG_AP1;
|
apFlags = ARM_MMU_L2_FLAG_AP1;
|
||||||
if ((attributes & B_WRITE_AREA) == 0) {
|
if ((attributes & B_WRITE_AREA) == 0)
|
||||||
apFlags |= ARM_MMU_L2_FLAG_AP2;
|
apFlags |= ARM_MMU_L2_FLAG_AP2;
|
||||||
}
|
else
|
||||||
|
apFlags |= ARM_MMU_L2_FLAG_HAIKU_SWDBM;
|
||||||
} else if ((attributes & B_KERNEL_WRITE_AREA) == 0) {
|
} else if ((attributes & B_KERNEL_WRITE_AREA) == 0) {
|
||||||
// kernel ro
|
// kernel ro
|
||||||
apFlags = ARM_MMU_L2_FLAG_AP2;
|
apFlags = ARM_MMU_L2_FLAG_AP2;
|
||||||
} else {
|
} else {
|
||||||
// kernel rw
|
// kernel rw
|
||||||
apFlags = 0;
|
apFlags = ARM_MMU_L2_FLAG_HAIKU_SWDBM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((attributes & B_KERNEL_EXECUTE_AREA) == 0) &&
|
if (((attributes & B_KERNEL_EXECUTE_AREA) == 0) &&
|
||||||
@@ -172,6 +192,9 @@ ARMPagingMethod32Bit::AttributesToPageTableEntryFlags(uint32 attributes)
|
|||||||
if ((attributes & PAGE_ACCESSED) != 0)
|
if ((attributes & PAGE_ACCESSED) != 0)
|
||||||
apFlags |= ARM_MMU_L2_FLAG_AP0;
|
apFlags |= ARM_MMU_L2_FLAG_AP0;
|
||||||
|
|
||||||
|
if ((attributes & PAGE_MODIFIED) == 0)
|
||||||
|
apFlags |= ARM_MMU_L2_FLAG_AP2;
|
||||||
|
|
||||||
return apFlags;
|
return apFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,7 +204,7 @@ ARMPagingMethod32Bit::PageTableEntryFlagsToAttributes(uint32 pageTableEntry)
|
|||||||
{
|
{
|
||||||
uint32 attributes;
|
uint32 attributes;
|
||||||
|
|
||||||
if ((pageTableEntry & ARM_MMU_L2_FLAG_AP2) == 0) {
|
if ((pageTableEntry & ARM_MMU_L2_FLAG_HAIKU_SWDBM) != 0) {
|
||||||
if ((pageTableEntry & ARM_MMU_L2_FLAG_AP1) != 0) {
|
if ((pageTableEntry & ARM_MMU_L2_FLAG_AP1) != 0) {
|
||||||
attributes = B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_READ_AREA | B_WRITE_AREA;
|
attributes = B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_READ_AREA | B_WRITE_AREA;
|
||||||
} else {
|
} else {
|
||||||
@@ -197,6 +220,9 @@ ARMPagingMethod32Bit::PageTableEntryFlagsToAttributes(uint32 pageTableEntry)
|
|||||||
if ((pageTableEntry & ARM_MMU_L2_FLAG_AP0) != 0)
|
if ((pageTableEntry & ARM_MMU_L2_FLAG_AP0) != 0)
|
||||||
attributes |= PAGE_ACCESSED;
|
attributes |= PAGE_ACCESSED;
|
||||||
|
|
||||||
|
if ((pageTableEntry & ARM_MMU_L2_FLAG_AP2) == 0)
|
||||||
|
attributes |= PAGE_MODIFIED;
|
||||||
|
|
||||||
if ((pageTableEntry & ARM_MMU_L2_FLAG_XN) == 0) {
|
if ((pageTableEntry & ARM_MMU_L2_FLAG_XN) == 0) {
|
||||||
if ((attributes & B_KERNEL_READ_AREA) != 0)
|
if ((attributes & B_KERNEL_READ_AREA) != 0)
|
||||||
attributes |= B_KERNEL_EXECUTE_AREA;
|
attributes |= B_KERNEL_EXECUTE_AREA;
|
||||||
|
|||||||
@@ -462,7 +462,7 @@ ARMVMTranslationMap32Bit::UnmapPages(VMArea* area, addr_t base, size_t size,
|
|||||||
// transfer the accessed/dirty flags to the page
|
// transfer the accessed/dirty flags to the page
|
||||||
if ((oldEntry & ARM_MMU_L2_FLAG_AP0) != 0)
|
if ((oldEntry & ARM_MMU_L2_FLAG_AP0) != 0)
|
||||||
page->accessed = true;
|
page->accessed = true;
|
||||||
if (/*(oldEntry & ARM_PTE_DIRTY) != 0 */ false) // XXX
|
if ((oldEntry & ARM_MMU_L2_FLAG_AP2) == 0)
|
||||||
page->modified = true;
|
page->modified = true;
|
||||||
|
|
||||||
// remove the mapping object/decrement the wired_count of the
|
// remove the mapping object/decrement the wired_count of the
|
||||||
@@ -771,17 +771,20 @@ ARMVMTranslationMap32Bit::SetFlags(addr_t virtualAddress, uint32 flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32 flagsToSet = (flags & PAGE_ACCESSED) ? ARM_MMU_L2_FLAG_AP0 : 0;
|
uint32 flagsToSet = (flags & PAGE_ACCESSED) ? ARM_MMU_L2_FLAG_AP0 : 0;
|
||||||
|
uint32 flagsToClear = (flags & PAGE_MODIFIED) ? ARM_MMU_L2_FLAG_AP2 : 0;
|
||||||
|
|
||||||
page_table_entry* pt = (page_table_entry*)ARMPagingMethod32Bit::Method()
|
page_table_entry* pt = (page_table_entry*)ARMPagingMethod32Bit::Method()
|
||||||
->PhysicalPageMapper()->InterruptGetPageTableAt(
|
->PhysicalPageMapper()->InterruptGetPageTableAt(
|
||||||
pd[index] & ARM_PDE_ADDRESS_MASK);
|
pd[index] & ARM_PDE_ADDRESS_MASK);
|
||||||
index = VADDR_TO_PTENT(virtualAddress);
|
index = VADDR_TO_PTENT(virtualAddress);
|
||||||
|
|
||||||
ARMPagingMethod32Bit::SetPageTableEntryFlags(&pt[index], flagsToSet);
|
ARMPagingMethod32Bit::SetAndClearPageTableEntryFlags(&pt[index], flagsToSet, flagsToClear);
|
||||||
|
|
||||||
// No need to flush TLB as we currently handle only accessed flag.
|
// normally we would call InvalidatePage() here and then Flush() later when all updates are done
|
||||||
// TLB flush will be needed once modified flag is implemented.
|
// however, as this scenario happens only in case of Modified flag handling,
|
||||||
//InvalidatePage(virtualAddress);
|
// we can directly call TLBIMVAIS from here as we need to update only a single TLB entry
|
||||||
|
if (flagsToClear)
|
||||||
|
arch_cpu_invalidate_TLB_page(virtualAddress);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -796,12 +799,10 @@ ARMVMTranslationMap32Bit::ClearFlags(addr_t va, uint32 flags)
|
|||||||
// no pagetable here
|
// no pagetable here
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
#if 0 //IRA
|
|
||||||
uint32 flagsToClear = ((flags & PAGE_MODIFIED) ? X86_PTE_DIRTY : 0)
|
|
||||||
| ((flags & PAGE_ACCESSED) ? ARM_MMU_L2_FLAG_AP0 : 0);
|
|
||||||
#else
|
|
||||||
uint32 flagsToClear = (flags & PAGE_ACCESSED) ? ARM_MMU_L2_FLAG_AP0 : 0;
|
uint32 flagsToClear = (flags & PAGE_ACCESSED) ? ARM_MMU_L2_FLAG_AP0 : 0;
|
||||||
#endif
|
uint32 flagsToSet = (flags & PAGE_MODIFIED) ? ARM_MMU_L2_FLAG_AP2 : 0;
|
||||||
|
|
||||||
Thread* thread = thread_get_current_thread();
|
Thread* thread = thread_get_current_thread();
|
||||||
ThreadCPUPinner pinner(thread);
|
ThreadCPUPinner pinner(thread);
|
||||||
|
|
||||||
@@ -809,14 +810,14 @@ ARMVMTranslationMap32Bit::ClearFlags(addr_t va, uint32 flags)
|
|||||||
pd[index] & ARM_PDE_ADDRESS_MASK);
|
pd[index] & ARM_PDE_ADDRESS_MASK);
|
||||||
index = VADDR_TO_PTENT(va);
|
index = VADDR_TO_PTENT(va);
|
||||||
|
|
||||||
// clear out the flags we've been requested to clear
|
// adjust the flags we've been requested to set/clear
|
||||||
page_table_entry oldEntry
|
page_table_entry oldEntry
|
||||||
= ARMPagingMethod32Bit::ClearPageTableEntryFlags(&pt[index],
|
= ARMPagingMethod32Bit::SetAndClearPageTableEntryFlags(&pt[index],
|
||||||
flagsToClear);
|
flagsToSet, flagsToClear);
|
||||||
|
|
||||||
pinner.Unlock();
|
pinner.Unlock();
|
||||||
|
|
||||||
if ((oldEntry & flagsToClear) != 0)
|
if (((oldEntry & flagsToClear) != 0) || ((oldEntry & flagsToSet) == 0))
|
||||||
InvalidatePage(va);
|
InvalidatePage(va);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@@ -859,8 +860,8 @@ ARMVMTranslationMap32Bit::ClearAccessedAndModified(VMArea* area, addr_t address,
|
|||||||
}
|
}
|
||||||
if (oldEntry & ARM_MMU_L2_FLAG_AP0) {
|
if (oldEntry & ARM_MMU_L2_FLAG_AP0) {
|
||||||
// page was accessed -- just clear the flags
|
// page was accessed -- just clear the flags
|
||||||
oldEntry = ARMPagingMethod32Bit::ClearPageTableEntryFlags(
|
oldEntry = ARMPagingMethod32Bit::SetAndClearPageTableEntryFlags(
|
||||||
&pt[index], ARM_MMU_L2_FLAG_AP0 /* | ARM_PTE_DIRTY*/ ); // XXX
|
&pt[index], ARM_MMU_L2_FLAG_AP2, ARM_MMU_L2_FLAG_AP0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -873,13 +874,13 @@ ARMVMTranslationMap32Bit::ClearAccessedAndModified(VMArea* area, addr_t address,
|
|||||||
// something changed -- check again
|
// something changed -- check again
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
oldEntry = ARMPagingMethod32Bit::ClearPageTableEntryFlags(&pt[index],
|
oldEntry = ARMPagingMethod32Bit::SetAndClearPageTableEntryFlags(&pt[index],
|
||||||
ARM_MMU_L2_FLAG_AP0 /* | ARM_PTE_DIRTY*/ ); // XXX
|
ARM_MMU_L2_FLAG_AP2, ARM_MMU_L2_FLAG_AP0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pinner.Unlock();
|
pinner.Unlock();
|
||||||
|
|
||||||
_modified = false /* (oldEntry & X86_PTE_DIRTY) != 0 */; // XXX IRA
|
_modified = (oldEntry & ARM_MMU_L2_FLAG_AP2) == 0;
|
||||||
|
|
||||||
if ((oldEntry & ARM_MMU_L2_FLAG_AP0) != 0) {
|
if ((oldEntry & ARM_MMU_L2_FLAG_AP0) != 0) {
|
||||||
// Note, that we only need to invalidate the address, if the
|
// Note, that we only need to invalidate the address, if the
|
||||||
|
|||||||
Reference in New Issue
Block a user