Author: cem
Date: Wed Nov 25 01:59:08 2015
New Revision: 291280
URL: https://svnweb.freebsd.org/changeset/base/291280

Log:
  NTB: WC/WB isn't enough; set MMR region as UC
  
  And expose vm_memattr_t of current mapping to consumers (as well as the
  ability to change it to one of UC, WB, WC).
  
  After short discussion with:  jhb (but no review)
  Sponsored by: EMC / Isilon Storage Division

Modified:
  head/sys/dev/ntb/ntb_hw/ntb_hw.c
  head/sys/dev/ntb/ntb_hw/ntb_hw.h

Modified: head/sys/dev/ntb/ntb_hw/ntb_hw.c
==============================================================================
--- head/sys/dev/ntb/ntb_hw/ntb_hw.c    Wed Nov 25 01:29:46 2015        
(r291279)
+++ head/sys/dev/ntb/ntb_hw/ntb_hw.c    Wed Nov 25 01:59:08 2015        
(r291280)
@@ -114,7 +114,7 @@ struct ntb_pci_bar_info {
        vm_paddr_t              pbase;
        caddr_t                 vbase;
        vm_size_t               size;
-       bool                    mapped_wc : 1;
+       vm_memattr_t            map_mode;
 
        /* Configuration register offsets */
        uint32_t                psz_off;
@@ -270,7 +270,8 @@ static inline bool bar_is_64bit(struct n
 static inline void bar_get_xlat_params(struct ntb_softc *, enum ntb_bar,
     uint32_t *base, uint32_t *xlat, uint32_t *lmt);
 static int ntb_map_pci_bars(struct ntb_softc *ntb);
-static int ntb_mw_set_wc_internal(struct ntb_softc *, unsigned idx, bool wc);
+static int ntb_mw_set_wc_internal(struct ntb_softc *, unsigned idx,
+    vm_memattr_t);
 static void print_map_success(struct ntb_softc *, struct ntb_pci_bar_info *,
     const char *);
 static int map_mmr_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar);
@@ -718,6 +719,7 @@ map_mmr_bar(struct ntb_softc *ntb, struc
                return (ENXIO);
 
        save_bar_parameters(bar);
+       bar->map_mode = VM_MEMATTR_UNCACHEABLE;
        print_map_success(ntb, bar, "mmr");
        return (0);
 }
@@ -726,6 +728,7 @@ static int
 map_memory_window_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar)
 {
        int rc;
+       vm_memattr_t mapmode;
        uint8_t bar_size_bits = 0;
 
        bar->pci_resource = bus_alloc_resource_any(ntb->device, SYS_RES_MEMORY,
@@ -771,29 +774,34 @@ map_memory_window_bar(struct ntb_softc *
                save_bar_parameters(bar);
        }
 
+       bar->map_mode = VM_MEMATTR_UNCACHEABLE;
        print_map_success(ntb, bar, "mw");
-       if (g_ntb_enable_wc == 0)
-               return (0);
 
        /* Mark bar region as write combining to improve performance. */
-       rc = pmap_change_attr((vm_offset_t)bar->vbase, bar->size,
-           VM_MEMATTR_WRITE_COMBINING);
+       mapmode = VM_MEMATTR_WRITE_COMBINING;
+       if (g_ntb_enable_wc == 0)
+               mapmode = VM_MEMATTR_WRITE_BACK;
+
+       rc = pmap_change_attr((vm_offset_t)bar->vbase, bar->size, mapmode);
        if (rc == 0) {
-               bar->mapped_wc = true;
+               bar->map_mode = mapmode;
                device_printf(ntb->device,
                    "Marked BAR%d v:[%p-%p] p:[%p-%p] as "
-                   "WRITE_COMBINING.\n",
+                   "%s.\n",
                    PCI_RID2BAR(bar->pci_resource_id), bar->vbase,
                    (char *)bar->vbase + bar->size - 1,
-                   (void *)bar->pbase, (void *)(bar->pbase + bar->size - 1));
+                   (void *)bar->pbase, (void *)(bar->pbase + bar->size - 1),
+                   (mapmode == VM_MEMATTR_WRITE_COMBINING) ? "WRITE_COMBINING"
+                   : "WRITE_BACK");
        } else
                device_printf(ntb->device,
                    "Unable to mark BAR%d v:[%p-%p] p:[%p-%p] as "
-                   "WRITE_COMBINING: %d\n",
+                   "%s: %d\n",
                    PCI_RID2BAR(bar->pci_resource_id), bar->vbase,
                    (char *)bar->vbase + bar->size - 1,
                    (void *)bar->pbase, (void *)(bar->pbase + bar->size - 1),
-                   rc);
+                   (mapmode == VM_MEMATTR_WRITE_COMBINING) ? "WRITE_COMBINING"
+                   : "WRITE_BACK", rc);
                /* Proceed anyway */
        return (0);
 }
@@ -1272,7 +1280,7 @@ ntb_xeon_init_dev(struct ntb_softc *ntb)
                    ntb->mw_count;
                ntb_printf(2, "Setting up b2b mw idx %d means %u\n",
                    g_ntb_mw_idx, ntb->b2b_mw_idx);
