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"