drivers/gpu/drm/i915/gvt/firmware.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/i915/gvt/firmware.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/gvt/firmware.c
Extension
.c
Size
6704 bytes
Lines
254
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct gvt_firmware_header {
	u64 magic;
	u32 crc32;		/* protect the data after this field */
	u32 version;
	u64 cfg_space_size;
	u64 cfg_space_offset;	/* offset in the file */
	u64 mmio_size;
	u64 mmio_offset;	/* offset in the file */
	unsigned char data[];
};

#define dev_to_drm_minor(d) dev_get_drvdata((d))

static BIN_ATTR_SIMPLE_ADMIN_RO(gvt_firmware);

static int expose_firmware_sysfs(struct intel_gvt *gvt)
{
	struct intel_gvt_device_info *info = &gvt->device_info;
	struct drm_i915_private *i915 = gvt->gt->i915;
	struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
	struct gvt_firmware_header *h;
	void *firmware;
	void *p;
	unsigned long size, crc32_start;
	int ret;

	size = offsetof(struct gvt_firmware_header, data) + info->mmio_size + info->cfg_space_size;
	firmware = vzalloc(size);
	if (!firmware)
		return -ENOMEM;

	h = firmware;

	h->magic = VGT_MAGIC;
	h->version = FIRMWARE_VERSION;
	h->cfg_space_size = info->cfg_space_size;
	h->cfg_space_offset = offsetof(struct gvt_firmware_header, data);
	h->mmio_size = info->mmio_size;
	h->mmio_offset = h->cfg_space_offset + h->cfg_space_size;

	p = firmware + h->cfg_space_offset;

	memcpy(gvt->firmware.cfg_space, i915->vgpu.initial_cfg_space,
	       info->cfg_space_size);
	memcpy(p, gvt->firmware.cfg_space, info->cfg_space_size);

	p = firmware + h->mmio_offset;

	memcpy(gvt->firmware.mmio, i915->vgpu.initial_mmio,
	       info->mmio_size);

	memcpy(p, gvt->firmware.mmio, info->mmio_size);

	crc32_start = offsetof(struct gvt_firmware_header, version);
	h->crc32 = crc32_le(0, firmware + crc32_start, size - crc32_start);

	bin_attr_gvt_firmware.size = size;
	bin_attr_gvt_firmware.private = firmware;

	ret = device_create_bin_file(&pdev->dev, &bin_attr_gvt_firmware);
	if (ret) {
		vfree(firmware);
		return ret;
	}
	return 0;
}

static void clean_firmware_sysfs(struct intel_gvt *gvt)
{
	struct pci_dev *pdev = to_pci_dev(gvt->gt->i915->drm.dev);

	device_remove_bin_file(&pdev->dev, &bin_attr_gvt_firmware);
	vfree(bin_attr_gvt_firmware.private);
}

/**
 * intel_gvt_free_firmware - free GVT firmware
 * @gvt: intel gvt device
 *
 */
void intel_gvt_free_firmware(struct intel_gvt *gvt)
{
	if (!gvt->firmware.firmware_loaded)
		clean_firmware_sysfs(gvt);

	kfree(gvt->firmware.cfg_space);
	vfree(gvt->firmware.mmio);
}

static int verify_firmware(struct intel_gvt *gvt,

Annotation

Implementation Notes