tis_get_tpm_version() was returning the interface version, which is always 1.2 since tis_probe() would have failed if the interface wasn't TIS.
New version check is based on the tpm2_probe() function from the Linux tpm_tis driver.
Signed-off-by: Stephen Douthit stephend@silicom-usa.com Tested-by: Stephen Douthit stephend@silicom-usa.com --- src/hw/tpm_drivers.c | 21 +++++++++++++++------ src/std/tcg.h | 1 + src/tcgbios.c | 2 +- src/tcgbios.h | 4 ++++ 4 files changed, 21 insertions(+), 7 deletions(-)
diff --git a/src/hw/tpm_drivers.c b/src/hw/tpm_drivers.c index 789d70a..32c34df 100644 --- a/src/hw/tpm_drivers.c +++ b/src/hw/tpm_drivers.c @@ -11,6 +11,7 @@ #include "config.h" // CONFIG_TPM_TIS_SHA1THRESHOLD #include "hw/tpm_drivers.h" // struct tpm_driver #include "std/tcg.h" // TCG_RESPONSE_TIMEOUT +#include "tcgbios.h" // tpm20_getcapability #include "output.h" // warn_timeout #include "stacks.h" // yield #include "string.h" // memcpy @@ -119,7 +120,7 @@ static u32 tis_probe(void) if ((didvid != 0) && (didvid != 0xffffffff)) rc = 1;
- /* TPM 2 has an interface register */ + /* Low 32 bits of CRB interface register overlap TIS interface register */ u32 ifaceid = readl(TIS_REG(0, TIS_REG_IFACE_ID));
if ((ifaceid & 0xf) != 0xf) { @@ -142,13 +143,21 @@ static u32 tis_probe(void)
static TPMVersion tis_get_tpm_version(void) { - /* TPM 2 has an interface register */ - u32 ifaceid = readl(TIS_REG(0, TIS_REG_IFACE_ID)); + u8 buffer[128]; + int ret; + struct tpm2_res_getcapability *trg = + (struct tpm2_res_getcapability *)&buffer; + + ret = tpm20_getcapability(TPM2_CAP_TPM_PROPERTIES, cpu_to_be32(0x100), + cpu_to_be32(1), &trg->hdr, sizeof(buffer)); + if (ret == TPM2_RC_INITIALIZE) + return TPM_VERSION_2; + else if (ret) + return TPM_VERSION_NONE;
- if ((ifaceid & 0xf) == 0) { - /* TPM 2 */ + if (cpu_to_be32(trg->hdr.tag) == TPM2_ST_NO_SESSIONS) return TPM_VERSION_2; - } + return TPM_VERSION_1_2; }
diff --git a/src/std/tcg.h b/src/std/tcg.h index 09a92d8..4c07493 100644 --- a/src/std/tcg.h +++ b/src/std/tcg.h @@ -357,6 +357,7 @@ struct tpm_res_sha1complete {
/* TPM 2 Capabilities */ #define TPM2_CAP_PCRS 0x00000005 +#define TPM2_CAP_TPM_PROPERTIES 0x00000006
/* TPM 2 data structures */
diff --git a/src/tcgbios.c b/src/tcgbios.c index 40b3028..b86bf64 100644 --- a/src/tcgbios.c +++ b/src/tcgbios.c @@ -381,7 +381,7 @@ tpm_simple_cmd(u8 locty, u32 ordinal return ret; }
-static int +int tpm20_getcapability(u32 capability, u32 property, u32 count, struct tpm_rsp_header *rsp, u32 rsize) { diff --git a/src/tcgbios.h b/src/tcgbios.h index 32fb941..9fc711a 100644 --- a/src/tcgbios.h +++ b/src/tcgbios.h @@ -1,6 +1,7 @@ #ifndef TCGBIOS_H #define TCGBIOS_H
+#include "std/tcg.h" // struct tpm_rsp_header #include "types.h"
struct bregs; @@ -15,5 +16,8 @@ void tpm_add_cdrom_catalog(const u8 *addr, u32 length); void tpm_option_rom(const void *addr, u32 len); int tpm_can_show_menu(void); void tpm_menu(void); +int +tpm20_getcapability(u32 capability, u32 property, u32 count, + struct tpm_rsp_header *rsp, u32 rsize);
#endif /* TCGBIOS_H */