⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tpm_drivers.c

📁 xen 3.2.2 源码
💻 C
字号:
/* *  Implementation of the TCG BIOS extension according to the specification *  described in *  https://www.trustedcomputinggroup.org/specs/PCClient/TCG_PCClientImplementationforBIOS_1-20_1-00.pdf * *  This library is free software; you can redistribute it and/or *  modify it under the terms of the GNU Lesser General Public *  License as published by the Free Software Foundation; either *  version 2 of the License, or (at your option) any later version. * *  This library 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 *  Lesser General Public License for more details. * *  You should have received a copy of the GNU Lesser General Public *  License along with this library; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA * * Copyright (C) IBM Corporation, 2006 * * Author: Stefan Berger <stefanb@us.ibm.com> */#include "rombios_compat.h"#include "util.h"#include "tpm_drivers.h"#include "tcgbios.h"#define STS_VALID                    (1 << 7) /* 0x80 */#define STS_COMMAND_READY            (1 << 6) /* 0x40 */#define STS_TPM_GO                   (1 << 5) /* 0x20 */#define STS_DATA_AVAILABLE           (1 << 4) /* 0x10 */#define STS_EXPECT                   (1 << 3) /* 0x08 */#define STS_RESPONSE_RETRY           (1 << 1) /* 0x02 */#define ACCESS_TPM_REG_VALID_STS     (1 << 7) /* 0x80 */#define ACCESS_ACTIVE_LOCALITY       (1 << 5) /* 0x20 */#define ACCESS_BEEN_SEIZED           (1 << 4) /* 0x10 */#define ACCESS_SEIZE                 (1 << 3) /* 0x08 */#define ACCESS_PENDING_REQUEST       (1 << 2) /* 0x04 */#define ACCESS_REQUEST_USE           (1 << 1) /* 0x02 */#define ACCESS_TPM_ESTABLISHMENT     (1 << 0) /* 0x01 */static uint32_t tis_wait_sts(uint8_t *addr, uint32_t time,                             uint8_t mask, uint8_t expect){	uint32_t rc = 0;	while (time > 0) {		uint8_t sts = mmio_readb(&addr[TPM_STS]);		if ((sts & mask) == expect) {			rc = 1;			break;		}		mssleep(1);		time--;	}	return rc;}static uint32_t tis_activate(uint32_t baseaddr){	uint32_t rc = 1;	uint8_t *tis_addr = (uint8_t*)baseaddr;	uint8_t acc;	/* request access to locality */	tis_addr[TPM_ACCESS] = ACCESS_REQUEST_USE;	acc = mmio_readb(&tis_addr[TPM_ACCESS]);	if ((acc & ACCESS_ACTIVE_LOCALITY) != 0) {		tis_addr[TPM_STS] = STS_COMMAND_READY;		rc = tis_wait_sts(tis_addr, 100,		                  STS_COMMAND_READY, STS_COMMAND_READY);	}	return rc;}uint32_t tis_ready(uint32_t baseaddr){	uint32_t rc = 0;	uint8_t *tis_addr = (uint8_t*)baseaddr;	tis_addr[TPM_STS] = STS_COMMAND_READY;	rc = tis_wait_sts(tis_addr, 100, STS_COMMAND_READY, STS_COMMAND_READY);	return rc;}uint32_t tis_senddata(uint32_t baseaddr, unsigned char *data, uint32_t len){	uint32_t rc = 0;	uint8_t *tis_addr = (uint8_t*)baseaddr;	uint32_t offset = 0;	uint32_t end = 0;	do {		uint16_t burst = 0;		uint32_t ctr = 0;		while (burst == 0 && ctr < 2000) {			burst = mmio_readw((uint16_t *)&tis_addr[TPM_STS+1]);			if (burst == 0) {				mssleep(1);				ctr++;			}		}		if (burst == 0) {			rc = TCG_RESPONSE_TIMEOUT;			break;		}		while (1) {			tis_addr[TPM_DATA_FIFO] = data[offset];			offset++;			burst--;			if (burst == 0 || offset == len) {				break;			}		}		if (offset == len) {			end = 1;		}	} while (end == 0);	return rc;}uint32_t tis_readresp(uint32_t baseaddr, unsigned char *buffer, uint32_t len){	uint32_t rc = 0;	uint32_t offset = 0;	uint8_t *tis_addr = (uint8_t*)baseaddr;	uint32_t sts;	while (offset < len) {		buffer[offset] = mmio_readb(&tis_addr[TPM_DATA_FIFO]);		offset++;		sts = mmio_readb(&tis_addr[TPM_STS]);		/* data left ? */		if ((sts & STS_DATA_AVAILABLE) == 0) {			break;		}	}	return rc;}uint32_t tis_waitdatavalid(uint32_t baseaddr){	uint8_t *tis_addr = (uint8_t*)baseaddr;	uint32_t rc = 0;	if (tis_wait_sts(tis_addr, 1000, STS_VALID, STS_VALID) == 0) {		rc = TCG_NO_RESPONSE;	}	return rc;}uint32_t tis_waitrespready(uint32_t baseaddr, uint32_t timeout){	uint32_t rc = 0;	uint8_t *tis_addr = (uint8_t*)baseaddr;	tis_addr[TPM_STS] = STS_TPM_GO;	if (tis_wait_sts(tis_addr, timeout,	                 STS_DATA_AVAILABLE, STS_DATA_AVAILABLE) == 0) {		rc = TCG_NO_RESPONSE;	}	return rc;}/* if device is not there, return '0', '1' otherwise */uint32_t tis_probe(uint32_t baseaddr){	uint32_t rc = 0;	uint8_t *tis_addr = (uint8_t*)baseaddr;	uint32_t didvid = mmio_readl((uint32_t *)&tis_addr[TPM_DID_VID]);	if ((didvid != 0) && (didvid != 0xffffffff)) {		rc = 1;	}	return rc;}struct tpm_driver tpm_drivers[TPM_NUM_DRIVERS] = {	{		.baseaddr      = TPM_TIS_BASE_ADDRESS,		.activate      = tis_activate,		.ready         = tis_ready,		.senddata      = tis_senddata,		.readresp      = tis_readresp,		.waitdatavalid = tis_waitdatavalid,		.waitrespready = tis_waitrespready,		.probe         = tis_probe,	},};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -