1 /* 2 * Copyright(c) 2011-2016 Intel Corporation. All rights reserved. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 * SOFTWARE. 22 * 23 * Authors: 24 * Zhi Wang <zhi.a.wang@intel.com> 25 * 26 * Contributors: 27 * Changbin Du <changbin.du@intel.com> 28 * 29 */ 30 31 #include <linux/firmware.h> 32 #include <linux/crc32.h> 33 34 #include "i915_drv.h" 35 #include "gvt.h" 36 #include "i915_pvinfo.h" 37 38 #define FIRMWARE_VERSION (0x0) 39 40 struct gvt_firmware_header { 41 u64 magic; 42 u32 crc32; /* protect the data after this field */ 43 u32 version; 44 u64 cfg_space_size; 45 u64 cfg_space_offset; /* offset in the file */ 46 u64 mmio_size; 47 u64 mmio_offset; /* offset in the file */ 48 unsigned char data[1]; 49 }; 50 51 #define RD(offset) (readl(mmio + offset.reg)) 52 #define WR(v, offset) (writel(v, mmio + offset.reg)) 53 54 static void bdw_forcewake_get(void __iomem *mmio) 55 { 56 WR(_MASKED_BIT_DISABLE(0xffff), FORCEWAKE_MT); 57 58 RD(ECOBUS); 59 60 if (wait_for((RD(FORCEWAKE_ACK_HSW) & FORCEWAKE_KERNEL) == 0, 50)) 61 gvt_err("fail to wait forcewake idle\n"); 62 63 WR(_MASKED_BIT_ENABLE(FORCEWAKE_KERNEL), FORCEWAKE_MT); 64 65 if (wait_for((RD(FORCEWAKE_ACK_HSW) & FORCEWAKE_KERNEL), 50)) 66 gvt_err("fail to wait forcewake ack\n"); 67 68 if (wait_for((RD(GEN6_GT_THREAD_STATUS_REG) & 69 GEN6_GT_THREAD_STATUS_CORE_MASK) == 0, 50)) 70 gvt_err("fail to wait c0 wake up\n"); 71 } 72 73 #undef RD 74 #undef WR 75 76 #define dev_to_drm_minor(d) dev_get_drvdata((d)) 77 78 static ssize_t 79 gvt_firmware_read(struct file *filp, struct kobject *kobj, 80 struct bin_attribute *attr, char *buf, 81 loff_t offset, size_t count) 82 { 83 memcpy(buf, attr->private + offset, count); 84 return count; 85 } 86 87 static struct bin_attribute firmware_attr = { 88 .attr = {.name = "gvt_firmware", .mode = (S_IRUSR)}, 89 .read = gvt_firmware_read, 90 .write = NULL, 91 .mmap = NULL, 92 }; 93 94 static int expose_firmware_sysfs(struct intel_gvt *gvt, 95 void __iomem *mmio) 96 { 97 struct intel_gvt_device_info *info = &gvt->device_info; 98 struct pci_dev *pdev = gvt->dev_priv->drm.pdev; 99 struct intel_gvt_mmio_info *e; 100 struct gvt_firmware_header *h; 101 void *firmware; 102 void *p; 103 unsigned long size; 104 int i; 105 int ret; 106 107 size = sizeof(*h) + info->mmio_size + info->cfg_space_size - 1; 108 firmware = vmalloc(size); 109 if (!firmware) 110 return -ENOMEM; 111 112 h = firmware; 113 114 h->magic = VGT_MAGIC; 115 h->version = FIRMWARE_VERSION; 116 h->cfg_space_size = info->cfg_space_size; 117 h->cfg_space_offset = offsetof(struct gvt_firmware_header, data); 118 h->mmio_size = info->mmio_size; 119 h->mmio_offset = h->cfg_space_offset + h->cfg_space_size; 120 121 p = firmware + h->cfg_space_offset; 122 123 for (i = 0; i < h->cfg_space_size; i += 4) 124 pci_read_config_dword(pdev, i, p + i); 125 126 memcpy(gvt->firmware.cfg_space, p, info->cfg_space_size); 127 128 p = firmware + h->mmio_offset; 129 130 hash_for_each(gvt->mmio.mmio_info_table, i, e, node) { 131 int j; 132 133 for (j = 0; j < e->length; j += 4) 134 *(u32 *)(p + e->offset + j) = 135 readl(mmio + e->offset + j); 136 } 137 138 memcpy(gvt->firmware.mmio, p, info->mmio_size); 139 140 firmware_attr.size = size; 141 firmware_attr.private = firmware; 142 143 ret = device_create_bin_file(&pdev->dev, &firmware_attr); 144 if (ret) { 145 vfree(firmware); 146 return ret; 147 } 148 return 0; 149 } 150 151 static void clean_firmware_sysfs(struct intel_gvt *gvt) 152 { 153 struct pci_dev *pdev = gvt->dev_priv->drm.pdev; 154 155 device_remove_bin_file(&pdev->dev, &firmware_attr); 156 vfree(firmware_attr.private); 157 } 158 159 /** 160 * intel_gvt_free_firmware - free GVT firmware 161 * @gvt: intel gvt device 162 * 163 */ 164 void intel_gvt_free_firmware(struct intel_gvt *gvt) 165 { 166 if (!gvt->firmware.firmware_loaded) 167 clean_firmware_sysfs(gvt); 168 169 kfree(gvt->firmware.cfg_space); 170 kfree(gvt->firmware.mmio); 171 } 172 173 static int verify_firmware(struct intel_gvt *gvt, 174 const struct firmware *fw) 175 { 176 struct intel_gvt_device_info *info = &gvt->device_info; 177 struct drm_i915_private *dev_priv = gvt->dev_priv; 178 struct pci_dev *pdev = dev_priv->drm.pdev; 179 struct gvt_firmware_header *h; 180 unsigned long id, crc32_start; 181 const void *mem; 182 const char *item; 183 u64 file, request; 184 185 h = (struct gvt_firmware_header *)fw->data; 186 187 crc32_start = offsetof(struct gvt_firmware_header, crc32) + 4; 188 mem = fw->data + crc32_start; 189 190 #define VERIFY(s, a, b) do { \ 191 item = (s); file = (u64)(a); request = (u64)(b); \ 192 if ((a) != (b)) \ 193 goto invalid_firmware; \ 194 } while (0) 195 196 VERIFY("magic number", h->magic, VGT_MAGIC); 197 VERIFY("version", h->version, FIRMWARE_VERSION); 198 VERIFY("crc32", h->crc32, crc32_le(0, mem, fw->size - crc32_start)); 199 VERIFY("cfg space size", h->cfg_space_size, info->cfg_space_size); 200 VERIFY("mmio size", h->mmio_size, info->mmio_size); 201 202 mem = (fw->data + h->cfg_space_offset); 203 204 id = *(u16 *)(mem + PCI_VENDOR_ID); 205 VERIFY("vender id", id, pdev->vendor); 206 207 id = *(u16 *)(mem + PCI_DEVICE_ID); 208 VERIFY("device id", id, pdev->device); 209 210 id = *(u8 *)(mem + PCI_REVISION_ID); 211 VERIFY("revision id", id, pdev->revision); 212 213 #undef VERIFY 214 return 0; 215 216 invalid_firmware: 217 gvt_dbg_core("Invalid firmware: %s [file] 0x%llx [request] 0x%llx\n", 218 item, file, request); 219 return -EINVAL; 220 } 221 222 #define GVT_FIRMWARE_PATH "i915/gvt" 223 224 /** 225 * intel_gvt_load_firmware - load GVT firmware 226 * @gvt: intel gvt device 227 * 228 */ 229 int intel_gvt_load_firmware(struct intel_gvt *gvt) 230 { 231 struct intel_gvt_device_info *info = &gvt->device_info; 232 struct drm_i915_private *dev_priv = gvt->dev_priv; 233 struct pci_dev *pdev = dev_priv->drm.pdev; 234 struct intel_gvt_firmware *firmware = &gvt->firmware; 235 struct gvt_firmware_header *h; 236 const struct firmware *fw; 237 char *path; 238 void __iomem *mmio; 239 void *mem; 240 int ret; 241 242 path = kmalloc(PATH_MAX, GFP_KERNEL); 243 if (!path) 244 return -ENOMEM; 245 246 mem = kmalloc(info->cfg_space_size, GFP_KERNEL); 247 if (!mem) { 248 kfree(path); 249 return -ENOMEM; 250 } 251 252 firmware->cfg_space = mem; 253 254 mem = kmalloc(info->mmio_size, GFP_KERNEL); 255 if (!mem) { 256 kfree(path); 257 kfree(firmware->cfg_space); 258 return -ENOMEM; 259 } 260 261 firmware->mmio = mem; 262 263 mmio = pci_iomap(pdev, info->mmio_bar, info->mmio_size); 264 if (!mmio) { 265 kfree(path); 266 kfree(firmware->cfg_space); 267 kfree(firmware->mmio); 268 return -EINVAL; 269 } 270 271 if (IS_BROADWELL(gvt->dev_priv) || IS_SKYLAKE(gvt->dev_priv)) 272 bdw_forcewake_get(mmio); 273 274 sprintf(path, "%s/vid_0x%04x_did_0x%04x_rid_0x%04x.golden_hw_state", 275 GVT_FIRMWARE_PATH, pdev->vendor, pdev->device, 276 pdev->revision); 277 278 gvt_dbg_core("request hw state firmware %s...\n", path); 279 280 ret = request_firmware(&fw, path, &dev_priv->drm.pdev->dev); 281 kfree(path); 282 283 if (ret) 284 goto expose_firmware; 285 286 gvt_dbg_core("success.\n"); 287 288 ret = verify_firmware(gvt, fw); 289 if (ret) 290 goto out_free_fw; 291 292 gvt_dbg_core("verified.\n"); 293 294 h = (struct gvt_firmware_header *)fw->data; 295 296 memcpy(firmware->cfg_space, fw->data + h->cfg_space_offset, 297 h->cfg_space_size); 298 memcpy(firmware->mmio, fw->data + h->mmio_offset, 299 h->mmio_size); 300 301 release_firmware(fw); 302 firmware->firmware_loaded = true; 303 pci_iounmap(pdev, mmio); 304 return 0; 305 306 out_free_fw: 307 release_firmware(fw); 308 expose_firmware: 309 expose_firmware_sysfs(gvt, mmio); 310 pci_iounmap(pdev, mmio); 311 return 0; 312 } 313