From 832ddfc205bc6df59ac5bcaffcb2ed665e1e9497 Mon Sep 17 00:00:00 2001 From: pca006132 Date: Tue, 1 Sep 2020 09:37:45 +0800 Subject: [PATCH] libconfig refactoring --- src/Cargo.toml | 18 +- src/libconfig/Cargo.toml | 15 ++ .../src/config.rs => libconfig/src/lib.rs} | 21 ++- .../src/net_settings.rs | 38 ++-- src/{runtime => libconfig}/src/sd_reader.rs | 0 src/runtime/Cargo.toml | 4 +- src/runtime/src/comms.rs | 5 +- src/runtime/src/load_pl.rs | 171 ------------------ src/runtime/src/main.rs | 13 +- 9 files changed, 73 insertions(+), 212 deletions(-) create mode 100644 src/libconfig/Cargo.toml rename src/{runtime/src/config.rs => libconfig/src/lib.rs} (88%) rename src/{runtime => libconfig}/src/net_settings.rs (58%) rename src/{runtime => libconfig}/src/sd_reader.rs (100%) delete mode 100644 src/runtime/src/load_pl.rs diff --git a/src/Cargo.toml b/src/Cargo.toml index d3378b1..e68c9bd 100644 --- a/src/Cargo.toml +++ b/src/Cargo.toml @@ -2,6 +2,7 @@ members = [ "libc", "libdyld", + "libconfig", "libcoreio", "libdwarf", "libunwind", @@ -9,6 +10,16 @@ members = [ "szl" ] +# Note: we are using dev profile for szl to override the opt-level only +[profile.dev] +panic = "abort" +debug = true +codegen-units = 1 +opt-level = 'z' +lto = true +debug-assertions = false +overflow-checks = false + [profile.release] panic = "abort" debug = true @@ -16,13 +27,6 @@ codegen-units = 1 opt-level = 's' lto = true -[profile.release.package.smoltcp] -opt-level = 2 -[profile.release.package.libasync] -opt-level = 2 -[profile.release.package.libboard_zynq] -opt-level = 2 - [patch.crates-io] core_io = { path = "./libcoreio" } compiler_builtins = { git = "https://git.m-labs.hk/M-Labs/compiler-builtins-zynq.git"} diff --git a/src/libconfig/Cargo.toml b/src/libconfig/Cargo.toml new file mode 100644 index 0000000..993cdd6 --- /dev/null +++ b/src/libconfig/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "libconfig" +version = "0.1.0" +authors = ["M-Labs"] +edition = "2018" + +[dependencies] +libboard_zynq = { git = "https://git.m-labs.hk/M-Labs/zynq-rs.git" } +core_io = { version = "0.1", features = ["collections"] } +fatfs = { version = "0.3", features = ["core_io"], default-features = false } +log = "0.4" + +[features] +ipv6 = [] + diff --git a/src/runtime/src/config.rs b/src/libconfig/src/lib.rs similarity index 88% rename from src/runtime/src/config.rs rename to src/libconfig/src/lib.rs index b8e3672..4e5ff30 100644 --- a/src/runtime/src/config.rs +++ b/src/libconfig/src/lib.rs @@ -1,10 +1,15 @@ -use crate::sd_reader; -use core::fmt; -use alloc::{string::FromUtf8Error, string::String, vec::Vec}; -use core_io::{self as io, BufRead, BufReader, Read}; +#![no_std] +extern crate alloc; +use core::fmt; +use alloc::{string::FromUtf8Error, string::String, vec::Vec, rc::Rc}; +use core_io::{self as io, BufRead, BufReader, Read}; use libboard_zynq::sdio; +pub mod sd_reader; +pub mod net_settings; +pub mod bootgen; + #[derive(Debug)] pub enum Error<'a> { SdError(sdio::sd_card::CardInitializationError), @@ -63,7 +68,7 @@ fn parse_config<'a>( } pub struct Config { - fs: Option>, + fs: Option>>, } impl Config { @@ -76,7 +81,11 @@ impl Config { let reader = sd_reader::SdReader::new(sd); let fs = reader.mount_fatfs(sd_reader::PartitionEntry::Entry1)?; - Ok(Config { fs: Some(fs) }) + Ok(Config { fs: Some(Rc::new(fs)) }) + } + + pub fn from_fs(fs: Option>>) -> Self { + Config { fs } } pub fn new_dummy() -> Self { diff --git a/src/runtime/src/net_settings.rs b/src/libconfig/src/net_settings.rs similarity index 58% rename from src/runtime/src/net_settings.rs rename to src/libconfig/src/net_settings.rs index 9bef1ea..76ddbb2 100644 --- a/src/runtime/src/net_settings.rs +++ b/src/libconfig/src/net_settings.rs @@ -2,31 +2,37 @@ use core::fmt; use libboard_zynq::smoltcp::wire::{EthernetAddress, IpAddress}; -use crate::config; +use super::Config; pub struct NetAddresses { pub hardware_addr: EthernetAddress, pub ipv4_addr: IpAddress, + #[cfg(feature = "ipv6")] pub ipv6_ll_addr: IpAddress, + #[cfg(feature = "ipv6")] pub ipv6_addr: Option } impl fmt::Display for NetAddresses { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "MAC={} IPv4={} IPv6-LL={} IPv6=", - self.hardware_addr, self.ipv4_addr, self.ipv6_ll_addr)?; - match self.ipv6_addr { - Some(addr) => write!(f, "{}", addr)?, - None => write!(f, "no configured address")? + write!(f, "MAC={} IPv4={} ", + self.hardware_addr, self.ipv4_addr)?; + + #[cfg(feature = "ipv6")] + { + write!(f, "IPv6-LL={}", self.ipv6_ll_addr)?; + match self.ipv6_addr { + Some(addr) => write!(f, " {}", addr)?, + None => write!(f, " IPv6: no configured address")? + } } Ok(()) } } -pub fn get_adresses(cfg: &config::Config) -> NetAddresses { +pub fn get_adresses(cfg: &Config) -> NetAddresses { let mut hardware_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x52]); let mut ipv4_addr = IpAddress::v4(192, 168, 1, 52); - let mut ipv6_addr = None; if let Ok(Ok(addr)) = cfg.read_str("mac").map(|s| s.parse()) { hardware_addr = addr; @@ -34,10 +40,10 @@ pub fn get_adresses(cfg: &config::Config) -> NetAddresses { if let Ok(Ok(addr)) = cfg.read_str("ip").map(|s| s.parse()) { ipv4_addr = addr; } - if let Ok(Ok(addr)) = cfg.read_str("ip6").map(|s| s.parse()) { - ipv6_addr = Some(addr); - } + #[cfg(feature = "ipv6")] + let ipv6_addr = cfg.read_str("ipv6").ok().and_then(|s| s.parse().ok()); + #[cfg(feature = "ipv6")] let ipv6_ll_addr = IpAddress::v6( 0xfe80, 0x0000, 0x0000, 0x0000, (((hardware_addr.0[0] ^ 0x02) as u16) << 8) | (hardware_addr.0[1] as u16), @@ -46,9 +52,11 @@ pub fn get_adresses(cfg: &config::Config) -> NetAddresses { ((hardware_addr.0[4] as u16) << 8) | (hardware_addr.0[5] as u16)); NetAddresses { - hardware_addr: hardware_addr, - ipv4_addr: ipv4_addr, - ipv6_ll_addr: ipv6_ll_addr, - ipv6_addr: ipv6_addr + hardware_addr, + ipv4_addr, + #[cfg(feature = "ipv6")] + ipv6_ll_addr, + #[cfg(feature = "ipv6")] + ipv6_addr } } diff --git a/src/runtime/src/sd_reader.rs b/src/libconfig/src/sd_reader.rs similarity index 100% rename from src/runtime/src/sd_reader.rs rename to src/libconfig/src/sd_reader.rs diff --git a/src/runtime/Cargo.toml b/src/runtime/Cargo.toml index 0137b05..88e4250 100644 --- a/src/runtime/Cargo.toml +++ b/src/runtime/Cargo.toml @@ -21,12 +21,11 @@ byteorder = { version = "1.3", default-features = false } void = { version = "1", default-features = false } futures = { version = "0.3", default-features = false, features = ["async-await"] } async-recursion = "0.3" -fatfs = { version = "0.3", features = ["core_io"], default-features = false } log_buffer = { version = "1.2" } libm = { version = "0.2", features = ["unstable"] } vcell = "0.1" -libboard_zynq = { git = "https://git.m-labs.hk/M-Labs/zynq-rs.git" } +libboard_zynq = { git = "https://git.m-labs.hk/M-Labs/zynq-rs.git", features = ["ipv6"]} libsupport_zynq = { default-features = false, features = ["alloc_core"], git = "https://git.m-labs.hk/M-Labs/zynq-rs.git" } libcortex_a9 = { git = "https://git.m-labs.hk/M-Labs/zynq-rs.git" } libasync = { git = "https://git.m-labs.hk/M-Labs/zynq-rs.git" } @@ -36,3 +35,4 @@ dyld = { path = "../libdyld" } dwarf = { path = "../libdwarf" } unwind = { path = "../libunwind" } libc = { path = "../libc" } +libconfig = { path = "../libconfig", features = ["ipv6"]} diff --git a/src/runtime/src/comms.rs b/src/runtime/src/comms.rs index b8a71fc..5e42314 100644 --- a/src/runtime/src/comms.rs +++ b/src/runtime/src/comms.rs @@ -20,9 +20,8 @@ use libboard_zynq::{ use libcortex_a9::{semaphore::Semaphore, mutex::Mutex}; use futures::{select_biased, future::FutureExt}; use libasync::{smoltcp::{Sockets, TcpStream}, task}; +use libconfig::{Config, net_settings}; -use crate::config; -use crate::net_settings; use crate::proto_async::*; use crate::kernel; use crate::rpc; @@ -315,7 +314,7 @@ async fn handle_connection(stream: &TcpStream, control: Rc for PlLoadingError { - fn from(error: Error) -> Self { - PlLoadingError::IoError(error) - } -} - -impl From for PlLoadingError { - fn from(error: devc::DevcError) -> Self { - PlLoadingError::DevcError(error) - } -} - -impl core::fmt::Display for PlLoadingError { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - use PlLoadingError::*; - match self { - BootImageNotFound => write!( - f, - "Boot image not found, make sure `boot.bin` exists and your SD card is plugged in." - ), - InvalidBootImageHeader => write!( - f, - "Invalid boot image header. Check if the file is correct." - ), - MissingBitstreamPartition => write!( - f, - "Bitstream partition not found. Check your compile configuration." - ), - EncryptedBitstream => write!(f, "Encrypted bitstream is not supported."), - IoError(e) => write!(f, "Error while reading: {}", e), - DevcError(e) => write!(f, "PCAP interface error: {}", e), - } - } -} - -#[repr(C)] -struct PartitionHeader { - pub encrypted_length: u32, - pub unencrypted_length: u32, - pub word_length: u32, - pub dest_load_addr: u32, - pub dest_exec_addr: u32, - pub data_offset: u32, - pub attribute_bits: u32, - pub section_count: u32, - pub checksum_offset: u32, - pub header_offset: u32, - pub cert_offset: u32, - pub reserved: [u32; 4], - pub checksum: u32, -} - -/// Read a u32 word from the reader. -fn read_u32(reader: &mut Reader) -> Result { - let mut buffer: [u8; 4] = [0; 4]; - reader.read_exact(&mut buffer)?; - let mut result: u32 = 0; - for i in 0..4 { - result |= (buffer[i] as u32) << (i * 8); - } - Ok(result) -} - -/// Load PL partition header. -fn load_pl_header( - file: &mut File, -) -> Result, PlLoadingError> { - let mut buffer: [u8; 0x40] = [0; 0x40]; - file.read_exact(&mut buffer)?; - let header = unsafe { core::mem::transmute::<_, PartitionHeader>(buffer) }; - if header.attribute_bits & (2 << 4) != 0 { - Ok(Some(header)) - } else { - Ok(None) - } -} - -/// Locate the PL bitstream from the image, and return the size (in bytes) of the bitstream if successful. -/// This function would seek the file to the location of the bitstream. -fn locate_bitstream(file: &mut File) -> Result { - const BOOT_HEADER_SIGN: u32 = 0x584C4E58; - // read boot header signature - file.seek(SeekFrom::Start(0x24))?; - if read_u32(file)? != BOOT_HEADER_SIGN { - return Err(PlLoadingError::InvalidBootImageHeader); - } - // read partition header offset - file.seek(SeekFrom::Start(0x9C))?; - let ptr = read_u32(file)?; - debug!("Partition header pointer = {:0X}", ptr); - file.seek(SeekFrom::Start(ptr as u64))?; - - let mut header_opt = None; - // at most 3 partition headers - for _ in 0..3 { - let result = load_pl_header(file)?; - if let Some(h) = result { - header_opt = Some(h); - break; - } - } - let header = match header_opt { - None => return Err(PlLoadingError::MissingBitstreamPartition), - Some(h) => h, - }; - - let encrypted_length = header.encrypted_length; - let unencrypted_length = header.unencrypted_length; - debug!("Unencrypted length = {:0X}", unencrypted_length); - if encrypted_length != unencrypted_length { - return Err(PlLoadingError::EncryptedBitstream); - } - - let start_addr = header.data_offset; - debug!("Partition start address: {:0X}", start_addr); - file.seek(SeekFrom::Start(start_addr as u64 * 4))?; - - Ok(unencrypted_length as usize * 4) -} - -/// Load bitstream from bootgen file. -/// This function parses the file, locate the bitstream and load it through the PCAP driver. -/// It requires a large buffer, please enable the DDR RAM before using it. -pub fn load_bitstream( - file: &mut File, -) -> Result<(), PlLoadingError> { - let size = locate_bitstream(file)?; - let mut buffer: alloc::vec::Vec = alloc::vec::Vec::with_capacity(size); - unsafe { - buffer.set_len(buffer.capacity()); - } - file.read_exact(&mut buffer)?; - - let mut devcfg = devc::DevC::new(); - devcfg.enable(); - devcfg.program(&buffer)?; - Ok(()) -} - -pub fn load_bitstream_from_sd() -> Result<(), PlLoadingError> { - let sdio0 = sdio::Sdio::sdio0(true); - if sdio0.is_card_inserted() { - info!("Card inserted. Mounting file system."); - let sd = sdio::sd_card::SdCard::from_sdio(sdio0).unwrap(); - let reader = sd_reader::SdReader::new(sd); - - let fs = reader.mount_fatfs(sd_reader::PartitionEntry::Entry1)?; - let root_dir = fs.root_dir(); - let mut file = root_dir.open_file("/BOOT.BIN").map_err(|_| PlLoadingError::BootImageNotFound)?; - info!("Found boot image!"); - load_bitstream(&mut file) - } else { - info!("SD card not inserted. Bitstream cannot be loaded."); - Err(PlLoadingError::BootImageNotFound) - } -} diff --git a/src/runtime/src/main.rs b/src/runtime/src/main.rs index e974d06..dd91c0b 100644 --- a/src/runtime/src/main.rs +++ b/src/runtime/src/main.rs @@ -21,10 +21,8 @@ use libregister::RegisterW; use nb; use void::Void; use embedded_hal::blocking::delay::DelayMs; +use libconfig::{Config, load_pl}; -mod sd_reader; -mod config; -mod net_settings; mod proto_core_io; mod proto_async; mod comms; @@ -39,7 +37,6 @@ mod rtio; mod rtio; mod kernel; mod moninj; -mod load_pl; mod eh_artiq; mod panic; mod logger; @@ -99,7 +96,7 @@ fn identifier_read(buf: &mut [u8]) -> &str { } } -fn init_rtio(timer: &mut GlobalTimer, cfg: &config::Config) { +fn init_rtio(timer: &mut GlobalTimer, cfg: &Config) { let clock_sel = if let Ok(rtioclk) = cfg.read_str("rtioclk") { match rtioclk.as_ref() { @@ -185,7 +182,7 @@ pub fn main_core0() { let buffer_logger = unsafe { logger::BufferLogger::new(&mut LOG_BUFFER[..]) }; - buffer_logger.set_uart_log_level(log::LevelFilter::Debug); + buffer_logger.set_uart_log_level(log::LevelFilter::Info); buffer_logger.register(); log::set_max_level(log::LevelFilter::Debug); @@ -197,11 +194,11 @@ pub fn main_core0() { init_gateware(); info!("detected gateware: {}", identifier_read(&mut [0; 64])); - let cfg = match config::Config::new() { + let cfg = match Config::new() { Ok(cfg) => cfg, Err(err) => { warn!("config initialization failed: {}", err); - config::Config::new_dummy() + Config::new_dummy() } };