前言
在Qcom 8255平台中,存在不同的i2c设备,根据不同的设备和不同的使用场景,这些设备的控制可以有以下几种方式:
- i2c设备及驱动在qnx侧,由qnx控制和使用
- i2c设备及驱动在android测,由android控制和使用
- i2c设备及驱动在qnx侧,qnx可以控制和使用,同时android侧也可以通过虚拟i2c设备经过hypervisor将控制信息发送到qnx侧,同样可以操控。
在①中的描述,只需要按照qnx侧配置使用即可;②的描述就是所谓的透传(passthrough),将硬件控制权从qnx透传到gvm侧,gvm按照普通的设备使用即可;③就需要使用VirtIO-i2c,gvm侧需要使用virtio设备和驱动,经过virtio最终由qnx侧的驱动来执行相应的控制。
可以参考qnx官网解释:https://www.qnx.com/developers/docs/7.0.0/index.html#com.qnx.doc.hypervisor.user/topic/virt/devs.html
在对上面三点进行详解前,先了解一下passthrough和virtual device:
1.1 Pass-through
在虚拟化系统中,直通设备是指某个虚拟机(guest)可以直接且独占地访问的物理设备。因为它是直接且独占的,这种对物理设备的访问可能比通过虚拟设备访问更快,或者比与其他虚拟机或虚拟化主机共享访问更快。
要使用直通设备,虚拟机必须有自己的物理设备驱动程序。在托管虚拟机的 qvm 进程中不需要虚拟设备(vdev),也不需要在虚拟化管理程序本身中使用驱动程序。
使用直通设备时,虚拟化主机域只需知道它必须将物理设备的中断直接路由到虚拟机,并将虚拟机的信号直接传递给设备。所有交互都在虚拟机和设备之间进行;虚拟化管理程序的唯一职责是识别并允许设备的中断和虚拟机的信号通过。
1.2 Virtual device
准虚拟化设备是一种虚拟设备。它们是在虚拟化管理程序层中运行的软件代码,但这些代码并不模拟任何特定的硬件设备。
相反,准虚拟化设备提供的功能可能在非虚拟化环境中由一个或多个物理设备提供,但不受模拟特定硬件的限制。
典型的准虚拟化设备需要在虚拟机(前端)中运行的代码以及在虚拟机外部(后端)运行的代码;例如,虚拟机中的文件系统设备驱动程序连接到运行在虚拟化主机上的块设备驱动程序。
准虚拟化设备的主要特征包括:
- 使用准虚拟化设备时,虚拟机必须知道它正在运行在虚拟化环境中。例如,要使用 virtio-net,虚拟机必须知道它在虚拟化环境中运行,因为 virtio-net 没有对应的物理设备(它仅以准虚拟化设备的形式存在)。
- 并不存在与准虚拟化设备完全对应的物理设备。
- 虚拟机必须拥有适当的驱动程序和接口以便与准虚拟化设备进行交互。
值得注意的是,在使用virtio虚拟化设备时,是分为前后端的;GVM也就是使用virtio的一侧为前端,通过前端将指令发送到实际操作的后端,也就是qnx,由他去具体执行。
1.3 Qnx I2C配置
1.3.1 QUP资源配置
SD-QNX4.5.6.0/tz/trustzone_images/core/settings/buses/qup_accesscontrol/qupv3/config/lemans/QUPAC_Access.c
不管是qnx还android使用,都需要提前在QUPAC_Access.c
文件中配置好qup资源
const QUPv3_se_security_permissions_type qupv3_perms_default_auto[] =
{
/* PeriphID, ProtocolID, Mode, NsOwner, bAllowFifo, bLoad, bModExcl */
/*QUPV3_0_SE0*/
/*QUPV3_0_SE1*/
/*QUPV3_0_SE2*/
{
QUPV3_0_SE3, QUPV3_PROTOCOL_UART_4W, QUPV3_MODE_FIFO, AC_HLOS, TRUE, TRUE, FALSE }, // BT UART (2nd Hastings)
{
QUPV3_0_SE4, QUPV3_PROTOCOL_UART_2W, QUPV3_MODE_FIFO, AC_HLOS, TRUE, TRUE, FALSE }, // VIP UART/SPI (SOC SLAVE)
/*QUPV3_0_SE5*/ // Spare
{
QUPV3_1_SE0, QUPV3_PROTOCOL_I2C, QUPV3_MODE_FIFO, AC_HLOS, TRUE, TRUE, FALSE }, // I2C Carplay
/*QUPV3_1_SE1*/
{
QUPV3_1_SE2, QUPV3_PROTOCOL_UART_2W, QUPV3_MODE_FIFO, AC_HLOS, TRUE, TRUE, FALSE }, // Tuner
{
QUPV3_1_SE3, QUPV3_PROTOCOL_UART_2W, QUPV3_MODE_FIFO, AC_HLOS, TRUE, FALSE, FALSE }, // Debug UART
{
QUPV3_1_SE4, QUPV3_PROTOCOL_I2C, QUPV3_MODE_FIFO, AC_HLOS, TRUE, TRUE, FALSE }, // I2C A2B Controller & Audio port expander
{
QUPV3_1_SE5, QUPV3_PROTOCOL_UART_2W, QUPV3_MODE_FIFO, AC_HLOS, TRUE, TRUE, FALSE }, // GNSS
/*QUPV3_1_SE6*/
{
QUPV3_2_SE0, QUPV3_PROTOCOL_SPI, QUPV3_MODE_FIFO, AC_HLOS, TRUE, TRUE, FALSE }, // FPGA
{
QUPV3_2_SE1, QUPV3_PROTOCOL_I2C, QUPV3_MODE_FIFO, AC_HLOS, TRUE, TRUE, FALSE }, // PCIe I2C MUX
{
QUPV3_2_SE2, QUPV3_PROTOCOL_SPI, QUPV3_MODE_FIFO, AC_HLOS, TRUE, TRUE, FALSE }, // SPI - Audio
{
QUPV3_2_SE3, QUPV3_PROTOCOL_UART_4W, QUPV3_MODE_FIFO, AC_HLOS, TRUE, TRUE, FALSE }, // BT UART
{
QUPV3_2_SE4, QUPV3_PROTOCOL_I2C, QUPV3_MODE_FIFO, AC_HLOS, TRUE, TRUE, FALSE }