use super::err::ChipNameError;
use super::Vendor;
pub const fn chip_name(
vendor: Vendor,
family: u8,
model: u8,
stepping: u8,
) -> Result<&'static str, ChipNameError> {
debug_assert!(family <= 0x1E);
debug_assert!(stepping <= 0xF);
match vendor {
Vendor::Intel => intel_chip_name(family, model, stepping),
Vendor::Amd => amd_chip_name(family, model, stepping),
Vendor::Centaur => centaur_chip_name(family, model, stepping),
Vendor::Cyrix => cyrix_chip_name(family, model),
_ => Err(ChipNameError::NoKnownNamesForVendor(vendor)),
}
}
const fn amd_chip_name(family: u8, model: u8, stepping: u8) -> Result<&'static str, ChipNameError> {
match family {
0x05 => match model {
0x06 => Ok("Model 6"),
0x07 => Ok("Little Foot"),
0x08 => match stepping {
0x0 => Ok("Chomper"),
_ => Ok("Chomper XT"),
},
0x09 => Ok("Sharptooth"),
0x0D => Ok("Sharptooth+"),
_ => Err(ChipNameError::NoKnownNamesForModel(model)),
},
0x06 => match model {
0x01 => Ok("Argon"),
0x02 => match stepping {
0x0..=0x1 => Ok("Pluto"),
_ => Ok("Orion / Pluto"),
},
0x03 => Ok("Spitfire"),
0x04 => Ok("Thunderbird"),
0x06 => Ok("Palomino"),
0x07 => Ok("Morgan"),
0x08 => match stepping {
0x0 => Ok("Thoroughbred"),
_ => Ok("Applebred / Thoroughbred"),
},
0x0A => Ok("Barton / Thorton"),
_ => Err(ChipNameError::NoKnownNamesForModel(model)),
},
0x0F => match model {
0x04 => match stepping {
0x0 => Ok("Sledgehammer-B0"),
0x8 => Ok("Sledgehammer-C0"),
0xA => Ok("Sledgehammer-CG"),
_ => Ok("Sledgehammer-B/C"),
},
0x05 => match stepping {
0x0 => Ok("Sledgehammer-B0"),
0x1 => Ok("Sledgehammer-B3"),
0x8 => Ok("Sledgehammer-C0"),
0xA => Ok("Sledgehammer-CG"),
_ => Ok("Sledgehammer-B/C"),
},
0x07 => Ok("Sledgehammer-CG"),
0x08 => Ok("Clawhammer-CG"),
0x0C => Ok("Drillhammer-CG"),
0x0E => Ok("Drillhammer-CG"),
0x0F => Ok("Drillhammer-C6"),
0x14 => Ok("Sledgehammer-D0"),
0x15 => Ok("Sledgehammer-D0"),
0x17 => Ok("Sledgehammer-D0"),
0x18 => Ok("Clawhammer-D0"),
0x1B => Ok("Clawhammer-D0"),
0x1C => Ok("Sledgehammer-D0 / Drillhammer-D0"),
0x1F => Ok("Drillhammer-D0"),
0x21 => Ok("Jackhammer-E1/E6"),
0x23 => Ok("Jackhammer-E6"),
0x24 => Ok("Sledgehammer-E5"),
0x25 => Ok("Sledgehammer-E4"),
0x27 => Ok("Sledgehammer-E4"),
0x2B => Ok("BallpeenHammer-E4"),
0x2C => match stepping {
0x0 => Ok("Drillhammer-E3"),
0x2 => Ok("Drillhammer-E6"),
_ => Ok("Drillhammer-E"),
},
0x2F => match stepping {
0x0 => Ok("Drillhammer-E3"),
0x2 => Ok("Drillhammer-E6"),
_ => Ok("Drillhammer-E"),
},
0x41 => Ok("Jackhammer-F2"),
0x43 => match stepping {
0x2 => Ok("Jackhammer-F2"),
0x3 => Ok("Jackhammer-F3"),
_ => Ok("Jackhammer-F"),
},
0x48 => Ok("BallpeenHammer-F2"),
0x4B => Ok("BallpeenHammer-F2"),
0x4C => Ok("Drillhammer-F2"),
0x4F => Ok("Drillhammer-F2"),
0x5D => Ok("Jackhammer-F3"),
0x5F => match stepping {
0x2 => Ok("Drillhammer-F2"),
0x3 => Ok("Drillhammer-F3"),
_ => Ok("Drillhammer-F"),
},
0x68 => match stepping {
0x1 => Ok("BallpeenHammer-G1"),
0x2 => Ok("BallpeenHammer-G2"),
_ => Ok("BallpeenHammer-G"),
},
0x6B => match stepping {
0x1 => Ok("BallpeenHammer-G1"),
0x2 => Ok("BallpeenHammer-G2"),
_ => Ok("BallpeenHammer-G"),
},
0x6F => Ok("Drillhammer-G2"),
0x7F => match stepping {
0x1 => Ok("Drillhammer-G1"),
0x2 => Ok("Drillhammer-G2"),
_ => Ok("Drillhammer-G"),
},
0xC1 => Ok("Jackhammer-F3"),
_ => Err(ChipNameError::NoKnownNamesForModel(model)),
},
0x10 => match model {
0x02 => Ok("Deerhound"),
0x04 => Ok("Ridgeback"),
0x05 => Ok("Bloodhound"),
0x06 => Ok("Dachshund"),
0x08 => Ok("Hydra"),
0x09 => Ok("Hydra"), 0x0A => Ok("Pharaoh"),
_ => Err(ChipNameError::NoKnownNamesForModel(model)),
},
0x11 => match model {
0x03 => Ok("Lion"),
_ => Err(ChipNameError::NoKnownNamesForModel(model)),
},
0x12 => match model {
0x00 => Ok("Llano"),
0x01 => Ok("Llano"),
_ => Err(ChipNameError::NoKnownNamesForModel(model)),
},
0x14 => match model {
0x02 => Ok("Desna / Ontario / Zacate"),
_ => Err(ChipNameError::NoKnownNamesForModel(model)),
},
0x15 => match model {
0x00 => Ok("Interlagos"),
0x01 => match stepping {
0x0 => Ok("Interlagos / Zambezi"),
0x1 => Ok("Interlagos"),
_ => Ok("Interlagos / Valencia / Zambezi / Zurich"),
},
0x02 => Ok("Abu Dhabi / Delhi / Seoul / Vishera / Warsaw"),
0x10 => match stepping {
0x0 => Ok("Trinity"),
_ => Ok("eTrinity / Trinity"),
},
0x13 => Ok("Richland"),
0x30 => match stepping {
0x0 => Ok("Kaveri"),
_ => Ok("Bald Eagle / Kaveri"),
},
0x38 => Ok("Godavari"),
0x60 => Ok("Brown Falcon / Carrizo / Merlin Falcon"),
0x65 => Ok("Bristol Ridge"),
0x70 => Ok("Stoney Ridge"),
_ => Err(ChipNameError::NoKnownNamesForModel(model)),
},
0x16 => match model {
0x00 => Ok("Kabini / Kyoto / Temash"),
0x30 => Ok("Beema / Mullins"),
_ => Err(ChipNameError::NoKnownNamesForModel(model)),
},
0x17 => match model {
0x01 => match stepping {
0x1 => Ok("Summit Ridge / Whitehaven"),
0x2 => Ok("Naples"),
_ => Ok("Summit Ridge / Whitehaven / Naples"),
},
0x08 => Ok("Colfax / Pinnacle Ridge"),
0x11 => Ok("Raven Ridge"),
0x18 => Ok("Picasso"),
0x20 => Ok("Dali"),
0x50 => Ok("Fenghuang"),
0x31 => Ok("Rome / Castle Peak"),
0x47 => Ok("Oberon"), 0x60 => Ok("Renoir"),
0x68 => Ok("Lucienne"),
0x71 => Ok("Matisse"),
0x84 => Ok("Anaconda"), 0x90 => Ok("Van Gogh"), 0x91 => Ok("Sephiroth"), 0xA0 => Ok("Mendocino"),
_ => Err(ChipNameError::NoKnownNamesForModel(model)),
},
0x18 => match model {
0x00 => Ok("Dhyana"),
_ => Err(ChipNameError::NoKnownNamesForModel(model)),
},
0x19 => match model {
0x01 => match stepping {
0x2 => Ok("Milan-X"),
_ => Ok("Milan"),
},
0x08 => Ok("Chagall"),
0x21 => Ok("Vermeer"),
0x30 => Ok("Badami / Trento"), 0x44 => Ok("Rembrandt"),
0x50 => Ok("Barcelo / Cezanne"),
0x11 => Ok("Genoa"),
0x18 => Ok("Storm Peak"),
0x61 => Ok("Raphael"),
0x74 => Ok("Phoenix Point"),
0x75 => Ok("Hawk Point"),
0x78 => Ok("Phoenix Point 2"),
0x90 => Ok("Aqua Vanjaram"), 0xA0 => Ok("Bergamo"),
_ => Err(ChipNameError::NoKnownNamesForModel(model)),
},
0x1A => match model {
0x02 => Ok("Turin"),
0x11 => Ok("Turin-D"),
0x24 => Ok("Strix Point"),
0x44 => Ok("Granite Ridge"),
0x60 => Ok("Krackan Point"),
0x70 => Ok("Strix Halo"),
_ => Err(ChipNameError::NoKnownNamesForModel(model)),
},
_ => Err(ChipNameError::NoKnownNamesForFamily(family)),
}
}
const fn centaur_chip_name(
family: u8,
model: u8,
stepping: u8,
) -> Result<&'static str, ChipNameError> {
match family {
0x05 => match model {
0x04 => Ok("C6"),
0x08 => match stepping {
0x7 => Ok("W2A"),
0xA => Ok("W2B"),
_ => Ok("W2"),
},
0x09 => Ok("W3"),
_ => Err(ChipNameError::NoKnownNamesForModel(model)),
},
0x06 => match model {
0x06 => Ok("Samuel"),
0x07 => match stepping {
0x0..=0x3 => Ok("Samuel 2"),
0x8 => Ok("Ezra"),
0xA => Ok("Ezra"),
_ => Ok("Samuel 2 / Ezra"),
},
0x08 => Ok("Ezra"),
0x09 => Ok("Nehemiah"),
0x0A => Ok("Esther"),
0x0D => Ok("Esther"),
0x0F => Ok("Isaiah"),
0x47 => Ok("CHA"),
_ => Err(ChipNameError::NoKnownNamesForModel(model)),
},
0x07 => match model {
0x1B => Ok("Wudaokou"),
0x3B => Ok("Lujiazui"),
0x5B => Ok("Yongfeng"),
0x6B => Ok("Shijidadao"),
_ => Err(ChipNameError::NoKnownNamesForModel(model)),
},
_ => Err(ChipNameError::NoKnownNamesForFamily(family)),
}
}
const fn cyrix_chip_name(family: u8, model: u8) -> Result<&'static str, ChipNameError> {
match family {
0x4 => match model {
0x4 => Ok("GX / GXi"),
_ => Err(ChipNameError::NoKnownNamesForModel(model)),
},
0x5 => match model {
0x2 => Ok("M1 / M1L"),
0x3 => Ok("M1"),
0x4 => Ok("GXm"),
_ => Err(ChipNameError::NoKnownNamesForModel(model)),
},
0x6 => Ok("M2"),
_ => Err(ChipNameError::NoKnownNamesForFamily(family)),
}
}
const fn intel_chip_name(
family: u8,
model: u8,
stepping: u8,
) -> Result<&'static str, ChipNameError> {
match family {
0x05 => match model {
0x01 => Ok("P5"),
0x02 => match stepping {
0x4 => Ok("P54C / P54CQS"),
0x5 => Ok("P54C / P54CQS / P54CS"),
0x6 => Ok("P54C / P54CQS"),
0xB => Ok("P54C / P54CQS / P54CS"),
0xC => Ok("P54C / P54CQS / P54CS"),
_ => Ok("P54C"),
},
0x04 => Ok("P55C"),
0x08 => Ok("Tillamook"),
_ => Err(ChipNameError::NoKnownNamesForModel(model)),
},
0x06 => match model {
0x01 => Ok("P6"),
0x03 => Ok("Klamath"),
0x05 => match stepping {
0x0..=0x1 => Ok("Covington / Deschutes"),
0x2..=0x3 => Ok("Deschutes / Drake"),
_ => Ok("Covington / Deschutes / Drake"),
},
0x06 => match stepping {
0xA => Ok("Dixon / Mendocino"),
_ => Ok("Mendocino"),
},
0x07 => Ok("Katmai / Tanner"),
0x08 => match stepping {
0xA => Ok("Coppermine / Coppermine-T"),
_ => Ok("Cascades / Coppermine"),
},
0x0A => Ok("Cascades"),
0x0B => match stepping {
0x1 => Ok("Coppermine-T / Tualatin"),
_ => Ok("Tualatin"),
},
0x09 => Ok("Banias"),
0x0D => match stepping {
0x8 => Ok("Dothan / Stealey"),
_ => Ok("Dothan"),
},
0x0E => match stepping {
0x8 | 0xC => Ok("Sossaman / Yonah"),
_ => Ok("Yonah"),
},
0x0F => match stepping {
0x1 => Ok("Conroe / Conroe-L"),
0x2 => Ok("Allendale / Conroe / Merom"),
0x4 => Ok("Clovertown / Conroe / Kentsfield / Merom"),
0x5 => Ok("Allendale / Conroe / Conroe XE / Kentsfield / Merom / Woodcrest"),
0x6 => Ok("Allendale / Conroe / Conroe XE / Merom / Woodcrest"),
0x7 => Ok("Clovertown / Kentsfield"),
0x9 => Ok("Conroe"),
0xB => Ok("Allendale / Clovertown / Conroe / Conroe-CL / Kentsfield / Merom / Tigerton / Woodcrest"),
0xD => Ok("Allendale / Conroe / Merom / Merom-2M"),
_ => Ok("Merom"),
},
0x16 => Ok("Conroe-L"),
0x17 => match stepping {
0x4 => Ok("Harpertown"),
0x6 => Ok("Harpertown / Penryn / Penryn-3M / Wolfdale / Wolfdale-3M / Yorkfield / Yorkfield-CL"),
0x7 => Ok("Yorkfield"),
0xA => Ok("Harpertown / Penryn / Penryn-3M / Penryn-L / Wolfdale / Wolfdale-3M / Wolfdale-CL / Yorkfield / Yorkfield-CL"),
_ => Ok("Penryn"),
},
0x1D => Ok("Dunnington"),
0x1A => match stepping {
0x4 => Ok("Bloomfield / Gainestown"),
0x5 => Ok("Bloomfield / Gainestown / Nehalem-WS"),
_ => Ok("Nehalem"),
},
0x1E => match stepping {
0x4 => Ok("Jasper Forest"),
0x5 => Ok("Clarksfield / Lynnfield"),
_ => Ok("Nehalem"),
},
0x1F => Ok("Auburndale / Havendale"),
0x2E => Ok("Beckton"),
0x25 => match stepping {
0x0 => Ok("Arrandale"),
0x1 | 0x2 | 0x5 => Ok("Arrandale / Clarkdale"),
_ => Ok("Westmere"),
},
0x2C => match stepping {
0x0 => Ok("Westmere-EP"),
0x1..=0x2 => Ok("Gulftown / Westmere-EP"),
_ => Ok("Westmere"),
},
0x2F => Ok("Westmere-EX"),
0x2A => Ok("Sandy Bridge"),
0x2D => match stepping {
0x5 => Ok("Sandy Bridge-E/EP"),
0x6..=0x7 => Ok("Sandy Bridge-E/EN/EP"),
_ => Ok("Sandy Bridge"),
},
0x3A => Ok("Ivy Bridge"),
0x3E => match stepping {
0x3 => Ok("Ivy Bridge-EP"),
0x4 => Ok("Ivy Bridge-E/EN/EP"),
0x7 => Ok("Ivy Bridge-EX"),
_ => Ok("Ivy Bridge"),
},
0x3C => match stepping {
0x3 => Ok("Haswell / Devil's Canyon"),
_ => Ok("Haswell"),
},
0x3F => match stepping {
0x2 => Ok("Haswell-E/EN/EP"),
0x4 => Ok("Haswell-EX"),
_ => Ok("Haswell"),
},
0x45 => Ok("Haswell"),
0x46 => Ok("Crystall Well"),
0x3D => Ok("Broadwell-U/Y"),
0x47 => Ok("Broadwell-H/K"),
0x4F => Ok("Broadwell-E/EP/EX"),
0x56 => match stepping {
0x5 => Ok("Broadwell-DE / Hewitt Lake"),
_ => Ok("Broadwell-DE"),
},
0x4E => Ok("Skylake-U/Y"),
0x55 => match stepping {
0x0..=0x3 => Ok("Skylake-SP"),
0x4 => Ok("Skylake-SP/W/X"),
0x5..=0x6 => Ok("Cascade Lake-SP"),
0x7 => Ok("Cascade Lake-AP/SP/W/X / Glacier Falls-W"),
0xA..=0xB => Ok("Cooper Lake-SP"),
_ => Ok("Skylake / Cascade Lake / Cooper Lake / Glacier Falls"),
},
0x5E => Ok("Skylake-H/S"),
0x8E => match stepping {
0x9 => Ok("Amber Lake-Y / Kaby Lake-U/Y"),
0xA => Ok("Coffee Lake-U / Kaby Lake-R/U"),
0xB => Ok("Whiskey Lake-U"),
0xC => Ok("Amber Lake-Y / Comet Lake-U / Whiskey Lake-U"),
_ => Ok("Amber Lake / Coffee Lake / Comet Lake / Kaby Lake / Whiskey Lake"),
},
0x9E => match stepping {
0x0..=0x9 => Ok("Kaby Lake-G/H/S/X"),
0xA..=0xD => Ok("Coffee Lake-E/H/S"),
_ => Ok("Kaby Lake / Coffee Lake"),
},
0xA5 => match stepping {
0x2 => Ok("Comet Lake-H"),
_ => Ok("Comet Lake-S"),
},
0xA6 => Ok("Comet Lake-U"),
0x66 => Ok("Cannon Lake-U"),
0x6A => Ok("Ice Lake-SP/W"),
0x6C => Ok("Ice Lake-D"),
0x7D => Ok("Ice Lake-H/S"),
0x7E => Ok("Ice Lake-U/UN/Y/YN"),
0x8A => Ok("Lakefield"),
0x9D => Ok("Spring Hill"),
0x8C => match stepping {
0x1 => Ok("Tiger Lake-H35/UP3/UP4"),
0x2 => Ok("Tiger Lake-H35/UP3"),
_ => Ok("Tiger Lake"),
},
0x8D => Ok("Tiger Lake-H"),
0xA7 => Ok("Rocket Lake-E/S"),
0x8F => match stepping {
0x0 => Ok("Sapphire Rapids (Unstable Edition)"),
0x7 => Ok("Sapphire Rapids-SP"),
0x8 => Ok("Sapphire Rapids-EE/SP/W"),
_ => Ok("Sapphire Rapids"),
},
0x97 => match stepping {
0x2 => Ok("Alder Lake-HX/S"),
0x5 => Ok("Alder Lake-S"),
_ => Ok("Alder Lake"),
},
0x9A => match stepping {
0x3 => Ok("Alder Lake-H/P/PS"),
0x4 => Ok("Alder Lake-P/PS/U"),
_ => Ok("Alder Lake"),
},
0xB7 => Ok("Raptor Lake-E/HX/S"),
0xBA => match stepping {
0x2 => Ok("Raptor Lake-H/P"),
0x3 => Ok("Raptor Lake-U"),
_ => Ok("Raptor Lake"),
},
0xBF => match stepping {
0x2 => Ok("Raptor Lake-HX/S"),
0x5 => Ok("Raptor Lake-S"),
_ => Ok("Raptor Lake"),
},
0xCF => Ok("Emerald Rapids-SP"),
0xD7 => Ok("Bartlett Lake"),
0xAA => Ok("Meteor Lake"),
0xAC => Ok("Meteor Lake-L"),
0xAD => Ok("Granite Rapids-X"),
0xAE => Ok("Granite Rapids-D"),
0xB5 => Ok("Arrow Lake-U"),
0xBD => Ok("Lunar Lake-M"),
0xC5 => Ok("Arrow Lake-H"),
0xC6 => Ok("Arrow Lake"),
0xCC => Ok("Panther Lake-L"),
0x1C => Ok("Diamondville / Pineview / Silverthorne"),
0x26 => Ok("Lincroft"),
0x27 => Ok("Penwell"),
0x35 => Ok("Cloverview"),
0x36 => Ok("Cedarview"),
0x37 => Ok("Bay Trail"),
0x4A => Ok("Tangier / Merrifield"),
0x4D => Ok("Avaton / Rangeley"),
0x5A => Ok("Anniedale / Moorefield"),
0x5D => Ok("SoFIA"),
0x4C => Ok("Braswell / Cherry Trail"),
0x75 => Ok("Lightning Mountain"),
0x5C => Ok("Apollo Lake"),
0x5F => Ok("Denverton"),
0x7A => Ok("Gemini Lake"),
0x86 => Ok("Jacobsville"),
0x96 => Ok("Elkhart Lake"),
0x9C => Ok("Jasper Lake"),
0xBE => Ok("Alder Lake-N / Amston Lake"),
0xAF => Ok("Sierra Forest"),
0xB6 => Ok("Grand Ridge"),
0xDD => Ok("Clearwater Forest"),
0x57 => Ok("Knights Landing"),
0x85 => Ok("Knights Mill"),
_ => Err(ChipNameError::NoKnownNamesForModel(model)),
},
0x0F => match model {
0x00 => match stepping {
0x2 => Ok("Willamette"),
0xA => Ok("Foster / Willamette"),
_ => Ok("Foster / Willamette"),
},
0x01 => match stepping {
0x1 => Ok("Foster MP"),
0x2 => Ok("Foster / Willamette"),
0x3 => Ok("Willamette"),
_ => Ok("Foster / Foster MP / Willamette"),
},
0x02 => match stepping {
0x2 => Ok("Gallatin"),
0x4 => Ok("Northwood / Prestonia"),
0x5 => Ok("Gallatin / Northwood / Prestonia"),
0x6 => Ok("Gallatin"),
0x7 => Ok("Northwood / Prestonia"),
0x9 => Ok("Northwood / Prestonia"),
_ => Ok("Gallatin / Northwood / Prestonia"),
},
0x03 => match stepping {
0x1 => Ok("Nocona / Prescott"),
0x2 => Ok("Nocona / Prescott"),
0x3 => Ok("Prescott"),
0x4 => Ok("Nocona / Prescott"),
0x7 => Ok("Nocona"),
_ => Ok("Nocona / Prescott"),
},
0x04 => match stepping {
0x1 => Ok("Cranford / Nocona / Potomac / Prescott"),
0x2 => Ok("Prescott"),
0x3 => Ok("Irwindale / Prescott-2M"),
0x4 => Ok("Smithfield"),
0x7 => Ok("Smithfield"),
0x8 => Ok("Paxville / Paxville MP"),
0x9 => Ok("Cranford / Nocona / Prescott"),
0xA => Ok("Irwindale / Prescott-2M"),
_ => Ok("Cranford / Irwindale / Nocona / Paxville / Paxville MP / Prescott / Prescott-2M"),
},
0x06 => match stepping {
0x1 => Ok("Presler"),
0x2 => Ok("Cedar Mill / Presler"),
0x4 => Ok("Cedar Mill / Dempsey / Presler"),
0x5 => Ok("Cedar Mill / Presler"),
0x8 => Ok("Tulsa"),
_ => Ok("Cedar Mill / Dempsey / Presler / Tulsa"),
},
_ => Err(ChipNameError::NoKnownNamesForModel(model)),
},
0x12 => match model {
0x01 => Ok("Nova Lake"),
0x03 => Ok("Nova Lake-L"),
_ => Err(ChipNameError::NoKnownNamesForModel(model)),
},
0x13 => match model {
0x01 => Ok("Diamond Rapids"),
_ => Err(ChipNameError::NoKnownNamesForModel(model)),
},
_ => Err(ChipNameError::NoKnownNamesForFamily(family)),
}
}
#[cfg(test)]
mod tests {
use super::*;
use strum::IntoEnumIterator;
#[test]
#[should_panic]
fn invalid_family() {
let _ = chip_name(Vendor::Intel, 0xFF, 0x4E, 0x0);
}
#[test]
#[should_panic]
fn invalid_stepping() {
let _ = chip_name(Vendor::Intel, 0x06, 0x4E, 0xFF);
}
#[test]
fn no_matches_for_vendor() {
assert!(chip_name(Vendor::Sis, 0x00, 0x0F, 0x0).is_err())
}
#[test]
fn valid_inputs_never_panic() {
Vendor::iter().for_each(|vendor| {
for family in 0..=0x1E {
for model in 0..=u8::MAX {
for stepping in 0..=0xF {
let _ = chip_name(vendor, family, model, stepping);
}
}
}
});
}
}