Re: [tpmdd-devel] [PATCH 1/3] tpm_crb: map locality registers

2016-10-11 Thread Jarkko Sakkinen
On Tue, Oct 11, 2016 at 11:01:43AM -0600, Jason Gunthorpe wrote:
> On Tue, Oct 11, 2016 at 12:23:04PM +0300, Jarkko Sakkinen wrote:
> > In order to provide access to locality registers, this commits adds
> > mapping of the head of the CRB registers, which are located right
> > before the control area.
> 
> I think you should squash this into the prior patch, no sense in
> changing all these lines twice
> 
> But looks better to me.

So... do you suggest to squash with request/reliquish locality stuff?
Just checking because this is 1/3 :)

> > -   priv->cca = crb_map_res(dev, priv, _res, buf->control_address,
> > -   sizeof(struct crb_control_area));
> > -   if (IS_ERR(priv->cca))
> > -   return PTR_ERR(priv->cca);
> > +   if (priv->flags & CRB_FL_CRB_START) {
> > +   priv->regs_h = crb_map_res(dev, priv, _res, io_res.start,
> > +  sizeof(struct crb_regs_head));
> > +   if (IS_ERR(priv->regs_h))
> > +   return PTR_ERR(priv->regs_h);
> > +   }
> > +
> > +   priv->regs_t = crb_map_res(dev, priv, _res, buf->control_address,
> > +  sizeof(struct crb_regs_tail));
> > +   if (IS_ERR(priv->regs_t))
> > +   return PTR_ERR(priv->regs_t);
> 
> So.. The ACPI IO region starts at the head area and continues to
> include the control area, as one nice sane region - except for some
> older stuff that puts the control area outside the ACPI IO region?

Yes. The old hardware triggered SMM to do a DMA transfer (those that
so called ACPI start). As a workaround for some of the hardware the
driver always sets the CRB start flag also in the control area.

That's why I also propose that we replace them with a single flag.

