Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
SPITIS_TPM20.cpp@3:4b9ad18eae02, 2015-04-11 (annotated)
- Committer:
- LordOfDorks
- Date:
- Sat Apr 11 04:01:54 2015 +0000
- Revision:
- 3:4b9ad18eae02
- Parent:
- 2:526bf792254d
Added TPM marshal library to make working with TPM structures easy.
Who changed what in which revision?
User | Revision | Line number | New 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 | |
LordOfDorks | 1:fd0a59e55a85 | 27 | TIS_TPM20::TIS_RESULT |
LordOfDorks | 1:fd0a59e55a85 | 28 | TIS_TPM20::InitializeTis() |
LordOfDorks | 0:b11c8971edd9 | 29 | { |
LordOfDorks | 1:fd0a59e55a85 | 30 | TIS_RESULT result = TIS_SESSION_RESULT_COMPLETE; |
LordOfDorks | 1:fd0a59e55a85 | 31 | uint8_t dataRegister[sizeof(m_intfCabability)] = {0}; |
LordOfDorks | 1:fd0a59e55a85 | 32 | |
LordOfDorks | 1:fd0a59e55a85 | 33 | if(RequestLocality(TIS_LOCALITY_0) == false) |
LordOfDorks | 1:fd0a59e55a85 | 34 | { |
LordOfDorks | 1:fd0a59e55a85 | 35 | result = TIS_SESSION_RESULT_FAILED; |
LordOfDorks | 1:fd0a59e55a85 | 36 | goto Cleanup; |
LordOfDorks | 1:fd0a59e55a85 | 37 | } |
LordOfDorks | 1:fd0a59e55a85 | 38 | |
LordOfDorks | 1:fd0a59e55a85 | 39 | // Read the TIS capabilities |
LordOfDorks | 1:fd0a59e55a85 | 40 | if(ReadRegister(TIS_INTF_CAPABILITY_REGISTER, dataRegister, sizeof(dataRegister)) == false) |
LordOfDorks | 1:fd0a59e55a85 | 41 | { |
LordOfDorks | 1:fd0a59e55a85 | 42 | result = TIS_SESSION_RESULT_FAILED; |
LordOfDorks | 1:fd0a59e55a85 | 43 | goto Cleanup; |
LordOfDorks | 1:fd0a59e55a85 | 44 | } |
LordOfDorks | 3:4b9ad18eae02 | 45 | m_intfCabability = BYTE_ARRAY_TO_LEUINT32(dataRegister); |
LordOfDorks | 1:fd0a59e55a85 | 46 | |
LordOfDorks | 0:b11c8971edd9 | 47 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 1:fd0a59e55a85 | 48 | printf("TIS.InitializeTis.IntfCapability = 0x%08x\n\r", m_intfCabability); |
LordOfDorks | 0:b11c8971edd9 | 49 | #endif |
LordOfDorks | 2:526bf792254d | 50 | |
LordOfDorks | 2:526bf792254d | 51 | // Check mandatory 0 bits to see if we read a valid register |
LordOfDorks | 2:526bf792254d | 52 | if(m_intfCabability & 0x0FFFF800) |
LordOfDorks | 2:526bf792254d | 53 | { |
LordOfDorks | 2:526bf792254d | 54 | result = TIS_SESSION_RESULT_FAILED; |
LordOfDorks | 2:526bf792254d | 55 | goto Cleanup; |
LordOfDorks | 2:526bf792254d | 56 | } |
LordOfDorks | 1:fd0a59e55a85 | 57 | |
LordOfDorks | 1:fd0a59e55a85 | 58 | // 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 | 59 | m_fixedBurstCount = (m_intfCabability & TIS_INTF_CAPPABILITY_BURST_COUNT_STATIC); |
LordOfDorks | 0:b11c8971edd9 | 60 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 2:526bf792254d | 61 | printf("TIS.InitializeTis.FixedBurstCount = %s\n\r", m_fixedBurstCount ? "YES" : "NO"); |
LordOfDorks | 0:b11c8971edd9 | 62 | #endif |
LordOfDorks | 2:526bf792254d | 63 | |
LordOfDorks | 2:526bf792254d | 64 | if((m_intfCabability & TIS_INTF_CAPPABILITY_DATA_TRANSFER_SIZE_SUPPORT_MASK) == TIS_INTF_CAPPABILITY_DATA_TRANSFER_SIZE_SUPPORT_8B) |
LordOfDorks | 2:526bf792254d | 65 | { |
LordOfDorks | 2:526bf792254d | 66 | m_maxBurstCount = 8; |
LordOfDorks | 1:fd0a59e55a85 | 67 | } |
LordOfDorks | 2:526bf792254d | 68 | else if((m_intfCabability & TIS_INTF_CAPPABILITY_DATA_TRANSFER_SIZE_SUPPORT_MASK) == TIS_INTF_CAPPABILITY_DATA_TRANSFER_SIZE_SUPPORT_32B) |
LordOfDorks | 2:526bf792254d | 69 | { |
LordOfDorks | 2:526bf792254d | 70 | m_maxBurstCount = 32; |
LordOfDorks | 2:526bf792254d | 71 | } |
LordOfDorks | 2:526bf792254d | 72 | else if ((m_intfCabability & TIS_INTF_CAPPABILITY_DATA_TRANSFER_SIZE_SUPPORT_MASK) == TIS_INTF_CAPPABILITY_DATA_TRANSFER_SIZE_SUPPORT_64B) |
LordOfDorks | 2:526bf792254d | 73 | { |
LordOfDorks | 2:526bf792254d | 74 | m_maxBurstCount = 64; |
LordOfDorks | 2:526bf792254d | 75 | } |
LordOfDorks | 2:526bf792254d | 76 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 2:526bf792254d | 77 | printf("TIS.InitializeTis.MaxBurstCount = %d\n\r", m_maxBurstCount); |
LordOfDorks | 2:526bf792254d | 78 | #endif |
LordOfDorks | 1:fd0a59e55a85 | 79 | |
LordOfDorks | 1:fd0a59e55a85 | 80 | result = TIS_SESSION_RESULT_COMPLETE; |
LordOfDorks | 1:fd0a59e55a85 | 81 | |
LordOfDorks | 1:fd0a59e55a85 | 82 | Cleanup: |
LordOfDorks | 1:fd0a59e55a85 | 83 | ReleaseLocality(); |
LordOfDorks | 1:fd0a59e55a85 | 84 | return result; |
LordOfDorks | 0:b11c8971edd9 | 85 | } |
LordOfDorks | 0:b11c8971edd9 | 86 | |
LordOfDorks | 1:fd0a59e55a85 | 87 | TIS_TPM20::TIS_RESULT |
LordOfDorks | 3:4b9ad18eae02 | 88 | TIS_TPM20::StartSession( |
LordOfDorks | 3:4b9ad18eae02 | 89 | TIS_TPM20::TIS_LOCALITY locality |
LordOfDorks | 3:4b9ad18eae02 | 90 | ) |
LordOfDorks | 1:fd0a59e55a85 | 91 | { |
LordOfDorks | 1:fd0a59e55a85 | 92 | TIS_RESULT result = TIS_SESSION_RESULT_COMPLETE; |
LordOfDorks | 1:fd0a59e55a85 | 93 | |
LordOfDorks | 1:fd0a59e55a85 | 94 | // Is the driver busy? |
LordOfDorks | 1:fd0a59e55a85 | 95 | if(m_locality != TIS_NOT_IN_USE) |
LordOfDorks | 0:b11c8971edd9 | 96 | { |
LordOfDorks | 1:fd0a59e55a85 | 97 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 1:fd0a59e55a85 | 98 | printf("TIS.Schedule: TIS busy at locality %d\n\r", m_locality); |
LordOfDorks | 1:fd0a59e55a85 | 99 | #endif |
LordOfDorks | 1:fd0a59e55a85 | 100 | // Can we preemt? |
LordOfDorks | 1:fd0a59e55a85 | 101 | if(m_locality < locality) |
LordOfDorks | 1:fd0a59e55a85 | 102 | { |
LordOfDorks | 1:fd0a59e55a85 | 103 | result = TIS_SESSION_RESULT_OCCUPIED; |
LordOfDorks | 1:fd0a59e55a85 | 104 | goto Cleanup; |
LordOfDorks | 1:fd0a59e55a85 | 105 | } |
LordOfDorks | 1:fd0a59e55a85 | 106 | else |
LordOfDorks | 1:fd0a59e55a85 | 107 | { |
LordOfDorks | 1:fd0a59e55a85 | 108 | result = TIS_SESSION_RESULT_PREEMPTED; |
LordOfDorks | 1:fd0a59e55a85 | 109 | goto Cleanup; |
LordOfDorks | 1:fd0a59e55a85 | 110 | } |
LordOfDorks | 1:fd0a59e55a85 | 111 | } |
LordOfDorks | 1:fd0a59e55a85 | 112 | |
LordOfDorks | 3:4b9ad18eae02 | 113 | // Request the locality |
LordOfDorks | 3:4b9ad18eae02 | 114 | if(!RequestLocality(locality)) |
LordOfDorks | 3:4b9ad18eae02 | 115 | { |
LordOfDorks | 3:4b9ad18eae02 | 116 | result = TIS_SESSION_RESULT_FAILED; |
LordOfDorks | 3:4b9ad18eae02 | 117 | goto Cleanup; |
LordOfDorks | 3:4b9ad18eae02 | 118 | } |
LordOfDorks | 3:4b9ad18eae02 | 119 | |
LordOfDorks | 3:4b9ad18eae02 | 120 | Cleanup: |
LordOfDorks | 3:4b9ad18eae02 | 121 | return result; |
LordOfDorks | 3:4b9ad18eae02 | 122 | } |
LordOfDorks | 3:4b9ad18eae02 | 123 | |
LordOfDorks | 3:4b9ad18eae02 | 124 | TIS_TPM20::TIS_RESULT |
LordOfDorks | 3:4b9ad18eae02 | 125 | TIS_TPM20::EndSession() |
LordOfDorks | 3:4b9ad18eae02 | 126 | { |
LordOfDorks | 3:4b9ad18eae02 | 127 | if(m_locality != TIS_NOT_IN_USE) |
LordOfDorks | 3:4b9ad18eae02 | 128 | { |
LordOfDorks | 3:4b9ad18eae02 | 129 | // Release the locality again |
LordOfDorks | 3:4b9ad18eae02 | 130 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 3:4b9ad18eae02 | 131 | printf("TIS.ReleaseLocality\r\n"); |
LordOfDorks | 3:4b9ad18eae02 | 132 | #endif |
LordOfDorks | 3:4b9ad18eae02 | 133 | if(!ReleaseLocality()) |
LordOfDorks | 3:4b9ad18eae02 | 134 | { |
LordOfDorks | 3:4b9ad18eae02 | 135 | return TIS_SESSION_RESULT_FAILED; |
LordOfDorks | 3:4b9ad18eae02 | 136 | } |
LordOfDorks | 3:4b9ad18eae02 | 137 | } |
LordOfDorks | 3:4b9ad18eae02 | 138 | return TIS_SESSION_RESULT_COMPLETE; |
LordOfDorks | 3:4b9ad18eae02 | 139 | } |
LordOfDorks | 3:4b9ad18eae02 | 140 | |
LordOfDorks | 3:4b9ad18eae02 | 141 | TIS_TPM20::TIS_RESULT |
LordOfDorks | 3:4b9ad18eae02 | 142 | TIS_TPM20::AbortCommand() |
LordOfDorks | 3:4b9ad18eae02 | 143 | { |
LordOfDorks | 3:4b9ad18eae02 | 144 | TIS_RESULT result = TIS_SESSION_RESULT_COMPLETE; |
LordOfDorks | 3:4b9ad18eae02 | 145 | uint8_t tisStatus = TIS_STS_COMMAND_READY; |
LordOfDorks | 3:4b9ad18eae02 | 146 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 3:4b9ad18eae02 | 147 | printf("TIS.AbortCommand\n\r"); |
LordOfDorks | 3:4b9ad18eae02 | 148 | #endif |
LordOfDorks | 3:4b9ad18eae02 | 149 | if((!WriteRegister(TIS_STS_REGISTER, &tisStatus, sizeof(tisStatus))) || |
LordOfDorks | 3:4b9ad18eae02 | 150 | (!ReadRegister(TIS_STS_REGISTER, &tisStatus, sizeof(tisStatus))) || |
LordOfDorks | 3:4b9ad18eae02 | 151 | ((tisStatus & TIS_STS_COMMAND_READY) == 0)) |
LordOfDorks | 3:4b9ad18eae02 | 152 | { |
LordOfDorks | 3:4b9ad18eae02 | 153 | result = TIS_SESSION_RESULT_FAILED; |
LordOfDorks | 3:4b9ad18eae02 | 154 | } |
LordOfDorks | 3:4b9ad18eae02 | 155 | return result; |
LordOfDorks | 3:4b9ad18eae02 | 156 | } |
LordOfDorks | 3:4b9ad18eae02 | 157 | |
LordOfDorks | 3:4b9ad18eae02 | 158 | TIS_TPM20::TIS_RESULT |
LordOfDorks | 3:4b9ad18eae02 | 159 | TIS_TPM20::SendCommand( |
LordOfDorks | 3:4b9ad18eae02 | 160 | uint8_t* pbCmd, |
LordOfDorks | 3:4b9ad18eae02 | 161 | uint32_t cbCmd, |
LordOfDorks | 3:4b9ad18eae02 | 162 | uint8_t* pbTrailingData, |
LordOfDorks | 3:4b9ad18eae02 | 163 | uint32_t cbTrailingData) |
LordOfDorks | 3:4b9ad18eae02 | 164 | { |
LordOfDorks | 3:4b9ad18eae02 | 165 | TIS_RESULT result = TIS_SESSION_RESULT_COMPLETE; |
LordOfDorks | 3:4b9ad18eae02 | 166 | uint8_t tisStatus = 0; |
LordOfDorks | 3:4b9ad18eae02 | 167 | uint16_t burstCount = 0; |
LordOfDorks | 3:4b9ad18eae02 | 168 | uint32_t index = 0; |
LordOfDorks | 3:4b9ad18eae02 | 169 | |
LordOfDorks | 3:4b9ad18eae02 | 170 | // In all TPM, a buffer size of 1,024 octets is allowed. |
LordOfDorks | 3:4b9ad18eae02 | 171 | if(cbTrailingData > 1024) |
LordOfDorks | 3:4b9ad18eae02 | 172 | { |
LordOfDorks | 3:4b9ad18eae02 | 173 | result = TIS_SESSION_RESULT_FAILED; |
LordOfDorks | 3:4b9ad18eae02 | 174 | goto Cleanup; |
LordOfDorks | 3:4b9ad18eae02 | 175 | } |
LordOfDorks | 3:4b9ad18eae02 | 176 | |
LordOfDorks | 1:fd0a59e55a85 | 177 | #ifndef TPM_TIS_NO_COMMAND_FILTERING |
LordOfDorks | 1:fd0a59e55a85 | 178 | // Apply command filtering |
LordOfDorks | 3:4b9ad18eae02 | 179 | if(ApplyFilter(m_locality, pbCmd, cbCmd) == TIS_SESSION_RESULT_FILTERED) |
LordOfDorks | 1:fd0a59e55a85 | 180 | { |
LordOfDorks | 1:fd0a59e55a85 | 181 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 1:fd0a59e55a85 | 182 | printf("TIS.Schedule: Command filtered\n\r"); |
LordOfDorks | 1:fd0a59e55a85 | 183 | #endif |
LordOfDorks | 1:fd0a59e55a85 | 184 | result = TIS_SESSION_RESULT_FILTERED; |
LordOfDorks | 1:fd0a59e55a85 | 185 | goto Cleanup; |
LordOfDorks | 1:fd0a59e55a85 | 186 | } |
LordOfDorks | 1:fd0a59e55a85 | 187 | #endif |
LordOfDorks | 1:fd0a59e55a85 | 188 | |
LordOfDorks | 1:fd0a59e55a85 | 189 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 1:fd0a59e55a85 | 190 | printf("TIS.Command: "); |
LordOfDorks | 1:fd0a59e55a85 | 191 | for(uint32_t n = 0; n < cbCmd; n++) printf("%02x ", pbCmd[n]); |
LordOfDorks | 1:fd0a59e55a85 | 192 | printf("\n\r"); |
LordOfDorks | 1:fd0a59e55a85 | 193 | #endif |
LordOfDorks | 1:fd0a59e55a85 | 194 | |
LordOfDorks | 3:4b9ad18eae02 | 195 | // Make sure the TPM is ready for a command |
LordOfDorks | 3:4b9ad18eae02 | 196 | do |
LordOfDorks | 1:fd0a59e55a85 | 197 | { |
LordOfDorks | 3:4b9ad18eae02 | 198 | tisStatus = TIS_STS_COMMAND_READY; |
LordOfDorks | 3:4b9ad18eae02 | 199 | if(!WriteRegister(TIS_STS_REGISTER, &tisStatus, sizeof(tisStatus))) |
LordOfDorks | 3:4b9ad18eae02 | 200 | { |
LordOfDorks | 3:4b9ad18eae02 | 201 | result = TIS_SESSION_RESULT_FAILED; |
LordOfDorks | 3:4b9ad18eae02 | 202 | goto Cleanup; |
LordOfDorks | 3:4b9ad18eae02 | 203 | } |
LordOfDorks | 3:4b9ad18eae02 | 204 | if(!ReadRegister(TIS_STS_REGISTER, &tisStatus, sizeof(tisStatus))) |
LordOfDorks | 1:fd0a59e55a85 | 205 | { |
LordOfDorks | 1:fd0a59e55a85 | 206 | result = TIS_SESSION_RESULT_FAILED; |
LordOfDorks | 1:fd0a59e55a85 | 207 | goto Cleanup; |
LordOfDorks | 1:fd0a59e55a85 | 208 | } |
LordOfDorks | 0:b11c8971edd9 | 209 | } |
LordOfDorks | 3:4b9ad18eae02 | 210 | while((tisStatus & TIS_STS_COMMAND_READY) == 0); |
LordOfDorks | 3:4b9ad18eae02 | 211 | |
LordOfDorks | 0:b11c8971edd9 | 212 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 1:fd0a59e55a85 | 213 | printf("TIS.ReadyForCommand\n\r"); |
LordOfDorks | 1:fd0a59e55a85 | 214 | #endif |
LordOfDorks | 1:fd0a59e55a85 | 215 | |
LordOfDorks | 1:fd0a59e55a85 | 216 | // Submit Command |
LordOfDorks | 1:fd0a59e55a85 | 217 | do |
LordOfDorks | 1:fd0a59e55a85 | 218 | { |
LordOfDorks | 1:fd0a59e55a85 | 219 | uint16_t iteration = 0; |
LordOfDorks | 1:fd0a59e55a85 | 220 | |
LordOfDorks | 1:fd0a59e55a85 | 221 | if((burstCount = GetBurstCount()) == 0) |
LordOfDorks | 1:fd0a59e55a85 | 222 | { |
LordOfDorks | 1:fd0a59e55a85 | 223 | result = TIS_SESSION_RESULT_FAILED; |
LordOfDorks | 1:fd0a59e55a85 | 224 | goto Cleanup; |
LordOfDorks | 1:fd0a59e55a85 | 225 | } |
LordOfDorks | 1:fd0a59e55a85 | 226 | |
LordOfDorks | 1:fd0a59e55a85 | 227 | // Assemble the buffer for transmission |
LordOfDorks | 1:fd0a59e55a85 | 228 | iteration = min((cbCmd - index), min(burstCount, TIS_MAX_HW_FRAME_SIZE)); |
LordOfDorks | 1:fd0a59e55a85 | 229 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 1:fd0a59e55a85 | 230 | printf("TIS.SendingBurst = %d\r\n", iteration); |
LordOfDorks | 0:b11c8971edd9 | 231 | #endif |
LordOfDorks | 1:fd0a59e55a85 | 232 | if(!WriteRegister(TIS_DATA_FIFO, &pbCmd[index], iteration)) |
LordOfDorks | 1:fd0a59e55a85 | 233 | { |
LordOfDorks | 1:fd0a59e55a85 | 234 | result = TIS_SESSION_RESULT_FAILED; |
LordOfDorks | 1:fd0a59e55a85 | 235 | goto Cleanup; |
LordOfDorks | 1:fd0a59e55a85 | 236 | } |
LordOfDorks | 1:fd0a59e55a85 | 237 | |
LordOfDorks | 1:fd0a59e55a85 | 238 | // Update the index |
LordOfDorks | 1:fd0a59e55a85 | 239 | index += iteration; |
LordOfDorks | 1:fd0a59e55a85 | 240 | } while((cbCmd - index) > 0); |
LordOfDorks | 1:fd0a59e55a85 | 241 | |
LordOfDorks | 3:4b9ad18eae02 | 242 | // Submit trailing data if there is any |
LordOfDorks | 3:4b9ad18eae02 | 243 | if((pbTrailingData != NULL) && (cbTrailingData != 0)) |
LordOfDorks | 3:4b9ad18eae02 | 244 | { |
LordOfDorks | 3:4b9ad18eae02 | 245 | index = 0; |
LordOfDorks | 3:4b9ad18eae02 | 246 | do |
LordOfDorks | 3:4b9ad18eae02 | 247 | { |
LordOfDorks | 3:4b9ad18eae02 | 248 | uint16_t iteration = 0; |
LordOfDorks | 3:4b9ad18eae02 | 249 | |
LordOfDorks | 3:4b9ad18eae02 | 250 | if((burstCount = GetBurstCount()) == 0) |
LordOfDorks | 3:4b9ad18eae02 | 251 | { |
LordOfDorks | 3:4b9ad18eae02 | 252 | result = TIS_SESSION_RESULT_FAILED; |
LordOfDorks | 3:4b9ad18eae02 | 253 | goto Cleanup; |
LordOfDorks | 3:4b9ad18eae02 | 254 | } |
LordOfDorks | 3:4b9ad18eae02 | 255 | |
LordOfDorks | 3:4b9ad18eae02 | 256 | // Assemble the buffer for transmission |
LordOfDorks | 3:4b9ad18eae02 | 257 | iteration = min((cbTrailingData - index), min(burstCount, TIS_MAX_HW_FRAME_SIZE)); |
LordOfDorks | 3:4b9ad18eae02 | 258 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 3:4b9ad18eae02 | 259 | printf("TIS.SendingBurst = %d\r\n", iteration); |
LordOfDorks | 3:4b9ad18eae02 | 260 | #endif |
LordOfDorks | 3:4b9ad18eae02 | 261 | if(!WriteRegister(TIS_DATA_FIFO, &pbTrailingData[index], iteration)) |
LordOfDorks | 3:4b9ad18eae02 | 262 | { |
LordOfDorks | 3:4b9ad18eae02 | 263 | result = TIS_SESSION_RESULT_FAILED; |
LordOfDorks | 3:4b9ad18eae02 | 264 | goto Cleanup; |
LordOfDorks | 3:4b9ad18eae02 | 265 | } |
LordOfDorks | 3:4b9ad18eae02 | 266 | |
LordOfDorks | 3:4b9ad18eae02 | 267 | // Update the index |
LordOfDorks | 3:4b9ad18eae02 | 268 | index += iteration; |
LordOfDorks | 3:4b9ad18eae02 | 269 | } while((cbTrailingData - index) > 0); |
LordOfDorks | 3:4b9ad18eae02 | 270 | } |
LordOfDorks | 3:4b9ad18eae02 | 271 | |
LordOfDorks | 1:fd0a59e55a85 | 272 | // Command complete? |
LordOfDorks | 1:fd0a59e55a85 | 273 | if((!ReadRegister(TIS_STS_REGISTER, &tisStatus, sizeof(tisStatus))) || |
LordOfDorks | 1:fd0a59e55a85 | 274 | (!(tisStatus & TIS_STS_VALID) || (tisStatus & TIS_STS_DATA_EXPECT))) |
LordOfDorks | 1:fd0a59e55a85 | 275 | { |
LordOfDorks | 1:fd0a59e55a85 | 276 | result = TIS_SESSION_RESULT_FAILED; |
LordOfDorks | 1:fd0a59e55a85 | 277 | goto Cleanup; |
LordOfDorks | 1:fd0a59e55a85 | 278 | } |
LordOfDorks | 1:fd0a59e55a85 | 279 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 1:fd0a59e55a85 | 280 | printf("TIS.CommandComplete\n\r"); |
LordOfDorks | 1:fd0a59e55a85 | 281 | #endif |
LordOfDorks | 1:fd0a59e55a85 | 282 | |
LordOfDorks | 1:fd0a59e55a85 | 283 | // Arm the Interrupt |
LordOfDorks | 1:fd0a59e55a85 | 284 | if(!TpmInteruptOn(TIS_INT_ENABLE_DATA_AVAILABLE_INT_ENABLE)) |
LordOfDorks | 1:fd0a59e55a85 | 285 | { |
LordOfDorks | 1:fd0a59e55a85 | 286 | goto Cleanup; |
LordOfDorks | 1:fd0a59e55a85 | 287 | } |
LordOfDorks | 1:fd0a59e55a85 | 288 | |
LordOfDorks | 1:fd0a59e55a85 | 289 | // Kick the command off |
LordOfDorks | 1:fd0a59e55a85 | 290 | tisStatus = TIS_STS_GO; |
LordOfDorks | 1:fd0a59e55a85 | 291 | if(!WriteRegister(TIS_STS_REGISTER, &tisStatus, sizeof(tisStatus))) |
LordOfDorks | 1:fd0a59e55a85 | 292 | { |
LordOfDorks | 1:fd0a59e55a85 | 293 | result = TIS_SESSION_RESULT_FAILED; |
LordOfDorks | 1:fd0a59e55a85 | 294 | goto Cleanup; |
LordOfDorks | 1:fd0a59e55a85 | 295 | } |
LordOfDorks | 1:fd0a59e55a85 | 296 | |
LordOfDorks | 1:fd0a59e55a85 | 297 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 1:fd0a59e55a85 | 298 | printf("TIS.Go."); |
LordOfDorks | 1:fd0a59e55a85 | 299 | #endif |
LordOfDorks | 1:fd0a59e55a85 | 300 | |
LordOfDorks | 1:fd0a59e55a85 | 301 | result = TIS_SESSION_RESULT_COMPLETE; |
LordOfDorks | 1:fd0a59e55a85 | 302 | |
LordOfDorks | 1:fd0a59e55a85 | 303 | Cleanup: |
LordOfDorks | 1:fd0a59e55a85 | 304 | if(result != TIS_SESSION_RESULT_COMPLETE) |
LordOfDorks | 1:fd0a59e55a85 | 305 | { |
LordOfDorks | 1:fd0a59e55a85 | 306 | AbortCommand(); |
LordOfDorks | 1:fd0a59e55a85 | 307 | } |
LordOfDorks | 1:fd0a59e55a85 | 308 | return result; |
LordOfDorks | 0:b11c8971edd9 | 309 | } |
LordOfDorks | 0:b11c8971edd9 | 310 | |
LordOfDorks | 1:fd0a59e55a85 | 311 | TIS_TPM20::TIS_RESULT |
LordOfDorks | 1:fd0a59e55a85 | 312 | TIS_TPM20::RetrieveResponse( |
LordOfDorks | 0:b11c8971edd9 | 313 | uint8_t* pbRsp, |
LordOfDorks | 0:b11c8971edd9 | 314 | uint32_t cbRsp, |
LordOfDorks | 1:fd0a59e55a85 | 315 | uint32_t* pcbRsp |
LordOfDorks | 0:b11c8971edd9 | 316 | ) |
LordOfDorks | 0:b11c8971edd9 | 317 | { |
LordOfDorks | 1:fd0a59e55a85 | 318 | TIS_RESULT result = TIS_SESSION_RESULT_COMPLETE; |
LordOfDorks | 1:fd0a59e55a85 | 319 | uint16_t burstCount = 0; |
LordOfDorks | 1:fd0a59e55a85 | 320 | uint32_t index = 0; |
LordOfDorks | 1:fd0a59e55a85 | 321 | uint32_t rspSize = 0; |
LordOfDorks | 0:b11c8971edd9 | 322 | |
LordOfDorks | 1:fd0a59e55a85 | 323 | if(m_interrupt != 0) |
LordOfDorks | 0:b11c8971edd9 | 324 | { |
LordOfDorks | 0:b11c8971edd9 | 325 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 326 | printf("."); |
LordOfDorks | 0:b11c8971edd9 | 327 | #endif |
LordOfDorks | 1:fd0a59e55a85 | 328 | result = TIS_SESSION_RESULT_PENDING; |
LordOfDorks | 1:fd0a59e55a85 | 329 | return result; |
LordOfDorks | 0:b11c8971edd9 | 330 | } |
LordOfDorks | 0:b11c8971edd9 | 331 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 1:fd0a59e55a85 | 332 | printf("IRQ!\r\n"); |
LordOfDorks | 0:b11c8971edd9 | 333 | #endif |
LordOfDorks | 0:b11c8971edd9 | 334 | |
LordOfDorks | 1:fd0a59e55a85 | 335 | // Disarm the Interrupt |
LordOfDorks | 1:fd0a59e55a85 | 336 | if(!TpmInteruptOn(0)) |
LordOfDorks | 0:b11c8971edd9 | 337 | { |
LordOfDorks | 0:b11c8971edd9 | 338 | goto Cleanup; |
LordOfDorks | 0:b11c8971edd9 | 339 | } |
LordOfDorks | 0:b11c8971edd9 | 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 | 3:4b9ad18eae02 | 350 | rspSize = BYTE_ARRAY_TO_UINT32(&pbRsp[sizeof(uint16_t)]); |
LordOfDorks | 3:4b9ad18eae02 | 351 | |
LordOfDorks | 1:fd0a59e55a85 | 352 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 1:fd0a59e55a85 | 353 | printf("Tis.ResponseSize = %d\r\n", rspSize); |
LordOfDorks | 1:fd0a59e55a85 | 354 | #endif |
LordOfDorks | 1:fd0a59e55a85 | 355 | |
LordOfDorks | 1:fd0a59e55a85 | 356 | if(min(rspSize, cbRsp) > index) |
LordOfDorks | 1:fd0a59e55a85 | 357 | { |
LordOfDorks | 1:fd0a59e55a85 | 358 | do |
LordOfDorks | 1:fd0a59e55a85 | 359 | { |
LordOfDorks | 3:4b9ad18eae02 | 360 | // Calculate the response iteration size |
LordOfDorks | 3:4b9ad18eae02 | 361 | uint16_t iteration = min((rspSize - index), (cbRsp - index)); |
LordOfDorks | 3:4b9ad18eae02 | 362 | if((burstCount = GetBurstCount()) == 0) |
LordOfDorks | 1:fd0a59e55a85 | 363 | { |
LordOfDorks | 1:fd0a59e55a85 | 364 | result = TIS_SESSION_RESULT_FAILED; |
LordOfDorks | 3:4b9ad18eae02 | 365 | goto Cleanup; |
LordOfDorks | 1:fd0a59e55a85 | 366 | } |
LordOfDorks | 3:4b9ad18eae02 | 367 | iteration = min(iteration, burstCount); |
LordOfDorks | 1:fd0a59e55a85 | 368 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 1:fd0a59e55a85 | 369 | printf("TIS.ReceivingBurst = %d\r\n", iteration); |
LordOfDorks | 1:fd0a59e55a85 | 370 | #endif |
LordOfDorks | 1:fd0a59e55a85 | 371 | |
LordOfDorks | 1:fd0a59e55a85 | 372 | // Read the data for this iteration |
LordOfDorks | 1:fd0a59e55a85 | 373 | if(!ReadRegister(TIS_DATA_FIFO, &pbRsp[index], iteration)) |
LordOfDorks | 1:fd0a59e55a85 | 374 | { |
LordOfDorks | 3:4b9ad18eae02 | 375 | result = TIS_SESSION_RESULT_FAILED; |
LordOfDorks | 1:fd0a59e55a85 | 376 | goto Cleanup; |
LordOfDorks | 1:fd0a59e55a85 | 377 | } |
LordOfDorks | 1:fd0a59e55a85 | 378 | index += iteration; |
LordOfDorks | 1:fd0a59e55a85 | 379 | } |
LordOfDorks | 1:fd0a59e55a85 | 380 | while(index < min(rspSize, cbRsp)); |
LordOfDorks | 1:fd0a59e55a85 | 381 | } |
LordOfDorks | 1:fd0a59e55a85 | 382 | |
LordOfDorks | 1:fd0a59e55a85 | 383 | *pcbRsp = index; |
LordOfDorks | 1:fd0a59e55a85 | 384 | |
LordOfDorks | 0:b11c8971edd9 | 385 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 386 | printf("TIS.Response: "); |
LordOfDorks | 1:fd0a59e55a85 | 387 | for(uint32_t n = 0; n < *pcbRsp; n++) printf("%02x ", pbRsp[n]); |
LordOfDorks | 0:b11c8971edd9 | 388 | printf("\n\r"); |
LordOfDorks | 0:b11c8971edd9 | 389 | #endif |
LordOfDorks | 0:b11c8971edd9 | 390 | |
LordOfDorks | 1:fd0a59e55a85 | 391 | result = TIS_SESSION_RESULT_COMPLETE; |
LordOfDorks | 0:b11c8971edd9 | 392 | |
LordOfDorks | 0:b11c8971edd9 | 393 | Cleanup: |
LordOfDorks | 1:fd0a59e55a85 | 394 | if((result != TIS_SESSION_RESULT_COMPLETE) && (result != TIS_SESSION_RESULT_PENDING)) |
LordOfDorks | 1:fd0a59e55a85 | 395 | { |
LordOfDorks | 1:fd0a59e55a85 | 396 | AbortCommand(); |
LordOfDorks | 1:fd0a59e55a85 | 397 | } |
LordOfDorks | 0:b11c8971edd9 | 398 | return result; |
LordOfDorks | 0:b11c8971edd9 | 399 | } |
LordOfDorks | 0:b11c8971edd9 | 400 | |
LordOfDorks | 0:b11c8971edd9 | 401 | bool |
LordOfDorks | 1:fd0a59e55a85 | 402 | TIS_TPM20::FullDuplex( |
LordOfDorks | 0:b11c8971edd9 | 403 | bool readCycle, |
LordOfDorks | 1:fd0a59e55a85 | 404 | uint16_t reg, |
LordOfDorks | 0:b11c8971edd9 | 405 | uint8_t* pbBuffer, |
LordOfDorks | 0:b11c8971edd9 | 406 | uint16_t cbBuffer |
LordOfDorks | 0:b11c8971edd9 | 407 | ) |
LordOfDorks | 0:b11c8971edd9 | 408 | { |
LordOfDorks | 0:b11c8971edd9 | 409 | bool result = false; |
LordOfDorks | 0:b11c8971edd9 | 410 | uint8_t dataByteIn; |
LordOfDorks | 0:b11c8971edd9 | 411 | uint8_t dataByteOut; |
LordOfDorks | 0:b11c8971edd9 | 412 | |
LordOfDorks | 0:b11c8971edd9 | 413 | // Lock the bus for this operation |
LordOfDorks | 1:fd0a59e55a85 | 414 | m_chipSelect = 0; |
LordOfDorks | 0:b11c8971edd9 | 415 | |
LordOfDorks | 0:b11c8971edd9 | 416 | // Send the TIS header |
LordOfDorks | 1:fd0a59e55a85 | 417 | uint32_t tisHdr = TIS_HEADER(m_locality, readCycle, reg, cbBuffer); |
LordOfDorks | 1:fd0a59e55a85 | 418 | #ifdef TPM_TIS_INTERFACE_DEBUG_OUTPUT |
LordOfDorks | 1:fd0a59e55a85 | 419 | printf("TIS(LC:%d,RG:%02x,SZ:%02x,%s):", m_locality, reg, cbBuffer, (readCycle) ? "RD" : "WR"); |
LordOfDorks | 0:b11c8971edd9 | 420 | #endif |
LordOfDorks | 0:b11c8971edd9 | 421 | |
LordOfDorks | 0:b11c8971edd9 | 422 | for(uint8_t n = 0; n < sizeof(tisHdr); n++) |
LordOfDorks | 0:b11c8971edd9 | 423 | { |
LordOfDorks | 1:fd0a59e55a85 | 424 | dataByteOut = tisHdr >> (8 * (3 - n)); |
LordOfDorks | 1:fd0a59e55a85 | 425 | dataByteIn = m_spi.write(dataByteOut); |
LordOfDorks | 1:fd0a59e55a85 | 426 | //#ifdef TPM_TIS_INTERFACE_DEBUG_OUTPUT |
LordOfDorks | 1:fd0a59e55a85 | 427 | // if(n < (sizeof(tisHdr) - 1)) printf("%02x ", dataByteOut); |
LordOfDorks | 1:fd0a59e55a85 | 428 | // else printf("%02x", dataByteOut); |
LordOfDorks | 1:fd0a59e55a85 | 429 | //#endif |
LordOfDorks | 0:b11c8971edd9 | 430 | } |
LordOfDorks | 1:fd0a59e55a85 | 431 | |
LordOfDorks | 1:fd0a59e55a85 | 432 | // The last bit we read full duplex is the first wait state indicator |
LordOfDorks | 1:fd0a59e55a85 | 433 | int16_t waitCycleRetry = 100; |
LordOfDorks | 1:fd0a59e55a85 | 434 | while(!(dataByteIn & 0x01)) |
LordOfDorks | 0:b11c8971edd9 | 435 | { |
LordOfDorks | 1:fd0a59e55a85 | 436 | #ifdef TPM_TIS_INTERFACE_DEBUG_OUTPUT |
LordOfDorks | 1:fd0a59e55a85 | 437 | printf("."); |
LordOfDorks | 0:b11c8971edd9 | 438 | #endif |
LordOfDorks | 1:fd0a59e55a85 | 439 | // Read the next byte to see is we still have to wait |
LordOfDorks | 1:fd0a59e55a85 | 440 | if((dataByteIn = m_spi.write(0x00)) == 0x01) |
LordOfDorks | 0:b11c8971edd9 | 441 | { |
LordOfDorks | 0:b11c8971edd9 | 442 | break; |
LordOfDorks | 0:b11c8971edd9 | 443 | } |
LordOfDorks | 0:b11c8971edd9 | 444 | |
LordOfDorks | 1:fd0a59e55a85 | 445 | // Check the timeout |
LordOfDorks | 1:fd0a59e55a85 | 446 | if(waitCycleRetry-- <= 0) |
LordOfDorks | 0:b11c8971edd9 | 447 | { |
LordOfDorks | 1:fd0a59e55a85 | 448 | result = false; |
LordOfDorks | 1:fd0a59e55a85 | 449 | goto Cleanup; |
LordOfDorks | 0:b11c8971edd9 | 450 | } |
LordOfDorks | 0:b11c8971edd9 | 451 | } |
LordOfDorks | 1:fd0a59e55a85 | 452 | |
LordOfDorks | 1:fd0a59e55a85 | 453 | // Full duplex the payload |
LordOfDorks | 1:fd0a59e55a85 | 454 | for(uint8_t n = 0; n < cbBuffer; n++) |
LordOfDorks | 1:fd0a59e55a85 | 455 | { |
LordOfDorks | 1:fd0a59e55a85 | 456 | dataByteOut = (readCycle) ? 0x00 : pbBuffer[n]; |
LordOfDorks | 1:fd0a59e55a85 | 457 | dataByteIn = m_spi.write(dataByteOut); |
LordOfDorks | 1:fd0a59e55a85 | 458 | if(readCycle) pbBuffer[n] = dataByteIn; |
LordOfDorks | 1:fd0a59e55a85 | 459 | #ifdef TPM_TIS_INTERFACE_DEBUG_OUTPUT |
LordOfDorks | 1:fd0a59e55a85 | 460 | printf("%02x ", (readCycle) ? dataByteIn : dataByteOut); |
LordOfDorks | 1:fd0a59e55a85 | 461 | #endif |
LordOfDorks | 1:fd0a59e55a85 | 462 | } |
LordOfDorks | 1:fd0a59e55a85 | 463 | result = true; |
LordOfDorks | 1:fd0a59e55a85 | 464 | |
LordOfDorks | 1:fd0a59e55a85 | 465 | Cleanup: |
LordOfDorks | 1:fd0a59e55a85 | 466 | #ifdef TPM_TIS_INTERFACE_DEBUG_OUTPUT |
LordOfDorks | 1:fd0a59e55a85 | 467 | printf("\r\n"); |
LordOfDorks | 1:fd0a59e55a85 | 468 | #endif |
LordOfDorks | 1:fd0a59e55a85 | 469 | // Make sure to release the bus before we leave |
LordOfDorks | 1:fd0a59e55a85 | 470 | m_chipSelect = 1; |
LordOfDorks | 1:fd0a59e55a85 | 471 | return result; |
LordOfDorks | 0:b11c8971edd9 | 472 | } |
LordOfDorks | 0:b11c8971edd9 | 473 | |
LordOfDorks | 1:fd0a59e55a85 | 474 | uint16_t |
LordOfDorks | 1:fd0a59e55a85 | 475 | TIS_TPM20::GetBurstCount() |
LordOfDorks | 0:b11c8971edd9 | 476 | { |
LordOfDorks | 2:526bf792254d | 477 | if(m_fixedBurstCount) |
LordOfDorks | 0:b11c8971edd9 | 478 | { |
LordOfDorks | 2:526bf792254d | 479 | return m_maxBurstCount; |
LordOfDorks | 1:fd0a59e55a85 | 480 | } |
LordOfDorks | 1:fd0a59e55a85 | 481 | else |
LordOfDorks | 1:fd0a59e55a85 | 482 | { |
LordOfDorks | 2:526bf792254d | 483 | uint16_t burstCount = 0; |
LordOfDorks | 1:fd0a59e55a85 | 484 | uint8_t dataBytes[sizeof(uint16_t)] = {0}; |
LordOfDorks | 1:fd0a59e55a85 | 485 | if(!ReadRegister(TIS_STS_BURSTCOUNT_REGISTER, dataBytes, sizeof(dataBytes))) |
LordOfDorks | 0:b11c8971edd9 | 486 | { |
LordOfDorks | 1:fd0a59e55a85 | 487 | return 0; |
LordOfDorks | 0:b11c8971edd9 | 488 | } |
LordOfDorks | 3:4b9ad18eae02 | 489 | burstCount = min(BYTE_ARRAY_TO_LEUINT16(dataBytes), m_maxBurstCount); |
LordOfDorks | 1:fd0a59e55a85 | 490 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 2:526bf792254d | 491 | printf("TIS.BurstCount = %d\r\n", burstCount); |
LordOfDorks | 1:fd0a59e55a85 | 492 | #endif |
LordOfDorks | 2:526bf792254d | 493 | return burstCount; |
LordOfDorks | 0:b11c8971edd9 | 494 | } |
LordOfDorks | 0:b11c8971edd9 | 495 | } |
LordOfDorks | 0:b11c8971edd9 | 496 | |
LordOfDorks | 0:b11c8971edd9 | 497 | bool |
LordOfDorks | 1:fd0a59e55a85 | 498 | TIS_TPM20::RequestLocality(TIS_TPM20::TIS_LOCALITY locality) |
LordOfDorks | 0:b11c8971edd9 | 499 | { |
LordOfDorks | 1:fd0a59e55a85 | 500 | m_locality = locality; |
LordOfDorks | 1:fd0a59e55a85 | 501 | |
LordOfDorks | 1:fd0a59e55a85 | 502 | for(uint8_t n = 0; n < 100; n++) |
LordOfDorks | 0:b11c8971edd9 | 503 | { |
LordOfDorks | 1:fd0a59e55a85 | 504 | uint8_t dataByte = 0; |
LordOfDorks | 1:fd0a59e55a85 | 505 | // Read a valid access register. Turns out, it may take a couple of times if the TPM was sleeping |
LordOfDorks | 1:fd0a59e55a85 | 506 | do |
LordOfDorks | 0:b11c8971edd9 | 507 | { |
LordOfDorks | 1:fd0a59e55a85 | 508 | dataByte = 0; |
LordOfDorks | 1:fd0a59e55a85 | 509 | if(!ReadRegister(TIS_ACCESS_REGISTER, &dataByte, sizeof(dataByte))) |
LordOfDorks | 1:fd0a59e55a85 | 510 | { |
LordOfDorks | 1:fd0a59e55a85 | 511 | goto Cleanup; |
LordOfDorks | 1:fd0a59e55a85 | 512 | } |
LordOfDorks | 1:fd0a59e55a85 | 513 | |
LordOfDorks | 1:fd0a59e55a85 | 514 | // First time we hit that, the TPM has to wake up give it some time |
LordOfDorks | 1:fd0a59e55a85 | 515 | if(!(dataByte & TIS_ACCESS_VALID)) |
LordOfDorks | 1:fd0a59e55a85 | 516 | { |
LordOfDorks | 1:fd0a59e55a85 | 517 | wait_us(5000); |
LordOfDorks | 1:fd0a59e55a85 | 518 | } |
LordOfDorks | 0:b11c8971edd9 | 519 | } |
LordOfDorks | 1:fd0a59e55a85 | 520 | while(!(dataByte & TIS_ACCESS_VALID)); |
LordOfDorks | 1:fd0a59e55a85 | 521 | |
LordOfDorks | 1:fd0a59e55a85 | 522 | // If we have the locality we are done |
LordOfDorks | 1:fd0a59e55a85 | 523 | if(dataByte & TIS_ACCESS_ACTIVE_LOCALITY) |
LordOfDorks | 0:b11c8971edd9 | 524 | { |
LordOfDorks | 1:fd0a59e55a85 | 525 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 1:fd0a59e55a85 | 526 | printf("TIS.LocalityAquired\n\r"); |
LordOfDorks | 1:fd0a59e55a85 | 527 | #endif |
LordOfDorks | 1:fd0a59e55a85 | 528 | return true; |
LordOfDorks | 0:b11c8971edd9 | 529 | } |
LordOfDorks | 0:b11c8971edd9 | 530 | |
LordOfDorks | 1:fd0a59e55a85 | 531 | // Request the locality |
LordOfDorks | 1:fd0a59e55a85 | 532 | dataByte = TIS_ACCESS_REQUEST_USE; |
LordOfDorks | 1:fd0a59e55a85 | 533 | if(!WriteRegister(TIS_ACCESS_REGISTER, &dataByte, sizeof(dataByte))) |
LordOfDorks | 1:fd0a59e55a85 | 534 | { |
LordOfDorks | 1:fd0a59e55a85 | 535 | goto Cleanup; |
LordOfDorks | 1:fd0a59e55a85 | 536 | } |
LordOfDorks | 1:fd0a59e55a85 | 537 | } |
LordOfDorks | 1:fd0a59e55a85 | 538 | |
LordOfDorks | 1:fd0a59e55a85 | 539 | m_locality = TIS_NOT_IN_USE; |
LordOfDorks | 1:fd0a59e55a85 | 540 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 1:fd0a59e55a85 | 541 | printf("TIS.LocalityRequest = FAILED\n\r"); |
LordOfDorks | 1:fd0a59e55a85 | 542 | #endif |
LordOfDorks | 1:fd0a59e55a85 | 543 | Cleanup: |
LordOfDorks | 1:fd0a59e55a85 | 544 | return false; |
LordOfDorks | 0:b11c8971edd9 | 545 | } |
LordOfDorks | 0:b11c8971edd9 | 546 | |
LordOfDorks | 0:b11c8971edd9 | 547 | bool |
LordOfDorks | 1:fd0a59e55a85 | 548 | TIS_TPM20::ReleaseLocality() |
LordOfDorks | 0:b11c8971edd9 | 549 | { |
LordOfDorks | 1:fd0a59e55a85 | 550 | for(uint8_t n = 0; n < 100; n++) |
LordOfDorks | 1:fd0a59e55a85 | 551 | { |
LordOfDorks | 1:fd0a59e55a85 | 552 | uint8_t dataByte = 0; |
LordOfDorks | 1:fd0a59e55a85 | 553 | // Read a valid access register. Turns out, it may take a couple of times if the TPM was sleeping |
LordOfDorks | 1:fd0a59e55a85 | 554 | do |
LordOfDorks | 1:fd0a59e55a85 | 555 | { |
LordOfDorks | 1:fd0a59e55a85 | 556 | if(!ReadRegister(TIS_ACCESS_REGISTER, &dataByte, sizeof(dataByte))) |
LordOfDorks | 1:fd0a59e55a85 | 557 | { |
LordOfDorks | 1:fd0a59e55a85 | 558 | break; |
LordOfDorks | 1:fd0a59e55a85 | 559 | } |
LordOfDorks | 1:fd0a59e55a85 | 560 | |
LordOfDorks | 1:fd0a59e55a85 | 561 | // First time we hit that, the TPM has to wake up give it some time |
LordOfDorks | 1:fd0a59e55a85 | 562 | if(!(dataByte & TIS_ACCESS_VALID)) |
LordOfDorks | 1:fd0a59e55a85 | 563 | { |
LordOfDorks | 1:fd0a59e55a85 | 564 | wait_us(5000); |
LordOfDorks | 1:fd0a59e55a85 | 565 | } |
LordOfDorks | 1:fd0a59e55a85 | 566 | } |
LordOfDorks | 1:fd0a59e55a85 | 567 | while(!(dataByte & TIS_ACCESS_VALID)); |
LordOfDorks | 0:b11c8971edd9 | 568 | |
LordOfDorks | 1:fd0a59e55a85 | 569 | // If we don't have the locality we are done |
LordOfDorks | 1:fd0a59e55a85 | 570 | if(!(dataByte & TIS_ACCESS_ACTIVE_LOCALITY)) |
LordOfDorks | 0:b11c8971edd9 | 571 | { |
LordOfDorks | 1:fd0a59e55a85 | 572 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 1:fd0a59e55a85 | 573 | printf("TIS.LocalityReleased\n\r"); |
LordOfDorks | 1:fd0a59e55a85 | 574 | #endif |
LordOfDorks | 1:fd0a59e55a85 | 575 | m_locality = TIS_NOT_IN_USE; |
LordOfDorks | 1:fd0a59e55a85 | 576 | return true; |
LordOfDorks | 0:b11c8971edd9 | 577 | } |
LordOfDorks | 1:fd0a59e55a85 | 578 | |
LordOfDorks | 1:fd0a59e55a85 | 579 | // Drop the locality |
LordOfDorks | 1:fd0a59e55a85 | 580 | dataByte = TIS_ACCESS_ACTIVE_LOCALITY; |
LordOfDorks | 1:fd0a59e55a85 | 581 | if(!WriteRegister(TIS_ACCESS_REGISTER, &dataByte, sizeof(dataByte))) |
LordOfDorks | 0:b11c8971edd9 | 582 | { |
LordOfDorks | 0:b11c8971edd9 | 583 | break; |
LordOfDorks | 0:b11c8971edd9 | 584 | } |
LordOfDorks | 0:b11c8971edd9 | 585 | } |
LordOfDorks | 1:fd0a59e55a85 | 586 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 1:fd0a59e55a85 | 587 | printf("TIS.LocalityReleased = FAILED\n\r"); |
LordOfDorks | 1:fd0a59e55a85 | 588 | #endif |
LordOfDorks | 0:b11c8971edd9 | 589 | |
LordOfDorks | 1:fd0a59e55a85 | 590 | return false; |
LordOfDorks | 0:b11c8971edd9 | 591 | } |
LordOfDorks | 0:b11c8971edd9 | 592 | |
LordOfDorks | 0:b11c8971edd9 | 593 | bool |
LordOfDorks | 1:fd0a59e55a85 | 594 | TIS_TPM20::TpmInteruptOn(uint32_t intEnable) |
LordOfDorks | 0:b11c8971edd9 | 595 | { |
LordOfDorks | 1:fd0a59e55a85 | 596 | uint32_t int_enable = TIS_INT_ENABLE_TYPE_POLARITY_LOW; |
LordOfDorks | 1:fd0a59e55a85 | 597 | uint8_t dataRegister[sizeof(uint32_t)] = {0}; |
LordOfDorks | 1:fd0a59e55a85 | 598 | uint8_t dataByte = 0; |
LordOfDorks | 1:fd0a59e55a85 | 599 | |
LordOfDorks | 3:4b9ad18eae02 | 600 | if(intEnable == 0) |
LordOfDorks | 1:fd0a59e55a85 | 601 | { |
LordOfDorks | 3:4b9ad18eae02 | 602 | // Reset the interrupt. Turns out the TPM needs some time to actually do this let me tell you: |
LordOfDorks | 3:4b9ad18eae02 | 603 | // That was a very interesting bug hunt! What we end up with here is the following - We reset |
LordOfDorks | 3:4b9ad18eae02 | 604 | // the interrupts now and don't look at them. While the TPM actually resets the line, we use |
LordOfDorks | 3:4b9ad18eae02 | 605 | // that time to send the next command but before interrupts are turned on for the next command |
LordOfDorks | 3:4b9ad18eae02 | 606 | // execution we have to wait until the line is back up again (see below). |
LordOfDorks | 3:4b9ad18eae02 | 607 | dataByte = TIS_INT_STATUS_RESET_ALL; |
LordOfDorks | 3:4b9ad18eae02 | 608 | if(!WriteRegister(TIS_INT_STATUS_REGISTER, &dataByte, sizeof(dataByte))) |
LordOfDorks | 3:4b9ad18eae02 | 609 | { |
LordOfDorks | 3:4b9ad18eae02 | 610 | return false; |
LordOfDorks | 3:4b9ad18eae02 | 611 | } |
LordOfDorks | 3:4b9ad18eae02 | 612 | } |
LordOfDorks | 3:4b9ad18eae02 | 613 | else |
LordOfDorks | 3:4b9ad18eae02 | 614 | { |
LordOfDorks | 3:4b9ad18eae02 | 615 | // Make sure the interrupt is really, really clear before we turn it back on. The TPM takes |
LordOfDorks | 3:4b9ad18eae02 | 616 | // around 5-10ms to transition the line back high. |
LordOfDorks | 3:4b9ad18eae02 | 617 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 3:4b9ad18eae02 | 618 | if(intEnable == 0) printf("TIS.InteruptStillActive\n\r"); |
LordOfDorks | 3:4b9ad18eae02 | 619 | #endif |
LordOfDorks | 3:4b9ad18eae02 | 620 | while(m_interrupt == 0) |
LordOfDorks | 3:4b9ad18eae02 | 621 | { |
LordOfDorks | 3:4b9ad18eae02 | 622 | wait_us(1000); |
LordOfDorks | 3:4b9ad18eae02 | 623 | } |
LordOfDorks | 3:4b9ad18eae02 | 624 | |
LordOfDorks | 1:fd0a59e55a85 | 625 | int_enable |= (uint32_t)TIS_INT_ENABLE_GLOBAL_INT_ENABLE | intEnable; |
LordOfDorks | 1:fd0a59e55a85 | 626 | } |
LordOfDorks | 1:fd0a59e55a85 | 627 | |
LordOfDorks | 3:4b9ad18eae02 | 628 | LEUINT32_TO_BYTE_ARRAY(int_enable, dataRegister); |
LordOfDorks | 1:fd0a59e55a85 | 629 | |
LordOfDorks | 1:fd0a59e55a85 | 630 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 3:4b9ad18eae02 | 631 | if(intEnable) |
LordOfDorks | 3:4b9ad18eae02 | 632 | printf("TIS.TpmInterupt = 0x%08x\n\r", intEnable); |
LordOfDorks | 3:4b9ad18eae02 | 633 | else |
LordOfDorks | 3:4b9ad18eae02 | 634 | printf("TIS.TpmInterupt = OFF\n\r"); |
LordOfDorks | 1:fd0a59e55a85 | 635 | #endif |
LordOfDorks | 3:4b9ad18eae02 | 636 | return(WriteRegister(TIS_INT_ENABLE_REGISTER, dataRegister, sizeof(dataRegister))); |
LordOfDorks | 0:b11c8971edd9 | 637 | } |
LordOfDorks | 0:b11c8971edd9 | 638 | |
LordOfDorks | 3:4b9ad18eae02 | 639 | |
LordOfDorks | 3:4b9ad18eae02 | 640 |