mediatek_optical/receiver/programming/
reserved.rs1use super::word;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub struct ReservedSkips {
8 pub address: u32,
10 pub first_start: u32,
12 pub first_length: u32,
14 pub final_start: u32,
16 pub required_r4: u32,
18 pub continuation: u32,
20 pub finished: u32,
22}
23
24pub fn inspect_reserved_skips(bytes: &[u8], base: u32, start: u32) -> Option<ReservedSkips> {
28 if start & 1 != 0 || base & 1 != 0 {
29 return None;
30 }
31 let words = [
34 0x6838, 0x211d, 0x0409, 0x4288, 0xd10b, 0x6839, 0x2007, 0x0380, 0x1809, 0x6039, 0x6831,
35 0x1809, 0x6031, 0x6829, 0x1a08, 0x6028, 0xe00d, 0x6838, 0x211f, 0x0409, 0x4288, 0xd108,
36 0x6838, 0x1900, 0x6038, 0x6830, 0x1900, 0x6030, 0x2300, 0x602b,
37 ];
38 for (index, expected) in words.into_iter().enumerate() {
39 let at = start.checked_add(u32::try_from(index).ok()?.checked_mul(2)?)?;
40 if word(bytes, base, at)? != expected {
41 return None;
42 }
43 }
44 let branch_at = start.checked_add(60)?;
45 let instruction = word(bytes, base, branch_at)?;
46 if instruction & 0xf800 != 0xe000 {
47 return None;
48 }
49 let displacement = (i32::from(instruction & 0x7ff) << 21) >> 20;
50 let finished = u32::try_from(i64::from(branch_at) + 4 + i64::from(displacement)).ok()?;
51 let continuation = start.checked_add(62)?;
52 if finished <= continuation {
53 return None;
54 }
55 word(bytes, base, finished)?;
56 word(bytes, base, continuation)?;
57 Some(ReservedSkips {
58 address: start,
59 first_start: 0x1d0000,
60 first_length: 0x1c000,
61 final_start: 0x1f0000,
62 required_r4: 0x10000,
63 continuation,
64 finished,
65 })
66}