> That makes a lot more sense..
> 
> Maybe chuck in a
> 
>if (priv->flags & CRB_FL_CRB_START) {
>   if (buf->control_address != io_res.start + sizeof(struct
>   crb_regs_head))
>   dev_warn(dev, FIRMWARE_BUG "Bad ACPI memory layout")
> 
> Jason

As a sanity check this would probably make sense.


/Jarkko

--
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
___
tpmdd-devel mailing list
tpmdd-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tpmdd-devel


Re: [tpmdd-devel] [PATCH 1/3] tpm_crb: map locality registers

2016-10-11 Thread Jason Gunthorpe
On Tue, Oct 11, 2016 at 12:23:04PM +0300, Jarkko Sakkinen wrote:
> In order to provide access to locality registers, this commits adds
> mapping of the head of the CRB registers, which are located right
> before the control area.

I think you should squash this into the prior patch, no sense in
changing all these lines twice

But looks better to me.

> - priv->cca = crb_map_res(dev, priv, _res, buf->control_address,
> - sizeof(struct crb_control_area));
> - if (IS_ERR(priv->cca))
> - return PTR_ERR(priv->cca);
> + if (priv->flags & CRB_FL_CRB_START) {
> + priv->regs_h = crb_map_res(dev, priv, _res, io_res.start,
> +sizeof(struct crb_regs_head));
> + if (IS_ERR(priv->regs_h))
> + return PTR_ERR(priv->regs_h);
> + }
> +
> + priv->regs_t = crb_map_res(dev, priv, _res, buf->control_address,
> +sizeof(struct crb_regs_tail));
> + if (IS_ERR(priv->regs_t))
> + return PTR_ERR(priv->regs_t);

So.. The ACPI IO region starts at the head area and continues to
include the control area, as one nice sane region - except for some
older stuff that puts the control area outside the ACPI IO region?

That makes a lot more sense..

Maybe chuck in a

   if (priv->flags & CRB_FL_CRB_START) {
  if (buf->control_address != io_res.start + sizeof(struct
  crb_regs_head))
  dev_warn(dev, FIRMWARE_BUG "Bad ACPI memory layout")

Jason

--
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
___
tpmdd-devel mailing list
tpmdd-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tpmdd-devel


Re: [tpmdd-devel] [PATCH 1/3] tpm_crb: map locality registers

2016-10-11 Thread Jarkko Sakkinen
On Tue, Oct 11, 2016 at 12:23:04PM +0300, Jarkko Sakkinen wrote:
> In order to provide access to locality registers, this commits adds
> mapping of the head of the CRB registers, which are located right
> before the control area.
> 
> Signed-off-by: Jarkko Sakkinen 
> ---
>  drivers/char/tpm/tpm_crb.c | 86 
> +-
>  1 file changed, 54 insertions(+), 32 deletions(-)
> 
> diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
> index 65040d7..c34318b 100644
> --- a/drivers/char/tpm/tpm_crb.c
> +++ b/drivers/char/tpm/tpm_crb.c
> @@ -52,18 +52,28 @@ enum crb_cancel {
>   CRB_CANCEL_INVOKE   = BIT(0),
>  };
>  
> -struct crb_control_area {
> - u32 req;
> - u32 sts;
> - u32 cancel;
> - u32 start;
> - u32 int_enable;
> - u32 int_sts;
> - u32 cmd_size;
> - u32 cmd_pa_low;
> - u32 cmd_pa_high;
> - u32 rsp_size;
> - u64 rsp_pa;
> +struct crb_regs_head {
> + u32 loc_state;
> + u32 reserved1;
> + u32 loc_ctrl;
> + u32 loc_sts;
> + u8 reserved2[32];
> + u64 intf_id;
> + u64 ctrl_ext;
> +} __packed;
> +
> +struct crb_regs_tail {
> + u32 ctrl_req;
> + u32 ctrl_sts;
> + u32 ctrl_cancel;
> + u32 ctrl_start;
> + u32 ctrl_int_enable;
> + u32 ctrl_int_sts;
> + u32 ctrl_cmd_size;
> + u32 ctrl_cmd_pa_low;
> + u32 ctrl_cmd_pa_high;
> + u32 ctrl_rsp_size;
> + u64 ctrl_rsp_pa;
>  } __packed;
>  
>  enum crb_status {
> @@ -78,7 +88,8 @@ enum crb_flags {
>  struct crb_priv {
>   unsigned int flags;
>   void __iomem *iobase;
> - struct crb_control_area __iomem *cca;
> + struct crb_regs_head __iomem *regs_h;
> + struct crb_regs_tail __iomem *regs_t;
>   u8 __iomem *cmd;
>   u8 __iomem *rsp;
>   u32 cmd_size;
> @@ -104,7 +115,7 @@ static int __maybe_unused crb_go_idle(struct device *dev, 
> struct crb_priv *priv)
>   if (priv->flags & CRB_FL_ACPI_START)
>   return 0;
>  
> - iowrite32(CRB_CTRL_REQ_GO_IDLE, >cca->req);
> + iowrite32(CRB_CTRL_REQ_GO_IDLE, >regs_t->ctrl_req);
>   /* we don't really care when this settles */
>  
>   return 0;
> @@ -128,16 +139,18 @@ static int __maybe_unused crb_cmd_ready(struct device 
> *dev,
>   struct crb_priv *priv)
>  {
>   ktime_t stop, start;
> + u32 req;
>  
>   if (priv->flags & CRB_FL_ACPI_START)
>   return 0;
>  
> - iowrite32(CRB_CTRL_REQ_CMD_READY, >cca->req);
> + iowrite32(CRB_CTRL_REQ_CMD_READY, >regs_t->ctrl_req);
>  
>   start = ktime_get();
>   stop = ktime_add(start, ms_to_ktime(TPM2_TIMEOUT_C));
>   do {
> - if (!(ioread32(>cca->req) & CRB_CTRL_REQ_CMD_READY)) {
> + req = ioread32(>regs_t->ctrl_req);
> + if (!(req & CRB_CTRL_REQ_CMD_READY)) {
>   dev_dbg(dev, "cmdReady in %lld usecs\n",
>   ktime_to_us(ktime_sub(ktime_get(), start)));
>   return 0;
> @@ -145,7 +158,7 @@ static int __maybe_unused crb_cmd_ready(struct device 
> *dev,
>   usleep_range(50, 100);
>   } while (ktime_before(ktime_get(), stop));
>  
> - if (ioread32(>cca->req) & CRB_CTRL_REQ_CMD_READY) {
> + if (ioread32(>regs_t->ctrl_req) & CRB_CTRL_REQ_CMD_READY) {
>   dev_warn(dev, "cmdReady timed out\n");
>   return -ETIME;
>   }
> @@ -158,7 +171,7 @@ static u8 crb_status(struct tpm_chip *chip)
>   struct crb_priv *priv = dev_get_drvdata(>dev);
>   u8 sts = 0;
>  
> - if ((ioread32(>cca->start) & CRB_START_INVOKE) !=
> + if ((ioread32(>regs_t->ctrl_start) & CRB_START_INVOKE) !=
>   CRB_START_INVOKE)
>   sts |= CRB_DRV_STS_COMPLETE;
>  
> @@ -174,7 +187,7 @@ static int crb_recv(struct tpm_chip *chip, u8 *buf, 
> size_t count)
>   if (count < 6)
>   return -EIO;
>  
> - if (ioread32(>cca->sts) & CRB_CTRL_STS_ERROR)
> + if (ioread32(>regs_t->ctrl_sts) & CRB_CTRL_STS_ERROR)
>   return -EIO;
>  
>   memcpy_fromio(buf, priv->rsp, 6);
> @@ -213,7 +226,7 @@ static int crb_send(struct tpm_chip *chip, u8 *buf, 
> size_t len)
>   /* Zero the cancel register so that the next command will not get
>* canceled.
>*/
> - iowrite32(0, >cca->cancel);
> + iowrite32(0, >regs_t->ctrl_cancel);
>  
>   if (len > priv->cmd_size) {
>   dev_err(>dev, "invalid command count value %zd %d\n",
> @@ -227,7 +240,7 @@ static int crb_send(struct tpm_chip *chip, u8 *buf, 
> size_t len)
>   wmb();
>  
>   if (priv->flags & CRB_FL_CRB_START)
> - iowrite32(CRB_START_INVOKE, >cca->start);
> + iowrite32(CRB_START_INVOKE, >regs_t->ctrl_start);
>  
>   if (priv->flags & CRB_FL_ACPI_START)
>   rc = crb_do_acpi_start(chip);
> @@ -239,7 +252,7 @@ static void crb_cancel(struct tpm_chip *chip)
>  {
>