Stefan Thom / SPITIS_TPM20
Committer:
LordOfDorks
Date:
Tue Apr 07 15:57:47 2015 +0000
Revision:
1:fd0a59e55a85
Parent:
0:b11c8971edd9
Child:
2:526bf792254d
Removed TIS based polling and added support for TPM PIRQ signal. Added a significant number of TPM specific structure definitions.

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