/* * GSC FW allows us to define the host_session_handle as we see fit, as long * as we use unique identifier for each user, with handle 0 being reserved for * kernel usage. * To be able to differentiate which client subsystem owns the given session, we * include the client id in the top 8 bits of the handle.
*/ #define HOST_SESSION_CLIENT_MASK GENMASK_ULL(63, 56)
/** * xe_gsc_create_host_session_id - Creates a random 64 bit host_session id with * bits 56-63 masked. * * Returns: random host_session_id which can be used to send messages to gsc cs
*/
u64 xe_gsc_create_host_session_id(void)
{
u64 host_session_id;
/** * xe_gsc_emit_header - write the MTL GSC header in memory * @xe: the Xe device * @map: the iosys map to write to * @offset: offset from the start of the map at which to write the header * @heci_client_id: client id identifying the type of command (see abi for values) * @host_session_id: host session ID of the caller * @payload_size: size of the payload that follows the header * * Returns: offset memory location following the header
*/
u32 xe_gsc_emit_header(struct xe_device *xe, struct iosys_map *map, u32 offset,
u8 heci_client_id, u64 host_session_id, u32 payload_size)
{
xe_assert(xe, !(host_session_id & HOST_SESSION_CLIENT_MASK));
if (host_session_id)
host_session_id |= FIELD_PREP(HOST_SESSION_CLIENT_MASK, heci_client_id);
/** * xe_gsc_poison_header - poison the MTL GSC header in memory * @xe: the Xe device * @map: the iosys map to write to * @offset: offset from the start of the map at which the header resides
*/ void xe_gsc_poison_header(struct xe_device *xe, struct iosys_map *map, u32 offset)
{
xe_map_memset(xe, map, offset, POISON_FREE, GSC_HDR_SIZE);
};
/** * xe_gsc_check_and_update_pending - check the pending bit and update the input * header with the retry handle from the output header * @xe: the Xe device * @in: the iosys map containing the input buffer * @offset_in: offset within the iosys at which the input buffer is located * @out: the iosys map containing the output buffer * @offset_out: offset within the iosys at which the output buffer is located * * Returns: true if the pending bit was set, false otherwise
*/ bool xe_gsc_check_and_update_pending(struct xe_device *xe, struct iosys_map *in, u32 offset_in, struct iosys_map *out, u32 offset_out)
{ if (mtl_gsc_header_rd(xe, out, offset_out, flags) & GSC_OUTFLAG_MSG_PENDING) {
u64 handle = mtl_gsc_header_rd(xe, out, offset_out, gsc_message_handle);
mtl_gsc_header_wr(xe, in, offset_in, gsc_message_handle, handle);
returntrue;
}
returnfalse;
}
/** * xe_gsc_read_out_header - reads and validates the output header and returns * the offset of the reply following the header * @xe: the Xe device * @map: the iosys map containing the output buffer * @offset: offset within the iosys at which the output buffer is located * @min_payload_size: minimum size of the message excluding the gsc header * @payload_offset: optional pointer to be set to the payload offset * * Returns: -errno value on failure, 0 otherwise
*/ int xe_gsc_read_out_header(struct xe_device *xe, struct iosys_map *map, u32 offset,
u32 min_payload_size,
u32 *payload_offset)
{
u32 marker = mtl_gsc_header_rd(xe, map, offset, validity_marker);
u32 size = mtl_gsc_header_rd(xe, map, offset, message_size);
u32 status = mtl_gsc_header_rd(xe, map, offset, status);
u32 payload_size = size - GSC_HDR_SIZE;
if (marker != GSC_HECI_VALIDITY_MARKER) return -EPROTO;
if (size < GSC_HDR_SIZE || payload_size < min_payload_size) return -ENODATA;
if (payload_offset)
*payload_offset = offset + GSC_HDR_SIZE;
return 0;
}
/** * xe_gsc_pkt_submit_kernel - submit a kernel heci pkt to the GSC * @gsc: the GSC uC * @addr_in: GGTT address of the message to send to the GSC * @size_in: size of the message to send to the GSC * @addr_out: GGTT address for the GSC to write the reply to * @size_out: size of the memory reserved for the reply
*/ int xe_gsc_pkt_submit_kernel(struct xe_gsc *gsc, u64 addr_in, u32 size_in,
u64 addr_out, u32 size_out)
{ struct xe_gt *gt = gsc_to_gt(gsc); struct xe_bb *bb; struct xe_sched_job *job; struct dma_fence *fence; long timeout;
if (size_in < GSC_HDR_SIZE) return -ENODATA;
if (size_out < GSC_HDR_SIZE) return -ENOMEM;
bb = xe_bb_new(gt, 8, false); if (IS_ERR(bb)) return PTR_ERR(bb);
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.