[haiku-commits] r36583 - haiku/trunk/src/system/kernel/arch/x86

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sun, 2 May 2010 17:30:52 +0200 (CEST)

Author: bonefish
Date: 2010-05-02 17:30:52 +0200 (Sun, 02 May 2010)
New Revision: 36583
Changeset: http://dev.haiku-os.org/changeset/36583/haiku

Modified:
   haiku/trunk/src/system/kernel/arch/x86/arch_vm_translation_map.cpp
   haiku/trunk/src/system/kernel/arch/x86/x86_paging.h
Log:
Support memory types in page mappings to the degree that is possible without
PAT support (i.e. uncacheable, write-through, and write-back). Has pretty
much no effect ATM, as the MTRRs restrict the types to what is actually
requested.


Modified: haiku/trunk/src/system/kernel/arch/x86/arch_vm_translation_map.cpp
===================================================================
--- haiku/trunk/src/system/kernel/arch/x86/arch_vm_translation_map.cpp  
2010-05-02 15:08:21 UTC (rev 36582)
+++ haiku/trunk/src/system/kernel/arch/x86/arch_vm_translation_map.cpp  
2010-05-02 15:30:52 UTC (rev 36583)
@@ -151,12 +151,44 @@
 }
 
 
+static inline uint32
+memory_type_to_pte_flags(uint32 memoryType)
+{
+       // ATM we only handle the uncacheable and write-through type 
explicitly. For
+       // all other types we rely on the MTRRs to be set up correctly. Since 
we set
+       // the default memory type to write-back and since the uncacheable type 
in
+       // the PTE overrides any MTRR attribute (though, as per the specs, that 
is
+       // not recommended for performance reasons), this reduces the work we
+       // actually *have* to do with the MTRRs to setting the remaining types
+       // (usually only write-combining for the frame buffer).
+       switch (memoryType) {
+               case B_MTR_UC:
+                       return X86_PTE_CACHING_DISABLED;
+
+               case B_MTR_WC:
+                       // X86_PTE_WRITE_THROUGH would be closer, but the 
combination with
+                       // MTRR WC is "implementation defined" for Pentium 
[Pro].
+                       return 0;
+
+               case B_MTR_WT:
+                       return X86_PTE_WRITE_THROUGH;
+
+               case B_MTR_WP:
+               case B_MTR_WB:
+               default:
+                       return 0;
+       }
+}
+
+
 static void
 put_page_table_entry_in_pgtable(page_table_entry* entry,
-       addr_t physicalAddress, uint32 attributes, bool globalPage)
+       addr_t physicalAddress, uint32 attributes, uint32 memoryType,
+       bool globalPage)
 {
        page_table_entry page = (physicalAddress & X86_PTE_ADDRESS_MASK)
-               | X86_PTE_PRESENT | (globalPage ? X86_PTE_GLOBAL : 0);
+               | X86_PTE_PRESENT | (globalPage ? X86_PTE_GLOBAL : 0)
+               | memory_type_to_pte_flags(memoryType);
 
        // if the page is user accessible, it's automatically
        // accessible in kernel space, too (but with the same
@@ -404,7 +436,6 @@
 X86VMTranslationMap::Map(addr_t va, addr_t pa, uint32 attributes,
        uint32 memoryType, vm_page_reservation* reservation)
 {
-// TODO: Support memory types!
        TRACE("map_tmap: entry pa 0x%lx va 0x%lx\n", pa, va);
 
 /*
@@ -458,7 +489,7 @@
                "virtual address: %#" B_PRIxADDR ", existing pte: %#" B_PRIx32, 
va,
                pt[index]);
 
-       put_page_table_entry_in_pgtable(&pt[index], pa, attributes,
+       put_page_table_entry_in_pgtable(&pt[index], pa, attributes, memoryType,
                IS_KERNEL_MAP(map));
 
        pinner.Unlock();
@@ -975,7 +1006,6 @@
 X86VMTranslationMap::Protect(addr_t start, addr_t end, uint32 attributes,
        uint32 memoryType)
 {
-// TODO: Support memory types!
        page_directory_entry *pd = fArchData->pgdir_virt;
 
        start = ROUNDDOWN(start, B_PAGE_SIZE);
@@ -1026,8 +1056,8 @@
                page_table_entry oldEntry;
                while (true) {
                        oldEntry = test_and_set_page_table_entry(&pt[index],
-                               (entry & ~(X86_PTE_WRITABLE | X86_PTE_USER))
-                                       | newProtectionFlags,
+                               (entry & ~(X86_PTE_PROTECTION_MASK | 
X86_PTE_MEMORY_TYPE_MASK))
+                                       | newProtectionFlags | 
memory_type_to_pte_flags(memoryType),
                                entry);
                        if (oldEntry == entry)
                                break;
@@ -1449,7 +1479,7 @@
 
        // now, fill in the pentry
        put_page_table_entry_in_pgtable(sPageHole + va / B_PAGE_SIZE, pa,
-               attributes, IS_KERNEL_ADDRESS(va));
+               attributes, 0, IS_KERNEL_ADDRESS(va));
 
        return B_OK;
 }

Modified: haiku/trunk/src/system/kernel/arch/x86/x86_paging.h
===================================================================
--- haiku/trunk/src/system/kernel/arch/x86/x86_paging.h 2010-05-02 15:08:21 UTC 
(rev 36582)
+++ haiku/trunk/src/system/kernel/arch/x86/x86_paging.h 2010-05-02 15:30:52 UTC 
(rev 36583)
@@ -54,6 +54,9 @@
 #define X86_PTE_IGNORED2                       0x00000400
 #define X86_PTE_IGNORED3                       0x00000800
 #define X86_PTE_ADDRESS_MASK           0xfffff000
+#define X86_PTE_PROTECTION_MASK                (X86_PTE_WRITABLE | 
X86_PTE_USER)
+#define X86_PTE_MEMORY_TYPE_MASK       (X86_PTE_WRITE_THROUGH \
+                                                                               
| X86_PTE_CACHING_DISABLED)
 
 
 typedef uint32 page_table_entry;


Other related posts:

  • » [haiku-commits] r36583 - haiku/trunk/src/system/kernel/arch/x86 - ingo_weinhold