1bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi//
2bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// Copyright (C) 2015 The Android Open Source Project
3bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi//
4bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// Licensed under the Apache License, Version 2.0 (the "License");
5bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// you may not use this file except in compliance with the License.
6bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// You may obtain a copy of the License at
7bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi//
8bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi//      http://www.apache.org/licenses/LICENSE-2.0
9bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi//
10bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// Unless required by applicable law or agreed to in writing, software
11bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// distributed under the License is distributed on an "AS IS" BASIS,
12bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// See the License for the specific language governing permissions and
14bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// limitations under the License.
15bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi//
16c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury
17c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury#ifndef TRUNKS_TRUNKS_FTDI_SPI_H_
18c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury#define TRUNKS_TRUNKS_FTDI_SPI_H_
19c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury
20c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury#include <string>
21c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury
22c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury#include <base/macros.h>
23c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury
24c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury#include "trunks/command_transceiver.h"
25c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury#include "trunks/trunks_export.h"
26c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury
27c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury#if defined SPI_OVER_FTDI
28c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury
29c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury#include "trunks/ftdi/mpsse.h"
30c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury
31c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendeburynamespace trunks {
32c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury
33c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury// TrunksFtdiSpi is a CommandTransceiver implementation that forwards all
34c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury// commands to the SPI over FTDI interface directly to a TPM chip.
35c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendeburyclass TRUNKS_EXPORT TrunksFtdiSpi: public CommandTransceiver {
36c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury public:
37ea14a6e1838ea01103d88cbc9ccc2eb7e57483ddVadim Bendebury  TrunksFtdiSpi() : mpsse_(NULL), locality_(0) {}
38c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury  ~TrunksFtdiSpi() override;
39c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury
40c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury  // CommandTransceiver methods.
41c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury  bool Init() override;
42c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury  void SendCommand(const std::string& command,
43c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury                   const ResponseCallback& callback) override;
44c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury  std::string SendCommandAndWait(const std::string& command) override;
45c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury
46c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury private:
47c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury  struct mpsse_context* mpsse_;
48ea14a6e1838ea01103d88cbc9ccc2eb7e57483ddVadim Bendebury  unsigned locality_;   // Set at initialization.
49c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury
5095146cebd9272c71e3b3b48e12d658e57e7a328bVadim Bendebury  // Read a TPM register into the passed in buffer, where 'bytes' the width of
5195146cebd9272c71e3b3b48e12d658e57e7a328bVadim Bendebury  // the register. Return true on success, false on failure.
5295146cebd9272c71e3b3b48e12d658e57e7a328bVadim Bendebury  bool FtdiReadReg(unsigned reg_number, size_t bytes,
53ea14a6e1838ea01103d88cbc9ccc2eb7e57483ddVadim Bendebury                   void *buffer);
5495146cebd9272c71e3b3b48e12d658e57e7a328bVadim Bendebury  // Write a TPM register from the passed in buffer, where 'bytes' the width of
5595146cebd9272c71e3b3b48e12d658e57e7a328bVadim Bendebury  // the register. Return true on success, false on failure.
5695146cebd9272c71e3b3b48e12d658e57e7a328bVadim Bendebury  bool FtdiWriteReg(unsigned reg_number, size_t bytes,
57ea14a6e1838ea01103d88cbc9ccc2eb7e57483ddVadim Bendebury                    const void *buffer);
5895146cebd9272c71e3b3b48e12d658e57e7a328bVadim Bendebury  // Generate a proper SPI frame for read/write transaction, read_write set to
5995146cebd9272c71e3b3b48e12d658e57e7a328bVadim Bendebury  // true for read transactions, the size of the transaction is passed as
6095146cebd9272c71e3b3b48e12d658e57e7a328bVadim Bendebury  // 'bytes', addr is the internal TPM address space address (accounting for
6195146cebd9272c71e3b3b48e12d658e57e7a328bVadim Bendebury  // locality).
6295146cebd9272c71e3b3b48e12d658e57e7a328bVadim Bendebury  //
6395146cebd9272c71e3b3b48e12d658e57e7a328bVadim Bendebury  // Note that this function is expected to be called when the SPI bus is idle
6495146cebd9272c71e3b3b48e12d658e57e7a328bVadim Bendebury  // (CS deasserted), and will assert the CS before transmitting.
6595146cebd9272c71e3b3b48e12d658e57e7a328bVadim Bendebury  void StartTransaction(bool read_write, size_t bytes, unsigned addr);
666b88fbeb67f5e7a55ae880047c51056557d142a4Vadim Bendebury  // TPM Status Register is going to be accessed a lot, let's have dedicated
676b88fbeb67f5e7a55ae880047c51056557d142a4Vadim Bendebury  // accessors for it,
686b88fbeb67f5e7a55ae880047c51056557d142a4Vadim Bendebury  bool ReadTpmSts(uint32_t *status);
696b88fbeb67f5e7a55ae880047c51056557d142a4Vadim Bendebury  bool WriteTpmSts(uint32_t status);
7032f46a0b006ef7cff2a00a5223867d3064ddfff2Vadim Bendebury  // Poll status register until the required value is read or the timeout
7132f46a0b006ef7cff2a00a5223867d3064ddfff2Vadim Bendebury  // expires.
7232f46a0b006ef7cff2a00a5223867d3064ddfff2Vadim Bendebury  bool WaitForStatus(uint32_t statusMask,
73b21ea123afb354647305411a51d318067544606cVadim Bendebury                     uint32_t statusExpected, int timeout_ms = 10000);
74c60690ba852723ab55ef6eb1da99b00d4501fec0Vadim Bendebury  // Retrieve current value of the burst count field.
75c60690ba852723ab55ef6eb1da99b00d4501fec0Vadim Bendebury  size_t GetBurstCount(void);
7695146cebd9272c71e3b3b48e12d658e57e7a328bVadim Bendebury
77c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury  DISALLOW_COPY_AND_ASSIGN(TrunksFtdiSpi);
78c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury};
79c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury
80c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury}  // namespace trunks
81c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury
82c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury#else  // SPI_OVER_FTDI ^^^^ defined  vvvvv NOT defined
83c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury
84c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendeburynamespace trunks {
85c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury
86c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury// A plug to support compilations on platforms where FTDI SPI interface is not
87c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury// available.
88c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendeburyclass TRUNKS_EXPORT TrunksFtdiSpi: public CommandTransceiver {
89c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury public:
90c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury  TrunksFtdiSpi() {}
91c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury  ~TrunksFtdiSpi() {}
92c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury
93c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury  bool Init() { return false; }
94c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury  void SendCommand(const std::string& command,
95c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury                   const ResponseCallback& callback) {}
96c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury  std::string SendCommandAndWait(const std::string& command) {
97c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury    return std::string(""); }
98c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury};
99c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury
100c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury}  // namespace trunks
101c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury
102c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury#endif  // SPI_OVER_FTDI ^^^^ NOT defined
103c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury
104c7a43d6afb860f06e3992855d81c5bc370dcad9cVadim Bendebury#endif  // TRUNKS_TRUNKS_FTDI_SPI_H_
105