Re: [PATCH 1/4] PCI: add resizeable BAR infrastructure v3

2017-03-24 Thread Bjorn Helgaas
On Mon, Mar 13, 2017 at 01:41:33PM +0100, Christian König wrote:
> From: Christian König 
> 
> Just the defines and helper functions to read the possible sizes of a BAR and
> update it's size.

s/it's/its/

> See 
> https://pcisig.com/sites/default/files/specification_documents/ECN_Resizable-BAR_24Apr2008.pdf.

It's good to have the public ECN that anybody can read, but we should
also have a reference to the full spec that incorporates it, e.g.,
PCIe r3.1, sec 7.22.

> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -1946,6 +1946,9 @@ void pci_request_acs(void);
>  bool pci_acs_enabled(struct pci_dev *pdev, u16 acs_flags);
>  bool pci_acs_path_enabled(struct pci_dev *start,
> struct pci_dev *end, u16 acs_flags);
> +u32 pci_rbar_get_possible_sizes(struct pci_dev *pdev, int bar);
> +int pci_rbar_get_current_size(struct pci_dev *pdev, int bar);
> +int pci_rbar_set_size(struct pci_dev *pdev, int bar, int size);

These should be declared in drivers/pci/pci.h unless they're needed
outside drivers/pci.  I hope they aren't needed outside, because
they're not safe to use after the PCI core has claimed resources.

>  #define PCI_VPD_LRDT 0x80/* Large Resource Data Type */
>  #define PCI_VPD_LRDT_ID(x)   ((x) | PCI_VPD_LRDT)
> diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h
> index e5a2e68..6de29d6 100644
> --- a/include/uapi/linux/pci_regs.h
> +++ b/include/uapi/linux/pci_regs.h
> @@ -932,9 +932,16 @@
>  #define PCI_SATA_SIZEOF_LONG 16
>  
>  /* Resizable BARs */
> +#define PCI_REBAR_CAP4   /* capability register */
> +#define  PCI_REBAR_CTRL_SIZES_MASK   (0xF << 4)  /* mask for sizes */
> +#define  PCI_REBAR_CTRL_SIZES_SHIFT  4   /* shift for sizes */
>  #define PCI_REBAR_CTRL   8   /* control register */
> +#define  PCI_REBAR_CTRL_BAR_IDX_MASK (7 << 0)/* mask for bar index */
> +#define  PCI_REBAR_CTRL_BAR_IDX_SHIFT0   /* shift for bar index 
> */
>  #define  PCI_REBAR_CTRL_NBAR_MASK(7 << 5)/* mask for # bars */
>  #define  PCI_REBAR_CTRL_NBAR_SHIFT   5   /* shift for # bars */
> +#define  PCI_REBAR_CTRL_BAR_SIZE_MASK(0x1F << 8) /* mask for bar 
> size */
> +#define  PCI_REBAR_CTRL_BAR_SIZE_SHIFT   8   /* shift for bar size */

s/bar/BAR/ several places above

>  /* Dynamic Power Allocation */
>  #define PCI_DPA_CAP  4   /* capability register */
> -- 
> 2.7.4
> 
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


Re: [PATCH 1/4] PCI: add resizeable BAR infrastructure v3

2017-03-14 Thread kbuild test robot
Hi Christian,

[auto build test WARNING on pci/next]
[also build test WARNING on v4.11-rc2 next-20170310]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Christian-K-nig/PCI-add-resizeable-BAR-infrastructure-v3/20170314-163334
base:   https://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git next
reproduce: make htmldocs

All warnings (new ones prefixed by >>):

   lib/crc32.c:148: warning: No description found for parameter 'tab)[256]'
   lib/crc32.c:148: warning: Excess function parameter 'tab' description in 
'crc32_le_generic'
   lib/crc32.c:293: warning: No description found for parameter 'tab)[256]'
   lib/crc32.c:293: warning: Excess function parameter 'tab' description in 
'crc32_be_generic'
   lib/crc32.c:1: warning: no structured comments found
>> drivers/pci/pci.c:2951: warning: No description found for parameter 'pdev'
>> drivers/pci/pci.c:2951: warning: Excess function parameter 'dev' description 
>> in 'pci_rbar_get_possible_sizes'
   drivers/pci/pci.c:2989: warning: No description found for parameter 'pdev'
>> drivers/pci/pci.c:2989: warning: Excess function parameter 'dev' description 
>> in 'pci_rbar_get_current_size'
   drivers/pci/pci.c:3027: warning: No description found for parameter 'pdev'
>> drivers/pci/pci.c:3027: warning: Excess function parameter 'dev' description 
>> in 'pci_rbar_set_size'