-               rc = ntb_mw_set_wc_internal(ntb, ntb->b2b_mw_idx, false);
+               rc = ntb_mw_set_wc_internal(ntb, ntb->b2b_mw_idx, 
VM_MEMATTR_UNCACHEABLE);
                KASSERT(rc == 0, ("shouldn't fail"));
        } else if (HAS_FEATURE(NTB_B2BDOORBELL_BIT14))
                /*
@@ -2672,9 +2680,11 @@ ntb_mw_clear_trans(struct ntb_softc *ntb
  *
  * Returns:  Zero on success, setting *wc; otherwise an error number (e.g. if
  * idx is an invalid memory window).
+ *
+ * Mode is a VM_MEMATTR_* type.
  */
 int
-ntb_mw_get_wc(struct ntb_softc *ntb, unsigned idx, bool *wc)
+ntb_mw_get_wc(struct ntb_softc *ntb, unsigned idx, vm_memattr_t *mode)
 {
        struct ntb_pci_bar_info *bar;
 
@@ -2683,49 +2693,48 @@ ntb_mw_get_wc(struct ntb_softc *ntb, uns
        idx = ntb_user_mw_to_idx(ntb, idx);
 
        bar = &ntb->bar_info[ntb_mw_to_bar(ntb, idx)];
-       *wc = bar->mapped_wc;
+       *mode = bar->map_mode;
        return (0);
 }
 
 /*
  * ntb_mw_set_wc - Set the write-combine status of a memory window
  *
- * If 'wc' matches the current status, this does nothing and succeeds.
+ * If 'mode' matches the current status, this does nothing and succeeds.  Mode
+ * is a VM_MEMATTR_* type.
  *
  * Returns:  Zero on success, setting the caching attribute on the virtual
  * mapping of the BAR; otherwise an error number (e.g. if idx is an invalid
  * memory window, or if changing the caching attribute fails).
  */
 int
-ntb_mw_set_wc(struct ntb_softc *ntb, unsigned idx, bool wc)
+ntb_mw_set_wc(struct ntb_softc *ntb, unsigned idx, vm_memattr_t mode)
 {
 
        if (idx >= ntb_mw_count(ntb))
                return (EINVAL);
 
        idx = ntb_user_mw_to_idx(ntb, idx);
-       return (ntb_mw_set_wc_internal(ntb, idx, wc));
+       return (ntb_mw_set_wc_internal(ntb, idx, mode));
 }
 
 static int
-ntb_mw_set_wc_internal(struct ntb_softc *ntb, unsigned idx, bool wc)
+ntb_mw_set_wc_internal(struct ntb_softc *ntb, unsigned idx, vm_memattr_t mode)
 {
        struct ntb_pci_bar_info *bar;
-       vm_memattr_t attr;
        int rc;
 
        bar = &ntb->bar_info[ntb_mw_to_bar(ntb, idx)];
-       if (bar->mapped_wc == wc)
+       if (bar->map_mode == mode)
                return (0);
 
-       if (wc)
-               attr = VM_MEMATTR_WRITE_COMBINING;
-       else
-               attr = VM_MEMATTR_DEFAULT;
+       if (mode != VM_MEMATTR_UNCACHEABLE && mode != VM_MEMATTR_DEFAULT &&
+           mode != VM_MEMATTR_WRITE_COMBINING)
+               return (EINVAL);
 
-       rc = pmap_change_attr((vm_offset_t)bar->vbase, bar->size, attr);
+       rc = pmap_change_attr((vm_offset_t)bar->vbase, bar->size, mode);
        if (rc == 0)
-               bar->mapped_wc = wc;
+               bar->map_mode = mode;
 
        return (rc);
 }

Modified: head/sys/dev/ntb/ntb_hw/ntb_hw.h
==============================================================================
--- head/sys/dev/ntb/ntb_hw/ntb_hw.h    Wed Nov 25 01:29:46 2015        
(r291279)
+++ head/sys/dev/ntb/ntb_hw/ntb_hw.h    Wed Nov 25 01:59:08 2015        
(r291280)
@@ -82,8 +82,8 @@ int ntb_mw_get_range(struct ntb_softc *,
 int ntb_mw_set_trans(struct ntb_softc *, unsigned mw_idx, bus_addr_t, size_t);
 int ntb_mw_clear_trans(struct ntb_softc *, unsigned mw_idx);
 
-int ntb_mw_get_wc(struct ntb_softc *, unsigned mw_idx, bool *wc);
-int ntb_mw_set_wc(struct ntb_softc *, unsigned mw_idx, bool wc);
+int ntb_mw_get_wc(struct ntb_softc *, unsigned mw_idx, vm_memattr_t *mode);
+int ntb_mw_set_wc(struct ntb_softc *, unsigned mw_idx, vm_memattr_t mode);
 
 uint8_t ntb_get_max_spads(struct ntb_softc *ntb);
 int ntb_spad_write(struct ntb_softc *ntb, unsigned int idx, uint32_t val);
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to