Skip to main content

mediatek_optical/
layout.rs

1//! The fixed geometry of an MT19xx flash image.
2//!
3//! Every MT1959 and MT1939 image is a flat 2 MiB SPI image with load address
4//! equal to file offset. The ranges below hold across the OEM corpus of both
5//! generations (LG, HP and ASUS builds).
6
7/// A named byte range of the flash image.
8#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
9pub struct Range {
10    /// Short human-readable name.
11    pub name: &'static str,
12    /// First byte, as a file offset.
13    pub start: usize,
14    /// Length in bytes.
15    pub len: usize,
16}
17
18impl Range {
19    /// One past the last byte.
20    pub const fn end(&self) -> usize {
21        self.start + self.len
22    }
23
24    /// This range of `image`, or `None` if the image is too short.
25    pub fn of<'a>(&self, image: &'a [u8]) -> Option<&'a [u8]> {
26        image.get(self.start..self.end())
27    }
28}
29
30/// Size of a complete firmware image (2 MiB).
31pub const IMAGE_SIZE: usize = 0x20_0000;
32
33/// The boot page. Flash stores it in a form that never reads back: READ BUFFER
34/// returns the page at [`BOOT_MIRROR`] here instead.
35pub const BOOT_PAGE: Range = Range {
36    name: "boot page",
37    start: 0,
38    len: 0x400,
39};
40
41/// The page a drive read returns in place of [`BOOT_PAGE`].
42pub const BOOT_MIRROR: Range = Range {
43    name: "boot mirror",
44    start: 0x1_0000,
45    len: 0x400,
46};
47
48/// The boot area: the 4 KiB flash sector holding [`BOOT_PAGE`]. The drive
49/// serves it remapped, so read-back verification skips it.
50pub const BOOT_AREA: Range = Range {
51    name: "boot area",
52    start: 0,
53    len: 0x1000,
54};
55
56/// The AES-CMAC integrity table (16 entries of 28 bytes).
57pub const CMAC_TABLE: Range = Range {
58    name: "integrity table",
59    start: 0x1_0400,
60    len: 16 * 28,
61};
62
63/// The ASCII boot banner, e.g. `MT1959 Boot BU5`.
64pub const BANNER: Range = Range {
65    name: "boot banner",
66    start: 0x3000,
67    len: 0x20,
68};
69
70/// The identity descriptor: vendor, model, revision, SKU and the
71/// `MTEKMT19xx` tag at `+0x34`, mirroring the drive's INQUIRY.
72pub const DESCRIPTOR: Range = Range {
73    name: "identity descriptor",
74    start: 0x1E_C000,
75    len: 0x100,
76};
77
78/// The UHD host revocation list. Erased on builds without UHD support.
79pub const UHD_REVOCATION: Range = Range {
80    name: "UHD revocation list",
81    start: 0x1D_8000,
82    len: 0x8000,
83};
84
85/// The BD host revocation list.
86pub const BD_REVOCATION: Range = Range {
87    name: "BD revocation list",
88    start: 0x1E_0000,
89    len: 0x8000,
90};
91
92/// The drive's settings page.
93pub const SETTINGS: Range = Range {
94    name: "settings",
95    start: 0x1E_8000,
96    len: 0x4000,
97};
98
99/// The per-unit calibration block.
100pub const CALIBRATION: Range = Range {
101    name: "calibration",
102    start: 0x1F_0000,
103    len: 0x1_0000,
104};
105
106/// Regions the drive rewrites at runtime and an update never overwrites. A
107/// drive read differs from the flashed image here and at [`BOOT_PAGE`] only.
108pub const DRIVE_WRITTEN: [Range; 4] = [UHD_REVOCATION, BD_REVOCATION, SETTINGS, CALIBRATION];
109
110/// `true` when every byte of `bytes` is erased flash (`0xFF`).
111pub fn is_erased(bytes: &[u8]) -> bool {
112    bytes.iter().all(|&b| b == 0xFF)
113}
114
115#[cfg(test)]
116#[path = "layout_tests.rs"]
117mod tests;