vim +/pdev +2951 drivers/pci/pci.c

  2945   * @bar: BAR to query
  2946   *
  2947   * Get the possible sizes of a resizeable BAR as bitmask defined in the 
spec
  2948   * (bit 0=1MB, bit 19=512GB). Returns 0 if BAR isn't resizeable.
  2949   */
  2950  u32 pci_rbar_get_possible_sizes(struct pci_dev *pdev, int bar)
> 2951  {
  2952  unsigned pos, nbars;
  2953  u32 ctrl, cap;
  2954  unsigned i;
  2955  
  2956  pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_REBAR);
  2957  if (!pos)
  2958  return 0;
  2959  
  2960  pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, );
  2961  nbars = (ctrl & PCI_REBAR_CTRL_NBAR_MASK) >> 
PCI_REBAR_CTRL_NBAR_SHIFT;
  2962  
  2963  for (i = 0; i < nbars; ++i, pos += 8) {
  2964  int bar_idx;
  2965  
  2966  pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, 
);
  2967  bar_idx = (ctrl & PCI_REBAR_CTRL_BAR_IDX_MASK) >>
  2968  PCI_REBAR_CTRL_BAR_IDX_SHIFT;
  2969  if (bar_idx != bar)
  2970  continue;
  2971  
  2972  pci_read_config_dword(pdev, pos + PCI_REBAR_CAP, );
  2973  return (cap & PCI_REBAR_CTRL_SIZES_MASK) >>
  2974  PCI_REBAR_CTRL_SIZES_SHIFT;
  2975  }
  2976  
  2977  return 0;
  2978  }
  2979  
  2980  /**
  2981   * pci_rbar_get_current_size - get the current size of a BAR
  2982   * @dev: PCI device
  2983   * @bar: BAR to set size to
  2984   *
  2985   * Read the size of a BAR from the resizeable BAR config.
  2986   * Returns size if found or negativ error code.
  2987   */
  2988  int pci_rbar_get_current_size(struct pci_dev *pdev, int bar)
> 2989  {
  2990  unsigned pos, nbars;
  2991  u32 ctrl;
  2992  unsigned i;
  2993  
  2994  pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_REBAR);
  2995  if (!pos)
  2996  return -ENOTSUPP;
  2997  
  2998  pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, );
  2999  nbars = (ctrl & PCI_REBAR_CTRL_NBAR_MASK) >> 
PCI_REBAR_CTRL_NBAR_SHIFT;
  3000  
  3001  for (i = 0; i < nbars; ++i, pos += 8) {
  3002  int bar_idx;
  3003  
  3004  pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, 
);
  3005  bar_idx = (ctrl & PCI_REBAR_CTRL_BAR_IDX_MASK) >>
  3006  PCI_REBAR_CTRL_BAR_IDX_SHIFT;
  3007  if (bar_idx != bar)
  3008  continue;
  3009  
  3010  return (ctrl & PCI_REBAR_CTRL_BAR_SIZE_MASK) >>
  3011  PCI_REBAR_CTRL_BAR_SIZE_SHIFT;
  3012  }
  3013  
  3014  return -ENOENT;
  3015  }
  3016  
  3017  /**
  3018   * pci_rbar_set_size - set a new size for a BAR
  3019   * @dev: PCI device
  3020   * @bar: BAR to set size to
  3021   * @size: new size as defined in the spec (log2(size in bytes) - 20)
  3022   *
  3023   * Set the new size of a BAR as defined in the spec (0=1MB, 19=512GB).
  3024   * Returns true if resizing was successful, false otherwise.
  3025   */
  3026  int pci_rbar_set_size(struct pci_dev *pdev, int bar, int size)
