Improve MMIO support to utilize the HAL framework.

pull/271/head
David Garske 2023-06-28 13:35:46 -07:00
parent 0cb092a4a9
commit 21638b065a
7 changed files with 154 additions and 101 deletions

View File

@ -203,7 +203,7 @@ then
AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_I2C"
fi
# WOLFTPM_MMIO_BUILTIN_CB
# Memory-mapped I/O
AC_ARG_ENABLE([mmio],
[AS_HELP_STRING([--enable-mmio],[Enable built-in MMIO callbacks (default: disabled)])],
[ ENABLED_MMIO=$enableval ],
@ -212,7 +212,7 @@ AC_ARG_ENABLE([mmio],
if test "x$ENABLED_MMIO" = "xyes"
then
AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_MMIO_BUILTIN_CB"
AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_MMIO"
fi
# Advanced IO
@ -441,7 +441,7 @@ AM_CONDITIONAL([BUILD_WINAPI], [test "x$ENABLED_WINAPI" = "xyes"])
AM_CONDITIONAL([BUILD_NUVOTON], [test "x$ENABLED_NUVOTON" = "xyes"])
AM_CONDITIONAL([BUILD_CHECKWAITSTATE], [test "x$ENABLED_CHECKWAITSTATE" = "xyes"])
AM_CONDITIONAL([BUILD_AUTODETECT], [test "x$ENABLED_AUTODETECT" = "xyes"])
AM_CONDITIONAL([BUILD_HAL], [test "x$ENABLED_EXAMPLE_HAL" = "xyes"])
AM_CONDITIONAL([BUILD_HAL], [test "x$ENABLED_EXAMPLE_HAL" = "xyes" || test "x$ENABLED_MMIO" = "xyes"])
CREATE_HEX_VERSION

View File

@ -8,6 +8,7 @@ src_libwolftpm_la_SOURCES += \
hal/tpm_io_barebox.c \
hal/tpm_io_linux.c \
hal/tpm_io_infineon.c \
hal/tpm_io_mmio.c \
hal/tpm_io_microchip.c \
hal/tpm_io_st.c \
hal/tpm_io_qnx.c \

View File

@ -46,7 +46,10 @@
/* Set WOLFTPM_INCLUDE_IO_FILE so each .c is built here and not compiled directly */
#define WOLFTPM_INCLUDE_IO_FILE
#if defined(__linux__)
#if defined(WOLFTPM_MMIO)
#include "tpm_io_mmio.c"
#elif defined(__linux__)
#include "hal/tpm_io_linux.c"
#elif defined(WOLFSSL_STM32_CUBEMX)
#include "hal/tpm_io_st.c"
@ -64,7 +67,7 @@
#include "hal/tpm_io_microchip.c"
#endif
#if !defined(WOLFTPM_I2C)
#if !defined(WOLFTPM_I2C) && !defined(WOLFTPM_MMIO)
static int TPM2_IoCb_SPI(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf,
word16 xferSz, void* userCtx)
{
@ -108,7 +111,7 @@ int TPM2_IoCb(TPM2_CTX* ctx, int isRead, word32 addr, byte* buf,
word16 size, void* userCtx)
{
int ret = TPM_RC_FAILURE;
#if !defined(WOLFTPM_I2C)
#if !defined(WOLFTPM_I2C) && !defined(WOLFTPM_MMIO)
byte txBuf[MAX_SPI_FRAMESIZE+TPM_TIS_HEADER_SZ];
byte rxBuf[MAX_SPI_FRAMESIZE+TPM_TIS_HEADER_SZ];
#endif
@ -122,7 +125,11 @@ int TPM2_IoCb(TPM2_CTX* ctx, int isRead, word32 addr, byte* buf,
}
#endif
#if defined(WOLFTPM_I2C)
#ifdef WOLFTPM_MMIO
ret = TPM2_IoCb_Mmio(ctx, isRead, addr, buf, size, userCtx);
#elif defined(WOLFTPM_I2C)
#if defined(__linux__)
/* Use Linux I2C */
ret = TPM2_IoCb_Linux_I2C(ctx, isRead, addr, buf, size, userCtx);

View File

@ -43,6 +43,7 @@
* - Native Linux (/dev/tpm0)
* - Linux through spidev without kernel driver thanks to wolfTPM own TIS layer
* - Linux through i2c without kernel driver thanks to wolfTPM own TIS layer
* - Intel MMIO interface
* - Native Windows
* - Atmel MCUs
* - Xilinx Zynq
@ -113,6 +114,12 @@ WOLFTPM_LOCAL int TPM2_IoCb_Microchip_SPI(TPM2_CTX* ctx, const byte* txBuf, byte
#endif /* WOLFTPM_I2C */
#if defined(WOLFTPM_MMIO)
/* requires WOLFTPM_ADV_IO */
WOLFTPM_LOCAL int TPM2_IoCb_Mmio(TPM2_CTX* ctx, int isRead, word32 addr, byte* buf,
word16 size, void* userCtx);
#endif
#endif /* WOLFTPM_EXAMPLE_HAL */
#endif /* !(WOLFTPM_LINUX_DEV || WOLFTPM_SWTPM || WOLFTPM_WINAPI) */

124
hal/tpm_io_mmio.c 100644
View File

@ -0,0 +1,124 @@
/* tpm_io_mmio.c
*
* Copyright (C) 2006-2023 wolfSSL Inc.
*
* This file is part of wolfTPM.
*
* wolfTPM is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfTPM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/* Support for Memory Mapped I/O for accessing TPM */
#include <wolftpm/tpm2.h>
#include <wolftpm/tpm2_tis.h>
#include "tpm_io.h"
/******************************************************************************/
/* --- BEGIN IO Callback Logic -- */
/******************************************************************************/
/* Included via tpm_io.c if WOLFTPM_INCLUDE_IO_FILE is defined */
#ifdef WOLFTPM_INCLUDE_IO_FILE
#ifdef WOLFTPM_MMIO
#ifndef MIMO_BASE_ADDRESS
#define MIMO_BASE_ADDRESS 0xFE000000u
#endif
#ifndef WOLFTPM_ADV_IO
#error "WOLFTPM_MMIO_BUILTIN_CB requires WOLFTPM_ADV_IO"
#endif
#ifdef __GNUC__
/* this will prevent the compiler to re-order memory accesses across
* sw_barrier() invocation.
*/
#define sw_barrier() __asm__ __volatile__ ("":::"memory")
#else
#define sw_barrier()
#endif /* __GNUC__ */
static void TPM2_Mmio_Read32(word32 addr, byte *buf)
{
volatile word32 *_addr = (volatile word32*)(wordptr)addr;
word32 v;
v = *_addr;
sw_barrier();
memcpy(buf, (byte*)&v, sizeof(word32));
}
static void TPM2_Mmio_Write32(word32 addr, byte *buf)
{
volatile word32 *_addr = (volatile word32*)(wordptr)addr;
word32 v;
memcpy((uint8_t*)&v, buf, sizeof(word32));
*_addr = v;
sw_barrier();
}
static void TPM2_Mmio_Read8(word32 addr, byte *buf)
{
volatile byte *_addr = (volatile byte*)(wordptr)addr;
*buf = *_addr;
sw_barrier();
}
static void TPM2_Mmio_Write8(word32 addr, byte *buf)
{
volatile byte *_addr = (volatile byte*)(wordptr)addr;
*_addr = *buf;
sw_barrier();
}
int TPM2_IoCb_Mmio(TPM2_CTX *ctx, int isRead, word32 addr, byte* buf, word16 size,
void* userCtx)
{
size_t i;
/* IO for 32-bit aligned */
for (i = 0; ((size_t)size - i) >= sizeof(word32); i += sizeof(word32)) {
if (isRead)
TPM2_Mmio_Read32(MIMO_BASE_ADDRESS + addr, buf + i);
else
TPM2_Mmio_Write32(MIMO_BASE_ADDRESS + addr, buf + i);
}
/* IO for unaligned remainder */
for (; i < (size_t)size; i++) {
if (isRead)
TPM2_Mmio_Read8(MIMO_BASE_ADDRESS + addr, buf + i);
else
TPM2_Mmio_Write8(MIMO_BASE_ADDRESS + addr, buf + i);
}
(void)ctx;
(void)userCtx;
return 0;
}
#undef sw_barrier
#endif /* WOLFTPM_MMIO */
#endif /* WOLFTPM_INCLUDE_IO_FILE */
/******************************************************************************/
/* --- END IO Callback Logic -- */
/******************************************************************************/

View File

@ -622,23 +622,21 @@ TPM_RC TPM2_Init_ex(TPM2_CTX* ctx, TPM2HalIoCb ioCb, void* userCtx,
ctx->tcpCtx.fd = -1;
#endif
#if defined(WOLFTPM_LINUX_DEV) || defined(WOLFTPM_SWTPM) || defined(WOLFTPM_WINAPI) \
|| defined(WOLFTPM_MMIO_BUILTIN_CB)
#if defined(WOLFTPM_LINUX_DEV) || defined(WOLFTPM_SWTPM) || \
defined(WOLFTPM_WINAPI) || defined(WOLFTPM_MMIO)
if (ioCb != NULL || userCtx != NULL) {
return BAD_FUNC_ARG;
}
#else
#else
#ifdef WOLFTPM_MMIO
if (ioCb == NULL)
ioCb = TPM2_Mmio_Cb;
#endif
/* Setup HAL IO Callback */
rc = TPM2_SetHalIoCb(ctx, ioCb, userCtx);
if (rc != TPM_RC_SUCCESS)
return rc;
#endif
#ifdef WOLFTPM_MMIO_BUILTIN_CB
rc = TPM2_SetHalIoCb(ctx, TPM2_Mmio_Cb, NULL);
if (rc != TPM_RC_SUCCESS)
return rc;
#endif /* WOLFTPM_MMIO_BUILTIN_CB */
#endif
/* Set the active TPM global */
TPM2_SetActiveCtx(ctx);

View File

@ -58,12 +58,8 @@ enum tpm_tis_int_flags {
};
#ifndef TPM_BASE_ADDRESS
#ifdef WOLFTPM_MMIO_BUILTIN_CB
#define TPM_BASE_ADDRESS (0xFED40000u)
#else
#define TPM_BASE_ADDRESS (0xD40000u)
#endif
#endif
#ifdef WOLFTPM_I2C
/* For I2C only the lower 8-bits of the address are used */
@ -575,86 +571,6 @@ exit:
return rc;
}
#ifdef WOLFTPM_MMIO_BUILTIN_CB
#ifndef WOLFTPM_ADV_IO
#error "WOLFTPM_MMIO_BUILTIN_CB requires WOLFTPM_ADV_IO"
#endif
#ifdef __GNUC__
/* this will prevent the compiler to re-order memory accesses across
* sw_barrier() invocation.
*/
#define sw_barrier() __asm__ __volatile__ ("":::"memory")
#endif /* __GNUC__ */
static void TPM2_Mmio_Read32(word32 addr, byte *buf)
{
volatile word32 *_addr = (volatile word32*)(wordptr)addr;
word32 v;
v = *_addr;
sw_barrier();
memcpy(buf, (byte*)&v, sizeof(word32));
}
static void TPM2_Mmio_Write32(word32 addr, byte *buf)
{
volatile word32 *_addr = (volatile word32*)(wordptr)addr;
word32 v;
memcpy((uint8_t*)&v, buf, sizeof(word32));
*_addr = v;
sw_barrier();
}
static void TPM2_Mmio_Read8(word32 addr, byte *buf)
{
volatile byte *_addr = (volatile byte*)(wordptr)addr;
*buf = *_addr;
sw_barrier();
}
static void TPM2_Mmio_Write8(word32 addr, byte *buf)
{
volatile byte *_addr = (volatile byte*)(wordptr)addr;
*_addr = *buf;
sw_barrier();
}
int TPM2_Mmio_Cb(TPM2_CTX *ctx, int isRead, word32 addr, byte* buf, word16 size,
void* userCtx)
{
unsigned int i;
(void)ctx;
(void)userCtx;
#ifdef WOLFTPM_DEBUG_VERBOSE
printf("mmio %s @ 0x%x size: %d\r\n", (isRead) ? "read" : "write",
addr, (word32)size);
#endif
for (i = 0; (size - i) >= sizeof(word32); i += sizeof(word32)) {
if (isRead)
TPM2_Mmio_Read32(addr, buf + i);
else
TPM2_Mmio_Write32(addr, buf + i);
}
for (; i < size; i++) {
if (isRead)
TPM2_Mmio_Read8(addr, buf + i);
else
TPM2_Mmio_Write8(addr, buf + i);
}
return 0;
}
#endif /* WOLFTPM_MMIO_BUILTIN_CB */
/******************************************************************************/
/* --- END TPM Interface Layer -- */
/******************************************************************************/