Skip to content

Commit

Permalink
tpm: Refactor TIS and add a SPI attachment
Browse files Browse the repository at this point in the history
Summary:
Though mostly used in x86 devices, TPM can be used on others, with a
direct SPI attachment.  Refactor the TPM 2.0 driver set to use an
attachment interface, and implement a SPI bus interface.

Test Plan:
Tested on a Raspberry Pi 4, with a GeeekPi TPM2.0 module (SLB9670
TPM) using security/tpm2-tools tpm2_getcaps for very light testing against the
spibus attachment.

Reviewed by:	kd
Obtained from:	Juniper Networks, Inc.
Differential Revision: https://reviews.freebsd.org/D45069
  • Loading branch information
chmeeedalf committed May 3, 2024
1 parent b95e960 commit c2e9c5b
Show file tree
Hide file tree
Showing 13 changed files with 640 additions and 154 deletions.
7 changes: 7 additions & 0 deletions sys/conf/files
Original file line number Diff line number Diff line change
Expand Up @@ -3194,6 +3194,13 @@ dev/syscons/warp/warp_saver.c optional warp_saver
dev/tcp_log/tcp_log_dev.c optional tcp_blackbox inet | tcp_blackbox inet6
dev/tdfx/tdfx_pci.c optional tdfx pci
dev/ti/if_ti.c optional ti pci
dev/tpm/tpm20.c optional tpm
dev/tpm/tpm_bus.c optional tpm acpi
dev/tpm/tpm_if.m optional tpm
dev/tpm/tpm_spibus.c optional tpm spibus fdt
dev/tpm/tpm_tis_acpi.c optional tpm acpi
dev/tpm/tpm_tis_core.c optional tpm
dev/tpm/tpm_tis_spibus.c optional tpm spibus fdt
dev/tws/tws.c optional tws
dev/tws/tws_cam.c optional tws
dev/tws/tws_hdm.c optional tws
Expand Down
2 changes: 0 additions & 2 deletions sys/conf/files.amd64
Original file line number Diff line number Diff line change
Expand Up @@ -372,9 +372,7 @@ dev/smartpqi/smartpqi_sis.c optional smartpqi
dev/smartpqi/smartpqi_tag.c optional smartpqi
dev/sume/if_sume.c optional sume
dev/syscons/apm/apm_saver.c optional apm_saver apm
dev/tpm/tpm20.c optional tpm
dev/tpm/tpm_crb.c optional tpm acpi
dev/tpm/tpm_tis.c optional tpm acpi
dev/tpm/tpm_acpi.c optional tpm acpi
dev/tpm/tpm_isa.c optional tpm isa
dev/p2sb/p2sb.c optional p2sb pci
Expand Down
6 changes: 3 additions & 3 deletions sys/dev/tpm/tpm20.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ tpm20_write(struct cdev *dev, struct uio *uio, int flags)
return (result);
}

result = sc->transmit(sc, byte_count);
result = TPM_TRANSMIT(sc->dev, byte_count);

