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@0:b11c8971edd9, 2015-03-23 (annotated)
- Committer:
- LordOfDorks
- Date:
- Mon Mar 23 19:03:50 2015 +0000
- Revision:
- 0:b11c8971edd9
- Child:
- 1:fd0a59e55a85
First release verified with STMicro TPM 2.0
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
LordOfDorks | 0:b11c8971edd9 | 1 | /* mbed TCG TIS 1.3 SPI TPM 2.0 Library, |
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 | 0:b11c8971edd9 | 22 | */ |
LordOfDorks | 0:b11c8971edd9 | 23 | |
LordOfDorks | 0:b11c8971edd9 | 24 | #include "SPITIS_TPM20.h" |
LordOfDorks | 0:b11c8971edd9 | 25 | |
LordOfDorks | 0:b11c8971edd9 | 26 | TISTPM20::TISTPM20( |
LordOfDorks | 0:b11c8971edd9 | 27 | PinName mosi, |
LordOfDorks | 0:b11c8971edd9 | 28 | PinName miso, |
LordOfDorks | 0:b11c8971edd9 | 29 | PinName clk, |
LordOfDorks | 0:b11c8971edd9 | 30 | PinName cs |
LordOfDorks | 0:b11c8971edd9 | 31 | ) |
LordOfDorks | 0:b11c8971edd9 | 32 | { |
LordOfDorks | 0:b11c8971edd9 | 33 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 34 | printf("TIS.Init: "); |
LordOfDorks | 0:b11c8971edd9 | 35 | #endif |
LordOfDorks | 0:b11c8971edd9 | 36 | m_SPITpmDev = new SPI(mosi, miso, clk); |
LordOfDorks | 0:b11c8971edd9 | 37 | m_SPITpmDev->format(8, 0); |
LordOfDorks | 0:b11c8971edd9 | 38 | m_SPITpmDev->frequency(4000000); |
LordOfDorks | 0:b11c8971edd9 | 39 | m_SPICSTpmDev = new DigitalOut(cs); |
LordOfDorks | 0:b11c8971edd9 | 40 | *m_SPICSTpmDev = 1; |
LordOfDorks | 0:b11c8971edd9 | 41 | m_ExclusiveAccess = false; |
LordOfDorks | 0:b11c8971edd9 | 42 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 43 | printf("OK.\n\r"); |
LordOfDorks | 0:b11c8971edd9 | 44 | #endif |
LordOfDorks | 0:b11c8971edd9 | 45 | } |
LordOfDorks | 0:b11c8971edd9 | 46 | |
LordOfDorks | 0:b11c8971edd9 | 47 | // Release all held resources |
LordOfDorks | 0:b11c8971edd9 | 48 | TISTPM20::~TISTPM20() |
LordOfDorks | 0:b11c8971edd9 | 49 | { |
LordOfDorks | 0:b11c8971edd9 | 50 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 51 | printf("TIS.Destroy: "); |
LordOfDorks | 0:b11c8971edd9 | 52 | #endif |
LordOfDorks | 0:b11c8971edd9 | 53 | if(m_SPITpmDev != NULL) |
LordOfDorks | 0:b11c8971edd9 | 54 | { |
LordOfDorks | 0:b11c8971edd9 | 55 | delete m_SPITpmDev; |
LordOfDorks | 0:b11c8971edd9 | 56 | m_SPITpmDev = NULL; |
LordOfDorks | 0:b11c8971edd9 | 57 | } |
LordOfDorks | 0:b11c8971edd9 | 58 | if(m_SPICSTpmDev != NULL) |
LordOfDorks | 0:b11c8971edd9 | 59 | { |
LordOfDorks | 0:b11c8971edd9 | 60 | delete m_SPICSTpmDev; |
LordOfDorks | 0:b11c8971edd9 | 61 | m_SPICSTpmDev = NULL; |
LordOfDorks | 0:b11c8971edd9 | 62 | } |
LordOfDorks | 0:b11c8971edd9 | 63 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 64 | printf("OK.\n\r"); |
LordOfDorks | 0:b11c8971edd9 | 65 | #endif |
LordOfDorks | 0:b11c8971edd9 | 66 | } |
LordOfDorks | 0:b11c8971edd9 | 67 | |
LordOfDorks | 0:b11c8971edd9 | 68 | uint32_t |
LordOfDorks | 0:b11c8971edd9 | 69 | TISTPM20::Execute( |
LordOfDorks | 0:b11c8971edd9 | 70 | uint8_t locality, |
LordOfDorks | 0:b11c8971edd9 | 71 | uint8_t* pbCmd, |
LordOfDorks | 0:b11c8971edd9 | 72 | uint32_t cbCmd, |
LordOfDorks | 0:b11c8971edd9 | 73 | uint8_t* pbRsp, |
LordOfDorks | 0:b11c8971edd9 | 74 | uint32_t cbRsp, |
LordOfDorks | 0:b11c8971edd9 | 75 | uint32_t timeout |
LordOfDorks | 0:b11c8971edd9 | 76 | ) |
LordOfDorks | 0:b11c8971edd9 | 77 | { |
LordOfDorks | 0:b11c8971edd9 | 78 | uint32_t result = 0; |
LordOfDorks | 0:b11c8971edd9 | 79 | Timeout watchdog; |
LordOfDorks | 0:b11c8971edd9 | 80 | |
LordOfDorks | 0:b11c8971edd9 | 81 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 82 | printf("TIS.ExecuteWaitForAccess."); |
LordOfDorks | 0:b11c8971edd9 | 83 | #endif |
LordOfDorks | 0:b11c8971edd9 | 84 | |
LordOfDorks | 0:b11c8971edd9 | 85 | // Only one caller should be talking to the TPM at any given time |
LordOfDorks | 0:b11c8971edd9 | 86 | while(m_ExclusiveAccess) |
LordOfDorks | 0:b11c8971edd9 | 87 | { |
LordOfDorks | 0:b11c8971edd9 | 88 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 89 | printf("."); |
LordOfDorks | 0:b11c8971edd9 | 90 | #endif |
LordOfDorks | 0:b11c8971edd9 | 91 | wait_us(500); |
LordOfDorks | 0:b11c8971edd9 | 92 | } |
LordOfDorks | 0:b11c8971edd9 | 93 | m_ExclusiveAccess = true; |
LordOfDorks | 0:b11c8971edd9 | 94 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 95 | printf("OK\n\r"); |
LordOfDorks | 0:b11c8971edd9 | 96 | #endif |
LordOfDorks | 0:b11c8971edd9 | 97 | |
LordOfDorks | 0:b11c8971edd9 | 98 | // Set the requested locality for the call |
LordOfDorks | 0:b11c8971edd9 | 99 | m_Locality = locality; |
LordOfDorks | 0:b11c8971edd9 | 100 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 101 | printf("TIS.Locality = %d\n\r", m_Locality); |
LordOfDorks | 0:b11c8971edd9 | 102 | #endif |
LordOfDorks | 0:b11c8971edd9 | 103 | |
LordOfDorks | 0:b11c8971edd9 | 104 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 105 | printf("TIS.SetupTimeout\n\r"); |
LordOfDorks | 0:b11c8971edd9 | 106 | #endif |
LordOfDorks | 0:b11c8971edd9 | 107 | // Setup TPM timeout |
LordOfDorks | 0:b11c8971edd9 | 108 | m_TimeoutTriggered = false; |
LordOfDorks | 0:b11c8971edd9 | 109 | watchdog.attach(this, &TISTPM20::TimeoutTrigger, 0.0001 * timeout); |
LordOfDorks | 0:b11c8971edd9 | 110 | |
LordOfDorks | 0:b11c8971edd9 | 111 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 112 | printf("TIS.Execute: "); |
LordOfDorks | 0:b11c8971edd9 | 113 | for(uint32_t n = 0; n < cbCmd; n++) printf("%02x ", pbCmd[n]); |
LordOfDorks | 0:b11c8971edd9 | 114 | printf("\n\r"); |
LordOfDorks | 0:b11c8971edd9 | 115 | #endif |
LordOfDorks | 0:b11c8971edd9 | 116 | |
LordOfDorks | 0:b11c8971edd9 | 117 | // Execute command on the TPM |
LordOfDorks | 0:b11c8971edd9 | 118 | if((result = ExecuteTIS(pbCmd, cbCmd, pbRsp, cbRsp)) == 0) |
LordOfDorks | 0:b11c8971edd9 | 119 | { |
LordOfDorks | 0:b11c8971edd9 | 120 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 121 | printf("TIS.Failed\n\r"); |
LordOfDorks | 0:b11c8971edd9 | 122 | #endif |
LordOfDorks | 0:b11c8971edd9 | 123 | goto Cleanup; |
LordOfDorks | 0:b11c8971edd9 | 124 | } |
LordOfDorks | 0:b11c8971edd9 | 125 | |
LordOfDorks | 0:b11c8971edd9 | 126 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 127 | printf("TIS.Response: "); |
LordOfDorks | 0:b11c8971edd9 | 128 | for(uint32_t n = 0; n < result; n++) printf("%02x ", pbRsp[n]); |
LordOfDorks | 0:b11c8971edd9 | 129 | printf("\n\r"); |
LordOfDorks | 0:b11c8971edd9 | 130 | #endif |
LordOfDorks | 0:b11c8971edd9 | 131 | |
LordOfDorks | 0:b11c8971edd9 | 132 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 133 | printf("TIS.CancelTimeout\n\r"); |
LordOfDorks | 0:b11c8971edd9 | 134 | #endif |
LordOfDorks | 0:b11c8971edd9 | 135 | |
LordOfDorks | 0:b11c8971edd9 | 136 | Cleanup: |
LordOfDorks | 0:b11c8971edd9 | 137 | watchdog.detach(); |
LordOfDorks | 0:b11c8971edd9 | 138 | m_ExclusiveAccess = false; |
LordOfDorks | 0:b11c8971edd9 | 139 | return result; |
LordOfDorks | 0:b11c8971edd9 | 140 | } |
LordOfDorks | 0:b11c8971edd9 | 141 | |
LordOfDorks | 0:b11c8971edd9 | 142 | uint32_t |
LordOfDorks | 0:b11c8971edd9 | 143 | TISTPM20::ParseResponseHeader( |
LordOfDorks | 0:b11c8971edd9 | 144 | uint8_t* pbRsp, |
LordOfDorks | 0:b11c8971edd9 | 145 | uint32_t rspLen, |
LordOfDorks | 0:b11c8971edd9 | 146 | uint16_t* rspTag, |
LordOfDorks | 0:b11c8971edd9 | 147 | uint32_t* rspSize, |
LordOfDorks | 0:b11c8971edd9 | 148 | uint32_t* cursor |
LordOfDorks | 0:b11c8971edd9 | 149 | ) |
LordOfDorks | 0:b11c8971edd9 | 150 | { |
LordOfDorks | 0:b11c8971edd9 | 151 | uint32_t rspResponseCode = 0; |
LordOfDorks | 0:b11c8971edd9 | 152 | |
LordOfDorks | 0:b11c8971edd9 | 153 | // Check that the response header is well formatted |
LordOfDorks | 0:b11c8971edd9 | 154 | if(rspLen < (sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint32_t))) |
LordOfDorks | 0:b11c8971edd9 | 155 | { |
LordOfDorks | 0:b11c8971edd9 | 156 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 157 | printf("TIS.ResponseHdr.rspLen = 0x%08x\n\r", rspLen); |
LordOfDorks | 0:b11c8971edd9 | 158 | #endif |
LordOfDorks | 0:b11c8971edd9 | 159 | rspResponseCode = TPM_RC_FAILURE; |
LordOfDorks | 0:b11c8971edd9 | 160 | goto Cleanup; |
LordOfDorks | 0:b11c8971edd9 | 161 | } |
LordOfDorks | 0:b11c8971edd9 | 162 | |
LordOfDorks | 0:b11c8971edd9 | 163 | // Read the header components |
LordOfDorks | 0:b11c8971edd9 | 164 | *rspTag = BYTEARRAY_TO_UINT16(pbRsp, *cursor); |
LordOfDorks | 0:b11c8971edd9 | 165 | *cursor += sizeof(uint16_t); |
LordOfDorks | 0:b11c8971edd9 | 166 | *rspSize = BYTEARRAY_TO_UINT32(pbRsp, *cursor); |
LordOfDorks | 0:b11c8971edd9 | 167 | *cursor += sizeof(uint32_t); |
LordOfDorks | 0:b11c8971edd9 | 168 | rspResponseCode = BYTEARRAY_TO_UINT32(pbRsp, *cursor); |
LordOfDorks | 0:b11c8971edd9 | 169 | *cursor += sizeof(uint32_t); |
LordOfDorks | 0:b11c8971edd9 | 170 | |
LordOfDorks | 0:b11c8971edd9 | 171 | // Check the components |
LordOfDorks | 0:b11c8971edd9 | 172 | if(((*rspTag != TPM_ST_NO_SESSIONS) && (*rspTag != TPM_ST_SESSIONS)) || |
LordOfDorks | 0:b11c8971edd9 | 173 | (*rspSize != rspLen)) |
LordOfDorks | 0:b11c8971edd9 | 174 | { |
LordOfDorks | 0:b11c8971edd9 | 175 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 176 | printf("TIS.ResponseHdr.rspTag = 0x%04x.rspLen=0x%08x\n\r", *rspTag, rspLen); |
LordOfDorks | 0:b11c8971edd9 | 177 | #endif |
LordOfDorks | 0:b11c8971edd9 | 178 | rspResponseCode = TPM_RC_FAILURE; |
LordOfDorks | 0:b11c8971edd9 | 179 | goto Cleanup; |
LordOfDorks | 0:b11c8971edd9 | 180 | } |
LordOfDorks | 0:b11c8971edd9 | 181 | |
LordOfDorks | 0:b11c8971edd9 | 182 | Cleanup: |
LordOfDorks | 0:b11c8971edd9 | 183 | return rspResponseCode; |
LordOfDorks | 0:b11c8971edd9 | 184 | } |
LordOfDorks | 0:b11c8971edd9 | 185 | |
LordOfDorks | 0:b11c8971edd9 | 186 | uint32_t |
LordOfDorks | 0:b11c8971edd9 | 187 | TISTPM20::TPM2_Startup( |
LordOfDorks | 0:b11c8971edd9 | 188 | uint8_t locality, |
LordOfDorks | 0:b11c8971edd9 | 189 | uint16_t startupType |
LordOfDorks | 0:b11c8971edd9 | 190 | ) |
LordOfDorks | 0:b11c8971edd9 | 191 | { |
LordOfDorks | 0:b11c8971edd9 | 192 | uint32_t rspLen = 0; |
LordOfDorks | 0:b11c8971edd9 | 193 | uint16_t rspTag = 0; |
LordOfDorks | 0:b11c8971edd9 | 194 | uint32_t rspSize = 0; |
LordOfDorks | 0:b11c8971edd9 | 195 | uint32_t rspResponseCode = 0; |
LordOfDorks | 0:b11c8971edd9 | 196 | uint32_t cursor = 0; |
LordOfDorks | 0:b11c8971edd9 | 197 | uint8_t tpmCmd[] = {0x80, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x01, 0x44, 0x00, 0x00}; |
LordOfDorks | 0:b11c8971edd9 | 198 | #ifndef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 199 | uint32_t timeout = 2000; |
LordOfDorks | 0:b11c8971edd9 | 200 | #else |
LordOfDorks | 0:b11c8971edd9 | 201 | uint32_t timeout = 20000; |
LordOfDorks | 0:b11c8971edd9 | 202 | #endif |
LordOfDorks | 0:b11c8971edd9 | 203 | UINT16_TO_BYTEARRAY(startupType, tpmCmd, sizeof(tpmCmd) - 2); |
LordOfDorks | 0:b11c8971edd9 | 204 | |
LordOfDorks | 0:b11c8971edd9 | 205 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 206 | printf("TIS.TPM2_Startup(0x%04x)\n\r", startupType); |
LordOfDorks | 0:b11c8971edd9 | 207 | #endif |
LordOfDorks | 0:b11c8971edd9 | 208 | |
LordOfDorks | 0:b11c8971edd9 | 209 | if((rspLen = Execute(locality, tpmCmd, sizeof(tpmCmd), tpmCmd, sizeof(tpmCmd), timeout)) == 0) |
LordOfDorks | 0:b11c8971edd9 | 210 | { |
LordOfDorks | 0:b11c8971edd9 | 211 | rspResponseCode = TPM_RC_FAILURE; |
LordOfDorks | 0:b11c8971edd9 | 212 | goto Cleanup; |
LordOfDorks | 0:b11c8971edd9 | 213 | } |
LordOfDorks | 0:b11c8971edd9 | 214 | if((rspResponseCode = ParseResponseHeader(tpmCmd, rspLen, &rspTag, &rspSize, &cursor)) != TPM_RC_SUCCESS) |
LordOfDorks | 0:b11c8971edd9 | 215 | { |
LordOfDorks | 0:b11c8971edd9 | 216 | goto Cleanup; |
LordOfDorks | 0:b11c8971edd9 | 217 | } |
LordOfDorks | 0:b11c8971edd9 | 218 | |
LordOfDorks | 0:b11c8971edd9 | 219 | if(rspSize != 0x0000000a) |
LordOfDorks | 0:b11c8971edd9 | 220 | { |
LordOfDorks | 0:b11c8971edd9 | 221 | rspResponseCode = TPM_RC_FAILURE; |
LordOfDorks | 0:b11c8971edd9 | 222 | } |
LordOfDorks | 0:b11c8971edd9 | 223 | |
LordOfDorks | 0:b11c8971edd9 | 224 | Cleanup: |
LordOfDorks | 0:b11c8971edd9 | 225 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 226 | printf("TIS.TPM2_Startup.ResponseCode = 0x%08x\n\r", rspResponseCode); |
LordOfDorks | 0:b11c8971edd9 | 227 | #endif |
LordOfDorks | 0:b11c8971edd9 | 228 | return rspResponseCode; |
LordOfDorks | 0:b11c8971edd9 | 229 | } |
LordOfDorks | 0:b11c8971edd9 | 230 | |
LordOfDorks | 0:b11c8971edd9 | 231 | uint32_t |
LordOfDorks | 0:b11c8971edd9 | 232 | TISTPM20::TPM2_Shutdown( |
LordOfDorks | 0:b11c8971edd9 | 233 | uint8_t locality, |
LordOfDorks | 0:b11c8971edd9 | 234 | uint16_t shutdownType |
LordOfDorks | 0:b11c8971edd9 | 235 | ) |
LordOfDorks | 0:b11c8971edd9 | 236 | { |
LordOfDorks | 0:b11c8971edd9 | 237 | uint32_t rspLen = 0; |
LordOfDorks | 0:b11c8971edd9 | 238 | uint16_t rspTag = 0; |
LordOfDorks | 0:b11c8971edd9 | 239 | uint32_t rspSize = 0; |
LordOfDorks | 0:b11c8971edd9 | 240 | uint32_t rspResponseCode = 0; |
LordOfDorks | 0:b11c8971edd9 | 241 | uint32_t cursor = 0; |
LordOfDorks | 0:b11c8971edd9 | 242 | uint8_t tpmCmd[] = {0x80, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x01, 0x45, 0x00, 0x00}; |
LordOfDorks | 0:b11c8971edd9 | 243 | #ifndef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 244 | uint32_t timeout = 2000; |
LordOfDorks | 0:b11c8971edd9 | 245 | #else |
LordOfDorks | 0:b11c8971edd9 | 246 | uint32_t timeout = 20000; |
LordOfDorks | 0:b11c8971edd9 | 247 | #endif |
LordOfDorks | 0:b11c8971edd9 | 248 | UINT16_TO_BYTEARRAY(shutdownType, tpmCmd, sizeof(tpmCmd) - 2); |
LordOfDorks | 0:b11c8971edd9 | 249 | |
LordOfDorks | 0:b11c8971edd9 | 250 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 251 | printf("TIS.TPM2_Shutdown(0x%04x)\n\r", shutdownType); |
LordOfDorks | 0:b11c8971edd9 | 252 | #endif |
LordOfDorks | 0:b11c8971edd9 | 253 | |
LordOfDorks | 0:b11c8971edd9 | 254 | if((rspLen = Execute(locality, tpmCmd, sizeof(tpmCmd), tpmCmd, sizeof(tpmCmd), timeout)) == 0) |
LordOfDorks | 0:b11c8971edd9 | 255 | { |
LordOfDorks | 0:b11c8971edd9 | 256 | rspResponseCode = TPM_RC_FAILURE; |
LordOfDorks | 0:b11c8971edd9 | 257 | goto Cleanup; |
LordOfDorks | 0:b11c8971edd9 | 258 | } |
LordOfDorks | 0:b11c8971edd9 | 259 | if((rspResponseCode = ParseResponseHeader(tpmCmd, rspLen, &rspTag, &rspSize, &cursor)) != TPM_RC_SUCCESS) |
LordOfDorks | 0:b11c8971edd9 | 260 | { |
LordOfDorks | 0:b11c8971edd9 | 261 | goto Cleanup; |
LordOfDorks | 0:b11c8971edd9 | 262 | } |
LordOfDorks | 0:b11c8971edd9 | 263 | |
LordOfDorks | 0:b11c8971edd9 | 264 | if(rspSize != 0x0000000a) |
LordOfDorks | 0:b11c8971edd9 | 265 | { |
LordOfDorks | 0:b11c8971edd9 | 266 | rspResponseCode = TPM_RC_FAILURE; |
LordOfDorks | 0:b11c8971edd9 | 267 | } |
LordOfDorks | 0:b11c8971edd9 | 268 | |
LordOfDorks | 0:b11c8971edd9 | 269 | Cleanup: |
LordOfDorks | 0:b11c8971edd9 | 270 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 271 | printf("TIS.TPM2_Shutdown.ResponseCode = 0x%08x\n\r", rspResponseCode); |
LordOfDorks | 0:b11c8971edd9 | 272 | #endif |
LordOfDorks | 0:b11c8971edd9 | 273 | return rspResponseCode; |
LordOfDorks | 0:b11c8971edd9 | 274 | } |
LordOfDorks | 0:b11c8971edd9 | 275 | |
LordOfDorks | 0:b11c8971edd9 | 276 | uint32_t |
LordOfDorks | 0:b11c8971edd9 | 277 | TISTPM20::TPM2_SelfTest( |
LordOfDorks | 0:b11c8971edd9 | 278 | uint8_t locality, |
LordOfDorks | 0:b11c8971edd9 | 279 | uint8_t fullTest |
LordOfDorks | 0:b11c8971edd9 | 280 | ) |
LordOfDorks | 0:b11c8971edd9 | 281 | { |
LordOfDorks | 0:b11c8971edd9 | 282 | uint32_t rspLen = 0; |
LordOfDorks | 0:b11c8971edd9 | 283 | uint16_t rspTag = 0; |
LordOfDorks | 0:b11c8971edd9 | 284 | uint32_t rspSize = 0; |
LordOfDorks | 0:b11c8971edd9 | 285 | uint32_t rspResponseCode = 0; |
LordOfDorks | 0:b11c8971edd9 | 286 | uint32_t cursor = 0; |
LordOfDorks | 0:b11c8971edd9 | 287 | uint8_t tpmCmd[] = {0x80, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x43, 0x00}; |
LordOfDorks | 0:b11c8971edd9 | 288 | #ifndef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 289 | uint32_t timeout = 2000; |
LordOfDorks | 0:b11c8971edd9 | 290 | #else |
LordOfDorks | 0:b11c8971edd9 | 291 | uint32_t timeout = 20000; |
LordOfDorks | 0:b11c8971edd9 | 292 | #endif |
LordOfDorks | 0:b11c8971edd9 | 293 | tpmCmd[sizeof(tpmCmd) - 1] = fullTest; |
LordOfDorks | 0:b11c8971edd9 | 294 | |
LordOfDorks | 0:b11c8971edd9 | 295 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 296 | printf("TIS.TPM2_SelfTest(0x%02x)\n\r", fullTest); |
LordOfDorks | 0:b11c8971edd9 | 297 | #endif |
LordOfDorks | 0:b11c8971edd9 | 298 | |
LordOfDorks | 0:b11c8971edd9 | 299 | if((rspLen = Execute(locality, tpmCmd, sizeof(tpmCmd), tpmCmd, sizeof(tpmCmd), timeout)) == 0) |
LordOfDorks | 0:b11c8971edd9 | 300 | { |
LordOfDorks | 0:b11c8971edd9 | 301 | rspResponseCode = TPM_RC_FAILURE; |
LordOfDorks | 0:b11c8971edd9 | 302 | goto Cleanup; |
LordOfDorks | 0:b11c8971edd9 | 303 | } |
LordOfDorks | 0:b11c8971edd9 | 304 | if((rspResponseCode = ParseResponseHeader(tpmCmd, rspLen, &rspTag, &rspSize, &cursor)) != TPM_RC_SUCCESS) |
LordOfDorks | 0:b11c8971edd9 | 305 | { |
LordOfDorks | 0:b11c8971edd9 | 306 | goto Cleanup; |
LordOfDorks | 0:b11c8971edd9 | 307 | } |
LordOfDorks | 0:b11c8971edd9 | 308 | |
LordOfDorks | 0:b11c8971edd9 | 309 | if(rspSize != 0x0000000a) |
LordOfDorks | 0:b11c8971edd9 | 310 | { |
LordOfDorks | 0:b11c8971edd9 | 311 | rspResponseCode = TPM_RC_FAILURE; |
LordOfDorks | 0:b11c8971edd9 | 312 | } |
LordOfDorks | 0:b11c8971edd9 | 313 | |
LordOfDorks | 0:b11c8971edd9 | 314 | Cleanup: |
LordOfDorks | 0:b11c8971edd9 | 315 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 316 | printf("TIS.TPM2_SelfTest.ResponseCode = 0x%08x\n\r", rspResponseCode); |
LordOfDorks | 0:b11c8971edd9 | 317 | #endif |
LordOfDorks | 0:b11c8971edd9 | 318 | return rspResponseCode; |
LordOfDorks | 0:b11c8971edd9 | 319 | } |
LordOfDorks | 0:b11c8971edd9 | 320 | |
LordOfDorks | 0:b11c8971edd9 | 321 | uint32_t |
LordOfDorks | 0:b11c8971edd9 | 322 | TISTPM20::TPM2_GetRandom( |
LordOfDorks | 0:b11c8971edd9 | 323 | uint8_t locality, |
LordOfDorks | 0:b11c8971edd9 | 324 | uint16_t bytesRequested, |
LordOfDorks | 0:b11c8971edd9 | 325 | uint8_t* randomBytes |
LordOfDorks | 0:b11c8971edd9 | 326 | ) |
LordOfDorks | 0:b11c8971edd9 | 327 | { |
LordOfDorks | 0:b11c8971edd9 | 328 | uint32_t cursor = 0; |
LordOfDorks | 0:b11c8971edd9 | 329 | uint32_t rspLen = 0; |
LordOfDorks | 0:b11c8971edd9 | 330 | uint16_t rspTag = 0; |
LordOfDorks | 0:b11c8971edd9 | 331 | uint32_t rspSize = 0; |
LordOfDorks | 0:b11c8971edd9 | 332 | uint32_t rspResponseCode = 0; |
LordOfDorks | 0:b11c8971edd9 | 333 | uint32_t tpmMax = sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint16_t) + bytesRequested; |
LordOfDorks | 0:b11c8971edd9 | 334 | uint8_t* tpmCmd = new uint8_t[tpmMax]; |
LordOfDorks | 0:b11c8971edd9 | 335 | uint16_t bytesReturned = 0; |
LordOfDorks | 0:b11c8971edd9 | 336 | #ifndef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 337 | uint32_t timeout = 2000; |
LordOfDorks | 0:b11c8971edd9 | 338 | #else |
LordOfDorks | 0:b11c8971edd9 | 339 | uint32_t timeout = 20000; |
LordOfDorks | 0:b11c8971edd9 | 340 | #endif |
LordOfDorks | 0:b11c8971edd9 | 341 | |
LordOfDorks | 0:b11c8971edd9 | 342 | if(tpmCmd == NULL) |
LordOfDorks | 0:b11c8971edd9 | 343 | { |
LordOfDorks | 0:b11c8971edd9 | 344 | rspResponseCode = TPM_RC_FAILURE; |
LordOfDorks | 0:b11c8971edd9 | 345 | goto Cleanup; |
LordOfDorks | 0:b11c8971edd9 | 346 | } |
LordOfDorks | 0:b11c8971edd9 | 347 | |
LordOfDorks | 0:b11c8971edd9 | 348 | // Build command |
LordOfDorks | 0:b11c8971edd9 | 349 | UINT16_TO_BYTEARRAY(TPM_ST_NO_SESSIONS, tpmCmd, cursor); |
LordOfDorks | 0:b11c8971edd9 | 350 | cursor += sizeof(uint16_t) + sizeof(cursor); |
LordOfDorks | 0:b11c8971edd9 | 351 | UINT32_TO_BYTEARRAY(TPM_CC_GetRandom, tpmCmd, cursor); |
LordOfDorks | 0:b11c8971edd9 | 352 | cursor += sizeof(TPM_CC_GetRandom); |
LordOfDorks | 0:b11c8971edd9 | 353 | UINT16_TO_BYTEARRAY(bytesRequested, tpmCmd, cursor); |
LordOfDorks | 0:b11c8971edd9 | 354 | cursor += sizeof(bytesRequested); |
LordOfDorks | 0:b11c8971edd9 | 355 | UINT32_TO_BYTEARRAY(cursor, tpmCmd, sizeof(uint16_t)); |
LordOfDorks | 0:b11c8971edd9 | 356 | |
LordOfDorks | 0:b11c8971edd9 | 357 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 358 | printf("TIS.TPM2_GetRandom(%d)\n\r", bytesRequested); |
LordOfDorks | 0:b11c8971edd9 | 359 | #endif |
LordOfDorks | 0:b11c8971edd9 | 360 | |
LordOfDorks | 0:b11c8971edd9 | 361 | if((rspLen = Execute(locality, tpmCmd, cursor, tpmCmd, tpmMax, timeout)) == 0) |
LordOfDorks | 0:b11c8971edd9 | 362 | { |
LordOfDorks | 0:b11c8971edd9 | 363 | rspResponseCode = TPM_RC_FAILURE; |
LordOfDorks | 0:b11c8971edd9 | 364 | goto Cleanup; |
LordOfDorks | 0:b11c8971edd9 | 365 | } |
LordOfDorks | 0:b11c8971edd9 | 366 | cursor = 0; |
LordOfDorks | 0:b11c8971edd9 | 367 | if((rspResponseCode = ParseResponseHeader(tpmCmd, rspLen, &rspTag, &rspSize, &cursor)) != TPM_RC_SUCCESS) |
LordOfDorks | 0:b11c8971edd9 | 368 | { |
LordOfDorks | 0:b11c8971edd9 | 369 | goto Cleanup; |
LordOfDorks | 0:b11c8971edd9 | 370 | } |
LordOfDorks | 0:b11c8971edd9 | 371 | |
LordOfDorks | 0:b11c8971edd9 | 372 | if(rspSize != tpmMax) |
LordOfDorks | 0:b11c8971edd9 | 373 | { |
LordOfDorks | 0:b11c8971edd9 | 374 | rspResponseCode = TPM_RC_FAILURE; |
LordOfDorks | 0:b11c8971edd9 | 375 | goto Cleanup; |
LordOfDorks | 0:b11c8971edd9 | 376 | } |
LordOfDorks | 0:b11c8971edd9 | 377 | |
LordOfDorks | 0:b11c8971edd9 | 378 | // Copy the random bytes out |
LordOfDorks | 0:b11c8971edd9 | 379 | bytesReturned = BYTEARRAY_TO_UINT16(tpmCmd, cursor); |
LordOfDorks | 0:b11c8971edd9 | 380 | cursor += sizeof(uint16_t); |
LordOfDorks | 0:b11c8971edd9 | 381 | memcpy(randomBytes, &tpmCmd[cursor], (size_t)min(bytesReturned, bytesRequested)); |
LordOfDorks | 0:b11c8971edd9 | 382 | |
LordOfDorks | 0:b11c8971edd9 | 383 | Cleanup: |
LordOfDorks | 0:b11c8971edd9 | 384 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 385 | printf("TIS.TPM2_GetRandom.ResponseCode = 0x%08x\n\r", rspResponseCode); |
LordOfDorks | 0:b11c8971edd9 | 386 | #endif |
LordOfDorks | 0:b11c8971edd9 | 387 | if(tpmCmd != NULL) |
LordOfDorks | 0:b11c8971edd9 | 388 | { |
LordOfDorks | 0:b11c8971edd9 | 389 | delete[] tpmCmd; |
LordOfDorks | 0:b11c8971edd9 | 390 | tpmCmd = NULL; |
LordOfDorks | 0:b11c8971edd9 | 391 | } |
LordOfDorks | 0:b11c8971edd9 | 392 | return rspResponseCode; |
LordOfDorks | 0:b11c8971edd9 | 393 | } |
LordOfDorks | 0:b11c8971edd9 | 394 | |
LordOfDorks | 0:b11c8971edd9 | 395 | uint32_t |
LordOfDorks | 0:b11c8971edd9 | 396 | TISTPM20::TPM2_StirRandom( |
LordOfDorks | 0:b11c8971edd9 | 397 | uint8_t locality, |
LordOfDorks | 0:b11c8971edd9 | 398 | uint16_t inDataLen, |
LordOfDorks | 0:b11c8971edd9 | 399 | uint8_t* inData |
LordOfDorks | 0:b11c8971edd9 | 400 | ) |
LordOfDorks | 0:b11c8971edd9 | 401 | { |
LordOfDorks | 0:b11c8971edd9 | 402 | uint32_t cursor = 0; |
LordOfDorks | 0:b11c8971edd9 | 403 | uint32_t rspLen = 0; |
LordOfDorks | 0:b11c8971edd9 | 404 | uint16_t rspTag = 0; |
LordOfDorks | 0:b11c8971edd9 | 405 | uint32_t rspSize = 0; |
LordOfDorks | 0:b11c8971edd9 | 406 | uint32_t rspResponseCode = 0; |
LordOfDorks | 0:b11c8971edd9 | 407 | uint32_t tpmMax = sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint16_t) + inDataLen; |
LordOfDorks | 0:b11c8971edd9 | 408 | uint8_t* tpmCmd = new uint8_t[tpmMax]; |
LordOfDorks | 0:b11c8971edd9 | 409 | #ifndef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 410 | uint32_t timeout = 2000; |
LordOfDorks | 0:b11c8971edd9 | 411 | #else |
LordOfDorks | 0:b11c8971edd9 | 412 | uint32_t timeout = 20000; |
LordOfDorks | 0:b11c8971edd9 | 413 | #endif |
LordOfDorks | 0:b11c8971edd9 | 414 | |
LordOfDorks | 0:b11c8971edd9 | 415 | if(tpmCmd == NULL) |
LordOfDorks | 0:b11c8971edd9 | 416 | { |
LordOfDorks | 0:b11c8971edd9 | 417 | rspResponseCode = TPM_RC_FAILURE; |
LordOfDorks | 0:b11c8971edd9 | 418 | goto Cleanup; |
LordOfDorks | 0:b11c8971edd9 | 419 | } |
LordOfDorks | 0:b11c8971edd9 | 420 | |
LordOfDorks | 0:b11c8971edd9 | 421 | // Build command |
LordOfDorks | 0:b11c8971edd9 | 422 | UINT16_TO_BYTEARRAY(TPM_ST_NO_SESSIONS, tpmCmd, cursor); |
LordOfDorks | 0:b11c8971edd9 | 423 | cursor += sizeof(uint16_t) + sizeof(cursor); |
LordOfDorks | 0:b11c8971edd9 | 424 | UINT32_TO_BYTEARRAY(TPM_CC_StirRandom, tpmCmd, cursor); |
LordOfDorks | 0:b11c8971edd9 | 425 | cursor += sizeof(TPM_CC_GetRandom); |
LordOfDorks | 0:b11c8971edd9 | 426 | UINT16_TO_BYTEARRAY(inDataLen, tpmCmd, cursor); |
LordOfDorks | 0:b11c8971edd9 | 427 | cursor += sizeof(inDataLen); |
LordOfDorks | 0:b11c8971edd9 | 428 | memcpy(&tpmCmd[cursor], inData, inDataLen); |
LordOfDorks | 0:b11c8971edd9 | 429 | cursor += inDataLen; |
LordOfDorks | 0:b11c8971edd9 | 430 | UINT32_TO_BYTEARRAY(cursor, tpmCmd, sizeof(uint16_t)); |
LordOfDorks | 0:b11c8971edd9 | 431 | |
LordOfDorks | 0:b11c8971edd9 | 432 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 433 | printf("TIS.TPM2_StirRandom(%d)\n\r", inDataLen); |
LordOfDorks | 0:b11c8971edd9 | 434 | #endif |
LordOfDorks | 0:b11c8971edd9 | 435 | |
LordOfDorks | 0:b11c8971edd9 | 436 | if((rspLen = Execute(locality, tpmCmd, cursor, tpmCmd, tpmMax, timeout)) == 0) |
LordOfDorks | 0:b11c8971edd9 | 437 | { |
LordOfDorks | 0:b11c8971edd9 | 438 | rspResponseCode = TPM_RC_FAILURE; |
LordOfDorks | 0:b11c8971edd9 | 439 | goto Cleanup; |
LordOfDorks | 0:b11c8971edd9 | 440 | } |
LordOfDorks | 0:b11c8971edd9 | 441 | cursor = 0; |
LordOfDorks | 0:b11c8971edd9 | 442 | if((rspResponseCode = ParseResponseHeader(tpmCmd, rspLen, &rspTag, &rspSize, &cursor)) != TPM_RC_SUCCESS) |
LordOfDorks | 0:b11c8971edd9 | 443 | { |
LordOfDorks | 0:b11c8971edd9 | 444 | goto Cleanup; |
LordOfDorks | 0:b11c8971edd9 | 445 | } |
LordOfDorks | 0:b11c8971edd9 | 446 | |
LordOfDorks | 0:b11c8971edd9 | 447 | if(rspSize != 0x0000000a) |
LordOfDorks | 0:b11c8971edd9 | 448 | { |
LordOfDorks | 0:b11c8971edd9 | 449 | rspResponseCode = TPM_RC_FAILURE; |
LordOfDorks | 0:b11c8971edd9 | 450 | goto Cleanup; |
LordOfDorks | 0:b11c8971edd9 | 451 | } |
LordOfDorks | 0:b11c8971edd9 | 452 | |
LordOfDorks | 0:b11c8971edd9 | 453 | Cleanup: |
LordOfDorks | 0:b11c8971edd9 | 454 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 455 | printf("TIS.TPM2_StirRandom.ResponseCode = 0x%08x\n\r", rspResponseCode); |
LordOfDorks | 0:b11c8971edd9 | 456 | #endif |
LordOfDorks | 0:b11c8971edd9 | 457 | if(tpmCmd != NULL) |
LordOfDorks | 0:b11c8971edd9 | 458 | { |
LordOfDorks | 0:b11c8971edd9 | 459 | delete[] tpmCmd; |
LordOfDorks | 0:b11c8971edd9 | 460 | tpmCmd = NULL; |
LordOfDorks | 0:b11c8971edd9 | 461 | } |
LordOfDorks | 0:b11c8971edd9 | 462 | return rspResponseCode; |
LordOfDorks | 0:b11c8971edd9 | 463 | } |
LordOfDorks | 0:b11c8971edd9 | 464 | |
LordOfDorks | 0:b11c8971edd9 | 465 | void |
LordOfDorks | 0:b11c8971edd9 | 466 | TISTPM20::TimeoutTrigger( |
LordOfDorks | 0:b11c8971edd9 | 467 | void |
LordOfDorks | 0:b11c8971edd9 | 468 | ) |
LordOfDorks | 0:b11c8971edd9 | 469 | { |
LordOfDorks | 0:b11c8971edd9 | 470 | m_TimeoutTriggered = true; |
LordOfDorks | 0:b11c8971edd9 | 471 | } |
LordOfDorks | 0:b11c8971edd9 | 472 | |
LordOfDorks | 0:b11c8971edd9 | 473 | uint32_t |
LordOfDorks | 0:b11c8971edd9 | 474 | TISTPM20::ExecuteTIS( |
LordOfDorks | 0:b11c8971edd9 | 475 | uint8_t* pbCmd, |
LordOfDorks | 0:b11c8971edd9 | 476 | uint32_t cbCmd, |
LordOfDorks | 0:b11c8971edd9 | 477 | uint8_t* pbRsp, |
LordOfDorks | 0:b11c8971edd9 | 478 | uint32_t cbRsp |
LordOfDorks | 0:b11c8971edd9 | 479 | ) |
LordOfDorks | 0:b11c8971edd9 | 480 | { |
LordOfDorks | 0:b11c8971edd9 | 481 | uint32_t result = 0; |
LordOfDorks | 0:b11c8971edd9 | 482 | uint8_t tisStatus = 0xFF; |
LordOfDorks | 0:b11c8971edd9 | 483 | uint32_t index = 0; |
LordOfDorks | 0:b11c8971edd9 | 484 | uint32_t rspSize = 0; |
LordOfDorks | 0:b11c8971edd9 | 485 | uint16_t tisBurstCount = 0; |
LordOfDorks | 0:b11c8971edd9 | 486 | |
LordOfDorks | 0:b11c8971edd9 | 487 | // Lock the requested locality |
LordOfDorks | 0:b11c8971edd9 | 488 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 489 | printf("TIS.RequestLocality\r\n"); |
LordOfDorks | 0:b11c8971edd9 | 490 | #endif |
LordOfDorks | 0:b11c8971edd9 | 491 | if(!RequestLocality()) |
LordOfDorks | 0:b11c8971edd9 | 492 | { |
LordOfDorks | 0:b11c8971edd9 | 493 | goto Cleanup; |
LordOfDorks | 0:b11c8971edd9 | 494 | } |
LordOfDorks | 0:b11c8971edd9 | 495 | |
LordOfDorks | 0:b11c8971edd9 | 496 | // Check the status before writing the command |
LordOfDorks | 0:b11c8971edd9 | 497 | if(!GetStatus(&tisStatus)) |
LordOfDorks | 0:b11c8971edd9 | 498 | { |
LordOfDorks | 0:b11c8971edd9 | 499 | goto Cleanup; |
LordOfDorks | 0:b11c8971edd9 | 500 | } |
LordOfDorks | 0:b11c8971edd9 | 501 | // Abort anything that may still be stuck in the TPM |
LordOfDorks | 0:b11c8971edd9 | 502 | if((tisStatus & TIS_STS_COMMAND_READY) == 0) |
LordOfDorks | 0:b11c8971edd9 | 503 | { |
LordOfDorks | 0:b11c8971edd9 | 504 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 505 | printf("TIS.GetReady\r\n"); |
LordOfDorks | 0:b11c8971edd9 | 506 | #endif |
LordOfDorks | 0:b11c8971edd9 | 507 | uint8_t mask = TIS_STS_COMMAND_READY; |
LordOfDorks | 0:b11c8971edd9 | 508 | if(!Abort() || !WaitForStatus(mask)) |
LordOfDorks | 0:b11c8971edd9 | 509 | { |
LordOfDorks | 0:b11c8971edd9 | 510 | goto Cleanup; |
LordOfDorks | 0:b11c8971edd9 | 511 | } |
LordOfDorks | 0:b11c8971edd9 | 512 | } |
LordOfDorks | 0:b11c8971edd9 | 513 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 514 | printf("TIS.ReadyForCommand\r\n"); |
LordOfDorks | 0:b11c8971edd9 | 515 | #endif |
LordOfDorks | 0:b11c8971edd9 | 516 | |
LordOfDorks | 0:b11c8971edd9 | 517 | // Send the command to the TPM |
LordOfDorks | 0:b11c8971edd9 | 518 | do |
LordOfDorks | 0:b11c8971edd9 | 519 | { |
LordOfDorks | 0:b11c8971edd9 | 520 | uint16_t cbIteration = 0; |
LordOfDorks | 0:b11c8971edd9 | 521 | |
LordOfDorks | 0:b11c8971edd9 | 522 | // Get the maximum bytes we can send for this iteration |
LordOfDorks | 0:b11c8971edd9 | 523 | if((!GetBurstCount(&tisBurstCount)) || (tisBurstCount == 0)) |
LordOfDorks | 0:b11c8971edd9 | 524 | { |
LordOfDorks | 0:b11c8971edd9 | 525 | goto Cleanup; |
LordOfDorks | 0:b11c8971edd9 | 526 | } |
LordOfDorks | 0:b11c8971edd9 | 527 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 528 | printf("TIS.GetBurstCount = %d\r\n", tisBurstCount); |
LordOfDorks | 0:b11c8971edd9 | 529 | #endif |
LordOfDorks | 0:b11c8971edd9 | 530 | |
LordOfDorks | 0:b11c8971edd9 | 531 | // Assemble the buffer for transmission |
LordOfDorks | 0:b11c8971edd9 | 532 | cbIteration = min((cbCmd - index), min(tisBurstCount, TIS_MAX_HW_FRAME_SIZE)); |
LordOfDorks | 0:b11c8971edd9 | 533 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 534 | printf("TIS.SendingBurst = %d\r\n", cbIteration); |
LordOfDorks | 0:b11c8971edd9 | 535 | #endif |
LordOfDorks | 0:b11c8971edd9 | 536 | if(!SPIFullDuplex(false, TIS_DATA_FIFO, &pbCmd[index], cbIteration)) |
LordOfDorks | 0:b11c8971edd9 | 537 | { |
LordOfDorks | 0:b11c8971edd9 | 538 | goto Cleanup; |
LordOfDorks | 0:b11c8971edd9 | 539 | } |
LordOfDorks | 0:b11c8971edd9 | 540 | |
LordOfDorks | 0:b11c8971edd9 | 541 | // Update the counts |
LordOfDorks | 0:b11c8971edd9 | 542 | index += cbIteration; |
LordOfDorks | 0:b11c8971edd9 | 543 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 544 | printf("TIS.Remaining = %d\r\n", (cbCmd - index)); |
LordOfDorks | 0:b11c8971edd9 | 545 | #endif |
LordOfDorks | 0:b11c8971edd9 | 546 | } while((cbCmd - index) > 0); |
LordOfDorks | 0:b11c8971edd9 | 547 | |
LordOfDorks | 0:b11c8971edd9 | 548 | // Wait for the TPM to get ready and kick the command off |
LordOfDorks | 0:b11c8971edd9 | 549 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 550 | printf("TIS.StatusValid\r\n"); |
LordOfDorks | 0:b11c8971edd9 | 551 | #endif |
LordOfDorks | 0:b11c8971edd9 | 552 | if(!WaitForStatus(TIS_STS_VALID) || !Go()) |
LordOfDorks | 0:b11c8971edd9 | 553 | { |
LordOfDorks | 0:b11c8971edd9 | 554 | goto Cleanup; |
LordOfDorks | 0:b11c8971edd9 | 555 | } |
LordOfDorks | 0:b11c8971edd9 | 556 | |
LordOfDorks | 0:b11c8971edd9 | 557 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 558 | printf("TIS.Go\r\n"); |
LordOfDorks | 0:b11c8971edd9 | 559 | #endif |
LordOfDorks | 0:b11c8971edd9 | 560 | |
LordOfDorks | 0:b11c8971edd9 | 561 | // Wait for the TPM to finish the command execution |
LordOfDorks | 0:b11c8971edd9 | 562 | do |
LordOfDorks | 0:b11c8971edd9 | 563 | { |
LordOfDorks | 0:b11c8971edd9 | 564 | wait_us(1000); |
LordOfDorks | 0:b11c8971edd9 | 565 | tisStatus = 0xFF; |
LordOfDorks | 0:b11c8971edd9 | 566 | if(!GetStatus(&tisStatus) || ((tisStatus & TIS_STS_VALID) == 0)) |
LordOfDorks | 0:b11c8971edd9 | 567 | { |
LordOfDorks | 0:b11c8971edd9 | 568 | goto Cleanup; |
LordOfDorks | 0:b11c8971edd9 | 569 | } |
LordOfDorks | 0:b11c8971edd9 | 570 | } |
LordOfDorks | 0:b11c8971edd9 | 571 | while(((tisStatus & TIS_STS_DATA_AVAIL) == 0) && (!m_TimeoutTriggered)); |
LordOfDorks | 0:b11c8971edd9 | 572 | |
LordOfDorks | 0:b11c8971edd9 | 573 | if(m_TimeoutTriggered) |
LordOfDorks | 0:b11c8971edd9 | 574 | { |
LordOfDorks | 0:b11c8971edd9 | 575 | goto Cleanup; |
LordOfDorks | 0:b11c8971edd9 | 576 | } |
LordOfDorks | 0:b11c8971edd9 | 577 | |
LordOfDorks | 0:b11c8971edd9 | 578 | // Get the response header from the TPM |
LordOfDorks | 0:b11c8971edd9 | 579 | index = 0; |
LordOfDorks | 0:b11c8971edd9 | 580 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 581 | printf("Tis.ReadResponseHeader\r\n"); |
LordOfDorks | 0:b11c8971edd9 | 582 | #endif |
LordOfDorks | 0:b11c8971edd9 | 583 | if(!GetBurstCount(&tisBurstCount) || |
LordOfDorks | 0:b11c8971edd9 | 584 | (tisBurstCount < (sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint32_t))) || |
LordOfDorks | 0:b11c8971edd9 | 585 | !SPIFullDuplex(true, TIS_DATA_FIFO, &pbRsp[index], (sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint32_t)))) |
LordOfDorks | 0:b11c8971edd9 | 586 | { |
LordOfDorks | 0:b11c8971edd9 | 587 | goto Cleanup; |
LordOfDorks | 0:b11c8971edd9 | 588 | } |
LordOfDorks | 0:b11c8971edd9 | 589 | index += (sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint32_t)); |
LordOfDorks | 0:b11c8971edd9 | 590 | |
LordOfDorks | 0:b11c8971edd9 | 591 | rspSize = BYTEARRAY_TO_UINT32(pbRsp, sizeof(uint16_t)); |
LordOfDorks | 0:b11c8971edd9 | 592 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 593 | printf("Tis.ResponseSize = %d\r\n", rspSize); |
LordOfDorks | 0:b11c8971edd9 | 594 | #endif |
LordOfDorks | 0:b11c8971edd9 | 595 | |
LordOfDorks | 0:b11c8971edd9 | 596 | if(rspSize > index) |
LordOfDorks | 0:b11c8971edd9 | 597 | { |
LordOfDorks | 0:b11c8971edd9 | 598 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 599 | printf("Tis.ReadResponse\r\n"); |
LordOfDorks | 0:b11c8971edd9 | 600 | #endif |
LordOfDorks | 0:b11c8971edd9 | 601 | do |
LordOfDorks | 0:b11c8971edd9 | 602 | { |
LordOfDorks | 0:b11c8971edd9 | 603 | uint16_t cbIteration = 0; |
LordOfDorks | 0:b11c8971edd9 | 604 | |
LordOfDorks | 0:b11c8971edd9 | 605 | // Check to make sure the TPM has still data for us |
LordOfDorks | 0:b11c8971edd9 | 606 | if(!GetStatus(&tisStatus) || ((tisStatus & TIS_STS_DATA_AVAIL) == 0)) |
LordOfDorks | 0:b11c8971edd9 | 607 | { |
LordOfDorks | 0:b11c8971edd9 | 608 | goto Cleanup; |
LordOfDorks | 0:b11c8971edd9 | 609 | } |
LordOfDorks | 0:b11c8971edd9 | 610 | |
LordOfDorks | 0:b11c8971edd9 | 611 | // Get the number of available bytes for reading in this iteration |
LordOfDorks | 0:b11c8971edd9 | 612 | if(!GetBurstCount(&tisBurstCount)) |
LordOfDorks | 0:b11c8971edd9 | 613 | { |
LordOfDorks | 0:b11c8971edd9 | 614 | goto Cleanup; |
LordOfDorks | 0:b11c8971edd9 | 615 | } |
LordOfDorks | 0:b11c8971edd9 | 616 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 617 | printf("TIS.GetBurstCount = %d\r\n", tisBurstCount); |
LordOfDorks | 0:b11c8971edd9 | 618 | #endif |
LordOfDorks | 0:b11c8971edd9 | 619 | |
LordOfDorks | 0:b11c8971edd9 | 620 | cbIteration = min((rspSize - index), min((cbRsp - index), min(tisBurstCount, TIS_MAX_HW_FRAME_SIZE))); |
LordOfDorks | 0:b11c8971edd9 | 621 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 622 | printf("TIS.ReceivingBurst = %d\r\n", cbIteration); |
LordOfDorks | 0:b11c8971edd9 | 623 | #endif |
LordOfDorks | 0:b11c8971edd9 | 624 | |
LordOfDorks | 0:b11c8971edd9 | 625 | // Read the data for this iteration |
LordOfDorks | 0:b11c8971edd9 | 626 | if(!SPIFullDuplex(true, TIS_DATA_FIFO, &pbRsp[index], cbIteration)) |
LordOfDorks | 0:b11c8971edd9 | 627 | { |
LordOfDorks | 0:b11c8971edd9 | 628 | goto Cleanup; |
LordOfDorks | 0:b11c8971edd9 | 629 | } |
LordOfDorks | 0:b11c8971edd9 | 630 | index += cbIteration; |
LordOfDorks | 0:b11c8971edd9 | 631 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 632 | printf("TIS.Remaining = %d\r\n", (min(rspSize, cbRsp) - index)); |
LordOfDorks | 0:b11c8971edd9 | 633 | #endif |
LordOfDorks | 0:b11c8971edd9 | 634 | } |
LordOfDorks | 0:b11c8971edd9 | 635 | while(index < min(rspSize, cbRsp)); |
LordOfDorks | 0:b11c8971edd9 | 636 | } |
LordOfDorks | 0:b11c8971edd9 | 637 | |
LordOfDorks | 0:b11c8971edd9 | 638 | result = index; |
LordOfDorks | 0:b11c8971edd9 | 639 | |
LordOfDorks | 0:b11c8971edd9 | 640 | Cleanup: |
LordOfDorks | 0:b11c8971edd9 | 641 | // Always leave the TPM in a clean state if somethign fishy happened |
LordOfDorks | 0:b11c8971edd9 | 642 | if(result == 0) |
LordOfDorks | 0:b11c8971edd9 | 643 | { |
LordOfDorks | 0:b11c8971edd9 | 644 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 645 | printf("TIS.Abort\r\n"); |
LordOfDorks | 0:b11c8971edd9 | 646 | #endif |
LordOfDorks | 0:b11c8971edd9 | 647 | Abort(); |
LordOfDorks | 0:b11c8971edd9 | 648 | } |
LordOfDorks | 0:b11c8971edd9 | 649 | |
LordOfDorks | 0:b11c8971edd9 | 650 | // Release the locality again |
LordOfDorks | 0:b11c8971edd9 | 651 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 652 | printf("TIS.ReleaseLocality\r\n"); |
LordOfDorks | 0:b11c8971edd9 | 653 | #endif |
LordOfDorks | 0:b11c8971edd9 | 654 | ReleaseLocality(); |
LordOfDorks | 0:b11c8971edd9 | 655 | return result; |
LordOfDorks | 0:b11c8971edd9 | 656 | } |
LordOfDorks | 0:b11c8971edd9 | 657 | |
LordOfDorks | 0:b11c8971edd9 | 658 | bool |
LordOfDorks | 0:b11c8971edd9 | 659 | TISTPM20::SPIFullDuplex( |
LordOfDorks | 0:b11c8971edd9 | 660 | bool readCycle, |
LordOfDorks | 0:b11c8971edd9 | 661 | uint8_t tisRegister, |
LordOfDorks | 0:b11c8971edd9 | 662 | uint8_t* pbBuffer, |
LordOfDorks | 0:b11c8971edd9 | 663 | uint16_t cbBuffer |
LordOfDorks | 0:b11c8971edd9 | 664 | ) |
LordOfDorks | 0:b11c8971edd9 | 665 | { |
LordOfDorks | 0:b11c8971edd9 | 666 | bool result = false; |
LordOfDorks | 0:b11c8971edd9 | 667 | uint8_t dataByteIn; |
LordOfDorks | 0:b11c8971edd9 | 668 | uint8_t dataByteOut; |
LordOfDorks | 0:b11c8971edd9 | 669 | |
LordOfDorks | 0:b11c8971edd9 | 670 | // Lock the bus for this operation |
LordOfDorks | 0:b11c8971edd9 | 671 | *m_SPICSTpmDev = 0; |
LordOfDorks | 0:b11c8971edd9 | 672 | |
LordOfDorks | 0:b11c8971edd9 | 673 | // Send the TIS header |
LordOfDorks | 0:b11c8971edd9 | 674 | uint32_t tisHdr = TIS_HEADER(m_Locality, readCycle, tisRegister, cbBuffer); |
LordOfDorks | 0:b11c8971edd9 | 675 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 676 | printf("TIS(LC:%d,RG:%02x,SZ:%02x,%s):", m_Locality, tisRegister, cbBuffer, (readCycle) ? "RD" : "WR"); |
LordOfDorks | 0:b11c8971edd9 | 677 | #endif |
LordOfDorks | 0:b11c8971edd9 | 678 | |
LordOfDorks | 0:b11c8971edd9 | 679 | for(uint8_t n = 0; n < sizeof(tisHdr); n++) |
LordOfDorks | 0:b11c8971edd9 | 680 | { |
LordOfDorks | 0:b11c8971edd9 | 681 | dataByteOut = tisHdr >> (8 * (3 - n)); |
LordOfDorks | 0:b11c8971edd9 | 682 | dataByteIn = m_SPITpmDev->write(dataByteOut); |
LordOfDorks | 0:b11c8971edd9 | 683 | } |
LordOfDorks | 0:b11c8971edd9 | 684 | |
LordOfDorks | 0:b11c8971edd9 | 685 | // The last read bit is the wait state indicator |
LordOfDorks | 0:b11c8971edd9 | 686 | if((dataByteIn & 0x01) == 0) |
LordOfDorks | 0:b11c8971edd9 | 687 | { |
LordOfDorks | 0:b11c8971edd9 | 688 | do |
LordOfDorks | 0:b11c8971edd9 | 689 | { |
LordOfDorks | 0:b11c8971edd9 | 690 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 691 | printf("."); |
LordOfDorks | 0:b11c8971edd9 | 692 | #endif |
LordOfDorks | 0:b11c8971edd9 | 693 | // Do we still have to wait? |
LordOfDorks | 0:b11c8971edd9 | 694 | if((dataByteIn = m_SPITpmDev->write(0xFF)) != 0x01) |
LordOfDorks | 0:b11c8971edd9 | 695 | { |
LordOfDorks | 0:b11c8971edd9 | 696 | wait_us(10); |
LordOfDorks | 0:b11c8971edd9 | 697 | } |
LordOfDorks | 0:b11c8971edd9 | 698 | } |
LordOfDorks | 0:b11c8971edd9 | 699 | while((dataByteIn != 0x01) && (!m_TimeoutTriggered)); |
LordOfDorks | 0:b11c8971edd9 | 700 | |
LordOfDorks | 0:b11c8971edd9 | 701 | // Check if we timed out |
LordOfDorks | 0:b11c8971edd9 | 702 | if((dataByteIn != 0x01) && (m_TimeoutTriggered)) |
LordOfDorks | 0:b11c8971edd9 | 703 | { |
LordOfDorks | 0:b11c8971edd9 | 704 | goto Cleanup; |
LordOfDorks | 0:b11c8971edd9 | 705 | } |
LordOfDorks | 0:b11c8971edd9 | 706 | } |
LordOfDorks | 0:b11c8971edd9 | 707 | |
LordOfDorks | 0:b11c8971edd9 | 708 | // Do the remaining bytes now |
LordOfDorks | 0:b11c8971edd9 | 709 | for(uint8_t n = 0; n < cbBuffer; n++) |
LordOfDorks | 0:b11c8971edd9 | 710 | { |
LordOfDorks | 0:b11c8971edd9 | 711 | dataByteOut = (readCycle) ? 0xFF : pbBuffer[n]; |
LordOfDorks | 0:b11c8971edd9 | 712 | dataByteIn = m_SPITpmDev->write(dataByteOut); |
LordOfDorks | 0:b11c8971edd9 | 713 | if(readCycle) pbBuffer[n] = dataByteIn; |
LordOfDorks | 0:b11c8971edd9 | 714 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 715 | printf("0x%02x ", (readCycle) ? dataByteIn : dataByteOut); |
LordOfDorks | 0:b11c8971edd9 | 716 | #endif |
LordOfDorks | 0:b11c8971edd9 | 717 | } |
LordOfDorks | 0:b11c8971edd9 | 718 | result = true; |
LordOfDorks | 0:b11c8971edd9 | 719 | #ifdef TPM_TIS_DEBUG_OUTPUT |
LordOfDorks | 0:b11c8971edd9 | 720 | printf("\r\n"); |
LordOfDorks | 0:b11c8971edd9 | 721 | #endif |
LordOfDorks | 0:b11c8971edd9 | 722 | |
LordOfDorks | 0:b11c8971edd9 | 723 | Cleanup: |
LordOfDorks | 0:b11c8971edd9 | 724 | // Make sure to release the bus before we leave |
LordOfDorks | 0:b11c8971edd9 | 725 | *m_SPICSTpmDev = 1; |
LordOfDorks | 0:b11c8971edd9 | 726 | return result; |
LordOfDorks | 0:b11c8971edd9 | 727 | } |
LordOfDorks | 0:b11c8971edd9 | 728 | |
LordOfDorks | 0:b11c8971edd9 | 729 | bool |
LordOfDorks | 0:b11c8971edd9 | 730 | TISTPM20::RequestLocality() |
LordOfDorks | 0:b11c8971edd9 | 731 | { |
LordOfDorks | 0:b11c8971edd9 | 732 | do |
LordOfDorks | 0:b11c8971edd9 | 733 | { |
LordOfDorks | 0:b11c8971edd9 | 734 | // Do we have access already? |
LordOfDorks | 0:b11c8971edd9 | 735 | uint8_t dataByte = 0xFF; |
LordOfDorks | 0:b11c8971edd9 | 736 | if(!SPIFullDuplex(true, TIS_ACCESS_REGISTER, &dataByte, sizeof(dataByte))) |
LordOfDorks | 0:b11c8971edd9 | 737 | { |
LordOfDorks | 0:b11c8971edd9 | 738 | return false; |
LordOfDorks | 0:b11c8971edd9 | 739 | } |
LordOfDorks | 0:b11c8971edd9 | 740 | if((dataByte & TIS_ACCESS_ACTIVE_LOCALITY) && |
LordOfDorks | 0:b11c8971edd9 | 741 | (dataByte & TIS_ACCESS_VALID)) |
LordOfDorks | 0:b11c8971edd9 | 742 | { |
LordOfDorks | 0:b11c8971edd9 | 743 | break; |
LordOfDorks | 0:b11c8971edd9 | 744 | } |
LordOfDorks | 0:b11c8971edd9 | 745 | |
LordOfDorks | 0:b11c8971edd9 | 746 | // Request access |
LordOfDorks | 0:b11c8971edd9 | 747 | dataByte = TIS_ACCESS_REQUEST_USE; |
LordOfDorks | 0:b11c8971edd9 | 748 | if(!SPIFullDuplex(false, TIS_ACCESS_REGISTER, &dataByte, sizeof(dataByte))) |
LordOfDorks | 0:b11c8971edd9 | 749 | { |
LordOfDorks | 0:b11c8971edd9 | 750 | return false; |
LordOfDorks | 0:b11c8971edd9 | 751 | } |
LordOfDorks | 0:b11c8971edd9 | 752 | if(m_TimeoutTriggered) |
LordOfDorks | 0:b11c8971edd9 | 753 | { |
LordOfDorks | 0:b11c8971edd9 | 754 | // We give up eventually |
LordOfDorks | 0:b11c8971edd9 | 755 | return false; |
LordOfDorks | 0:b11c8971edd9 | 756 | } |
LordOfDorks | 0:b11c8971edd9 | 757 | wait_us(10); |
LordOfDorks | 0:b11c8971edd9 | 758 | } |
LordOfDorks | 0:b11c8971edd9 | 759 | while(1); |
LordOfDorks | 0:b11c8971edd9 | 760 | return true; |
LordOfDorks | 0:b11c8971edd9 | 761 | } |
LordOfDorks | 0:b11c8971edd9 | 762 | |
LordOfDorks | 0:b11c8971edd9 | 763 | bool TISTPM20::ReleaseLocality() |
LordOfDorks | 0:b11c8971edd9 | 764 | { |
LordOfDorks | 0:b11c8971edd9 | 765 | do |
LordOfDorks | 0:b11c8971edd9 | 766 | { |
LordOfDorks | 0:b11c8971edd9 | 767 | // Do we even have access? |
LordOfDorks | 0:b11c8971edd9 | 768 | uint8_t dataByte = 0xFF; |
LordOfDorks | 0:b11c8971edd9 | 769 | if(!SPIFullDuplex(true, TIS_ACCESS_REGISTER, &dataByte, sizeof(dataByte))) |
LordOfDorks | 0:b11c8971edd9 | 770 | { |
LordOfDorks | 0:b11c8971edd9 | 771 | return false; |
LordOfDorks | 0:b11c8971edd9 | 772 | } |
LordOfDorks | 0:b11c8971edd9 | 773 | if(!(dataByte & TIS_ACCESS_ACTIVE_LOCALITY) && |
LordOfDorks | 0:b11c8971edd9 | 774 | (dataByte & TIS_ACCESS_VALID)) |
LordOfDorks | 0:b11c8971edd9 | 775 | { |
LordOfDorks | 0:b11c8971edd9 | 776 | break; |
LordOfDorks | 0:b11c8971edd9 | 777 | } |
LordOfDorks | 0:b11c8971edd9 | 778 | |
LordOfDorks | 0:b11c8971edd9 | 779 | // Release access |
LordOfDorks | 0:b11c8971edd9 | 780 | dataByte = TIS_ACCESS_ACTIVE_LOCALITY; |
LordOfDorks | 0:b11c8971edd9 | 781 | if(!SPIFullDuplex(false, TIS_ACCESS_REGISTER, &dataByte, sizeof(dataByte))) |
LordOfDorks | 0:b11c8971edd9 | 782 | { |
LordOfDorks | 0:b11c8971edd9 | 783 | return false; |
LordOfDorks | 0:b11c8971edd9 | 784 | } |
LordOfDorks | 0:b11c8971edd9 | 785 | if(m_TimeoutTriggered) |
LordOfDorks | 0:b11c8971edd9 | 786 | { |
LordOfDorks | 0:b11c8971edd9 | 787 | // We give up eventually |
LordOfDorks | 0:b11c8971edd9 | 788 | return false; |
LordOfDorks | 0:b11c8971edd9 | 789 | } |
LordOfDorks | 0:b11c8971edd9 | 790 | wait_us(10); |
LordOfDorks | 0:b11c8971edd9 | 791 | } |
LordOfDorks | 0:b11c8971edd9 | 792 | while(1); |
LordOfDorks | 0:b11c8971edd9 | 793 | return true; |
LordOfDorks | 0:b11c8971edd9 | 794 | } |
LordOfDorks | 0:b11c8971edd9 | 795 | |
LordOfDorks | 0:b11c8971edd9 | 796 | bool |
LordOfDorks | 0:b11c8971edd9 | 797 | TISTPM20::GetBurstCount( |
LordOfDorks | 0:b11c8971edd9 | 798 | uint16_t* pBurstCount |
LordOfDorks | 0:b11c8971edd9 | 799 | ) |
LordOfDorks | 0:b11c8971edd9 | 800 | { |
LordOfDorks | 0:b11c8971edd9 | 801 | uint8_t dataBytes[sizeof(*pBurstCount)] = {0}; |
LordOfDorks | 0:b11c8971edd9 | 802 | do |
LordOfDorks | 0:b11c8971edd9 | 803 | { |
LordOfDorks | 0:b11c8971edd9 | 804 | if(!SPIFullDuplex(true, TIS_BURSTCOUNT_REGISTER, dataBytes, sizeof(dataBytes))) |
LordOfDorks | 0:b11c8971edd9 | 805 | { |
LordOfDorks | 0:b11c8971edd9 | 806 | return false; |
LordOfDorks | 0:b11c8971edd9 | 807 | } |
LordOfDorks | 0:b11c8971edd9 | 808 | *pBurstCount = (uint16_t)dataBytes[0] | (uint16_t)(dataBytes[1] << 8); |
LordOfDorks | 0:b11c8971edd9 | 809 | |
LordOfDorks | 0:b11c8971edd9 | 810 | // Burst count can be 0 if we are too fast |
LordOfDorks | 0:b11c8971edd9 | 811 | if(*pBurstCount != 0) |
LordOfDorks | 0:b11c8971edd9 | 812 | { |
LordOfDorks | 0:b11c8971edd9 | 813 | break; |
LordOfDorks | 0:b11c8971edd9 | 814 | } |
LordOfDorks | 0:b11c8971edd9 | 815 | if(m_TimeoutTriggered) |
LordOfDorks | 0:b11c8971edd9 | 816 | { |
LordOfDorks | 0:b11c8971edd9 | 817 | // We give up eventually |
LordOfDorks | 0:b11c8971edd9 | 818 | return false; |
LordOfDorks | 0:b11c8971edd9 | 819 | } |
LordOfDorks | 0:b11c8971edd9 | 820 | wait_us(10); |
LordOfDorks | 0:b11c8971edd9 | 821 | } |
LordOfDorks | 0:b11c8971edd9 | 822 | while(1); |
LordOfDorks | 0:b11c8971edd9 | 823 | return true; |
LordOfDorks | 0:b11c8971edd9 | 824 | } |
LordOfDorks | 0:b11c8971edd9 | 825 | |
LordOfDorks | 0:b11c8971edd9 | 826 | bool |
LordOfDorks | 0:b11c8971edd9 | 827 | TISTPM20::GetStatus( |
LordOfDorks | 0:b11c8971edd9 | 828 | uint8_t* pStatus |
LordOfDorks | 0:b11c8971edd9 | 829 | ) |
LordOfDorks | 0:b11c8971edd9 | 830 | { |
LordOfDorks | 0:b11c8971edd9 | 831 | bool result = SPIFullDuplex(true, TIS_STATUS_REGISTER, pStatus, sizeof(*pStatus)); |
LordOfDorks | 0:b11c8971edd9 | 832 | return result; |
LordOfDorks | 0:b11c8971edd9 | 833 | } |
LordOfDorks | 0:b11c8971edd9 | 834 | |
LordOfDorks | 0:b11c8971edd9 | 835 | bool |
LordOfDorks | 0:b11c8971edd9 | 836 | TISTPM20::WaitForStatus( |
LordOfDorks | 0:b11c8971edd9 | 837 | uint8_t statusMask |
LordOfDorks | 0:b11c8971edd9 | 838 | ) |
LordOfDorks | 0:b11c8971edd9 | 839 | { |
LordOfDorks | 0:b11c8971edd9 | 840 | bool result = false; |
LordOfDorks | 0:b11c8971edd9 | 841 | uint8_t tisStatus = 0xFF; |
LordOfDorks | 0:b11c8971edd9 | 842 | |
LordOfDorks | 0:b11c8971edd9 | 843 | do |
LordOfDorks | 0:b11c8971edd9 | 844 | { |
LordOfDorks | 0:b11c8971edd9 | 845 | if(!GetStatus(&tisStatus)) |
LordOfDorks | 0:b11c8971edd9 | 846 | { |
LordOfDorks | 0:b11c8971edd9 | 847 | goto Cleanup; |
LordOfDorks | 0:b11c8971edd9 | 848 | } |
LordOfDorks | 0:b11c8971edd9 | 849 | if((tisStatus & statusMask) == statusMask) |
LordOfDorks | 0:b11c8971edd9 | 850 | { |
LordOfDorks | 0:b11c8971edd9 | 851 | result = true; |
LordOfDorks | 0:b11c8971edd9 | 852 | break; |
LordOfDorks | 0:b11c8971edd9 | 853 | } |
LordOfDorks | 0:b11c8971edd9 | 854 | wait_us(10); |
LordOfDorks | 0:b11c8971edd9 | 855 | } |
LordOfDorks | 0:b11c8971edd9 | 856 | while(!m_TimeoutTriggered); |
LordOfDorks | 0:b11c8971edd9 | 857 | |
LordOfDorks | 0:b11c8971edd9 | 858 | Cleanup: |
LordOfDorks | 0:b11c8971edd9 | 859 | return result; |
LordOfDorks | 0:b11c8971edd9 | 860 | } |
LordOfDorks | 0:b11c8971edd9 | 861 | |
LordOfDorks | 0:b11c8971edd9 | 862 | bool |
LordOfDorks | 0:b11c8971edd9 | 863 | TISTPM20::Abort() |
LordOfDorks | 0:b11c8971edd9 | 864 | { |
LordOfDorks | 0:b11c8971edd9 | 865 | uint8_t dataByte = TIS_STS_COMMAND_READY; |
LordOfDorks | 0:b11c8971edd9 | 866 | return SPIFullDuplex(false, TIS_STATUS_REGISTER, &dataByte, sizeof(dataByte)); |
LordOfDorks | 0:b11c8971edd9 | 867 | } |
LordOfDorks | 0:b11c8971edd9 | 868 | |
LordOfDorks | 0:b11c8971edd9 | 869 | bool |
LordOfDorks | 0:b11c8971edd9 | 870 | TISTPM20::Go() |
LordOfDorks | 0:b11c8971edd9 | 871 | { |
LordOfDorks | 0:b11c8971edd9 | 872 | uint8_t dataByte = TIS_STS_GO; |
LordOfDorks | 0:b11c8971edd9 | 873 | return SPIFullDuplex(false, TIS_STATUS_REGISTER, &dataByte, sizeof(dataByte)); |
LordOfDorks | 0:b11c8971edd9 | 874 | } |