> 3027  {
  3028  unsigned pos, nbars;
  3029  u32 ctrl;
  3030  unsigned i;

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   

[PATCH 1/4] PCI: add resizeable BAR infrastructure v3

2017-03-13 Thread Christian König
From: Christian König 

Just the defines and helper functions to read the possible sizes of a BAR and
update it's size.

See 
https://pcisig.com/sites/default/files/specification_documents/ECN_Resizable-BAR_24Apr2008.pdf.

This is useful for hardware with large local storage (mostly GFX) which only
expose 256MB BARs initially to be compatible with 32bit systems.

v2: provide read helper as well
v3: improve function names, use unsigned values, add better comments.

Signed-off-by: Christian König 
---
 drivers/pci/pci.c | 115 ++
 include/linux/pci.h   |   3 ++
 include/uapi/linux/pci_regs.h |   7 +++
 3 files changed, 125 insertions(+)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index ba34907..c2d9f78 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -2944,6 +2944,121 @@ bool pci_acs_path_enabled(struct pci_dev *start,
 }
 
 /**
+ * pci_rbar_get_possible_sizes - get possible sizes for BAR
+ * @dev: PCI device
+ * @bar: BAR to query
+ *
+ * Get the possible sizes of a resizeable BAR as bitmask defined in the spec
+ * (bit 0=1MB, bit 19=512GB). Returns 0 if BAR isn't resizeable.
+ */
+u32 pci_rbar_get_possible_sizes(struct pci_dev *pdev, int bar)
+{
+   unsigned pos, nbars;
+   u32 ctrl, cap;
+   unsigned i;
+
+   pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_REBAR);
+   if (!pos)
+   return 0;
+
+   pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, );
+   nbars = (ctrl & PCI_REBAR_CTRL_NBAR_MASK) >> PCI_REBAR_CTRL_NBAR_SHIFT;
+
+   for (i = 0; i < nbars; ++i, pos += 8) {
+   int bar_idx;
+
+   pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, );
+   bar_idx = (ctrl & PCI_REBAR_CTRL_BAR_IDX_MASK) >>
+   PCI_REBAR_CTRL_BAR_IDX_SHIFT;
+   if (bar_idx != bar)
+   continue;
+
+   pci_read_config_dword(pdev, pos + PCI_REBAR_CAP, );
+   return (cap & PCI_REBAR_CTRL_SIZES_MASK) >>
+   PCI_REBAR_CTRL_SIZES_SHIFT;
+   }
+
+   return 0;
+}
+
+/**
+ * pci_rbar_get_current_size - get the current size of a BAR
+ * @dev: PCI device
+ * @bar: BAR to set size to
+ *
+ * Read the size of a BAR from the resizeable BAR config.
+ * Returns size if found or negativ error code.
+ */
+int pci_rbar_get_current_size(struct pci_dev *pdev, int bar)
+{
+   unsigned pos, nbars;
+   u32 ctrl;
+   unsigned i;
+
+   pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_REBAR);
+   if (!pos)
+   return -ENOTSUPP;
+
+   pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, );
+   nbars = (ctrl & PCI_REBAR_CTRL_NBAR_MASK) >> PCI_REBAR_CTRL_NBAR_SHIFT;
+
+   for (i = 0; i < nbars; ++i, pos += 8) {
+   int bar_idx;
+
+   pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, );
+   bar_idx = (ctrl & PCI_REBAR_CTRL_BAR_IDX_MASK) >>
+   PCI_REBAR_CTRL_BAR_IDX_SHIFT;
+   if (bar_idx != bar)
+   continue;
+
+   return (ctrl & PCI_REBAR_CTRL_BAR_SIZE_MASK) >>
+   PCI_REBAR_CTRL_BAR_SIZE_SHIFT;
+   }
+
+   return -ENOENT;
+}
+
+/**
+ * pci_rbar_set_size - set a new size for a BAR
+ * @dev: PCI device
+ * @bar: BAR to set size to
+ * @size: new size as defined in the spec (log2(size in bytes) - 20)
+ *
+ * Set the new size of a BAR as defined in the spec (0=1MB, 19=512GB).
+ * Returns true if resizing was successful, false otherwise.
+ */
+int pci_rbar_set_size(struct pci_dev *pdev, int bar, int size)
+{
+   unsigned pos, nbars;
+   u32 ctrl;
+   unsigned i;
+
+   pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_REBAR);
+   if (!pos)
+   return -ENOTSUPP;
+
+   pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, );
+   nbars = (ctrl & PCI_REBAR_CTRL_NBAR_MASK) >> PCI_REBAR_CTRL_NBAR_SHIFT;
+
+   for (i = 0; i < nbars; ++i, pos += 8) {
+   int bar_idx;
+
+   pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, );
+   bar_idx = (ctrl & PCI_REBAR_CTRL_BAR_IDX_MASK) >>
+   PCI_REBAR_CTRL_BAR_IDX_SHIFT;
+   if (bar_idx != bar)
+   continue;
+
+   ctrl &= ~PCI_REBAR_CTRL_BAR_SIZE_MASK;
+   ctrl |= size << PCI_REBAR_CTRL_BAR_SIZE_SHIFT;
+   pci_write_config_dword(pdev, pos + PCI_REBAR_CTRL, ctrl);
+   return 0;
+   }
+
+   return -ENOENT;
+}
+
+/**
  * pci_swizzle_interrupt_pin - swizzle INTx for device behind bridge
  * @dev: the PCI device
  * @pin: the INTx pin (1=INTA, 2=INTB, 3=INTC, 4=INTD)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index a38772a..6954e50 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1946,6 +1946,9 @@ void pci_request_acs(void);
 bool