Allow multiple flash device in AreaDesc

AreaDesc was modified to not receive a flash device on its constructor,
and instead a new function `add_flash_sectors` was added that allows it
to receive a flash device and id.

The `add_image` function that populates the areas also now receives a
dev_id that is used internally as fa_device_id.

Signed-off-by: Fabio Utzig <utzig@apache.org>
diff --git a/sim/mcuboot-sys/src/area.rs b/sim/mcuboot-sys/src/area.rs
index 08896db..841bc78 100644
--- a/sim/mcuboot-sys/src/area.rs
+++ b/sim/mcuboot-sys/src/area.rs
@@ -2,28 +2,33 @@
 
 use simflash::{Flash, SimFlash, Sector};
 use std::ptr;
+use std::collections::HashMap;
 
 /// Structure to build up the boot area table.
 #[derive(Debug, Clone)]
 pub struct AreaDesc {
     areas: Vec<Vec<FlashArea>>,
     whole: Vec<FlashArea>,
-    sectors: Vec<Sector>,
+    sectors: HashMap<u8, Vec<Sector>>,
 }
 
 impl AreaDesc {
-    pub fn new(flash: &SimFlash) -> AreaDesc {
+    pub fn new() -> AreaDesc {
         AreaDesc {
             areas: vec![],
             whole: vec![],
-            sectors: flash.sector_iter().collect(),
+            sectors: HashMap::new(),
         }
     }
 
+    pub fn add_flash_sectors(&mut self, id: u8, flash: &SimFlash) {
+        self.sectors.insert(id, flash.sector_iter().collect());
+    }
+
     /// Add a slot to the image.  The slot must align with erasable units in the flash device.
     /// Panics if the description is not valid.  There are also bootloader assumptions that the
     /// slots are SLOT0, SLOT1, and SCRATCH in that order.
-    pub fn add_image(&mut self, base: usize, len: usize, id: FlashId) {
+    pub fn add_image(&mut self, base: usize, len: usize, id: FlashId, dev_id: u8) {
         let nid = id as usize;
         let orig_base = base;
         let orig_len = len;
@@ -41,7 +46,7 @@
 
         let mut area = vec![];
 
-        for sector in &self.sectors {
+        for sector in &self.sectors[&dev_id] {
             if len == 0 {
                 break;
             };
@@ -54,7 +59,7 @@
 
             area.push(FlashArea {
                 flash_id: id,
-                device_id: 0,
+                device_id: dev_id,
                 pad16: 0,
                 off: sector.base as u32,
                 size: sector.size as u32,
@@ -71,7 +76,7 @@
         self.areas.push(area);
         self.whole.push(FlashArea {
             flash_id: id,
-            device_id: 0,
+            device_id: dev_id,
             pad16: 0,
             off: orig_base as u32,
             size: orig_len as u32,
@@ -82,10 +87,10 @@
     // single unit.  It assumes that the image lines up with image boundaries.  This tests
     // configurations where the partition table uses larger sectors than the underlying flash
     // device.
-    pub fn add_simple_image(&mut self, base: usize, len: usize, id: FlashId) {
+    pub fn add_simple_image(&mut self, base: usize, len: usize, id: FlashId, dev_id: u8) {
         let area = vec![FlashArea {
             flash_id: id,
-            device_id: 0,
+            device_id: dev_id,
             pad16: 0,
             off: base as u32,
             size: len as u32,
@@ -94,7 +99,7 @@
         self.areas.push(area);
         self.whole.push(FlashArea {
             flash_id: id,
-            device_id: 0,
+            device_id: dev_id,
             pad16: 0,
             off: base as u32,
             size: len as u32,
@@ -105,6 +110,7 @@
     // not present.
     pub fn find(&self, id: FlashId) -> (usize, usize) {
         for area in &self.whole {
+            // FIXME: should we ensure id is not duplicated over multiple devices?
             if area.flash_id == id {
                 return (area.off as usize, area.size as usize);
             }
@@ -146,6 +152,7 @@
     whole: FlashArea,
     areas: *const FlashArea,
     num_areas: u32,
+    // FIXME: is this not already available on whole/areas?
     id: FlashId,
 }
 
diff --git a/sim/src/lib.rs b/sim/src/lib.rs
index 194fd7f..992dcee 100644
--- a/sim/src/lib.rs
+++ b/sim/src/lib.rs
@@ -327,20 +327,24 @@
                                       64 * 1024,
                                       128 * 1024, 128 * 1024, 128 * 1024],
                                       align as usize, erased_val);
-            let mut areadesc = AreaDesc::new(&flash);
-            areadesc.add_image(0x020000, 0x020000, FlashId::Image0);
-            areadesc.add_image(0x040000, 0x020000, FlashId::Image1);
-            areadesc.add_image(0x060000, 0x020000, FlashId::ImageScratch);
+            let flash_id = 0;
+            let mut areadesc = AreaDesc::new();
+            areadesc.add_flash_sectors(flash_id, &flash);
+            areadesc.add_image(0x020000, 0x020000, FlashId::Image0, flash_id);
+            areadesc.add_image(0x040000, 0x020000, FlashId::Image1, flash_id);
+            areadesc.add_image(0x060000, 0x020000, FlashId::ImageScratch, flash_id);
             (flash, areadesc)
         }
         DeviceName::K64f => {
             // NXP style flash.  Small sectors, one small sector for scratch.
             let flash = SimFlash::new(vec![4096; 128], align as usize, erased_val);
 
-            let mut areadesc = AreaDesc::new(&flash);
-            areadesc.add_image(0x020000, 0x020000, FlashId::Image0);
-            areadesc.add_image(0x040000, 0x020000, FlashId::Image1);
-            areadesc.add_image(0x060000, 0x001000, FlashId::ImageScratch);
+            let flash_id = 0;
+            let mut areadesc = AreaDesc::new();
+            areadesc.add_flash_sectors(flash_id, &flash);
+            areadesc.add_image(0x020000, 0x020000, FlashId::Image0, flash_id);
+            areadesc.add_image(0x040000, 0x020000, FlashId::Image1, flash_id);
+            areadesc.add_image(0x060000, 0x001000, FlashId::ImageScratch, flash_id);
             (flash, areadesc)
         }
         DeviceName::K64fBig => {
@@ -348,10 +352,12 @@
             // uses small sectors, but we tell the bootloader they are large.
             let flash = SimFlash::new(vec![4096; 128], align as usize, erased_val);
 
-            let mut areadesc = AreaDesc::new(&flash);
-            areadesc.add_simple_image(0x020000, 0x020000, FlashId::Image0);
-            areadesc.add_simple_image(0x040000, 0x020000, FlashId::Image1);
-            areadesc.add_simple_image(0x060000, 0x020000, FlashId::ImageScratch);
+            let dev_id = 0;
+            let mut areadesc = AreaDesc::new();
+            areadesc.add_flash_sectors(dev_id, &flash);
+            areadesc.add_simple_image(0x020000, 0x020000, FlashId::Image0, dev_id);
+            areadesc.add_simple_image(0x040000, 0x020000, FlashId::Image1, dev_id);
+            areadesc.add_simple_image(0x060000, 0x020000, FlashId::ImageScratch, dev_id);
             (flash, areadesc)
         }
         DeviceName::Nrf52840 => {
@@ -359,10 +365,12 @@
             // does not divide into the image size.
             let flash = SimFlash::new(vec![4096; 128], align as usize, erased_val);
 
-            let mut areadesc = AreaDesc::new(&flash);
-            areadesc.add_image(0x008000, 0x034000, FlashId::Image0);
-            areadesc.add_image(0x03c000, 0x034000, FlashId::Image1);
-            areadesc.add_image(0x070000, 0x00d000, FlashId::ImageScratch);
+            let dev_id = 0;
+            let mut areadesc = AreaDesc::new();
+            areadesc.add_flash_sectors(dev_id, &flash);
+            areadesc.add_image(0x008000, 0x034000, FlashId::Image0, dev_id);
+            areadesc.add_image(0x03c000, 0x034000, FlashId::Image1, dev_id);
+            areadesc.add_image(0x070000, 0x00d000, FlashId::ImageScratch, dev_id);
             (flash, areadesc)
         }
     }