Skip to content

Commit fd899c0

Browse files
committed
--capsule: Find any number of PD binaries in capsule
The PDs may not be all the same version, so we should show them all. Signed-off-by: Daniel Schaefer <dhs@frame.work>
1 parent 98d0523 commit fd899c0

File tree

3 files changed

+56
-19
lines changed

3 files changed

+56
-19
lines changed

framework_lib/src/capsule_content.rs

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -51,19 +51,38 @@ pub fn find_ec_in_bios_cap(data: &[u8]) -> Option<&[u8]> {
5151
}
5252

5353
pub fn find_pd_in_bios_cap(data: &[u8]) -> Option<&[u8]> {
54-
// Just search for the first couple of bytes in PD binaries
55-
// TODO: There's a second one but unless the capsule is bad, we can assume
56-
// they're the same version
57-
let ccg5_needle = &[0x00, 0x20, 0x00, 0x20, 0x11, 0x00];
58-
let ccg6_needle = &[0x00, 0x40, 0x00, 0x20, 0x11, 0x00];
59-
let ccg8_needle = &[0x00, 0x80, 0x00, 0x20, 0xAD, 0x0C];
60-
if let Some(found_pd1) = util::find_sequence(data, ccg5_needle) {
61-
Some(&data[found_pd1..found_pd1 + CCG5_PD_LEN])
62-
} else if let Some(found_pd1) = util::find_sequence(data, ccg6_needle) {
63-
Some(&data[found_pd1..found_pd1 + CCG6_PD_LEN])
64-
} else if let Some(found_pd1) = util::find_sequence(data, ccg8_needle) {
65-
Some(&data[found_pd1..found_pd1 + CCG8_PD_LEN])
66-
} else {
67-
None
54+
find_all_pds_in_bios_cap(data).into_iter().next()
55+
}
56+
57+
/// PD binary signatures and their corresponding lengths
58+
const CCG5_NEEDLE: &[u8] = &[0x00, 0x20, 0x00, 0x20, 0x11, 0x00];
59+
const CCG6_NEEDLE: &[u8] = &[0x00, 0x40, 0x00, 0x20, 0x11, 0x00];
60+
const CCG8_NEEDLE: &[u8] = &[0x00, 0x80, 0x00, 0x20, 0xAD, 0x0C];
61+
62+
/// Find all PD firmware binaries embedded in a BIOS capsule
63+
pub fn find_all_pds_in_bios_cap(data: &[u8]) -> Vec<&[u8]> {
64+
let mut results = Vec::new();
65+
66+
// Search for CCG5 PDs
67+
for offset in util::find_all_sequences(data, CCG5_NEEDLE) {
68+
if offset + CCG5_PD_LEN <= data.len() {
69+
results.push(&data[offset..offset + CCG5_PD_LEN]);
70+
}
6871
}
72+
73+
// Search for CCG6 PDs
74+
for offset in util::find_all_sequences(data, CCG6_NEEDLE) {
75+
if offset + CCG6_PD_LEN <= data.len() {
76+
results.push(&data[offset..offset + CCG6_PD_LEN]);
77+
}
78+
}
79+
80+
// Search for CCG8 PDs
81+
for offset in util::find_all_sequences(data, CCG8_NEEDLE) {
82+
if offset + CCG8_PD_LEN <= data.len() {
83+
results.push(&data[offset..offset + CCG8_PD_LEN]);
84+
}
85+
}
86+
87+
results
6988
}

framework_lib/src/commandline/mod.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use crate::built_info;
2828
use crate::camera::check_camera_version;
2929
use crate::capsule;
3030
use crate::capsule_content::{
31-
find_bios_version, find_ec_in_bios_cap, find_pd_in_bios_cap, find_retimer_version,
31+
find_all_pds_in_bios_cap, find_bios_version, find_ec_in_bios_cap, find_retimer_version,
3232
};
3333
use crate::ccgx::device::{FwMode, PdController, PdPort};
3434
#[cfg(feature = "hidapi")]
@@ -1348,9 +1348,10 @@ pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 {
13481348
println!("Embedded EC");
13491349
analyze_ec_fw(ec_bin);
13501350
}
1351-
if let Some(pd_bin) = find_pd_in_bios_cap(&data) {
1351+
let pd_bins = find_all_pds_in_bios_cap(&data);
1352+
for (i, pd_bin) in pd_bins.iter().enumerate() {
13521353
found_any = true;
1353-
println!("Embedded PD");
1354+
println!("Embedded PD {}", i + 1);
13541355
analyze_ccgx_pd_fw(pd_bin);
13551356
}
13561357
if !found_any {
@@ -1935,8 +1936,9 @@ pub fn analyze_capsule(data: &[u8]) -> Option<capsule::EfiCapsuleHeader> {
19351936
println!(" RW Version: {:>18}", ver.version);
19361937
}
19371938
}
1938-
if let Some(pd_bin) = find_pd_in_bios_cap(data) {
1939-
println!("Embedded PD");
1939+
let pd_bins = find_all_pds_in_bios_cap(data);
1940+
for (i, pd_bin) in pd_bins.iter().enumerate() {
1941+
println!("Embedded PD {}", i + 1);
19401942
analyze_ccgx_pd_fw(pd_bin);
19411943
}
19421944
}

framework_lib/src/util.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,22 @@ pub fn find_sequence(haystack: &[u8], needle: &[u8]) -> Option<usize> {
258258
.position(|window| window == needle)
259259
}
260260

261+
/// Find all occurrences of a sequence of bytes in a long slice of bytes
262+
pub fn find_all_sequences(haystack: &[u8], needle: &[u8]) -> Vec<usize> {
263+
let mut results = Vec::new();
264+
let mut pos = 0;
265+
while pos + needle.len() <= haystack.len() {
266+
if let Some(offset) = find_sequence(&haystack[pos..], needle) {
267+
let absolute_pos = pos + offset;
268+
results.push(absolute_pos);
269+
pos = absolute_pos + needle.len();
270+
} else {
271+
break;
272+
}
273+
}
274+
results
275+
}
276+
261277
/// Assert length of an EC response from the windows driver
262278
/// It's always 20 more than expected. TODO: Figure out why
263279
pub fn assert_win_len<N: Num + std::fmt::Debug + Ord + NumCast + Copy>(left: N, right: N) {

0 commit comments

Comments
 (0)