-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfig.rs
More file actions
157 lines (143 loc) · 5.6 KB
/
Copy pathconfig.rs
File metadata and controls
157 lines (143 loc) · 5.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
use crate::Error;
const CONF_FILE_IDENTIFIER: &str = "uboot-nand-dump";
const CONF_VERSION: u32 = 1;
/// Specific config for NAND parameters and U-boot operation settings.
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct Config {
/// It must be `uboot-nand-dump`.
pub conf_file_ident: String,
/// It must be `1` for the current version.
pub conf_version: u32,
/// Defaults to 115,200 if not given.
pub baud_rate: Option<u32>,
/// Known NAND chip parameters needed here.
pub nand_conf: NandConfig,
/// Index of the target NAND selected using `nand device` command, defaults to `0`.
pub nand_index: Option<u32>,
/// A string that should be found in the response of the `nand device` command.
pub expected_nand_info: Option<String>,
/// Start offset of a target RAM space given to this utility.
/// The space must be enough for 1 NAND page with OOB.
pub page_buf_ram_offset: Option<u64>,
/// Enables an extra space in the target RAM region to be filled with 0xFF, used for
/// empty page checking. Increases the used RAM region size by 1 NAND page without OOB.
/// Defaults to `false`; `true` value is invalid if `page_buf_ram_offset` is `None`.
pub fast_empty_check: Option<bool>,
/// Uses `nand read` instead of `nand read.raw`. Defaults to `false`; `true` value
/// is invalid if `page_buf_ram_offset` is `None`, because `nand dump` does raw read.
pub enable_uboot_ecc: Option<bool>,
}
impl Config {
/// Returns an error if the config is significantly malformed.
pub fn check(&self) -> Result<(), Error> {
if self.conf_file_ident.as_str() != CONF_FILE_IDENTIFIER {
return Err(Error::InvalidConfig("not a config for this utility"));
}
if self.conf_version != CONF_VERSION {
return Err(Error::InvalidConfig("config format version mismatch"));
}
if self.page_buf_ram_offset.is_none() {
if self.fast_empty_check() {
return Err(Error::InvalidConfig(
"fast_empty_check without given page_buf_ram_offset",
));
}
if self.enable_uboot_ecc() {
return Err(Error::InvalidConfig(
"enable_uboot_ecc without given page_buf_ram_offset",
));
}
}
self.nand_conf.check()?;
if self.baud_rate() < 110 || self.baud_rate() > 2_000_000 {
return Err(Error::InvalidConfig("unusual baud rate"));
}
Ok(())
}
/// Defaults to 115,200 if it is not set.
pub fn baud_rate(&self) -> u32 {
self.baud_rate.unwrap_or(115_200)
}
/// Defaults to 0 if it is not set.
pub fn nand_index(&self) -> u32 {
self.nand_index.unwrap_or(0)
}
pub fn fast_empty_check(&self) -> bool {
self.page_buf_ram_offset.is_some() && self.fast_empty_check.unwrap_or(false)
}
pub fn enable_uboot_ecc(&self) -> bool {
self.page_buf_ram_offset.is_some() && self.enable_uboot_ecc.unwrap_or(false)
}
}
impl Default for Config {
/// Defaults to page size 2048, 64 pages each block, 128MiB flash size.
/// The default flash size is likely wrong for your target.
fn default() -> Self {
Self {
conf_file_ident: CONF_FILE_IDENTIFIER.to_string(),
conf_version: 1,
baud_rate: None,
nand_conf: NandConfig::default(),
nand_index: None,
expected_nand_info: None,
page_buf_ram_offset: None,
fast_empty_check: None,
enable_uboot_ecc: None,
}
}
}
/// Specifies critical parameters of the NAND flash.
///
/// These parameters are not parsed from U-Boot output because of U-Boot version issues.
#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct NandConfig {
pub page_size: usize,
pub page_oob_size: usize,
pub erase_size: usize,
pub flash_size: usize,
}
impl Default for NandConfig {
/// Defaults to page size 2048, 64 pages each block, 128MiB flash size.
/// The default flash size is likely wrong for your target.
fn default() -> Self {
Self {
page_size: 2048,
page_oob_size: 64,
erase_size: 64 * 2048,
flash_size: 128 * 1024 * 1024,
}
}
}
impl NandConfig {
/// Returns an error if the config is significantly malformed.
pub fn check(&self) -> Result<(), Error> {
if self.page_size < 512 {
return Err(Error::InvalidConfig("invalid page size"));
}
if self.page_oob_size < 16 {
return Err(Error::InvalidConfig("invalid page OOB size"));
}
if self.erase_size == 0 || !self.erase_size.is_multiple_of(self.page_size) {
return Err(Error::InvalidConfig("invalid erase size"));
}
if self.flash_size == 0 || !self.flash_size.is_multiple_of(self.erase_size) {
return Err(Error::InvalidConfig("invalid flash size"));
}
Ok(())
}
}
/// Specifies whether or not to dump the main/OOB data, or to dump both regions of the page.
#[derive(Clone, Copy, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
pub enum DumpMode {
MainOnly,
OobOnly,
Both,
}
impl DumpMode {
pub fn has_main(&self) -> bool {
self == &DumpMode::Both || self == &DumpMode::MainOnly
}
pub fn has_oob(&self) -> bool {
self == &DumpMode::Both || self == &DumpMode::OobOnly
}
}