drivers/gpu/drm/xe/xe_gsc_proxy.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/xe/xe_gsc_proxy.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/xe/xe_gsc_proxy.c
Extension
.c
Size
15540 bytes
Lines
560
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

if (ret) {
			xe_gt_err(gt, "Invalid gsc header in proxy reply (%pe)\n",
				  ERR_PTR(ret));
			goto proxy_error;
		}

		/* copy the proxy header reply from GSC */
		xe_map_memcpy_from(xe, to_csme_hdr, &gsc->proxy.from_gsc,
				   reply_offset, PROXY_HDR_SIZE);

		/* Check the status and stop if this was the last message */
		if (FIELD_GET(GSC_PROXY_TYPE, to_csme_hdr->hdr) == GSC_PROXY_MSG_TYPE_PROXY_END) {
			ret = validate_proxy_header(gt, to_csme_hdr,
						    GSC_PROXY_ADDRESSING_GSC,
						    GSC_PROXY_ADDRESSING_KMD,
						    GSC_PROXY_BUFFER_SIZE - reply_offset);
			break;
		}

		/* make sure the GSC-to-CSME proxy header is sane */
		ret = validate_proxy_header(gt, to_csme_hdr,
					    GSC_PROXY_ADDRESSING_GSC,
					    GSC_PROXY_ADDRESSING_CSME,
					    GSC_PROXY_BUFFER_SIZE - reply_offset);
		if (ret) {
			xe_gt_err(gt, "invalid GSC to CSME proxy header! (%pe)\n",
				  ERR_PTR(ret));
			goto proxy_error;
		}

		/* copy the rest of the message */
		size = FIELD_GET(GSC_PROXY_PAYLOAD_LENGTH, to_csme_hdr->hdr);
		xe_map_memcpy_from(xe, to_csme_payload, &gsc->proxy.from_gsc,
				   reply_offset + PROXY_HDR_SIZE, size);

		/* send the GSC message to the CSME */
		ret = proxy_send_to_csme(gsc, size + PROXY_HDR_SIZE);
		if (ret < 0)
			goto proxy_error;

		/* reply size from CSME, including the proxy header */
		size = ret;
		if (size < PROXY_HDR_SIZE) {
			xe_gt_err(gt, "CSME to GSC proxy msg too small: 0x%x\n", size);
			ret = -EPROTO;
			goto proxy_error;
		}

		/* make sure the CSME-to-GSC proxy header is sane */
		ret = validate_proxy_header(gt, gsc->proxy.from_csme,
					    GSC_PROXY_ADDRESSING_CSME,
					    GSC_PROXY_ADDRESSING_GSC,
					    GSC_PROXY_BUFFER_SIZE - reply_offset);
		if (ret) {
			xe_gt_err(gt, "invalid CSME to GSC proxy header! %d\n", ret);
			goto proxy_error;
		}

		/* Emit a new header for sending the reply to the GSC */
		wr_offset = xe_gsc_emit_header(xe, &gsc->proxy.to_gsc, 0,
					       HECI_MEADDRESS_PROXY, 0, size);

		/* copy the CSME reply and update the total msg size to include the GSC header */
		xe_map_memcpy_to(xe, &gsc->proxy.to_gsc, wr_offset, gsc->proxy.from_csme, size);

		size += wr_offset;
	}

proxy_error:
	return ret < 0 ? ret : 0;
}

int xe_gsc_proxy_request_handler(struct xe_gsc *gsc)
{
	struct xe_gt *gt = gsc_to_gt(gsc);
	int slept;
	int err;

	if (!gsc->proxy.component_added)
		return -ENODEV;

	/* when GSC is loaded, we can queue this before the component is bound */
	for (slept = 0; slept < GSC_PROXY_INIT_TIMEOUT_MS; slept += 100) {
		if (gsc->proxy.component)
			break;

		msleep(100);
	}

	mutex_lock(&gsc->proxy.mutex);

Annotation

Implementation Notes