Changeset 90512 in vbox
- Timestamp:
- Aug 4, 2021 10:59:07 AM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 146116
- Location:
- trunk
- Files:
-
- 1 added
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Security/DevTpm.cpp
r90492 r90512 25 25 #define LOG_GROUP LOG_GROUP_DEFAULT /** @todo DEV_TPM */ 26 26 #include <VBox/vmm/pdmdev.h> 27 #include <VBox/vmm/pdmtpmifs.h> 27 28 #include <iprt/assert.h> 28 29 #include <iprt/string.h> 30 #include <iprt/uuid.h> 29 31 30 32 #include "VBoxDD.h" … … 55 57 #define TPM_LOCALITY_MMIO_SIZE 0x1000 56 58 57 /** @name TPM locality register related defines .59 /** @name TPM locality register related defines for the FIFO interface. 58 60 * @{ */ 59 61 /** Ownership management for a particular locality. */ 60 #define TPM_ LOCALITY_REG_ACCESS 0x0061 /** I Ndicates 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) 63 65 /** On reads indicates whether the locality requests use of the TPM (1) or not or is already active locality (0), 64 66 * 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) 66 68 /** 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) 68 70 /** 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) 70 72 /** 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) 72 74 /** 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) 74 76 /** 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) 76 78 /** Writable mask. */ 77 # define TPM_ LOCALITY_REG_ACCESS_WR_MASK 0x3a79 # define TPM_FIFO_LOCALITY_REG_ACCESS_WR_MASK 0x3a 78 80 79 81 /** Interrupt enable register. */ 80 #define TPM_ LOCALITY_REG_INT_ENABLE 0x0882 #define TPM_FIFO_LOCALITY_REG_INT_ENABLE 0x08 81 83 /** 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) 83 85 /** 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) 85 87 /** 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) 87 89 /** Interrupt polarity configuration. */ 88 # define TPM_ LOCALITY_REG_INT_ENABLE_POLARITY_MASK 0x1889 # define TPM_ LOCALITY_REG_INT_ENABLE_POLARITY_SHIFT 390 # 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) 92 94 /** High level interrupt trigger. */ 93 # define TPM_ LOCALITY_REG_INT_ENABLE_POLARITY_HIGH 095 # define TPM_FIFO_LOCALITY_REG_INT_ENABLE_POLARITY_HIGH 0 94 96 /** Low level interrupt trigger. */ 95 # define TPM_ LOCALITY_REG_INT_ENABLE_POLARITY_LOW 197 # define TPM_FIFO_LOCALITY_REG_INT_ENABLE_POLARITY_LOW 1 96 98 /** Rising edge interrupt trigger. */ 97 # define TPM_ LOCALITY_REG_INT_ENABLE_POLARITY_RISING 299 # define TPM_FIFO_LOCALITY_REG_INT_ENABLE_POLARITY_RISING 2 98 100 /** Falling edge interrupt trigger. */ 99 # define TPM_ LOCALITY_REG_INT_ENABLE_POLARITY_FALLING 3101 # define TPM_FIFO_LOCALITY_REG_INT_ENABLE_POLARITY_FALLING 3 100 102 /** 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) 102 104 /** 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) 104 106 105 107 /** Configured interrupt vector register. */ 106 #define TPM_ LOCALITY_REG_INT_VEC 0x0c108 #define TPM_FIFO_LOCALITY_REG_INT_VEC 0x0c 107 109 108 110 /** Interrupt status register. */ 109 #define TPM_ LOCALITY_REG_INT_STS 0x10111 #define TPM_FIFO_LOCALITY_REG_INT_STS 0x10 110 112 /** 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) 112 114 /** 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) 114 116 /** 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) 116 118 /** 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) 118 120 /** 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) 120 122 121 123 /** Interfacce capabilities register. */ 122 #define TPM_ LOCALITY_REG_IF_CAP 0x14124 #define TPM_FIFO_LOCALITY_REG_IF_CAP 0x14 123 125 /** 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) 125 127 /** 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) 127 129 /** 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) 129 131 /** 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) 131 133 /** 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) 133 135 /** 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) 135 137 /** 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) 137 139 /** 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) 139 141 /** 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) 141 143 /** Maximum transfer size support. */ 142 # define TPM_ LOCALITY_REG_IF_CAP_DATA_XFER_SZ_MASK 0x600143 # define TPM_ LOCALITY_REG_IF_CAP_DATA_XFER_SZ_SHIFT 9144 # 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) 145 147 /** Only legacy transfers supported. */ 146 # define TPM_ LOCALITY_REG_IF_CAP_DATA_XFER_SZ_LEGACY 0x0148 # define TPM_FIFO_LOCALITY_REG_IF_CAP_DATA_XFER_SZ_LEGACY 0x0 147 149 /** 8B maximum transfer size. */ 148 # define TPM_ LOCALITY_REG_IF_CAP_DATA_XFER_SZ_8B 0x1150 # define TPM_FIFO_LOCALITY_REG_IF_CAP_DATA_XFER_SZ_8B 0x1 149 151 /** 32B maximum transfer size. */ 150 # define TPM_ LOCALITY_REG_IF_CAP_DATA_XFER_SZ_32B 0x2152 # define TPM_FIFO_LOCALITY_REG_IF_CAP_DATA_XFER_SZ_32B 0x2 151 153 /** 64B maximum transfer size. */ 152 # define TPM_ LOCALITY_REG_IF_CAP_DATA_XFER_SZ_64B 0x3154 # define TPM_FIFO_LOCALITY_REG_IF_CAP_DATA_XFER_SZ_64B 0x3 153 155 /** 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 28156 # 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) 157 159 /** Interface 1.21 or ealier. */ 158 # define TPM_ LOCALITY_REG_IF_CAP_IF_VERSION_IF_1_21 0160 # define TPM_FIFO_LOCALITY_REG_IF_CAP_IF_VERSION_IF_1_21 0 159 161 /** Interface 1.3. */ 160 # define TPM_ LOCALITY_REG_IF_CAP_IF_VERSION_IF_1_3 2162 # define TPM_FIFO_LOCALITY_REG_IF_CAP_IF_VERSION_IF_1_3 2 161 163 /** Interface 1.3 for TPM 2.0. */ 162 # define TPM_ LOCALITY_REG_IF_CAP_IF_VERSION_IF_1_3_TPM2 3164 # define TPM_FIFO_LOCALITY_REG_IF_CAP_IF_VERSION_IF_1_3_TPM2 3 163 165 164 166 /** TPM status register. */ 165 #define TPM_ LOCALITY_REG_STS 0x18167 #define TPM_FIFO_LOCALITY_REG_STS 0x18 166 168 /** 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) 168 170 /** 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) 170 172 /** 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) 172 174 /** 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) 174 176 /** 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) 176 178 /** On reads indicates whether the TPM is ready to receive a new command (1) or not (0), 177 179 * 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) 179 181 /** 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 8183 # 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) 184 186 185 187 /** TPM end of HASH operation signal register for locality 4. */ 186 #define TPM_ LOCALITY_REG_HASH_END 0x20188 #define TPM_FIFO_LOCALITY_REG_HASH_END 0x20 187 189 /** Data FIFO read/write register. */ 188 #define TPM_ LOCALITY_REG_DATA_FIFO 0x24190 #define TPM_FIFO_LOCALITY_REG_DATA_FIFO 0x24 189 191 /** TPM start of HASH operation signal register for locality 4. */ 190 #define TPM_ LOCALITY_REG_HASH_START 0x28192 #define TPM_FIFO_LOCALITY_REG_HASH_START 0x28 191 193 /** Extended data FIFO read/write register. */ 192 #define TPM_ LOCALITY_REG_XDATA_FIFO 0x80194 #define TPM_FIFO_LOCALITY_REG_XDATA_FIFO 0x80 193 195 /** TPM device and vendor ID. */ 194 #define TPM_ LOCALITY_REG_DID_VID 0xf00196 #define TPM_FIFO_LOCALITY_REG_DID_VID 0xf00 195 197 /** 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 197 356 /** @} */ 198 357 … … 203 362 204 363 /** 205 * Possible localitystates364 * Possible TPM states 206 365 * (see chapter 5.6.12.1 Figure 3 State Transition Diagram). 207 366 */ 208 typedef enum DEVTPM LOCALITYSTATE367 typedef enum DEVTPMSTATE 209 368 { 210 369 /** Invalid state, do not use. */ 211 DEVTPM LOCALITYSTATE_INVALID = 0,212 /** I nitstate. */213 DEVTPM LOCALITYSTATE_INIT,370 DEVTPMSTATE_INVALID = 0, 371 /** Idle state. */ 372 DEVTPMSTATE_IDLE, 214 373 /** Ready to accept command data. */ 215 DEVTPM LOCALITYSTATE_READY,374 DEVTPMSTATE_READY, 216 375 /** Command data being transfered. */ 217 DEVTPM LOCALITYSTATE_CMD_RECEPTION,376 DEVTPMSTATE_CMD_RECEPTION, 218 377 /** Command is being executed by the TPM. */ 219 DEVTPM LOCALITYSTATE_CMD_EXEC,378 DEVTPMSTATE_CMD_EXEC, 220 379 /** 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, 222 385 /** 32bit hack. */ 223 DEVTPM LOCALITYSTATE_32BIT_HACK = 0x7fffffff224 } DEVTPM LOCALITYSTATE;386 DEVTPMSTATE_32BIT_HACK = 0x7fffffff 387 } DEVTPMSTATE; 225 388 226 389 … … 230 393 typedef struct DEVTPMLOCALITY 231 394 { 232 /** The current state of the locality. */233 DEVTPMLOCALITYSTATE enmState;234 /** Access register state. */235 uint32_t uRegAccess;236 395 /** The interrupt enable register. */ 237 396 uint32_t uRegIntEn; … … 239 398 uint32_t uRegIntSts; 240 399 } DEVTPMLOCALITY; 400 /** Pointer to a locality state. */ 241 401 typedef DEVTPMLOCALITY *PDEVTPMLOCALITY; 402 /** Pointer to a const locality state. */ 242 403 typedef const DEVTPMLOCALITY *PCDEVTPMLOCALITY; 243 404 … … 248 409 typedef struct DEVTPM 249 410 { 411 /** Base MMIO address of the TPM device. */ 412 RTGCPHYS GCPhysMmio; 250 413 /** The handle of the MMIO region. */ 251 414 IOMMMIOHANDLE hMmio; 415 /** The handle for the ring-3 task. */ 416 PDMTASKHANDLE hTpmCmdTask; 252 417 /** The vendor ID configured. */ 253 418 uint16_t uVenId; … … 258 423 /** The IRQ value. */ 259 424 uint8_t uIrq; 425 /** Flag whether CRB access mode is used. */ 426 bool fCrb; 260 427 261 428 /** Currently selected locality. */ … … 263 430 /** States of the implemented localities. */ 264 431 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]; 266 441 } DEVTPM; 267 442 /** Pointer to the shared TPM device state. */ … … 277 452 typedef struct DEVTPMR3 278 453 { 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; 280 460 } DEVTPMR3; 281 461 /** Pointer to the TPM device state for ring-3. */ … … 288 468 typedef struct DEVTPMR0 289 469 { 290 uint 8_t bDummy;470 uint32_t u32Dummy; 291 471 } DEVTPMR0; 292 472 /** Pointer to the TPM device state for ring-0. */ … … 299 479 typedef struct DEVTPMRC 300 480 { 301 uint 8_t bDummy;481 uint32_t u32Dummy; 302 482 } DEVTPMRC; 303 483 /** Pointer to the TPM device state for raw-mode. */ … … 338 518 PDMBOTHCBDECL(void) tpmLocIrqUpdate(PPDMDEVINS pDevIns, PDEVTPM pThis, PDEVTPMLOCALITY pLoc) 339 519 { 340 if (pLoc->uRegIntEn & pLoc->uRegIntSts) 520 if ( (pLoc->uRegIntEn & TPM_CRB_LOCALITY_REG_INT_GLOBAL_ENABLE) 521 && (pLoc->uRegIntEn & pLoc->uRegIntSts)) 341 522 tpmIrqReq(pDevIns, pThis, 1); 342 523 else 343 524 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 */ 537 static 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 */ 551 static 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); 344 558 } 345 559 … … 369 583 370 584 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 */ 596 static 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); 385 600 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; 390 604 switch (uReg) 391 605 { 392 case TPM_ LOCALITY_REG_ACCESS:393 u 32= 0;394 break; 395 case TPM_ LOCALITY_REG_INT_ENABLE:396 u 32= pLoc->uRegIntEn;397 break; 398 case TPM_ LOCALITY_REG_INT_VEC:399 u 32= pThis->uIrq;400 break; 401 case TPM_ LOCALITY_REG_INT_STS:402 u 32= pLoc->uRegIntSts;403 break; 404 case TPM_ LOCALITY_REG_IF_CAP:405 u 32 = TPM_LOCALITY_REG_IF_CAP_INT_DATA_AVAIL406 | TPM_ LOCALITY_REG_IF_CAP_INT_STS_VALID407 | TPM_ LOCALITY_REG_IF_CAP_INT_LOCALITY_CHANGE408 | TPM_ LOCALITY_REG_IF_CAP_INT_LVL_LOW409 | TPM_ LOCALITY_REG_IF_CAP_INT_CMD_RDY410 | 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: 414 628 if (bLoc != pThis->bLoc) 415 629 { 416 u 32 = UINT32_MAX;630 u64 = UINT64_MAX; 417 631 break; 418 632 } 419 633 /** @todo */ 420 634 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: 423 637 /** @todo */ 424 638 break; 425 case TPM_ LOCALITY_REG_DID_VID:426 u 32= RT_H2BE_U32(RT_MAKE_U32(pThis->uVenId, pThis->uDevId));427 break; 428 case TPM_ LOCALITY_REG_RID:429 u 32= 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; 430 644 break; 431 645 default: /* Return ~0. */ 432 u 32 = UINT32_MAX;646 u64 = UINT64_MAX; 433 647 break; 434 648 } 435 649 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 443 652 444 653 return rc; … … 447 656 448 657 /** 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 */ 668 static 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); 468 672 469 673 VBOXSTRICTRC rc = VINF_SUCCESS; 470 uint32_t uReg = tpmGetRegisterFromOffset(off); 471 uint 8_t bLoc = tpmGetLocalityFromOffset(off);472 PDEVTPMLOCALITY pLoc = &pThis->aLoc[bLoc]; 674 #if 0 675 uint32_t u32 = (uint32_t)u64; 676 473 677 switch (uReg) 474 678 { 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; 477 681 /* 478 682 * Chapter 5.6.11, 2 states that writing to this register with more than one … … 484 688 /** @todo */ 485 689 break; 486 case TPM_ LOCALITY_REG_INT_ENABLE:690 case TPM_FIFO_LOCALITY_REG_INT_ENABLE: 487 691 if (bLoc != pThis->bLoc) 488 692 break; 489 693 /** @todo */ 490 694 break; 491 case TPM_ LOCALITY_REG_INT_STS:695 case TPM_FIFO_LOCALITY_REG_INT_STS: 492 696 if (bLoc != pThis->bLoc) 493 697 break; 494 pLoc->uRegSts &= ~(u32 & TPM_ LOCALITY_REG_INT_STS_WR_MASK);698 pLoc->uRegSts &= ~(u32 & TPM_FIFO_LOCALITY_REG_INT_STS_WR_MASK); 495 699 tpmLocIrqUpdate(pDevIns, pThis, pLoc); 496 700 break; 497 case TPM_ LOCALITY_REG_STS:701 case TPM_FIFO_LOCALITY_REG_STS: 498 702 /* 499 703 * Writes are ignored completely if the locality being accessed is not the … … 502 706 */ 503 707 if ( bLoc != pThis->bLoc 504 || !RT_IS_POWER_OF_TWO(u 32))708 || !RT_IS_POWER_OF_TWO(u64)) 505 709 break; 506 710 /** @todo */ 507 711 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: 510 714 if (bLoc != pThis->bLoc) 511 715 break; 512 716 /** @todo */ 513 717 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: 518 722 default: /* Ignore. */ 519 723 break; 520 724 } 521 725 #endif 522 726 return rc; 523 727 } 524 728 525 729 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 */ 742 static 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 */ 867 static 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 */ 999 static 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 */ 1038 static 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 526 1071 #ifdef IN_RING3 1072 1073 /** 1074 * @callback_method_impl{FNPDMTASKDEV, Execute a command in ring-3} 1075 */ 1076 static 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 } 527 1086 528 1087 … … 590 1149 591 1150 1151 /* -=-=-=-=-=-=-=-=- PDMIBASE -=-=-=-=-=-=-=-=- */ 1152 1153 /** 1154 * @interface_method_impl{PDMIBASE,pfnQueryInterface} 1155 */ 1156 static 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 592 1165 /* -=-=-=-=-=-=-=-=- PDMDEVREG -=-=-=-=-=-=-=-=- */ 593 1166 … … 597 1170 static DECLCALLBACK(void) tpmR3Reset(PPDMDEVINS pDevIns) 598 1171 { 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 602 1178 for (uint32_t i = 0; i < RT_ELEMENTS(pThis->aLoc); i++) 603 1179 { 604 1180 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; 609 1183 } 610 1184 } … … 632 1206 PDMDEV_CHECK_VERSIONS_RETURN(pDevIns); 633 1207 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); 635 1209 PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3; 636 1210 int rc; 637 1211 638 1212 RT_NOREF(iInstance); 1213 1214 pThis->hTpmCmdTask = NIL_PDMTASKHANDLE; 1215 1216 /* IBase */ 1217 pThisCC->IBase.pfnQueryInterface = tpmR3QueryInterface; 639 1218 640 1219 /* … … 645 1224 "|VendorId" 646 1225 "|DeviceId" 647 "|RevisionId", 1226 "|RevisionId" 1227 "|Crb", 648 1228 ""); 649 1229 650 uint8_t uIrq = 0; 651 rc = pHlp->pfnCFGMQueryU8Def(pCfg, "Irq", &uIrq, 10); 1230 rc = pHlp->pfnCFGMQueryU8Def(pCfg, "Irq", &pThis->uIrq, 10); 652 1231 if (RT_FAILURE(rc)) 653 1232 return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to get the \"Irq\" value")); 654 1233 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); 657 1235 if (RT_FAILURE(rc)) 658 1236 return PDMDEV_SET_ERROR(pDevIns, rc, … … 671 1249 return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to get the \"RevisionId\" value")); 672 1250 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")); 674 1254 675 1255 /* … … 677 1257 * addresses and sizes. 678 1258 */ 679 rc = PDMDevHlpMmioCreateAndMap(pDevIns, GCPhysMmio, TPM_MMIO_SIZE, tpmMmioWrite, tpmMmioRead,1259 rc = PDMDevHlpMmioCreateAndMap(pDevIns, pThis->GCPhysMmio, TPM_MMIO_SIZE, tpmMmioWrite, tpmMmioRead, 680 1260 IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU, 681 1261 "TPM MMIO", &pThis->hMmio); 682 1262 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); 683 1286 684 1287 /*
Note:
See TracChangeset
for help on using the changeset viewer.