Skip to content

Commit a48b5da

Browse files
committed
bitfield: Added x86 family field decoding
This is 2 seperate regions of a register making a seperate struct the better way to decode it properly
1 parent ce755e6 commit a48b5da

2 files changed

Lines changed: 55 additions & 1 deletion

File tree

src/bitfield.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,31 @@ impl Bindable for X86Model {
9898
}
9999
}
100100

101+
#[derive(Serialize, Deserialize, Debug)]
102+
pub struct X86Family {
103+
pub name: String,
104+
}
105+
106+
const EXTENDED_FAMILY_START_BIT: u8 = 20;
107+
impl Bindable for X86Family {
108+
type Rep = u32;
109+
fn value(&self, reg_val: Register) -> Option<Self::Rep> {
110+
let reg32 = reg_val as u32;
111+
const FAMILY_MASK: u32 = 0xF;
112+
const EXT_FAMILY_MASK: u32 = 0xFF;
113+
let family = (reg32 >> FAMILY_START_BIT) & FAMILY_MASK;
114+
let extended_family = (reg32 >> EXTENDED_FAMILY_START_BIT) & EXT_FAMILY_MASK;
115+
116+
match family {
117+
0xF => Some(extended_family + family),
118+
_ => Some(family),
119+
}
120+
}
121+
fn name(&self) -> &String {
122+
&self.name
123+
}
124+
}
125+
101126
pub struct Bound<'a, T: Bindable> {
102127
reg_val: Register,
103128
bits: &'a T,
@@ -162,18 +187,31 @@ impl<'a> fmt::Display for Bound<'a, X86Model> {
162187
}
163188
}
164189

190+
impl<'a> fmt::Display for Bound<'a, X86Family> {
191+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
192+
write!(
193+
f,
194+
"{} = {:>10}",
195+
self.bits.name,
196+
self.bits.value(self.reg_val).unwrap_or(0)
197+
)
198+
}
199+
}
200+
165201
#[derive(Debug, Serialize, Deserialize)]
166202
#[serde(tag = "type")]
167203
pub enum Field {
168204
Int(Int),
169205
Flag(Flag),
170206
X86Model(X86Model),
207+
X86Family(X86Family),
171208
}
172209

173210
pub enum BoundField<'a> {
174211
Int(Bound<'a, Int>),
175212
Flag(Bound<'a, Flag>),
176213
X86Model(Bound<'a, X86Model>),
214+
X86Family(Bound<'a, X86Family>),
177215
}
178216

179217
impl<'a> BoundField<'a> {
@@ -182,6 +220,7 @@ impl<'a> BoundField<'a> {
182220
Field::Int(bits) => Self::Int(Bound { reg_val, bits }),
183221
Field::Flag(bits) => Self::Flag(Bound { reg_val, bits }),
184222
Field::X86Model(bits) => Self::X86Model(Bound { reg_val, bits }),
223+
Field::X86Family(bits) => Self::X86Family(Bound { reg_val, bits }),
185224
}
186225
}
187226
}
@@ -192,6 +231,7 @@ impl<'a> fmt::Display for BoundField<'a> {
192231
Self::Int(bound) => bound.fmt(f),
193232
Self::Flag(bound) => bound.fmt(f),
194233
Self::X86Model(bound) => bound.fmt(f),
234+
Self::X86Family(bound) => bound.fmt(f),
195235
}
196236
}
197237
}
@@ -202,6 +242,7 @@ impl<'a, T: From<bool> + From<u32>> Facter<T> for BoundField<'a> {
202242
Self::Int(bound) => bound.collect_fact(),
203243
Self::Flag(bound) => bound.collect_fact(),
204244
Self::X86Model(bound) => bound.collect_fact(),
245+
Self::X86Family(bound) => bound.collect_fact(),
205246
}
206247
}
207248
}
@@ -222,4 +263,17 @@ mod test {
222263
let extended_family_model: super::Register = 0x0AF50F41;
223264
assert_eq!(field_definition.value(extended_family_model).unwrap(), 0x54);
224265
}
266+
#[test]
267+
fn x86_family_test() {
268+
let field_definition = super::X86Family {
269+
name: "model".to_string(),
270+
};
271+
let regular_model: super::Register = 0x0AE50341;
272+
assert_eq!(field_definition.value(regular_model).unwrap(), 0x3);
273+
let extended_family_model: super::Register = 0x0AE50F41;
274+
assert_eq!(
275+
field_definition.value(extended_family_model).unwrap(),
276+
0xAE + 0xF
277+
);
278+
}
225279
}

src/config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ cpuids:
1616
end: 4
1717
- type: X86Model
1818
name: model
19-
- type: Int
19+
- type: X86Family
2020
name: family
2121
bounds:
2222
start: 8

0 commit comments

Comments
 (0)