/* the protocol supports up to 32K in each direction */ #define GSC_PROXY_BUFFER_SIZE SZ_32K #define GSC_PROXY_CHANNEL_SIZE (GSC_PROXY_BUFFER_SIZE * 2) #define GSC_PROXY_MAX_MSG_SIZE (GSC_PROXY_BUFFER_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;
}
staticint 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;
/* make sure the marker write is flushed */
wmb();
while (1) { /* clear the GSC response header space */
memset(gsc->proxy.to_csme, 0, sizeof(struct gsc_proxy_msg));
/* send proxy message to GSC */
ret = proxy_send_to_gsc(gsc); if (ret) {
gt_err(gt, "failed to send proxy message to GSC! %d\n", ret); goto proxy_error;
}
/* stop if this was the last message */ if (FIELD_GET(GSC_PROXY_TYPE, to_csme->proxy_header.hdr) ==
GSC_PROXY_MSG_TYPE_PROXY_END) break;
/* make sure the GSC-to-CSME proxy header is sane */
ret = validate_proxy_header(&to_csme->proxy_header,
GSC_PROXY_ADDRESSING_GSC,
GSC_PROXY_ADDRESSING_CSME); if (ret) {
gt_err(gt, "invalid GSC to CSME proxy header! %d\n", ret); goto proxy_error;
}
/* send the GSC message to the CSME */
ret = proxy_send_to_csme(gsc); if (ret < 0) {
gt_err(gt, "failed to send proxy message to CSME! %d\n", ret); goto proxy_error;
}
/* update the GSC message size with the returned value from CSME */
to_gsc->header.message_size = ret + sizeof(struct intel_gsc_mtl_header);
/* make sure the CSME-to-GSC proxy header is sane */
ret = validate_proxy_header(&to_gsc->proxy_header,
GSC_PROXY_ADDRESSING_CSME,
GSC_PROXY_ADDRESSING_GSC); if (ret) {
gt_err(gt, "invalid CSME to GSC proxy header! %d\n", ret); goto proxy_error;
}
}
proxy_error: return ret < 0 ? ret : 0;
}
int intel_gsc_proxy_request_handler(struct intel_gsc_uc *gsc)
{ struct intel_gt *gt = gsc_uc_to_gt(gsc); int err;
if (!gsc->proxy.component_added) return -ENODEV;
assert_rpm_wakelock_held(gt->uncore->rpm);
/* when GSC is loaded, we can queue this before the component is bound */
err = wait_for(gsc->proxy.component, GSC_PROXY_INIT_TIMEOUT_MS); if (err) {
gt_err(gt, "GSC proxy component didn't bind within the expected timeout\n"); return -EIO;
}
mutex_lock(&gsc->proxy.mutex); if (!gsc->proxy.component) {
gt_err(gt, "GSC proxy worker called without the component being bound!\n");
err = -EIO;
} else { /* *writethestatusbittoclearitandallownewproxy *interruptstobegeneratedwhilewehandlethecurrent *request,butbesurenottowritetheresetbit
*/
intel_uncore_rmw(gt->uncore, HECI_H_CSR(MTL_GSC_HECI2_BASE),
HECI_H_CSR_RST, HECI_H_CSR_IS);
err = proxy_query(gsc);
}
mutex_unlock(&gsc->proxy.mutex); return err;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.