From 4441930e32738b0996d3d107b80c36a552e6bd4e Mon Sep 17 00:00:00 2001 From: Matt Coffin Date: Mon, 5 Dec 2016 10:36:01 -0700 Subject: [PATCH 1/2] build: Fix build.rs formatting --- build.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/build.rs b/build.rs index 7269dc64..9838a83e 100644 --- a/build.rs +++ b/build.rs @@ -15,11 +15,11 @@ fn get_platform() -> Option { } fn file_exists(file: &Path) -> bool { - match fs::metadata(file) { - Ok(_) => true, - // Check for ENOENT (No such file or directory) - Err(e) => e.raw_os_error() != Some(2), - } + match fs::metadata(file) { + Ok(_) => true, + // Check for ENOENT (No such file or directory) + Err(e) => e.raw_os_error() != Some(2), + } } fn copy_linker_scripts, Q: AsRef>(target: P, out_path: Q) -> io::Result<()> { From c3e54e6e96ce500fbb4714029cdac715f60bd825 Mon Sep 17 00:00:00 2001 From: Matt Coffin Date: Mon, 5 Dec 2016 19:19:01 -0700 Subject: [PATCH 2/2] build: Generate layout.ld from templates --- Cargo.toml | 6 ++ build.rs | 126 +++++++++++++++++++++++++++++++++++-- src/hal/k20/layout.yml | 3 + src/hal/layout.ld.in | 18 ++++++ src/hal/lpc11xx/layout.ld | 15 ----- src/hal/lpc11xx/layout.yml | 11 ++++ src/hal/lpc17xx/iomem.ld | 2 + src/hal/lpc17xx/layout.ld | 19 ------ src/hal/lpc17xx/layout.yml | 11 ++++ src/hal/stm32f1/layout.ld | 16 ----- src/hal/stm32f1/layout.yml | 11 ++++ src/hal/stm32f4/layout.ld | 18 ------ src/hal/stm32f4/layout.yml | 15 +++++ src/hal/stm32f7/layout.ld | 22 ------- src/hal/stm32f7/layout.yml | 15 +++++ src/hal/stm32l1/layout.ld | 16 ----- src/hal/stm32l1/layout.yml | 11 ++++ src/hal/tiva_c/layout.ld | 16 ----- src/hal/tiva_c/layout.yml | 10 +++ 19 files changed, 235 insertions(+), 126 deletions(-) create mode 100644 src/hal/k20/layout.yml create mode 100644 src/hal/layout.ld.in delete mode 100644 src/hal/lpc11xx/layout.ld create mode 100644 src/hal/lpc11xx/layout.yml delete mode 100644 src/hal/lpc17xx/layout.ld create mode 100644 src/hal/lpc17xx/layout.yml delete mode 100644 src/hal/stm32f1/layout.ld create mode 100644 src/hal/stm32f1/layout.yml delete mode 100644 src/hal/stm32f4/layout.ld create mode 100644 src/hal/stm32f4/layout.yml delete mode 100644 src/hal/stm32f7/layout.ld create mode 100644 src/hal/stm32f7/layout.yml delete mode 100644 src/hal/stm32l1/layout.ld create mode 100644 src/hal/stm32l1/layout.yml delete mode 100644 src/hal/tiva_c/layout.ld create mode 100644 src/hal/tiva_c/layout.yml diff --git a/Cargo.toml b/Cargo.toml index 2716ae26..1422a3b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,3 +46,9 @@ path = "./macro_platformtree" [dev-dependencies.macro_zinc] path = "./macro_zinc" + +[build-dependencies] +rustache = "0.1" +serde = "= 0.8.8" +serde_derive = "= 0.8.8" +serde_yaml = "0.4.1" diff --git a/build.rs b/build.rs index 9838a83e..332a93cf 100644 --- a/build.rs +++ b/build.rs @@ -1,8 +1,15 @@ +#![feature(custom_attribute, proc_macro, rustc_macro)] + +extern crate rustache; +#[macro_use] +extern crate serde_derive; +extern crate serde_yaml; + use std::ascii::AsciiExt; use std::env; use std::fs; use std::io; -use std::path::Path; +use std::path::{Path, PathBuf}; fn get_platform() -> Option { let features = env::vars().filter(|&(ref key, _)| key.starts_with("CARGO_FEATURE_MCU_")); @@ -14,7 +21,8 @@ fn get_platform() -> Option { } } -fn file_exists(file: &Path) -> bool { +fn file_exists>(file: P) -> bool { + let file: &Path = file.as_ref(); match fs::metadata(file) { Ok(_) => true, // Check for ENOENT (No such file or directory) @@ -22,6 +30,90 @@ fn file_exists(file: &Path) -> bool { } } +#[derive(Debug)] +enum GenerateLayoutError { + Io(io::Error), + Yaml(serde_yaml::Error), + Rustache(rustache::RustacheError), +} + +fn target_dir>(target: P) -> PathBuf { + Path::new("src/hal").join(target) +} + +trait RustacheHash { + fn rustache_insert<'a>(&self, hb: rustache::HashBuilder<'a>) -> rustache::HashBuilder<'a>; +} + +#[derive(Serialize, Deserialize, Debug)] +struct McuLayout { + vectors: String, + memories: Vec, +} + +impl RustacheHash for McuLayout { + fn rustache_insert<'a>(&self, hb: rustache::HashBuilder<'a>) -> rustache::HashBuilder<'a> { + let memories = self.memories.iter().fold(rustache::VecBuilder::new(), |memories, memory| { + memories.push(memory.rustache_insert(rustache::HashBuilder::new())) + }); + hb + .insert("vectors", self.vectors.clone()) + .insert("memories", memories) + } +} + +#[derive(Serialize, Deserialize, Debug)] +struct McuMemory { + name: String, + mode: String, + origin: u64, + length: u64, +} + +impl RustacheHash for McuMemory { + fn rustache_insert<'a>(&self, hb: rustache::HashBuilder<'a>) -> rustache::HashBuilder<'a> { + hb + .insert("name", self.name.clone()) + .insert("mode", self.mode.clone()) + .insert("origin", self.origin as i32) + .insert("length", self.length as i32) + } +} + +fn generate_layout>(target: &str, out_path: P) -> Result<(), GenerateLayoutError> { + use rustache::Render; + use std::io::Read; + + let layout_file = target_dir(target).join("layout.yml"); + fs::File::open(layout_file) + .map_err(|e| GenerateLayoutError::Io(e)) + .and_then(|f| { + let res: serde_yaml::Result = serde_yaml::from_reader(f); + res.map_err(|e| GenerateLayoutError::Yaml(e)) + }) + .and_then(|layout| { + fs::File::open("src/hal/layout.ld.in") + .and_then(|mut f| { + let mut buf = String::from(""); + f.read_to_string(&mut buf) + .map(|_| (layout, buf)) + }) + .map_err(|e| GenerateLayoutError::Io(e)) + }) + .and_then(|(layout, template)| { + fs::OpenOptions::new().write(true).create_new(true).open(out_path) + .map_err(|e| GenerateLayoutError::Io(e)) + .map(|f| (layout, template, f)) + }) + .and_then(|(layout, template, mut f)| { + let layout = &layout; + let hb = rustache::HashBuilder::new(); + let hb = layout.rustache_insert(hb); + hb.render(&template, &mut f) + .map_err(|e| GenerateLayoutError::Rustache(e)) + }) +} + fn copy_linker_scripts, Q: AsRef>(target: P, out_path: Q) -> io::Result<()> { let path_prefix = if env::var("CARGO_MANIFEST_DIR").unwrap().find("/examples/").is_none() { Path::new(".") @@ -29,14 +121,25 @@ fn copy_linker_scripts, Q: AsRef>(target: P, out_path: Q) - Path::new("./../..") }; // Try copying the linker scripts - let target_dir = Path::new("src/hal").join(target); + let target_dir = target_dir(target); let out_dir: &Path = out_path.as_ref(); try!(fs::copy(path_prefix.join("src/hal/layout_common.ld"), out_dir.join("layout_common.ld"))); let iomem_ld = path_prefix.join(target_dir.join("iomem.ld")); if file_exists(iomem_ld.as_path()) { try!(fs::copy(iomem_ld, out_dir.join("iomem.ld"))); + } else { + try!(fs::OpenOptions::new().create(true).write(true).open(out_dir.join("iomem.ld"))); + } + // If the MCU has a layout.ld script, we want to override the generated one + // with new one. + let layout_ld = path_prefix.join(target_dir.join("layout.ld")); + if file_exists(layout_ld.as_path()) { + let layout_ld_out = out_dir.join("layout.ld"); + if file_exists(&layout_ld_out) { + try!(fs::remove_file(&layout_ld_out)) + } + try!(fs::copy(layout_ld, &layout_ld_out)); } - try!(fs::copy(path_prefix.join(target_dir.join("layout.ld")), out_dir.join("layout.ld"))); Ok(()) } @@ -48,9 +151,24 @@ fn main() { return; }, }; + // Get output directory for cargo for zinc crate let out_dir = env::var("OUT_DIR").unwrap(); + let layout_path = Path::new(&out_dir).join("layout.ld"); + if file_exists(&layout_path) { + match fs::remove_file(&layout_path) { + Ok(..) => {}, + Err(e) => panic!("Failed to clean layout.ld: {}", e), + } + } + + // Create the new layout.ld + match generate_layout(platform.as_str(), &layout_path) { + Ok(..) => {}, + Err(e) => panic!("Failed to create layout.ld: {:?}", e), + } + // Move linker scripts to cargo output dir match copy_linker_scripts(&platform, &out_dir) { Ok(_) => {}, diff --git a/src/hal/k20/layout.yml b/src/hal/k20/layout.yml new file mode 100644 index 00000000..b8161407 --- /dev/null +++ b/src/hal/k20/layout.yml @@ -0,0 +1,3 @@ +--- +vectors: rom +memories: [] diff --git a/src/hal/layout.ld.in b/src/hal/layout.ld.in new file mode 100644 index 00000000..eb4a1304 --- /dev/null +++ b/src/hal/layout.ld.in @@ -0,0 +1,18 @@ +INCLUDE iomem.ld + +_data_load = LOADADDR(.data); + +ENTRY(main) + +MEMORY +{ + {{#memories}} + {{name}}({{mode}}) : ORIGIN = {{origin}}, LENGTH = {{length}} + {{/memories}} +} + +__STACK_BASE = ORIGIN(ram) + LENGTH(ram); + +REGION_ALIAS("vectors", {{vectors}}); + +INCLUDE layout_common.ld diff --git a/src/hal/lpc11xx/layout.ld b/src/hal/lpc11xx/layout.ld deleted file mode 100644 index fbea5e05..00000000 --- a/src/hal/lpc11xx/layout.ld +++ /dev/null @@ -1,15 +0,0 @@ -__STACK_BASE = 0x10002000; - -_data_load = LOADADDR(.data); - -ENTRY(main) - -MEMORY -{ - rom(RX) : ORIGIN = 0x00000000, LENGTH = 32K - ram(WAIL) : ORIGIN = 0x10000000, LENGTH = 4K -} - -REGION_ALIAS("vectors", rom); - -INCLUDE layout_common.ld diff --git a/src/hal/lpc11xx/layout.yml b/src/hal/lpc11xx/layout.yml new file mode 100644 index 00000000..ef9b883d --- /dev/null +++ b/src/hal/lpc11xx/layout.yml @@ -0,0 +1,11 @@ +--- +vectors: rom +memories: + - name: rom + mode: RX + origin: 0x00000000 + length: 0x8000 + - name: ram + mode: WAIL + origin: 0x10000000 + length: 0x1000 diff --git a/src/hal/lpc17xx/iomem.ld b/src/hal/lpc17xx/iomem.ld index 90c3502c..dc4ae910 100644 --- a/src/hal/lpc17xx/iomem.ld +++ b/src/hal/lpc17xx/iomem.ld @@ -89,3 +89,5 @@ lpc17xx_iomem_PCLKSEL0 = 0x400FC1A8; lpc17xx_iomem_PCLKSEL1 = 0x400FC1AC; lpc17xx_iomem_SCS = 0x400FC1A0; + +isr_reserved_1 = 0 - (__STACK_BASE + main + 1 + isr_nmi + 1 + isr_hardfault + 1); diff --git a/src/hal/lpc17xx/layout.ld b/src/hal/lpc17xx/layout.ld deleted file mode 100644 index 9989791b..00000000 --- a/src/hal/lpc17xx/layout.ld +++ /dev/null @@ -1,19 +0,0 @@ -__STACK_BASE = 0x10002000; - -INCLUDE iomem.ld - -isr_reserved_1 = 0 - (__STACK_BASE + main + 1 + isr_nmi + 1 + isr_hardfault + 1); - -_data_load = LOADADDR(.data); - -ENTRY(main) - -MEMORY -{ - rom(RX) : ORIGIN = 0x00000000, LENGTH = 64K - ram(WAIL) : ORIGIN = 0x10000000, LENGTH = 0x2000 -} - -REGION_ALIAS("vectors", rom); - -INCLUDE layout_common.ld diff --git a/src/hal/lpc17xx/layout.yml b/src/hal/lpc17xx/layout.yml new file mode 100644 index 00000000..3b78180c --- /dev/null +++ b/src/hal/lpc17xx/layout.yml @@ -0,0 +1,11 @@ +--- +vectors: rom +memories: + - name: rom + mode: RX + origin: 0x00000000 + length: 0x10000 + - name: ram + mode: WAIL + origin: 0x10000000 + length: 0x2000 diff --git a/src/hal/stm32f1/layout.ld b/src/hal/stm32f1/layout.ld deleted file mode 100644 index 8ed6a1c7..00000000 --- a/src/hal/stm32f1/layout.ld +++ /dev/null @@ -1,16 +0,0 @@ -__STACK_BASE = 0x20004FFF; /* end of ram */ -_data_load = LOADADDR(.data); - -INCLUDE iomem.ld - -ENTRY(main) - -MEMORY -{ - rom(RX) : ORIGIN = 0x08000000, LENGTH = 64K - ram(WAIL) : ORIGIN = 0x20000000, LENGTH = 20K -} - -REGION_ALIAS("vectors", rom); - -INCLUDE layout_common.ld diff --git a/src/hal/stm32f1/layout.yml b/src/hal/stm32f1/layout.yml new file mode 100644 index 00000000..53e03ecc --- /dev/null +++ b/src/hal/stm32f1/layout.yml @@ -0,0 +1,11 @@ +--- +vectors: rom +memories: + - name: rom + mode: RX + origin: 0x08000000 + length: 0x10000 + - name: ram + mode: WAIL + origin: 0x20000000 + length: 0x4FFF diff --git a/src/hal/stm32f4/layout.ld b/src/hal/stm32f4/layout.ld deleted file mode 100644 index 83b81072..00000000 --- a/src/hal/stm32f4/layout.ld +++ /dev/null @@ -1,18 +0,0 @@ -__STACK_BASE = 0x2001FFFF; -_data_load = LOADADDR(.data); - -INCLUDE iomem.ld - -ENTRY(main) - -MEMORY -{ - rom(RX) : ORIGIN = 0x08000000, LENGTH = 1024K - ram_c(WAIL) : ORIGIN = 0x10000000, LENGTH = 64K - ram(WAIL) : ORIGIN = 0x20000000, LENGTH = 112K + 16K - /* ram(WAIL) : ORIGIN = 0x2001C000, LENGTH = 16K */ -} - -REGION_ALIAS("vectors", rom); - -INCLUDE layout_common.ld diff --git a/src/hal/stm32f4/layout.yml b/src/hal/stm32f4/layout.yml new file mode 100644 index 00000000..49b0e1cd --- /dev/null +++ b/src/hal/stm32f4/layout.yml @@ -0,0 +1,15 @@ +--- +vectors: rom +memories: + - name: rom + mode: RX + origin: 0x08000000 + length: 0x100000 + - name: ram_c + mode: WAIL + origin: 0x10000000 + length: 0x10000 + - name: ram + mode: WAIL + origin: 0x20000000 + length: 0x20000 diff --git a/src/hal/stm32f7/layout.ld b/src/hal/stm32f7/layout.ld deleted file mode 100644 index c4d89375..00000000 --- a/src/hal/stm32f7/layout.ld +++ /dev/null @@ -1,22 +0,0 @@ -__STACK_BASE = 0x2004FFFF; -_data_load = LOADADDR(.data); - -INCLUDE iomem.ld - -ENTRY(main) - -MEMORY -{ - rom(RX) : ORIGIN = 0x08000000, LENGTH = 1024K - ram_c(WAIL) : ORIGIN = 0x10000000, LENGTH = 64K - - /* DTCM: 0x20000000 for 64K - * SRAM1: 0x20010000 for 240K - * SRAM2: 0x2004C000 for 16K - */ - ram(WAIL) : ORIGIN = 0x20000000, LENGTH = 64K + 240K + 16K -} - -REGION_ALIAS("vectors", rom); - -INCLUDE layout_common.ld diff --git a/src/hal/stm32f7/layout.yml b/src/hal/stm32f7/layout.yml new file mode 100644 index 00000000..3aa555d2 --- /dev/null +++ b/src/hal/stm32f7/layout.yml @@ -0,0 +1,15 @@ +--- +vectors: rom +memories: + - name: rom + mode: RX + origin: 0x08000000 + length: 0x100000 + - name: ram_c + mode: WAIL + origin: 0x10000000 + length: 0x10000 + - name: ram + mode: WAIL + origin: 0x20000000 + length: 0x50000 diff --git a/src/hal/stm32l1/layout.ld b/src/hal/stm32l1/layout.ld deleted file mode 100644 index 5e055b07..00000000 --- a/src/hal/stm32l1/layout.ld +++ /dev/null @@ -1,16 +0,0 @@ -__STACK_BASE = 0x20008000; /* end of ram */ -_data_load = LOADADDR(.data); - -INCLUDE iomem.ld - -ENTRY(main) - -MEMORY -{ - rom(RX) : ORIGIN = 0x08000000, LENGTH = 6 * 64K - ram(WAIL) : ORIGIN = 0x20000000, LENGTH = 32K -} - -REGION_ALIAS("vectors", rom); - -INCLUDE layout_common.ld diff --git a/src/hal/stm32l1/layout.yml b/src/hal/stm32l1/layout.yml new file mode 100644 index 00000000..52dd9056 --- /dev/null +++ b/src/hal/stm32l1/layout.yml @@ -0,0 +1,11 @@ +--- +vectors: rom +memories: + - name: rom + mode: RX + origin: 0x08000000 + length: 0x60000 + - name: ram + mode: WAIL + origin: 0x20000000 + length: 0x8000 diff --git a/src/hal/tiva_c/layout.ld b/src/hal/tiva_c/layout.ld deleted file mode 100644 index 76426661..00000000 --- a/src/hal/tiva_c/layout.ld +++ /dev/null @@ -1,16 +0,0 @@ -_boot_checksum = 0; /* TODO(farcaller): extract this to lpc code only */ -_data_load = LOADADDR(.data); - -ENTRY(main) - -MEMORY -{ - rom(RX) : ORIGIN = 0x00000000, LENGTH = 0x40000 - ram(WAIL) : ORIGIN = 0x20000000, LENGTH = 0x8000 /* 32KB SRAM */ -} - -__STACK_BASE = ORIGIN(ram) + LENGTH(ram); - -REGION_ALIAS("vectors", rom); - -INCLUDE layout_common.ld diff --git a/src/hal/tiva_c/layout.yml b/src/hal/tiva_c/layout.yml new file mode 100644 index 00000000..45c36cfa --- /dev/null +++ b/src/hal/tiva_c/layout.yml @@ -0,0 +1,10 @@ +vectors: rom +memories: + - name: rom + mode: RX + origin: 0x00000000 + length: 0x40000 + - name: ram + mode: WAIL + origin: 0x20000000 + length: 0x8000