diff mbox

[U-Boot,2/4] spi: ST33ZP24 SPI: Patch driver to support 2 TPMs

Message ID 1396356528-6905-3-git-send-email-jean-luc.blanc@st.com
State Superseded
Headers show

Commit Message

Jean-Luc BLANC April 1, 2014, 12:48 p.m. UTC
In order to support 2 SPI TPMs on same platform, add spi_select()
to tpm command set. Selection is done at driver level to keep compatibility
with standard tpm commands.
---
 README                         |   13 ++++++++++++
 common/cmd_tpm.c               |   31 ++++++++++++++++++++++++++++
 drivers/tpm/tpm_spi_stm_st33.c |   44 ++++++++++++++++++++++++++++++++++++++++
 include/tpm.h                  |   10 +++++++++
 lib/tpm.c                      |   13 ++++++++++++
 5 files changed, 111 insertions(+)

Comments

Simon Glass April 11, 2014, 8:57 p.m. UTC | #1
Hi Jean-Luc,

On 1 April 2014 05:48, Jean-Luc BLANC <stmicroelectronics.tpm@gmail.com>wrote:

> In order to support 2 SPI TPMs on same platform, add spi_select()
> to tpm command set. Selection is done at driver level to keep compatibility
> with standard tpm commands.
> ---
>  README                         |   13 ++++++++++++
>  common/cmd_tpm.c               |   31 ++++++++++++++++++++++++++++
>  drivers/tpm/tpm_spi_stm_st33.c |   44
> ++++++++++++++++++++++++++++++++++++++++
>  include/tpm.h                  |   10 +++++++++
>  lib/tpm.c                      |   13 ++++++++++++
>  5 files changed, 111 insertions(+)
>
> diff --git a/README b/README
> index e04866d..ef66550 100644
> --- a/README
> +++ b/README
> @@ -1334,6 +1334,19 @@ The following options need to be configured:
>                         TPM0_SPI_CS
>                         Define SPI Chip Select ID connected to TPM
>
> +               CONFIG_TPM_ST_2TPM
> +               Support additional STMicoelectronics SPI TPM.
> +               Require CONFIG_TPM_ST_SPI
> +
> +                       TPM1_SPI_MAX_SPEED
> +                       Define SPI frequency for TPM, 10000000 Hz max
> +
> +                       TPM1_SPI_BUS_NUM
> +                       Define SPI Bus ID connected to TPM
> +
> +                       TPM1_SPI_CS
> +                       Define SPI Chip Select ID connected to TPM
> +
>  - USB Support:
>                 At the moment only the UHCI host controller is
>                 supported (PIP405, MIP405, MPC5200); define
> diff --git a/common/cmd_tpm.c b/common/cmd_tpm.c
> index 0294952..3085d34 100644
> --- a/common/cmd_tpm.c
> +++ b/common/cmd_tpm.c
> @@ -355,6 +355,27 @@ static int do_tpm_pcr_read(cmd_tbl_t *cmdtp, int flag,
>         return convert_return_code(rc);
>  }
>
> +#ifdef CONFIG_TPM_ST_2TPM
>

Do we really need this config? Perhaps support 2 TPMs always?


