vmap_pmem_nocache()
authorBarret Rhoden <brho@cs.berkeley.edu>
Thu, 3 Apr 2014 21:37:04 +0000 (14:37 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 3 Apr 2014 23:04:39 +0000 (16:04 -0700)
Maps in physical memory to the kernel's VA space, but with caching
disabled (if available).  We'll need to use this for device MMIO.

kern/arch/riscv/ros/mmu.h
kern/arch/x86/ros/mmu32.h
kern/arch/x86/ros/mmu64.h
kern/drivers/net/etherigbe.c
kern/include/mm.h
kern/src/mm.c

index 43a9c43..633e87f 100644 (file)
 #define PTE_SR   0x200 // Supervisor Write permission
 #define PTE_PERM (PTE_SR | PTE_SW | PTE_SX | PTE_UR | PTE_UW | PTE_UX)
 #define PTE_PPN_SHIFT 13
+#define PTE_NOCACHE    0 // PTE bits to turn off caching, if possible
 
 // commly used access modes
 #define PTE_KERN_RW    (PTE_SR | PTE_SW | PTE_SX)
index 22f6bf1..62196f7 100644 (file)
@@ -188,6 +188,7 @@ typedef unsigned long pde_t;
 #define PTE_PS         0x080   // Page Size (only applies to PDEs)
 #define PTE_PAT                0x080   // PAT (only applies to second layer PTEs)
 #define PTE_G          0x100   // Global Page
+#define PTE_NOCACHE    (PTE_PWT | PTE_PCD)
 
 #define PTE_PERM       (PTE_W | PTE_U) // The permissions fields
 // commly used access modes
index d89804b..7113573 100644 (file)
@@ -274,6 +274,7 @@ typedef unsigned long pde_t;
 #define PTE_PAT                        0x080   /* Page attribute table */
 #define PTE_G                  0x100   /* Global Page */
 #define PTE_JPAT               0x800   /* Jumbo PAT */
+#define PTE_NOCACHE            (PTE_PWT | PTE_PCD)
 
 /* Permissions fields and common access modes.  These should be read as 'just
  * kernel or user too' and 'RO or RW'.  USER_RO means read-only for everyone. */
index 1e8be98..14ca78e 100644 (file)
@@ -2022,7 +2022,7 @@ igbepci(void)
 
                mmio_paddr = pcidev->bar[0].mmio_base32 ? pcidev->bar[0].mmio_base32 : 
                                                          pcidev->bar[0].mmio_base64;
-               mem = (void*)vmap_pmem(mmio_paddr, pcidev->bar[0].mmio_sz);
+               mem = (void*)vmap_pmem_nocache(mmio_paddr, pcidev->bar[0].mmio_sz);
                if(mem == NULL){
                        printd("igbe: can't map %p\n", pcidev->bar[0].mmio_base32);
                        continue;
index f18b260..a58aa3e 100644 (file)
@@ -79,6 +79,7 @@ int map_vmap_segment(uintptr_t vaddr, uintptr_t paddr, unsigned long num_pages,
 int unmap_vmap_segment(uintptr_t vaddr, unsigned long num_pages);
 /* Helper wrappers, since no one will probably call the *_segment funcs */
 uintptr_t vmap_pmem(uintptr_t paddr, size_t nr_bytes);
+uintptr_t vmap_pmem_nocache(uintptr_t paddr, size_t nr_bytes);
 int vunmap_vmem(uintptr_t vaddr, size_t nr_bytes);
 
 #endif /* !ROS_KERN_MM_H */
index 7207747..ac2b7ac 100644 (file)
@@ -1155,7 +1155,7 @@ int unmap_vmap_segment(uintptr_t vaddr, unsigned long num_pages)
        return 0;
 }
 
-uintptr_t vmap_pmem(uintptr_t paddr, size_t nr_bytes)
+static uintptr_t vmap_pmem_flags(uintptr_t paddr, size_t nr_bytes, int flags)
 {
        uintptr_t vaddr;
        unsigned long nr_pages = ROUNDUP(nr_bytes, PGSIZE) >> PGSHIFT;
@@ -1165,13 +1165,23 @@ uintptr_t vmap_pmem(uintptr_t paddr, size_t nr_bytes)
                warn("Unable to get a vmap segment");   /* probably a bug */
                return 0;
        }
-       if (map_vmap_segment(vaddr, paddr, nr_pages, PTE_P | PTE_KERN_RW)) {
+       if (map_vmap_segment(vaddr, paddr, nr_pages, PTE_P | PTE_KERN_RW | flags)) {
                warn("Unable to map a vmap segment");   /* probably a bug */
                return 0;
        }
        return vaddr;
 }
 
+uintptr_t vmap_pmem(uintptr_t paddr, size_t nr_bytes)
+{
+       return vmap_pmem_flags(paddr, nr_bytes, 0);
+}
+
+uintptr_t vmap_pmem_nocache(uintptr_t paddr, size_t nr_bytes)
+{
+       return vmap_pmem_flags(paddr, nr_bytes, PTE_NOCACHE);
+}
+
 int vunmap_vmem(uintptr_t vaddr, size_t nr_bytes)
 {
        unsigned long nr_pages = ROUNDUP(nr_bytes, PGSIZE) >> PGSHIFT;