VirtualBox

Changeset 90512 in vbox


Ignore:
Timestamp:
Aug 4, 2021 10:59:07 AM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
146116
Message:

Devices/Security/DevTpm: Updates to the TPM code, started implmenting the CRB interface first as it looks saner, bugref:10075

Location:
trunk
Files:
1 added
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Security/DevTpm.cpp

    r90492 r90512  
    2525#define LOG_GROUP LOG_GROUP_DEFAULT /** @todo DEV_TPM */
    2626#include <VBox/vmm/pdmdev.h>
     27#include <VBox/vmm/pdmtpmifs.h>
    2728#include <iprt/assert.h>
    2829#include <iprt/string.h>
     30#include <iprt/uuid.h>
    2931
    3032#include "VBoxDD.h"
     
    5557#define TPM_LOCALITY_MMIO_SIZE                          0x1000
    5658
    57 /** @name TPM locality register related defines.
     59/** @name TPM locality register related defines for the FIFO interface.
    5860 * @{ */
    5961/** Ownership management for a particular locality. */
    60 #define TPM_LOCALITY_REG_ACCESS                         0x00
    61 /** INdicates whether a dynamic OS has been established on this platform before.. */
    62 # define TPM_LOCALITY_REG_ESTABLISHMENT                 RT_BIT(0)
     62#define TPM_FIFO_LOCALITY_REG_ACCESS                         0x00
     63/** Indicates whether a dynamic OS has been established on this platform before.. */
     64# define TPM_FIFO_LOCALITY_REG_ESTABLISHMENT                 RT_BIT(0)
    6365/** On reads indicates whether the locality requests use of the TPM (1) or not or is already active locality (0),
    6466 * writing a 1 requests the locality to be granted getting the active locality.. */
    65 # define TPM_LOCALITY_REG_REQUEST_USE                   RT_BIT(1)
     67# define TPM_FIFO_LOCALITY_REG_REQUEST_USE                   RT_BIT(1)
    6668/** Indicates whether another locality is requesting usage of the TPM. */
    67 # define TPM_LOCALITY_REG_PENDING_REQUEST               RT_BIT(2)
     69# define TPM_FIFO_LOCALITY_REG_PENDING_REQUEST               RT_BIT(2)
    6870/** Writing a 1 forces the TPM to give control to the locality if it has a higher priority. */
    69 # define TPM_LOCALITY_REG_ACCESS_SEIZE                  RT_BIT(3)
     71# define TPM_FIFO_LOCALITY_REG_ACCESS_SEIZE                  RT_BIT(3)
    7072/** On reads indicates whether this locality has been seized by a higher locality (1) or not (0), writing a 1 clears this bit. */
    71 # define TPM_LOCALITY_REG_ACCESS_BEEN_SEIZED            RT_BIT(4)
     73# define TPM_FIFO_LOCALITY_REG_ACCESS_BEEN_SEIZED            RT_BIT(4)
    7274/** On reads indicates whether this locality is active (1) or not (0), writing a 1 relinquishes control for this locality. */
    73 # define TPM_LOCALITY_REG_ACCESS_ACTIVE                 RT_BIT(5)
     75# define TPM_FIFO_LOCALITY_REG_ACCESS_ACTIVE                 RT_BIT(5)
    7476/** Set bit indicates whether all other bits in this register have valid data. */
    75 # define TPM_LOCALITY_REG_ACCESS_VALID                  RT_BIT(7)
     77# define TPM_FIFO_LOCALITY_REG_ACCESS_VALID                  RT_BIT(7)
    7678/** Writable mask. */
    77 # define TPM_LOCALITY_REG_ACCESS_WR_MASK                0x3a
     79# define TPM_FIFO_LOCALITY_REG_ACCESS_WR_MASK                0x3a
    7880
    7981/** Interrupt enable register. */
    80 #define TPM_LOCALITY_REG_INT_ENABLE                     0x08
     82#define TPM_FIFO_LOCALITY_REG_INT_ENABLE                     0x08
    8183/** Data available interrupt enable bit. */
    82 # define TPM_LOCALITY_REG_INT_ENABLE_DATA_AVAIL         RT_BIT_32(0)
     84# define TPM_FIFO_LOCALITY_REG_INT_ENABLE_DATA_AVAIL         RT_BIT_32(0)
    8385/** Status valid interrupt enable bit. */
    84 # define TPM_LOCALITY_REG_INT_ENABLE_STS_VALID          RT_BIT_32(1)
     86# define TPM_FIFO_LOCALITY_REG_INT_ENABLE_STS_VALID          RT_BIT_32(1)
    8587/** Locality change interrupt enable bit. */
    86 # define TPM_LOCALITY_REG_INT_ENABLE_LOCALITY_CHANGE    RT_BIT_32(2)
     88# define TPM_FIFO_LOCALITY_REG_INT_ENABLE_LOCALITY_CHANGE    RT_BIT_32(2)
    8789/** Interrupt polarity configuration. */
    88 # define TPM_LOCALITY_REG_INT_ENABLE_POLARITY_MASK      0x18
    89 # define TPM_LOCALITY_REG_INT_ENABLE_POLARITY_SHIFT     3
    90 # define TPM_LOCALITY_REG_INT_ENABLE_POLARITY_SET(a)    ((a) << TPM_LOCALITY_REG_INT_POLARITY_SHIFT)
    91 # define TPM_LOCALITY_REG_INT_ENABLE_POLARITY_GET(a)    (((a) & TPM_LOCALITY_REG_INT_POLARITY_MASK) >> TPM_LOCALITY_REG_INT_POLARITY_SHIFT)
     90# define TPM_FIFO_LOCALITY_REG_INT_ENABLE_POLARITY_MASK      0x18
     91# define TPM_FIFO_LOCALITY_REG_INT_ENABLE_POLARITY_SHIFT     3
     92# define TPM_FIFO_LOCALITY_REG_INT_ENABLE_POLARITY_SET(a)    ((a) << TPM_FIFO_LOCALITY_REG_INT_POLARITY_SHIFT)
     93# define TPM_FIFO_LOCALITY_REG_INT_ENABLE_POLARITY_GET(a)    (((a) & TPM_FIFO_LOCALITY_REG_INT_POLARITY_MASK) >> TPM_FIFO_LOCALITY_REG_INT_POLARITY_SHIFT)
    9294/** High level interrupt trigger. */
    93 #  define TPM_LOCALITY_REG_INT_ENABLE_POLARITY_HIGH     0
     95#  define TPM_FIFO_LOCALITY_REG_INT_ENABLE_POLARITY_HIGH     0
    9496/** Low level interrupt trigger. */
    95 #  define TPM_LOCALITY_REG_INT_ENABLE_POLARITY_LOW      1
     97#  define TPM_FIFO_LOCALITY_REG_INT_ENABLE_POLARITY_LOW      1
    9698/** Rising edge interrupt trigger. */
    97 #  define TPM_LOCALITY_REG_INT_ENABLE_POLARITY_RISING   2
     99#  define TPM_FIFO_LOCALITY_REG_INT_ENABLE_POLARITY_RISING   2
    98100/** Falling edge interrupt trigger. */
    99 #  define TPM_LOCALITY_REG_INT_ENABLE_POLARITY_FALLING  3
     101#  define TPM_FIFO_LOCALITY_REG_INT_ENABLE_POLARITY_FALLING  3
    100102/** Command ready enable bit. */
    101 # define TPM_LOCALITY_REG_INT_ENABLE_CMD_RDY            RT_BIT_32(7)
     103# define TPM_FIFO_LOCALITY_REG_INT_ENABLE_CMD_RDY            RT_BIT_32(7)
    102104/** Global interrupt enable/disable bit. */
    103 # define TPM_LOCALITY_REG_INT_ENABLE_GLOBAL             RT_BIT_32(31)
     105# define TPM_FIFO_LOCALITY_REG_INT_ENABLE_GLOBAL             RT_BIT_32(31)
    104106
    105107/** Configured interrupt vector register. */
    106 #define TPM_LOCALITY_REG_INT_VEC                        0x0c
     108#define TPM_FIFO_LOCALITY_REG_INT_VEC                        0x0c
    107109
    108110/** Interrupt status register. */
    109 #define TPM_LOCALITY_REG_INT_STS                        0x10
     111#define TPM_FIFO_LOCALITY_REG_INT_STS                        0x10
    110112/** Data available interrupt occured bit, writing a 1 clears the bit. */
    111 # define TPM_LOCALITY_REG_INT_STS_DATA_AVAIL            RT_BIT_32(0)
     113# define TPM_FIFO_LOCALITY_REG_INT_STS_DATA_AVAIL            RT_BIT_32(0)
    112114/** Status valid interrupt occured bit, writing a 1 clears the bit. */
    113 # define TPM_LOCALITY_REG_INT_STS_STS_VALID             RT_BIT_32(1)
     115# define TPM_FIFO_LOCALITY_REG_INT_STS_STS_VALID             RT_BIT_32(1)
    114116/** Locality change interrupt occured bit, writing a 1 clears the bit. */
    115 # define TPM_LOCALITY_REG_INT_STS_LOCALITY_CHANGE       RT_BIT_32(2)
     117# define TPM_FIFO_LOCALITY_REG_INT_STS_LOCALITY_CHANGE       RT_BIT_32(2)
    116118/** Command ready occured bit, writing a 1 clears the bit. */
    117 # define TPM_LOCALITY_REG_INT_STS_CMD_RDY               RT_BIT_32(7)
     119# define TPM_FIFO_LOCALITY_REG_INT_STS_CMD_RDY               RT_BIT_32(7)
    118120/** Writable mask. */
    119 # define TPM_LOCALITY_REG_INT_STS_WR_MASK               UINT32_C(0x87)
     121# define TPM_FIFO_LOCALITY_REG_INT_STS_WR_MASK               UINT32_C(0x87)
    120122
    121123/** Interfacce capabilities register. */
    122 #define TPM_LOCALITY_REG_IF_CAP                         0x14
     124#define TPM_FIFO_LOCALITY_REG_IF_CAP                         0x14
    123125/** Flag whether the TPM supports the data avilable interrupt. */
    124 # define TPM_LOCALITY_REG_IF_CAP_INT_DATA_AVAIL         RT_BIT(0)
     126# define TPM_FIFO_LOCALITY_REG_IF_CAP_INT_DATA_AVAIL         RT_BIT(0)
    125127/** Flag whether the TPM supports the status valid interrupt. */
    126 # define TPM_LOCALITY_REG_IF_CAP_INT_STS_VALID          RT_BIT(1)
     128# define TPM_FIFO_LOCALITY_REG_IF_CAP_INT_STS_VALID          RT_BIT(1)
    127129/** Flag whether the TPM supports the data avilable interrupt. */
    128 # define TPM_LOCALITY_REG_IF_CAP_INT_LOCALITY_CHANGE    RT_BIT(2)
     130# define TPM_FIFO_LOCALITY_REG_IF_CAP_INT_LOCALITY_CHANGE    RT_BIT(2)
    129131/** Flag whether the TPM supports high level interrupts. */
    130 # define TPM_LOCALITY_REG_IF_CAP_INT_LVL_HIGH           RT_BIT(3)
     132# define TPM_FIFO_LOCALITY_REG_IF_CAP_INT_LVL_HIGH           RT_BIT(3)
    131133/** Flag whether the TPM supports low level interrupts. */
    132 # define TPM_LOCALITY_REG_IF_CAP_INT_LVL_LOW            RT_BIT(4)
     134# define TPM_FIFO_LOCALITY_REG_IF_CAP_INT_LVL_LOW            RT_BIT(4)
    133135/** Flag whether the TPM supports rising edge interrupts. */
    134 # define TPM_LOCALITY_REG_IF_CAP_INT_RISING_EDGE        RT_BIT(5)
     136# define TPM_FIFO_LOCALITY_REG_IF_CAP_INT_RISING_EDGE        RT_BIT(5)
    135137/** Flag whether the TPM supports falling edge interrupts. */
    136 # define TPM_LOCALITY_REG_IF_CAP_INT_FALLING_EDGE       RT_BIT(6)
     138# define TPM_FIFO_LOCALITY_REG_IF_CAP_INT_FALLING_EDGE       RT_BIT(6)
    137139/** Flag whether the TPM supports the command ready interrupt. */
    138 # define TPM_LOCALITY_REG_IF_CAP_INT_CMD_RDY            RT_BIT(7)
     140# define TPM_FIFO_LOCALITY_REG_IF_CAP_INT_CMD_RDY            RT_BIT(7)
    139141/** Flag whether the busrt count field is static or dynamic. */
    140 # define TPM_LOCALITY_REG_IF_CAP_BURST_CNT_STATIC       RT_BIT(8)
     142# define TPM_FIFO_LOCALITY_REG_IF_CAP_BURST_CNT_STATIC       RT_BIT(8)
    141143/** Maximum transfer size support. */
    142 # define TPM_LOCALITY_REG_IF_CAP_DATA_XFER_SZ_MASK      0x600
    143 # define TPM_LOCALITY_REG_IF_CAP_DATA_XFER_SZ_SHIFT     9
    144 # define TPM_LOCALITY_REG_IF_CAP_DATA_XFER_SZ_SET(a)    ((a) << TPM_LOCALITY_REG_IF_CAP_DATA_XFER_SZ_SHIFT)
     144# define TPM_FIFO_LOCALITY_REG_IF_CAP_DATA_XFER_SZ_MASK      0x600
     145# define TPM_FIFO_LOCALITY_REG_IF_CAP_DATA_XFER_SZ_SHIFT     9
     146# define TPM_FIFO_LOCALITY_REG_IF_CAP_DATA_XFER_SZ_SET(a)    ((a) << TPM_FIFO_LOCALITY_REG_IF_CAP_DATA_XFER_SZ_SHIFT)
    145147/** Only legacy transfers supported. */
    146 #  define TPM_LOCALITY_REG_IF_CAP_DATA_XFER_SZ_LEGACY   0x0
     148#  define TPM_FIFO_LOCALITY_REG_IF_CAP_DATA_XFER_SZ_LEGACY   0x0
    147149/** 8B maximum transfer size. */
    148 #  define TPM_LOCALITY_REG_IF_CAP_DATA_XFER_SZ_8B       0x1
     150#  define TPM_FIFO_LOCALITY_REG_IF_CAP_DATA_XFER_SZ_8B       0x1
    149151/** 32B maximum transfer size. */
    150 #  define TPM_LOCALITY_REG_IF_CAP_DATA_XFER_SZ_32B      0x2
     152#  define TPM_FIFO_LOCALITY_REG_IF_CAP_DATA_XFER_SZ_32B      0x2
    151153/** 64B maximum transfer size. */
    152 #  define TPM_LOCALITY_REG_IF_CAP_DATA_XFER_SZ_64B      0x3
     154#  define TPM_FIFO_LOCALITY_REG_IF_CAP_DATA_XFER_SZ_64B      0x3
    153155/** Interface version. */
    154 # define TPM_LOCALITY_REG_IF_CAP_IF_VERSION_MASK        UINT32_C(0x70000000)
    155 # define TPM_LOCALITY_REG_IF_CAP_IF_VERSION_SHIFT       28
    156 # define TPM_LOCALITY_REG_IF_CAP_IF_VERSION_SET(a)      ((a) << TPM_LOCALITY_REG_IF_CAP_IF_VERSION_SHIFT)
     156# define TPM_FIFO_LOCALITY_REG_IF_CAP_IF_VERSION_MASK        UINT32_C(0x70000000)
     157# define TPM_FIFO_LOCALITY_REG_IF_CAP_IF_VERSION_SHIFT       28
     158# define TPM_FIFO_LOCALITY_REG_IF_CAP_IF_VERSION_SET(a)      ((a) << TPM_FIFO_LOCALITY_REG_IF_CAP_IF_VERSION_SHIFT)
    157159/** Interface 1.21 or ealier. */
    158 #  define TPM_LOCALITY_REG_IF_CAP_IF_VERSION_IF_1_21    0
     160#  define TPM_FIFO_LOCALITY_REG_IF_CAP_IF_VERSION_IF_1_21    0
    159161/** Interface 1.3. */
    160 #  define TPM_LOCALITY_REG_IF_CAP_IF_VERSION_IF_1_3     2
     162#  define TPM_FIFO_LOCALITY_REG_IF_CAP_IF_VERSION_IF_1_3     2
    161163/** Interface 1.3 for TPM 2.0. */
    162 #  define TPM_LOCALITY_REG_IF_CAP_IF_VERSION_IF_1_3_TPM2    3
     164#  define TPM_FIFO_LOCALITY_REG_IF_CAP_IF_VERSION_IF_1_3_TPM2    3
    163165
    164166/** TPM status register. */
    165 #define TPM_LOCALITY_REG_STS                            0x18
     167#define TPM_FIFO_LOCALITY_REG_STS                            0x18
    166168/** Writing a 1 forces the TPM to re-send the response. */
    167 # define TPM_LOCALITY_REG_STS_RESPONSE_RETRY            RT_BIT_32(1)
     169# define TPM_FIFO_LOCALITY_REG_STS_RESPONSE_RETRY            RT_BIT_32(1)
    168170/** Indicating whether the TPM has finished a self test. */
    169 # define TPM_LOCALITY_REG_STS_SELF_TEST_DONE            RT_BIT_32(2)
     171# define TPM_FIFO_LOCALITY_REG_STS_SELF_TEST_DONE            RT_BIT_32(2)
    170172/** Flag indicating whether the TPM expects more data for the command. */
    171 # define TPM_LOCALITY_REG_STS_EXPECT                    RT_BIT_32(3)
     173# define TPM_FIFO_LOCALITY_REG_STS_EXPECT                    RT_BIT_32(3)
    172174/** Flag indicating whether the TPM has more response data available. */
    173 # define TPM_LOCALITY_REG_STS_DATA_AVAIL                RT_BIT_32(4)
     175# define TPM_FIFO_LOCALITY_REG_STS_DATA_AVAIL                RT_BIT_32(4)
    174176/** Written by software to cause the TPM to execute a previously transfered command. */
    175 # define TPM_LOCALITY_REG_STS_TPM_GO                    RT_BIT_32(5)
     177# define TPM_FIFO_LOCALITY_REG_STS_TPM_GO                    RT_BIT_32(5)
    176178/** On reads indicates whether the TPM is ready to receive a new command (1) or not (0),
    177179 * a write of 1 causes the TPM to transition to this state. */
    178 # define TPM_LOCALITY_REG_STS_CMD_RDY                   RT_BIT_32(6)
     180# define TPM_FIFO_LOCALITY_REG_STS_CMD_RDY                   RT_BIT_32(6)
    179181/** Indicates whether the Expect and data available bits are valid. */
    180 # define TPM_LOCALITY_REG_STS_VALID                     RT_BIT_32(7)
    181 # define TPM_LOCALITY_REG_STS_BURST_CNT_MASK            UINT32_C(0xffff00)
    182 # define TPM_LOCALITY_REG_STS_BURST_CNT_SHIFT           8
    183 # define TPM_LOCALITY_REG_STS_BURST_CNT_SET(a)          ((a) << TPM_LOCALITY_REG_STS_BURST_CNT_SHIFT)
     182# define TPM_FIFO_LOCALITY_REG_STS_VALID                     RT_BIT_32(7)
     183# define TPM_FIFO_LOCALITY_REG_STS_BURST_CNT_MASK            UINT32_C(0xffff00)
     184# define TPM_FIFO_LOCALITY_REG_STS_BURST_CNT_SHIFT           8
     185# define TPM_FIFO_LOCALITY_REG_STS_BURST_CNT_SET(a)          ((a) << TPM_FIFO_LOCALITY_REG_STS_BURST_CNT_SHIFT)
    184186
    185187/** TPM end of HASH operation signal register for locality 4. */
    186 #define TPM_LOCALITY_REG_HASH_END                       0x20
     188#define TPM_FIFO_LOCALITY_REG_HASH_END                       0x20
    187189/** Data FIFO read/write register. */
    188 #define TPM_LOCALITY_REG_DATA_FIFO                      0x24
     190#define TPM_FIFO_LOCALITY_REG_DATA_FIFO                      0x24
    189191/** TPM start of HASH operation signal register for locality 4. */
    190 #define TPM_LOCALITY_REG_HASH_START                     0x28
     192#define TPM_FIFO_LOCALITY_REG_HASH_START                     0x28
    191193/** Extended data FIFO read/write register. */
    192 #define TPM_LOCALITY_REG_XDATA_FIFO                     0x80
     194#define TPM_FIFO_LOCALITY_REG_XDATA_FIFO                     0x80
    193195/** TPM device and vendor ID. */
    194 #define TPM_LOCALITY_REG_DID_VID                        0xf00
     196#define TPM_FIFO_LOCALITY_REG_DID_VID                        0xf00
    195197/** TPM revision ID. */
    196 #define TPM_LOCALITY_REG_RID                            0xf04
     198#define TPM_FIFO_LOCALITY_REG_RID                            0xf04
     199/** @} */
     200
     201
     202/** @name TPM locality register related defines for the CRB interface.
     203 * @{ */
     204/** Locality state register. */
     205#define TPM_CRB_LOCALITY_REG_STATE                           0x00
     206/** Indicates whether a dynamic OS has been established on this platform before.. */
     207# define TPM_CRB_LOCALITY_REG_ESTABLISHMENT                  RT_BIT(0)
     208/** Flag whether the host has a locality assigned (1) or not (0). */
     209# define TPM_CRB_LOCALITY_REG_STATE_LOC_ASSIGNED             RT_BIT(1)
     210/** Indicates the currently active locality. */
     211# define TPM_CRB_LOCALITY_REG_STATE_ACTIVE_LOC_MASK          UINT32_C(0x1c)
     212# define TPM_CRB_LOCALITY_REG_STATE_ACTIVE_LOC_SHIFT         2
     213# define TPM_CRB_LOCALITY_REG_STATE_ACTIVE_LOC_SET(a)        ((a) << TPM_CRB_LOCALITY_REG_STATE_ACTIVE_LOC_SHIFT)
     214/** Flag whether the register contains valid values. */
     215# define TPM_CRB_LOCALITY_REG_STATE_VALID                    RT_BIT(7)
     216
     217/** Locality control register. */
     218#define TPM_CRB_LOCALITY_REG_CTRL                            0x08
     219/** Request TPM access from this locality. */
     220# define TPM_CRB_LOCALITY_REG_CTRL_REQ_ACCESS                RT_BIT(0)
     221/** Release TPM access from this locality. */
     222# define TPM_CRB_LOCALITY_REG_CTRL_RELINQUISH                RT_BIT(1)
     223/** Seize TPM access in favor of this locality if it has a higher priority. */
     224# define TPM_CRB_LOCALITY_REG_CTRL_SEIZE                     RT_BIT(2)
     225/** Resets the established bit if written from locality 3 or 4. */
     226# define TPM_CRB_LOCALITY_REG_CTRL_RST_ESTABLISHMENT         RT_BIT(3)
     227
     228/** Locality status register. */
     229#define TPM_CRB_LOCALITY_REG_STS                             0x0c
     230/** Locality has been granted access to the TPM. */
     231# define TPM_CRB_LOCALITY_REG_STS_GRANTED                    RT_BIT(0)
     232/** A higher locality has seized the TPM from this locality. */
     233# define TPM_CRB_LOCALITY_REG_STS_SEIZED                     RT_BIT(1)
     234
     235/** Locality interface ID register. */
     236#define TPM_CRB_LOCALITY_REG_INTF_ID                         0x30
     237/** Interface type field. */
     238# define TPM_CRB_LOCALITY_REG_INTF_ID_IF_TYPE_MASK           UINT32_C(0xf)
     239# define TPM_CRB_LOCALITY_REG_INTF_ID_IF_TYPE_SHIFT          0
     240# define TPM_CRB_LOCALITY_REG_INTF_ID_IF_TYPE_SET(a)         ((a) << TPM_CRB_LOCALITY_REG_INTF_ID_IF_TYPE_SHIFT)
     241/** FIFO interface as defined in PTP for TPM 2.0 is active. */
     242#  define TPM_CRB_LOCALITY_REG_INTF_ID_IF_TYPE_FIFO_TPM20    0x0
     243/** CRB interface is active. */
     244#  define TPM_CRB_LOCALITY_REG_INTF_ID_IF_TYPE_CRB           0x1
     245/** FIFO interface as defined in TIS 1.3 is active. */
     246#  define TPM_CRB_LOCALITY_REG_INTF_ID_IF_TYPE_TIS1_3        0xf
     247/** Interface type field. */
     248# define TPM_CRB_LOCALITY_REG_INTF_ID_IF_VERS_MASK           UINT32_C(0xf)
     249# define TPM_CRB_LOCALITY_REG_INTF_ID_IF_VERS_SHIFT          4
     250# define TPM_CRB_LOCALITY_REG_INTF_ID_IF_VERS_SET(a)         ((a) << TPM_CRB_LOCALITY_REG_INTF_ID_IF_VERS_SHIFT)
     251/** FIFO interface for TPM 2.0 */
     252#  define TPM_CRB_LOCALITY_REG_INTF_ID_IF_VERS_FIFO          0
     253/** CRB interface version 0. */
     254#  define TPM_CRB_LOCALITY_REG_INTF_ID_IF_VERS_CRB           1
     255/** Only locality 0 is supported when clear, set if 5 localities are supported. */
     256# define TPM_CRB_LOCALITY_REG_INTF_ID_CAP_LOCALITY           RT_BIT(8)
     257/** @todo TPM supports ... */
     258# define TPM_CRB_LOCALITY_REG_INTF_ID_CAP_CRB_IDLE_BYPASS    RT_BIT(9)
     259/** Maximum transfer size support. */
     260# define TPM_CRB_LOCALITY_REG_INTF_ID_CAP_DATA_XFER_SZ_MASK   0x1800
     261# define TPM_CRB_LOCALITY_REG_INTF_ID_CAP_DATA_XFER_SZ_SHIFT  11
     262# define TPM_CRB_LOCALITY_REG_INTF_ID_CAP_DATA_XFER_SZ_SET(a) ((a) << TPM_FIFO_LOCALITY_REG_IF_CAP_DATA_XFER_SZ_SHIFT)
     263/** Only legacy transfers supported. */
     264#  define TPM_CRB_LOCALITY_REG_INTF_ID_CAP_DATA_XFER_SZ_LEGACY 0x0
     265/** 8B maximum transfer size. */
     266#  define TPM_CRB_LOCALITY_REG_INTF_ID_CAP_DATA_XFER_SZ_8B   0x1
     267/** 32B maximum transfer size. */
     268#  define TPM_CRB_LOCALITY_REG_INTF_ID_CAP_DATA_XFER_SZ_32B  0x2
     269/** 64B maximum transfer size. */
     270#  define TPM_CRB_LOCALITY_REG_INTF_ID_CAP_DATA_XFER_SZ_64B  0x3
     271/** FIFO interface is supported and may be selected. */
     272# define TPM_CRB_LOCALITY_REG_INTF_ID_CAP_FIFO               RT_BIT(13)
     273/** CRB interface is supported and may be selected. */
     274# define TPM_CRB_LOCALITY_REG_INTF_ID_CAP_CRB                RT_BIT(14)
     275/** Interrupt polarity configuration. */
     276# define TPM_CRB_LOCALITY_REG_INTF_ID_IF_SEL_MASK            0x60000
     277# define TPM_CRB_LOCALITY_REG_INTF_ID_IF_SEL_SHIFT           17
     278# define TPM_CRB_LOCALITY_REG_INTF_ID_IF_SEL_SET(a)          ((a) << TPM_CRB_LOCALITY_REG_INTF_ID_IF_SEL_SHIFT)
     279# define TPM_CRB_LOCALITY_REG_INTF_ID_IF_SEL_GET(a)          (((a) & TPM_CRB_LOCALITY_REG_INTF_ID_IF_SEL_MASK) >> TPM_CRB_LOCALITY_REG_INTF_ID_IF_SEL_SHIFT)
     280/** Selects the FIFO interface, takes effect on next _TPM_INIT. */
     281#  define TPM_CRB_LOCALITY_REG_INTF_ID_IF_SEL_FIFO           0
     282/** Selects the CRB interface, takes effect on next _TPM_INIT. */
     283#  define TPM_CRB_LOCALITY_REG_INTF_ID_IF_SEL_CRB            1
     284/** Locks the interface selector field and prevents further changes. */
     285# define TPM_CRB_LOCALITY_REG_INTF_ID_IF_SEL_LOCK            RT_BIT(19)
     286/** Revision ID field. */
     287# define TPM_CRB_LOCALITY_REG_INTF_ID_RID_SHIFT              17
     288# define TPM_CRB_LOCALITY_REG_INTF_ID_RID_SET(a)             ((uint64_t)(a) << TPM_CRB_LOCALITY_REG_INTF_ID_RID_SHIFT)
     289/** Vendor ID field. */
     290# define TPM_CRB_LOCALITY_REG_INTF_ID_VID_SHIFT              32
     291# define TPM_CRB_LOCALITY_REG_INTF_ID_VID_SET(a)             ((uint64_t)(a) << TPM_CRB_LOCALITY_REG_INTF_ID_VID_SHIFT)
     292/** Device ID field. */
     293# define TPM_CRB_LOCALITY_REG_INTF_ID_DID_SHIFT              48
     294# define TPM_CRB_LOCALITY_REG_INTF_ID_DID_SET(a)             ((uint64_t)(a) << TPM_CRB_LOCALITY_REG_INTF_ID_DID_SHIFT)
     295
     296/** Locality CRB extension register (optional and locality 0 only). */
     297#define TPM_CRB_LOCALITY_REG_CTRL_EXT                        0x38
     298
     299/** Locality CRB request register. */
     300#define TPM_CRB_LOCALITY_REG_CTRL_REQ                        0x40
     301/** The TPM should transition to the ready state to receive a new command. */
     302# define TPM_CRB_LOCALITY_REG_CTRL_REQ_CMD_RDY               RT_BIT(0)
     303/** The TPM should transition to the idle state. */
     304# define TPM_CRB_LOCALITY_REG_CTRL_REQ_IDLE                  RT_BIT(1)
     305
     306/** Locality CRB status register. */
     307#define TPM_CRB_LOCALITY_REG_CTRL_STS                        0x44
     308/** This bit indicates that the TPM ran into a fatal error if set. */
     309# define TPM_CRB_LOCALITY_REG_CTRL_STS_TPM_FATAL_ERR         RT_BIT(0)
     310/** This bit indicates that the TPM is in the idle state. */
     311# define TPM_CRB_LOCALITY_REG_CTRL_STS_TPM_IDLE              RT_BIT(1)
     312
     313/** Locality CRB cancel register. */
     314#define TPM_CRB_LOCALITY_REG_CTRL_CANCEL                     0x48
     315/** Locality CRB start register. */
     316#define TPM_CRB_LOCALITY_REG_CTRL_START                      0x4c
     317
     318/** Locality interrupt enable register. */
     319#define TPM_CRB_LOCALITY_REG_INT_ENABLE                      0x50
     320/** Enable the "TPM has executed a reqeust and response is available" interrupt. */
     321# define TPM_CRB_LOCALITY_REG_INT_ENABLE_START               RT_BIT(0)
     322/** Enable the "TPM has transitioned to the command ready state" interrupt. */
     323# define TPM_CRB_LOCALITY_REG_INT_CMD_RDY                    RT_BIT(1)
     324/** Enable the "TPM has cleared the establishment flag" interrupt. */
     325# define TPM_CRB_LOCALITY_REG_INT_ESTABLISHMENT_CLR          RT_BIT(2)
     326/** Enable the "active locality has changed" interrupt. */
     327# define TPM_CRB_LOCALITY_REG_INT_LOC_CHANGED                RT_BIT(3)
     328/** Enables interrupts globally as defined by the individual bits in this register. */
     329# define TPM_CRB_LOCALITY_REG_INT_GLOBAL_ENABLE              RT_BIT(31)
     330
     331/** Locality interrupt status register. */
     332#define TPM_CRB_LOCALITY_REG_INT_STS                         0x54
     333/** Indicates that the TPM as executed a command and the response is available for reading, writing a 1 clears the bit. */
     334# define TPM_CRB_LOCALITY_REG_INT_STS_START                  RT_BIT(0)
     335/** Indicates that the TPM has finished the transition to the ready state, writing a 1 clears this bit. */
     336# define TPM_CRB_LOCALITY_REG_INT_STS_CMD_RDY                RT_BIT(1)
     337/** Indicates that the TPM has cleared the establishment flag, writing a 1 clears this bit. */
     338# define TPM_CRB_LOCALITY_REG_INT_STS_ESTABLISHMENT_CLR      RT_BIT(2)
     339/** Indicates that a locality change has occurrec, writing a 1 clears this bit. */
     340# define TPM_CRB_LOCALITY_REG_INT_STS_LOC_CHANGED            RT_BIT(3)
     341
     342/** Locality command buffer size register. */
     343#define TPM_CRB_LOCALITY_REG_CTRL_CMD_SZ                     0x58
     344/** Locality command buffer low address register. */
     345#define TPM_CRB_LOCALITY_REG_CTRL_CMD_LADDR                  0x5c
     346/** Locality command buffer low address register. */
     347#define TPM_CRB_LOCALITY_REG_CTRL_CMD_HADDR                  0x60
     348/** Locality response buffer size register. */
     349#define TPM_CRB_LOCALITY_REG_CTRL_RSP_SZ                     0x64
     350/** Locality response buffer size register. */
     351#define TPM_CRB_LOCALITY_REG_CTRL_RSP_ADDR                   0x68
     352/** Locality data buffer. */
     353#define TPM_CRB_LOCALITY_REG_DATA_BUFFER                     0x80
     354/** Size of the data buffer. */
     355#define TPM_CRB_LOCALITY_REG_DATA_BUFFER_SIZE                3968
    197356/** @} */
    198357
     
    203362
    204363/**
    205  * Possible locality states
     364 * Possible TPM states
    206365 * (see chapter 5.6.12.1 Figure 3 State Transition Diagram).
    207366 */
    208 typedef enum DEVTPMLOCALITYSTATE
     367typedef enum DEVTPMSTATE
    209368{
    210369    /** Invalid state, do not use. */
    211     DEVTPMLOCALITYSTATE_INVALID = 0,
    212     /** Init state. */
    213     DEVTPMLOCALITYSTATE_INIT,
     370    DEVTPMSTATE_INVALID = 0,
     371    /** Idle state. */
     372    DEVTPMSTATE_IDLE,
    214373    /** Ready to accept command data. */
    215     DEVTPMLOCALITYSTATE_READY,
     374    DEVTPMSTATE_READY,
    216375    /** Command data being transfered. */
    217     DEVTPMLOCALITYSTATE_CMD_RECEPTION,
     376    DEVTPMSTATE_CMD_RECEPTION,
    218377    /** Command is being executed by the TPM. */
    219     DEVTPMLOCALITYSTATE_CMD_EXEC,
     378    DEVTPMSTATE_CMD_EXEC,
    220379    /** Command has completed and data can be read. */
    221     DEVTPMLOCALITYSTATE_CMD_COMPLETION,
     380    DEVTPMSTATE_CMD_COMPLETION,
     381    /** Command is being canceled. */
     382    DEVTPMSTATE_CMD_CANCEL,
     383    /** TPM ran into a fatal error and is not operational. */
     384    DEVTPMSTATE_FATAL_ERROR,
    222385    /** 32bit hack. */
    223     DEVTPMLOCALITYSTATE_32BIT_HACK = 0x7fffffff
    224 } DEVTPMLOCALITYSTATE;
     386    DEVTPMSTATE_32BIT_HACK = 0x7fffffff
     387} DEVTPMSTATE;
    225388
    226389
     
    230393typedef struct DEVTPMLOCALITY
    231394{
    232     /** The current state of the locality. */
    233     DEVTPMLOCALITYSTATE             enmState;
    234     /** Access register state. */
    235     uint32_t                        uRegAccess;
    236395    /** The interrupt enable register. */
    237396    uint32_t                        uRegIntEn;
     
    239398    uint32_t                        uRegIntSts;
    240399} DEVTPMLOCALITY;
     400/** Pointer to a locality state. */
    241401typedef DEVTPMLOCALITY *PDEVTPMLOCALITY;
     402/** Pointer to a const locality state. */
    242403typedef const DEVTPMLOCALITY *PCDEVTPMLOCALITY;
    243404
     
    248409typedef struct DEVTPM
    249410{
     411    /** Base MMIO address of the TPM device. */
     412    RTGCPHYS                        GCPhysMmio;
    250413    /** The handle of the MMIO region. */
    251414    IOMMMIOHANDLE                   hMmio;
     415    /** The handle for the ring-3 task. */
     416    PDMTASKHANDLE                   hTpmCmdTask;
    252417    /** The vendor ID configured. */
    253418    uint16_t                        uVenId;
     
    258423    /** The IRQ value. */
    259424    uint8_t                         uIrq;
     425    /** Flag whether CRB access mode is used. */
     426    bool                            fCrb;
    260427
    261428    /** Currently selected locality. */
     
    263430    /** States of the implemented localities. */
    264431    DEVTPMLOCALITY                  aLoc[TPM_LOCALITY_COUNT];
    265 
     432    /** Bitmask of localities having requested access to the TPM. */
     433    uint32_t                        bmLocReqAcc;
     434    /** Bitmask of localities having been seized access from the TPM. */
     435    uint32_t                        bmLocSeizedAcc;
     436    /** The current state of the TPM. */
     437    DEVTPMSTATE                     enmState;
     438
     439    /** Command/Response buffer. */
     440    uint8_t                         abCmdResp[TPM_CRB_LOCALITY_REG_DATA_BUFFER_SIZE];
    266441} DEVTPM;
    267442/** Pointer to the shared TPM device state. */
     
    277452typedef struct DEVTPMR3
    278453{
    279     uint8_t                         bDummy;
     454    /** The base interface for LUN\#0. */
     455    PDMIBASE                        IBase;
     456    /** The base interface below. */
     457    R3PTRTYPE(PPDMIBASE)            pDrvBase;
     458    /** The TPM connector interface below. */
     459    R3PTRTYPE(PPDMITPMCONNECTOR)    pDrvTpm;
    280460} DEVTPMR3;
    281461/** Pointer to the TPM device state for ring-3. */
     
    288468typedef struct DEVTPMR0
    289469{
    290     uint8_t                         bDummy;
     470    uint32_t                        u32Dummy;
    291471} DEVTPMR0;
    292472/** Pointer to the TPM device state for ring-0. */
     
    299479typedef struct DEVTPMRC
    300480{
    301     uint8_t                         bDummy;
     481    uint32_t                        u32Dummy;
    302482} DEVTPMRC;
    303483/** Pointer to the TPM device state for raw-mode. */
     
    338518PDMBOTHCBDECL(void) tpmLocIrqUpdate(PPDMDEVINS pDevIns, PDEVTPM pThis, PDEVTPMLOCALITY pLoc)
    339519{
    340     if (pLoc->uRegIntEn & pLoc->uRegIntSts)
     520    if (   (pLoc->uRegIntEn & TPM_CRB_LOCALITY_REG_INT_GLOBAL_ENABLE)
     521        && (pLoc->uRegIntEn & pLoc->uRegIntSts))
    341522        tpmIrqReq(pDevIns, pThis, 1);
    342523    else
    343524        tpmIrqReq(pDevIns, pThis, 0);
     525}
     526
     527
     528/**
     529 * Sets the interrupt status for the given locality, firing an interrupt if necessary.
     530 *
     531 * @returns nothing.
     532 * @param   pDevIns             Pointer to the PDM device instance data.
     533 * @param   pThis               Pointer to the shared TPM device.
     534 * @param   pLoc                The locality state.
     535 * @param   uSts                The interrupt status bit to set.
     536 */
     537static void tpmLocSetIntSts(PPDMDEVINS pDevIns, PDEVTPM pThis, PDEVTPMLOCALITY pLoc, uint32_t uSts)
     538{
     539    pLoc->uRegIntSts |= uSts;
     540    tpmLocIrqUpdate(pDevIns, pThis, pLoc);
     541}
     542
     543
     544/**
     545 * Selects the next locality which has requested access.
     546 *
     547 * @returns nothing.
     548 * @param   pDevIns             Pointer to the PDM device instance data.
     549 * @param   pThis               Pointer to the shared TPM device.
     550 */
     551static void tpmLocSelectNext(PPDMDEVINS pDevIns, PDEVTPM pThis)
     552{
     553    Assert(pThis->bmLocReqAcc);
     554    Assert(pThis->bLoc == TPM_NO_LOCALITY_SELECTED);
     555    pThis->bLoc = (uint8_t)ASMBitLastSetU32(pThis->bmLocReqAcc) - 1; /* Select one with highest priority. */
     556
     557    tpmLocSetIntSts(pDevIns, pThis, &pThis->aLoc[pThis->bLoc], TPM_CRB_LOCALITY_REG_INT_STS_LOC_CHANGED);
    344558}
    345559
     
    369583
    370584
    371 /* -=-=-=-=-=- MMIO callbacks -=-=-=-=-=- */
    372 
    373 
    374 /**
    375  * @callback_method_impl{FNIOMMMIONEWREAD}
    376  */
    377 static DECLCALLBACK(VBOXSTRICTRC) tpmMmioRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, unsigned cb)
    378 {
    379     PDEVTPM pThis  = PDMDEVINS_2_DATA(pDevIns, PDEVTPM);
    380     RT_NOREF(pvUser);
    381 
    382     Assert(!(off & (cb - 1)));
    383 
    384     LogFlowFunc((": %RGp %#x\n", off, cb));
     585/**
     586 * Read from a FIFO interface register.
     587 *
     588 * @returns VBox strict status code.
     589 * @param   pDevIns             Pointer to the PDM device instance data.
     590 * @param   pThis               Pointer to the shared TPM device.
     591 * @param   pLoc                The locality state being read from.
     592 * @param   bLoc                The locality index.
     593 * @param   uReg                The register offset being accessed.
     594 * @param   pu64                Where to store the read data.
     595 */
     596static VBOXSTRICTRC tpmMmioFifoRead(PPDMDEVINS pDevIns, PDEVTPM pThis, PDEVTPMLOCALITY pLoc,
     597                                    uint8_t bLoc, uint32_t uReg, uint64_t *pu64)
     598{
     599    RT_NOREF(pDevIns, pThis, pLoc, bLoc, uReg, pu64);
    385600    VBOXSTRICTRC rc = VINF_SUCCESS;
    386     uint32_t uReg = tpmGetRegisterFromOffset(off);
    387     uint8_t bLoc = tpmGetLocalityFromOffset(off);
    388     PDEVTPMLOCALITY pLoc = &pThis->aLoc[bLoc];
    389     uint32_t u32;
     601
     602#if 0
     603    uint64_t u64;
    390604    switch (uReg)
    391605    {
    392         case TPM_LOCALITY_REG_ACCESS:
    393             u32 = 0;
    394             break;
    395         case TPM_LOCALITY_REG_INT_ENABLE:
    396             u32 = pLoc->uRegIntEn;
    397             break;
    398         case TPM_LOCALITY_REG_INT_VEC:
    399             u32 = pThis->uIrq;
    400             break;
    401         case TPM_LOCALITY_REG_INT_STS:
    402             u32 = pLoc->uRegIntSts;
    403             break;
    404         case TPM_LOCALITY_REG_IF_CAP:
    405             u32 =   TPM_LOCALITY_REG_IF_CAP_INT_DATA_AVAIL
    406                   | TPM_LOCALITY_REG_IF_CAP_INT_STS_VALID
    407                   | TPM_LOCALITY_REG_IF_CAP_INT_LOCALITY_CHANGE
    408                   | TPM_LOCALITY_REG_IF_CAP_INT_LVL_LOW
    409                   | TPM_LOCALITY_REG_IF_CAP_INT_CMD_RDY
    410                   | TPM_LOCALITY_REG_IF_CAP_DATA_XFER_SZ_SET(TPM_LOCALITY_REG_IF_CAP_DATA_XFER_SZ_64B)
    411                   | TPM_LOCALITY_REG_IF_CAP_IF_VERSION_SET(TPM_LOCALITY_REG_IF_CAP_IF_VERSION_IF_1_3); /** @todo Make some of them configurable? */
    412             break;
    413         case TPM_LOCALITY_REG_STS:
     606        case TPM_FIFO_LOCALITY_REG_ACCESS:
     607            u64 = 0;
     608            break;
     609        case TPM_FIFO_LOCALITY_REG_INT_ENABLE:
     610            u64 = pLoc->uRegIntEn;
     611            break;
     612        case TPM_FIFO_LOCALITY_REG_INT_VEC:
     613            u64 = pThis->uIrq;
     614            break;
     615        case TPM_FIFO_LOCALITY_REG_INT_STS:
     616            u64 = pLoc->uRegIntSts;
     617            break;
     618        case TPM_FIFO_LOCALITY_REG_IF_CAP:
     619            u64 =   TPM_FIFO_LOCALITY_REG_IF_CAP_INT_DATA_AVAIL
     620                  | TPM_FIFO_LOCALITY_REG_IF_CAP_INT_STS_VALID
     621                  | TPM_FIFO_LOCALITY_REG_IF_CAP_INT_LOCALITY_CHANGE
     622                  | TPM_FIFO_LOCALITY_REG_IF_CAP_INT_LVL_LOW
     623                  | TPM_FIFO_LOCALITY_REG_IF_CAP_INT_CMD_RDY
     624                  | TPM_FIFO_LOCALITY_REG_IF_CAP_DATA_XFER_SZ_SET(TPM_FIFO_LOCALITY_REG_IF_CAP_DATA_XFER_SZ_64B)
     625                  | TPM_FIFO_LOCALITY_REG_IF_CAP_IF_VERSION_SET(TPM_FIFO_LOCALITY_REG_IF_CAP_IF_VERSION_IF_1_3); /** @todo Make some of them configurable? */
     626            break;
     627        case TPM_FIFO_LOCALITY_REG_STS:
    414628            if (bLoc != pThis->bLoc)
    415629            {
    416                 u32 = UINT32_MAX;
     630                u64 = UINT64_MAX;
    417631                break;
    418632            }
    419633            /** @todo */
    420634            break;
    421         case TPM_LOCALITY_REG_DATA_FIFO:
    422         case TPM_LOCALITY_REG_DATA_XFIFO:
     635        case TPM_FIFO_LOCALITY_REG_DATA_FIFO:
     636        //case TPM_FIFO_LOCALITY_REG_DATA_XFIFO:
    423637            /** @todo */
    424638            break;
    425         case TPM_LOCALITY_REG_DID_VID:
    426             u32 = RT_H2BE_U32(RT_MAKE_U32(pThis->uVenId, pThis->uDevId));
    427             break;
    428         case TPM_LOCALITY_REG_RID:
    429             u32 = pThis->bRevId;
     639        case TPM_FIFO_LOCALITY_REG_DID_VID:
     640            u64 = RT_H2BE_U32(RT_MAKE_U32(pThis->uVenId, pThis->uDevId));
     641            break;
     642        case TPM_FIFO_LOCALITY_REG_RID:
     643            u64 = pThis->bRevId;
    430644            break;
    431645        default: /* Return ~0. */
    432             u32 = UINT32_MAX;
     646            u64 = UINT64_MAX;
    433647            break;
    434648    }
    435649
    436     switch (cb)
    437     {
    438         case 1: *(uint8_t *)pv = (uint8_t)u32; break;
    439         case 2: *(uint16_t *)pv = (uint16_t)u32; break;
    440         case 4: *(uint32_t *)pv = u32; break;
    441         default: AssertFailedBreakStmt(rc = VERR_INTERNAL_ERROR);
    442     }
     650    *pu64 = u64;
     651#endif
    443652
    444653    return rc;
     
    447656
    448657/**
    449  * @callback_method_impl{FNIOMMMIONEWWRITE}
    450  */
    451 static DECLCALLBACK(VBOXSTRICTRC) tpmMmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void const *pv, unsigned cb)
    452 {
    453     PDEVTPM pThis  = PDMDEVINS_2_DATA(pDevIns, PDEVTPM);
    454     RT_NOREF(pvUser);
    455 
    456     Assert(!(off & (cb - 1)));
    457 
    458     uint32_t u32;
    459     switch (cb)
    460     {
    461         case 1: u32 = *(const uint8_t *)pv; break;
    462         case 2: u32 = *(const uint16_t *)pv; break;
    463         case 4: u32 = *(const uint32_t *)pv; break;
    464         default: AssertFailedReturn(VERR_INTERNAL_ERROR);
    465     }
    466 
    467     LogFlowFunc((": %RGp %#x\n", off, u32));
     658 * Read to a FIFO interface register.
     659 *
     660 * @returns VBox strict status code.
     661 * @param   pDevIns             Pointer to the PDM device instance data.
     662 * @param   pThis               Pointer to the shared TPM device.
     663 * @param   pLoc                The locality state being written to.
     664 * @param   bLoc                The locality index.
     665 * @param   uReg                The register offset being accessed.
     666 * @param   u64                 The value to write.
     667 */
     668static VBOXSTRICTRC tpmMmioFifoWrite(PPDMDEVINS pDevIns, PDEVTPM pThis, PDEVTPMLOCALITY pLoc,
     669                                     uint8_t bLoc, uint32_t uReg, uint64_t u64)
     670{
     671    RT_NOREF(pDevIns, pThis, pLoc, bLoc, uReg, u64);
    468672
    469673    VBOXSTRICTRC rc = VINF_SUCCESS;
    470     uint32_t uReg = tpmGetRegisterFromOffset(off);
    471     uint8_t bLoc = tpmGetLocalityFromOffset(off);
    472     PDEVTPMLOCALITY pLoc = &pThis->aLoc[bLoc];
     674#if 0
     675    uint32_t u32 = (uint32_t)u64;
     676
    473677    switch (uReg)
    474678    {
    475         case TPM_LOCALITY_REG_ACCESS:
    476             u32 &= TPM_LOCALITY_REG_ACCESS_WR_MASK;
     679        case TPM_FIFO_LOCALITY_REG_ACCESS:
     680            u32 &= TPM_FIFO_LOCALITY_REG_ACCESS_WR_MASK;
    477681             /*
    478682              * Chapter 5.6.11, 2 states that writing to this register with more than one
     
    484688            /** @todo */
    485689            break;
    486         case TPM_LOCALITY_REG_INT_ENABLE:
     690        case TPM_FIFO_LOCALITY_REG_INT_ENABLE:
    487691            if (bLoc != pThis->bLoc)
    488692                break;
    489693            /** @todo */
    490694            break;
    491         case TPM_LOCALITY_REG_INT_STS:
     695        case TPM_FIFO_LOCALITY_REG_INT_STS:
    492696            if (bLoc != pThis->bLoc)
    493697                break;
    494             pLoc->uRegSts &= ~(u32 & TPM_LOCALITY_REG_INT_STS_WR_MASK);
     698            pLoc->uRegSts &= ~(u32 & TPM_FIFO_LOCALITY_REG_INT_STS_WR_MASK);
    495699            tpmLocIrqUpdate(pDevIns, pThis, pLoc);
    496700            break;
    497         case TPM_LOCALITY_REG_STS:
     701        case TPM_FIFO_LOCALITY_REG_STS:
    498702            /*
    499703             * Writes are ignored completely if the locality being accessed is not the
     
    502706             */
    503707            if (   bLoc != pThis->bLoc
    504                 || !RT_IS_POWER_OF_TWO(u32))
     708                || !RT_IS_POWER_OF_TWO(u64))
    505709                break;
    506710            /** @todo */
    507711            break;
    508         case TPM_LOCALITY_REG_DATA_FIFO:
    509         case TPM_LOCALITY_REG_DATA_XFIFO:
     712        case TPM_FIFO_LOCALITY_REG_DATA_FIFO:
     713        case TPM_FIFO_LOCALITY_REG_DATA_XFIFO:
    510714            if (bLoc != pThis->bLoc)
    511715                break;
    512716            /** @todo */
    513717            break;
    514         case TPM_LOCALITY_REG_INT_VEC:
    515         case TPM_LOCALITY_REG_IF_CAP:
    516         case TPM_LOCALITY_REG_DID_VID:
    517         case TPM_LOCALITY_REG_RID:
     718        case TPM_FIFO_LOCALITY_REG_INT_VEC:
     719        case TPM_FIFO_LOCALITY_REG_IF_CAP:
     720        case TPM_FIFO_LOCALITY_REG_DID_VID:
     721        case TPM_FIFO_LOCALITY_REG_RID:
    518722        default: /* Ignore. */
    519723            break;
    520724    }
    521 
     725#endif
    522726    return rc;
    523727}
    524728
    525729
     730/**
     731 * Read from a CRB interface register.
     732 *
     733 * @returns VBox strict status code.
     734 * @param   pDevIns             Pointer to the PDM device instance data.
     735 * @param   pThis               Pointer to the shared TPM device.
     736 * @param   pLoc                The locality state being read from.
     737 * @param   bLoc                The locality index.
     738 * @param   uReg                The register offset being accessed.
     739 * @param   pu64                Where to store the read data.
     740 * @param   cb                  Size of the read in bytes.
     741 */
     742static VBOXSTRICTRC tpmMmioCrbRead(PPDMDEVINS pDevIns, PDEVTPM pThis, PDEVTPMLOCALITY pLoc,
     743                                   uint8_t bLoc, uint32_t uReg, uint64_t *pu64, size_t cb)
     744{
     745    RT_NOREF(pDevIns);
     746
     747    /* Special path for the data buffer. */
     748    if (   uReg >= TPM_CRB_LOCALITY_REG_DATA_BUFFER
     749        && uReg < TPM_CRB_LOCALITY_REG_DATA_BUFFER + TPM_CRB_LOCALITY_REG_DATA_BUFFER_SIZE
     750        && bLoc == pThis->bLoc
     751        && pThis->enmState == DEVTPMSTATE_CMD_COMPLETION)
     752    {
     753        memcpy(pu64, &pThis->abCmdResp[uReg - TPM_CRB_LOCALITY_REG_DATA_BUFFER], cb);
     754        return VINF_SUCCESS;
     755    }
     756
     757    VBOXSTRICTRC rc = VINF_SUCCESS;
     758    uint64_t u64 = UINT64_MAX;
     759    switch (uReg)
     760    {
     761        case TPM_CRB_LOCALITY_REG_STATE:
     762            u64 =   TPM_CRB_LOCALITY_REG_STATE_VALID
     763                  | (  pThis->bLoc != TPM_NO_LOCALITY_SELECTED
     764                     ? TPM_CRB_LOCALITY_REG_STATE_ACTIVE_LOC_SET(pThis->bLoc) | TPM_CRB_LOCALITY_REG_STATE_LOC_ASSIGNED
     765                     : TPM_CRB_LOCALITY_REG_STATE_ACTIVE_LOC_SET(0));
     766            break;
     767        case TPM_CRB_LOCALITY_REG_STS:
     768            u64 =   pThis->bLoc == bLoc
     769                  ? TPM_CRB_LOCALITY_REG_STS_GRANTED
     770                  : 0;
     771            u64 |=   pThis->bmLocSeizedAcc & RT_BIT_32(bLoc)
     772                   ? TPM_CRB_LOCALITY_REG_STS_SEIZED
     773                   : 0;
     774            break;
     775        case TPM_CRB_LOCALITY_REG_INTF_ID:
     776            u64 =   TPM_CRB_LOCALITY_REG_INTF_ID_IF_TYPE_SET(TPM_CRB_LOCALITY_REG_INTF_ID_IF_TYPE_CRB)
     777                  | TPM_CRB_LOCALITY_REG_INTF_ID_IF_VERS_SET(TPM_CRB_LOCALITY_REG_INTF_ID_IF_VERS_CRB)
     778                  | TPM_CRB_LOCALITY_REG_INTF_ID_CAP_LOCALITY
     779                  | TPM_CRB_LOCALITY_REG_INTF_ID_CAP_DATA_XFER_SZ_SET(TPM_CRB_LOCALITY_REG_INTF_ID_CAP_DATA_XFER_SZ_64B)
     780                  | TPM_CRB_LOCALITY_REG_INTF_ID_CAP_CRB
     781                  | TPM_CRB_LOCALITY_REG_INTF_ID_IF_SEL_GET(TPM_CRB_LOCALITY_REG_INTF_ID_IF_SEL_CRB)
     782                  | TPM_CRB_LOCALITY_REG_INTF_ID_IF_SEL_LOCK
     783                  | TPM_CRB_LOCALITY_REG_INTF_ID_RID_SET(pThis->bRevId)
     784                  | TPM_CRB_LOCALITY_REG_INTF_ID_VID_SET(pThis->uVenId)
     785                  | TPM_CRB_LOCALITY_REG_INTF_ID_DID_SET(pThis->uDevId);
     786            break;
     787        case TPM_CRB_LOCALITY_REG_CTRL_REQ:
     788            if (bLoc != pThis->bLoc)
     789                break;
     790            /*
     791             * Command ready and go idle are always 0 upon read
     792             * as we don't need time to transition to this state
     793             * when written by the guest.
     794             */
     795            u64 = 0;
     796            break;
     797        case TPM_CRB_LOCALITY_REG_CTRL_STS:
     798            if (bLoc != pThis->bLoc)
     799                break;
     800            if (pThis->enmState == DEVTPMSTATE_FATAL_ERROR)
     801                u64 = TPM_CRB_LOCALITY_REG_CTRL_STS_TPM_FATAL_ERR;
     802            else if (pThis->enmState == DEVTPMSTATE_IDLE)
     803                u64 = TPM_CRB_LOCALITY_REG_CTRL_STS_TPM_IDLE;
     804            else
     805                u64 = 0;
     806            break;
     807        case TPM_CRB_LOCALITY_REG_CTRL_CANCEL:
     808            if (bLoc != pThis->bLoc)
     809                break;
     810            if (pThis->enmState == DEVTPMSTATE_CMD_CANCEL)
     811                u64 = 0x1;
     812            else
     813                u64 = 0;
     814            break;
     815        case TPM_CRB_LOCALITY_REG_CTRL_START:
     816            if (bLoc != pThis->bLoc)
     817                break;
     818            if (pThis->enmState == DEVTPMSTATE_CMD_EXEC)
     819                u64 = 0x1;
     820            else
     821                u64 = 0;
     822            break;
     823        case TPM_CRB_LOCALITY_REG_INT_ENABLE:
     824            u64 = pLoc->uRegIntEn;
     825            break;
     826        case TPM_CRB_LOCALITY_REG_INT_STS:
     827            u64 = pLoc->uRegIntSts;
     828            break;
     829        case TPM_CRB_LOCALITY_REG_CTRL_CMD_LADDR:
     830            u64 = pThis->GCPhysMmio + (bLoc * TPM_LOCALITY_MMIO_SIZE) + TPM_CRB_LOCALITY_REG_DATA_BUFFER;
     831            break;
     832        case TPM_CRB_LOCALITY_REG_CTRL_CMD_HADDR:
     833            u64 = (pThis->GCPhysMmio + (bLoc * TPM_LOCALITY_MMIO_SIZE) + TPM_CRB_LOCALITY_REG_DATA_BUFFER) >> 32;
     834            break;
     835        case TPM_CRB_LOCALITY_REG_CTRL_CMD_SZ:
     836        case TPM_CRB_LOCALITY_REG_CTRL_RSP_SZ:
     837            u64 = TPM_CRB_LOCALITY_REG_DATA_BUFFER_SIZE;
     838            break;
     839        case TPM_CRB_LOCALITY_REG_CTRL_RSP_ADDR:
     840            u64 = pThis->GCPhysMmio + (bLoc * TPM_LOCALITY_MMIO_SIZE) + TPM_CRB_LOCALITY_REG_DATA_BUFFER;
     841            break;
     842        case TPM_CRB_LOCALITY_REG_CTRL: /* Writeonly */
     843            u64 = 0;
     844            break;
     845        case TPM_CRB_LOCALITY_REG_CTRL_EXT:
     846        default:
     847            break; /* Return ~0 */
     848    }
     849
     850    *pu64 = u64;
     851    return rc;
     852}
     853
     854
     855/**
     856 * Read to a CRB interface register.
     857 *
     858 * @returns VBox strict status code.
     859 * @param   pDevIns             Pointer to the PDM device instance data.
     860 * @param   pThis               Pointer to the shared TPM device.
     861 * @param   pLoc                The locality state being written to.
     862 * @param   bLoc                The locality index.
     863 * @param   uReg                The register offset being accessed.
     864 * @param   u64                 The value to write.
     865 * @param   cb                  Size of the write in bytes.
     866 */
     867static VBOXSTRICTRC tpmMmioCrbWrite(PPDMDEVINS pDevIns, PDEVTPM pThis, PDEVTPMLOCALITY pLoc,
     868                                    uint8_t bLoc, uint32_t uReg, uint64_t u64, size_t cb)
     869{
     870    VBOXSTRICTRC rc = VINF_SUCCESS;
     871    uint32_t u32 = (uint32_t)u64;
     872
     873    /* Special path for the data buffer. */
     874    if (   uReg >= TPM_CRB_LOCALITY_REG_DATA_BUFFER
     875        && uReg < TPM_CRB_LOCALITY_REG_DATA_BUFFER + TPM_CRB_LOCALITY_REG_DATA_BUFFER_SIZE
     876        && bLoc == pThis->bLoc
     877        && pThis->enmState == DEVTPMSTATE_CMD_RECEPTION)
     878    {
     879        memcpy(&pThis->abCmdResp[uReg - TPM_CRB_LOCALITY_REG_DATA_BUFFER], &u64, cb);
     880        return VINF_SUCCESS;
     881    }
     882
     883    switch (uReg)
     884    {
     885        case TPM_CRB_LOCALITY_REG_CTRL:
     886        {
     887            /* See chapter 6.5.3.2.2.1. */
     888            if (u64 & TPM_CRB_LOCALITY_REG_CTRL_RST_ESTABLISHMENT)
     889                /** @todo */;
     890
     891            /*
     892             * The following three checks should be mutually exclusive as the writer shouldn't
     893             * request, relinquish and seize access in the same write.
     894             */
     895            /* Seize access only if this locality has a higher priority than the currently selected one. */
     896            if (   (u64 & TPM_CRB_LOCALITY_REG_CTRL_SEIZE)
     897                && pThis->bLoc != TPM_NO_LOCALITY_SELECTED
     898                && bLoc > pThis->bLoc)
     899            {
     900                pThis->bmLocSeizedAcc |= RT_BIT_32(pThis->bLoc);
     901                /** @todo Abort command. */
     902                pThis->bLoc = bLoc;
     903            }
     904
     905            if (   (u64 & TPM_CRB_LOCALITY_REG_CTRL_REQ_ACCESS)
     906                && !(pThis->bmLocReqAcc & RT_BIT_32(bLoc)))
     907            {
     908                pThis->bmLocReqAcc |= RT_BIT_32(bLoc);
     909                if (pThis->bLoc == TPM_NO_LOCALITY_SELECTED)
     910                {
     911                    pThis->bLoc = bLoc; /* Doesn't fire an interrupt. */
     912                    pThis->bmLocSeizedAcc &= ~RT_BIT_32(bLoc);
     913                }
     914            }
     915
     916            if (   (u64 & TPM_CRB_LOCALITY_REG_CTRL_RELINQUISH)
     917                && (pThis->bmLocReqAcc & RT_BIT_32(bLoc)))
     918            {
     919                pThis->bmLocReqAcc &= ~RT_BIT_32(bLoc);
     920                if (pThis->bLoc == bLoc)
     921                {
     922                    pThis->bLoc = TPM_NO_LOCALITY_SELECTED;
     923                    if (pThis->bmLocReqAcc)
     924                        tpmLocSelectNext(pDevIns, pThis); /* Select the next locality. */
     925                }
     926            }
     927            break;
     928        }
     929        case TPM_CRB_LOCALITY_REG_CTRL_REQ:
     930            if (   bLoc != pThis->bLoc
     931                || !RT_IS_POWER_OF_TWO(u32)) /* Ignore if multiple bits are set. */
     932                break;
     933            if (   (u32 & TPM_CRB_LOCALITY_REG_CTRL_REQ_CMD_RDY)
     934                && pThis->enmState == DEVTPMSTATE_IDLE)
     935            {
     936                pThis->enmState = DEVTPMSTATE_READY;
     937                tpmLocSetIntSts(pDevIns, pThis, pLoc, TPM_CRB_LOCALITY_REG_INT_STS_CMD_RDY);
     938            }
     939            else if (   (u32 & TPM_CRB_LOCALITY_REG_CTRL_REQ_IDLE)
     940                     && pThis->enmState != DEVTPMSTATE_CMD_EXEC)
     941            {
     942                /* Invalidate the command/response buffer. */
     943                RT_ZERO(pThis->abCmdResp);
     944                pThis->enmState = DEVTPMSTATE_IDLE;
     945            }
     946            break;
     947        case TPM_CRB_LOCALITY_REG_CTRL_CANCEL:
     948            if (bLoc != pThis->bLoc)
     949                break;
     950            if (   pThis->enmState == DEVTPMSTATE_CMD_EXEC
     951                && u32 == 0x1)
     952            {
     953                pThis->enmState == DEVTPMSTATE_CMD_CANCEL;
     954                /** @todo Cancel. */
     955                pThis->enmState == DEVTPMSTATE_CMD_COMPLETION;
     956                tpmLocSetIntSts(pDevIns, pThis, pLoc, TPM_CRB_LOCALITY_REG_INT_STS_START);
     957            }
     958            break;
     959        case TPM_CRB_LOCALITY_REG_CTRL_START:
     960            if (bLoc != pThis->bLoc)
     961                break;
     962            if (   pThis->enmState == DEVTPMSTATE_CMD_RECEPTION
     963                && u32 == 0x1)
     964            {
     965                pThis->enmState == DEVTPMSTATE_CMD_EXEC;
     966                rc = PDMDevHlpTaskTrigger(pDevIns, pThis->hTpmCmdTask);
     967            }
     968            break;
     969        case TPM_CRB_LOCALITY_REG_INT_ENABLE:
     970            pLoc->uRegIntEn = u32;
     971            tpmLocIrqUpdate(pDevIns, pThis, pLoc);
     972            break;
     973        case TPM_CRB_LOCALITY_REG_INT_STS:
     974            pLoc->uRegIntSts &= ~u32;
     975            tpmLocIrqUpdate(pDevIns, pThis, pLoc);
     976            break;
     977        case TPM_CRB_LOCALITY_REG_CTRL_EXT: /* Not implemented. */
     978        case TPM_CRB_LOCALITY_REG_STATE: /* Readonly */
     979        case TPM_CRB_LOCALITY_REG_INTF_ID:
     980        case TPM_CRB_LOCALITY_REG_CTRL_STS:
     981        case TPM_CRB_LOCALITY_REG_CTRL_CMD_LADDR:
     982        case TPM_CRB_LOCALITY_REG_CTRL_CMD_HADDR:
     983        case TPM_CRB_LOCALITY_REG_CTRL_CMD_SZ:
     984        case TPM_CRB_LOCALITY_REG_CTRL_RSP_SZ:
     985        case TPM_CRB_LOCALITY_REG_CTRL_RSP_ADDR:
     986        default: /* Ignore. */
     987            break;
     988    }
     989
     990    return rc;
     991}
     992
     993
     994/* -=-=-=-=-=- MMIO callbacks -=-=-=-=-=- */
     995
     996/**
     997 * @callback_method_impl{FNIOMMMIONEWREAD}
     998 */
     999static DECLCALLBACK(VBOXSTRICTRC) tpmMmioRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, unsigned cb)
     1000{
     1001    PDEVTPM pThis  = PDMDEVINS_2_DATA(pDevIns, PDEVTPM);
     1002    RT_NOREF(pvUser);
     1003
     1004    Assert(!(off & (cb - 1)));
     1005
     1006    LogFlowFunc((": %RGp %#x\n", off, cb));
     1007    VBOXSTRICTRC rc = VINF_SUCCESS;
     1008    uint32_t uReg = tpmGetRegisterFromOffset(off);
     1009    uint8_t bLoc = tpmGetLocalityFromOffset(off);
     1010    PDEVTPMLOCALITY pLoc = &pThis->aLoc[bLoc];
     1011
     1012
     1013    uint64_t u64;
     1014    if (pThis->fCrb)
     1015        rc = tpmMmioCrbRead(pDevIns, pThis, pLoc, bLoc, uReg, &u64, cb);
     1016    else
     1017        rc = tpmMmioFifoRead(pDevIns, pThis, pLoc, bLoc, uReg, &u64);
     1018
     1019    if (rc == VINF_SUCCESS)
     1020    {
     1021        switch (cb)
     1022        {
     1023            case 1: *(uint8_t *)pv = (uint8_t)u64; break;
     1024            case 2: *(uint16_t *)pv = (uint16_t)u64; break;
     1025            case 4: *(uint32_t *)pv = (uint32_t)u64; break;
     1026            case 8: *(uint64_t *)pv = u64; break;
     1027            default: AssertFailedBreakStmt(rc = VERR_INTERNAL_ERROR);
     1028        }
     1029    }
     1030
     1031    return rc;
     1032}
     1033
     1034
     1035/**
     1036 * @callback_method_impl{FNIOMMMIONEWWRITE}
     1037 */
     1038static DECLCALLBACK(VBOXSTRICTRC) tpmMmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void const *pv, unsigned cb)
     1039{
     1040    PDEVTPM pThis  = PDMDEVINS_2_DATA(pDevIns, PDEVTPM);
     1041    RT_NOREF(pvUser);
     1042
     1043    Assert(!(off & (cb - 1)));
     1044
     1045    uint64_t u64;
     1046    switch (cb)
     1047    {
     1048        case 1: u64 = *(const uint8_t *)pv; break;
     1049        case 2: u64 = *(const uint16_t *)pv; break;
     1050        case 4: u64 = *(const uint32_t *)pv; break;
     1051        case 8: u64 = *(const uint64_t *)pv; break;
     1052        default: AssertFailedReturn(VERR_INTERNAL_ERROR);
     1053    }
     1054
     1055    LogFlowFunc((": %RGp %#llx\n", off, u64));
     1056
     1057    VBOXSTRICTRC rc = VINF_SUCCESS;
     1058    uint32_t uReg = tpmGetRegisterFromOffset(off);
     1059    uint8_t bLoc = tpmGetLocalityFromOffset(off);
     1060    PDEVTPMLOCALITY pLoc = &pThis->aLoc[bLoc];
     1061
     1062    if (pThis->fCrb)
     1063        rc = tpmMmioCrbWrite(pDevIns, pThis, pLoc, bLoc, uReg, u64, cb);
     1064    else
     1065        rc = tpmMmioFifoWrite(pDevIns, pThis, pLoc, bLoc, uReg, u64);
     1066
     1067    return rc;
     1068}
     1069
     1070
    5261071#ifdef IN_RING3
     1072
     1073/**
     1074 * @callback_method_impl{FNPDMTASKDEV, Execute a command in ring-3}
     1075 */
     1076static DECLCALLBACK(void) tpmR3CmdExecWorker(PPDMDEVINS pDevIns, void *pvUser)
     1077{
     1078    PDEVTPM     pThis   = PDMDEVINS_2_DATA(pDevIns, PDEVTPM);
     1079    PDEVTPMR3   pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PDEVTPMR3);
     1080    RT_NOREF(pvUser);
     1081    LogFlowFunc(("\n"));
     1082
     1083    /** @todo */
     1084    RT_NOREF(pThis, pThisCC);
     1085}
    5271086
    5281087
     
    5901149
    5911150
     1151/* -=-=-=-=-=-=-=-=- PDMIBASE -=-=-=-=-=-=-=-=- */
     1152
     1153/**
     1154 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
     1155 */
     1156static DECLCALLBACK(void *) tpmR3QueryInterface(PPDMIBASE pInterface, const char *pszIID)
     1157{
     1158    PDEVTPMCC pThisCC = RT_FROM_MEMBER(pInterface, DEVTPMCC, IBase);
     1159    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pThisCC->IBase);
     1160    //PDMIBASE_RETURN_INTERFACE(pszIID, PDMITPMPORT, &pThisCC->ITpmPort);
     1161    return NULL;
     1162}
     1163
     1164
    5921165/* -=-=-=-=-=-=-=-=- PDMDEVREG -=-=-=-=-=-=-=-=- */
    5931166
     
    5971170static DECLCALLBACK(void) tpmR3Reset(PPDMDEVINS pDevIns)
    5981171{
    599     PDEVTPM   pThis   = PDMDEVINS_2_DATA(pDevIns, PDEVTPM);
    600 
    601     pThis->bLoc = TPM_NO_LOCALITY_SELECTED;
     1172    PDEVTPM pThis = PDMDEVINS_2_DATA(pDevIns, PDEVTPM);
     1173
     1174    pThis->enmState = DEVTPMSTATE_IDLE;
     1175    pThis->bLoc     = TPM_NO_LOCALITY_SELECTED;
     1176    RT_ZERO(pThis->abCmdResp);
     1177
    6021178    for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aLoc); i++)
    6031179    {
    6041180        PDEVTPMLOCALITY pLoc = &pThis->aLoc[i];
    605 
    606         pLoc->enmState   = DEVTPMLOCALITYSTATE_INIT;
    607         pLoc->aRegIntEn  = 0;
    608         pLoc->aRegIntSts = 0;
     1181        pLoc->uRegIntEn  = 0;
     1182        pLoc->uRegIntSts = 0;
    6091183    }
    6101184}
     
    6321206    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
    6331207    PDEVTPM         pThis   = PDMDEVINS_2_DATA(pDevIns, PDEVTPM);
    634     //PDEVTPMCC       pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PDEVTPMCC);
     1208    PDEVTPMCC       pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PDEVTPMCC);
    6351209    PCPDMDEVHLPR3   pHlp    = pDevIns->pHlpR3;
    6361210    int             rc;
    6371211
    6381212    RT_NOREF(iInstance);
     1213
     1214    pThis->hTpmCmdTask = NIL_PDMTASKHANDLE;
     1215
     1216    /* IBase */
     1217    pThisCC->IBase.pfnQueryInterface = tpmR3QueryInterface;
    6391218
    6401219    /*
     
    6451224                                           "|VendorId"
    6461225                                           "|DeviceId"
    647                                            "|RevisionId",
     1226                                           "|RevisionId"
     1227                                           "|Crb",
    6481228                                           "");
    6491229
    650     uint8_t uIrq = 0;
    651     rc = pHlp->pfnCFGMQueryU8Def(pCfg, "Irq", &uIrq, 10);
     1230    rc = pHlp->pfnCFGMQueryU8Def(pCfg, "Irq", &pThis->uIrq, 10);
    6521231    if (RT_FAILURE(rc))
    6531232        return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to get the \"Irq\" value"));
    6541233
    655     RTGCPHYS GCPhysMmio;
    656     rc = pHlp->pfnCFGMQueryU64Def(pCfg, "MmioBase", &GCPhysMmio, TPM_MMIO_BASE_DEFAULT);
     1234    rc = pHlp->pfnCFGMQueryU64Def(pCfg, "MmioBase", &pThis->GCPhysMmio, TPM_MMIO_BASE_DEFAULT);
    6571235    if (RT_FAILURE(rc))
    6581236        return PDMDEV_SET_ERROR(pDevIns, rc,
     
    6711249        return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to get the \"RevisionId\" value"));
    6721250
    673     pThis->uIrq = uIrq;
     1251    rc = pHlp->pfnCFGMQueryBoolDef(pCfg, "Crb", &pThis->fCrb, true);
     1252    if (RT_FAILURE(rc))
     1253        return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to get the \"Crb\" value"));
    6741254
    6751255    /*
     
    6771257     * addresses and sizes.
    6781258     */
    679     rc = PDMDevHlpMmioCreateAndMap(pDevIns, GCPhysMmio, TPM_MMIO_SIZE, tpmMmioWrite, tpmMmioRead,
     1259    rc = PDMDevHlpMmioCreateAndMap(pDevIns, pThis->GCPhysMmio, TPM_MMIO_SIZE, tpmMmioWrite, tpmMmioRead,
    6801260                                   IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU,
    6811261                                   "TPM MMIO", &pThis->hMmio);
    6821262    AssertRCReturn(rc, rc);
     1263
     1264    /*
     1265     * Attach any TPM driver below.
     1266     */
     1267    rc = PDMDevHlpDriverAttach(pDevIns, 0 /*iLUN*/, &pThisCC->IBase, &pThisCC->pDrvBase, "TPM");
     1268    if (RT_SUCCESS(rc))
     1269    {
     1270        pThisCC->pDrvTpm = PDMIBASE_QUERY_INTERFACE(pThisCC->pDrvBase, PDMITPMCONNECTOR);
     1271        AssertLogRelMsgReturn(pThisCC->pDrvTpm, ("TPM#%d: Driver is missing the TPM interface.\n", iInstance), VERR_PDM_MISSING_INTERFACE);
     1272    }
     1273    else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
     1274    {
     1275        pThisCC->pDrvBase = NULL;
     1276        pThisCC->pDrvTpm  = NULL;
     1277        LogRel(("TPM#%d: no unit\n", iInstance));
     1278    }
     1279    else
     1280        AssertLogRelMsgRCReturn(rc, ("TPM#%d: Failed to attach to TPM driver. rc=%Rrc\n", iInstance, rc), rc);
     1281
     1282    /* Create task for executing requests in ring-3. */
     1283    rc = PDMDevHlpTaskCreate(pDevIns, PDMTASK_F_RZ, "TPMCmdWrk",
     1284                             tpmR3CmdExecWorker, NULL /*pvUser*/, &pThis->hTpmCmdTask);
     1285    AssertRCReturn(rc,rc);
    6831286
    6841287    /*
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette