drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c
Extension
.c
Size
11875 bytes
Lines
430
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 intel_gsc_proxy_header {
	/*
	 * hdr:
	 * Bits 0-7: type of the proxy message (see enum intel_gsc_proxy_type)
	 * Bits 8-15: rsvd
	 * Bits 16-31: length in bytes of the payload following the proxy header
	 */
	u32 hdr;
#define GSC_PROXY_TYPE		 GENMASK(7, 0)
#define GSC_PROXY_PAYLOAD_LENGTH GENMASK(31, 16)

	u32 source;		/* Source of the Proxy message */
	u32 destination;	/* Destination of the Proxy message */
#define GSC_PROXY_ADDRESSING_KMD  0x10000
#define GSC_PROXY_ADDRESSING_GSC  0x20000
#define GSC_PROXY_ADDRESSING_CSME 0x30000

	u32 status;		/* Command status */
} __packed;

/* FW-defined proxy types */
enum intel_gsc_proxy_type {
	GSC_PROXY_MSG_TYPE_PROXY_INVALID = 0,
	GSC_PROXY_MSG_TYPE_PROXY_QUERY = 1,
	GSC_PROXY_MSG_TYPE_PROXY_PAYLOAD = 2,
	GSC_PROXY_MSG_TYPE_PROXY_END = 3,
	GSC_PROXY_MSG_TYPE_PROXY_NOTIFICATION = 4,
};

struct gsc_proxy_msg {
	struct intel_gsc_mtl_header header;
	struct intel_gsc_proxy_header proxy_header;
} __packed;

static int proxy_send_to_csme(struct intel_gsc_uc *gsc)
{
	struct intel_gt *gt = gsc_uc_to_gt(gsc);
	struct i915_gsc_proxy_component *comp = gsc->proxy.component;
	struct intel_gsc_mtl_header *hdr;
	void *in = gsc->proxy.to_csme;
	void *out = gsc->proxy.to_gsc;
	u32 in_size;
	int ret;

	/* CSME msg only includes the proxy */
	hdr = in;
	in += sizeof(struct intel_gsc_mtl_header);
	out += sizeof(struct intel_gsc_mtl_header);

	in_size = hdr->message_size - sizeof(struct intel_gsc_mtl_header);

	/* the message must contain at least the proxy header */
	if (in_size < sizeof(struct intel_gsc_proxy_header) ||
	    in_size > GSC_PROXY_MAX_MSG_SIZE) {
		gt_err(gt, "Invalid CSME message size: %u\n", in_size);
		return -EINVAL;
	}

	ret = comp->ops->send(comp->mei_dev, in, in_size);
	if (ret < 0) {
		gt_err(gt, "Failed to send CSME message\n");
		return ret;
	}

	ret = comp->ops->recv(comp->mei_dev, out, GSC_PROXY_MAX_MSG_SIZE);
	if (ret < 0) {
		gt_err(gt, "Failed to receive CSME message\n");
		return ret;
	}

	return ret;
}

static int proxy_send_to_gsc(struct intel_gsc_uc *gsc)
{
	struct intel_gt *gt = gsc_uc_to_gt(gsc);
	u32 *marker = gsc->proxy.to_csme; /* first dw of the reply header */
	u64 addr_in = i915_ggtt_offset(gsc->proxy.vma);
	u64 addr_out = addr_in + GSC_PROXY_BUFFER_SIZE;
	u32 size = ((struct gsc_proxy_msg *)gsc->proxy.to_gsc)->header.message_size;
	int err;

	/* the message must contain at least the gsc and proxy headers */
	if (size < sizeof(struct gsc_proxy_msg) || size > GSC_PROXY_BUFFER_SIZE) {
		gt_err(gt, "Invalid GSC proxy message size: %u\n", size);
		return -EINVAL;
	}

	/* clear the message marker */
	*marker = 0;

Annotation

Implementation Notes