/* data immediately available */ if (core_data->host_read_ptr != core_data->dsp_write_ptr) returntrue;
/* wait for available trace data from FW */
init_waitqueue_entry(&wait, current);
set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&core_data->trace_sleep, &wait);
if (!signal_pending(current)) { /* set timeout to max value, no error code */
schedule_timeout(MAX_SCHEDULE_TIMEOUT);
}
remove_wait_queue(&core_data->trace_sleep, &wait);
if (core_data->host_read_ptr != core_data->dsp_write_ptr) returntrue;
/* check pos and count */ if (lpos < 0) return -EINVAL; if (!count || count < sizeof(avail)) return0;
/* get available count based on current host offset */ if (!sof_wait_mtrace_avail(core_data)) { /* No data available */
avail = 0; if (copy_to_user(buffer, &avail, sizeof(avail))) return -EFAULT;
return0;
}
if (core_data->slot_offset == SOF_IPC4_INVALID_SLOT_OFFSET) return0;
/* The log data buffer starts after the two pointer in the slot */
log_buffer_offset = core_data->slot_offset + (sizeof(u32) * 2); /* The log data size excludes the pointers */
log_buffer_size = SOF_IPC4_DEBUG_SLOT_SIZE - (sizeof(u32) * 2);
if (read_ptr < write_ptr) { /* Read data between read pointer and write pointer */
sof_mailbox_read(sdev, log_buffer_offset + read_ptr, log_buffer, avail);
} else { /* read from read pointer to end of the slot */
sof_mailbox_read(sdev, log_buffer_offset + read_ptr, log_buffer,
avail - write_ptr); /* read from slot start to write pointer */ if (write_ptr)
sof_mailbox_read(sdev, log_buffer_offset,
(u8 *)(log_buffer) + avail - write_ptr,
write_ptr);
}
/* first write the number of bytes we have gathered */
ret = copy_to_user(buffer, &avail, sizeof(avail)); if (ret) return -EFAULT;
/* Followed by the data itself */
ret = copy_to_user(buffer + sizeof(avail), log_buffer, avail); if (ret) return -EFAULT;
/* Update the host_read_ptr in the slot for this core */
read_ptr += avail; if (read_ptr >= log_buffer_size)
read_ptr -= log_buffer_size;
sof_mailbox_write(sdev, core_data->slot_offset, &read_ptr, sizeof(read_ptr));
/* Only update the host_read_ptr if mtrace is enabled */ if (priv->mtrace_state != SOF_MTRACE_DISABLED)
core_data->host_read_ptr = read_ptr;
for (i = 0; i < SOF_IPC4_MAX_DEBUG_SLOTS; i++) { /* The type is the second u32 in the slot descriptor */
slot_desc_type_offset = sdev->debug_box.offset;
slot_desc_type_offset += SOF_IPC4_DEBUG_DESCRIPTOR_SIZE * i + sizeof(u32);
sof_mailbox_read(sdev, slot_desc_type_offset, &type, sizeof(type));
if ((type & SOF_MTRACE_SLOT_TYPE_MASK) == SOF_IPC4_DEBUG_SLOT_DEBUG_LOG) {
core = type & SOF_MTRACE_SLOT_CORE_MASK;
if (core >= sdev->num_cores) {
dev_dbg(sdev->dev, "core%u is invalid for slot%d\n",
core, i); continue;
}
core_data = &priv->cores[core]; /* *Theareareservedfordescriptorshavethesamesize *asaslot. *Inotherwords:slot0startsat *debug_box+SOF_MTRACE_SLOT_SIZEoffset
*/
core_data->slot_offset = sdev->debug_box.offset;
core_data->slot_offset += SOF_IPC4_DEBUG_SLOT_SIZE * (i + 1);
dev_dbg(sdev->dev, "slot%d is used for core%u\n", i, core); if (core_data->delayed_pos_update) {
sof_ipc4_mtrace_update_pos(sdev, core);
core_data->delayed_pos_update = false;
}
} elseif (type) {
dev_dbg(sdev->dev, "slot%d is not a log slot (%#x)\n", i, type);
}
}
}
staticint ipc4_mtrace_init(struct snd_sof_dev *sdev)
{ struct sof_ipc4_fw_data *ipc4_data = sdev->private; struct sof_mtrace_priv *priv; int i, ret;
if (sdev->fw_trace_data) {
dev_err(sdev->dev, "fw_trace_data has been already allocated\n"); return -EBUSY;
}
staticint sof_ipc4_mtrace_update_pos_all_cores(struct snd_sof_dev *sdev)
{ int i;
for (i = 0; i < sdev->num_cores; i++)
sof_ipc4_mtrace_update_pos(sdev, i);
return0;
}
int sof_ipc4_mtrace_update_pos(struct snd_sof_dev *sdev, int core)
{ struct sof_mtrace_priv *priv = sdev->fw_trace_data; struct sof_mtrace_core_data *core_data;
if (!sdev->fw_trace_is_supported ||
priv->mtrace_state == SOF_MTRACE_DISABLED) return0;
if (core >= sdev->num_cores) return -EINVAL;
core_data = &priv->cores[core];
if (core_data->slot_offset == SOF_IPC4_INVALID_SLOT_OFFSET) {
core_data->delayed_pos_update = true; return0;
}
/* Read out the dsp_write_ptr from the slot for this core */
sof_mailbox_read(sdev, core_data->slot_offset + sizeof(u32),
&core_data->dsp_write_ptr, 4);
core_data->dsp_write_ptr -= core_data->dsp_write_ptr % 4;
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.