> +static int do_tpm_spi_select(cmd_tbl_t *cmdtp, int flag,
> +               int argc, char * const argv[])
> +{
> +       uint32_t rc, spi_number;
> +
> +       if (argc != 2)
> +               return CMD_RET_USAGE;
> +
> +       spi_number = simple_strtoul(argv[1], NULL, 0);
> +
> +       if ((spi_number == 0) | (spi_number == 1)) {
>

Seems like you need a #define for MAX_TPMS and then you can check that the
spi_number < MAX_TPMS.


> +               rc = tpm_spi_select(spi_number);
> +       } else {
> +               printf("Couldn't parse argument %s\n", argv[1]);
> +               return CMD_RET_FAILURE;
> +       }
> +       return convert_return_code(rc);
> +}
> +#endif /* CONFIG_TPM_ST_2TPM */
> +
>  static int do_tpm_tsc_physical_presence(cmd_tbl_t *cmdtp, int flag,
>                 int argc, char * const argv[])
>  {
> @@ -631,6 +652,10 @@ static cmd_tbl_t tpm_commands[] = {
>                         do_tpm_extend, "", ""),
>         U_BOOT_CMD_MKENT(pcr_read, 0, 1,
>                         do_tpm_pcr_read, "", ""),
> +#ifdef CONFIG_TPM_ST_2TPM
> +       U_BOOT_CMD_MKENT(spi_select, 0, 1,
> +                       do_tpm_spi_select, "", ""),
> +#endif /* CONFIG_TPM_ST_2TPM */
>         U_BOOT_CMD_MKENT(tsc_physical_presence, 0, 1,
>                         do_tpm_tsc_physical_presence, "", ""),
>         U_BOOT_CMD_MKENT(read_pubek, 0, 1,
> @@ -754,4 +779,10 @@ U_BOOT_CMD(tpm, CONFIG_SYS_MAXARGS, 1, do_tpm,
>  "    - Read from space <index> to environment variables <vars...>.\n"
>  "  nv_write types_string index values...\n"
>  "    - Write to space <index> from values <values...>.\n"
> +#ifdef CONFIG_TPM_ST_2TPM
> +"TPM Select Command:\n"
> +"  spi_select <TPM_ID>\n"
> +"    - In platform with multiple SPI TPM, activate <TPM_ID> for coming\n"
> +"      TPM operations. 0 or 1 are recognized <TPM_ID>\n"
> +#endif /* CONFIG_TPM_ST_2TPM */
>  );
> diff --git a/drivers/tpm/tpm_spi_stm_st33.c
> b/drivers/tpm/tpm_spi_stm_st33.c
> index 78a4e54..d7b4d65 100644
> --- a/drivers/tpm/tpm_spi_stm_st33.c
> +++ b/drivers/tpm/tpm_spi_stm_st33.c
> @@ -62,7 +62,11 @@ struct tpm_chip  {
>         struct spi_slave *tpm_dev_spi_info;
>  };
>
> +#ifdef CONFIG_TPM_ST_2TPM                      /* 2 TPM on board */
> +struct tpm_chip tpm_st33_spi_board_info[2];
>

MAX_TPMS


> +#else                                          /* Only 1 TPM on board */
>  struct tpm_chip tpm_st33_spi_board_info[1];
> +#endif
>
>  struct tpm_chip *active_tpm;
>
> @@ -589,6 +593,30 @@ int tis_init(void)
>                 active_tpm->is_open = 1;
>                 printf("ST33ZP24 SPI TPM from STMicroelectronics found\n");
>         }
> +#ifdef CONFIG_TPM_ST_2TPM
> +       slave = spi_setup_slave(TPM1_SPI_BUS_NUM, TPM1_SPI_CS,
> +                       TPM1_SPI_MAX_SPEED, SPI_MODE_0);
> +       if (slave != NULL) {
> +               active_tpm = &tpm_st33_spi_board_info[1];
> +               active_tpm->timeout_a = TIS_SHORT_TIMEOUT;
>

This code seems common so should go in a function.


> +               active_tpm->timeout_b = TIS_LONG_TIMEOUT;
> +               active_tpm->timeout_c = TIS_SHORT_TIMEOUT;
> +               active_tpm->timeout_d = TIS_SHORT_TIMEOUT;
> +               active_tpm->locality = LOCALITY0;
> +               active_tpm->duration = TPM_MAX_COMMAND_DURATION;
> +               active_tpm->tpm_dev_spi_info = slave;
> +               active_tpm->latency = 2;
> +               if (spi_read8_reg(active_tpm, active_tpm->locality,
> +                       TPM_ACCESS, active_tpm->buf, 1) != 0) {
> +                       rc = -TPM_DRIVER_ERR;
> +                       active_tpm->is_open = 0;
> +                       goto out_err;
> +               }
> +               active_tpm->is_open = 1;
> +               printf("ST33ZP24 2nd SPI TPM from STMicroelectronics
> found\n");
> +               active_tpm = &tpm_st33_spi_board_info[0];
> +       }
> +#endif
>  out_err:
>         return rc;
>  }      /* tis_init() */
> @@ -669,3 +697,19 @@ int tis_close(void)
>         return release_locality(active_tpm);
>  }      /* tis_close() */
>
> +/*
> + * tis_select_tpm() switch the active TPM to "chip_number"
> + * removal did not succeed).
> + * @param: chip_number, the tpm chip to activate (0 or 1)
> + * @return: 0 on success, -TPM_DRIVER_ERR if an error occur
> + */
> +int tis_select_tpm(int chip_number)
> +{
> +       if (chip_number > MAX_NUMBER_TPM_ONBOARD - 1) {
>

Seems like MAX_NUMBER_TPM_ONBOARD is the #define I mentioned above.


> +               printf("Error, trying to select a TPM number that not
> exist\n");
> +               return -TPM_DRIVER_ERR;
> +       }
> +       active_tpm = &tpm_st33_spi_board_info[chip_number];
> +       return 0;
> +}
> +
> diff --git a/include/tpm.h b/include/tpm.h
> index 88aeba2..b726142 100644
> --- a/include/tpm.h
> +++ b/include/tpm.h
> @@ -239,6 +239,16 @@ uint32_t tpm_extend(uint32_t index, const void
> *in_digest, void *out_digest);
>   */
>  uint32_t tpm_pcr_read(uint32_t index, void *data, size_t count);
>
> +#ifdef CONFIG_TPM_ST_2TPM
> +/**
> + * On platform with 2 declared SPI TPM, select one or the other.
> + *
> + * @param TPM ID to select (0 or 1)
> + * @return 0 if success, otherwise means an error occurs.
> + */
> +uint32_t tpm_spi_select(int selected_tpm);
> +#endif /* CONFIG_TPM_ST_2TPM */
> +
>  /**
>   * Issue a TSC_PhysicalPresence command.  TPM physical presence flag
>   * is bit-wise OR'ed of flags listed in enum tpm_physical_presence.
> diff --git a/lib/tpm.c b/lib/tpm.c
> index 967c8e6..bc8524e 100644
> --- a/lib/tpm.c
> +++ b/lib/tpm.c
> @@ -459,6 +459,19 @@ uint32_t tpm_pcr_read(uint32_t index, void *data,
> size_t count)
>         return 0;
>  }
>
> +#ifdef CONFIG_TPM_ST_2TPM
> +uint32_t tpm_spi_select(int selected_tpm)
> +{
> +       uint32_t err;
> +
> +       err = tis_select_tpm(selected_tpm);
> +       if (err)
> +               return err;
> +
> +       return 0;
> +}
> +#endif /* CONFIG_TPM_ST_2TPM */
> +
>  uint32_t tpm_tsc_physical_presence(uint16_t presence)
>  {
>         const uint8_t command[12] = {
> --
> 1.7.9.5
>
>
Regards,
Simon
diff mbox

Patch

diff --git a/README b/README
index e04866d..ef66550 100644
--- a/README
+++ b/README
@@ -1334,6 +1334,19 @@  The following options need to be configured:
 			TPM0_SPI_CS
 			Define SPI Chip Select ID connected to TPM
 
+		CONFIG_TPM_ST_2TPM
+		Support additional STMicoelectronics SPI TPM. 
+		Require CONFIG_TPM_ST_SPI
+
+			TPM1_SPI_MAX_SPEED
+			Define SPI frequency for TPM, 10000000 Hz max
+
+			TPM1_SPI_BUS_NUM
+			Define SPI Bus ID connected to TPM
+
+			TPM1_SPI_CS
+			Define SPI Chip Select ID connected to TPM
+
 - USB Support:
 		At the moment only the UHCI host controller is
 		supported (PIP405, MIP405, MPC5200); define
diff --git a/common/cmd_tpm.c b/common/cmd_tpm.c
index 0294952..3085d34 100644
--- a/common/cmd_tpm.c
+++ b/common/cmd_tpm.c
@@ -355,6 +355,27 @@  static int do_tpm_pcr_read(cmd_tbl_t *cmdtp, int flag,
 	return convert_return_code(rc);
 }
 
+#ifdef CONFIG_TPM_ST_2TPM
+static int do_tpm_spi_select(cmd_tbl_t *cmdtp, int flag,
+		int argc, char * const argv[])
+{
+	uint32_t rc, spi_number;
+
+	if (argc != 2)
+		return CMD_RET_USAGE;
+
+	spi_number = simple_strtoul(argv[1], NULL, 0);
+
+	if ((spi_number == 0) | (spi_number == 1)) {
+		rc = tpm_spi_select(spi_number);
+	} else {
+		printf("Couldn't parse argument %s\n", argv[1]);
+		return CMD_RET_FAILURE;
+	}
+	return convert_return_code(rc);
+}
+#endif /* CONFIG_TPM_ST_2TPM */
+
 static int do_tpm_tsc_physical_presence(cmd_tbl_t *cmdtp, int flag,
 		int argc, char * const argv[])
 {
@@ -631,6 +652,10 @@  static cmd_tbl_t tpm_commands[] = {
 			do_tpm_extend, "", ""),
 	U_BOOT_CMD_MKENT(pcr_read, 0, 1,
 			do_tpm_pcr_read, "", ""),
+#ifdef CONFIG_TPM_ST_2TPM
+	U_BOOT_CMD_MKENT(spi_select, 0, 1,
+			do_tpm_spi_select, "", ""),
+#endif /* CONFIG_TPM_ST_2TPM */
 	U_BOOT_CMD_MKENT(tsc_physical_presence, 0, 1,
 			do_tpm_tsc_physical_presence, "", ""),
 	U_BOOT_CMD_MKENT(read_pubek, 0, 1,
@@ -754,4 +779,10 @@  U_BOOT_CMD(tpm, CONFIG_SYS_MAXARGS, 1, do_tpm,
 "    - Read from space <index> to environment variables <vars...>.\n"
 "  nv_write types_string index values...\n"
 "    - Write to space <index> from values <values...>.\n"
+#ifdef CONFIG_TPM_ST_2TPM
+"TPM Select Command:\n"
+"  spi_select <TPM_ID>\n"
+"    - In platform with multiple SPI TPM, activate <TPM_ID> for coming\n"
+"      TPM operations. 0 or 1 are recognized <TPM_ID>\n"
+#endif /* CONFIG_TPM_ST_2TPM */
 );
diff --git a/drivers/tpm/tpm_spi_stm_st33.c b/drivers/tpm/tpm_spi_stm_st33.c
index 78a4e54..d7b4d65 100644
--- a/drivers/tpm/tpm_spi_stm_st33.c
+++ b/drivers/tpm/tpm_spi_stm_st33.c
@@ -62,7 +62,11 @@  struct tpm_chip  {
 	struct spi_slave *tpm_dev_spi_info;
 };
 
+#ifdef CONFIG_TPM_ST_2TPM			/* 2 TPM on board */
+struct tpm_chip tpm_st33_spi_board_info[2];
+#else						/* Only 1 TPM on board */
 struct tpm_chip tpm_st33_spi_board_info[1];
+#endif
 
 struct tpm_chip *active_tpm;
 
@@ -589,6 +593,30 @@  int tis_init(void)
 		active_tpm->is_open = 1;
 		printf("ST33ZP24 SPI TPM from STMicroelectronics found\n");
 	}
+#ifdef CONFIG_TPM_ST_2TPM
+	slave = spi_setup_slave(TPM1_SPI_BUS_NUM, TPM1_SPI_CS,
+			TPM1_SPI_MAX_SPEED, SPI_MODE_0);
+	if (slave != NULL) {
+		active_tpm = &tpm_st33_spi_board_info[1];
+		active_tpm->timeout_a = TIS_SHORT_TIMEOUT;
+		active_tpm->timeout_b = TIS_LONG_TIMEOUT;
+		active_tpm->timeout_c = TIS_SHORT_TIMEOUT;
+		active_tpm->timeout_d = TIS_SHORT_TIMEOUT;
+		active_tpm->locality = LOCALITY0;
+		active_tpm->duration = TPM_MAX_COMMAND_DURATION;
+		active_tpm->tpm_dev_spi_info = slave;
+		active_tpm->latency = 2;
+		if (spi_read8_reg(active_tpm, active_tpm->locality,
+			TPM_ACCESS, active_tpm->buf, 1) != 0) {
+			rc = -TPM_DRIVER_ERR;
+			active_tpm->is_open = 0;
+			goto out_err;
+		}
+		active_tpm->is_open = 1;
+		printf("ST33ZP24 2nd SPI TPM from STMicroelectronics found\n");
+		active_tpm = &tpm_st33_spi_board_info[0];
+	}
+#endif
 out_err:
 	return rc;
 }	/* tis_init() */
@@ -669,3 +697,19 @@  int tis_close(void)
 	return release_locality(active_tpm);
 }	/* tis_close() */
 
+/*
+ * tis_select_tpm() switch the active TPM to "chip_number"
+ * removal did not succeed).
+ * @param: chip_number, the tpm chip to activate (0 or 1)
+ * @return: 0 on success, -TPM_DRIVER_ERR if an error occur
+ */
+int tis_select_tpm(int chip_number)
+{
+	if (chip_number > MAX_NUMBER_TPM_ONBOARD - 1) {
+		printf("Error, trying to select a TPM number that not exist\n");
+		return -TPM_DRIVER_ERR;
+	}
+	active_tpm = &tpm_st33_spi_board_info[chip_number];
+	return 0;
+}
+
diff --git a/include/tpm.h b/include/tpm.h
index 88aeba2..b726142 100644
--- a/include/tpm.h
+++ b/include/tpm.h
@@ -239,6 +239,16 @@  uint32_t tpm_extend(uint32_t index, const void *in_digest, void *out_digest);
  */
 uint32_t tpm_pcr_read(uint32_t index, void *data, size_t count);
 
+#ifdef CONFIG_TPM_ST_2TPM
+/**
+ * On platform with 2 declared SPI TPM, select one or the other.
+ *
+ * @param TPM ID to select (0 or 1)
+ * @return 0 if success, otherwise means an error occurs.
+ */
+uint32_t tpm_spi_select(int selected_tpm);
+#endif /* CONFIG_TPM_ST_2TPM */
+
 /**
  * Issue a TSC_PhysicalPresence command.  TPM physical presence flag
  * is bit-wise OR'ed of flags listed in enum tpm_physical_presence.
diff --git a/lib/tpm.c b/lib/tpm.c
index 967c8e6..bc8524e 100644
--- a/lib/tpm.c
+++ b/lib/tpm.c
@@ -459,6 +459,19 @@  uint32_t tpm_pcr_read(uint32_t index, void *data, size_t count)
 	return 0;
 }
 
+#ifdef CONFIG_TPM_ST_2TPM
+uint32_t tpm_spi_select(int selected_tpm)
+{
+	uint32_t err;
+
+	err = tis_select_tpm(selected_tpm);
+	if (err)
+		return err;
+
+	return 0;
+}
+#endif /* CONFIG_TPM_ST_2TPM */
+
 uint32_t tpm_tsc_physical_presence(uint16_t presence)
 {
 	const uint8_t command[12] = {