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@1:fd0a59e55a85, 2015-04-07 (annotated)
- 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?
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 | 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 | } |