blob: c74f6647cde5445514a686c56cf6da583a7517d8 [file] [log] [blame]
David Brownde7729e2017-01-09 10:41:35 -07001//! Describe flash areas.
2
3use flash::{Flash, Sector};
4use std::marker::PhantomData;
5use std::ptr;
6
7/// Structure to build up the boot area table.
8#[derive(Debug)]
9pub struct AreaDesc {
10 areas: Vec<Vec<FlashArea>>,
11 whole: Vec<FlashArea>,
12 sectors: Vec<Sector>,
13}
14
15impl AreaDesc {
16 pub fn new(flash: &Flash) -> AreaDesc {
17 AreaDesc {
18 areas: vec![],
19 whole: vec![],
20 sectors: flash.sector_iter().collect(),
21 }
22 }
23
24 /// Add a slot to the image. The slot must align with erasable units in the flash device.
25 /// Panics if the description is not valid. There are also bootloader assumptions that the
26 /// slots are SLOT0, SLOT1, and SCRATCH in that order.
27 pub fn add_image(&mut self, base: usize, len: usize, id: FlashId) {
28 let nid = id as usize;
29 let orig_base = base;
30 let orig_len = len;
31 let mut base = base;
32 let mut len = len;
33
34 while nid > self.areas.len() {
35 self.areas.push(vec![]);
36 self.whole.push(Default::default());
37 }
38
39 if nid != self.areas.len() {
40 panic!("Flash areas not added in order");
41 }
42
43 let mut area = vec![];
44
45 for sector in &self.sectors {
46 if len == 0 {
47 break;
48 };
49 if base > sector.base + sector.size - 1 {
50 continue;
51 }
52 if sector.base != base {
53 panic!("Image does not start on a sector boundary");
54 }
55
56 area.push(FlashArea {
57 flash_id: id,
58 device_id: 42,
59 pad16: 0,
60 off: sector.base as u32,
61 size: sector.size as u32,
62 });
63
64 base += sector.size;
65 len -= sector.size;
66 }
67
68 if len != 0 {
69 panic!("Image goes past end of device");
70 }
71
72 self.areas.push(area);
73 self.whole.push(FlashArea {
74 flash_id: id,
75 device_id: 42,
76 pad16: 0,
77 off: orig_base as u32,
78 size: orig_len as u32,
79 });
80 }
81
David Brown90c19132017-01-23 10:21:28 -070082 // Add a simple slot to the image. This ignores the device layout, and just adds the area as a
83 // single unit. It assumes that the image lines up with image boundaries. This tests
84 // configurations where the partition table uses larger sectors than the underlying flash
85 // device.
86 pub fn add_simple_image(&mut self, base: usize, len: usize, id: FlashId) {
87 let area = vec![FlashArea {
88 flash_id: id,
89 device_id: 42,
90 pad16: 0,
91 off: base as u32,
92 size: len as u32,
93 }];
94
95 self.areas.push(area);
96 self.whole.push(FlashArea {
97 flash_id: id,
98 device_id: 42,
99 pad16: 0,
100 off: base as u32,
101 size: len as u32,
102 });
103 }
104
David Brownde7729e2017-01-09 10:41:35 -0700105 pub fn get_c(&self) -> CAreaDesc {
106 let mut areas: CAreaDesc = Default::default();
107
108 assert_eq!(self.areas.len(), self.whole.len());
109
110 for (i, area) in self.areas.iter().enumerate() {
111 if area.len() > 0 {
112 areas.slots[i].areas = &area[0];
113 areas.slots[i].whole = self.whole[i].clone();
114 areas.slots[i].num_areas = area.len() as u32;
115 areas.slots[i].id = area[0].flash_id;
116 }
117 }
118
119 areas.num_slots = self.areas.len() as u32;
120
121 areas
122 }
123}
124
125/// The area descriptor, C format.
126#[repr(C)]
127#[derive(Debug, Default)]
128pub struct CAreaDesc<'a> {
129 slots: [CArea<'a>; 16],
130 num_slots: u32,
131}
132
133#[repr(C)]
134#[derive(Debug)]
135pub struct CArea<'a> {
136 whole: FlashArea,
137 areas: *const FlashArea,
138 num_areas: u32,
139 id: FlashId,
140 phantom: PhantomData<&'a AreaDesc>,
141}
142
143impl<'a> Default for CArea<'a> {
144 fn default() -> CArea<'a> {
145 CArea {
146 areas: ptr::null(),
147 whole: Default::default(),
148 id: FlashId::BootLoader,
149 num_areas: 0,
150 phantom: PhantomData,
151 }
152 }
153}
154
155/// Flash area map.
156#[repr(u8)]
157#[derive(Copy, Clone, Debug, Eq, PartialEq)]
158#[allow(dead_code)]
159pub enum FlashId {
160 BootLoader = 0,
161 Image0 = 1,
162 Image1 = 2,
163 ImageScratch = 3,
164 Nffs = 4,
165 Core = 5,
166 RebootLog = 6
167}
168
169impl Default for FlashId {
170 fn default() -> FlashId {
171 FlashId::BootLoader
172 }
173}
174
175#[repr(C)]
176#[derive(Debug, Clone, Default)]
177pub struct FlashArea {
178 flash_id: FlashId,
179 device_id: u8,
180 pad16: u16,
181 off: u32,
182 size: u32,
183}
184