mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	PCI: vmd: Add offset to bus numbers if necessary
Depending on platform configuration, certain VMD devices may have an
additional configuration option which specifies the range of bus numbers
allowed in a VMD PCIe domain. We determine this requirement by checking
the value of two vendor specific config registers in the VMD endpoint:
 VMCAP[0] | VMCONFIG[9:8] | Bus Numbers
----------------------------------------
    0     |       *       |     0-255
    1     |      00       |     0-127
    1     |      01       |   128-255
    1     |      10       |     0-255
This feature is also added as a bit in driver_data, to allow future
conforming device ids which support these features to be enabled through
sysfs new_id.
Signed-off-by: Jon Derrick <jonathan.derrick@intel.com>
[lorenzo.pieralisi@arm.com: updated commit subject]
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
			
			
This commit is contained in:
		
							parent
							
								
									6788958e4f
								
							
						
					
					
						commit
						2a5a9c9a20
					
				
					 1 changed files with 29 additions and 5 deletions
				
			
		| 
						 | 
				
			
			@ -24,6 +24,10 @@
 | 
			
		|||
#define VMD_MEMBAR1	2
 | 
			
		||||
#define VMD_MEMBAR2	4
 | 
			
		||||
 | 
			
		||||
#define PCI_REG_VMCAP		0x40
 | 
			
		||||
#define BUS_RESTRICT_CAP(vmcap)	(vmcap & 0x1)
 | 
			
		||||
#define PCI_REG_VMCONFIG	0x44
 | 
			
		||||
#define BUS_RESTRICT_CFG(vmcfg)	((vmcfg >> 8) & 0x3)
 | 
			
		||||
#define PCI_REG_VMLOCK		0x70
 | 
			
		||||
#define MB2_SHADOW_EN(vmlock)	(vmlock & 0x2)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -34,6 +38,12 @@ enum vmd_features {
 | 
			
		|||
	 * resource assignment to enable guest virtualization
 | 
			
		||||
	 */
 | 
			
		||||
	VMD_FEAT_HAS_MEMBAR_SHADOW	= (1 << 0),
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Device may provide root port configuration information which limits
 | 
			
		||||
	 * bus numbering
 | 
			
		||||
	 */
 | 
			
		||||
	VMD_FEAT_HAS_BUS_RESTRICTIONS	= (1 << 1),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			@ -567,7 +577,7 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)
 | 
			
		|||
	unsigned long flags;
 | 
			
		||||
	LIST_HEAD(resources);
 | 
			
		||||
	resource_size_t offset[2] = {0};
 | 
			
		||||
	resource_size_t membar2_offset = 0x2000;
 | 
			
		||||
	resource_size_t membar2_offset = 0x2000, busn_start = 0;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Shadow registers may exist in certain VMD device ids which allow
 | 
			
		||||
| 
						 | 
				
			
			@ -598,11 +608,25 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Certain VMD devices may have a root port configuration option which
 | 
			
		||||
	 * limits the bus range to between 0-127 or 128-255
 | 
			
		||||
	 */
 | 
			
		||||
	if (features & VMD_FEAT_HAS_BUS_RESTRICTIONS) {
 | 
			
		||||
		u32 vmcap, vmconfig;
 | 
			
		||||
 | 
			
		||||
		pci_read_config_dword(vmd->dev, PCI_REG_VMCAP, &vmcap);
 | 
			
		||||
		pci_read_config_dword(vmd->dev, PCI_REG_VMCONFIG, &vmconfig);
 | 
			
		||||
		if (BUS_RESTRICT_CAP(vmcap) &&
 | 
			
		||||
		    (BUS_RESTRICT_CFG(vmconfig) == 0x1))
 | 
			
		||||
			busn_start = 128;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	res = &vmd->dev->resource[VMD_CFGBAR];
 | 
			
		||||
	vmd->resources[0] = (struct resource) {
 | 
			
		||||
		.name  = "VMD CFGBAR",
 | 
			
		||||
		.start = 0,
 | 
			
		||||
		.end   = (resource_size(res) >> 20) - 1,
 | 
			
		||||
		.start = busn_start,
 | 
			
		||||
		.end   = busn_start + (resource_size(res) >> 20) - 1,
 | 
			
		||||
		.flags = IORESOURCE_BUS | IORESOURCE_PCI_FIXED,
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -670,8 +694,8 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)
 | 
			
		|||
	pci_add_resource_offset(&resources, &vmd->resources[1], offset[0]);
 | 
			
		||||
	pci_add_resource_offset(&resources, &vmd->resources[2], offset[1]);
 | 
			
		||||
 | 
			
		||||
	vmd->bus = pci_create_root_bus(&vmd->dev->dev, 0, &vmd_ops, sd,
 | 
			
		||||
				       &resources);
 | 
			
		||||
	vmd->bus = pci_create_root_bus(&vmd->dev->dev, busn_start, &vmd_ops,
 | 
			
		||||
				       sd, &resources);
 | 
			
		||||
	if (!vmd->bus) {
 | 
			
		||||
		pci_free_resource_list(&resources);
 | 
			
		||||
		irq_domain_remove(vmd->irq_domain);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue