/** * struct mchp_ipc_mbox_info - IPC probe message format * * @hw_type: IPC implementation available in the hardware * @num_channels: number of IPC channels available in the hardware * * Used to retrieve information on the IPC implementation * using the SBI_EXT_IPC_PROBE SBI function id.
*/ struct mchp_ipc_mbox_info { enum ipc_hw hw_type;
u8 num_channels;
};
/** * struct mchp_ipc_init - IPC channel init message format * * @max_msg_size: maxmimum message size in bytes of a given channel * * struct used by the SBI_EXT_IPC_CH_INIT SBI function id to get * the max message size in bytes of the initialized channel.
*/ struct mchp_ipc_init {
u16 max_msg_size;
};
/** * struct mchp_ipc_status - IPC status message format * * @status: interrupt status for all channels associated to a cluster * @cluster: specifies the cluster instance that originated an irq * * struct used by the SBI_EXT_IPC_STATUS SBI function id to get * the message present and message clear interrupt status for all the * channels associated to a cluster.
*/ struct mchp_ipc_status {
u32 status;
u8 cluster;
};
/** * struct mchp_ipc_sbi_msg - IPC SBI payload message * * @buf_addr: physical address where the received data should be copied to * @size: maximum size(in bytes) that can be stored in the buffer pointed to by `buf` * @irq_type: mask representing the irq types that triggered an irq * * struct used by the SBI_EXT_IPC_SEND/SBI_EXT_IPC_RECEIVE SBI function * ids to send/receive a message from an associated processor using * the IPC.
*/ struct mchp_ipc_sbi_msg {
u64 buf_addr;
u16 size;
u8 irq_type;
};
struct mchp_ipc_cluster_cfg { void *buf_base;
phys_addr_t buf_base_addr; int irq;
};
/* Find out the hart that originated the irq */
for_each_online_cpu(i) {
hartid = cpuid_to_hartid_map(i); if (irq == ipc->cluster_cfg[hartid].irq) break;
}
ret = mchp_ipc_sbi_send(SBI_EXT_IPC_STATUS, ipc->cluster_cfg[hartid].buf_base_addr); if (ret < 0) {
dev_err_ratelimited(ipc->dev, "could not get IHC irq status ret=%d\n", ret); return IRQ_HANDLED;
}
/* * Iterate over each bit set in the IHC interrupt status register (IRQ_STATUS) to identify * the channel(s) that have a message to be processed/acknowledged. * The bits are organized in alternating format, where each pair of bits represents * the status of the message present and message clear interrupts for each cluster/hart * (from hart 0 to hart 5). Each cluster can have up to 5 fixed channels associated.
*/
for_each_set_bit(i, (unsignedlong *)&status_msg.status, IRQ_STATUS_BITS) { /* Find out the destination hart that triggered the interrupt */
chan_index = i / 2;
/* * The IP has no loopback channels, so we need to decrement the index when * the target hart has a greater index than our own
*/ if (chan_index >= status_msg.cluster)
chan_index--;
/* * Calculate the channel id given the hart and channel index. Channel IDs * are unique across all clusters of an IPC, and iterate contiguously * across all clusters.
*/
chan_id = status_msg.cluster * (NUM_CHANS_PER_CLUSTER + chan_index);
if (i % 2 == 0) {
mchp_ipc_prepare_receive_req(chan);
ret = mchp_ipc_sbi_chan_send(SBI_EXT_IPC_RECEIVE, chan_id,
chan_info->buf_base_rx_addr); if (ret < 0) continue;
/* * The TX base buffer is used to transmit two types of messages: * - struct mchp_ipc_init to initialize the channel * - struct mchp_ipc_sbi_msg to transmit user data/payload * Ensure the TX buffer size is large enough to accommodate either message type.
*/
size_t max_size = max(sizeof(struct mchp_ipc_init), sizeof(struct mchp_ipc_sbi_msg));
chan_info->buf_base_tx = kmalloc(max_size, GFP_KERNEL); if (!chan_info->buf_base_tx) {
ret = -ENOMEM; goto fail;
}
if (ipc->hw_type == MIV_IHC) {
ipc->cluster_cfg = devm_kcalloc(dev, num_online_cpus(), sizeof(struct mchp_ipc_cluster_cfg),
GFP_KERNEL); if (!ipc->cluster_cfg) return -ENOMEM;
if (mchp_ipc_get_cluster_aggr_irq(ipc))
irq_avail = true;
}
if (!irq_avail) return dev_err_probe(dev, -ENODEV, "missing interrupt property\n");
ret = devm_mbox_controller_register(dev, &ipc->controller); if (ret) return dev_err_probe(dev, ret, "Inter-Processor communication (IPC) registration failed\n");
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.