The Tegra Hypervisor driver exposes a number of APIs both for user-space communication and kernel space drivers. The purpose of the APIs is to facilitate safe and relatively efficient communication between software entities running on different guests of the hypervisor. In kernel IVC API ----------------- The steps required for an in-kernel user are: 1. Call tegra_hv_ivc_reserve() to request an IVC channel and reserve it for your own use: 2. Use the fields of the IVC cookie returned as required. For instance you can allocate buffers and/or install interrupt handled. 3. Use the transfer API to read/write data from the channel, and/or query the state of it. 4. Finally, call tegra_hv_ivc_unreserve() to release the channel. Structures ---------- struct tegra_hv_ivc_cookie: - is the cookie returned from the call to tegra_hv_ivc_reserve() struct tegra_hv_ivc_cookie { int irq; /* interrupt this channel uses (both for rx/tx) */ int peer_vmid; /* guest id of the other end */ int nframes; /* number of frames in the queue */ int frame_size; /* frame size in bytes */ }; struct tegra_hv_ivc_ops - structure pointer to pass to tegra_hv_ivc_reserve(), when you don't want to perform IRQ installation in your driver. struct tegra_hv_ivc_ops { /* called when data are received */ void (*rx_rdy)(struct tegra_hv_ivc_cookie *ivck); /* called when space is available to write data */ void (*tx_rdy)(struct tegra_hv_ivc_cookie *ivck); }; Functions --------- /** * tegra_hv_ivc_reserve - Reserve an IVC queue for use * @dn: Device node pointer to the queue in the DT * If NULL, then operate on first HV device * @queue_id Id number of the queue to use. * @ops Ops structure or NULL * * Reserves the queue for use * * Returns a pointer to the ivc_dev to use or an ERR_PTR. * Note that returning EPROBE_DEFER means that the ivc driver * hasn't loaded yet and you should try again later in the * boot sequence. */ struct tegra_hv_ivc_cookie *tegra_hv_ivc_reserve( struct device_node *dn, int id, const struct tegra_hv_ivc_ops *ops); /** * tegra_hv_ivc_unreserve - Unreserve an IVC queue used * @ivck IVC cookie * * Unreserves the IVC channel * * Returns 0 on success and an error code otherwise */ int tegra_hv_ivc_unreserve(struct tegra_hv_ivc_cookie *ivck); /** * ivc_hv_ivc_write - Writes a frame to the IVC queue * @ivck IVC cookie of the queue * @buf Pointer to the data to write * @size Size of the data to write * * Write a number of bytes (as a single frame) from the queue. * * Returns size on success and an error code otherwise */ int tegra_hv_ivc_write(struct tegra_hv_ivc_cookie *ivck, const void *buf, int size); /** * ivc_hv_ivc_read - Reads a frame from the IVC queue * @ivck IVC cookie of the queue * @buf Pointer to the data to read * @size max size of the data to read * * Reads a number of bytes (as a single frame) from the queue. * * Returns size on success and an error code otherwise */ int tegra_hv_ivc_read(struct tegra_hv_ivc_cookie *ivck, void *buf, int size); /** * ivc_hv_ivc_can_read - Test whether data are available * @ivck IVC cookie of the queue * * Test wheter data to read are available * * Returns 1 if data are available in the rx queue, 0 if not */ int tegra_hv_ivc_can_read(struct tegra_hv_ivc_cookie *ivck); /** * ivc_hv_ivc_can_write - Test whether data can be written * @ivck IVC cookie of the queue * * Test wheter data can be written * * Returns 1 if data are can be written to the tx queue, 0 if not */ int tegra_hv_ivc_can_write(struct tegra_hv_ivc_cookie *ivck); /** * ivc_hv_ivc_tx_empty - Test whether the tx queue is empty * @ivck IVC cookie of the queue * * Test wheter the tx queue is completely empty * * Returns 1 if the queue is empty, zero otherwise */ int tegra_hv_ivc_tx_empty(struct tegra_hv_ivc_cookie *ivck); /** * ivc_hv_ivc_loopback - Sets (or clears) loopback mode * @ivck IVC cookie of the queue * @mode Set loopback on/off (1 = on, 0 = off) * * Sets or clears loopback mode accordingly. * * When loopback is active any writes are ignored, while * reads do not return data. * Incoming data are copied immediately to the tx queue. * * Returns 0 on success, a negative error code otherwise */ int tegra_hv_ivc_set_loopback(struct tegra_hv_ivc_cookie *ivck, int mode); /* perform fast loopback */ int tegra_hv_ivc_perform_loopback(struct tegra_hv_ivc_cookie *ivck); /* debugging aid */ int tegra_hv_ivc_dump(struct tegra_hv_ivc_cookie *ivck); /** * ivc_hv_ivc_read_peek - Peek (copying) data from a received frame * @ivck IVC cookie of the queue * @buf Buffer to receive the data * @off Offset in the frame * @count Count of bytes to copy * * Peek data from a received frame, copying to buf, without removing * the frame from the queue. * * Returns 0 on success, a negative error code otherwise */ int tegra_hv_ivc_read_peek(struct tegra_hv_ivc_cookie *ivck, void *buf, int off, int count); /** * ivc_hv_ivc_read_get_next_frame - Peek at the next frame to receive * @ivck IVC cookie of the queue * * Peek at the next frame to be received, without removing it from * the queue. * * Returns a pointer to the frame, or an error encoded pointer. */ void *tegra_hv_ivc_read_get_next_frame(struct tegra_hv_ivc_cookie *ivck); /** * ivc_hv_ivc_read_advance - Advance the read queue * @ivck IVC cookie of the queue * * Advance the read queue * * Returns 0, or a negative error value if failed. */ int tegra_hv_ivc_read_advance(struct tegra_hv_ivc_cookie *ivck); /** * ivc_hv_ivc_write_poke - Poke data to a frame to be transmitted * @ivck IVC cookie of the queue * @buf Buffer to the data * @off Offset in the frame * @count Count of bytes to copy * * Copy data to a transmit frame, copying from buf, without advancing * the the transmit queue. * * Returns 0 on success, a negative error code otherwise */ int tegra_hv_ivc_write_poke(struct tegra_hv_ivc_cookie *ivck, const void *buf, int off, int count); /** * ivc_hv_ivc_write_get_next_frame - Poke at the next frame to transmit * @ivck IVC cookie of the queue * * Get access to the next frame. * * Returns a pointer to the frame, or an error encoded pointer. */ void *tegra_hv_ivc_write_get_next_frame(struct tegra_hv_ivc_cookie *ivck); /** * ivc_hv_ivc_write_advance - Advance the write queue * @ivck IVC cookie of the queue * * Advance the write queue * * Returns 0, or a negative error value if failed. */ int tegra_hv_ivc_write_advance(struct tegra_hv_ivc_cookie *ivck);