Home | History | Annotate | Line # | Download | only in gvt
      1  1.1  riastrad /*	$NetBSD: cfg_space.c,v 1.2 2021/12/18 23:45:31 riastradh Exp $	*/
      2  1.1  riastrad 
      3  1.1  riastrad /*
      4  1.1  riastrad  * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
      5  1.1  riastrad  *
      6  1.1  riastrad  * Permission is hereby granted, free of charge, to any person obtaining a
      7  1.1  riastrad  * copy of this software and associated documentation files (the "Software"),
      8  1.1  riastrad  * to deal in the Software without restriction, including without limitation
      9  1.1  riastrad  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  1.1  riastrad  * and/or sell copies of the Software, and to permit persons to whom the
     11  1.1  riastrad  * Software is furnished to do so, subject to the following conditions:
     12  1.1  riastrad  *
     13  1.1  riastrad  * The above copyright notice and this permission notice (including the next
     14  1.1  riastrad  * paragraph) shall be included in all copies or substantial portions of the
     15  1.1  riastrad  * Software.
     16  1.1  riastrad  *
     17  1.1  riastrad  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     18  1.1  riastrad  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  1.1  riastrad  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     20  1.1  riastrad  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     21  1.1  riastrad  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     22  1.1  riastrad  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     23  1.1  riastrad  * SOFTWARE.
     24  1.1  riastrad  *
     25  1.1  riastrad  * Authors:
     26  1.1  riastrad  *    Eddie Dong <eddie.dong (at) intel.com>
     27  1.1  riastrad  *    Jike Song <jike.song (at) intel.com>
     28  1.1  riastrad  *
     29  1.1  riastrad  * Contributors:
     30  1.1  riastrad  *    Zhi Wang <zhi.a.wang (at) intel.com>
     31  1.1  riastrad  *    Min He <min.he (at) intel.com>
     32  1.1  riastrad  *    Bing Niu <bing.niu (at) intel.com>
     33  1.1  riastrad  *
     34  1.1  riastrad  */
     35  1.1  riastrad 
     36  1.1  riastrad #include <sys/cdefs.h>
     37  1.1  riastrad __KERNEL_RCSID(0, "$NetBSD: cfg_space.c,v 1.2 2021/12/18 23:45:31 riastradh Exp $");
     38  1.1  riastrad 
     39  1.1  riastrad #include "i915_drv.h"
     40  1.1  riastrad #include "gvt.h"
     41  1.1  riastrad 
     42  1.1  riastrad enum {
     43  1.1  riastrad 	INTEL_GVT_PCI_BAR_GTTMMIO = 0,
     44  1.1  riastrad 	INTEL_GVT_PCI_BAR_APERTURE,
     45  1.1  riastrad 	INTEL_GVT_PCI_BAR_PIO,
     46  1.1  riastrad 	INTEL_GVT_PCI_BAR_MAX,
     47  1.1  riastrad };
     48  1.1  riastrad 
     49  1.1  riastrad /* bitmap for writable bits (RW or RW1C bits, but cannot co-exist in one
     50  1.1  riastrad  * byte) byte by byte in standard pci configuration space. (not the full
     51  1.1  riastrad  * 256 bytes.)
     52  1.1  riastrad  */
     53  1.1  riastrad static const u8 pci_cfg_space_rw_bmp[PCI_INTERRUPT_LINE + 4] = {
     54  1.1  riastrad 	[PCI_COMMAND]		= 0xff, 0x07,
     55  1.1  riastrad 	[PCI_STATUS]		= 0x00, 0xf9, /* the only one RW1C byte */
     56  1.1  riastrad 	[PCI_CACHE_LINE_SIZE]	= 0xff,
     57  1.1  riastrad 	[PCI_BASE_ADDRESS_0 ... PCI_CARDBUS_CIS - 1] = 0xff,
     58  1.1  riastrad 	[PCI_ROM_ADDRESS]	= 0x01, 0xf8, 0xff, 0xff,
     59  1.1  riastrad 	[PCI_INTERRUPT_LINE]	= 0xff,
     60  1.1  riastrad };
     61  1.1  riastrad 
     62  1.1  riastrad /**
     63  1.1  riastrad  * vgpu_pci_cfg_mem_write - write virtual cfg space memory
     64  1.1  riastrad  * @vgpu: target vgpu
     65  1.1  riastrad  * @off: offset
     66  1.1  riastrad  * @src: src ptr to write
     67  1.1  riastrad  * @bytes: number of bytes
     68  1.1  riastrad  *
     69  1.1  riastrad  * Use this function to write virtual cfg space memory.
     70  1.1  riastrad  * For standard cfg space, only RW bits can be changed,
     71  1.1  riastrad  * and we emulates the RW1C behavior of PCI_STATUS register.
     72  1.1  riastrad  */
     73  1.1  riastrad static void vgpu_pci_cfg_mem_write(struct intel_vgpu *vgpu, unsigned int off,
     74  1.1  riastrad 				   u8 *src, unsigned int bytes)
     75  1.1  riastrad {
     76  1.1  riastrad 	u8 *cfg_base = vgpu_cfg_space(vgpu);
     77  1.1  riastrad 	u8 mask, new, old;
     78  1.1  riastrad 	int i = 0;
     79  1.1  riastrad 
     80  1.1  riastrad 	for (; i < bytes && (off + i < sizeof(pci_cfg_space_rw_bmp)); i++) {
     81  1.1  riastrad 		mask = pci_cfg_space_rw_bmp[off + i];
     82  1.1  riastrad 		old = cfg_base[off + i];
     83  1.1  riastrad 		new = src[i] & mask;
     84  1.1  riastrad 
     85  1.1  riastrad 		/**
     86  1.1  riastrad 		 * The PCI_STATUS high byte has RW1C bits, here
     87  1.1  riastrad 		 * emulates clear by writing 1 for these bits.
     88  1.1  riastrad 		 * Writing a 0b to RW1C bits has no effect.
     89  1.1  riastrad 		 */
     90  1.1  riastrad 		if (off + i == PCI_STATUS + 1)
     91  1.1  riastrad 			new = (~new & old) & mask;
     92  1.1  riastrad 
     93  1.1  riastrad 		cfg_base[off + i] = (old & ~mask) | new;
     94  1.1  riastrad 	}
     95  1.1  riastrad 
     96  1.1  riastrad 	/* For other configuration space directly copy as it is. */
     97  1.1  riastrad 	if (i < bytes)
     98  1.1  riastrad 		memcpy(cfg_base + off + i, src + i, bytes - i);
     99  1.1  riastrad }
    100  1.1  riastrad 
    101  1.1  riastrad /**
    102  1.1  riastrad  * intel_vgpu_emulate_cfg_read - emulate vGPU configuration space read
    103  1.1  riastrad  * @vgpu: target vgpu
    104  1.1  riastrad  * @offset: offset
    105  1.1  riastrad  * @p_data: return data ptr
    106  1.1  riastrad  * @bytes: number of bytes to read
    107  1.1  riastrad  *
    108  1.1  riastrad  * Returns:
    109  1.1  riastrad  * Zero on success, negative error code if failed.
    110  1.1  riastrad  */
    111  1.1  riastrad int intel_vgpu_emulate_cfg_read(struct intel_vgpu *vgpu, unsigned int offset,
    112  1.1  riastrad 	void *p_data, unsigned int bytes)
    113  1.1  riastrad {
    114  1.1  riastrad 	if (WARN_ON(bytes > 4))
    115  1.1  riastrad 		return -EINVAL;
    116  1.1  riastrad 
    117  1.1  riastrad 	if (WARN_ON(offset + bytes > vgpu->gvt->device_info.cfg_space_size))
    118  1.1  riastrad 		return -EINVAL;
    119  1.1  riastrad 
    120  1.1  riastrad 	memcpy(p_data, vgpu_cfg_space(vgpu) + offset, bytes);
    121  1.1  riastrad 	return 0;
    122  1.1  riastrad }
    123  1.1  riastrad 
    124  1.1  riastrad static int map_aperture(struct intel_vgpu *vgpu, bool map)
    125  1.1  riastrad {
    126  1.1  riastrad 	phys_addr_t aperture_pa = vgpu_aperture_pa_base(vgpu);
    127  1.1  riastrad 	unsigned long aperture_sz = vgpu_aperture_sz(vgpu);
    128  1.1  riastrad 	u64 first_gfn;
    129  1.1  riastrad 	u64 val;
    130  1.1  riastrad 	int ret;
    131  1.1  riastrad 
    132  1.1  riastrad 	if (map == vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_APERTURE].tracked)
    133  1.1  riastrad 		return 0;
    134  1.1  riastrad 
    135  1.1  riastrad 	val = vgpu_cfg_space(vgpu)[PCI_BASE_ADDRESS_2];
    136  1.1  riastrad 	if (val & PCI_BASE_ADDRESS_MEM_TYPE_64)
    137  1.1  riastrad 		val = *(u64 *)(vgpu_cfg_space(vgpu) + PCI_BASE_ADDRESS_2);
    138  1.1  riastrad 	else
    139  1.1  riastrad 		val = *(u32 *)(vgpu_cfg_space(vgpu) + PCI_BASE_ADDRESS_2);
    140  1.1  riastrad 
    141  1.1  riastrad 	first_gfn = (val + vgpu_aperture_offset(vgpu)) >> PAGE_SHIFT;
    142  1.1  riastrad 
    143  1.1  riastrad 	ret = intel_gvt_hypervisor_map_gfn_to_mfn(vgpu, first_gfn,
    144  1.1  riastrad 						  aperture_pa >> PAGE_SHIFT,
    145  1.1  riastrad 						  aperture_sz >> PAGE_SHIFT,
    146  1.1  riastrad 						  map);
    147  1.1  riastrad 	if (ret)
    148  1.1  riastrad 		return ret;
    149  1.1  riastrad 
    150  1.1  riastrad 	vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_APERTURE].tracked = map;
    151  1.1  riastrad 	return 0;
    152  1.1  riastrad }
    153  1.1  riastrad 
    154  1.1  riastrad static int trap_gttmmio(struct intel_vgpu *vgpu, bool trap)
    155  1.1  riastrad {
    156  1.1  riastrad 	u64 start, end;
    157  1.1  riastrad 	u64 val;
    158  1.1  riastrad 	int ret;
    159  1.1  riastrad 
    160  1.1  riastrad 	if (trap == vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_GTTMMIO].tracked)
    161  1.1  riastrad 		return 0;
    162  1.1  riastrad 
    163  1.1  riastrad 	val = vgpu_cfg_space(vgpu)[PCI_BASE_ADDRESS_0];
    164  1.1  riastrad 	if (val & PCI_BASE_ADDRESS_MEM_TYPE_64)
    165  1.1  riastrad 		start = *(u64 *)(vgpu_cfg_space(vgpu) + PCI_BASE_ADDRESS_0);
    166  1.1  riastrad 	else
    167  1.1  riastrad 		start = *(u32 *)(vgpu_cfg_space(vgpu) + PCI_BASE_ADDRESS_0);
    168  1.1  riastrad 
    169  1.1  riastrad 	start &= ~GENMASK(3, 0);
    170  1.1  riastrad 	end = start + vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_GTTMMIO].size - 1;
    171  1.1  riastrad 
    172  1.1  riastrad 	ret = intel_gvt_hypervisor_set_trap_area(vgpu, start, end, trap);
    173  1.1  riastrad 	if (ret)
    174  1.1  riastrad 		return ret;
    175  1.1  riastrad 
    176  1.1  riastrad 	vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_GTTMMIO].tracked = trap;
    177  1.1  riastrad 	return 0;
    178  1.1  riastrad }
    179  1.1  riastrad 
    180  1.1  riastrad static int emulate_pci_command_write(struct intel_vgpu *vgpu,
    181  1.1  riastrad 	unsigned int offset, void *p_data, unsigned int bytes)
    182  1.1  riastrad {
    183  1.1  riastrad 	u8 old = vgpu_cfg_space(vgpu)[offset];
    184  1.1  riastrad 	u8 new = *(u8 *)p_data;
    185  1.1  riastrad 	u8 changed = old ^ new;
    186  1.1  riastrad 	int ret;
    187  1.1  riastrad 
    188  1.1  riastrad 	vgpu_pci_cfg_mem_write(vgpu, offset, p_data, bytes);
    189  1.1  riastrad 	if (!(changed & PCI_COMMAND_MEMORY))
    190  1.1  riastrad 		return 0;
    191  1.1  riastrad 
    192  1.1  riastrad 	if (old & PCI_COMMAND_MEMORY) {
    193  1.1  riastrad 		ret = trap_gttmmio(vgpu, false);
    194  1.1  riastrad 		if (ret)
    195  1.1  riastrad 			return ret;
    196  1.1  riastrad 		ret = map_aperture(vgpu, false);
    197  1.1  riastrad 		if (ret)
    198  1.1  riastrad 			return ret;
    199  1.1  riastrad 	} else {
    200  1.1  riastrad 		ret = trap_gttmmio(vgpu, true);
    201  1.1  riastrad 		if (ret)
    202  1.1  riastrad 			return ret;
    203  1.1  riastrad 		ret = map_aperture(vgpu, true);
    204  1.1  riastrad 		if (ret)
    205  1.1  riastrad 			return ret;
    206  1.1  riastrad 	}
    207  1.1  riastrad 
    208  1.1  riastrad 	return 0;
    209  1.1  riastrad }
    210  1.1  riastrad 
    211  1.1  riastrad static int emulate_pci_rom_bar_write(struct intel_vgpu *vgpu,
    212  1.1  riastrad 	unsigned int offset, void *p_data, unsigned int bytes)
    213  1.1  riastrad {
    214  1.1  riastrad 	u32 *pval = (u32 *)(vgpu_cfg_space(vgpu) + offset);
    215  1.1  riastrad 	u32 new = *(u32 *)(p_data);
    216  1.1  riastrad 
    217  1.1  riastrad 	if ((new & PCI_ROM_ADDRESS_MASK) == PCI_ROM_ADDRESS_MASK)
    218  1.1  riastrad 		/* We don't have rom, return size of 0. */
    219  1.1  riastrad 		*pval = 0;
    220  1.1  riastrad 	else
    221  1.1  riastrad 		vgpu_pci_cfg_mem_write(vgpu, offset, p_data, bytes);
    222  1.1  riastrad 	return 0;
    223  1.1  riastrad }
    224  1.1  riastrad 
    225  1.1  riastrad static int emulate_pci_bar_write(struct intel_vgpu *vgpu, unsigned int offset,
    226  1.1  riastrad 	void *p_data, unsigned int bytes)
    227  1.1  riastrad {
    228  1.1  riastrad 	u32 new = *(u32 *)(p_data);
    229  1.1  riastrad 	bool lo = IS_ALIGNED(offset, 8);
    230  1.1  riastrad 	u64 size;
    231  1.1  riastrad 	int ret = 0;
    232  1.1  riastrad 	bool mmio_enabled =
    233  1.1  riastrad 		vgpu_cfg_space(vgpu)[PCI_COMMAND] & PCI_COMMAND_MEMORY;
    234  1.1  riastrad 	struct intel_vgpu_pci_bar *bars = vgpu->cfg_space.bar;
    235  1.1  riastrad 
    236  1.1  riastrad 	/*
    237  1.1  riastrad 	 * Power-up software can determine how much address
    238  1.1  riastrad 	 * space the device requires by writing a value of
    239  1.1  riastrad 	 * all 1's to the register and then reading the value
    240  1.1  riastrad 	 * back. The device will return 0's in all don't-care
    241  1.1  riastrad 	 * address bits.
    242  1.1  riastrad 	 */
    243  1.1  riastrad 	if (new == 0xffffffff) {
    244  1.1  riastrad 		switch (offset) {
    245  1.1  riastrad 		case PCI_BASE_ADDRESS_0:
    246  1.1  riastrad 		case PCI_BASE_ADDRESS_1:
    247  1.1  riastrad 			size = ~(bars[INTEL_GVT_PCI_BAR_GTTMMIO].size -1);
    248  1.1  riastrad 			intel_vgpu_write_pci_bar(vgpu, offset,
    249  1.1  riastrad 						size >> (lo ? 0 : 32), lo);
    250  1.1  riastrad 			/*
    251  1.1  riastrad 			 * Untrap the BAR, since guest hasn't configured a
    252  1.1  riastrad 			 * valid GPA
    253  1.1  riastrad 			 */
    254  1.1  riastrad 			ret = trap_gttmmio(vgpu, false);
    255  1.1  riastrad 			break;
    256  1.1  riastrad 		case PCI_BASE_ADDRESS_2:
    257  1.1  riastrad 		case PCI_BASE_ADDRESS_3:
    258  1.1  riastrad 			size = ~(bars[INTEL_GVT_PCI_BAR_APERTURE].size -1);
    259  1.1  riastrad 			intel_vgpu_write_pci_bar(vgpu, offset,
    260  1.1  riastrad 						size >> (lo ? 0 : 32), lo);
    261  1.1  riastrad 			ret = map_aperture(vgpu, false);
    262  1.1  riastrad 			break;
    263  1.1  riastrad 		default:
    264  1.1  riastrad 			/* Unimplemented BARs */
    265  1.1  riastrad 			intel_vgpu_write_pci_bar(vgpu, offset, 0x0, false);
    266  1.1  riastrad 		}
    267  1.1  riastrad 	} else {
    268  1.1  riastrad 		switch (offset) {
    269  1.1  riastrad 		case PCI_BASE_ADDRESS_0:
    270  1.1  riastrad 		case PCI_BASE_ADDRESS_1:
    271  1.1  riastrad 			/*
    272  1.1  riastrad 			 * Untrap the old BAR first, since guest has
    273  1.1  riastrad 			 * re-configured the BAR
    274  1.1  riastrad 			 */
    275  1.1  riastrad 			trap_gttmmio(vgpu, false);
    276  1.1  riastrad 			intel_vgpu_write_pci_bar(vgpu, offset, new, lo);
    277  1.1  riastrad 			ret = trap_gttmmio(vgpu, mmio_enabled);
    278  1.1  riastrad 			break;
    279  1.1  riastrad 		case PCI_BASE_ADDRESS_2:
    280  1.1  riastrad 		case PCI_BASE_ADDRESS_3:
    281  1.1  riastrad 			map_aperture(vgpu, false);
    282  1.1  riastrad 			intel_vgpu_write_pci_bar(vgpu, offset, new, lo);
    283  1.1  riastrad 			ret = map_aperture(vgpu, mmio_enabled);
    284  1.1  riastrad 			break;
    285  1.1  riastrad 		default:
    286  1.1  riastrad 			intel_vgpu_write_pci_bar(vgpu, offset, new, lo);
    287  1.1  riastrad 		}
    288  1.1  riastrad 	}
    289  1.1  riastrad 	return ret;
    290  1.1  riastrad }
    291  1.1  riastrad 
    292  1.1  riastrad /**
    293  1.1  riastrad  * intel_vgpu_emulate_cfg_read - emulate vGPU configuration space write
    294  1.1  riastrad  * @vgpu: target vgpu
    295  1.1  riastrad  * @offset: offset
    296  1.1  riastrad  * @p_data: write data ptr
    297  1.1  riastrad  * @bytes: number of bytes to write
    298  1.1  riastrad  *
    299  1.1  riastrad  * Returns:
    300  1.1  riastrad  * Zero on success, negative error code if failed.
    301  1.1  riastrad  */
    302  1.1  riastrad int intel_vgpu_emulate_cfg_write(struct intel_vgpu *vgpu, unsigned int offset,
    303  1.1  riastrad 	void *p_data, unsigned int bytes)
    304  1.1  riastrad {
    305  1.1  riastrad 	int ret;
    306  1.1  riastrad 
    307  1.1  riastrad 	if (WARN_ON(bytes > 4))
    308  1.1  riastrad 		return -EINVAL;
    309  1.1  riastrad 
    310  1.1  riastrad 	if (WARN_ON(offset + bytes > vgpu->gvt->device_info.cfg_space_size))
    311  1.1  riastrad 		return -EINVAL;
    312  1.1  riastrad 
    313  1.1  riastrad 	/* First check if it's PCI_COMMAND */
    314  1.1  riastrad 	if (IS_ALIGNED(offset, 2) && offset == PCI_COMMAND) {
    315  1.1  riastrad 		if (WARN_ON(bytes > 2))
    316  1.1  riastrad 			return -EINVAL;
    317  1.1  riastrad 		return emulate_pci_command_write(vgpu, offset, p_data, bytes);
    318  1.1  riastrad 	}
    319  1.1  riastrad 
    320  1.1  riastrad 	switch (rounddown(offset, 4)) {
    321  1.1  riastrad 	case PCI_ROM_ADDRESS:
    322  1.1  riastrad 		if (WARN_ON(!IS_ALIGNED(offset, 4)))
    323  1.1  riastrad 			return -EINVAL;
    324  1.1  riastrad 		return emulate_pci_rom_bar_write(vgpu, offset, p_data, bytes);
    325  1.1  riastrad 
    326  1.1  riastrad 	case PCI_BASE_ADDRESS_0 ... PCI_BASE_ADDRESS_5:
    327  1.1  riastrad 		if (WARN_ON(!IS_ALIGNED(offset, 4)))
    328  1.1  riastrad 			return -EINVAL;
    329  1.1  riastrad 		return emulate_pci_bar_write(vgpu, offset, p_data, bytes);
    330  1.1  riastrad 
    331  1.1  riastrad 	case INTEL_GVT_PCI_SWSCI:
    332  1.1  riastrad 		if (WARN_ON(!IS_ALIGNED(offset, 4)))
    333  1.1  riastrad 			return -EINVAL;
    334  1.1  riastrad 		ret = intel_vgpu_emulate_opregion_request(vgpu, *(u32 *)p_data);
    335  1.1  riastrad 		if (ret)
    336  1.1  riastrad 			return ret;
    337  1.1  riastrad 		break;
    338  1.1  riastrad 
    339  1.1  riastrad 	case INTEL_GVT_PCI_OPREGION:
    340  1.1  riastrad 		if (WARN_ON(!IS_ALIGNED(offset, 4)))
    341  1.1  riastrad 			return -EINVAL;
    342  1.1  riastrad 		ret = intel_vgpu_opregion_base_write_handler(vgpu,
    343  1.1  riastrad 						   *(u32 *)p_data);
    344  1.1  riastrad 		if (ret)
    345  1.1  riastrad 			return ret;
    346  1.1  riastrad 
    347  1.1  riastrad 		vgpu_pci_cfg_mem_write(vgpu, offset, p_data, bytes);
    348  1.1  riastrad 		break;
    349  1.1  riastrad 	default:
    350  1.1  riastrad 		vgpu_pci_cfg_mem_write(vgpu, offset, p_data, bytes);
    351  1.1  riastrad 		break;
    352  1.1  riastrad 	}
    353  1.1  riastrad 	return 0;
    354  1.1  riastrad }
    355  1.1  riastrad 
    356  1.1  riastrad /**
    357  1.1  riastrad  * intel_vgpu_init_cfg_space - init vGPU configuration space when create vGPU
    358  1.1  riastrad  *
    359  1.1  riastrad  * @vgpu: a vGPU
    360  1.1  riastrad  * @primary: is the vGPU presented as primary
    361  1.1  riastrad  *
    362  1.1  riastrad  */
    363  1.1  riastrad void intel_vgpu_init_cfg_space(struct intel_vgpu *vgpu,
    364  1.1  riastrad 			       bool primary)
    365  1.1  riastrad {
    366  1.1  riastrad 	struct intel_gvt *gvt = vgpu->gvt;
    367  1.1  riastrad 	const struct intel_gvt_device_info *info = &gvt->device_info;
    368  1.1  riastrad 	u16 *gmch_ctl;
    369  1.1  riastrad 
    370  1.1  riastrad 	memcpy(vgpu_cfg_space(vgpu), gvt->firmware.cfg_space,
    371  1.1  riastrad 	       info->cfg_space_size);
    372  1.1  riastrad 
    373  1.1  riastrad 	if (!primary) {
    374  1.1  riastrad 		vgpu_cfg_space(vgpu)[PCI_CLASS_DEVICE] =
    375  1.1  riastrad 			INTEL_GVT_PCI_CLASS_VGA_OTHER;
    376  1.1  riastrad 		vgpu_cfg_space(vgpu)[PCI_CLASS_PROG] =
    377  1.1  riastrad 			INTEL_GVT_PCI_CLASS_VGA_OTHER;
    378  1.1  riastrad 	}
    379  1.1  riastrad 
    380  1.1  riastrad 	/* Show guest that there isn't any stolen memory.*/
    381  1.1  riastrad 	gmch_ctl = (u16 *)(vgpu_cfg_space(vgpu) + INTEL_GVT_PCI_GMCH_CONTROL);
    382  1.1  riastrad 	*gmch_ctl &= ~(BDW_GMCH_GMS_MASK << BDW_GMCH_GMS_SHIFT);
    383  1.1  riastrad 
    384  1.1  riastrad 	intel_vgpu_write_pci_bar(vgpu, PCI_BASE_ADDRESS_2,
    385  1.1  riastrad 				 gvt_aperture_pa_base(gvt), true);
    386  1.1  riastrad 
    387  1.1  riastrad 	vgpu_cfg_space(vgpu)[PCI_COMMAND] &= ~(PCI_COMMAND_IO
    388  1.1  riastrad 					     | PCI_COMMAND_MEMORY
    389  1.1  riastrad 					     | PCI_COMMAND_MASTER);
    390  1.1  riastrad 	/*
    391  1.1  riastrad 	 * Clear the bar upper 32bit and let guest to assign the new value
    392  1.1  riastrad 	 */
    393  1.1  riastrad 	memset(vgpu_cfg_space(vgpu) + PCI_BASE_ADDRESS_1, 0, 4);
    394  1.1  riastrad 	memset(vgpu_cfg_space(vgpu) + PCI_BASE_ADDRESS_3, 0, 4);
    395  1.1  riastrad 	memset(vgpu_cfg_space(vgpu) + PCI_BASE_ADDRESS_4, 0, 8);
    396  1.1  riastrad 	memset(vgpu_cfg_space(vgpu) + INTEL_GVT_PCI_OPREGION, 0, 4);
    397  1.1  riastrad 
    398  1.1  riastrad 	vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_GTTMMIO].size =
    399  1.1  riastrad 				pci_resource_len(gvt->dev_priv->drm.pdev, 0);
    400  1.1  riastrad 	vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_APERTURE].size =
    401  1.1  riastrad 				pci_resource_len(gvt->dev_priv->drm.pdev, 2);
    402  1.1  riastrad 
    403  1.1  riastrad 	memset(vgpu_cfg_space(vgpu) + PCI_ROM_ADDRESS, 0, 4);
    404  1.1  riastrad }
    405  1.1  riastrad 
    406  1.1  riastrad /**
    407  1.1  riastrad  * intel_vgpu_reset_cfg_space - reset vGPU configuration space
    408  1.1  riastrad  *
    409  1.1  riastrad  * @vgpu: a vGPU
    410  1.1  riastrad  *
    411  1.1  riastrad  */
    412  1.1  riastrad void intel_vgpu_reset_cfg_space(struct intel_vgpu *vgpu)
    413  1.1  riastrad {
    414  1.1  riastrad 	u8 cmd = vgpu_cfg_space(vgpu)[PCI_COMMAND];
    415  1.1  riastrad 	bool primary = vgpu_cfg_space(vgpu)[PCI_CLASS_DEVICE] !=
    416  1.1  riastrad 				INTEL_GVT_PCI_CLASS_VGA_OTHER;
    417  1.1  riastrad 
    418  1.1  riastrad 	if (cmd & PCI_COMMAND_MEMORY) {
    419  1.1  riastrad 		trap_gttmmio(vgpu, false);
    420  1.1  riastrad 		map_aperture(vgpu, false);
    421  1.1  riastrad 	}
    422  1.1  riastrad 
    423  1.1  riastrad 	/**
    424  1.1  riastrad 	 * Currently we only do such reset when vGPU is not
    425  1.1  riastrad 	 * owned by any VM, so we simply restore entire cfg
    426  1.1  riastrad 	 * space to default value.
    427  1.1  riastrad 	 */
    428  1.1  riastrad 	intel_vgpu_init_cfg_space(vgpu, primary);
    429  1.1  riastrad }
    430