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
use crate::elf::{FirmwareImage, RomSegment};
use crate::Error;
use bytemuck::{Pod, Zeroable};
pub use esp32::ESP32;
pub use esp8266::ESP8266;
mod esp32;
mod esp8266;
const ESP_MAGIC: u8 = 0xe9;
pub trait ChipType {
const DATE_REG1_VALUE: u32;
const DATE_REG2_VALUE: u32;
const SPI_REGISTERS: SPIRegisters;
fn get_flash_segments<'a>(
image: &'a FirmwareImage,
) -> Box<dyn Iterator<Item = Result<RomSegment<'a>, Error>> + 'a>;
fn addr_is_flash(addr: u32) -> bool;
}
pub struct SPIRegisters {
base: u32,
usr_offset: u32,
usr1_offset: u32,
usr2_offset: u32,
w0_offset: u32,
mosi_length_offset: Option<u32>,
miso_length_offset: Option<u32>,
}
impl SPIRegisters {
pub fn cmd(&self) -> u32 {
self.base
}
pub fn usr(&self) -> u32 {
self.base + self.usr_offset
}
pub fn usr1(&self) -> u32 {
self.base + self.usr1_offset
}
pub fn usr2(&self) -> u32 {
self.base + self.usr2_offset
}
pub fn w0(&self) -> u32 {
self.base + self.w0_offset
}
pub fn mosi_length(&self) -> Option<u32> {
self.mosi_length_offset.map(|offset| self.base + offset)
}
pub fn miso_length(&self) -> Option<u32> {
self.miso_length_offset.map(|offset| self.base + offset)
}
}
#[derive(Debug, Copy, Clone)]
pub enum Chip {
Esp8266,
Esp32,
}
impl Chip {
pub fn from_regs(value1: u32, value2: u32) -> Option<Self> {
match (value1, value2) {
(ESP8266::DATE_REG1_VALUE, _) => Some(Chip::Esp8266),
(ESP32::DATE_REG1_VALUE, _) => Some(Chip::Esp32),
_ => None,
}
}
pub fn get_flash_segments<'a>(
&self,
image: &'a FirmwareImage,
) -> Box<dyn Iterator<Item = Result<RomSegment<'a>, Error>> + 'a> {
match self {
Chip::Esp8266 => ESP8266::get_flash_segments(image),
Chip::Esp32 => ESP32::get_flash_segments(image),
}
}
pub fn addr_is_flash(&self, addr: u32) -> bool {
match self {
Chip::Esp8266 => ESP8266::addr_is_flash(addr),
Chip::Esp32 => ESP32::addr_is_flash(addr),
}
}
pub fn spi_registers(&self) -> SPIRegisters {
match self {
Chip::Esp8266 => ESP8266::SPI_REGISTERS,
Chip::Esp32 => ESP32::SPI_REGISTERS,
}
}
}
#[derive(Copy, Clone, Zeroable, Pod, Debug)]
#[repr(C)]
struct ESPCommonHeader {
magic: u8,
segment_count: u8,
flash_mode: u8,
flash_config: u8,
entry: u32,
}
#[derive(Copy, Clone, Zeroable, Pod, Debug)]
#[repr(C)]
struct SegmentHeader {
addr: u32,
length: u32,
}