mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-01-12 23:51:49 +00:00
devices: rework TPM register and field look-up
Match against enums instead. This then drops the need to import phf. Signed-off-by: Wei Liu <liuwe@microsoft.com>
This commit is contained in:
parent
99d8c34861
commit
cd1470e289
64
Cargo.lock
generated
64
Cargo.lock
generated
@ -268,7 +268,6 @@ dependencies = [
|
|||||||
"hypervisor",
|
"hypervisor",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"phf",
|
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tpm",
|
"tpm",
|
||||||
"versionize",
|
"versionize",
|
||||||
@ -869,48 +868,6 @@ dependencies = [
|
|||||||
"wait-timeout",
|
"wait-timeout",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "phf"
|
|
||||||
version = "0.11.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "928c6535de93548188ef63bb7c4036bd415cd8f36ad25af44b9789b2ee72a48c"
|
|
||||||
dependencies = [
|
|
||||||
"phf_macros",
|
|
||||||
"phf_shared",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "phf_generator"
|
|
||||||
version = "0.11.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b1181c94580fa345f50f19d738aaa39c0ed30a600d95cb2d3e23f94266f14fbf"
|
|
||||||
dependencies = [
|
|
||||||
"phf_shared",
|
|
||||||
"rand",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "phf_macros"
|
|
||||||
version = "0.11.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "92aacdc5f16768709a569e913f7451034034178b05bdc8acda226659a3dccc66"
|
|
||||||
dependencies = [
|
|
||||||
"phf_generator",
|
|
||||||
"phf_shared",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "phf_shared"
|
|
||||||
version = "0.11.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e1fb5f6f826b772a8d4c0394209441e7d37cbbb967ae9c7e0e8134365c9ee676"
|
|
||||||
dependencies = [
|
|
||||||
"siphasher",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pkg-config"
|
name = "pkg-config"
|
||||||
version = "0.3.26"
|
version = "0.3.26"
|
||||||
@ -1035,21 +992,6 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand"
|
|
||||||
version = "0.8.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
|
||||||
dependencies = [
|
|
||||||
"rand_core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_core"
|
|
||||||
version = "0.6.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rate_limiter"
|
name = "rate_limiter"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@ -1245,12 +1187,6 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "siphasher"
|
|
||||||
version = "0.3.10"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "1.10.0"
|
version = "1.10.0"
|
||||||
|
@ -13,7 +13,6 @@ byteorder = "1.4.3"
|
|||||||
hypervisor = { path = "../hypervisor" }
|
hypervisor = { path = "../hypervisor" }
|
||||||
libc = "0.2.139"
|
libc = "0.2.139"
|
||||||
log = "0.4.17"
|
log = "0.4.17"
|
||||||
phf = { version = "0.11.1", features = ["macros"] }
|
|
||||||
thiserror = "1.0.38"
|
thiserror = "1.0.38"
|
||||||
tpm = { path = "../tpm" }
|
tpm = { path = "../tpm" }
|
||||||
versionize = "0.1.9"
|
versionize = "0.1.9"
|
||||||
|
@ -8,7 +8,6 @@ use anyhow::anyhow;
|
|||||||
use arch::aarch64::layout::{TPM_SIZE, TPM_START};
|
use arch::aarch64::layout::{TPM_SIZE, TPM_START};
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use arch::x86_64::layout::{TPM_SIZE, TPM_START};
|
use arch::x86_64::layout::{TPM_SIZE, TPM_START};
|
||||||
use phf::phf_map;
|
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::sync::{Arc, Barrier};
|
use std::sync::{Arc, Barrier};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
@ -28,57 +27,132 @@ pub enum Error {
|
|||||||
}
|
}
|
||||||
type Result<T> = anyhow::Result<T, Error>;
|
type Result<T> = anyhow::Result<T, Error>;
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
enum LocStateFields {
|
||||||
|
TpmEstablished,
|
||||||
|
LocAssigned,
|
||||||
|
ActiveLocality,
|
||||||
|
Reserved,
|
||||||
|
TpmRegValidSts,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum LocStsFields {
|
||||||
|
Granted,
|
||||||
|
BeenSeized,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
enum IntfIdFields {
|
||||||
|
InterfaceType,
|
||||||
|
InterfaceVersion,
|
||||||
|
CapLocality,
|
||||||
|
CapCRBIdleBypass,
|
||||||
|
Reserved1,
|
||||||
|
CapDataXferSizeSupport,
|
||||||
|
CapFIFO,
|
||||||
|
CapCRB,
|
||||||
|
CapIFRes,
|
||||||
|
InterfaceSelector,
|
||||||
|
IntfSelLock,
|
||||||
|
Reserved2,
|
||||||
|
Rid,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
enum IntfId2Fields {
|
||||||
|
Vid,
|
||||||
|
Did,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum CtrlStsFields {
|
||||||
|
TpmSts,
|
||||||
|
TpmIdle,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum CrbRegister {
|
||||||
|
LocState(LocStateFields),
|
||||||
|
LocSts(LocStsFields),
|
||||||
|
IntfId(IntfIdFields),
|
||||||
|
IntfId2(IntfId2Fields),
|
||||||
|
CtrlSts(CtrlStsFields),
|
||||||
|
}
|
||||||
|
|
||||||
/* crb 32-bit registers */
|
/* crb 32-bit registers */
|
||||||
const CRB_LOC_STATE: u32 = 0x0;
|
const CRB_LOC_STATE: u32 = 0x0;
|
||||||
//Register Fields
|
//Register Fields
|
||||||
// Field => (start, length)
|
// Field => (base, offset, length)
|
||||||
// start: lowest bit in the bit field numbered from 0
|
// base: starting position of the register
|
||||||
|
// offset: lowest bit in the bit field numbered from 0
|
||||||
// length: length of the bit field
|
// length: length of the bit field
|
||||||
const CRB_LOC_STATE_FIELDS: phf::Map<&str, [u32; 2]> = phf_map! {
|
const fn get_crb_loc_state_field(f: LocStateFields) -> (u32, u32, u32) {
|
||||||
"tpmEstablished" => [0, 1],
|
let (offset, len) = match f {
|
||||||
"locAssigned" => [1,1],
|
LocStateFields::TpmEstablished => (0, 1),
|
||||||
"activeLocality"=> [2, 3],
|
LocStateFields::LocAssigned => (1, 1),
|
||||||
"reserved" => [5, 2],
|
LocStateFields::ActiveLocality => (2, 3),
|
||||||
"tpmRegValidSts" => [7, 1]
|
LocStateFields::Reserved => (5, 2),
|
||||||
};
|
LocStateFields::TpmRegValidSts => (7, 1),
|
||||||
|
};
|
||||||
|
|
||||||
|
(CRB_LOC_STATE, offset, len)
|
||||||
|
}
|
||||||
|
|
||||||
const CRB_LOC_CTRL: u32 = 0x08;
|
const CRB_LOC_CTRL: u32 = 0x08;
|
||||||
const CRB_LOC_CTRL_REQUEST_ACCESS: u32 = 1 << 0;
|
const CRB_LOC_CTRL_REQUEST_ACCESS: u32 = 1 << 0;
|
||||||
const CRB_LOC_CTRL_RELINQUISH: u32 = 1 << 1;
|
const CRB_LOC_CTRL_RELINQUISH: u32 = 1 << 1;
|
||||||
const CRB_LOC_CTRL_RESET_ESTABLISHMENT_BIT: u32 = 1 << 3;
|
const CRB_LOC_CTRL_RESET_ESTABLISHMENT_BIT: u32 = 1 << 3;
|
||||||
const CRB_LOC_STS: u32 = 0x0C;
|
const CRB_LOC_STS: u32 = 0x0C;
|
||||||
const CRB_LOC_STS_FIELDS: phf::Map<&str, [u32; 2]> = phf_map! {
|
const fn get_crb_loc_sts_field(f: LocStsFields) -> (u32, u32, u32) {
|
||||||
"Granted" => [0, 1],
|
let (offset, len) = match f {
|
||||||
"beenSeized" => [1,1]
|
LocStsFields::Granted => (0, 1),
|
||||||
};
|
LocStsFields::BeenSeized => (1, 1),
|
||||||
|
};
|
||||||
|
|
||||||
|
(CRB_LOC_STS, offset, len)
|
||||||
|
}
|
||||||
|
|
||||||
const CRB_INTF_ID: u32 = 0x30;
|
const CRB_INTF_ID: u32 = 0x30;
|
||||||
const CRB_INTF_ID_FIELDS: phf::Map<&str, [u32; 2]> = phf_map! {
|
const fn get_crb_intf_id_field(f: IntfIdFields) -> (u32, u32, u32) {
|
||||||
"InterfaceType" => [0, 4],
|
let (offset, len) = match f {
|
||||||
"InterfaceVersion" => [4, 4],
|
IntfIdFields::InterfaceType => (0, 4),
|
||||||
"CapLocality" => [8, 1],
|
IntfIdFields::InterfaceVersion => (4, 4),
|
||||||
"CapCRBIdleBypass" => [9, 1],
|
IntfIdFields::CapLocality => (8, 1),
|
||||||
"Reserved1" => [10, 1],
|
IntfIdFields::CapCRBIdleBypass => (9, 1),
|
||||||
"CapDataXferSizeSupport" => [11, 2],
|
IntfIdFields::Reserved1 => (10, 1),
|
||||||
"CapFIFO" => [13, 1],
|
IntfIdFields::CapDataXferSizeSupport => (11, 2),
|
||||||
"CapCRB" => [14, 1],
|
IntfIdFields::CapFIFO => (13, 1),
|
||||||
"CapIFRes" => [15, 2],
|
IntfIdFields::CapCRB => (14, 1),
|
||||||
"InterfaceSelector" => [17, 2],
|
IntfIdFields::CapIFRes => (15, 2),
|
||||||
"IntfSelLock" => [19, 1],
|
IntfIdFields::InterfaceSelector => (17, 2),
|
||||||
"Reserved2" => [20, 4],
|
IntfIdFields::IntfSelLock => (19, 1),
|
||||||
"RID" => [24, 8]
|
IntfIdFields::Reserved2 => (20, 4),
|
||||||
};
|
IntfIdFields::Rid => (24, 8),
|
||||||
|
};
|
||||||
|
|
||||||
|
(CRB_INTF_ID, offset, len)
|
||||||
|
}
|
||||||
|
|
||||||
const CRB_INTF_ID2: u32 = 0x34;
|
const CRB_INTF_ID2: u32 = 0x34;
|
||||||
const CRB_INTF_ID2_FIELDS: phf::Map<&str, [u32; 2]> = phf_map! {
|
const fn get_crb_intf_id2_field(f: IntfId2Fields) -> (u32, u32, u32) {
|
||||||
"VID" => [0, 16],
|
let (offset, len) = match f {
|
||||||
"DID" => [16, 16]
|
IntfId2Fields::Vid => (0, 16),
|
||||||
};
|
IntfId2Fields::Did => (16, 16),
|
||||||
|
};
|
||||||
|
|
||||||
|
(CRB_INTF_ID2, offset, len)
|
||||||
|
}
|
||||||
|
|
||||||
const CRB_CTRL_REQ: u32 = 0x40;
|
const CRB_CTRL_REQ: u32 = 0x40;
|
||||||
const CRB_CTRL_REQ_CMD_READY: u32 = 1 << 0;
|
const CRB_CTRL_REQ_CMD_READY: u32 = 1 << 0;
|
||||||
const CRB_CTRL_REQ_GO_IDLE: u32 = 1 << 1;
|
const CRB_CTRL_REQ_GO_IDLE: u32 = 1 << 1;
|
||||||
const CRB_CTRL_STS: u32 = 0x44;
|
const CRB_CTRL_STS: u32 = 0x44;
|
||||||
const CRB_CTRL_STS_FIELDS: phf::Map<&str, [u32; 2]> = phf_map! {
|
const fn get_crb_ctrl_sts_field(f: CtrlStsFields) -> (u32, u32, u32) {
|
||||||
"tpmSts" => [0, 1],
|
let (offset, len) = match f {
|
||||||
"tpmIdle" => [1, 1]
|
CtrlStsFields::TpmSts => (0, 1),
|
||||||
};
|
CtrlStsFields::TpmIdle => (1, 1),
|
||||||
|
};
|
||||||
|
|
||||||
|
(CRB_CTRL_STS, offset, len)
|
||||||
|
}
|
||||||
const CRB_CTRL_CANCEL: u32 = 0x48;
|
const CRB_CTRL_CANCEL: u32 = 0x48;
|
||||||
const CRB_CANCEL_INVOKE: u32 = 1 << 0;
|
const CRB_CANCEL_INVOKE: u32 = 1 << 0;
|
||||||
const CRB_CTRL_START: u32 = 0x4C;
|
const CRB_CTRL_START: u32 = 0x4C;
|
||||||
@ -109,47 +183,29 @@ const PCI_VENDOR_ID_IBM: u32 = 0x1014;
|
|||||||
const CRB_CTRL_CMD_SIZE_REG: u32 = 0x58;
|
const CRB_CTRL_CMD_SIZE_REG: u32 = 0x58;
|
||||||
const CRB_CTRL_CMD_SIZE: usize = TPM_CRB_ADDR_SIZE - CRB_DATA_BUFFER as usize;
|
const CRB_CTRL_CMD_SIZE: usize = TPM_CRB_ADDR_SIZE - CRB_DATA_BUFFER as usize;
|
||||||
|
|
||||||
fn get_fields_map(reg: u32) -> phf::Map<&'static str, [u32; 2]> {
|
// Returns (register base, offset, len)
|
||||||
|
const fn get_field(reg: CrbRegister) -> (u32, u32, u32) {
|
||||||
match reg {
|
match reg {
|
||||||
CRB_LOC_STATE => CRB_LOC_STATE_FIELDS,
|
CrbRegister::LocState(f) => get_crb_loc_state_field(f),
|
||||||
CRB_LOC_STS => CRB_LOC_STS_FIELDS,
|
CrbRegister::LocSts(f) => get_crb_loc_sts_field(f),
|
||||||
CRB_INTF_ID => CRB_INTF_ID_FIELDS,
|
CrbRegister::IntfId(f) => get_crb_intf_id_field(f),
|
||||||
CRB_INTF_ID2 => CRB_INTF_ID2_FIELDS,
|
CrbRegister::IntfId2(f) => get_crb_intf_id2_field(f),
|
||||||
CRB_CTRL_STS => CRB_CTRL_STS_FIELDS,
|
CrbRegister::CtrlSts(f) => get_crb_ctrl_sts_field(f),
|
||||||
_ => {
|
|
||||||
panic!("Fields in '{reg:?}' register were accessed which are Invalid");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set a particular field in a Register
|
// Set a particular field in a Register
|
||||||
fn set_reg_field(regs: &mut [u32; TPM_CRB_R_MAX], reg: u32, field: &str, value: u32) {
|
fn set_reg_field(regs: &mut [u32; TPM_CRB_R_MAX], reg: CrbRegister, value: u32) {
|
||||||
let reg_fields = get_fields_map(reg);
|
let (base, offset, len) = get_field(reg);
|
||||||
if reg_fields.contains_key(field) {
|
let mask = (!(0_u32) >> (32 - len)) << offset;
|
||||||
let start = reg_fields.get(field).unwrap()[0];
|
regs[base as usize] = (regs[base as usize] & !mask) | ((value << offset) & mask);
|
||||||
let len = reg_fields.get(field).unwrap()[1];
|
|
||||||
let mask = (!(0_u32) >> (32 - len)) << start;
|
|
||||||
regs[reg as usize] = (regs[reg as usize] & !mask) | ((value << start) & mask);
|
|
||||||
} else {
|
|
||||||
error!(
|
|
||||||
"Failed to tpm Register. {:?} is not a valid field in Reg {:#X}",
|
|
||||||
field, reg
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the value of a particular field in a Register
|
// Get the value of a particular field in a Register
|
||||||
fn get_reg_field(regs: &[u32; TPM_CRB_R_MAX], reg: u32, field: &str) -> u32 {
|
const fn get_reg_field(regs: &[u32; TPM_CRB_R_MAX], reg: CrbRegister) -> u32 {
|
||||||
let reg_fields = get_fields_map(reg);
|
let (base, offset, len) = get_field(reg);
|
||||||
if reg_fields.contains_key(field) {
|
let mask = (!(0_u32) >> (32 - len)) << offset;
|
||||||
let start = reg_fields.get(field).unwrap()[0];
|
(regs[base as usize] & mask) >> offset
|
||||||
let len = reg_fields.get(field).unwrap()[1];
|
|
||||||
let mask = (!(0_u32) >> (32 - len)) << start;
|
|
||||||
(regs[reg as usize] & mask) >> start
|
|
||||||
} else {
|
|
||||||
// TODO: Sensible return value if fields do not exist
|
|
||||||
0x0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn locality_from_addr(addr: u32) -> u8 {
|
fn locality_from_addr(addr: u32) -> u8 {
|
||||||
@ -182,74 +238,93 @@ impl Tpm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_active_locality(&mut self) -> u32 {
|
fn get_active_locality(&mut self) -> u32 {
|
||||||
if get_reg_field(&self.regs, CRB_LOC_STATE, "locAssigned") == 0 {
|
if get_reg_field(
|
||||||
|
&self.regs,
|
||||||
|
CrbRegister::LocState(LocStateFields::LocAssigned),
|
||||||
|
) == 0
|
||||||
|
{
|
||||||
return TPM_CRB_NO_LOCALITY;
|
return TPM_CRB_NO_LOCALITY;
|
||||||
}
|
}
|
||||||
get_reg_field(&self.regs, CRB_LOC_STATE, "activeLocality")
|
get_reg_field(
|
||||||
|
&self.regs,
|
||||||
|
CrbRegister::LocState(LocStateFields::ActiveLocality),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn request_completed(&mut self, result: isize) {
|
fn request_completed(&mut self, result: isize) {
|
||||||
self.regs[CRB_CTRL_START as usize] = !CRB_START_INVOKE;
|
self.regs[CRB_CTRL_START as usize] = !CRB_START_INVOKE;
|
||||||
if result != 0 {
|
if result != 0 {
|
||||||
set_reg_field(&mut self.regs, CRB_CTRL_STS, "tpmSts", 1);
|
set_reg_field(
|
||||||
|
&mut self.regs,
|
||||||
|
CrbRegister::CtrlSts(CtrlStsFields::TpmSts),
|
||||||
|
1,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset(&mut self) -> Result<()> {
|
fn reset(&mut self) -> Result<()> {
|
||||||
let cur_buff_size = self.emulator.get_buffer_size().unwrap();
|
let cur_buff_size = self.emulator.get_buffer_size().unwrap();
|
||||||
self.regs = [0; TPM_CRB_R_MAX];
|
self.regs = [0; TPM_CRB_R_MAX];
|
||||||
set_reg_field(&mut self.regs, CRB_LOC_STATE, "tpmRegValidSts", 1);
|
|
||||||
set_reg_field(&mut self.regs, CRB_CTRL_STS, "tpmIdle", 1);
|
|
||||||
set_reg_field(
|
set_reg_field(
|
||||||
&mut self.regs,
|
&mut self.regs,
|
||||||
CRB_INTF_ID,
|
CrbRegister::LocState(LocStateFields::TpmRegValidSts),
|
||||||
"InterfaceType",
|
1,
|
||||||
|
);
|
||||||
|
set_reg_field(
|
||||||
|
&mut self.regs,
|
||||||
|
CrbRegister::CtrlSts(CtrlStsFields::TpmIdle),
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
set_reg_field(
|
||||||
|
&mut self.regs,
|
||||||
|
CrbRegister::IntfId(IntfIdFields::InterfaceType),
|
||||||
CRB_INTF_TYPE_CRB_ACTIVE,
|
CRB_INTF_TYPE_CRB_ACTIVE,
|
||||||
);
|
);
|
||||||
set_reg_field(
|
set_reg_field(
|
||||||
&mut self.regs,
|
&mut self.regs,
|
||||||
CRB_INTF_ID,
|
CrbRegister::IntfId(IntfIdFields::InterfaceVersion),
|
||||||
"InterfaceVersion",
|
|
||||||
CRB_INTF_VERSION_CRB,
|
CRB_INTF_VERSION_CRB,
|
||||||
);
|
);
|
||||||
set_reg_field(
|
set_reg_field(
|
||||||
&mut self.regs,
|
&mut self.regs,
|
||||||
CRB_INTF_ID,
|
CrbRegister::IntfId(IntfIdFields::CapLocality),
|
||||||
"CapLocality",
|
|
||||||
CRB_INTF_CAP_LOCALITY_0_ONLY,
|
CRB_INTF_CAP_LOCALITY_0_ONLY,
|
||||||
);
|
);
|
||||||
set_reg_field(
|
set_reg_field(
|
||||||
&mut self.regs,
|
&mut self.regs,
|
||||||
CRB_INTF_ID,
|
CrbRegister::IntfId(IntfIdFields::CapCRBIdleBypass),
|
||||||
"CapCRBIdleBypass",
|
|
||||||
CRB_INTF_CAP_IDLE_FAST,
|
CRB_INTF_CAP_IDLE_FAST,
|
||||||
);
|
);
|
||||||
set_reg_field(
|
set_reg_field(
|
||||||
&mut self.regs,
|
&mut self.regs,
|
||||||
CRB_INTF_ID,
|
CrbRegister::IntfId(IntfIdFields::CapDataXferSizeSupport),
|
||||||
"CapDataXferSizeSupport",
|
|
||||||
CRB_INTF_CAP_XFER_SIZE_64,
|
CRB_INTF_CAP_XFER_SIZE_64,
|
||||||
);
|
);
|
||||||
set_reg_field(
|
set_reg_field(
|
||||||
&mut self.regs,
|
&mut self.regs,
|
||||||
CRB_INTF_ID,
|
CrbRegister::IntfId(IntfIdFields::CapFIFO),
|
||||||
"CapFIFO",
|
|
||||||
CRB_INTF_CAP_FIFO_NOT_SUPPORTED,
|
CRB_INTF_CAP_FIFO_NOT_SUPPORTED,
|
||||||
);
|
);
|
||||||
set_reg_field(
|
set_reg_field(
|
||||||
&mut self.regs,
|
&mut self.regs,
|
||||||
CRB_INTF_ID,
|
CrbRegister::IntfId(IntfIdFields::CapCRB),
|
||||||
"CapCRB",
|
|
||||||
CRB_INTF_CAP_CRB_SUPPORTED,
|
CRB_INTF_CAP_CRB_SUPPORTED,
|
||||||
);
|
);
|
||||||
set_reg_field(
|
set_reg_field(
|
||||||
&mut self.regs,
|
&mut self.regs,
|
||||||
CRB_INTF_ID,
|
CrbRegister::IntfId(IntfIdFields::InterfaceSelector),
|
||||||
"InterfaceSelector",
|
|
||||||
CRB_INTF_IF_SELECTOR_CRB,
|
CRB_INTF_IF_SELECTOR_CRB,
|
||||||
);
|
);
|
||||||
set_reg_field(&mut self.regs, CRB_INTF_ID, "RID", 0b0000);
|
set_reg_field(
|
||||||
set_reg_field(&mut self.regs, CRB_INTF_ID2, "VID", PCI_VENDOR_ID_IBM);
|
&mut self.regs,
|
||||||
|
CrbRegister::IntfId(IntfIdFields::Rid),
|
||||||
|
0b0000,
|
||||||
|
);
|
||||||
|
set_reg_field(
|
||||||
|
&mut self.regs,
|
||||||
|
CrbRegister::IntfId2(IntfId2Fields::Vid),
|
||||||
|
PCI_VENDOR_ID_IBM,
|
||||||
|
);
|
||||||
|
|
||||||
self.regs[CRB_CTRL_CMD_SIZE_REG as usize] = CRB_CTRL_CMD_SIZE as u32;
|
self.regs[CRB_CTRL_CMD_SIZE_REG as usize] = CRB_CTRL_CMD_SIZE as u32;
|
||||||
self.regs[CRB_CTRL_CMD_LADDR as usize] = TPM_CRB_ADDR_BASE + CRB_DATA_BUFFER;
|
self.regs[CRB_CTRL_CMD_LADDR as usize] = TPM_CRB_ADDR_BASE + CRB_DATA_BUFFER;
|
||||||
@ -367,10 +442,18 @@ impl BusDevice for Tpm {
|
|||||||
}
|
}
|
||||||
CRB_CTRL_REQ => match v {
|
CRB_CTRL_REQ => match v {
|
||||||
CRB_CTRL_REQ_CMD_READY => {
|
CRB_CTRL_REQ_CMD_READY => {
|
||||||
set_reg_field(&mut self.regs, CRB_CTRL_STS, "tpmIdle", 0);
|
set_reg_field(
|
||||||
|
&mut self.regs,
|
||||||
|
CrbRegister::CtrlSts(CtrlStsFields::TpmIdle),
|
||||||
|
0,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
CRB_CTRL_REQ_GO_IDLE => {
|
CRB_CTRL_REQ_GO_IDLE => {
|
||||||
set_reg_field(&mut self.regs, CRB_CTRL_STS, "tpmIdle", 1);
|
set_reg_field(
|
||||||
|
&mut self.regs,
|
||||||
|
CrbRegister::CtrlSts(CtrlStsFields::TpmIdle),
|
||||||
|
1,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
error!("Invalid value passed to CRTL_REQ register");
|
error!("Invalid value passed to CRTL_REQ register");
|
||||||
@ -424,13 +507,33 @@ impl BusDevice for Tpm {
|
|||||||
match v {
|
match v {
|
||||||
CRB_LOC_CTRL_RESET_ESTABLISHMENT_BIT => {}
|
CRB_LOC_CTRL_RESET_ESTABLISHMENT_BIT => {}
|
||||||
CRB_LOC_CTRL_RELINQUISH => {
|
CRB_LOC_CTRL_RELINQUISH => {
|
||||||
set_reg_field(&mut self.regs, CRB_LOC_STATE, "locAssigned", 0);
|
set_reg_field(
|
||||||
set_reg_field(&mut self.regs, CRB_LOC_STS, "Granted", 0);
|
&mut self.regs,
|
||||||
|
CrbRegister::LocState(LocStateFields::LocAssigned),
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
set_reg_field(
|
||||||
|
&mut self.regs,
|
||||||
|
CrbRegister::LocSts(LocStsFields::Granted),
|
||||||
|
0,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
CRB_LOC_CTRL_REQUEST_ACCESS => {
|
CRB_LOC_CTRL_REQUEST_ACCESS => {
|
||||||
set_reg_field(&mut self.regs, CRB_LOC_STS, "Granted", 1);
|
set_reg_field(
|
||||||
set_reg_field(&mut self.regs, CRB_LOC_STS, "beenSeized", 0);
|
&mut self.regs,
|
||||||
set_reg_field(&mut self.regs, CRB_LOC_STATE, "locAssigned", 1);
|
CrbRegister::LocSts(LocStsFields::Granted),
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
set_reg_field(
|
||||||
|
&mut self.regs,
|
||||||
|
CrbRegister::LocSts(LocStsFields::BeenSeized),
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
set_reg_field(
|
||||||
|
&mut self.regs,
|
||||||
|
CrbRegister::LocState(LocStateFields::LocAssigned),
|
||||||
|
1,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
error!("Invalid value to write in CRB_LOC_CTRL {:#X} ", v);
|
error!("Invalid value to write in CRB_LOC_CTRL {:#X} ", v);
|
||||||
@ -457,9 +560,9 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_set_get_reg_field() {
|
fn test_set_get_reg_field() {
|
||||||
let mut regs: [u32; TPM_CRB_R_MAX] = [0; TPM_CRB_R_MAX];
|
let mut regs: [u32; TPM_CRB_R_MAX] = [0; TPM_CRB_R_MAX];
|
||||||
set_reg_field(&mut regs, CRB_INTF_ID, "RID", 0xAC);
|
set_reg_field(&mut regs, CrbRegister::IntfId(IntfIdFields::Rid), 0xAC);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
get_reg_field(®s, CRB_INTF_ID, "RID"),
|
get_reg_field(®s, CrbRegister::IntfId(IntfIdFields::Rid)),
|
||||||
0xAC,
|
0xAC,
|
||||||
concat!("Test: ", stringify!(set_get_reg_field))
|
concat!("Test: ", stringify!(set_get_reg_field))
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user