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@2:526bf792254d, 2015-04-07 (annotated)
- 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?
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 | #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 | } |