Re: [PATCH] PCI: Exclude VTBAR range from Local MMIOL if necessary

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 2010-01-14 at 14:45 -0800, Yinghai Lu wrote:
> On 01/14/2010 02:23 PM, Myron Stowe wrote:
> 
> Subject: [PATCH -v2] PCI: Exclude VTBAR range from Local MMIOL if necessary
> To: jbarnes@xxxxxxxxxxxxxxxx
> From: Myron Stowe <myron.stowe@xxxxxx>
> Cc: linux-pci@xxxxxxxxxxxxxxx, yinghai@xxxxxxxxxx
> 
> Intel's x58 chipset (IOH) includes a VTBAR (Base Address Register for
> Intel VT-d Chipset Registers) that specifies an 8K aligned system memory
> address for VT-d memory mapped registers.  If BIOS has placed the VT-d
> register window within the Local MMIOL range, it will not be available
> for downstream PCI devices, so remove it from the host bridge's MMIOL
> range.
> 
> This patch determines if the VTBAR is enabled and modifies the IOH's
> Local MMIOL range if it is programmed within such.
> 
> 
> Reference: "Intel X58 Express Chipset Datasheet"
>            http://www.intel.com/Assets/PDF/datasheet/320838.pdf
> 
> -v2: yinghai update it with more complete range comparing
> 	and change 0x120 to 0x200 again
> -v3: yinghai update it with add/subtract_range
> 
> ---
> 
>  arch/x86/pci/intel_bus.c |   29 +++++++++++++++++++++++++++--
>  1 file changed, 27 insertions(+), 2 deletions(-)
> 
> Index: linux-2.6/arch/x86/pci/intel_bus.c
> ===================================================================
> --- linux-2.6.orig/arch/x86/pci/intel_bus.c
> +++ linux-2.6/arch/x86/pci/intel_bus.c
> @@ -41,6 +41,11 @@ static inline void print_ioh_resources(s
>  #define IOH_LMMIOH_LIMITU	0x118
>  #define IOH_LCFGBUS		0x11c
>  
> +#define IOH_VTBAR		0x180
> +#define IOH_VTSIZE		0x2000	/* Fixed HW size (not programmable) */
> +
> +#define RANGE_NUM 16
> +
>  static void __devinit pci_root_bus_res(struct pci_dev *dev)
>  {
>  	u16 word;
> @@ -50,9 +55,11 @@ static void __devinit pci_root_bus_res(s
>  	u32 mmiol_base, mmiol_end;
>  	u64 mmioh_base, mmioh_end;
>  	int bus_base, bus_end;
> +	struct range range[RANGE_NUM];
> +	int i;
>  
>  	/* some sys doesn't get mmconf enabled */
> -	if (dev->cfg_size < 0x120)
> +	if (dev->cfg_size < 0x200)
>  		return;
>  
>  	if (pci_root_num >= PCI_ROOT_NR) {
> @@ -78,7 +85,25 @@ static void __devinit pci_root_bus_res(s
>  	pci_read_config_dword(dev, IOH_LMMIOL, &dword);
>  	mmiol_base = (dword & 0xff00) << (24 - 8);
>  	mmiol_end = (dword & 0xff000000) | 0xffffff;
> -	update_res(info, mmiol_base, mmiol_end, IORESOURCE_MEM, 0);
> +	memset(range, 0, sizeof(range));
> +	add_range(range, RANGE_NUM, 0, mmiol_base, (u64)mmiol_end + 1);
> +	pci_read_config_dword(dev, IOH_VTBAR, &dword);
> +	if (dword & 0x1) {
> +		u32 vt_base, vt_end;
> +
> +		vt_base = dword & 0xfffffffe;
> +		vt_end = vt_base + IOH_VTSIZE - 1;
> +
> +		subtract_range(range, RANGE_NUM, vt_base, vt_end + 1);
> +	}
> +	for (i = 0; i < RANGE_NUM; i++) {
> +		if (!range[i].end)
> +			continue;
> +
> +		update_res(info, cap_resource(range[i].start),
> +			   cap_resource(range[i].end - 1),
> +			   IORESOURCE_MEM, 0);
> +	}
>  
>  	pci_read_config_dword(dev, IOH_LMMIOH, &dword);
>  	mmioh_base = ((u64)(dword & 0xfc00)) << (26 - 10);
> 

You originally asked if I could create a 'vt_base' and a 'vt_end', is
that all your stuck on?  I find it a little interesting that your latest
alternate suggestion creates 'vt_base' and 'vt_end' with no real
purpose.  If you have discovered a real hole/issue in the original patch
then please let me know about such.


I do think your usage of 'add_range()' and 'subtract_range()' may lead
to a better long term solution.  They effectively do the exact same
thing as the patch content I added, albeit by separating out the range
manipulation into a separate routine which will be better in the long
term (so that others can leverage - much the same way you are trying to
leverage the mtrr specific routines).

I do have to ask however - what tree are you using?  I noticed that
'add_range()' and 'subtract_range()' are static routines related to mtrr
code.  I rebased my git tree to tip and applied your latest patch and
got:
        arch/x86/pci/intel_bus.c: In function ‘pci_root_bus_res’:
        arch/x86/pci/intel_bus.c:56: error: array type has incomplete element type
        arch/x86/pci/intel_bus.c:87: error: implicit declaration of function ‘add_range’
        arch/x86/pci/intel_bus.c:95: error: implicit declaration of function ‘subtract_range’
        arch/x86/pci/intel_bus.c:101: error: implicit declaration of function ‘cap_resource’
        arch/x86/pci/intel_bus.c:56: warning: unused variable ‘range’
        make[1]: *** [arch/x86/pci/intel_bus.o] Error 1
        make: *** [arch/x86/pci] Error 2

Myron

-- 
Myron Stowe                             HP Open Source Linux Lab (OSLL)

--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux