224 lines
6.4 KiB
Plaintext
224 lines
6.4 KiB
Plaintext
|
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);
|
||
|
|