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