if (result == 0) {
callout_reset(&sc->discard_buffer_callout,
Expand Down Expand Up @@ -267,7 +267,7 @@ tpm20_harvest(void *arg, int unused)
cv_wait(&sc->buf_cv, &sc->dev_lock);

memcpy(sc->buf, cmd, sizeof(cmd));
result = sc->transmit(sc, sizeof(cmd));
result = TPM_TRANSMIT(sc->dev, sizeof(cmd));
if (result != 0) {
sx_xunlock(&sc->dev_lock);
return;
Expand Down Expand Up @@ -319,7 +319,7 @@ tpm20_save_state(device_t dev, bool suspend)
sx_xlock(&sc->dev_lock);

memcpy(sc->buf, save_cmd, sizeof(save_cmd));
sc->transmit(sc, sizeof(save_cmd));
TPM_TRANSMIT(sc->dev, sizeof(save_cmd));

sx_xunlock(&sc->dev_lock);

Expand Down
53 changes: 19 additions & 34 deletions sys/dev/tpm/tpm20.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#ifndef _TPM20_H_
#define _TPM20_H_

#include "opt_acpi.h"
#include <sys/cdefs.h>
#include <sys/endian.h>
#include <sys/param.h>
Expand All @@ -39,6 +40,7 @@
#include <sys/bus.h>
#include <sys/callout.h>
#include <sys/conf.h>
#include <sys/lock.h>
#include <sys/module.h>
#include <sys/rman.h>
#include <sys/sx.h>
Expand All @@ -49,12 +51,14 @@
#include <machine/md_var.h>
#include <machine/resource.h>

#ifdef DEV_ACPI
#include <contrib/dev/acpica/include/acpi.h>
#include <contrib/dev/acpica/include/accommon.h>
#include <dev/acpica/acpivar.h>
#include "opt_acpi.h"
#endif

#include "opt_tpm.h"
#include "tpm_if.h"

#define BIT(x) (1 << (x))

Expand Down Expand Up @@ -136,55 +140,36 @@ int32_t tpm20_get_timeout(uint32_t command);
int tpm20_init(struct tpm_sc *sc);
void tpm20_release(struct tpm_sc *sc);

/* Small helper routines for io ops */
static inline uint8_t
RD1(struct tpm_sc *sc, bus_size_t off)
{

return (bus_read_1(sc->mem_res, off));
}
static inline uint32_t
RD4(struct tpm_sc *sc, bus_size_t off)
{

return (bus_read_4(sc->mem_res, off));
}
#ifdef __amd64__
static inline uint64_t
RD8(struct tpm_sc *sc, bus_size_t off)
{
/* Mode driver types */
DECLARE_CLASS(tpmtis_driver);
int tpmtis_attach(device_t dev);

return (bus_read_8(sc->mem_res, off));
}
#endif
static inline void
WR1(struct tpm_sc *sc, bus_size_t off, uint8_t val)
{
DECLARE_CLASS(tpmcrb_driver);

bus_write_1(sc->mem_res, off, val);
}
static inline void
WR4(struct tpm_sc *sc, bus_size_t off, uint32_t val)
{
/* Bus driver types */
DECLARE_CLASS(tpm_bus_driver);
DECLARE_CLASS(tpm_spi_driver);

bus_write_4(sc->mem_res, off, val);
}
/* Small helper routines for io ops */
static inline void
AND4(struct tpm_sc *sc, bus_size_t off, uint32_t val)
{
uint32_t v = TPM_READ_4(sc->dev, off);

WR4(sc, off, RD4(sc, off) & val);
TPM_WRITE_4(sc->dev, off, v & val);
}
static inline void
OR1(struct tpm_sc *sc, bus_size_t off, uint8_t val)
{
uint8_t v = TPM_READ_1(sc->dev, off);

WR1(sc, off, RD1(sc, off) | val);
TPM_WRITE_1(sc->dev, off, v | val);
}
static inline void
OR4(struct tpm_sc *sc, bus_size_t off, uint32_t val)
{
uint32_t v = TPM_READ_1(sc->dev, off);

WR4(sc, off, RD4(sc, off) | val);
TPM_WRITE_4(sc->dev, off, v | val);
}
#endif /* _TPM20_H_ */
99 changes: 99 additions & 0 deletions sys/dev/tpm/tpm_bus.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*-
* Copyright (c) 2023 Juniper Networks, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

#include <sys/cdefs.h>
#include <sys/types.h>
#include <sys/bus.h>
#include "tpm_if.h"
#include "tpm20.h"

/* Override accessors */
static uint8_t
tpm_read_1(device_t dev, bus_size_t off)
{
struct tpm_sc *sc = device_get_softc(dev);

return (bus_read_1(sc->mem_res, off));
}

static uint32_t
tpm_read_4(device_t dev, bus_size_t off)
{
struct tpm_sc *sc = device_get_softc(dev);

return (bus_read_4(sc->mem_res, off));
}

/*
* Only i386 is missing bus_space_read_8.
*/
#ifndef __i386__
static uint64_t
tpm_read_8(device_t dev, bus_size_t off)
{
struct tpm_sc *sc = device_get_softc(dev);

return (bus_read_8(sc->mem_res, off));
}
#endif

static void
tpm_write_1(device_t dev, bus_size_t off, uint8_t val)
{
struct tpm_sc *sc = device_get_softc(dev);

bus_write_1(sc->mem_res, off, val);
}

static void
tpm_write_4(device_t dev, bus_size_t off, uint32_t val)
{
struct tpm_sc *sc = device_get_softc(dev);

bus_write_4(sc->mem_res, off, val);
}

static void
tpm_write_barrier(device_t dev, bus_addr_t off, bus_size_t length)
{
struct tpm_sc *sc = device_get_softc(dev);

bus_barrier(sc->mem_res, off, length, BUS_SPACE_BARRIER_WRITE);
}

static device_method_t tpm_bus_methods[] = {
DEVMETHOD(tpm_read_1, tpm_read_1),
DEVMETHOD(tpm_read_4, tpm_read_4),
#ifndef __i386__
DEVMETHOD(tpm_read_8, tpm_read_8),
#endif
DEVMETHOD(tpm_write_1, tpm_write_1),
DEVMETHOD(tpm_write_4, tpm_write_4),
DEVMETHOD(tpm_write_barrier, tpm_write_barrier),
DEVMETHOD_END
};

DEFINE_CLASS_0(tpm_lbc, tpm_bus_driver, tpm_bus_methods, sizeof(struct tpm_sc));
Loading

0 comments on commit c2e9c5b

Please sign in to comment.