Stefan Thom / SPITIS_TPM20
Committer:
LordOfDorks
Date:
Tue Apr 07 19:13:09 2015 +0000
Revision:
2:526bf792254d
Parent:
1:fd0a59e55a85
Child:
3:4b9ad18eae02
Handle non-static burst count more better

Who changed what in which revision?

UserRevisionLine numberNew contents of line
LordOfDorks 1:fd0a59e55a85 1 /* mbed TCG SPI TPM 2.0 TIS 1.3 driver,
LordOfDorks 0:b11c8971edd9 2 * Copyright (c) 2015, Microsoft Coprporation Inc.
LordOfDorks 0:b11c8971edd9 3 * by Stefan Thom (LordOfDorks) StefanTh@Microsoft.com, Stefan@ThomsR.Us
LordOfDorks 0:b11c8971edd9 4 *
LordOfDorks 0:b11c8971edd9 5 * Permission is hereby granted, free of charge, to any person obtaining a copy
LordOfDorks 0:b11c8971edd9 6 * of this software and associated documentation files (the "Software"), to deal
LordOfDorks 0:b11c8971edd9 7 * in the Software without restriction, including without limitation the rights
LordOfDorks 0:b11c8971edd9 8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
LordOfDorks 0:b11c8971edd9 9 * copies of the Software, and to permit persons to whom the Software is
LordOfDorks 0:b11c8971edd9 10 * furnished to do so, subject to the following conditions:
LordOfDorks 0:b11c8971edd9 11 *
LordOfDorks 0:b11c8971edd9 12 * The above copyright notice and this permission notice shall be included in
LordOfDorks 0:b11c8971edd9 13 * all copies or substantial portions of the Software.
LordOfDorks 0:b11c8971edd9 14 *
LordOfDorks 0:b11c8971edd9 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
LordOfDorks 0:b11c8971edd9 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
LordOfDorks 0:b11c8971edd9 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
LordOfDorks 0:b11c8971edd9 18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LordOfDorks 0:b11c8971edd9 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
LordOfDorks 0:b11c8971edd9 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
LordOfDorks 0:b11c8971edd9 21 * THE SOFTWARE.
LordOfDorks 1:fd0a59e55a85 22 *
LordOfDorks 0:b11c8971edd9 23 */
LordOfDorks 1:fd0a59e55a85 24
LordOfDorks 1:fd0a59e55a85 25 #include "SPITIS_TPM20.h"
LordOfDorks 1:fd0a59e55a85 26 #include "TPM20Tables.h"
LordOfDorks 1:fd0a59e55a85 27
LordOfDorks 1:fd0a59e55a85 28 TIS_TPM20::TIS_RESULT
LordOfDorks 1:fd0a59e55a85 29 TIS_TPM20::InitializeTis()
LordOfDorks 0:b11c8971edd9 30 {
LordOfDorks 1:fd0a59e55a85 31 TIS_RESULT result = TIS_SESSION_RESULT_COMPLETE;
LordOfDorks 1:fd0a59e55a85 32 uint8_t dataRegister[sizeof(m_intfCabability)] = {0};
LordOfDorks 1:fd0a59e55a85 33
LordOfDorks 1:fd0a59e55a85 34 if(RequestLocality(TIS_LOCALITY_0) == false)
LordOfDorks 1:fd0a59e55a85 35 {
LordOfDorks 1:fd0a59e55a85 36 result = TIS_SESSION_RESULT_FAILED;
LordOfDorks 1:fd0a59e55a85 37 goto Cleanup;
LordOfDorks 1:fd0a59e55a85 38 }
LordOfDorks 1:fd0a59e55a85 39
LordOfDorks 1:fd0a59e55a85 40 // Read the TIS capabilities
LordOfDorks 1:fd0a59e55a85 41 if(ReadRegister(TIS_INTF_CAPABILITY_REGISTER, dataRegister, sizeof(dataRegister)) == false)
LordOfDorks 1:fd0a59e55a85 42 {
LordOfDorks 1:fd0a59e55a85 43 result = TIS_SESSION_RESULT_FAILED;
LordOfDorks 1:fd0a59e55a85 44 goto Cleanup;
LordOfDorks 1:fd0a59e55a85 45 }
LordOfDorks 1:fd0a59e55a85 46 m_intfCabability = LE_BYTEARRAY_TO_UINT32(dataRegister, 0);
LordOfDorks 1:fd0a59e55a85 47
LordOfDorks 0:b11c8971edd9 48 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 1:fd0a59e55a85 49 printf("TIS.InitializeTis.IntfCapability = 0x%08x\n\r", m_intfCabability);
LordOfDorks 0:b11c8971edd9 50 #endif
LordOfDorks 2:526bf792254d 51
LordOfDorks 2:526bf792254d 52 // Check mandatory 0 bits to see if we read a valid register
LordOfDorks 2:526bf792254d 53 if(m_intfCabability & 0x0FFFF800)
LordOfDorks 2:526bf792254d 54 {
LordOfDorks 2:526bf792254d 55 result = TIS_SESSION_RESULT_FAILED;
LordOfDorks 2:526bf792254d 56 goto Cleanup;
LordOfDorks 2:526bf792254d 57 }
LordOfDorks 1:fd0a59e55a85 58
LordOfDorks 1:fd0a59e55a85 59 // If the TIS interface has a fixed burst count use that number instead of asking the TPM over and over and save cycles
LordOfDorks 2:526bf792254d 60 m_fixedBurstCount = (m_intfCabability & TIS_INTF_CAPPABILITY_BURST_COUNT_STATIC);
LordOfDorks 0:b11c8971edd9 61 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 2:526bf792254d 62 printf("TIS.InitializeTis.FixedBurstCount = %s\n\r", m_fixedBurstCount ? "YES" : "NO");
LordOfDorks 0:b11c8971edd9 63 #endif
LordOfDorks 2:526bf792254d 64
LordOfDorks 2:526bf792254d 65 if((m_intfCabability & TIS_INTF_CAPPABILITY_DATA_TRANSFER_SIZE_SUPPORT_MASK) == TIS_INTF_CAPPABILITY_DATA_TRANSFER_SIZE_SUPPORT_8B)
LordOfDorks 2:526bf792254d 66 {
LordOfDorks 2:526bf792254d 67 m_maxBurstCount = 8;
LordOfDorks 1:fd0a59e55a85 68 }
LordOfDorks 2:526bf792254d 69 else if((m_intfCabability & TIS_INTF_CAPPABILITY_DATA_TRANSFER_SIZE_SUPPORT_MASK) == TIS_INTF_CAPPABILITY_DATA_TRANSFER_SIZE_SUPPORT_32B)
LordOfDorks 2:526bf792254d 70 {
LordOfDorks 2:526bf792254d 71 m_maxBurstCount = 32;
LordOfDorks 2:526bf792254d 72 }
LordOfDorks 2:526bf792254d 73 else if ((m_intfCabability & TIS_INTF_CAPPABILITY_DATA_TRANSFER_SIZE_SUPPORT_MASK) == TIS_INTF_CAPPABILITY_DATA_TRANSFER_SIZE_SUPPORT_64B)
LordOfDorks 2:526bf792254d 74 {
LordOfDorks 2:526bf792254d 75 m_maxBurstCount = 64;
LordOfDorks 2:526bf792254d 76 }
LordOfDorks 2:526bf792254d 77 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 2:526bf792254d 78 printf("TIS.InitializeTis.MaxBurstCount = %d\n\r", m_maxBurstCount);
LordOfDorks 2:526bf792254d 79 #endif
LordOfDorks 1:fd0a59e55a85 80
LordOfDorks 1:fd0a59e55a85 81 result = TIS_SESSION_RESULT_COMPLETE;
LordOfDorks 1:fd0a59e55a85 82
LordOfDorks 1:fd0a59e55a85 83 Cleanup:
LordOfDorks 1:fd0a59e55a85 84 ReleaseLocality();
LordOfDorks 1:fd0a59e55a85 85 return result;
LordOfDorks 0:b11c8971edd9 86 }
LordOfDorks 0:b11c8971edd9 87
LordOfDorks 1:fd0a59e55a85 88 #ifndef TPM_TPM_TIS_NO_COMMAND_FILTERING
LordOfDorks 1:fd0a59e55a85 89 TIS_TPM20::TIS_RESULT
LordOfDorks 1:fd0a59e55a85 90 TIS_TPM20::ApplyFilter(TIS_TPM20::TIS_LOCALITY locality, uint8_t* pbCmd, uint32_t cbCmd)
LordOfDorks 0:b11c8971edd9 91 {
LordOfDorks 1:fd0a59e55a85 92 uint32_t cursor = sizeof(uint16_t) + sizeof(uint32_t);
LordOfDorks 1:fd0a59e55a85 93 uint32_t ordinal = BE_BYTEARRAY_TO_UINT32(pbCmd, cursor);
LordOfDorks 1:fd0a59e55a85 94 int32_t handleCount = -1;
LordOfDorks 1:fd0a59e55a85 95
LordOfDorks 1:fd0a59e55a85 96 // First filter ordinals based on locality
LordOfDorks 1:fd0a59e55a85 97 if(locality == TIS_LOCALITY_0)
LordOfDorks 1:fd0a59e55a85 98 {
LordOfDorks 1:fd0a59e55a85 99 switch(ordinal)
LordOfDorks 1:fd0a59e55a85 100 {
LordOfDorks 1:fd0a59e55a85 101 // We will not allow certain from locality 0 - aka the external TPM channel
LordOfDorks 1:fd0a59e55a85 102 case TPM_CC_ChangeEPS:
LordOfDorks 1:fd0a59e55a85 103 case TPM_CC_ChangePPS:
LordOfDorks 1:fd0a59e55a85 104 case TPM_CC_Clear:
LordOfDorks 1:fd0a59e55a85 105 case TPM_CC_ClearControl:
LordOfDorks 1:fd0a59e55a85 106 case TPM_CC_ClockSet:
LordOfDorks 1:fd0a59e55a85 107 case TPM_CC_PCR_Allocate:
LordOfDorks 1:fd0a59e55a85 108 case TPM_CC_PCR_SetAuthPolicy:
LordOfDorks 1:fd0a59e55a85 109 case TPM_CC_Shutdown:
LordOfDorks 1:fd0a59e55a85 110 return TIS_SESSION_RESULT_FILTERED;
LordOfDorks 1:fd0a59e55a85 111 default:
LordOfDorks 1:fd0a59e55a85 112 break;
LordOfDorks 1:fd0a59e55a85 113 }
LordOfDorks 1:fd0a59e55a85 114 }
LordOfDorks 1:fd0a59e55a85 115
LordOfDorks 1:fd0a59e55a85 116 // Move on the and lets look at the handle filter
LordOfDorks 1:fd0a59e55a85 117 cursor += sizeof(ordinal);
LordOfDorks 1:fd0a59e55a85 118
LordOfDorks 1:fd0a59e55a85 119 // Lookup the number of handles in the command
LordOfDorks 1:fd0a59e55a85 120 for(uint32_t n = 0; s_ccAttr[n].commandIndex != 0x0000 ;n++)
LordOfDorks 1:fd0a59e55a85 121 {
LordOfDorks 1:fd0a59e55a85 122 if(s_ccAttr[n].commandIndex == ordinal)
LordOfDorks 1:fd0a59e55a85 123 {
LordOfDorks 1:fd0a59e55a85 124 handleCount = s_ccAttr[n].cHandles;
LordOfDorks 1:fd0a59e55a85 125 break;
LordOfDorks 1:fd0a59e55a85 126 }
LordOfDorks 1:fd0a59e55a85 127 }
LordOfDorks 1:fd0a59e55a85 128
LordOfDorks 1:fd0a59e55a85 129 // Easy elimination of invalid cases
LordOfDorks 1:fd0a59e55a85 130 if((handleCount < 0) || (handleCount > 3) ||
LordOfDorks 1:fd0a59e55a85 131 (cbCmd < (cursor + (sizeof(uint32_t) * handleCount))))
LordOfDorks 1:fd0a59e55a85 132 {
LordOfDorks 1:fd0a59e55a85 133 return TIS_SESSION_RESULT_FILTERED;
LordOfDorks 1:fd0a59e55a85 134 }
LordOfDorks 1:fd0a59e55a85 135
LordOfDorks 1:fd0a59e55a85 136 // Read the handles from the command and see if they are allowed
LordOfDorks 1:fd0a59e55a85 137 for(uint32_t n = 0 ;n < handleCount; n++)
LordOfDorks 0:b11c8971edd9 138 {
LordOfDorks 1:fd0a59e55a85 139 uint32_t objectHandle = BE_BYTEARRAY_TO_UINT32(pbCmd, cursor);
LordOfDorks 1:fd0a59e55a85 140 cursor += sizeof(objectHandle);
LordOfDorks 1:fd0a59e55a85 141
LordOfDorks 1:fd0a59e55a85 142 if(locality == TIS_LOCALITY_0)
LordOfDorks 1:fd0a59e55a85 143 {
LordOfDorks 1:fd0a59e55a85 144 switch(objectHandle)
LordOfDorks 1:fd0a59e55a85 145 {
LordOfDorks 1:fd0a59e55a85 146 // We will not allow the platform entity to be used from locality 0
LordOfDorks 1:fd0a59e55a85 147 case TPM_RH_PLATFORM:
LordOfDorks 1:fd0a59e55a85 148 return TIS_SESSION_RESULT_FILTERED;
LordOfDorks 1:fd0a59e55a85 149 default:
LordOfDorks 1:fd0a59e55a85 150 break;
LordOfDorks 1:fd0a59e55a85 151 }
LordOfDorks 1:fd0a59e55a85 152 }
LordOfDorks 0:b11c8971edd9 153 }
LordOfDorks 1:fd0a59e55a85 154
LordOfDorks 1:fd0a59e55a85 155 return TIS_SESSION_RESULT_COMPLETE;
LordOfDorks 1:fd0a59e55a85 156 }
LordOfDorks 1:fd0a59e55a85 157 #endif
LordOfDorks 1:fd0a59e55a85 158
LordOfDorks 1:fd0a59e55a85 159 TIS_TPM20::TIS_RESULT
LordOfDorks 1:fd0a59e55a85 160 TIS_TPM20::SendCommand(
LordOfDorks 1:fd0a59e55a85 161 uint8_t* pbCmd,
LordOfDorks 1:fd0a59e55a85 162 uint32_t cbCmd,
LordOfDorks 1:fd0a59e55a85 163 TIS_TPM20::TIS_LOCALITY locality)
LordOfDorks 1:fd0a59e55a85 164 {
LordOfDorks 1:fd0a59e55a85 165 TIS_RESULT result = TIS_SESSION_RESULT_COMPLETE;
LordOfDorks 1:fd0a59e55a85 166 uint8_t tisStatus = 0;
LordOfDorks 1:fd0a59e55a85 167 uint16_t burstCount = 0;
LordOfDorks 1:fd0a59e55a85 168 uint32_t index = 0;
LordOfDorks 1:fd0a59e55a85 169
LordOfDorks 1:fd0a59e55a85 170 // Is the driver busy?
LordOfDorks 1:fd0a59e55a85 171 if(m_locality != TIS_NOT_IN_USE)
LordOfDorks 0:b11c8971edd9 172 {
LordOfDorks 1:fd0a59e55a85 173 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 1:fd0a59e55a85 174 printf("TIS.Schedule: TIS busy at locality %d\n\r", m_locality);
LordOfDorks 1:fd0a59e55a85 175 #endif
LordOfDorks 1:fd0a59e55a85 176 // Can we preemt?
LordOfDorks 1:fd0a59e55a85 177 if(m_locality < locality)
LordOfDorks 1:fd0a59e55a85 178 {
LordOfDorks 1:fd0a59e55a85 179 result = TIS_SESSION_RESULT_OCCUPIED;
LordOfDorks 1:fd0a59e55a85 180 goto Cleanup;
LordOfDorks 1:fd0a59e55a85 181 }
LordOfDorks 1:fd0a59e55a85 182 else
LordOfDorks 1:fd0a59e55a85 183 {
LordOfDorks 1:fd0a59e55a85 184 result = TIS_SESSION_RESULT_PREEMPTED;
LordOfDorks 1:fd0a59e55a85 185 goto Cleanup;
LordOfDorks 1:fd0a59e55a85 186 }
LordOfDorks 1:fd0a59e55a85 187 }
LordOfDorks 1:fd0a59e55a85 188
LordOfDorks 1:fd0a59e55a85 189 #ifndef TPM_TIS_NO_COMMAND_FILTERING
LordOfDorks 1:fd0a59e55a85 190 // Apply command filtering
LordOfDorks 1:fd0a59e55a85 191 if(ApplyFilter(locality, pbCmd, cbCmd) == TIS_SESSION_RESULT_FILTERED)
LordOfDorks 1:fd0a59e55a85 192 {
LordOfDorks 1:fd0a59e55a85 193 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 1:fd0a59e55a85 194 printf("TIS.Schedule: Command filtered\n\r");
LordOfDorks 1:fd0a59e55a85 195 #endif
LordOfDorks 1:fd0a59e55a85 196 result = TIS_SESSION_RESULT_FILTERED;
LordOfDorks 1:fd0a59e55a85 197 goto Cleanup;
LordOfDorks 1:fd0a59e55a85 198 }
LordOfDorks 1:fd0a59e55a85 199 #endif
LordOfDorks 1:fd0a59e55a85 200
LordOfDorks 1:fd0a59e55a85 201 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 1:fd0a59e55a85 202 printf("TIS.Command: ");
LordOfDorks 1:fd0a59e55a85 203 for(uint32_t n = 0; n < cbCmd; n++) printf("%02x ", pbCmd[n]);
LordOfDorks 1:fd0a59e55a85 204 printf("\n\r");
LordOfDorks 1:fd0a59e55a85 205 #endif
LordOfDorks 1:fd0a59e55a85 206
LordOfDorks 1:fd0a59e55a85 207 // Assert the locality
LordOfDorks 1:fd0a59e55a85 208
LordOfDorks 1:fd0a59e55a85 209 if(!RequestLocality(locality))
LordOfDorks 1:fd0a59e55a85 210 {
LordOfDorks 1:fd0a59e55a85 211 result = TIS_SESSION_RESULT_FAILED;
LordOfDorks 1:fd0a59e55a85 212 goto Cleanup;
LordOfDorks 1:fd0a59e55a85 213 }
LordOfDorks 1:fd0a59e55a85 214
LordOfDorks 1:fd0a59e55a85 215 // Make sure the TPM is ready for a command
LordOfDorks 1:fd0a59e55a85 216 if(!ReadRegister(TIS_STS_REGISTER, &tisStatus, sizeof(tisStatus)))
LordOfDorks 1:fd0a59e55a85 217 {
LordOfDorks 1:fd0a59e55a85 218 result = TIS_SESSION_RESULT_FAILED;
LordOfDorks 1:fd0a59e55a85 219 goto Cleanup;
LordOfDorks 1:fd0a59e55a85 220 }
LordOfDorks 1:fd0a59e55a85 221
LordOfDorks 1:fd0a59e55a85 222 // Get TPM ready
LordOfDorks 1:fd0a59e55a85 223 if((tisStatus & TIS_STS_COMMAND_READY) == 0)
LordOfDorks 1:fd0a59e55a85 224 {
LordOfDorks 1:fd0a59e55a85 225 if(!AbortCommand())
LordOfDorks 1:fd0a59e55a85 226 {
LordOfDorks 1:fd0a59e55a85 227 result = TIS_SESSION_RESULT_FAILED;
LordOfDorks 1:fd0a59e55a85 228 goto Cleanup;
LordOfDorks 1:fd0a59e55a85 229 }
LordOfDorks 0:b11c8971edd9 230 }
LordOfDorks 0:b11c8971edd9 231 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 1:fd0a59e55a85 232 printf("TIS.ReadyForCommand\n\r");
LordOfDorks 1:fd0a59e55a85 233 #endif
LordOfDorks 1:fd0a59e55a85 234
LordOfDorks 1:fd0a59e55a85 235 // Submit Command
LordOfDorks 1:fd0a59e55a85 236 do
LordOfDorks 1:fd0a59e55a85 237 {
LordOfDorks 1:fd0a59e55a85 238 uint16_t iteration = 0;
LordOfDorks 1:fd0a59e55a85 239
LordOfDorks 1:fd0a59e55a85 240 if((burstCount = GetBurstCount()) == 0)
LordOfDorks 1:fd0a59e55a85 241 {
LordOfDorks 1:fd0a59e55a85 242 result = TIS_SESSION_RESULT_FAILED;
LordOfDorks 1:fd0a59e55a85 243 goto Cleanup;
LordOfDorks 1:fd0a59e55a85 244 }
LordOfDorks 1:fd0a59e55a85 245
LordOfDorks 1:fd0a59e55a85 246 // Assemble the buffer for transmission
LordOfDorks 1:fd0a59e55a85 247 iteration = min((cbCmd - index), min(burstCount, TIS_MAX_HW_FRAME_SIZE));
LordOfDorks 1:fd0a59e55a85 248 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 1:fd0a59e55a85 249 printf("TIS.SendingBurst = %d\r\n", iteration);
LordOfDorks 0:b11c8971edd9 250 #endif
LordOfDorks 1:fd0a59e55a85 251 if(!WriteRegister(TIS_DATA_FIFO, &pbCmd[index], iteration))
LordOfDorks 1:fd0a59e55a85 252 {
LordOfDorks 1:fd0a59e55a85 253 result = TIS_SESSION_RESULT_FAILED;
LordOfDorks 1:fd0a59e55a85 254 goto Cleanup;
LordOfDorks 1:fd0a59e55a85 255 }
LordOfDorks 1:fd0a59e55a85 256
LordOfDorks 1:fd0a59e55a85 257 // Update the index
LordOfDorks 1:fd0a59e55a85 258 index += iteration;
LordOfDorks 1:fd0a59e55a85 259 } while((cbCmd - index) > 0);
LordOfDorks 1:fd0a59e55a85 260
LordOfDorks 1:fd0a59e55a85 261 // Command complete?
LordOfDorks 1:fd0a59e55a85 262 if((!ReadRegister(TIS_STS_REGISTER, &tisStatus, sizeof(tisStatus))) ||
LordOfDorks 1:fd0a59e55a85 263 (!(tisStatus & TIS_STS_VALID) || (tisStatus & TIS_STS_DATA_EXPECT)))
LordOfDorks 1:fd0a59e55a85 264 {
LordOfDorks 1:fd0a59e55a85 265 result = TIS_SESSION_RESULT_FAILED;
LordOfDorks 1:fd0a59e55a85 266 goto Cleanup;
LordOfDorks 1:fd0a59e55a85 267 }
LordOfDorks 1:fd0a59e55a85 268 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 1:fd0a59e55a85 269 printf("TIS.CommandComplete\n\r");
LordOfDorks 1:fd0a59e55a85 270 #endif
LordOfDorks 1:fd0a59e55a85 271
LordOfDorks 1:fd0a59e55a85 272 // Arm the Interrupt
LordOfDorks 1:fd0a59e55a85 273 if(!TpmInteruptOn(TIS_INT_ENABLE_DATA_AVAILABLE_INT_ENABLE))
LordOfDorks 1:fd0a59e55a85 274 {
LordOfDorks 1:fd0a59e55a85 275 goto Cleanup;
LordOfDorks 1:fd0a59e55a85 276 }
LordOfDorks 1:fd0a59e55a85 277
LordOfDorks 1:fd0a59e55a85 278 // Kick the command off
LordOfDorks 1:fd0a59e55a85 279 tisStatus = TIS_STS_GO;
LordOfDorks 1:fd0a59e55a85 280 if(!WriteRegister(TIS_STS_REGISTER, &tisStatus, sizeof(tisStatus)))
LordOfDorks 1:fd0a59e55a85 281 {
LordOfDorks 1:fd0a59e55a85 282 result = TIS_SESSION_RESULT_FAILED;
LordOfDorks 1:fd0a59e55a85 283 goto Cleanup;
LordOfDorks 1:fd0a59e55a85 284 }
LordOfDorks 1:fd0a59e55a85 285
LordOfDorks 1:fd0a59e55a85 286 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 1:fd0a59e55a85 287 printf("TIS.Go.");
LordOfDorks 1:fd0a59e55a85 288 #endif
LordOfDorks 1:fd0a59e55a85 289
LordOfDorks 1:fd0a59e55a85 290 result = TIS_SESSION_RESULT_COMPLETE;
LordOfDorks 1:fd0a59e55a85 291
LordOfDorks 1:fd0a59e55a85 292 Cleanup:
LordOfDorks 1:fd0a59e55a85 293 if(result != TIS_SESSION_RESULT_COMPLETE)
LordOfDorks 1:fd0a59e55a85 294 {
LordOfDorks 1:fd0a59e55a85 295 AbortCommand();
LordOfDorks 1:fd0a59e55a85 296 }
LordOfDorks 1:fd0a59e55a85 297 return result;
LordOfDorks 0:b11c8971edd9 298 }
LordOfDorks 0:b11c8971edd9 299
LordOfDorks 1:fd0a59e55a85 300 TIS_TPM20::TIS_RESULT
LordOfDorks 1:fd0a59e55a85 301 TIS_TPM20::RetrieveResponse(
LordOfDorks 0:b11c8971edd9 302 uint8_t* pbRsp,
LordOfDorks 0:b11c8971edd9 303 uint32_t cbRsp,
LordOfDorks 1:fd0a59e55a85 304 uint32_t* pcbRsp
LordOfDorks 0:b11c8971edd9 305 )
LordOfDorks 0:b11c8971edd9 306 {
LordOfDorks 1:fd0a59e55a85 307 TIS_RESULT result = TIS_SESSION_RESULT_COMPLETE;
LordOfDorks 1:fd0a59e55a85 308 uint8_t tisStatus = 0;
LordOfDorks 1:fd0a59e55a85 309 uint16_t burstCount = 0;
LordOfDorks 1:fd0a59e55a85 310 uint32_t index = 0;
LordOfDorks 1:fd0a59e55a85 311 uint32_t rspSize = 0;
LordOfDorks 0:b11c8971edd9 312
LordOfDorks 1:fd0a59e55a85 313 if(m_interrupt != 0)
LordOfDorks 0:b11c8971edd9 314 {
LordOfDorks 0:b11c8971edd9 315 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 316 printf(".");
LordOfDorks 0:b11c8971edd9 317 #endif
LordOfDorks 1:fd0a59e55a85 318 result = TIS_SESSION_RESULT_PENDING;
LordOfDorks 1:fd0a59e55a85 319 return result;
LordOfDorks 0:b11c8971edd9 320 }
LordOfDorks 0:b11c8971edd9 321 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 1:fd0a59e55a85 322 printf("IRQ!\r\n");
LordOfDorks 0:b11c8971edd9 323 #endif
LordOfDorks 0:b11c8971edd9 324
LordOfDorks 1:fd0a59e55a85 325 // Disarm the Interrupt
LordOfDorks 1:fd0a59e55a85 326 if(!TpmInteruptOn(0))
LordOfDorks 0:b11c8971edd9 327 {
LordOfDorks 0:b11c8971edd9 328 goto Cleanup;
LordOfDorks 0:b11c8971edd9 329 }
LordOfDorks 0:b11c8971edd9 330
LordOfDorks 1:fd0a59e55a85 331 if((!ReadRegister(TIS_STS_REGISTER, &tisStatus, sizeof(tisStatus))) ||
LordOfDorks 1:fd0a59e55a85 332 (!(tisStatus & TIS_STS_VALID) || !(tisStatus & TIS_STS_DATA_AVAIL)))
LordOfDorks 1:fd0a59e55a85 333 {
LordOfDorks 1:fd0a59e55a85 334 result = TIS_SESSION_RESULT_FAILED;
LordOfDorks 1:fd0a59e55a85 335 goto Cleanup;
LordOfDorks 1:fd0a59e55a85 336 }
LordOfDorks 1:fd0a59e55a85 337 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 1:fd0a59e55a85 338 printf("TIS.DataAvailable\r\n");
LordOfDorks 1:fd0a59e55a85 339 #endif
LordOfDorks 1:fd0a59e55a85 340
LordOfDorks 1:fd0a59e55a85 341 // Get the response header from the TPM
LordOfDorks 1:fd0a59e55a85 342 if(((burstCount = GetBurstCount()) == 0) ||
LordOfDorks 1:fd0a59e55a85 343 (burstCount < (sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint32_t))) ||
LordOfDorks 1:fd0a59e55a85 344 (!ReadRegister(TIS_DATA_FIFO, &pbRsp[index], (sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint32_t)))))
LordOfDorks 1:fd0a59e55a85 345 {
LordOfDorks 1:fd0a59e55a85 346 result = TIS_SESSION_RESULT_FAILED;
LordOfDorks 1:fd0a59e55a85 347 goto Cleanup;
LordOfDorks 1:fd0a59e55a85 348 }
LordOfDorks 1:fd0a59e55a85 349 index += (sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint32_t));
LordOfDorks 1:fd0a59e55a85 350 rspSize = BE_BYTEARRAY_TO_UINT32(pbRsp, sizeof(uint16_t));
LordOfDorks 1:fd0a59e55a85 351 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 1:fd0a59e55a85 352 printf("Tis.ResponseSize = %d\r\n", rspSize);
LordOfDorks 1:fd0a59e55a85 353 #endif
LordOfDorks 1:fd0a59e55a85 354
LordOfDorks 1:fd0a59e55a85 355 if(min(rspSize, cbRsp) > index)
LordOfDorks 1:fd0a59e55a85 356 {
LordOfDorks 1:fd0a59e55a85 357 do
LordOfDorks 1:fd0a59e55a85 358 {
LordOfDorks 1:fd0a59e55a85 359 uint16_t iteration = 0;
LordOfDorks 1:fd0a59e55a85 360
LordOfDorks 1:fd0a59e55a85 361 // Check to make sure the TPM has still data for us
LordOfDorks 1:fd0a59e55a85 362 if((!ReadRegister(TIS_STS_REGISTER, &tisStatus, sizeof(tisStatus))) ||
LordOfDorks 1:fd0a59e55a85 363 (!(tisStatus & TIS_STS_VALID) || !(tisStatus & TIS_STS_DATA_AVAIL)) ||
LordOfDorks 1:fd0a59e55a85 364 ((burstCount = GetBurstCount()) == 0))
LordOfDorks 1:fd0a59e55a85 365 {
LordOfDorks 1:fd0a59e55a85 366 result = TIS_SESSION_RESULT_FAILED;
LordOfDorks 1:fd0a59e55a85 367 goto Cleanup;
LordOfDorks 1:fd0a59e55a85 368 }
LordOfDorks 1:fd0a59e55a85 369 iteration = min((rspSize - index), min((cbRsp - index), min(burstCount, TIS_MAX_HW_FRAME_SIZE)));
LordOfDorks 1:fd0a59e55a85 370 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 1:fd0a59e55a85 371 printf("TIS.ReceivingBurst = %d\r\n", iteration);
LordOfDorks 1:fd0a59e55a85 372 #endif
LordOfDorks 1:fd0a59e55a85 373
LordOfDorks 1:fd0a59e55a85 374 // Read the data for this iteration
LordOfDorks 1:fd0a59e55a85 375 if(!ReadRegister(TIS_DATA_FIFO, &pbRsp[index], iteration))
LordOfDorks 1:fd0a59e55a85 376 {
LordOfDorks 1:fd0a59e55a85 377 goto Cleanup;
LordOfDorks 1:fd0a59e55a85 378 }
LordOfDorks 1:fd0a59e55a85 379 index += iteration;
LordOfDorks 1:fd0a59e55a85 380 }
LordOfDorks 1:fd0a59e55a85 381 while(index < min(rspSize, cbRsp));
LordOfDorks 1:fd0a59e55a85 382 }
LordOfDorks 1:fd0a59e55a85 383
LordOfDorks 1:fd0a59e55a85 384 *pcbRsp = index;
LordOfDorks 1:fd0a59e55a85 385
LordOfDorks 0:b11c8971edd9 386 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 0:b11c8971edd9 387 printf("TIS.Response: ");
LordOfDorks 1:fd0a59e55a85 388 for(uint32_t n = 0; n < *pcbRsp; n++) printf("%02x ", pbRsp[n]);
LordOfDorks 0:b11c8971edd9 389 printf("\n\r");
LordOfDorks 0:b11c8971edd9 390 #endif
LordOfDorks 0:b11c8971edd9 391
LordOfDorks 1:fd0a59e55a85 392 result = TIS_SESSION_RESULT_COMPLETE;
LordOfDorks 0:b11c8971edd9 393
LordOfDorks 0:b11c8971edd9 394 Cleanup:
LordOfDorks 1:fd0a59e55a85 395 if((result != TIS_SESSION_RESULT_COMPLETE) && (result != TIS_SESSION_RESULT_PENDING))
LordOfDorks 1:fd0a59e55a85 396 {
LordOfDorks 1:fd0a59e55a85 397 AbortCommand();
LordOfDorks 1:fd0a59e55a85 398 }
LordOfDorks 1:fd0a59e55a85 399 // Release the locality again
LordOfDorks 1:fd0a59e55a85 400 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 1:fd0a59e55a85 401 printf("TIS.ReleaseLocality\r\n");
LordOfDorks 1:fd0a59e55a85 402 #endif
LordOfDorks 1:fd0a59e55a85 403 ReleaseLocality();
LordOfDorks 0:b11c8971edd9 404 return result;
LordOfDorks 0:b11c8971edd9 405 }
LordOfDorks 0:b11c8971edd9 406
LordOfDorks 0:b11c8971edd9 407 uint32_t
LordOfDorks 1:fd0a59e55a85 408 TIS_TPM20::ParseResponseHeader(uint8_t* pbRsp, uint32_t cbRsp, uint16_t* rspTag, uint32_t* rspSize)
LordOfDorks 0:b11c8971edd9 409 {
LordOfDorks 0:b11c8971edd9 410 uint32_t rspResponseCode = 0;
LordOfDorks 1:fd0a59e55a85 411 uint32_t cursor = 0;
LordOfDorks 0:b11c8971edd9 412
LordOfDorks 0:b11c8971edd9 413 // Check that the response header is well formatted
LordOfDorks 1:fd0a59e55a85 414 if(cbRsp < (sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint32_t)))
LordOfDorks 0:b11c8971edd9 415 {
LordOfDorks 0:b11c8971edd9 416 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 1:fd0a59e55a85 417 printf("TIS.ResponseHdr: Too short = 0x%08x\n\r", cbRsp);
LordOfDorks 0:b11c8971edd9 418 #endif
LordOfDorks 0:b11c8971edd9 419 rspResponseCode = TPM_RC_FAILURE;
LordOfDorks 0:b11c8971edd9 420 goto Cleanup;
LordOfDorks 0:b11c8971edd9 421 }
LordOfDorks 1:fd0a59e55a85 422
LordOfDorks 0:b11c8971edd9 423 // Read the header components
LordOfDorks 1:fd0a59e55a85 424 *rspTag = BE_BYTEARRAY_TO_UINT16(pbRsp, cursor);
LordOfDorks 1:fd0a59e55a85 425 cursor += sizeof(*rspTag);
LordOfDorks 1:fd0a59e55a85 426 *rspSize = BE_BYTEARRAY_TO_UINT32(pbRsp, cursor);
LordOfDorks 1:fd0a59e55a85 427 cursor += sizeof(*rspSize);
LordOfDorks 1:fd0a59e55a85 428 rspResponseCode = BE_BYTEARRAY_TO_UINT32(pbRsp, cursor);
LordOfDorks 1:fd0a59e55a85 429 cursor += sizeof(rspResponseCode);
LordOfDorks 0:b11c8971edd9 430
LordOfDorks 0:b11c8971edd9 431 // Check the components
LordOfDorks 0:b11c8971edd9 432 if(((*rspTag != TPM_ST_NO_SESSIONS) && (*rspTag != TPM_ST_SESSIONS)) ||
LordOfDorks 1:fd0a59e55a85 433 (*rspSize != cbRsp))
LordOfDorks 0:b11c8971edd9 434 {
LordOfDorks 0:b11c8971edd9 435 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 1:fd0a59e55a85 436 printf("TIS.ResponseHdr: Tag=0x%04x, Len=0x%08x, RC=0x%08x\n\r", *rspTag, *rspSize, rspResponseCode);
LordOfDorks 0:b11c8971edd9 437 #endif
LordOfDorks 0:b11c8971edd9 438 rspResponseCode = TPM_RC_FAILURE;
LordOfDorks 0:b11c8971edd9 439 goto Cleanup;
LordOfDorks 0:b11c8971edd9 440 }
LordOfDorks 0:b11c8971edd9 441
LordOfDorks 0:b11c8971edd9 442 Cleanup:
LordOfDorks 0:b11c8971edd9 443 return rspResponseCode;
LordOfDorks 0:b11c8971edd9 444 }
LordOfDorks 0:b11c8971edd9 445
LordOfDorks 0:b11c8971edd9 446 bool
LordOfDorks 1:fd0a59e55a85 447 TIS_TPM20::FullDuplex(
LordOfDorks 0:b11c8971edd9 448 bool readCycle,
LordOfDorks 1:fd0a59e55a85 449 uint16_t reg,
LordOfDorks 0:b11c8971edd9 450 uint8_t* pbBuffer,
LordOfDorks 0:b11c8971edd9 451 uint16_t cbBuffer
LordOfDorks 0:b11c8971edd9 452 )
LordOfDorks 0:b11c8971edd9 453 {
LordOfDorks 0:b11c8971edd9 454 bool result = false;
LordOfDorks 0:b11c8971edd9 455 uint8_t dataByteIn;
LordOfDorks 0:b11c8971edd9 456 uint8_t dataByteOut;
LordOfDorks 0:b11c8971edd9 457
LordOfDorks 0:b11c8971edd9 458 // Lock the bus for this operation
LordOfDorks 1:fd0a59e55a85 459 m_chipSelect = 0;
LordOfDorks 0:b11c8971edd9 460
LordOfDorks 0:b11c8971edd9 461 // Send the TIS header
LordOfDorks 1:fd0a59e55a85 462 uint32_t tisHdr = TIS_HEADER(m_locality, readCycle, reg, cbBuffer);
LordOfDorks 1:fd0a59e55a85 463 #ifdef TPM_TIS_INTERFACE_DEBUG_OUTPUT
LordOfDorks 1:fd0a59e55a85 464 printf("TIS(LC:%d,RG:%02x,SZ:%02x,%s):", m_locality, reg, cbBuffer, (readCycle) ? "RD" : "WR");
LordOfDorks 0:b11c8971edd9 465 #endif
LordOfDorks 0:b11c8971edd9 466
LordOfDorks 0:b11c8971edd9 467 for(uint8_t n = 0; n < sizeof(tisHdr); n++)
LordOfDorks 0:b11c8971edd9 468 {
LordOfDorks 1:fd0a59e55a85 469 dataByteOut = tisHdr >> (8 * (3 - n));
LordOfDorks 1:fd0a59e55a85 470 dataByteIn = m_spi.write(dataByteOut);
LordOfDorks 1:fd0a59e55a85 471 //#ifdef TPM_TIS_INTERFACE_DEBUG_OUTPUT
LordOfDorks 1:fd0a59e55a85 472 // if(n < (sizeof(tisHdr) - 1)) printf("%02x ", dataByteOut);
LordOfDorks 1:fd0a59e55a85 473 // else printf("%02x", dataByteOut);
LordOfDorks 1:fd0a59e55a85 474 //#endif
LordOfDorks 0:b11c8971edd9 475 }
LordOfDorks 1:fd0a59e55a85 476
LordOfDorks 1:fd0a59e55a85 477 // The last bit we read full duplex is the first wait state indicator
LordOfDorks 1:fd0a59e55a85 478 int16_t waitCycleRetry = 100;
LordOfDorks 1:fd0a59e55a85 479 while(!(dataByteIn & 0x01))
LordOfDorks 0:b11c8971edd9 480 {
LordOfDorks 1:fd0a59e55a85 481 #ifdef TPM_TIS_INTERFACE_DEBUG_OUTPUT
LordOfDorks 1:fd0a59e55a85 482 printf(".");
LordOfDorks 0:b11c8971edd9 483 #endif
LordOfDorks 1:fd0a59e55a85 484 // Read the next byte to see is we still have to wait
LordOfDorks 1:fd0a59e55a85 485 if((dataByteIn = m_spi.write(0x00)) == 0x01)
LordOfDorks 0:b11c8971edd9 486 {
LordOfDorks 0:b11c8971edd9 487 break;
LordOfDorks 0:b11c8971edd9 488 }
LordOfDorks 0:b11c8971edd9 489
LordOfDorks 1:fd0a59e55a85 490 // Check the timeout
LordOfDorks 1:fd0a59e55a85 491 if(waitCycleRetry-- <= 0)
LordOfDorks 0:b11c8971edd9 492 {
LordOfDorks 1:fd0a59e55a85 493 result = false;
LordOfDorks 1:fd0a59e55a85 494 goto Cleanup;
LordOfDorks 0:b11c8971edd9 495 }
LordOfDorks 0:b11c8971edd9 496 }
LordOfDorks 1:fd0a59e55a85 497
LordOfDorks 1:fd0a59e55a85 498 // Full duplex the payload
LordOfDorks 1:fd0a59e55a85 499 for(uint8_t n = 0; n < cbBuffer; n++)
LordOfDorks 1:fd0a59e55a85 500 {
LordOfDorks 1:fd0a59e55a85 501 dataByteOut = (readCycle) ? 0x00 : pbBuffer[n];
LordOfDorks 1:fd0a59e55a85 502 dataByteIn = m_spi.write(dataByteOut);
LordOfDorks 1:fd0a59e55a85 503 if(readCycle) pbBuffer[n] = dataByteIn;
LordOfDorks 1:fd0a59e55a85 504 #ifdef TPM_TIS_INTERFACE_DEBUG_OUTPUT
LordOfDorks 1:fd0a59e55a85 505 printf("%02x ", (readCycle) ? dataByteIn : dataByteOut);
LordOfDorks 1:fd0a59e55a85 506 #endif
LordOfDorks 1:fd0a59e55a85 507 }
LordOfDorks 1:fd0a59e55a85 508 result = true;
LordOfDorks 1:fd0a59e55a85 509
LordOfDorks 1:fd0a59e55a85 510 Cleanup:
LordOfDorks 1:fd0a59e55a85 511 #ifdef TPM_TIS_INTERFACE_DEBUG_OUTPUT
LordOfDorks 1:fd0a59e55a85 512 printf("\r\n");
LordOfDorks 1:fd0a59e55a85 513 #endif
LordOfDorks 1:fd0a59e55a85 514 // Make sure to release the bus before we leave
LordOfDorks 1:fd0a59e55a85 515 m_chipSelect = 1;
LordOfDorks 1:fd0a59e55a85 516 return result;
LordOfDorks 0:b11c8971edd9 517 }
LordOfDorks 0:b11c8971edd9 518
LordOfDorks 1:fd0a59e55a85 519 uint16_t
LordOfDorks 1:fd0a59e55a85 520 TIS_TPM20::GetBurstCount()
LordOfDorks 0:b11c8971edd9 521 {
LordOfDorks 2:526bf792254d 522 if(m_fixedBurstCount)
LordOfDorks 0:b11c8971edd9 523 {
LordOfDorks 2:526bf792254d 524 return m_maxBurstCount;
LordOfDorks 1:fd0a59e55a85 525 }
LordOfDorks 1:fd0a59e55a85 526 else
LordOfDorks 1:fd0a59e55a85 527 {
LordOfDorks 2:526bf792254d 528 uint16_t burstCount = 0;
LordOfDorks 1:fd0a59e55a85 529 uint8_t dataBytes[sizeof(uint16_t)] = {0};
LordOfDorks 1:fd0a59e55a85 530 if(!ReadRegister(TIS_STS_BURSTCOUNT_REGISTER, dataBytes, sizeof(dataBytes)))
LordOfDorks 0:b11c8971edd9 531 {
LordOfDorks 1:fd0a59e55a85 532 return 0;
LordOfDorks 0:b11c8971edd9 533 }
LordOfDorks 2:526bf792254d 534 burstCount = min(LE_BYTEARRAY_TO_UINT16(dataBytes , 0), m_maxBurstCount);
LordOfDorks 1:fd0a59e55a85 535 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 2:526bf792254d 536 printf("TIS.BurstCount = %d\r\n", burstCount);
LordOfDorks 1:fd0a59e55a85 537 #endif
LordOfDorks 2:526bf792254d 538 return burstCount;
LordOfDorks 0:b11c8971edd9 539 }
LordOfDorks 0:b11c8971edd9 540 }
LordOfDorks 0:b11c8971edd9 541
LordOfDorks 0:b11c8971edd9 542 bool
LordOfDorks 1:fd0a59e55a85 543 TIS_TPM20::RequestLocality(TIS_TPM20::TIS_LOCALITY locality)
LordOfDorks 0:b11c8971edd9 544 {
LordOfDorks 1:fd0a59e55a85 545 m_locality = locality;
LordOfDorks 1:fd0a59e55a85 546
LordOfDorks 1:fd0a59e55a85 547 for(uint8_t n = 0; n < 100; n++)
LordOfDorks 0:b11c8971edd9 548 {
LordOfDorks 1:fd0a59e55a85 549 uint8_t dataByte = 0;
LordOfDorks 1:fd0a59e55a85 550 // Read a valid access register. Turns out, it may take a couple of times if the TPM was sleeping
LordOfDorks 1:fd0a59e55a85 551 do
LordOfDorks 0:b11c8971edd9 552 {
LordOfDorks 1:fd0a59e55a85 553 dataByte = 0;
LordOfDorks 1:fd0a59e55a85 554 if(!ReadRegister(TIS_ACCESS_REGISTER, &dataByte, sizeof(dataByte)))
LordOfDorks 1:fd0a59e55a85 555 {
LordOfDorks 1:fd0a59e55a85 556 goto Cleanup;
LordOfDorks 1:fd0a59e55a85 557 }
LordOfDorks 1:fd0a59e55a85 558
LordOfDorks 1:fd0a59e55a85 559 // First time we hit that, the TPM has to wake up give it some time
LordOfDorks 1:fd0a59e55a85 560 if(!(dataByte & TIS_ACCESS_VALID))
LordOfDorks 1:fd0a59e55a85 561 {
LordOfDorks 1:fd0a59e55a85 562 wait_us(5000);
LordOfDorks 1:fd0a59e55a85 563 }
LordOfDorks 0:b11c8971edd9 564 }
LordOfDorks 1:fd0a59e55a85 565 while(!(dataByte & TIS_ACCESS_VALID));
LordOfDorks 1:fd0a59e55a85 566
LordOfDorks 1:fd0a59e55a85 567 // If we have the locality we are done
LordOfDorks 1:fd0a59e55a85 568 if(dataByte & TIS_ACCESS_ACTIVE_LOCALITY)
LordOfDorks 0:b11c8971edd9 569 {
LordOfDorks 1:fd0a59e55a85 570 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 1:fd0a59e55a85 571 printf("TIS.LocalityAquired\n\r");
LordOfDorks 1:fd0a59e55a85 572 #endif
LordOfDorks 1:fd0a59e55a85 573 return true;
LordOfDorks 0:b11c8971edd9 574 }
LordOfDorks 0:b11c8971edd9 575
LordOfDorks 1:fd0a59e55a85 576 // Request the locality
LordOfDorks 1:fd0a59e55a85 577 dataByte = TIS_ACCESS_REQUEST_USE;
LordOfDorks 1:fd0a59e55a85 578 if(!WriteRegister(TIS_ACCESS_REGISTER, &dataByte, sizeof(dataByte)))
LordOfDorks 1:fd0a59e55a85 579 {
LordOfDorks 1:fd0a59e55a85 580 goto Cleanup;
LordOfDorks 1:fd0a59e55a85 581 }
LordOfDorks 1:fd0a59e55a85 582 }
LordOfDorks 1:fd0a59e55a85 583
LordOfDorks 1:fd0a59e55a85 584 m_locality = TIS_NOT_IN_USE;
LordOfDorks 1:fd0a59e55a85 585 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 1:fd0a59e55a85 586 printf("TIS.LocalityRequest = FAILED\n\r");
LordOfDorks 1:fd0a59e55a85 587 #endif
LordOfDorks 1:fd0a59e55a85 588 Cleanup:
LordOfDorks 1:fd0a59e55a85 589 return false;
LordOfDorks 0:b11c8971edd9 590 }
LordOfDorks 0:b11c8971edd9 591
LordOfDorks 0:b11c8971edd9 592 bool
LordOfDorks 1:fd0a59e55a85 593 TIS_TPM20::ReleaseLocality()
LordOfDorks 0:b11c8971edd9 594 {
LordOfDorks 1:fd0a59e55a85 595 for(uint8_t n = 0; n < 100; n++)
LordOfDorks 1:fd0a59e55a85 596 {
LordOfDorks 1:fd0a59e55a85 597 uint8_t dataByte = 0;
LordOfDorks 1:fd0a59e55a85 598 // Read a valid access register. Turns out, it may take a couple of times if the TPM was sleeping
LordOfDorks 1:fd0a59e55a85 599 do
LordOfDorks 1:fd0a59e55a85 600 {
LordOfDorks 1:fd0a59e55a85 601 if(!ReadRegister(TIS_ACCESS_REGISTER, &dataByte, sizeof(dataByte)))
LordOfDorks 1:fd0a59e55a85 602 {
LordOfDorks 1:fd0a59e55a85 603 break;
LordOfDorks 1:fd0a59e55a85 604 }
LordOfDorks 1:fd0a59e55a85 605
LordOfDorks 1:fd0a59e55a85 606 // First time we hit that, the TPM has to wake up give it some time
LordOfDorks 1:fd0a59e55a85 607 if(!(dataByte & TIS_ACCESS_VALID))
LordOfDorks 1:fd0a59e55a85 608 {
LordOfDorks 1:fd0a59e55a85 609 wait_us(5000);
LordOfDorks 1:fd0a59e55a85 610 }
LordOfDorks 1:fd0a59e55a85 611 }
LordOfDorks 1:fd0a59e55a85 612 while(!(dataByte & TIS_ACCESS_VALID));
LordOfDorks 0:b11c8971edd9 613
LordOfDorks 1:fd0a59e55a85 614 // If we don't have the locality we are done
LordOfDorks 1:fd0a59e55a85 615 if(!(dataByte & TIS_ACCESS_ACTIVE_LOCALITY))
LordOfDorks 0:b11c8971edd9 616 {
LordOfDorks 1:fd0a59e55a85 617 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 1:fd0a59e55a85 618 printf("TIS.LocalityReleased\n\r");
LordOfDorks 1:fd0a59e55a85 619 #endif
LordOfDorks 1:fd0a59e55a85 620 m_locality = TIS_NOT_IN_USE;
LordOfDorks 1:fd0a59e55a85 621 return true;
LordOfDorks 0:b11c8971edd9 622 }
LordOfDorks 1:fd0a59e55a85 623
LordOfDorks 1:fd0a59e55a85 624 // Drop the locality
LordOfDorks 1:fd0a59e55a85 625 dataByte = TIS_ACCESS_ACTIVE_LOCALITY;
LordOfDorks 1:fd0a59e55a85 626 if(!WriteRegister(TIS_ACCESS_REGISTER, &dataByte, sizeof(dataByte)))
LordOfDorks 0:b11c8971edd9 627 {
LordOfDorks 0:b11c8971edd9 628 break;
LordOfDorks 0:b11c8971edd9 629 }
LordOfDorks 0:b11c8971edd9 630 }
LordOfDorks 1:fd0a59e55a85 631 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 1:fd0a59e55a85 632 printf("TIS.LocalityReleased = FAILED\n\r");
LordOfDorks 1:fd0a59e55a85 633 #endif
LordOfDorks 0:b11c8971edd9 634
LordOfDorks 1:fd0a59e55a85 635 return false;
LordOfDorks 0:b11c8971edd9 636 }
LordOfDorks 0:b11c8971edd9 637
LordOfDorks 0:b11c8971edd9 638 bool
LordOfDorks 1:fd0a59e55a85 639 TIS_TPM20::TpmInteruptOn(uint32_t intEnable)
LordOfDorks 0:b11c8971edd9 640 {
LordOfDorks 1:fd0a59e55a85 641 uint32_t int_enable = TIS_INT_ENABLE_TYPE_POLARITY_LOW;
LordOfDorks 1:fd0a59e55a85 642 uint8_t dataRegister[sizeof(uint32_t)] = {0};
LordOfDorks 1:fd0a59e55a85 643 uint8_t dataByte = 0;
LordOfDorks 1:fd0a59e55a85 644
LordOfDorks 1:fd0a59e55a85 645 if(intEnable != 0)
LordOfDorks 1:fd0a59e55a85 646 {
LordOfDorks 1:fd0a59e55a85 647 int_enable |= (uint32_t)TIS_INT_ENABLE_GLOBAL_INT_ENABLE | intEnable;
LordOfDorks 1:fd0a59e55a85 648 }
LordOfDorks 1:fd0a59e55a85 649
LordOfDorks 1:fd0a59e55a85 650 // Read the Interrupt state
LordOfDorks 1:fd0a59e55a85 651 ReadRegister(TIS_INT_STATUS_REGISTER, &dataByte, sizeof(dataByte));
LordOfDorks 1:fd0a59e55a85 652
LordOfDorks 1:fd0a59e55a85 653 dataByte = TIS_INT_STATUS_RESET_ALL;
LordOfDorks 1:fd0a59e55a85 654 LE_UINT32_TO_BYTEARRAY(int_enable, dataRegister, 0);
LordOfDorks 1:fd0a59e55a85 655 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 1:fd0a59e55a85 656 printf("TIS.ArmTpmInterupt = 0x%08x\n\r", intEnable);
LordOfDorks 1:fd0a59e55a85 657 #endif
LordOfDorks 1:fd0a59e55a85 658 return ((WriteRegister(TIS_INT_STATUS_REGISTER, &dataByte, sizeof(dataByte))) &&
LordOfDorks 1:fd0a59e55a85 659 (WriteRegister(TIS_INT_ENABLE_REGISTER, dataRegister, sizeof(dataRegister))));
LordOfDorks 0:b11c8971edd9 660 }
LordOfDorks 0:b11c8971edd9 661
LordOfDorks 0:b11c8971edd9 662 bool
LordOfDorks 1:fd0a59e55a85 663 TIS_TPM20::AbortCommand()
LordOfDorks 0:b11c8971edd9 664 {
LordOfDorks 1:fd0a59e55a85 665 uint8_t tisStatus = TIS_STS_COMMAND_READY;
LordOfDorks 1:fd0a59e55a85 666 #ifdef TPM_TIS_DEBUG_OUTPUT
LordOfDorks 1:fd0a59e55a85 667 printf("TIS.AbortCommand\n\r");
LordOfDorks 1:fd0a59e55a85 668 #endif
LordOfDorks 1:fd0a59e55a85 669 return((WriteRegister(TIS_STS_REGISTER, &tisStatus, sizeof(tisStatus))) &&
LordOfDorks 1:fd0a59e55a85 670 (ReadRegister(TIS_STS_REGISTER, &tisStatus, sizeof(tisStatus))) &&
LordOfDorks 1:fd0a59e55a85 671 ((tisStatus & TIS_STS_COMMAND_READY) != 0));
LordOfDorks 1:fd0a59e55a85 672 }