diff --git a/flake.nix b/flake.nix index ac8bb7a..fcff558 100644 --- a/flake.nix +++ b/flake.nix @@ -253,6 +253,23 @@ ''; }; + fmt-check = pkgs.stdenv.mkDerivation { + name = "fmt-check"; + + nativeBuildInputs = [ + rustPlatform.rust.cargo + ]; + + phases = [ "buildPhase" ]; + + buildPhase = + '' + cd ${self}/src + cargo fmt -- --check + touch $out + ''; + }; + # for hitl-tests zc706-nist_qc2 = (build { target = "zc706"; variant = "nist_qc2"; }); zc706-hitl-tests = pkgs.stdenv.mkDerivation { @@ -341,7 +358,7 @@ (build { target = "kasli_soc"; variant = "master"; json = ./kasli-soc-master.json; }) // (build { target = "kasli_soc"; variant = "satellite"; json = ./kasli-soc-satellite.json; }); - hydraJobs = packages.x86_64-linux // { inherit zc706-hitl-tests; inherit gateware-sim; }; + hydraJobs = packages.x86_64-linux // { inherit zc706-hitl-tests; inherit gateware-sim; inherit fmt-check; }; devShell.x86_64-linux = pkgs.mkShell { name = "artiq-zynq-dev-shell"; diff --git a/src/libboard_artiq/src/drtio_routing.rs b/src/libboard_artiq/src/drtio_routing.rs index e4d6b4f..9057943 100644 --- a/src/libboard_artiq/src/drtio_routing.rs +++ b/src/libboard_artiq/src/drtio_routing.rs @@ -1,9 +1,10 @@ -use libconfig::Config; -#[cfg(has_drtio_routing)] -use crate::pl::csr; use core::fmt; -use log::{warn, info}; +use libconfig::Config; +use log::{info, warn}; + +#[cfg(has_drtio_routing)] +use crate::pl::csr; #[cfg(has_drtio_routing)] pub const DEST_COUNT: usize = 256; @@ -18,7 +19,7 @@ impl RoutingTable { // default routing table is for star topology with no repeaters pub fn default_master(default_n_links: usize) -> RoutingTable { let mut ret = RoutingTable([[INVALID_HOP; MAX_HOPS]; DEST_COUNT]); - let n_entries = default_n_links + 1; // include local RTIO + let n_entries = default_n_links + 1; // include local RTIO for i in 0..n_entries { ret.0[i][0] = i as u8; } @@ -58,10 +59,10 @@ impl fmt::Display for RoutingTable { pub fn config_routing_table(default_n_links: usize, cfg: &Config) -> RoutingTable { let mut ret = RoutingTable::default_master(default_n_links); if let Ok(data) = cfg.read("routing_table") { - if data.len() == DEST_COUNT*MAX_HOPS { + if data.len() == DEST_COUNT * MAX_HOPS { for i in 0..DEST_COUNT { for j in 0..MAX_HOPS { - ret.0[i][j] = data[i*MAX_HOPS+j]; + ret.0[i][j] = data[i * MAX_HOPS + j]; } } } else { diff --git a/src/libboard_artiq/src/drtioaux.rs b/src/libboard_artiq/src/drtioaux.rs index f9c442c..6b8077a 100644 --- a/src/libboard_artiq/src/drtioaux.rs +++ b/src/libboard_artiq/src/drtioaux.rs @@ -1,14 +1,12 @@ +use core_io::{Error as IoError, ErrorKind as IoErrorKind}; use crc; - -use core_io::{ErrorKind as IoErrorKind, Error as IoError}; -use io::{proto::ProtoRead, proto::ProtoWrite, Cursor}; -use libboard_zynq::{timer::GlobalTimer, time::Milliseconds}; +use io::{proto::{ProtoRead, ProtoWrite}, + Cursor}; +use libboard_zynq::{time::Milliseconds, timer::GlobalTimer}; use libcortex_a9::asm::dmb; -use crate::mem::mem::DRTIOAUX_MEM; -use crate::pl::csr::DRTIOAUX; -use crate::drtioaux_proto::Error as ProtocolError; pub use crate::drtioaux_proto::Packet; +use crate::{drtioaux_proto::Error as ProtocolError, mem::mem::DRTIOAUX_MEM, pl::csr::DRTIOAUX}; #[derive(Debug)] pub enum Error { @@ -21,7 +19,7 @@ pub enum Error { RoutingError, - Protocol(ProtocolError) + Protocol(ProtocolError), } impl From for Error { @@ -63,7 +61,7 @@ pub fn copy_work_buffer(src: *mut u32, dst: *mut u32, len: isize) { // and AXI burst reads/writes are not implemented yet in gateware // thus the need for a work buffer for transmitting and copying it over unsafe { - for i in 0..(len/4) { + for i in 0..(len / 4) { *dst.offset(i) = *src.offset(i); //data memory barrier to prevent bursts dmb(); @@ -72,8 +70,7 @@ pub fn copy_work_buffer(src: *mut u32, dst: *mut u32, len: isize) { } fn receive(linkno: u8, f: F) -> Result, Error> - where F: FnOnce(&[u8]) -> Result -{ +where F: FnOnce(&[u8]) -> Result { let linkidx = linkno as usize; unsafe { if (DRTIOAUX[linkidx].aux_rx_present_read)() == 1 { @@ -93,12 +90,12 @@ fn receive(linkno: u8, f: F) -> Result, Error> pub fn recv(linkno: u8) -> Result, Error> { if has_rx_error(linkno) { - return Err(Error::GatewareError) + return Err(Error::GatewareError); } receive(linkno, |buffer| { if buffer.len() < 8 { - return Err(IoError::new(IoErrorKind::UnexpectedEof, "Unexpected end").into()) + return Err(IoError::new(IoErrorKind::UnexpectedEof, "Unexpected end").into()); } let mut reader = Cursor::new(buffer); @@ -107,7 +104,7 @@ pub fn recv(linkno: u8) -> Result, Error> { let checksum = crc::crc32::checksum_ieee(&reader.get_ref()[0..checksum_at]); reader.set_position(checksum_at); if reader.read_u32()? != checksum { - return Err(Error::CorruptedPacket) + return Err(Error::CorruptedPacket); } reader.set_position(0); @@ -115,9 +112,7 @@ pub fn recv(linkno: u8) -> Result, Error> { }) } -pub fn recv_timeout(linkno: u8, timeout_ms: Option, - timer: GlobalTimer) -> Result -{ +pub fn recv_timeout(linkno: u8, timeout_ms: Option, timer: GlobalTimer) -> Result { let timeout_ms = Milliseconds(timeout_ms.unwrap_or(10)); let limit = timer.get_time() + timeout_ms; while timer.get_time() < limit { @@ -130,15 +125,14 @@ pub fn recv_timeout(linkno: u8, timeout_ms: Option, } fn transmit(linkno: u8, f: F) -> Result<(), Error> - where F: FnOnce(&mut [u8]) -> Result -{ +where F: FnOnce(&mut [u8]) -> Result { let linkno = linkno as usize; unsafe { while (DRTIOAUX[linkno].aux_tx_read)() != 0 {} let ptr = DRTIOAUX_MEM[linkno].base as *mut u32; let len = DRTIOAUX_MEM[linkno].size / 2; // work buffer, works with unaligned mem access - let mut buf: [u8; 1024] = [0; 1024]; + let mut buf: [u8; 1024] = [0; 1024]; let len = f(&mut buf[0..len])?; copy_work_buffer(buf.as_mut_ptr() as *mut u32, ptr, len as isize); (DRTIOAUX[linkno].aux_tx_length_write)(len as u16); @@ -152,7 +146,7 @@ pub fn send(linkno: u8, packet: &Packet) -> Result<(), Error> { let mut writer = Cursor::new(buffer); packet.write_to(&mut writer)?; - + // Pad till offset 4, insert checksum there let padding = (12 - (writer.position() % 8)) % 8; for _ in 0..padding { diff --git a/src/libboard_artiq/src/drtioaux_async.rs b/src/libboard_artiq/src/drtioaux_async.rs index 2f2247a..9a79131 100644 --- a/src/libboard_artiq/src/drtioaux_async.rs +++ b/src/libboard_artiq/src/drtioaux_async.rs @@ -1,18 +1,16 @@ +use core_io::{Error as IoError, ErrorKind as IoErrorKind}; use crc; - -use core_io::{ErrorKind as IoErrorKind, Error as IoError}; -use void::Void; +use io::{proto::{ProtoRead, ProtoWrite}, + Cursor}; +use libasync::{block_async, task}; +use libboard_zynq::{time::Milliseconds, timer::GlobalTimer}; use nb; - -use libboard_zynq::{timer::GlobalTimer, time::Milliseconds}; -use libasync::{task, block_async}; - -use io::{proto::ProtoRead, proto::ProtoWrite, Cursor}; -use crate::mem::mem::DRTIOAUX_MEM; -use crate::pl::csr::DRTIOAUX; -use crate::drtioaux::{Error, has_rx_error, copy_work_buffer}; +use void::Void; pub use crate::drtioaux_proto::Packet; +use crate::{drtioaux::{copy_work_buffer, has_rx_error, Error}, + mem::mem::DRTIOAUX_MEM, + pl::csr::DRTIOAUX}; pub async fn reset(linkno: u8) { let linkno = linkno as usize; @@ -29,16 +27,14 @@ fn tx_ready(linkno: usize) -> nb::Result<(), Void> { unsafe { if (DRTIOAUX[linkno].aux_tx_read)() != 0 { Err(nb::Error::WouldBlock) - } - else { + } else { Ok(()) } } } async fn receive(linkno: u8, f: F) -> Result, Error> - where F: FnOnce(&[u8]) -> Result -{ +where F: FnOnce(&[u8]) -> Result { let linkidx = linkno as usize; unsafe { if (DRTIOAUX[linkidx].aux_rx_present_read)() == 1 { @@ -58,12 +54,12 @@ async fn receive(linkno: u8, f: F) -> Result, Error> pub async fn recv(linkno: u8) -> Result, Error> { if has_rx_error(linkno) { - return Err(Error::GatewareError) + return Err(Error::GatewareError); } receive(linkno, |buffer| { if buffer.len() < 8 { - return Err(IoError::new(IoErrorKind::UnexpectedEof, "Unexpected end").into()) + return Err(IoError::new(IoErrorKind::UnexpectedEof, "Unexpected end").into()); } let mut reader = Cursor::new(buffer); @@ -72,17 +68,16 @@ pub async fn recv(linkno: u8) -> Result, Error> { let checksum = crc::crc32::checksum_ieee(&reader.get_ref()[0..checksum_at]); reader.set_position(checksum_at); if reader.read_u32()? != checksum { - return Err(Error::CorruptedPacket) + return Err(Error::CorruptedPacket); } reader.set_position(0); Ok(Packet::read_from(&mut reader)?) - }).await + }) + .await } -pub async fn recv_timeout(linkno: u8, timeout_ms: Option, - timer: GlobalTimer) -> Result -{ +pub async fn recv_timeout(linkno: u8, timeout_ms: Option, timer: GlobalTimer) -> Result { let timeout_ms = Milliseconds(timeout_ms.unwrap_or(10)); let limit = timer.get_time() + timeout_ms; let mut would_block = false; @@ -93,7 +88,9 @@ pub async fn recv_timeout(linkno: u8, timeout_ms: Option, task::r#yield().await; } match recv(linkno).await? { - None => { would_block = true; }, + None => { + would_block = true; + } Some(packet) => return Ok(packet), } } @@ -101,15 +98,14 @@ pub async fn recv_timeout(linkno: u8, timeout_ms: Option, } async fn transmit(linkno: u8, f: F) -> Result<(), Error> - where F: FnOnce(&mut [u8]) -> Result -{ +where F: FnOnce(&mut [u8]) -> Result { let linkno = linkno as usize; unsafe { let _ = block_async!(tx_ready(linkno)).await; let ptr = DRTIOAUX_MEM[linkno].base as *mut u32; let len = DRTIOAUX_MEM[linkno].size / 2; // work buffer, works with unaligned mem access - let mut buf: [u8; 1024] = [0; 1024]; + let mut buf: [u8; 1024] = [0; 1024]; let len = f(&mut buf[0..len])?; copy_work_buffer(buf.as_mut_ptr() as *mut u32, ptr, len as isize); (DRTIOAUX[linkno].aux_tx_length_write)(len as u16); @@ -123,7 +119,7 @@ pub async fn send(linkno: u8, packet: &Packet) -> Result<(), Error> { let mut writer = Cursor::new(buffer); packet.write_to(&mut writer)?; - + // Pad till offset 4, insert checksum there let padding = (12 - (writer.position() % 8)) % 8; for _ in 0..padding { @@ -134,5 +130,6 @@ pub async fn send(linkno: u8, packet: &Packet) -> Result<(), Error> { writer.write_u32(checksum)?; Ok(writer.position()) - }).await + }) + .await } diff --git a/src/libboard_artiq/src/drtioaux_proto.rs b/src/libboard_artiq/src/drtioaux_proto.rs index dc76497..db4f56b 100644 --- a/src/libboard_artiq/src/drtioaux_proto.rs +++ b/src/libboard_artiq/src/drtioaux_proto.rs @@ -1,11 +1,10 @@ -use core_io::{Write, Read, Error as IoError}; - -use io::proto::{ProtoWrite, ProtoRead}; +use core_io::{Error as IoError, Read, Write}; +use io::proto::{ProtoRead, ProtoWrite}; #[derive(Debug)] pub enum Error { UnknownPacket(u8), - Io(IoError) + Io(IoError), } impl From for Error { @@ -22,45 +21,122 @@ pub enum Packet { ResetAck, TSCAck, - DestinationStatusRequest { destination: u8 }, + DestinationStatusRequest { + destination: u8, + }, DestinationDownReply, DestinationOkReply, - DestinationSequenceErrorReply { channel: u16 }, - DestinationCollisionReply { channel: u16 }, - DestinationBusyReply { channel: u16 }, + DestinationSequenceErrorReply { + channel: u16, + }, + DestinationCollisionReply { + channel: u16, + }, + DestinationBusyReply { + channel: u16, + }, - RoutingSetPath { destination: u8, hops: [u8; 32] }, - RoutingSetRank { rank: u8 }, + RoutingSetPath { + destination: u8, + hops: [u8; 32], + }, + RoutingSetRank { + rank: u8, + }, RoutingAck, - MonitorRequest { destination: u8, channel: u16, probe: u8 }, - MonitorReply { value: u64 }, - InjectionRequest { destination: u8, channel: u16, overrd: u8, value: u8 }, - InjectionStatusRequest { destination: u8, channel: u16, overrd: u8 }, - InjectionStatusReply { value: u8 }, + MonitorRequest { + destination: u8, + channel: u16, + probe: u8, + }, + MonitorReply { + value: u64, + }, + InjectionRequest { + destination: u8, + channel: u16, + overrd: u8, + value: u8, + }, + InjectionStatusRequest { + destination: u8, + channel: u16, + overrd: u8, + }, + InjectionStatusReply { + value: u8, + }, - I2cStartRequest { destination: u8, busno: u8 }, - I2cRestartRequest { destination: u8, busno: u8 }, - I2cStopRequest { destination: u8, busno: u8 }, - I2cWriteRequest { destination: u8, busno: u8, data: u8 }, - I2cWriteReply { succeeded: bool, ack: bool }, - I2cReadRequest { destination: u8, busno: u8, ack: bool }, - I2cReadReply { succeeded: bool, data: u8 }, - I2cBasicReply { succeeded: bool }, - I2cSwitchSelectRequest { destination: u8, busno: u8, address: u8, mask: u8 }, - - SpiSetConfigRequest { destination: u8, busno: u8, flags: u8, length: u8, div: u8, cs: u8 }, - SpiWriteRequest { destination: u8, busno: u8, data: u32 }, - SpiReadRequest { destination: u8, busno: u8 }, - SpiReadReply { succeeded: bool, data: u32 }, - SpiBasicReply { succeeded: bool }, + I2cStartRequest { + destination: u8, + busno: u8, + }, + I2cRestartRequest { + destination: u8, + busno: u8, + }, + I2cStopRequest { + destination: u8, + busno: u8, + }, + I2cWriteRequest { + destination: u8, + busno: u8, + data: u8, + }, + I2cWriteReply { + succeeded: bool, + ack: bool, + }, + I2cReadRequest { + destination: u8, + busno: u8, + ack: bool, + }, + I2cReadReply { + succeeded: bool, + data: u8, + }, + I2cBasicReply { + succeeded: bool, + }, + I2cSwitchSelectRequest { + destination: u8, + busno: u8, + address: u8, + mask: u8, + }, + SpiSetConfigRequest { + destination: u8, + busno: u8, + flags: u8, + length: u8, + div: u8, + cs: u8, + }, + SpiWriteRequest { + destination: u8, + busno: u8, + data: u32, + }, + SpiReadRequest { + destination: u8, + busno: u8, + }, + SpiReadReply { + succeeded: bool, + data: u32, + }, + SpiBasicReply { + succeeded: bool, + }, } impl Packet { pub fn read_from(reader: &mut R) -> Result - where R: Read + ?Sized - { + where R: Read + ?Sized { Ok(match reader.read_u8()? { 0x00 => Packet::EchoRequest, 0x01 => Packet::EchoReply, @@ -69,18 +145,18 @@ impl Packet { 0x04 => Packet::TSCAck, 0x20 => Packet::DestinationStatusRequest { - destination: reader.read_u8()? + destination: reader.read_u8()?, }, 0x21 => Packet::DestinationDownReply, 0x22 => Packet::DestinationOkReply, 0x23 => Packet::DestinationSequenceErrorReply { - channel: reader.read_u16()? + channel: reader.read_u16()?, }, 0x24 => Packet::DestinationCollisionReply { - channel: reader.read_u16()? + channel: reader.read_u16()?, }, 0x25 => Packet::DestinationBusyReply { - channel: reader.read_u16()? + channel: reader.read_u16()?, }, 0x30 => { @@ -89,75 +165,75 @@ impl Packet { reader.read_exact(&mut hops)?; Packet::RoutingSetPath { destination: destination, - hops: hops + hops: hops, } - }, + } 0x31 => Packet::RoutingSetRank { - rank: reader.read_u8()? + rank: reader.read_u8()?, }, 0x32 => Packet::RoutingAck, 0x40 => Packet::MonitorRequest { destination: reader.read_u8()?, channel: reader.read_u16()?, - probe: reader.read_u8()? + probe: reader.read_u8()?, }, 0x41 => Packet::MonitorReply { - value: reader.read_u64()? + value: reader.read_u64()?, }, 0x50 => Packet::InjectionRequest { destination: reader.read_u8()?, channel: reader.read_u16()?, overrd: reader.read_u8()?, - value: reader.read_u8()? + value: reader.read_u8()?, }, 0x51 => Packet::InjectionStatusRequest { destination: reader.read_u8()?, channel: reader.read_u16()?, - overrd: reader.read_u8()? + overrd: reader.read_u8()?, }, 0x52 => Packet::InjectionStatusReply { - value: reader.read_u8()? + value: reader.read_u8()?, }, 0x80 => Packet::I2cStartRequest { destination: reader.read_u8()?, - busno: reader.read_u8()? + busno: reader.read_u8()?, }, 0x81 => Packet::I2cRestartRequest { destination: reader.read_u8()?, - busno: reader.read_u8()? + busno: reader.read_u8()?, }, 0x82 => Packet::I2cStopRequest { destination: reader.read_u8()?, - busno: reader.read_u8()? + busno: reader.read_u8()?, }, 0x83 => Packet::I2cWriteRequest { destination: reader.read_u8()?, busno: reader.read_u8()?, - data: reader.read_u8()? + data: reader.read_u8()?, }, 0x84 => Packet::I2cWriteReply { succeeded: reader.read_bool()?, - ack: reader.read_bool()? + ack: reader.read_bool()?, }, 0x85 => Packet::I2cReadRequest { destination: reader.read_u8()?, busno: reader.read_u8()?, - ack: reader.read_bool()? + ack: reader.read_bool()?, }, 0x86 => Packet::I2cReadReply { succeeded: reader.read_bool()?, - data: reader.read_u8()? + data: reader.read_u8()?, }, 0x87 => Packet::I2cBasicReply { - succeeded: reader.read_bool()? + succeeded: reader.read_bool()?, }, 0x88 => Packet::I2cSwitchSelectRequest { destination: reader.read_u8()?, busno: reader.read_u8()?, address: reader.read_u8()?, - mask: reader.read_u8()? + mask: reader.read_u8()?, }, 0x90 => Packet::SpiSetConfigRequest { @@ -166,157 +242,180 @@ impl Packet { flags: reader.read_u8()?, length: reader.read_u8()?, div: reader.read_u8()?, - cs: reader.read_u8()? + cs: reader.read_u8()?, }, /* 0x91: was Packet::SpiSetXferRequest */ 0x92 => Packet::SpiWriteRequest { destination: reader.read_u8()?, busno: reader.read_u8()?, - data: reader.read_u32()? + data: reader.read_u32()?, }, 0x93 => Packet::SpiReadRequest { destination: reader.read_u8()?, - busno: reader.read_u8()? + busno: reader.read_u8()?, }, 0x94 => Packet::SpiReadReply { succeeded: reader.read_bool()?, - data: reader.read_u32()? + data: reader.read_u32()?, }, 0x95 => Packet::SpiBasicReply { - succeeded: reader.read_bool()? + succeeded: reader.read_bool()?, }, - ty => return Err(Error::UnknownPacket(ty)) + ty => return Err(Error::UnknownPacket(ty)), }) } pub fn write_to(&self, writer: &mut W) -> Result<(), IoError> - where W: Write + ?Sized - { - + where W: Write + ?Sized { match *self { - Packet::EchoRequest => - writer.write_u8(0x00)?, - Packet::EchoReply => - writer.write_u8(0x01)?, - Packet::ResetRequest => - writer.write_u8(0x02)?, - Packet::ResetAck => - writer.write_u8(0x03)?, - Packet::TSCAck => - writer.write_u8(0x04)?, + Packet::EchoRequest => writer.write_u8(0x00)?, + Packet::EchoReply => writer.write_u8(0x01)?, + Packet::ResetRequest => writer.write_u8(0x02)?, + Packet::ResetAck => writer.write_u8(0x03)?, + Packet::TSCAck => writer.write_u8(0x04)?, Packet::DestinationStatusRequest { destination } => { writer.write_u8(0x20)?; writer.write_u8(destination)?; - }, - Packet::DestinationDownReply => - writer.write_u8(0x21)?, - Packet::DestinationOkReply => - writer.write_u8(0x22)?, + } + Packet::DestinationDownReply => writer.write_u8(0x21)?, + Packet::DestinationOkReply => writer.write_u8(0x22)?, Packet::DestinationSequenceErrorReply { channel } => { writer.write_u8(0x23)?; writer.write_u16(channel)?; - }, + } Packet::DestinationCollisionReply { channel } => { writer.write_u8(0x24)?; writer.write_u16(channel)?; - }, + } Packet::DestinationBusyReply { channel } => { writer.write_u8(0x25)?; writer.write_u16(channel)?; - }, + } Packet::RoutingSetPath { destination, hops } => { writer.write_u8(0x30)?; writer.write_u8(destination)?; writer.write_all(&hops)?; - }, + } Packet::RoutingSetRank { rank } => { writer.write_u8(0x31)?; writer.write_u8(rank)?; - }, - Packet::RoutingAck => - writer.write_u8(0x32)?, + } + Packet::RoutingAck => writer.write_u8(0x32)?, - Packet::MonitorRequest { destination, channel, probe } => { + Packet::MonitorRequest { + destination, + channel, + probe, + } => { writer.write_u8(0x40)?; writer.write_u8(destination)?; writer.write_u16(channel)?; writer.write_u8(probe)?; - }, + } Packet::MonitorReply { value } => { writer.write_u8(0x41)?; writer.write_u64(value)?; - }, - Packet::InjectionRequest { destination, channel, overrd, value } => { + } + Packet::InjectionRequest { + destination, + channel, + overrd, + value, + } => { writer.write_u8(0x50)?; writer.write_u8(destination)?; writer.write_u16(channel)?; writer.write_u8(overrd)?; writer.write_u8(value)?; - }, - Packet::InjectionStatusRequest { destination, channel, overrd } => { + } + Packet::InjectionStatusRequest { + destination, + channel, + overrd, + } => { writer.write_u8(0x51)?; writer.write_u8(destination)?; writer.write_u16(channel)?; writer.write_u8(overrd)?; - }, + } Packet::InjectionStatusReply { value } => { writer.write_u8(0x52)?; writer.write_u8(value)?; - }, + } Packet::I2cStartRequest { destination, busno } => { writer.write_u8(0x80)?; writer.write_u8(destination)?; writer.write_u8(busno)?; - }, + } Packet::I2cRestartRequest { destination, busno } => { writer.write_u8(0x81)?; writer.write_u8(destination)?; writer.write_u8(busno)?; - }, + } Packet::I2cStopRequest { destination, busno } => { writer.write_u8(0x82)?; writer.write_u8(destination)?; writer.write_u8(busno)?; - }, - Packet::I2cWriteRequest { destination, busno, data } => { + } + Packet::I2cWriteRequest { + destination, + busno, + data, + } => { writer.write_u8(0x83)?; writer.write_u8(destination)?; writer.write_u8(busno)?; writer.write_u8(data)?; - }, + } Packet::I2cWriteReply { succeeded, ack } => { writer.write_u8(0x84)?; writer.write_bool(succeeded)?; writer.write_bool(ack)?; - }, - Packet::I2cReadRequest { destination, busno, ack } => { + } + Packet::I2cReadRequest { + destination, + busno, + ack, + } => { writer.write_u8(0x85)?; writer.write_u8(destination)?; writer.write_u8(busno)?; writer.write_bool(ack)?; - }, + } Packet::I2cReadReply { succeeded, data } => { writer.write_u8(0x86)?; writer.write_bool(succeeded)?; writer.write_u8(data)?; - }, + } Packet::I2cBasicReply { succeeded } => { writer.write_u8(0x87)?; writer.write_bool(succeeded)?; - }, - Packet::I2cSwitchSelectRequest { destination, busno, address, mask } => { + } + Packet::I2cSwitchSelectRequest { + destination, + busno, + address, + mask, + } => { writer.write_u8(0x88)?; writer.write_u8(destination)?; writer.write_u8(busno)?; writer.write_u8(address)?; writer.write_u8(mask)?; - }, + } - Packet::SpiSetConfigRequest { destination, busno, flags, length, div, cs } => { + Packet::SpiSetConfigRequest { + destination, + busno, + flags, + length, + div, + cs, + } => { writer.write_u8(0x90)?; writer.write_u8(destination)?; writer.write_u8(busno)?; @@ -324,30 +423,32 @@ impl Packet { writer.write_u8(length)?; writer.write_u8(div)?; writer.write_u8(cs)?; - }, - Packet::SpiWriteRequest { destination, busno, data } => { + } + Packet::SpiWriteRequest { + destination, + busno, + data, + } => { writer.write_u8(0x92)?; writer.write_u8(destination)?; writer.write_u8(busno)?; writer.write_u32(data)?; - }, + } Packet::SpiReadRequest { destination, busno } => { writer.write_u8(0x93)?; writer.write_u8(destination)?; writer.write_u8(busno)?; - }, + } Packet::SpiReadReply { succeeded, data } => { writer.write_u8(0x94)?; writer.write_bool(succeeded)?; writer.write_u32(data)?; - }, + } Packet::SpiBasicReply { succeeded } => { writer.write_u8(0x95)?; writer.write_bool(succeeded)?; - }, - + } } Ok(()) } - } diff --git a/src/libboard_artiq/src/io_expander.rs b/src/libboard_artiq/src/io_expander.rs index 5e76867..918b773 100644 --- a/src/libboard_artiq/src/io_expander.rs +++ b/src/libboard_artiq/src/io_expander.rs @@ -19,10 +19,8 @@ pub struct IoExpander<'a> { registers: Registers, } - impl<'a> IoExpander<'a> { pub fn new(i2c: &'a mut i2c::I2c, index: u8) -> Result { - // Both expanders on SHARED I2C bus let mut io_expander = match index { 0 => IoExpander { @@ -54,10 +52,7 @@ impl<'a> IoExpander<'a> { _ => return Err("incorrect I/O expander index"), }; if !io_expander.check_ack()? { - info!( - "MCP23017 io expander {} not found. Checking for PCA9539.", - index - ); + info!("MCP23017 io expander {} not found. Checking for PCA9539.", index); io_expander.address += 0xa8; // translate to PCA9539 addresses (see schematic) io_expander.registers = Registers { iodira: 0x06, diff --git a/src/libboard_artiq/src/lib.rs b/src/libboard_artiq/src/lib.rs index b05b3fe..2704e2e 100644 --- a/src/libboard_artiq/src/lib.rs +++ b/src/libboard_artiq/src/lib.rs @@ -1,34 +1,36 @@ #![no_std] #![feature(never_type)] -extern crate log; +extern crate core_io; extern crate crc; extern crate embedded_hal; -extern crate core_io; extern crate io; +extern crate libasync; extern crate libboard_zynq; -extern crate libregister; extern crate libconfig; extern crate libcortex_a9; -extern crate libasync; +extern crate libregister; +extern crate log; extern crate log_buffer; -#[path = "../../../build/pl.rs"] -pub mod pl; -pub mod drtioaux_proto; pub mod drtio_routing; -pub mod logger; -#[cfg(has_si5324)] -pub mod si5324; #[cfg(has_drtio)] pub mod drtioaux; #[cfg(has_drtio)] pub mod drtioaux_async; -#[cfg(has_drtio)] -#[path = "../../../build/mem.rs"] -pub mod mem; +pub mod drtioaux_proto; #[cfg(feature = "target_kasli_soc")] pub mod io_expander; +pub mod logger; +#[cfg(has_drtio)] +#[rustfmt::skip] +#[path = "../../../build/mem.rs"] +pub mod mem; +#[rustfmt::skip] +#[path = "../../../build/pl.rs"] +pub mod pl; +#[cfg(has_si5324)] +pub mod si5324; use core::{cmp, str}; diff --git a/src/libboard_artiq/src/logger.rs b/src/libboard_artiq/src/logger.rs index 3ae9643..eaf472c 100644 --- a/src/libboard_artiq/src/logger.rs +++ b/src/libboard_artiq/src/logger.rs @@ -1,13 +1,13 @@ -use core::cell::Cell; -use core::fmt::Write; -use log::{Log, LevelFilter}; -use log_buffer::LogBuffer; -use libcortex_a9::mutex::{Mutex, MutexGuard}; +use core::{cell::Cell, fmt::Write}; + use libboard_zynq::{println, timer::GlobalTimer}; +use libcortex_a9::mutex::{Mutex, MutexGuard}; +use log::{LevelFilter, Log}; +use log_buffer::LogBuffer; pub struct LogBufferRef<'a> { - buffer: MutexGuard<'a, LogBuffer<&'static mut [u8]>>, - old_log_level: LevelFilter + buffer: MutexGuard<'a, LogBuffer<&'static mut [u8]>>, + old_log_level: LevelFilter, } impl<'a> LogBufferRef<'a> { @@ -37,7 +37,7 @@ impl<'a> Drop for LogBufferRef<'a> { } pub struct BufferLogger { - buffer: Mutex>, + buffer: Mutex>, uart_filter: Cell, buffer_filter: Cell, } @@ -56,8 +56,7 @@ impl BufferLogger { pub fn register(self) { unsafe { LOGGER = Some(self); - log::set_logger(LOGGER.as_ref().unwrap()) - .expect("global logger can only be initialized once"); + log::set_logger(LOGGER.as_ref().unwrap()).expect("global logger can only be initialized once"); } } @@ -66,9 +65,7 @@ impl BufferLogger { } pub fn buffer<'a>(&'a self) -> Option> { - self.buffer - .try_lock() - .map(LogBufferRef::new) + self.buffer.try_lock().map(LogBufferRef::new) } pub fn uart_log_level(&self) -> LevelFilter { @@ -99,25 +96,36 @@ impl Log for BufferLogger { fn log(&self, record: &log::Record) { if self.enabled(record.metadata()) { - let timestamp = unsafe { - GlobalTimer::get() - }.get_us().0; - let seconds = timestamp / 1_000_000; - let micros = timestamp % 1_000_000; + let timestamp = unsafe { GlobalTimer::get() }.get_us().0; + let seconds = timestamp / 1_000_000; + let micros = timestamp % 1_000_000; if record.level() <= self.buffer_log_level() { let mut buffer = self.buffer.lock(); - writeln!(buffer, "[{:6}.{:06}s] {:>5}({}): {}", seconds, micros, - record.level(), record.target(), record.args()).unwrap(); + writeln!( + buffer, + "[{:6}.{:06}s] {:>5}({}): {}", + seconds, + micros, + record.level(), + record.target(), + record.args() + ) + .unwrap(); } if record.level() <= self.uart_log_level() { - println!("[{:6}.{:06}s] {:>5}({}): {}", seconds, micros, - record.level(), record.target(), record.args()); + println!( + "[{:6}.{:06}s] {:>5}({}): {}", + seconds, + micros, + record.level(), + record.target(), + record.args() + ); } } } - fn flush(&self) { - } + fn flush(&self) {} } diff --git a/src/libboard_artiq/src/si5324.rs b/src/libboard_artiq/src/si5324.rs index cd31874..b53174d 100644 --- a/src/libboard_artiq/src/si5324.rs +++ b/src/libboard_artiq/src/si5324.rs @@ -1,7 +1,9 @@ use core::result; -use log::info; -use libboard_zynq::{i2c::I2c, timer::GlobalTimer, time::Milliseconds}; + use embedded_hal::blocking::delay::DelayUs; +use libboard_zynq::{i2c::I2c, time::Milliseconds, timer::GlobalTimer}; +use log::info; + #[cfg(not(si5324_soft_reset))] use crate::pl::csr; @@ -11,9 +13,13 @@ const ADDRESS: u8 = 0x68; #[cfg(not(si5324_soft_reset))] fn hard_reset(timer: &mut GlobalTimer) { - unsafe { csr::si5324_rst_n::out_write(0); } + unsafe { + csr::si5324_rst_n::out_write(0); + } timer.delay_us(1_000); - unsafe { csr::si5324_rst_n::out_write(1); } + unsafe { + csr::si5324_rst_n::out_write(1); + } timer.delay_us(10_000); } @@ -29,7 +35,7 @@ pub struct FrequencySettings { pub n31: u32, pub n32: u32, pub bwsel: u8, - pub crystal_as_ckin2: bool + pub crystal_as_ckin2: bool, } pub enum Input { @@ -39,52 +45,52 @@ pub enum Input { fn map_frequency_settings(settings: &FrequencySettings) -> Result { if settings.nc1_ls != 0 && (settings.nc1_ls % 2) == 1 { - return Err("NC1_LS must be 0 or even") + return Err("NC1_LS must be 0 or even"); } if settings.nc1_ls > (1 << 20) { - return Err("NC1_LS is too high") + return Err("NC1_LS is too high"); } if (settings.n2_ls % 2) == 1 { - return Err("N2_LS must be even") + return Err("N2_LS must be even"); } if settings.n2_ls > (1 << 20) { - return Err("N2_LS is too high") + return Err("N2_LS is too high"); } if settings.n31 > (1 << 19) { - return Err("N31 is too high") + return Err("N31 is too high"); } if settings.n32 > (1 << 19) { - return Err("N32 is too high") + return Err("N32 is too high"); } let r = FrequencySettings { n1_hs: match settings.n1_hs { - 4 => 0b000, - 5 => 0b001, - 6 => 0b010, - 7 => 0b011, - 8 => 0b100, - 9 => 0b101, + 4 => 0b000, + 5 => 0b001, + 6 => 0b010, + 7 => 0b011, + 8 => 0b100, + 9 => 0b101, 10 => 0b110, 11 => 0b111, - _ => return Err("N1_HS has an invalid value") + _ => return Err("N1_HS has an invalid value"), }, nc1_ls: settings.nc1_ls - 1, n2_hs: match settings.n2_hs { - 4 => 0b000, - 5 => 0b001, - 6 => 0b010, - 7 => 0b011, - 8 => 0b100, - 9 => 0b101, + 4 => 0b000, + 5 => 0b001, + 6 => 0b010, + 7 => 0b011, + 8 => 0b100, + 9 => 0b101, 10 => 0b110, 11 => 0b111, - _ => return Err("N2_HS has an invalid value") + _ => return Err("N2_HS has an invalid value"), }, n2_ls: settings.n2_ls - 1, n31: settings.n31 - 1, n32: settings.n32 - 1, bwsel: settings.bwsel, - crystal_as_ckin2: settings.crystal_as_ckin2 + crystal_as_ckin2: settings.crystal_as_ckin2, }; Ok(r) } @@ -92,13 +98,13 @@ fn map_frequency_settings(settings: &FrequencySettings) -> Result Result<()> { i2c.start().unwrap(); if !i2c.write(ADDRESS << 1).unwrap() { - return Err("Si5324 failed to ack write address") + return Err("Si5324 failed to ack write address"); } if !i2c.write(reg).unwrap() { - return Err("Si5324 failed to ack register") + return Err("Si5324 failed to ack register"); } if !i2c.write(val).unwrap() { - return Err("Si5324 failed to ack value") + return Err("Si5324 failed to ack value"); } i2c.stop().unwrap(); Ok(()) @@ -108,10 +114,10 @@ fn write(i2c: &mut I2c, reg: u8, val: u8) -> Result<()> { fn write_no_ack_value(i2c: &mut I2c, reg: u8, val: u8) -> Result<()> { i2c.start().unwrap(); if !i2c.write(ADDRESS << 1).unwrap() { - return Err("Si5324 failed to ack write address") + return Err("Si5324 failed to ack write address"); } if !i2c.write(reg).unwrap() { - return Err("Si5324 failed to ack register") + return Err("Si5324 failed to ack register"); } i2c.write(val).unwrap(); i2c.stop().unwrap(); @@ -121,22 +127,22 @@ fn write_no_ack_value(i2c: &mut I2c, reg: u8, val: u8) -> Result<()> { fn read(i2c: &mut I2c, reg: u8) -> Result { i2c.start().unwrap(); if !i2c.write(ADDRESS << 1).unwrap() { - return Err("Si5324 failed to ack write address") + return Err("Si5324 failed to ack write address"); } if !i2c.write(reg).unwrap() { - return Err("Si5324 failed to ack register") + return Err("Si5324 failed to ack register"); } i2c.restart().unwrap(); if !i2c.write((ADDRESS << 1) | 1).unwrap() { - return Err("Si5324 failed to ack read address") + return Err("Si5324 failed to ack read address"); } let val = i2c.read(false).unwrap(); i2c.stop().unwrap(); Ok(val) } -fn rmw(i2c: &mut I2c, reg: u8, f: F) -> Result<()> where - F: Fn(u8) -> u8 { +fn rmw(i2c: &mut I2c, reg: u8, f: F) -> Result<()> +where F: Fn(u8) -> u8 { let value = read(i2c, reg)?; write(i2c, reg, f(value))?; Ok(()) @@ -155,18 +161,18 @@ fn soft_reset(i2c: &mut I2c, timer: &mut GlobalTimer) -> Result<()> { } fn has_xtal(i2c: &mut I2c) -> Result { - Ok((read(i2c, 129)? & 0x01) == 0) // LOSX_INT=0 + Ok((read(i2c, 129)? & 0x01) == 0) // LOSX_INT=0 } fn has_ckin(i2c: &mut I2c, input: Input) -> Result { match input { - Input::Ckin1 => Ok((read(i2c, 129)? & 0x02) == 0), // LOS1_INT=0 - Input::Ckin2 => Ok((read(i2c, 129)? & 0x04) == 0), // LOS2_INT=0 + Input::Ckin1 => Ok((read(i2c, 129)? & 0x02) == 0), // LOS1_INT=0 + Input::Ckin2 => Ok((read(i2c, 129)? & 0x04) == 0), // LOS2_INT=0 } } fn locked(i2c: &mut I2c) -> Result { - Ok((read(i2c, 130)? & 0x01) == 0) // LOL_INT=0 + Ok((read(i2c, 130)? & 0x01) == 0) // LOL_INT=0 } fn monitor_lock(i2c: &mut I2c, timer: &mut GlobalTimer) -> Result<()> { @@ -211,11 +217,11 @@ pub fn bypass(i2c: &mut I2c, input: Input, timer: &mut GlobalTimer) -> Result<() Input::Ckin2 => 0b01, }; init(i2c, timer)?; - rmw(i2c, 21, |v| v & 0xfe)?; // CKSEL_PIN=0 - rmw(i2c, 3, |v| (v & 0x3f) | (cksel_reg << 6))?; // CKSEL_REG - rmw(i2c, 4, |v| (v & 0x3f) | (0b00 << 6))?; // AUTOSEL_REG=b00 - rmw(i2c, 6, |v| (v & 0xc0) | 0b111111)?; // SFOUT2_REG=b111 SFOUT1_REG=b111 - rmw(i2c, 0, |v| (v & 0xfd) | 0x02)?; // BYPASS_REG=1 + rmw(i2c, 21, |v| v & 0xfe)?; // CKSEL_PIN=0 + rmw(i2c, 3, |v| (v & 0x3f) | (cksel_reg << 6))?; // CKSEL_REG + rmw(i2c, 4, |v| (v & 0x3f) | (0b00 << 6))?; // AUTOSEL_REG=b00 + rmw(i2c, 6, |v| (v & 0xc0) | 0b111111)?; // SFOUT2_REG=b111 SFOUT1_REG=b111 + rmw(i2c, 0, |v| (v & 0xfd) | 0x02)?; // BYPASS_REG=1 Ok(()) } @@ -228,31 +234,31 @@ pub fn setup(i2c: &mut I2c, settings: &FrequencySettings, input: Input, timer: & init(i2c, timer)?; if settings.crystal_as_ckin2 { - rmw(i2c, 0, |v| v | 0x40)?; // FREE_RUN=1 + rmw(i2c, 0, |v| v | 0x40)?; // FREE_RUN=1 } - rmw(i2c, 2, |v| (v & 0x0f) | (s.bwsel << 4))?; - rmw(i2c, 21, |v| v & 0xfe)?; // CKSEL_PIN=0 - rmw(i2c, 3, |v| (v & 0x2f) | (cksel_reg << 6) | 0x10)?; // CKSEL_REG, SQ_ICAL=1 - rmw(i2c, 4, |v| (v & 0x3f) | (0b00 << 6))?; // AUTOSEL_REG=b00 - rmw(i2c, 6, |v| (v & 0xc0) | 0b111111)?; // SFOUT2_REG=b111 SFOUT1_REG=b111 - write(i2c, 25, (s.n1_hs << 5 ) as u8)?; - write(i2c, 31, (s.nc1_ls >> 16) as u8)?; - write(i2c, 32, (s.nc1_ls >> 8 ) as u8)?; - write(i2c, 33, (s.nc1_ls) as u8)?; - write(i2c, 34, (s.nc1_ls >> 16) as u8)?; // write to NC2_LS as well - write(i2c, 35, (s.nc1_ls >> 8 ) as u8)?; - write(i2c, 36, (s.nc1_ls) as u8)?; - write(i2c, 40, (s.n2_hs << 5 ) as u8 | (s.n2_ls >> 16) as u8)?; - write(i2c, 41, (s.n2_ls >> 8 ) as u8)?; - write(i2c, 42, (s.n2_ls) as u8)?; - write(i2c, 43, (s.n31 >> 16) as u8)?; - write(i2c, 44, (s.n31 >> 8) as u8)?; - write(i2c, 45, (s.n31) as u8)?; - write(i2c, 46, (s.n32 >> 16) as u8)?; - write(i2c, 47, (s.n32 >> 8) as u8)?; - write(i2c, 48, (s.n32) as u8)?; - rmw(i2c, 137, |v| v | 0x01)?; // FASTLOCK=1 - rmw(i2c, 136, |v| v | 0x40)?; // ICAL=1 + rmw(i2c, 2, |v| (v & 0x0f) | (s.bwsel << 4))?; + rmw(i2c, 21, |v| v & 0xfe)?; // CKSEL_PIN=0 + rmw(i2c, 3, |v| (v & 0x2f) | (cksel_reg << 6) | 0x10)?; // CKSEL_REG, SQ_ICAL=1 + rmw(i2c, 4, |v| (v & 0x3f) | (0b00 << 6))?; // AUTOSEL_REG=b00 + rmw(i2c, 6, |v| (v & 0xc0) | 0b111111)?; // SFOUT2_REG=b111 SFOUT1_REG=b111 + write(i2c, 25, (s.n1_hs << 5) as u8)?; + write(i2c, 31, (s.nc1_ls >> 16) as u8)?; + write(i2c, 32, (s.nc1_ls >> 8) as u8)?; + write(i2c, 33, (s.nc1_ls) as u8)?; + write(i2c, 34, (s.nc1_ls >> 16) as u8)?; // write to NC2_LS as well + write(i2c, 35, (s.nc1_ls >> 8) as u8)?; + write(i2c, 36, (s.nc1_ls) as u8)?; + write(i2c, 40, (s.n2_hs << 5) as u8 | (s.n2_ls >> 16) as u8)?; + write(i2c, 41, (s.n2_ls >> 8) as u8)?; + write(i2c, 42, (s.n2_ls) as u8)?; + write(i2c, 43, (s.n31 >> 16) as u8)?; + write(i2c, 44, (s.n31 >> 8) as u8)?; + write(i2c, 45, (s.n31) as u8)?; + write(i2c, 46, (s.n32 >> 16) as u8)?; + write(i2c, 47, (s.n32 >> 8) as u8)?; + write(i2c, 48, (s.n32) as u8)?; + rmw(i2c, 137, |v| v | 0x01)?; // FASTLOCK=1 + rmw(i2c, 136, |v| v | 0x40)?; // ICAL=1 if !has_xtal(i2c)? { return Err("Si5324 misses XA/XB signal"); @@ -270,7 +276,7 @@ pub fn select_input(i2c: &mut I2c, input: Input, timer: &mut GlobalTimer) -> Res Input::Ckin1 => 0b00, Input::Ckin2 => 0b01, }; - rmw(i2c, 3, |v| (v & 0x3f) | (cksel_reg << 6))?; + rmw(i2c, 3, |v| (v & 0x3f) | (cksel_reg << 6))?; if !has_ckin(i2c, input)? { return Err("Si5324 misses clock input signal"); } @@ -285,12 +291,12 @@ pub mod siphaser { pub fn select_recovered_clock(i2c: &mut I2c, rc: bool, timer: &mut GlobalTimer) -> Result<()> { let val = read(i2c, 3)?; - write(i2c, 3, (val & 0xdf) | (1 << 5))?; // DHOLD=1 + write(i2c, 3, (val & 0xdf) | (1 << 5))?; // DHOLD=1 unsafe { csr::siphaser::switch_clocks_write(if rc { 1 } else { 0 }); } let val = read(i2c, 3)?; - write(i2c, 3, (val & 0xdf) | (0 << 5))?; // DHOLD=0 + write(i2c, 3, (val & 0xdf) | (0 << 5))?; // DHOLD=0 monitor_lock(i2c, timer)?; Ok(()) } @@ -309,9 +315,7 @@ pub mod siphaser { csr::siphaser::error_write(1); } timer.delay_us(5_000); - unsafe { - csr::siphaser::error_read() != 0 - } + unsafe { csr::siphaser::error_read() != 0 } } fn find_edge(target: bool, timer: &mut GlobalTimer) -> Result { @@ -340,14 +344,19 @@ pub mod siphaser { } let width = find_edge(true, timer)? + jitter_margin; // width is 360 degrees (one full rotation of the phase between s/h limits) minus jitter - info!("calibration successful, lead: {}, width: {} ({}deg)", lead, width, width*360/(56*8)); + info!( + "calibration successful, lead: {}, width: {} ({}deg)", + lead, + width, + width * 360 / (56 * 8) + ); // Apply reverse phase shift for half the width to get into the // middle of the working region. - for _ in 0..width/2 { + for _ in 0..width / 2 { phase_shift(0, timer); } Ok(()) } -} \ No newline at end of file +} diff --git a/src/libbuild_zynq/lib.rs b/src/libbuild_zynq/lib.rs index 7bb0aef..ab31b06 100644 --- a/src/libbuild_zynq/lib.rs +++ b/src/libbuild_zynq/lib.rs @@ -1,8 +1,7 @@ -use std::env; -use std::fs::File; -use std::io::{BufRead, BufReader, Write}; -use std::path::PathBuf; - +use std::{env, + fs::File, + io::{BufRead, BufReader, Write}, + path::PathBuf}; pub fn add_linker_script() { // Put the linker script somewhere the linker can find it diff --git a/src/libc/build.rs b/src/libc/build.rs index 08002d9..23f678c 100644 --- a/src/libc/build.rs +++ b/src/libc/build.rs @@ -4,8 +4,7 @@ fn main() { } mod libc { - use std::path::Path; - use std::env; + use std::{env, path::Path}; pub fn compile() { let cfg = &mut cc::Build::new(); @@ -32,9 +31,7 @@ mod libc { cfg.flag("-U_FORTIFY_SOURCE"); cfg.define("_FORTIFY_SOURCE", Some("0")); - let sources = vec![ - "printf.c" - ]; + let sources = vec!["printf.c"]; let root = Path::new("./"); for src in sources { diff --git a/src/libdwarf/src/eh.rs b/src/libdwarf/src/eh.rs index c7fd15b..e9b2358 100644 --- a/src/libdwarf/src/eh.rs +++ b/src/libdwarf/src/eh.rs @@ -11,10 +11,12 @@ #![allow(non_upper_case_globals)] #![allow(unused)] -use crate::DwarfReader; use core::mem; + use cslice::CSlice; +use crate::DwarfReader; + pub const DW_EH_PE_omit: u8 = 0xFF; pub const DW_EH_PE_absptr: u8 = 0x00; @@ -160,15 +162,11 @@ pub unsafe fn find_eh_action( if ar_filter == 0 { saw_cleanup = true; } else if ar_filter > 0 { - let catch_type = get_ttype_entry( - ar_filter as usize, - ttype_encoding, - ttype_base, - ttype_table, - )?; + let catch_type = + get_ttype_entry(ar_filter as usize, ttype_encoding, ttype_base, ttype_table)?; match catch_type { Some(clause_ptr) if *(clause_ptr as *const u32) == id => { - return Ok(EHAction::Catch(lpad)) + return Ok(EHAction::Catch(lpad)); } None => return Ok(EHAction::Catch(lpad)), _ => {} @@ -251,19 +249,11 @@ fn get_base(encoding: u8, context: &EHContext<'_>) -> Result { } } -unsafe fn read_encoded_pointer( - reader: &mut DwarfReader, - context: &EHContext<'_>, - encoding: u8, -) -> Result { +unsafe fn read_encoded_pointer(reader: &mut DwarfReader, context: &EHContext<'_>, encoding: u8) -> Result { read_encoded_pointer_with_base(reader, encoding, get_base(encoding, context)?) } -unsafe fn read_encoded_pointer_with_base( - reader: &mut DwarfReader, - encoding: u8, - base: usize, -) -> Result { +unsafe fn read_encoded_pointer_with_base(reader: &mut DwarfReader, encoding: u8, base: usize) -> Result { if encoding == DW_EH_PE_omit { return Err(()); } diff --git a/src/libdyld/src/elf.rs b/src/libdyld/src/elf.rs index e988b87..f4e835d 100644 --- a/src/libdyld/src/elf.rs +++ b/src/libdyld/src/elf.rs @@ -1451,8 +1451,7 @@ pub const R_AARCH64_TLSDESC_CALL: usize = 569; pub const R_AARCH64_TLSLE_LDST128_TPREL_LO12: usize = 570; pub const R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC: usize = 571; pub const R_AARCH64_TLSLD_LDST128_DTPREL_LO12: usize = 572; -pub const R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC: usize = - 573; +pub const R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC: usize = 573; pub const R_AARCH64_COPY: usize = 1024; pub const R_AARCH64_GLOB_DAT: usize = 1025; pub const R_AARCH64_JUMP_SLOT: usize = 1026; @@ -2267,7 +2266,9 @@ pub struct Elf32_Ehdr { pub e_shstrndx: Elf32_Half, } impl Clone for Elf32_Ehdr { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Debug, Copy)] @@ -2288,7 +2289,9 @@ pub struct Elf64_Ehdr { pub e_shstrndx: Elf64_Half, } impl Clone for Elf64_Ehdr { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Debug, Copy)] @@ -2305,7 +2308,9 @@ pub struct Elf32_Shdr { pub sh_entsize: Elf32_Word, } impl Clone for Elf32_Shdr { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Debug, Copy)] @@ -2322,7 +2327,9 @@ pub struct Elf64_Shdr { pub sh_entsize: Elf64_Xword, } impl Clone for Elf64_Shdr { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Debug, Copy)] @@ -2335,7 +2342,9 @@ pub struct Elf32_Sym { pub st_shndx: Elf32_Section, } impl Clone for Elf32_Sym { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Debug, Copy)] @@ -2348,7 +2357,9 @@ pub struct Elf64_Sym { pub st_size: Elf64_Xword, } impl Clone for Elf64_Sym { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Debug, Copy)] @@ -2357,7 +2368,9 @@ pub struct Elf32_Syminfo { pub si_flags: Elf32_Half, } impl Clone for Elf32_Syminfo { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Debug, Copy)] @@ -2366,7 +2379,9 @@ pub struct Elf64_Syminfo { pub si_flags: Elf64_Half, } impl Clone for Elf64_Syminfo { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Debug, Copy)] @@ -2375,7 +2390,9 @@ pub struct Elf32_Rel { pub r_info: Elf32_Word, } impl Clone for Elf32_Rel { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Debug, Copy)] @@ -2384,7 +2401,9 @@ pub struct Elf64_Rel { pub r_info: Elf64_Xword, } impl Clone for Elf64_Rel { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Debug, Copy)] @@ -2394,7 +2413,9 @@ pub struct Elf32_Rela { pub r_addend: Elf32_Sword, } impl Clone for Elf32_Rela { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Debug, Copy)] @@ -2404,7 +2425,9 @@ pub struct Elf64_Rela { pub r_addend: Elf64_Sxword, } impl Clone for Elf64_Rela { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Debug, Copy)] @@ -2419,7 +2442,9 @@ pub struct Elf32_Phdr { pub p_align: Elf32_Word, } impl Clone for Elf32_Phdr { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Debug, Copy)] @@ -2434,7 +2459,9 @@ pub struct Elf64_Phdr { pub p_align: Elf64_Xword, } impl Clone for Elf64_Phdr { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Copy)] @@ -2449,10 +2476,14 @@ pub union Elf32_Dyn__bindgen_ty_1 { pub d_ptr: Elf32_Addr, } impl Clone for Elf32_Dyn__bindgen_ty_1 { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } impl Clone for Elf32_Dyn { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Copy)] @@ -2467,10 +2498,14 @@ pub union Elf64_Dyn__bindgen_ty_1 { pub d_ptr: Elf64_Addr, } impl Clone for Elf64_Dyn__bindgen_ty_1 { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } impl Clone for Elf64_Dyn { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Debug, Copy)] @@ -2484,7 +2519,9 @@ pub struct Elf32_Verdef { pub vd_next: Elf32_Word, } impl Clone for Elf32_Verdef { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Debug, Copy)] @@ -2498,7 +2535,9 @@ pub struct Elf64_Verdef { pub vd_next: Elf64_Word, } impl Clone for Elf64_Verdef { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Debug, Copy)] @@ -2507,7 +2546,9 @@ pub struct Elf32_Verdaux { pub vda_next: Elf32_Word, } impl Clone for Elf32_Verdaux { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Debug, Copy)] @@ -2516,7 +2557,9 @@ pub struct Elf64_Verdaux { pub vda_next: Elf64_Word, } impl Clone for Elf64_Verdaux { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Debug, Copy)] @@ -2528,7 +2571,9 @@ pub struct Elf32_Verneed { pub vn_next: Elf32_Word, } impl Clone for Elf32_Verneed { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Debug, Copy)] @@ -2540,7 +2585,9 @@ pub struct Elf64_Verneed { pub vn_next: Elf64_Word, } impl Clone for Elf64_Verneed { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Debug, Copy)] @@ -2552,7 +2599,9 @@ pub struct Elf32_Vernaux { pub vna_next: Elf32_Word, } impl Clone for Elf32_Vernaux { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Debug, Copy)] @@ -2564,7 +2613,9 @@ pub struct Elf64_Vernaux { pub vna_next: Elf64_Word, } impl Clone for Elf64_Vernaux { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Copy)] @@ -2578,10 +2629,14 @@ pub union Elf32_auxv_t__bindgen_ty_1 { pub a_val: u32, } impl Clone for Elf32_auxv_t__bindgen_ty_1 { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } impl Clone for Elf32_auxv_t { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Copy)] @@ -2595,10 +2650,14 @@ pub union Elf64_auxv_t__bindgen_ty_1 { pub a_val: u64, } impl Clone for Elf64_auxv_t__bindgen_ty_1 { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } impl Clone for Elf64_auxv_t { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Debug, Copy)] @@ -2608,7 +2667,9 @@ pub struct Elf32_Nhdr { pub n_type: Elf32_Word, } impl Clone for Elf32_Nhdr { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Debug, Copy)] @@ -2618,7 +2679,9 @@ pub struct Elf64_Nhdr { pub n_type: Elf64_Word, } impl Clone for Elf64_Nhdr { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Debug, Copy)] @@ -2630,7 +2693,9 @@ pub struct Elf32_Move { pub m_stride: Elf32_Half, } impl Clone for Elf32_Move { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Debug, Copy)] @@ -2642,7 +2707,9 @@ pub struct Elf64_Move { pub m_stride: Elf64_Half, } impl Clone for Elf64_Move { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Copy)] @@ -2657,7 +2724,9 @@ pub struct Elf32_gptab__bindgen_ty_1 { pub gt_unused: Elf32_Word, } impl Clone for Elf32_gptab__bindgen_ty_1 { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Debug, Copy)] @@ -2666,10 +2735,14 @@ pub struct Elf32_gptab__bindgen_ty_2 { pub gt_bytes: Elf32_Word, } impl Clone for Elf32_gptab__bindgen_ty_2 { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } impl Clone for Elf32_gptab { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Debug, Copy)] @@ -2679,7 +2752,9 @@ pub struct Elf32_RegInfo { pub ri_gp_value: Elf32_Sword, } impl Clone for Elf32_RegInfo { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Debug, Copy)] @@ -2690,7 +2765,9 @@ pub struct Elf_Options { pub info: Elf32_Word, } impl Clone for Elf_Options { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Debug, Copy)] @@ -2699,7 +2776,9 @@ pub struct Elf_Options_Hw { pub hwp_flags2: Elf32_Word, } impl Clone for Elf_Options_Hw { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Debug, Copy)] @@ -2711,7 +2790,9 @@ pub struct Elf32_Lib { pub l_flags: Elf32_Word, } impl Clone for Elf32_Lib { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } #[repr(C)] #[derive(Debug, Copy)] @@ -2723,17 +2804,31 @@ pub struct Elf64_Lib { pub l_flags: Elf64_Word, } impl Clone for Elf64_Lib { - fn clone(&self) -> Self { *self } + fn clone(&self) -> Self { + *self + } } pub type Elf32_Conflict = Elf32_Addr; #[repr(C)] #[derive(Clone, Copy)] pub struct EXIDX_Entry(u32, u32); -pub fn ELF32_R_SYM(info: Elf32_Word) -> Elf32_Word { info >> 8 } -pub fn ELF32_R_TYPE(info: Elf32_Word) -> u8 { info as u8 } -pub fn ELF32_R_INFO(sym: Elf32_Word, ty: u8) -> Elf32_Word { sym << 8 | ty as Elf32_Word } +pub fn ELF32_R_SYM(info: Elf32_Word) -> Elf32_Word { + info >> 8 +} +pub fn ELF32_R_TYPE(info: Elf32_Word) -> u8 { + info as u8 +} +pub fn ELF32_R_INFO(sym: Elf32_Word, ty: u8) -> Elf32_Word { + sym << 8 | ty as Elf32_Word +} -pub fn ELF32_ST_BIND(info: u8) -> u8 { info >> 4 } -pub fn ELF32_ST_TYPE(info: u8) -> u8 { info & 0xf } -pub fn ELF32_ST_INFO(bind: u8, ty: u8) -> u8 { (bind << 4) | (ty & 0xf) } +pub fn ELF32_ST_BIND(info: u8) -> u8 { + info >> 4 +} +pub fn ELF32_ST_TYPE(info: u8) -> u8 { + info & 0xf +} +pub fn ELF32_ST_INFO(bind: u8, ty: u8) -> u8 { + (bind << 4) | (ty & 0xf) +} diff --git a/src/libdyld/src/file.rs b/src/libdyld/src/file.rs index 1c149dc..e67f5de 100644 --- a/src/libdyld/src/file.rs +++ b/src/libdyld/src/file.rs @@ -1,8 +1,8 @@ -use core::{mem, ptr, ops::{Deref, Range}}; -use super::{ - Arch, - elf::*, -}; +use core::{mem, + ops::{Deref, Range}, + ptr}; + +use super::{elf::*, Arch}; fn read_unaligned(data: &[u8], offset: usize) -> Option { if data.len() < offset + mem::size_of::() { @@ -31,14 +31,40 @@ impl<'a> File<'a> { pub fn arch(&self) -> Option { const IDENT_OPENRISC: [u8; EI_NIDENT] = [ - ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3, - ELFCLASS32, ELFDATA2MSB, EV_CURRENT, ELFOSABI_NONE, - /* ABI version */ 0, /* padding */ 0, 0, 0, 0, 0, 0, 0 + ELFMAG0, + ELFMAG1, + ELFMAG2, + ELFMAG3, + ELFCLASS32, + ELFDATA2MSB, + EV_CURRENT, + ELFOSABI_NONE, + /* ABI version */ 0, + /* padding */ 0, + 0, + 0, + 0, + 0, + 0, + 0, ]; const IDENT_ARM: [u8; EI_NIDENT] = [ - ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3, - ELFCLASS32, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, - /* ABI version */ 0, /* padding */ 0, 0, 0, 0, 0, 0, 0 + ELFMAG0, + ELFMAG1, + ELFMAG2, + ELFMAG3, + ELFCLASS32, + ELFDATA2LSB, + EV_CURRENT, + ELFOSABI_NONE, + /* ABI version */ 0, + /* padding */ 0, + 0, + 0, + 0, + 0, + 0, + 0, ]; match (self.ehdr.e_ident, self.ehdr.e_machine) { @@ -48,16 +74,14 @@ impl<'a> File<'a> { } } - pub fn program_headers<'b>(&'b self) -> impl Iterator> + 'b - { + pub fn program_headers<'b>(&'b self) -> impl Iterator> + 'b { (0..self.ehdr.e_phnum).map(move |i| { let phdr_off = self.ehdr.e_phoff as usize + mem::size_of::() * i as usize; self.read_unaligned::(phdr_off) }) } - pub fn section_headers<'b>(&'b self) -> impl Iterator> + 'b - { + pub fn section_headers<'b>(&'b self) -> impl Iterator> + 'b { (0..self.ehdr.e_shnum).map(move |i| { let shdr_off = self.ehdr.e_shoff as usize + mem::size_of::() * i as usize; self.read_unaligned::(shdr_off) diff --git a/src/libdyld/src/image.rs b/src/libdyld/src/image.rs index 34ef7cf..f127020 100644 --- a/src/libdyld/src/image.rs +++ b/src/libdyld/src/image.rs @@ -1,13 +1,9 @@ -use core::{ - ops::{Deref, DerefMut, Range}, - mem, - slice, -}; use alloc::alloc::{alloc_zeroed, dealloc, Layout, LayoutError}; -use super::{ - elf::*, - Error, -}; +use core::{mem, + ops::{Deref, DerefMut, Range}, + slice}; + +use super::{elf::*, Error}; pub struct DynamicSection { pub strtab: Range, @@ -34,17 +30,12 @@ impl Image { slice::from_raw_parts_mut(ptr, size) }; - Ok(Image { - layout, - data, - }) + Ok(Image { layout, data }) } /// assumes that self.data is properly aligned pub(crate) fn get_ref(&self, offset: usize) -> Option<&T> - where - T: Copy, - { + where T: Copy { if self.data.len() < offset + mem::size_of::() { None } else if (self.data.as_ptr() as usize + offset) & (mem::align_of::() - 1) != 0 { @@ -66,55 +57,53 @@ impl Image { unsafe { slice::from_raw_parts(ptr, len) } } - fn dyn_headers<'a>(&'a self, range: Range) -> - impl Iterator + 'a - { + fn dyn_headers<'a>(&'a self, range: Range) -> impl Iterator + 'a { range .step_by(mem::size_of::()) - .filter_map(move |offset| { - self.get_ref::(offset) - }) + .filter_map(move |offset| self.get_ref::(offset)) .take_while(|d| unsafe { d.d_un.d_val } as i32 != DT_NULL) } pub fn dyn_section(&self, range: Range) -> Result { let (mut strtab_off, mut strtab_sz) = (0, 0); - let (mut rel_off, mut rel_sz) = (0, 0); - let (mut rela_off, mut rela_sz) = (0, 0); + let (mut rel_off, mut rel_sz) = (0, 0); + let (mut rela_off, mut rela_sz) = (0, 0); let (mut pltrel_off, mut pltrel_sz) = (0, 0); - let (mut hash_off, mut hash_sz) = (0, 0); + let (mut hash_off, mut hash_sz) = (0, 0); let mut symtab_off = 0; - let mut sym_ent = 0; - let mut rel_ent = 0; - let mut rela_ent = 0; - let mut nbucket = 0; - let mut nchain = 0; + let mut sym_ent = 0; + let mut rel_ent = 0; + let mut rela_ent = 0; + let mut nbucket = 0; + let mut nchain = 0; for dyn_header in self.dyn_headers(range) { let val = unsafe { dyn_header.d_un.d_val } as usize; match dyn_header.d_tag { - DT_NULL => break, - DT_STRTAB => strtab_off = val, - DT_STRSZ => strtab_sz = val, - DT_SYMTAB => symtab_off = val, - DT_SYMENT => sym_ent = val, - DT_REL => rel_off = val, - DT_RELSZ => rel_sz = val, - DT_RELENT => rel_ent = val, - DT_RELA => rela_off = val, - DT_RELASZ => rela_sz = val, - DT_RELAENT => rela_ent = val, - DT_JMPREL => pltrel_off = val, - DT_PLTRELSZ => pltrel_sz = val, - DT_HASH => { - nbucket = *self.get_ref::(val + 0) + DT_NULL => break, + DT_STRTAB => strtab_off = val, + DT_STRSZ => strtab_sz = val, + DT_SYMTAB => symtab_off = val, + DT_SYMENT => sym_ent = val, + DT_REL => rel_off = val, + DT_RELSZ => rel_sz = val, + DT_RELENT => rel_ent = val, + DT_RELA => rela_off = val, + DT_RELASZ => rela_sz = val, + DT_RELAENT => rela_ent = val, + DT_JMPREL => pltrel_off = val, + DT_PLTRELSZ => pltrel_sz = val, + DT_HASH => { + nbucket = *self + .get_ref::(val + 0) .ok_or("cannot read hash bucket count")? as usize; - nchain = *self.get_ref::(val + 4) + nchain = *self + .get_ref::(val + 4) .ok_or("cannot read hash chain count")? as usize; hash_off = val + 8; - hash_sz = (nbucket + nchain) * mem::size_of::(); + hash_sz = (nbucket + nchain) * mem::size_of::(); } - _ => () + _ => (), } } @@ -123,28 +112,28 @@ impl Image { let symtab_sz = nchain * mem::size_of::(); if strtab_off + strtab_sz > self.data.len() { - return Err("invalid strtab offset/size")? + return Err("invalid strtab offset/size")?; } if symtab_off + symtab_sz > self.data.len() { - return Err("invalid symtab offset/size")? + return Err("invalid symtab offset/size")?; } if sym_ent != mem::size_of::() { - return Err("incorrect symbol entry size")? + return Err("incorrect symbol entry size")?; } if rel_off + rel_sz > self.data.len() { - return Err("invalid rel offset/size")? + return Err("invalid rel offset/size")?; } if rel_ent != 0 && rel_ent != mem::size_of::() { - return Err("incorrect relocation entry size")? + return Err("incorrect relocation entry size")?; } if rela_off + rela_sz > self.data.len() { - return Err("invalid rela offset/size")? + return Err("invalid rela offset/size")?; } if rela_ent != 0 && rela_ent != mem::size_of::() { - return Err("incorrect relocation entry size")? + return Err("incorrect relocation entry size")?; } if pltrel_off + pltrel_sz > self.data.len() { - return Err("invalid pltrel offset/size")? + return Err("invalid pltrel offset/size")?; } Ok(DynamicSection { @@ -165,7 +154,7 @@ impl Image { pub fn write(&self, offset: usize, value: Elf32_Word) -> Result<(), Error> { if offset + mem::size_of::() > self.data.len() { - return Err("relocation out of image bounds")? + return Err("relocation out of image bounds")?; } let ptr = (self.data.as_ptr() as usize + offset) as *mut Elf32_Addr; diff --git a/src/libdyld/src/lib.rs b/src/libdyld/src/lib.rs index a4621bd..111a911 100644 --- a/src/libdyld/src/lib.rs +++ b/src/libdyld/src/lib.rs @@ -1,13 +1,14 @@ #![no_std] extern crate alloc; -extern crate log; extern crate libcortex_a9; +extern crate log; -use core::{convert, fmt, ops::Range, str}; use alloc::string::String; -use log::{debug, trace}; +use core::{convert, fmt, ops::Range, str}; + use elf::*; +use log::{debug, trace}; pub mod elf; mod file; @@ -21,11 +22,10 @@ pub enum Arch { OpenRisc, } - #[derive(Debug)] pub enum Error { Parsing(&'static str), - Lookup(String) + Lookup(String), } impl convert::From<&'static str> for Error { @@ -37,10 +37,8 @@ impl convert::From<&'static str> for Error { impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - &Error::Parsing(desc) => - write!(f, "parse error: {}", desc), - &Error::Lookup(ref sym) => - write!(f, "symbol lookup error: {}", sym), + &Error::Parsing(desc) => write!(f, "parse error: {}", desc), + &Error::Lookup(ref sym) => write!(f, "symbol lookup error: {}", sym), } } } @@ -103,20 +101,22 @@ impl Library { let mut index = self.hash_bucket()[hash as usize % self.hash_bucket().len()] as usize; loop { - if index == STN_UNDEF { return None } + if index == STN_UNDEF { + return None; + } let sym = &self.symtab()[index]; let sym_name_off = sym.st_name as usize; match self.strtab().get(sym_name_off..sym_name_off + name.len()) { Some(sym_name) if sym_name == name => { if ELF32_ST_BIND(sym.st_info) & STB_GLOBAL == 0 { - return None + return None; } match sym.st_shndx { SHN_UNDEF => return None, SHN_ABS => return Some(self.image.ptr() as u32 + sym.st_value), - _ => return Some(self.image.ptr() as u32 + sym.st_value) + _ => return Some(self.image.ptr() as u32 + sym.st_value), } } _ => (), @@ -127,10 +127,16 @@ impl Library { } pub fn name_starting_at(&self, offset: usize) -> Result<&[u8], Error> { - let size = self.strtab().iter().skip(offset).position(|&x| x == 0) - .ok_or("symbol in symbol table not null-terminated")?; - Ok(self.strtab().get(offset..offset + size) - .ok_or("cannot read symbol name")?) + let size = self + .strtab() + .iter() + .skip(offset) + .position(|&x| x == 0) + .ok_or("symbol in symbol table not null-terminated")?; + Ok(self + .strtab() + .get(offset..offset + size) + .ok_or("cannot read symbol name")?) } /// Rebind Rela by `name` to a new `addr` @@ -143,53 +149,59 @@ impl Library { } } -pub fn load( - data: &[u8], - resolve: &dyn Fn(&[u8]) -> Option -) -> Result { +pub fn load(data: &[u8], resolve: &dyn Fn(&[u8]) -> Option) -> Result { // validate ELF file - let file = file::File::new(data) - .ok_or("cannot read ELF header")?; + let file = file::File::new(data).ok_or("cannot read ELF header")?; if file.ehdr.e_type != ET_DYN { - return Err("not a shared library")? + return Err("not a shared library")?; } - let arch = file.arch() - .ok_or("not for a supported architecture")?; + let arch = file.arch().ok_or("not for a supported architecture")?; // prepare target memory - let image_size = file.program_headers() + let image_size = file + .program_headers() .filter_map(|phdr| phdr.map(|phdr| phdr.p_vaddr + phdr.p_memsz)) .max() .unwrap_or(0) as usize; - let image_align = file.program_headers() - .filter_map(|phdr| phdr.and_then(|phdr| { - if phdr.p_type == PT_LOAD { - Some(phdr.p_align) - } else { - None - } - })) + let image_align = file + .program_headers() + .filter_map(|phdr| { + phdr.and_then(|phdr| { + if phdr.p_type == PT_LOAD { + Some(phdr.p_align) + } else { + None + } + }) + }) .max() .unwrap_or(4) as usize; // 1 image for all segments - let mut image = image::Image::new(image_size, image_align) - .map_err(|_| "cannot allocate target image")?; - debug!("ELF target: {} bytes, align to {:X}, allocated at {:08X}", image_size, image_align, image.ptr() as usize); + let mut image = image::Image::new(image_size, image_align).map_err(|_| "cannot allocate target image")?; + debug!( + "ELF target: {} bytes, align to {:X}, allocated at {:08X}", + image_size, + image_align, + image.ptr() as usize + ); // LOAD for phdr in file.program_headers() { let phdr = phdr.ok_or("cannot read program header")?; - trace!("Program header: {:08X}+{:08X} to {:08X}", - phdr.p_offset, phdr.p_filesz, - image.ptr() as u32 + trace!( + "Program header: {:08X}+{:08X} to {:08X}", + phdr.p_offset, + phdr.p_filesz, + image.ptr() as u32 ); let file_range = phdr.p_offset as usize..(phdr.p_offset + phdr.p_filesz) as usize; match phdr.p_type { PT_LOAD => { - let src = file.get(file_range) + let src = file + .get(file_range) .ok_or("program header requests an out of bounds load (in file)")?; - let dst = image.get_mut(phdr.p_vaddr as usize.. - (phdr.p_vaddr + phdr.p_filesz) as usize) + let dst = image + .get_mut(phdr.p_vaddr as usize..(phdr.p_vaddr + phdr.p_filesz) as usize) .ok_or("program header requests an out of bounds load (in target)")?; dst.copy_from_slice(src); } @@ -203,9 +215,9 @@ pub fn load( let shdr = shdr.ok_or("cannot read section header")?; match shdr.sh_type as usize { SHT_ARM_EXIDX => { - let range = shdr.sh_addr as usize.. - (shdr.sh_addr + shdr.sh_size) as usize; - let _ = image.get(range.clone()) + let range = shdr.sh_addr as usize..(shdr.sh_addr + shdr.sh_size) as usize; + let _ = image + .get(range.clone()) .ok_or("section header specifies EXIDX outside of image (in target)")?; exidx = Some(range); } @@ -214,11 +226,14 @@ pub fn load( } // relocate DYNAMIC - let dyn_range = file.dyn_header_vaddr() - .ok_or("cannot find a dynamic header")?; + let dyn_range = file.dyn_header_vaddr().ok_or("cannot find a dynamic header")?; let dyn_section = image.dyn_section(dyn_range.clone())?; - debug!("Relocating {} rela, {} rel, {} pltrel", - dyn_section.rela.len(), dyn_section.rel.len(), dyn_section.pltrel.len()); + debug!( + "Relocating {} rela, {} rel, {} pltrel", + dyn_section.rela.len(), + dyn_section.rel.len(), + dyn_section.pltrel.len() + ); let lib = Library { arch, image, diff --git a/src/libdyld/src/reloc.rs b/src/libdyld/src/reloc.rs index 93f4bbc..90b21fd 100644 --- a/src/libdyld/src/reloc.rs +++ b/src/libdyld/src/reloc.rs @@ -1,16 +1,10 @@ use alloc::string::String; + +use libcortex_a9::{asm::{dsb, isb}, + cache::{bpiall, dcci_slice, iciallu}}; use log::trace; -use super::{ - Arch, - elf::*, - Error, - image::Image, - Library, -}; -use libcortex_a9::{ - cache::{dcci_slice, iciallu, bpiall}, - asm::{dsb, isb}, -}; + +use super::{elf::*, image::Image, Arch, Error, Library}; pub trait Relocatable { fn offset(&self) -> usize; @@ -66,25 +60,18 @@ enum RelType { impl RelType { pub fn new(arch: Arch, type_info: u8) -> Option { match type_info { - R_OR1K_NONE if arch == Arch::OpenRisc => - Some(RelType::None), - R_ARM_NONE if arch == Arch::Arm => - Some(RelType::None), + R_OR1K_NONE if arch == Arch::OpenRisc => Some(RelType::None), + R_ARM_NONE if arch == Arch::Arm => Some(RelType::None), - R_OR1K_RELATIVE if arch == Arch::OpenRisc => - Some(RelType::Relative), - R_ARM_RELATIVE if arch == Arch::Arm => - Some(RelType::Relative), + R_OR1K_RELATIVE if arch == Arch::OpenRisc => Some(RelType::Relative), + R_ARM_RELATIVE if arch == Arch::Arm => Some(RelType::Relative), - R_OR1K_32 | R_OR1K_GLOB_DAT | R_OR1K_JMP_SLOT - if arch == Arch::OpenRisc => Some(RelType::LookupAbs), - R_ARM_GLOB_DAT | R_ARM_JUMP_SLOT | R_ARM_ABS32 - if arch == Arch::Arm => Some(RelType::LookupAbs), + R_OR1K_32 | R_OR1K_GLOB_DAT | R_OR1K_JMP_SLOT if arch == Arch::OpenRisc => Some(RelType::LookupAbs), + R_ARM_GLOB_DAT | R_ARM_JUMP_SLOT | R_ARM_ABS32 if arch == Arch::Arm => Some(RelType::LookupAbs), R_ARM_PREL31 if arch == Arch::Arm => Some(RelType::LookupRel), - _ => - None + _ => None, } } } @@ -96,22 +83,25 @@ fn format_sym_name(sym_name: &[u8]) -> String { } pub fn relocate( - arch: Arch, lib: &Library, - rel: &R, resolve: &dyn Fn(&[u8]) -> Option + arch: Arch, + lib: &Library, + rel: &R, + resolve: &dyn Fn(&[u8]) -> Option, ) -> Result<(), Error> { let sym; if rel.sym_info() == 0 { sym = None; } else { - sym = Some(lib.symtab().get(rel.sym_info() as usize) - .ok_or("symbol out of bounds of symbol table")?) + sym = Some( + lib.symtab() + .get(rel.sym_info() as usize) + .ok_or("symbol out of bounds of symbol table")?, + ) } - let rel_type = RelType::new(arch, rel.type_info()) - .ok_or("unsupported relocation type")?; + let rel_type = RelType::new(arch, rel.type_info()).ok_or("unsupported relocation type")?; let value = match rel_type { - RelType::None => - return Ok(()), + RelType::None => return Ok(()), RelType::Relative => { let addend = rel.addend(&lib.image); @@ -132,42 +122,48 @@ pub fn relocate( addr } else { // We couldn't find it anywhere. - return Err(Error::Lookup(format_sym_name(sym_name))) + return Err(Error::Lookup(format_sym_name(sym_name))); }; match rel_type { RelType::LookupAbs => sym_addr, - RelType::LookupRel => - sym_addr.wrapping_sub( - lib.image.ptr().wrapping_offset(rel.offset() as isize) as Elf32_Addr), - _ => unreachable!() + RelType::LookupRel => { + sym_addr.wrapping_sub(lib.image.ptr().wrapping_offset(rel.offset() as isize) as Elf32_Addr) + } + _ => unreachable!(), } } }; match rel.type_info() { R_ARM_PREL31 => { - let reloc_word = lib.image.get_ref::(rel.offset()) - .ok_or("relocation offset cannot be read")?; - lib.image.write(rel.offset(), (reloc_word & 0x80000000) | (value & 0x7FFFFFFF)) - }, + let reloc_word = lib + .image + .get_ref::(rel.offset()) + .ok_or("relocation offset cannot be read")?; + lib.image + .write(rel.offset(), (reloc_word & 0x80000000) | (value & 0x7FFFFFFF)) + } _ => lib.image.write(rel.offset(), value), } } -pub fn rebind( - arch: Arch, lib: &Library, name: &[u8], value: Elf32_Word -) -> Result<(), Error> { +pub fn rebind(arch: Arch, lib: &Library, name: &[u8], value: Elf32_Word) -> Result<(), Error> { fn rebind_symbol_to_value( - arch: Arch, lib: &Library,name: &[u8], value: Elf32_Word, relocs: &[R] + arch: Arch, + lib: &Library, + name: &[u8], + value: Elf32_Word, + relocs: &[R], ) -> Result<(), Error> { for reloc in relocs { - let rel_type = RelType::new(arch, reloc.type_info()) - .ok_or("unsupported relocation type")?; + let rel_type = RelType::new(arch, reloc.type_info()).ok_or("unsupported relocation type")?; match rel_type { RelType::LookupAbs => { - let sym = lib.symtab().get(reloc.sym_info() as usize) + let sym = lib + .symtab() + .get(reloc.sym_info() as usize) .ok_or("symbol out of bounds of symbol table")?; let sym_name = lib.name_starting_at(sym.st_name as usize)?; diff --git a/src/libio/cursor.rs b/src/libio/cursor.rs index c31c8da..50a5a09 100644 --- a/src/libio/cursor.rs +++ b/src/libio/cursor.rs @@ -1,9 +1,9 @@ -use core_io::{Read, Write, Error as IoError}; +use core_io::{Error as IoError, Read, Write}; #[derive(Debug, Clone)] pub struct Cursor { inner: T, - pos: usize + pos: usize, } impl Cursor { @@ -39,7 +39,6 @@ impl Cursor { } impl> Read for Cursor { - fn read(&mut self, buf: &mut [u8]) -> Result { let data = &self.inner.as_ref()[self.pos..]; let len = buf.len().min(data.len()); @@ -50,10 +49,9 @@ impl> Read for Cursor { } impl Write for Cursor<&mut [u8]> { - fn write(&mut self, buf: &[u8]) -> Result { let data = &mut self.inner[self.pos..]; - let len = buf.len().min(data.len()); + let len = buf.len().min(data.len()); data[..len].copy_from_slice(&buf[..len]); self.pos += len; Ok(len) @@ -67,7 +65,6 @@ impl Write for Cursor<&mut [u8]> { #[cfg(feature = "alloc")] impl Write for Cursor<::alloc::Vec> { - #[inline] fn write(&mut self, buf: &[u8]) -> Result { self.inner.extend_from_slice(buf); diff --git a/src/libio/lib.rs b/src/libio/lib.rs index e754be4..1010e24 100644 --- a/src/libio/lib.rs +++ b/src/libio/lib.rs @@ -16,7 +16,7 @@ pub mod cursor; pub mod proto; pub use cursor::Cursor; +#[cfg(all(feature = "byteorder", feature = "alloc"))] +pub use proto::ReadStringError; #[cfg(feature = "byteorder")] pub use proto::{ProtoRead, ProtoWrite}; -#[cfg(all(feature = "byteorder", feature = "alloc"))] -pub use proto::ReadStringError; \ No newline at end of file diff --git a/src/libio/proto.rs b/src/libio/proto.rs index c165606..cb24624 100644 --- a/src/libio/proto.rs +++ b/src/libio/proto.rs @@ -1,15 +1,14 @@ +use alloc::{string::String, vec}; use core::str::Utf8Error; -use byteorder::{ByteOrder, NativeEndian}; -use alloc::vec; -use alloc::string::String; -use core_io::{Read, Write, Error as IoError}; +use byteorder::{ByteOrder, NativeEndian}; +use core_io::{Error as IoError, Read, Write}; #[allow(dead_code)] #[derive(Debug, Clone, PartialEq)] pub enum ReadStringError { Utf8(Utf8Error), - Other(T) + Other(T), } pub trait ProtoRead { @@ -141,7 +140,9 @@ pub trait ProtoWrite { } } -impl ProtoRead for T where T: Read + ?Sized { +impl ProtoRead for T +where T: Read + ?Sized +{ type ReadError = IoError; fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Self::ReadError> { @@ -149,7 +150,9 @@ impl ProtoRead for T where T: Read + ?Sized { } } -impl ProtoWrite for T where T: Write + ?Sized { +impl ProtoWrite for T +where T: Write + ?Sized +{ type WriteError = IoError; fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::WriteError> { diff --git a/src/libunwind/backtrace.rs b/src/libunwind/backtrace.rs index 7ad0dd7..8ec66c0 100644 --- a/src/libunwind/backtrace.rs +++ b/src/libunwind/backtrace.rs @@ -1,27 +1,25 @@ -use libc::{c_void, c_int}; +use libc::{c_int, c_void}; + use crate::libunwind as uw; const UW_REG_SP: c_int = 13; pub fn backtrace(f: F) -> Result<(), uw::_Unwind_Reason_Code> - where F: FnMut(usize) -> () -{ +where F: FnMut(usize) -> () { struct TraceContext { step_fn: F, - prev_sp: uw::_Unwind_Word + prev_sp: uw::_Unwind_Word, } - extern fn trace(context: *mut uw::_Unwind_Context, arg: *mut c_void) - -> uw::_Unwind_Reason_Code - where F: FnMut(usize) -> () - { + extern "C" fn trace(context: *mut uw::_Unwind_Context, arg: *mut c_void) -> uw::_Unwind_Reason_Code + where F: FnMut(usize) -> () { unsafe { let trace_context = &mut *(arg as *mut TraceContext); // Detect the root of a libfringe thread let cur_sp = uw::_Unwind_GetGR(context, UW_REG_SP); if cur_sp == trace_context.prev_sp { - return uw::_URC_END_OF_STACK + return uw::_URC_END_OF_STACK; } else { trace_context.prev_sp = cur_sp; } @@ -35,7 +33,7 @@ pub fn backtrace(f: F) -> Result<(), uw::_Unwind_Reason_Code> let mut trace_context = TraceContext { step_fn: f, prev_sp: 0 }; match uw::_Unwind_Backtrace(trace::, &mut trace_context as *mut _ as *mut c_void) { uw::_URC_NO_REASON => Ok(()), - err => Err(err) + err => Err(err), } } } diff --git a/src/libunwind/build.rs b/src/libunwind/build.rs index 0c06c67..fe33bdd 100644 --- a/src/libunwind/build.rs +++ b/src/libunwind/build.rs @@ -5,8 +5,7 @@ fn main() { } mod llvm_libunwind { - use std::path::Path; - use std::env; + use std::{env, path::Path}; fn setup_options(cfg: &mut cc::Build) { cfg.no_default_flags(true); @@ -82,11 +81,7 @@ mod llvm_libunwind { cfg.flag("-fvisibility=hidden"); cfg.flag_if_supported("-fvisibility-global-new-delete-hidden"); - let unwind_sources = vec![ - "Unwind-EHABI.cpp", - "Unwind-seh.cpp", - "libunwind.cpp" - ]; + let unwind_sources = vec!["Unwind-EHABI.cpp", "Unwind-seh.cpp", "libunwind.cpp"]; let root = Path::new("../llvm_libunwind"); cfg.include(root.join("include")); diff --git a/src/libunwind/libunwind.rs b/src/libunwind/libunwind.rs index 24fce7d..0f0e457 100644 --- a/src/libunwind/libunwind.rs +++ b/src/libunwind/libunwind.rs @@ -21,8 +21,7 @@ pub use _Unwind_Reason_Code::*; pub type _Unwind_Exception_Class = u64; pub type _Unwind_Word = uintptr_t; pub type _Unwind_Ptr = uintptr_t; -pub type _Unwind_Trace_Fn = - extern "C" fn(ctx: *mut _Unwind_Context, arg: *mut c_void) -> _Unwind_Reason_Code; +pub type _Unwind_Trace_Fn = extern "C" fn(ctx: *mut _Unwind_Context, arg: *mut c_void) -> _Unwind_Reason_Code; #[cfg(target_arch = "x86")] pub const unwinder_private_data_size: usize = 5; @@ -279,7 +278,6 @@ if #[cfg(all(windows, target_arch = "x86_64", target_env = "gnu"))] { } // cfg_if! #[no_mangle] -extern fn abort() { +extern "C" fn abort() { panic!("Abort!"); } - diff --git a/src/runtime/src/analyzer.rs b/src/runtime/src/analyzer.rs index 20fbd9b..532fb30 100644 --- a/src/runtime/src/analyzer.rs +++ b/src/runtime/src/analyzer.rs @@ -3,8 +3,7 @@ use libboard_zynq::smoltcp::Error; use libcortex_a9::cache; use log::{debug, info, warn}; -use crate::proto_async::*; -use crate::pl; +use crate::{pl, proto_async::*}; const BUFFER_SIZE: usize = 512 * 1024; @@ -13,9 +12,7 @@ struct Buffer { data: [u8; BUFFER_SIZE], } -static mut BUFFER: Buffer = Buffer { - data: [0; BUFFER_SIZE] -}; +static mut BUFFER: Buffer = Buffer { data: [0; BUFFER_SIZE] }; fn arm() { debug!("arming RTIO analyzer"); @@ -46,7 +43,7 @@ struct Header { total_byte_count: u64, error_occurred: bool, log_channel: u8, - dds_onehot_sel: bool + dds_onehot_sel: bool, } async fn write_header(stream: &mut TcpStream, header: &Header) -> Result<(), Error> { @@ -78,10 +75,14 @@ async fn handle_connection(stream: &mut TcpStream) -> Result<(), Error> { let header = Header { total_byte_count: total_byte_count, - sent_bytes: if wraparound { BUFFER_SIZE as u32 } else { total_byte_count as u32 }, + sent_bytes: if wraparound { + BUFFER_SIZE as u32 + } else { + total_byte_count as u32 + }, error_occurred: overflow_occurred | bus_error_occurred, log_channel: pl::csr::CONFIG_RTIO_LOG_CHANNEL as u8, - dds_onehot_sel: true // kept for backward compatibility of analyzer dumps + dds_onehot_sel: true, // kept for backward compatibility of analyzer dumps }; debug!("{:?}", header); diff --git a/src/runtime/src/comms.rs b/src/runtime/src/comms.rs index e14e7c6..1465d77 100644 --- a/src/runtime/src/comms.rs +++ b/src/runtime/src/comms.rs @@ -1,39 +1,33 @@ -use core::{fmt, slice, str}; -use core::cell::RefCell; -use alloc::{vec, vec::Vec, string::String, collections::BTreeMap, rc::Rc}; -use log::{info, warn, error}; +use alloc::{collections::BTreeMap, rc::Rc, string::String, vec, vec::Vec}; +use core::{cell::RefCell, fmt, slice, str}; + use cslice::CSlice; - -use num_derive::{FromPrimitive, ToPrimitive}; -use num_traits::{FromPrimitive, ToPrimitive}; - -use libboard_zynq::{ - self as zynq, - smoltcp::{ - self, - wire::IpCidr, - iface::{NeighborCache, EthernetInterfaceBuilder}, - time::Instant, - }, - timer::GlobalTimer, -}; -use libcortex_a9::{semaphore::Semaphore, mutex::Mutex, sync_channel::{Sender, Receiver}}; -use futures::{select_biased, future::FutureExt}; -use libasync::{smoltcp::{Sockets, TcpStream}, task}; -use libconfig::{Config, net_settings}; +use futures::{future::FutureExt, select_biased}; +use libasync::{smoltcp::{Sockets, TcpStream}, + task}; use libboard_artiq::drtio_routing; #[cfg(feature = "target_kasli_soc")] use libboard_zynq::error_led::ErrorLED; +use libboard_zynq::{self as zynq, + smoltcp::{self, + iface::{EthernetInterfaceBuilder, NeighborCache}, + time::Instant, + wire::IpCidr}, + timer::GlobalTimer}; +use libconfig::{net_settings, Config}; +use libcortex_a9::{mutex::Mutex, + semaphore::Semaphore, + sync_channel::{Receiver, Sender}}; +use log::{error, info, warn}; +use num_derive::{FromPrimitive, ToPrimitive}; +use num_traits::{FromPrimitive, ToPrimitive}; -use crate::proto_async::*; -use crate::kernel; -use crate::rpc; -use crate::moninj; -use crate::mgmt; -use crate::analyzer; -use crate::rtio_mgt::{self, resolve_channel_name}; #[cfg(has_drtio)] use crate::pl; +use crate::{analyzer, kernel, mgmt, moninj, + proto_async::*, + rpc, + rtio_mgt::{self, resolve_channel_name}}; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Error { @@ -49,9 +43,9 @@ impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Error::NetworkError(error) => write!(f, "network error: {}", error), - Error::UnexpectedPattern => write!(f, "unexpected pattern"), - Error::UnrecognizedPacket => write!(f, "unrecognized packet"), - Error::BufferExhausted => write!(f, "buffer exhausted"), + Error::UnexpectedPattern => write!(f, "unexpected pattern"), + Error::UnrecognizedPacket => write!(f, "unrecognized packet"), + Error::BufferExhausted => write!(f, "buffer exhausted"), } } } @@ -88,15 +82,16 @@ static CACHE_STORE: Mutex>> = Mutex::new(BTreeMap::new static DMA_RECORD_STORE: Mutex, i64)>> = Mutex::new(BTreeMap::new()); async fn write_header(stream: &TcpStream, reply: Reply) -> Result<()> { - stream.send_slice(&[0x5a, 0x5a, 0x5a, 0x5a, reply.to_u8().unwrap()]).await?; + stream + .send_slice(&[0x5a, 0x5a, 0x5a, 0x5a, reply.to_u8().unwrap()]) + .await?; Ok(()) } async fn read_request(stream: &TcpStream, allow_close: bool) -> Result> { match expect(stream, &[0x5a, 0x5a, 0x5a, 0x5a]).await { Ok(true) => {} - Ok(false) => - return Err(Error::UnexpectedPattern), + Ok(false) => return Err(Error::UnexpectedPattern), Err(smoltcp::Error::Finished) => { if allow_close { info!("peer closed connection"); @@ -105,11 +100,12 @@ async fn read_request(stream: &TcpStream, allow_close: bool) -> Result - return Err(e)?, + } + Err(e) => return Err(e)?, } - Ok(Some(FromPrimitive::from_i8(read_i8(&stream).await?).ok_or(Error::UnrecognizedPacket)?)) + Ok(Some( + FromPrimitive::from_i8(read_i8(&stream).await?).ok_or(Error::UnrecognizedPacket)?, + )) } async fn read_bytes(stream: &TcpStream, max_length: usize) -> Result> { @@ -128,9 +124,7 @@ async fn fast_send(sender: &mut Sender<'_, kernel::Message>, content: kernel::Me let mut content = content; for _ in 0..RETRY_LIMIT { match sender.try_send(content) { - Ok(()) => { - return - }, + Ok(()) => return, Err(v) => { content = v; } @@ -142,10 +136,8 @@ async fn fast_send(sender: &mut Sender<'_, kernel::Message>, content: kernel::Me async fn fast_recv(receiver: &mut Receiver<'_, kernel::Message>) -> kernel::Message { for _ in 0..RETRY_LIMIT { match receiver.try_recv() { - Ok(v) => { - return v; - }, - Err(()) => () + Ok(v) => return v, + Err(()) => (), } } receiver.async_recv().await @@ -161,7 +153,11 @@ async fn write_exception_string(stream: &TcpStream, s: CSlice<'static, u8>) -> R Ok(()) } -async fn handle_run_kernel(stream: Option<&TcpStream>, control: &Rc>, _up_destinations: &Rc>) -> Result<()> { +async fn handle_run_kernel( + stream: Option<&TcpStream>, + control: &Rc>, + _up_destinations: &Rc>, +) -> Result<()> { control.borrow_mut().tx.async_send(kernel::Message::StartRequest).await; loop { let reply = control.borrow_mut().rx.async_recv().await; @@ -169,7 +165,7 @@ async fn handle_run_kernel(stream: Option<&TcpStream>, control: &Rc { if stream.is_none() { error!("Unexpected RPC from startup/idle kernel!"); - break + break; } let stream = stream.unwrap(); write_header(stream, Reply::RPCRequest).await?; @@ -196,46 +192,64 @@ async fn handle_run_kernel(stream: Option<&TcpStream>, control: &Rc slot, - other => panic!("expected nested value slot from kernel CPU, not {:?}", other), + other => { + panic!("expected nested value slot from kernel CPU, not {:?}", other) + } } } } - }).await?; - control.borrow_mut().tx.async_send(kernel::Message::RpcRecvReply(Ok(0))).await; - }, + }) + .await?; + control + .borrow_mut() + .tx + .async_send(kernel::Message::RpcRecvReply(Ok(0))) + .await; + } Request::RPCException => { let mut control = control.borrow_mut(); match control.rx.async_recv().await { kernel::Message::RpcRecvRequest(_) => (), other => panic!("expected (ignored) root value slot from kernel CPU, not {:?}", other), } - let id = read_i32(stream).await? as u32; - let message = read_i32(stream).await? as u32; - let param = [read_i64(stream).await?, - read_i64(stream).await?, - read_i64(stream).await?]; - let file = read_i32(stream).await? as u32; - let line = read_i32(stream).await?; - let column = read_i32(stream).await?; + let id = read_i32(stream).await? as u32; + let message = read_i32(stream).await? as u32; + let param = [ + read_i64(stream).await?, + read_i64(stream).await?, + read_i64(stream).await?, + ]; + let file = read_i32(stream).await? as u32; + let line = read_i32(stream).await?; + let column = read_i32(stream).await?; let function = read_i32(stream).await? as u32; - control.tx.async_send(kernel::Message::RpcRecvReply(Err(kernel::RPCException { - id, message, param, file, line, column, function - }))).await; - }, + control + .tx + .async_send(kernel::Message::RpcRecvReply(Err(kernel::RPCException { + id, + message, + param, + file, + line, + column, + function, + }))) + .await; + } _ => { error!("unexpected RPC request from host: {:?}", host_request); - return Err(Error::UnrecognizedPacket) + return Err(Error::UnrecognizedPacket); } } } - }, + } kernel::Message::KernelFinished(async_errors) => { if let Some(stream) = stream { write_header(stream, Reply::KernelFinished).await?; write_i8(stream, async_errors as i8).await?; } break; - }, + } kernel::Message::KernelException(exceptions, stack_pointers, backtrace, async_errors) => { match stream { Some(stream) => { @@ -247,12 +261,22 @@ async fn handle_run_kernel(stream: Option<&TcpStream>, control: &Rc, control: &Rc { error!("Uncaught kernel exceptions: {:?}", exceptions); } @@ -284,27 +308,41 @@ async fn handle_run_kernel(stream: Option<&TcpStream>, control: &Rc { CACHE_STORE.lock().insert(key, value); - }, + } kernel::Message::CacheGetRequest(key) => { const DEFAULT: Vec = Vec::new(); let value = CACHE_STORE.lock().get(&key).unwrap_or(&DEFAULT).clone(); - control.borrow_mut().tx.async_send(kernel::Message::CacheGetReply(value)).await; - }, + control + .borrow_mut() + .tx + .async_send(kernel::Message::CacheGetReply(value)) + .await; + } kernel::Message::DmaPutRequest(recorder) => { - DMA_RECORD_STORE.lock().insert(recorder.name, (recorder.buffer, recorder.duration)); - }, + DMA_RECORD_STORE + .lock() + .insert(recorder.name, (recorder.buffer, recorder.duration)); + } kernel::Message::DmaEraseRequest(name) => { // prevent possible OOM when we have large DMA record replacement. DMA_RECORD_STORE.lock().remove(&name); - }, + } kernel::Message::DmaGetRequest(name) => { let result = DMA_RECORD_STORE.lock().get(&name).map(|v| v.clone()); - control.borrow_mut().tx.async_send(kernel::Message::DmaGetReply(result)).await; - }, + control + .borrow_mut() + .tx + .async_send(kernel::Message::DmaGetReply(result)) + .await; + } #[cfg(has_drtio)] kernel::Message::UpDestinationsRequest(destination) => { let result = _up_destinations.borrow()[destination as usize]; - control.borrow_mut().tx.async_send(kernel::Message::UpDestinationsReply(result)).await; + control + .borrow_mut() + .tx + .async_send(kernel::Message::UpDestinationsReply(result)) + .await; } _ => { panic!("unexpected message from core1 while kernel was running: {:?}", reply); @@ -314,11 +352,17 @@ async fn handle_run_kernel(stream: Option<&TcpStream>, control: &Rc, control: &Rc>, stream: Option<&TcpStream>) -> Result<()> { +async fn load_kernel( + buffer: &Vec, + control: &Rc>, + stream: Option<&TcpStream>, +) -> Result<()> { let mut control = control.borrow_mut(); control.restart(); - control.tx.async_send(kernel::Message::LoadRequest(buffer.to_vec())).await; + control + .tx + .async_send(kernel::Message::LoadRequest(buffer.to_vec())) + .await; let reply = control.rx.async_recv().await; match reply { kernel::Message::LoadCompleted => { @@ -326,7 +370,7 @@ async fn load_kernel(buffer: &Vec, control: &Rc>, s write_header(stream, Reply::LoadCompleted).await?; } Ok(()) - }, + } kernel::Message::LoadFailed => { if let Some(stream) = stream { write_header(stream, Reply::LoadFailed).await?; @@ -335,7 +379,7 @@ async fn load_kernel(buffer: &Vec, control: &Rc>, s error!("Kernel load failed"); } Err(Error::UnexpectedPattern) - }, + } _ => { error!("unexpected message from core1: {:?}", reply); if let Some(stream) = stream { @@ -347,7 +391,11 @@ async fn load_kernel(buffer: &Vec, control: &Rc>, s } } -async fn handle_connection(stream: &mut TcpStream, control: Rc>, up_destinations: &Rc>) -> Result<()> { +async fn handle_connection( + stream: &mut TcpStream, + control: Rc>, + up_destinations: &Rc>, +) -> Result<()> { stream.set_ack_delay(None); if !expect(stream, b"ARTIQ coredev\n").await? { @@ -364,17 +412,17 @@ async fn handle_connection(stream: &mut TcpStream, control: Rc { write_header(stream, Reply::SystemInfo).await?; stream.send_slice("ARZQ".as_bytes()).await?; - }, + } Request::LoadKernel => { - let buffer = read_bytes(stream, 1024*1024).await?; + let buffer = read_bytes(stream, 1024 * 1024).await?; load_kernel(&buffer, &control, Some(stream)).await?; - }, + } Request::RunKernel => { handle_run_kernel(Some(stream), &control, &up_destinations).await?; - }, + } _ => { error!("unexpected request from host: {:?}", request); - return Err(Error::UnrecognizedPacket) + return Err(Error::UnrecognizedPacket); } } } @@ -398,24 +446,24 @@ pub fn main(timer: GlobalTimer, cfg: Config) { let ip_addrs = [ IpCidr::new(net_addresses.ipv4_addr, 0), IpCidr::new(net_addresses.ipv6_ll_addr, 0), - IpCidr::new(addr, 0) + IpCidr::new(addr, 0), ]; EthernetInterfaceBuilder::new(&mut eth) - .ethernet_addr(net_addresses.hardware_addr) - .ip_addrs(ip_addrs) - .neighbor_cache(neighbor_cache) - .finalize() + .ethernet_addr(net_addresses.hardware_addr) + .ip_addrs(ip_addrs) + .neighbor_cache(neighbor_cache) + .finalize() } None => { let ip_addrs = [ IpCidr::new(net_addresses.ipv4_addr, 0), - IpCidr::new(net_addresses.ipv6_ll_addr, 0) + IpCidr::new(net_addresses.ipv6_ll_addr, 0), ]; EthernetInterfaceBuilder::new(&mut eth) - .ethernet_addr(net_addresses.hardware_addr) - .ip_addrs(ip_addrs) - .neighbor_cache(neighbor_cache) - .finalize() + .ethernet_addr(net_addresses.hardware_addr) + .ip_addrs(ip_addrs) + .neighbor_cache(neighbor_cache) + .finalize() } }; @@ -424,8 +472,10 @@ pub fn main(timer: GlobalTimer, cfg: Config) { // before, mutex was on io, but now that io isn't used...? let aux_mutex: Rc> = Rc::new(Mutex::new(false)); #[cfg(has_drtio)] - let drtio_routing_table = Rc::new(RefCell::new( - drtio_routing::config_routing_table(pl::csr::DRTIO.len(), &cfg))); + let drtio_routing_table = Rc::new(RefCell::new(drtio_routing::config_routing_table( + pl::csr::DRTIO.len(), + &cfg, + ))); #[cfg(not(has_drtio))] let drtio_routing_table = Rc::new(RefCell::new(drtio_routing::RoutingTable::default_empty())); let up_destinations = Rc::new(RefCell::new([false; drtio_routing::DEST_COUNT])); @@ -497,14 +547,10 @@ pub fn main(timer: GlobalTimer, cfg: Config) { } }); - Sockets::run(&mut iface, || { - Instant::from_millis(timer.get_time().0 as i32) - }); + Sockets::run(&mut iface, || Instant::from_millis(timer.get_time().0 as i32)); } - pub fn soft_panic_main(timer: GlobalTimer, cfg: Config) -> ! { - let net_addresses = net_settings::get_addresses(&cfg); info!("network addresses: {}", net_addresses); @@ -522,24 +568,24 @@ pub fn soft_panic_main(timer: GlobalTimer, cfg: Config) -> ! { let ip_addrs = [ IpCidr::new(net_addresses.ipv4_addr, 0), IpCidr::new(net_addresses.ipv6_ll_addr, 0), - IpCidr::new(addr, 0) + IpCidr::new(addr, 0), ]; EthernetInterfaceBuilder::new(&mut eth) - .ethernet_addr(net_addresses.hardware_addr) - .ip_addrs(ip_addrs) - .neighbor_cache(neighbor_cache) - .finalize() + .ethernet_addr(net_addresses.hardware_addr) + .ip_addrs(ip_addrs) + .neighbor_cache(neighbor_cache) + .finalize() } None => { let ip_addrs = [ IpCidr::new(net_addresses.ipv4_addr, 0), - IpCidr::new(net_addresses.ipv6_ll_addr, 0) + IpCidr::new(net_addresses.ipv6_ll_addr, 0), ]; EthernetInterfaceBuilder::new(&mut eth) - .ethernet_addr(net_addresses.hardware_addr) - .ip_addrs(ip_addrs) - .neighbor_cache(neighbor_cache) - .finalize() + .ethernet_addr(net_addresses.hardware_addr) + .ip_addrs(ip_addrs) + .neighbor_cache(neighbor_cache) + .finalize() } }; @@ -555,7 +601,5 @@ pub fn soft_panic_main(timer: GlobalTimer, cfg: Config) -> ! { err_led.toggle(true); } - Sockets::run(&mut iface, || { - Instant::from_millis(timer.get_time().0 as i32) - }); -} \ No newline at end of file + Sockets::run(&mut iface, || Instant::from_millis(timer.get_time().0 as i32)); +} diff --git a/src/runtime/src/eh_artiq.rs b/src/runtime/src/eh_artiq.rs index 9696201..5db3aad 100644 --- a/src/runtime/src/eh_artiq.rs +++ b/src/runtime/src/eh_artiq.rs @@ -13,14 +13,14 @@ #![allow(non_camel_case_types)] use core::mem; + use cslice::CSlice; -use unwind as uw; -use libc::{c_int, c_void, uintptr_t}; -use log::{trace, error}; -use crate::kernel::KERNEL_IMAGE; - use dwarf::eh::{self, EHAction, EHContext}; +use libc::{c_int, c_void, uintptr_t}; +use log::{error, trace}; +use unwind as uw; +use crate::kernel::KERNEL_IMAGE; const EXCEPTION_CLASS: uw::_Unwind_Exception_Class = 0x4d_4c_42_53_41_52_54_51; /* 'MLBSARTQ' */ @@ -32,13 +32,13 @@ const UNWIND_DATA_REG: (i32, i32) = (0, 1); // R0, R1 #[repr(C)] #[derive(Clone, Copy)] pub struct Exception<'a> { - pub id: u32, - pub file: CSlice<'a, u8>, - pub line: u32, - pub column: u32, + pub id: u32, + pub file: CSlice<'a, u8>, + pub line: u32, + pub column: u32, pub function: CSlice<'a, u8>, - pub message: CSlice<'a, u8>, - pub param: [i64; 3] + pub message: CSlice<'a, u8>, + pub param: [i64; 3], } fn str_err(_: core::str::Utf8Error) -> core::fmt::Error { @@ -55,12 +55,16 @@ fn exception_str<'a>(s: &'a CSlice<'a, u8>) -> Result<&'a str, core::str::Utf8Er impl<'a> core::fmt::Debug for Exception<'a> { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - write!(f, "Exception {} from {} in {}:{}:{}, message: {}", + write!( + f, + "Exception {} from {} in {}:{}:{}, message: {}", self.id, exception_str(&self.function).map_err(str_err)?, exception_str(&self.file).map_err(str_err)?, - self.line, self.column, - exception_str(&self.message).map_err(str_err)?) + self.line, + self.column, + exception_str(&self.message).map_err(str_err)? + ) } } @@ -91,9 +95,9 @@ struct ExceptionBuffer { static mut EXCEPTION_BUFFER: ExceptionBuffer = ExceptionBuffer { uw_exceptions: [uw::_Unwind_Exception { - exception_class: EXCEPTION_CLASS, + exception_class: EXCEPTION_CLASS, exception_cleanup: cleanup, - private: [0; uw::unwinder_private_data_size], + private: [0; uw::unwinder_private_data_size], }; MAX_INFLIGHT_EXCEPTIONS], exceptions: [None; MAX_INFLIGHT_EXCEPTIONS + 1], exception_stack: [-1; MAX_INFLIGHT_EXCEPTIONS + 1], @@ -102,17 +106,17 @@ static mut EXCEPTION_BUFFER: ExceptionBuffer = ExceptionBuffer { stack_pointers: [StackPointerBacktrace { stack_pointer: 0, initial_backtrace_size: 0, - current_backtrace_size: 0 + current_backtrace_size: 0, }; MAX_INFLIGHT_EXCEPTIONS + 1], - exception_count: 0 + exception_count: 0, }; -pub unsafe extern fn reset_exception_buffer() { +pub unsafe extern "C" fn reset_exception_buffer() { trace!("reset exception buffer"); EXCEPTION_BUFFER.uw_exceptions = [uw::_Unwind_Exception { - exception_class: EXCEPTION_CLASS, + exception_class: EXCEPTION_CLASS, exception_cleanup: cleanup, - private: [0; uw::unwinder_private_data_size], + private: [0; uw::unwinder_private_data_size], }; MAX_INFLIGHT_EXCEPTIONS]; EXCEPTION_BUFFER.exceptions = [None; MAX_INFLIGHT_EXCEPTIONS + 1]; EXCEPTION_BUFFER.exception_stack = [-1; MAX_INFLIGHT_EXCEPTIONS + 1]; @@ -120,26 +124,25 @@ pub unsafe extern fn reset_exception_buffer() { EXCEPTION_BUFFER.exception_count = 0; } -type _Unwind_Stop_Fn = extern "C" fn(version: c_int, - actions: i32, - exception_class: uw::_Unwind_Exception_Class, - exception_object: *mut uw::_Unwind_Exception, - context: *mut uw::_Unwind_Context, - stop_parameter: *mut c_void) - -> uw::_Unwind_Reason_Code; +type _Unwind_Stop_Fn = extern "C" fn( + version: c_int, + actions: i32, + exception_class: uw::_Unwind_Exception_Class, + exception_object: *mut uw::_Unwind_Exception, + context: *mut uw::_Unwind_Context, + stop_parameter: *mut c_void, +) -> uw::_Unwind_Reason_Code; -extern { +extern "C" { // not defined in EHABI, but LLVM added it and is useful to us - fn _Unwind_ForcedUnwind(exception: *mut uw::_Unwind_Exception, - stop_fn: _Unwind_Stop_Fn, - stop_parameter: *mut c_void) -> uw::_Unwind_Reason_Code; + fn _Unwind_ForcedUnwind( + exception: *mut uw::_Unwind_Exception, + stop_fn: _Unwind_Stop_Fn, + stop_parameter: *mut c_void, + ) -> uw::_Unwind_Reason_Code; } -unsafe fn find_eh_action( - context: *mut uw::_Unwind_Context, - foreign_exception: bool, - id: u32, -) -> Result { +unsafe fn find_eh_action(context: *mut uw::_Unwind_Context, foreign_exception: bool, id: u32) -> Result { let lsda = uw::_Unwind_GetLanguageSpecificData(context) as *const u8; let mut ip_before_instr: c_int = 0; let ip = uw::_Unwind_GetIPInfo(context, &mut ip_before_instr); @@ -154,10 +157,11 @@ unsafe fn find_eh_action( eh::find_eh_action(lsda, &eh_context, foreign_exception, id) } -pub unsafe fn artiq_personality(_state: uw::_Unwind_State, - exception_object: *mut uw::_Unwind_Exception, - context: *mut uw::_Unwind_Context) - -> uw::_Unwind_Reason_Code { +pub unsafe fn artiq_personality( + _state: uw::_Unwind_State, + exception_object: *mut uw::_Unwind_Exception, + context: *mut uw::_Unwind_Context, +) -> uw::_Unwind_Reason_Code { // we will only do phase 2 forced unwinding now // The DWARF unwinder assumes that _Unwind_Context holds things like the function // and LSDA pointers, however ARM EHABI places them into the exception object. @@ -165,9 +169,7 @@ pub unsafe fn artiq_personality(_state: uw::_Unwind_State, // take only the context pointer, GCC personality routines stash a pointer to // exception_object in the context, using location reserved for ARM's // "scratch register" (r12). - uw::_Unwind_SetGR(context, - uw::UNWIND_POINTER_REG, - exception_object as uw::_Unwind_Ptr); + uw::_Unwind_SetGR(context, uw::UNWIND_POINTER_REG, exception_object as uw::_Unwind_Ptr); // ...A more principled approach would be to provide the full definition of ARM's // _Unwind_Context in our libunwind bindings and fetch the required data from there // directly, bypassing DWARF compatibility functions. @@ -186,10 +188,8 @@ pub unsafe fn artiq_personality(_state: uw::_Unwind_State, }; match eh_action { EHAction::None => return continue_unwind(exception_object, context), - EHAction::Cleanup(lpad) | - EHAction::Catch(lpad) => { - uw::_Unwind_SetGR(context, UNWIND_DATA_REG.0, - exception_object as uintptr_t); + EHAction::Cleanup(lpad) | EHAction::Catch(lpad) => { + uw::_Unwind_SetGR(context, UNWIND_DATA_REG.0, exception_object as uintptr_t); uw::_Unwind_SetGR(context, UNWIND_DATA_REG.1, exception as *const _ as uw::_Unwind_Word); uw::_Unwind_SetIP(context, lpad); return uw::_URC_INSTALL_CONTEXT; @@ -199,9 +199,10 @@ pub unsafe fn artiq_personality(_state: uw::_Unwind_State, // On ARM EHABI the personality routine is responsible for actually // unwinding a single stack frame before returning (ARM EHABI Sec. 6.1). - unsafe fn continue_unwind(exception_object: *mut uw::_Unwind_Exception, - context: *mut uw::_Unwind_Context) - -> uw::_Unwind_Reason_Code { + unsafe fn continue_unwind( + exception_object: *mut uw::_Unwind_Exception, + context: *mut uw::_Unwind_Context, + ) -> uw::_Unwind_Reason_Code { let reason = __gnu_unwind_frame(exception_object, context); if reason == uw::_URC_NO_REASON { uw::_URC_CONTINUE_UNWIND @@ -211,13 +212,14 @@ pub unsafe fn artiq_personality(_state: uw::_Unwind_State, } // defined in libgcc extern "C" { - fn __gnu_unwind_frame(exception_object: *mut uw::_Unwind_Exception, - context: *mut uw::_Unwind_Context) - -> uw::_Unwind_Reason_Code; + fn __gnu_unwind_frame( + exception_object: *mut uw::_Unwind_Exception, + context: *mut uw::_Unwind_Context, + ) -> uw::_Unwind_Reason_Code; } } -pub unsafe extern fn raise(exception: *const Exception) -> ! { +pub unsafe extern "C" fn raise(exception: *const Exception) -> ! { use cslice::AsCSlice; let count = EXCEPTION_BUFFER.exception_count; @@ -244,8 +246,11 @@ pub unsafe extern fn raise(exception: *const Exception) -> ! { } } assert!(found); - let _result = _Unwind_ForcedUnwind(&mut EXCEPTION_BUFFER.uw_exceptions[stack[count - 1] as usize], - stop_fn, core::ptr::null_mut()); + let _result = _Unwind_ForcedUnwind( + &mut EXCEPTION_BUFFER.uw_exceptions[stack[count - 1] as usize], + stop_fn, + core::ptr::null_mut(), + ); } else { if count < MAX_INFLIGHT_EXCEPTIONS { trace!("raising exception at level {}", count); @@ -253,34 +258,33 @@ pub unsafe extern fn raise(exception: *const Exception) -> ! { for (i, slot) in EXCEPTION_BUFFER.exceptions.iter_mut().enumerate() { // we should always be able to find a slot if slot.is_none() { - *slot = Some( - *mem::transmute::<*const Exception, *const Exception<'static>> - (exception)); + *slot = Some(*mem::transmute::<*const Exception, *const Exception<'static>>( + exception, + )); EXCEPTION_BUFFER.exception_stack[count] = i as isize; - EXCEPTION_BUFFER.uw_exceptions[i].private = - [0; uw::unwinder_private_data_size]; + EXCEPTION_BUFFER.uw_exceptions[i].private = [0; uw::unwinder_private_data_size]; EXCEPTION_BUFFER.stack_pointers[i] = StackPointerBacktrace { stack_pointer: 0, initial_backtrace_size: EXCEPTION_BUFFER.backtrace_size, current_backtrace_size: 0, }; EXCEPTION_BUFFER.exception_count += 1; - let _result = _Unwind_ForcedUnwind(&mut EXCEPTION_BUFFER.uw_exceptions[i], - stop_fn, core::ptr::null_mut()); + let _result = + _Unwind_ForcedUnwind(&mut EXCEPTION_BUFFER.uw_exceptions[i], stop_fn, core::ptr::null_mut()); } } } else { error!("too many nested exceptions"); // TODO: better reporting? let exception = Exception { - id: get_exception_id("RuntimeError"), - file: file!().as_c_slice(), - line: line!(), - column: column!(), + id: get_exception_id("RuntimeError"), + file: file!().as_c_slice(), + line: line!(), + column: column!(), // https://github.com/rust-lang/rfcs/pull/1719 function: "__artiq_raise".as_c_slice(), - message: "too many nested exceptions".as_c_slice(), - param: [0, 0, 0] + message: "too many nested exceptions".as_c_slice(), + param: [0, 0, 0], }; EXCEPTION_BUFFER.exceptions[MAX_INFLIGHT_EXCEPTIONS] = Some(mem::transmute(exception)); EXCEPTION_BUFFER.stack_pointers[MAX_INFLIGHT_EXCEPTIONS] = Default::default(); @@ -291,17 +295,20 @@ pub unsafe extern fn raise(exception: *const Exception) -> ! { unreachable!(); } -pub unsafe extern fn resume() -> ! { +pub unsafe extern "C" fn resume() -> ! { trace!("resume"); assert!(EXCEPTION_BUFFER.exception_count != 0); let i = EXCEPTION_BUFFER.exception_stack[EXCEPTION_BUFFER.exception_count - 1]; assert!(i != -1); - let _result = _Unwind_ForcedUnwind(&mut EXCEPTION_BUFFER.uw_exceptions[i as usize], - stop_fn, core::ptr::null_mut()); + let _result = _Unwind_ForcedUnwind( + &mut EXCEPTION_BUFFER.uw_exceptions[i as usize], + stop_fn, + core::ptr::null_mut(), + ); unreachable!() } -pub unsafe extern fn end_catch() { +pub unsafe extern "C" fn end_catch() { let mut count = EXCEPTION_BUFFER.exception_count; assert!(count != 0); // we remove all exceptions with SP <= current exception SP @@ -309,8 +316,7 @@ pub unsafe extern fn end_catch() { let index = EXCEPTION_BUFFER.exception_stack[count - 1] as usize; EXCEPTION_BUFFER.exception_stack[count - 1] = -1; EXCEPTION_BUFFER.exceptions[index] = None; - let outer_sp = EXCEPTION_BUFFER.stack_pointers - [index].stack_pointer; + let outer_sp = EXCEPTION_BUFFER.stack_pointers[index].stack_pointer; count -= 1; for i in (0..count).rev() { let index = EXCEPTION_BUFFER.exception_stack[i]; @@ -334,8 +340,7 @@ pub unsafe extern fn end_catch() { }; } -extern fn cleanup(_unwind_code: uw::_Unwind_Reason_Code, - _uw_exception: *mut uw::_Unwind_Exception) { +extern "C" fn cleanup(_unwind_code: uw::_Unwind_Reason_Code, _uw_exception: *mut uw::_Unwind_Exception) { unimplemented!() } @@ -345,18 +350,26 @@ fn uncaught_exception() -> ! { for i in 0..EXCEPTION_BUFFER.exception_count { if EXCEPTION_BUFFER.exception_stack[i] != i as isize { // find the correct index - let index = EXCEPTION_BUFFER.exception_stack + let index = EXCEPTION_BUFFER + .exception_stack .iter() - .position(|v| *v == i as isize).unwrap(); + .position(|v| *v == i as isize) + .unwrap(); let a = EXCEPTION_BUFFER.exception_stack[index]; let b = EXCEPTION_BUFFER.exception_stack[i]; assert!(a != -1 && b != -1); - core::mem::swap(&mut EXCEPTION_BUFFER.exception_stack[index], - &mut EXCEPTION_BUFFER.exception_stack[i]); - core::mem::swap(&mut EXCEPTION_BUFFER.exceptions[a as usize], - &mut EXCEPTION_BUFFER.exceptions[b as usize]); - core::mem::swap(&mut EXCEPTION_BUFFER.stack_pointers[a as usize], - &mut EXCEPTION_BUFFER.stack_pointers[b as usize]); + core::mem::swap( + &mut EXCEPTION_BUFFER.exception_stack[index], + &mut EXCEPTION_BUFFER.exception_stack[i], + ); + core::mem::swap( + &mut EXCEPTION_BUFFER.exceptions[a as usize], + &mut EXCEPTION_BUFFER.exceptions[b as usize], + ); + core::mem::swap( + &mut EXCEPTION_BUFFER.stack_pointers[a as usize], + &mut EXCEPTION_BUFFER.stack_pointers[b as usize], + ); } } } @@ -364,17 +377,20 @@ fn uncaught_exception() -> ! { crate::kernel::core1::terminate( EXCEPTION_BUFFER.exceptions[..EXCEPTION_BUFFER.exception_count].as_ref(), EXCEPTION_BUFFER.stack_pointers[..EXCEPTION_BUFFER.exception_count].as_ref(), - EXCEPTION_BUFFER.backtrace[..EXCEPTION_BUFFER.backtrace_size].as_mut()) + EXCEPTION_BUFFER.backtrace[..EXCEPTION_BUFFER.backtrace_size].as_mut(), + ) } } // stop function which would be executed when we unwind each frame -extern fn stop_fn(_version: c_int, - actions: i32, - _uw_exception_class: uw::_Unwind_Exception_Class, - _uw_exception: *mut uw::_Unwind_Exception, - context: *mut uw::_Unwind_Context, - _stop_parameter: *mut c_void) -> uw::_Unwind_Reason_Code { +extern "C" fn stop_fn( + _version: c_int, + actions: i32, + _uw_exception_class: uw::_Unwind_Exception_Class, + _uw_exception: *mut uw::_Unwind_Exception, + context: *mut uw::_Unwind_Context, + _stop_parameter: *mut c_void, +) -> uw::_Unwind_Reason_Code { unsafe { let load_addr = KERNEL_IMAGE.as_ref().unwrap().get_load_addr(); let backtrace_size = EXCEPTION_BUFFER.backtrace_size; @@ -423,7 +439,7 @@ static EXCEPTION_ID_LOOKUP: [(&str, u32); 11] = [ pub fn get_exception_id(name: &str) -> u32 { for (n, id) in EXCEPTION_ID_LOOKUP.iter() { if *n == name { - return *id + return *id; } } unimplemented!("unallocated internal exception id") @@ -431,26 +447,24 @@ pub fn get_exception_id(name: &str) -> u32 { #[macro_export] macro_rules! artiq_raise { - ($name:expr, $message:expr, $param0:expr, $param1:expr, $param2:expr) => ({ + ($name:expr, $message:expr, $param0:expr, $param1:expr, $param2:expr) => {{ use cslice::AsCSlice; let name_id = $crate::eh_artiq::get_exception_id($name); let message_cl = $message.clone(); let exn = $crate::eh_artiq::Exception { - id: name_id, - file: file!().as_c_slice(), - line: line!(), - column: column!(), + id: name_id, + file: file!().as_c_slice(), + line: line!(), + column: column!(), // https://github.com/rust-lang/rfcs/pull/1719 function: "(Rust function)".as_c_slice(), - message: message_cl.as_c_slice(), - param: [$param0, $param1, $param2] + message: message_cl.as_c_slice(), + param: [$param0, $param1, $param2], }; #[allow(unused_unsafe)] unsafe { $crate::eh_artiq::raise(&exn) } - }); - ($name:expr, $message:expr) => ({ - artiq_raise!($name, $message, 0, 0, 0) - }); + }}; + ($name:expr, $message:expr) => {{ artiq_raise!($name, $message, 0, 0, 0) }}; } diff --git a/src/runtime/src/i2c.rs b/src/runtime/src/i2c.rs index de908f3..ccebcce 100644 --- a/src/runtime/src/i2c.rs +++ b/src/runtime/src/i2c.rs @@ -1,9 +1,10 @@ use libboard_zynq; + use crate::artiq_raise; pub static mut I2C_BUS: Option = None; -pub extern fn start(busno: i32) { +pub extern "C" fn start(busno: i32) { if busno > 0 { artiq_raise!("I2CError", "I2C bus could not be accessed"); } @@ -14,7 +15,7 @@ pub extern fn start(busno: i32) { } } -pub extern fn restart(busno: i32) { +pub extern "C" fn restart(busno: i32) { if busno > 0 { artiq_raise!("I2CError", "I2C bus could not be accessed"); } @@ -25,7 +26,7 @@ pub extern fn restart(busno: i32) { } } -pub extern fn stop(busno: i32) { +pub extern "C" fn stop(busno: i32) { if busno > 0 { artiq_raise!("I2CError", "I2C bus could not be accessed"); } @@ -36,7 +37,7 @@ pub extern fn stop(busno: i32) { } } -pub extern fn write(busno: i32, data: i32) -> bool { +pub extern "C" fn write(busno: i32, data: i32) -> bool { if busno > 0 { artiq_raise!("I2CError", "I2C bus could not be accessed"); } @@ -48,7 +49,7 @@ pub extern fn write(busno: i32, data: i32) -> bool { } } -pub extern fn read(busno: i32, ack: bool) -> i32 { +pub extern "C" fn read(busno: i32, ack: bool) -> i32 { if busno > 0 { artiq_raise!("I2CError", "I2C bus could not be accessed"); } @@ -60,11 +61,12 @@ pub extern fn read(busno: i32, ack: bool) -> i32 { } } -pub extern fn switch_select(busno: i32, address: i32, mask: i32) { +pub extern "C" fn switch_select(busno: i32, address: i32, mask: i32) { if busno > 0 { artiq_raise!("I2CError", "I2C bus could not be accessed"); } - let ch = match mask { //decode from mainline, PCA9548-centric API + let ch = match mask { + //decode from mainline, PCA9548-centric API 0x00 => None, 0x01 => Some(0), 0x02 => Some(1), @@ -74,10 +76,15 @@ pub extern fn switch_select(busno: i32, address: i32, mask: i32) { 0x20 => Some(5), 0x40 => Some(6), 0x80 => Some(7), - _ => artiq_raise!("I2CError", "switch select supports only one channel") + _ => artiq_raise!("I2CError", "switch select supports only one channel"), }; unsafe { - if (&mut I2C_BUS).as_mut().unwrap().pca954x_select(address as u8, ch).is_err() { + if (&mut I2C_BUS) + .as_mut() + .unwrap() + .pca954x_select(address as u8, ch) + .is_err() + { artiq_raise!("I2CError", "switch select failed"); } } diff --git a/src/runtime/src/irq.rs b/src/runtime/src/irq.rs index c821abe..a18feb9 100644 --- a/src/runtime/src/irq.rs +++ b/src/runtime/src/irq.rs @@ -1,12 +1,9 @@ -use libboard_zynq::{gic, mpcore, println, stdio}; -use libcortex_a9::{ - asm, interrupt_handler, - regs::MPIDR, - spin_lock_yield, notify_spin_lock -}; -use libregister::RegisterR; use core::sync::atomic::{AtomicBool, Ordering}; +use libboard_zynq::{gic, mpcore, println, stdio}; +use libcortex_a9::{asm, interrupt_handler, notify_spin_lock, regs::MPIDR, spin_lock_yield}; +use libregister::RegisterR; + extern "C" { static mut __stack1_start: u32; fn main_core1() -> !; diff --git a/src/runtime/src/kernel/api.rs b/src/runtime/src/kernel/api.rs index 1d92761..ce4587a 100644 --- a/src/runtime/src/kernel/api.rs +++ b/src/runtime/src/kernel/api.rs @@ -1,29 +1,25 @@ -use core::ffi::VaList; -use core::ptr; -use core::str; +use alloc::vec; +use core::{ffi::VaList, ptr, str}; + use libc::{c_char, c_int, size_t}; use libm; use log::{info, warn}; -use alloc::vec; - -use crate::eh_artiq; -use crate::rtio; -use crate::i2c; -use super::rpc::{rpc_send, rpc_send_async, rpc_recv}; -use super::dma; -use super::cache; -use super::core1::rtio_get_destination_status; +use super::{cache, + core1::rtio_get_destination_status, + dma, + rpc::{rpc_recv, rpc_send, rpc_send_async}}; +use crate::{eh_artiq, i2c, rtio}; extern "C" { fn vsnprintf_(buffer: *mut c_char, count: size_t, format: *const c_char, va: VaList) -> c_int; } -unsafe extern fn core_log(fmt: *const c_char, mut args: ...) { +unsafe extern "C" fn core_log(fmt: *const c_char, mut args: ...) { let size = vsnprintf_(ptr::null_mut(), 0, fmt, args.as_va_list()) as usize; let mut buf = vec![0; size + 1]; vsnprintf_(buf.as_mut_ptr() as *mut i8, size + 1, fmt, args.as_va_list()); - let buf: &[u8] = &buf.as_slice()[..size-1]; // strip \n and NUL + let buf: &[u8] = &buf.as_slice()[..size - 1]; // strip \n and NUL match str::from_utf8(buf) { Ok(s) => info!("kernel: {}", s), Err(e) => { @@ -33,14 +29,13 @@ unsafe extern fn core_log(fmt: *const c_char, mut args: ...) { } } -unsafe extern fn rtio_log(fmt: *const c_char, mut args: ...) { +unsafe extern "C" fn rtio_log(fmt: *const c_char, mut args: ...) { let size = vsnprintf_(ptr::null_mut(), 0, fmt, args.as_va_list()) as usize; let mut buf = vec![0; size + 1]; vsnprintf_(buf.as_mut_ptr(), size + 1, fmt, args.as_va_list()); rtio::write_log(buf.as_slice()); } - macro_rules! api { ($i:ident) => ({ extern { static $i: u8; } @@ -56,24 +51,25 @@ macro_rules! api { } macro_rules! api_libm_f64f64 { - ($i:ident) => ({ - extern fn $i(x: f64) -> f64 { + ($i:ident) => {{ + extern "C" fn $i(x: f64) -> f64 { libm::$i(x) } api!($i = $i) - }) + }}; } macro_rules! api_libm_f64f64f64 { - ($i:ident) => ({ - extern fn $i(x: f64, y: f64) -> f64 { + ($i:ident) => {{ + extern "C" fn $i(x: f64, y: f64) -> f64 { libm::$i(x, y) } api!($i = $i) - }) + }}; } pub fn resolve(required: &[u8]) -> Option { + #[rustfmt::skip] let api = &[ // timing api!(now_mu = rtio::now_mu), @@ -124,6 +120,7 @@ pub fn resolve(required: &[u8]) -> Option { api!(__aeabi_ddiv), api!(__aeabi_dmul), api!(__aeabi_dsub), + // Double-precision floating-point comparison helper functions // RTABI chapter 4.1.2, Table 3 api!(__aeabi_dcmpeq), @@ -133,12 +130,14 @@ pub fn resolve(required: &[u8]) -> Option { api!(__aeabi_dcmpge), api!(__aeabi_dcmpgt), api!(__aeabi_dcmpun), + // Single-precision floating-point arithmetic helper functions // RTABI chapter 4.1.2, Table 4 api!(__aeabi_fadd), api!(__aeabi_fdiv), api!(__aeabi_fmul), api!(__aeabi_fsub), + // Single-precision floating-point comparison helper functions // RTABI chapter 4.1.2, Table 5 api!(__aeabi_fcmpeq), @@ -148,6 +147,7 @@ pub fn resolve(required: &[u8]) -> Option { api!(__aeabi_fcmpge), api!(__aeabi_fcmpgt), api!(__aeabi_fcmpun), + // Floating-point to integer conversions. // RTABI chapter 4.1.2, Table 6 api!(__aeabi_d2iz), @@ -158,9 +158,11 @@ pub fn resolve(required: &[u8]) -> Option { api!(__aeabi_f2uiz), api!(__aeabi_f2lz), api!(__aeabi_f2ulz), + // Conversions between floating types. // RTABI chapter 4.1.2, Table 7 api!(__aeabi_f2d), + // Integer to floating-point conversions. // RTABI chapter 4.1.2, Table 8 api!(__aeabi_i2d), @@ -171,12 +173,14 @@ pub fn resolve(required: &[u8]) -> Option { api!(__aeabi_ui2f), api!(__aeabi_l2f), api!(__aeabi_ul2f), + // Long long helper functions // RTABI chapter 4.2, Table 9 api!(__aeabi_lmul), api!(__aeabi_llsl), api!(__aeabi_llsr), api!(__aeabi_lasr), + // Integer division functions // RTABI chapter 4.3.1 api!(__aeabi_idiv), @@ -184,6 +188,7 @@ pub fn resolve(required: &[u8]) -> Option { api!(__aeabi_idivmod), api!(__aeabi_uidiv), api!(__aeabi_uldivmod), + // 4.3.4 Memory copying, clearing, and setting api!(__aeabi_memcpy8), api!(__aeabi_memcpy4), @@ -199,10 +204,30 @@ pub fn resolve(required: &[u8]) -> Option { api!(__aeabi_memclr), // libc - api!(memcpy, extern { fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut u8; }), - api!(memmove, extern { fn memmove(dest: *mut u8, src: *const u8, n: usize) -> *mut u8; }), - api!(memset, extern { fn memset(s: *mut u8, c: i32, n: usize) -> *mut u8; }), - api!(memcmp, extern { fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32; }), + api!( + memcpy, + extern "C" { + fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut u8; + } + ), + api!( + memmove, + extern "C" { + fn memmove(dest: *mut u8, src: *const u8, n: usize) -> *mut u8; + } + ), + api!( + memset, + extern "C" { + fn memset(s: *mut u8, c: i32, n: usize) -> *mut u8; + } + ), + api!( + memcmp, + extern "C" { + fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32; + } + ), // exceptions api!(_Unwind_Resume = unwind::_Unwind_Resume), @@ -210,6 +235,7 @@ pub fn resolve(required: &[u8]) -> Option { api!(__nac3_raise = eh_artiq::raise), api!(__nac3_resume = eh_artiq::resume), api!(__nac3_end_catch = eh_artiq::end_catch), + // legacy exception symbols api!(__artiq_personality = eh_artiq::artiq_personality), api!(__artiq_raise = eh_artiq::raise), @@ -241,7 +267,7 @@ pub fn resolve(required: &[u8]) -> Option { api_libm_f64f64!(fabs), api_libm_f64f64!(floor), { - extern fn fma(x: f64, y: f64, z: f64) -> f64 { + extern "C" fn fma(x: f64, y: f64, z: f64) -> f64 { libm::fma(x, y, z) } api!(fma = fma) @@ -253,7 +279,7 @@ pub fn resolve(required: &[u8]) -> Option { api_libm_f64f64!(j0), api_libm_f64f64!(j1), { - extern fn jn(n: i32, x: f64) -> f64 { + extern "C" fn jn(n: i32, x: f64) -> f64 { libm::jn(n, x) } api!(jn = jn) @@ -275,13 +301,13 @@ pub fn resolve(required: &[u8]) -> Option { api_libm_f64f64!(y0), api_libm_f64f64!(y1), { - extern fn yn(n: i32, x: f64) -> f64 { + extern "C" fn yn(n: i32, x: f64) -> f64 { libm::yn(n, x) } api!(yn = yn) }, ]; api.iter() - .find(|&&(exported, _)| exported.as_bytes() == required) - .map(|&(_, ptr)| ptr as u32) + .find(|&&(exported, _)| exported.as_bytes() == required) + .map(|&(_, ptr)| ptr as u32) } diff --git a/src/runtime/src/kernel/cache.rs b/src/runtime/src/kernel/cache.rs index b7433c7..09b85b1 100644 --- a/src/runtime/src/kernel/cache.rs +++ b/src/runtime/src/kernel/cache.rs @@ -1,12 +1,17 @@ -use alloc::{string::String, boxed::Box}; -use cslice::{CSlice, AsCSlice}; -use core::mem::{transmute, forget}; -use super::{KERNEL_CHANNEL_0TO1, KERNEL_CHANNEL_1TO0, Message}; +use alloc::{boxed::Box, string::String}; +use core::mem::{forget, transmute}; -pub extern fn get(key: CSlice) -> &CSlice<'static, i32> { +use cslice::{AsCSlice, CSlice}; + +use super::{Message, KERNEL_CHANNEL_0TO1, KERNEL_CHANNEL_1TO0}; + +pub extern "C" fn get(key: CSlice) -> &CSlice<'static, i32> { let key = String::from_utf8(key.as_ref().to_vec()).unwrap(); unsafe { - KERNEL_CHANNEL_1TO0.as_mut().unwrap().send(Message::CacheGetRequest(key)); + KERNEL_CHANNEL_1TO0 + .as_mut() + .unwrap() + .send(Message::CacheGetRequest(key)); let msg = KERNEL_CHANNEL_0TO1.as_mut().unwrap().recv(); if let Message::CacheGetReply(v) = msg { let leaked = Box::new(v.as_c_slice()); @@ -20,11 +25,13 @@ pub extern fn get(key: CSlice) -> &CSlice<'static, i32> { } } -pub extern fn put(key: CSlice, list: &CSlice) { +pub extern "C" fn put(key: CSlice, list: &CSlice) { let key = String::from_utf8(key.as_ref().to_vec()).unwrap(); let value = list.as_ref().to_vec(); unsafe { - KERNEL_CHANNEL_1TO0.as_mut().unwrap().send(Message::CachePutRequest(key, value)); + KERNEL_CHANNEL_1TO0 + .as_mut() + .unwrap() + .send(Message::CachePutRequest(key, value)); } } - diff --git a/src/runtime/src/kernel/control.rs b/src/runtime/src/kernel/control.rs index 05f6ea4..fcd35dc 100644 --- a/src/runtime/src/kernel/control.rs +++ b/src/runtime/src/kernel/control.rs @@ -1,11 +1,11 @@ -use libcortex_a9::sync_channel::{Sender, Receiver}; +use core::mem::{forget, replace}; + +use libcortex_a9::sync_channel::{Receiver, Sender}; use libsupport_zynq::boot::Core1; -use super::{CHANNEL_0TO1, CHANNEL_1TO0, CHANNEL_SEM, INIT_LOCK, Message}; +use super::{Message, CHANNEL_0TO1, CHANNEL_1TO0, CHANNEL_SEM, INIT_LOCK}; use crate::irq::restart_core1; -use core::mem::{forget, replace}; - pub struct Control { pub tx: Sender<'static, Message>, pub rx: Receiver<'static, Message>, @@ -53,4 +53,3 @@ impl Control { forget(replace(&mut self.rx, core0_rx)); } } - diff --git a/src/runtime/src/kernel/core1.rs b/src/runtime/src/kernel/core1.rs index 52a2928..60e648d 100644 --- a/src/runtime/src/kernel/core1.rs +++ b/src/runtime/src/kernel/core1.rs @@ -1,31 +1,20 @@ //! Kernel prologue/epilogue that runs on the 2nd CPU core -use core::{mem, ptr, cell::UnsafeCell}; use alloc::borrow::ToOwned; -use log::{debug, info, error}; -use cslice::CSlice; +use core::{cell::UnsafeCell, mem, ptr}; -use libcortex_a9::{ - enable_fpu, - cache::{dcci_slice, iciallu, bpiall}, - asm::{dsb, isb}, - sync_channel, -}; -use libboard_zynq::{mpcore, gic}; +use cslice::CSlice; +use dyld::{self, elf::EXIDX_Entry, Library}; +use libboard_zynq::{gic, mpcore}; +use libcortex_a9::{asm::{dsb, isb}, + cache::{bpiall, dcci_slice, iciallu}, + enable_fpu, sync_channel}; use libsupport_zynq::ram; -use dyld::{self, Library, elf::EXIDX_Entry}; +use log::{debug, error, info}; + +use super::{api::resolve, dma, rpc::rpc_send_async, Message, CHANNEL_0TO1, CHANNEL_1TO0, CHANNEL_SEM, INIT_LOCK, + KERNEL_CHANNEL_0TO1, KERNEL_CHANNEL_1TO0, KERNEL_IMAGE}; use crate::{eh_artiq, get_async_errors, rtio}; -use super::{ - api::resolve, - rpc::rpc_send_async, - INIT_LOCK, - CHANNEL_0TO1, CHANNEL_1TO0, - CHANNEL_SEM, - KERNEL_CHANNEL_0TO1, KERNEL_CHANNEL_1TO0, - KERNEL_IMAGE, - Message, - dma, -}; // linker symbols extern "C" { @@ -38,13 +27,13 @@ extern "C" { unsafe fn attribute_writeback(typeinfo: *const ()) { struct Attr { offset: usize, - tag: CSlice<'static, u8>, - name: CSlice<'static, u8> + tag: CSlice<'static, u8>, + name: CSlice<'static, u8>, } struct Type { attributes: *const *const Attr, - objects: *const *const () + objects: *const *const (), } let mut tys = typeinfo as *const *const Type; @@ -63,11 +52,16 @@ unsafe fn attribute_writeback(typeinfo: *const ()) { attributes = attributes.offset(1); if (*attribute).tag.len() > 0 { - rpc_send_async(0, &(*attribute).tag, [ - &object as *const _ as *const (), - &(*attribute).name as *const _ as *const (), - (object as usize + (*attribute).offset) as *const () - ].as_ptr()); + rpc_send_async( + 0, + &(*attribute).tag, + [ + &object as *const _ as *const (), + &(*attribute).name as *const _ as *const (), + (object as usize + (*attribute).offset) as *const (), + ] + .as_ptr(), + ); } } } @@ -82,7 +76,8 @@ pub struct KernelImage { impl KernelImage { pub fn new(library: Library) -> Result { - let __modinit__ = library.lookup(b"__modinit__") + let __modinit__ = library + .lookup(b"__modinit__") .ok_or(dyld::Error::Lookup("__modinit__".to_owned()))?; let typeinfo = library.lookup(b"typeinfo"); @@ -90,8 +85,7 @@ impl KernelImage { let bss_start = library.lookup(b"__bss_start"); let end = library.lookup(b"_end"); if let Some(bss_start) = bss_start { - let end = end - .ok_or(dyld::Error::Lookup("_end".to_owned()))?; + let end = end.ok_or(dyld::Error::Lookup("_end".to_owned()))?; unsafe { ptr::write_bytes(bss_start as *mut u8, 0, (end - bss_start) as usize); } @@ -126,9 +120,7 @@ impl KernelImage { } pub fn get_load_addr(&self) -> usize { - unsafe { - self.library.get().as_ref().unwrap().image.as_ptr() as usize - } + unsafe { self.library.get().as_ref().unwrap().image.as_ptr() as usize } } } @@ -164,20 +156,19 @@ pub extern "C" fn main_core1() { let message = core1_rx.recv(); match message { Message::LoadRequest(data) => { - let result = dyld::load(&data, &resolve) - .and_then(KernelImage::new); + let result = dyld::load(&data, &resolve).and_then(KernelImage::new); match result { Ok(kernel) => { loaded_kernel = Some(kernel); debug!("kernel loaded"); core1_tx.send(Message::LoadCompleted); - }, + } Err(error) => { error!("failed to load shared library: {}", error); core1_tx.send(Message::LoadFailed); } } - }, + } Message::StartRequest => { info!("kernel starting"); if let Some(kernel) = loaded_kernel.take() { @@ -202,9 +193,11 @@ pub extern "C" fn main_core1() { } /// Called by eh_artiq -pub fn terminate(exceptions: &'static [Option>], - stack_pointers: &'static [eh_artiq::StackPointerBacktrace], - backtrace: &'static mut [(usize, usize)]) -> ! { +pub fn terminate( + exceptions: &'static [Option>], + stack_pointers: &'static [eh_artiq::StackPointerBacktrace], + backtrace: &'static mut [(usize, usize)], +) -> ! { { let core1_tx = unsafe { KERNEL_CHANNEL_1TO0.as_mut().unwrap() }; let errors = unsafe { get_async_errors() }; @@ -215,7 +208,7 @@ pub fn terminate(exceptions: &'static [Option>], /// Called by llvm_libunwind #[no_mangle] -extern fn dl_unwind_find_exidx(pc: *const u32, len_ptr: *mut u32) -> *const u32 { +extern "C" fn dl_unwind_find_exidx(pc: *const u32, len_ptr: *mut u32) -> *const u32 { let length; let start: *const EXIDX_Entry; unsafe { @@ -223,9 +216,14 @@ extern fn dl_unwind_find_exidx(pc: *const u32, len_ptr: *mut u32) -> *const u32 length = (&__exidx_end as *const EXIDX_Entry).offset_from(&__exidx_start) as u32; start = &__exidx_start; } else if KERNEL_IMAGE != ptr::null() { - let exidx = KERNEL_IMAGE.as_ref() + let exidx = KERNEL_IMAGE + .as_ref() .expect("dl_unwind_find_exidx kernel image") - .library.get().as_ref().unwrap().exidx(); + .library + .get() + .as_ref() + .unwrap() + .exidx(); length = exidx.len() as u32; start = exidx.as_ptr(); } else { @@ -237,7 +235,7 @@ extern fn dl_unwind_find_exidx(pc: *const u32, len_ptr: *mut u32) -> *const u32 start as *const u32 } -pub extern fn rtio_get_destination_status(destination: i32) -> bool { +pub extern "C" fn rtio_get_destination_status(destination: i32) -> bool { #[cfg(has_drtio)] if destination > 0 && destination < 255 { let reply = unsafe { @@ -248,9 +246,9 @@ pub extern fn rtio_get_destination_status(destination: i32) -> bool { }; return match reply { Message::UpDestinationsReply(x) => x, - _ => panic!("received unexpected reply to UpDestinationsRequest: {:?}", reply) + _ => panic!("received unexpected reply to UpDestinationsRequest: {:?}", reply), }; - } + } destination == 0 -} \ No newline at end of file +} diff --git a/src/runtime/src/kernel/dma.rs b/src/runtime/src/kernel/dma.rs index 20cb87e..d4c473a 100644 --- a/src/runtime/src/kernel/dma.rs +++ b/src/runtime/src/kernel/dma.rs @@ -1,21 +1,18 @@ -use crate::{ - pl::csr, - artiq_raise, - rtio, -}; -use alloc::{vec::Vec, string::String, boxed::Box}; -use cslice::CSlice; -use super::{KERNEL_IMAGE, KERNEL_CHANNEL_0TO1, KERNEL_CHANNEL_1TO0, Message}; +use alloc::{boxed::Box, string::String, vec::Vec}; use core::mem; +use cslice::CSlice; use libcortex_a9::cache::dcci_slice; +use super::{Message, KERNEL_CHANNEL_0TO1, KERNEL_CHANNEL_1TO0, KERNEL_IMAGE}; +use crate::{artiq_raise, pl::csr, rtio}; + const ALIGNMENT: usize = 16 * 8; #[repr(C)] pub struct DmaTrace { duration: i64, - address: i32, + address: i32, } #[derive(Clone, Debug)] @@ -33,10 +30,13 @@ pub unsafe fn init_dma_recorder() { mem::forget(mem::replace(&mut RECORDER, None)); } -pub extern fn dma_record_start(name: CSlice) { +pub extern "C" fn dma_record_start(name: CSlice) { let name = String::from_utf8(name.as_ref().to_vec()).unwrap(); unsafe { - KERNEL_CHANNEL_1TO0.as_mut().unwrap().send(Message::DmaEraseRequest(name.clone())); + KERNEL_CHANNEL_1TO0 + .as_mut() + .unwrap() + .send(Message::DmaEraseRequest(name.clone())); } unsafe { if RECORDER.is_some() { @@ -44,10 +44,10 @@ pub extern fn dma_record_start(name: CSlice) { } let library = KERNEL_IMAGE.as_ref().unwrap(); - library.rebind(b"rtio_output", - dma_record_output as *const ()).unwrap(); - library.rebind(b"rtio_output_wide", - dma_record_output_wide as *const ()).unwrap(); + library.rebind(b"rtio_output", dma_record_output as *const ()).unwrap(); + library + .rebind(b"rtio_output_wide", dma_record_output_wide as *const ()) + .unwrap(); RECORDER = Some(DmaRecorder { name, @@ -57,29 +57,29 @@ pub extern fn dma_record_start(name: CSlice) { } } -pub extern fn dma_record_stop(duration: i64) { +pub extern "C" fn dma_record_stop(duration: i64) { unsafe { if RECORDER.is_none() { artiq_raise!("DMAError", "DMA is not recording") } let library = KERNEL_IMAGE.as_ref().unwrap(); - library.rebind(b"rtio_output", - rtio::output as *const ()).unwrap(); - library.rebind(b"rtio_output_wide", - rtio::output_wide as *const ()).unwrap(); + library.rebind(b"rtio_output", rtio::output as *const ()).unwrap(); + library + .rebind(b"rtio_output_wide", rtio::output_wide as *const ()) + .unwrap(); let mut recorder = RECORDER.take().unwrap(); recorder.duration = duration; - KERNEL_CHANNEL_1TO0.as_mut().unwrap().send( - Message::DmaPutRequest(recorder) - ); + KERNEL_CHANNEL_1TO0 + .as_mut() + .unwrap() + .send(Message::DmaPutRequest(recorder)); } } #[inline(always)] -unsafe fn dma_record_output_prepare(timestamp: i64, target: i32, - words: usize) { +unsafe fn dma_record_output_prepare(timestamp: i64, target: i32, words: usize) { // See gateware/rtio/dma.py. const HEADER_LENGTH: usize = /*length*/1 + /*channel*/3 + /*timestamp*/8 + /*address*/1; let length = HEADER_LENGTH + /*data*/words * 4; @@ -87,36 +87,36 @@ unsafe fn dma_record_output_prepare(timestamp: i64, target: i32, let buffer = &mut RECORDER.as_mut().unwrap().buffer; buffer.reserve(length); buffer.extend_from_slice(&[ - (length >> 0) as u8, - (target >> 8) as u8, - (target >> 16) as u8, - (target >> 24) as u8, - (timestamp >> 0) as u8, - (timestamp >> 8) as u8, + (length >> 0) as u8, + (target >> 8) as u8, + (target >> 16) as u8, + (target >> 24) as u8, + (timestamp >> 0) as u8, + (timestamp >> 8) as u8, (timestamp >> 16) as u8, (timestamp >> 24) as u8, (timestamp >> 32) as u8, (timestamp >> 40) as u8, (timestamp >> 48) as u8, (timestamp >> 56) as u8, - (target >> 0) as u8, + (target >> 0) as u8, ]); } -pub extern fn dma_record_output(target: i32, word: i32) { +pub extern "C" fn dma_record_output(target: i32, word: i32) { unsafe { let timestamp = rtio::now_mu(); dma_record_output_prepare(timestamp, target, 1); RECORDER.as_mut().unwrap().buffer.extend_from_slice(&[ - (word >> 0) as u8, - (word >> 8) as u8, + (word >> 0) as u8, + (word >> 8) as u8, (word >> 16) as u8, (word >> 24) as u8, ]); } } -pub extern fn dma_record_output_wide(target: i32, words: CSlice) { +pub extern "C" fn dma_record_output_wide(target: i32, words: CSlice) { assert!(words.len() <= 16); // enforce the hardware limit unsafe { @@ -125,8 +125,8 @@ pub extern fn dma_record_output_wide(target: i32, words: CSlice) { let buffer = &mut RECORDER.as_mut().unwrap().buffer; for word in words.as_ref().iter() { buffer.extend_from_slice(&[ - (word >> 0) as u8, - (word >> 8) as u8, + (word >> 0) as u8, + (word >> 8) as u8, (word >> 16) as u8, (word >> 24) as u8, ]); @@ -134,19 +134,22 @@ pub extern fn dma_record_output_wide(target: i32, words: CSlice) { } } -pub extern fn dma_erase(name: CSlice) { +pub extern "C" fn dma_erase(name: CSlice) { let name = String::from_utf8(name.as_ref().to_vec()).unwrap(); unsafe { - KERNEL_CHANNEL_1TO0.as_mut().unwrap().send(Message::DmaEraseRequest(name)); + KERNEL_CHANNEL_1TO0 + .as_mut() + .unwrap() + .send(Message::DmaEraseRequest(name)); } } -pub extern fn dma_retrieve(name: CSlice) -> DmaTrace { +pub extern "C" fn dma_retrieve(name: CSlice) -> DmaTrace { let name = String::from_utf8(name.as_ref().to_vec()).unwrap(); unsafe { KERNEL_CHANNEL_1TO0.as_mut().unwrap().send(Message::DmaGetRequest(name)); } - match unsafe {KERNEL_CHANNEL_0TO1.as_mut().unwrap()}.recv() { + match unsafe { KERNEL_CHANNEL_0TO1.as_mut().unwrap() }.recv() { Message::DmaGetReply(None) => (), Message::DmaGetReply(Some((mut v, duration))) => { v.reserve(ALIGNMENT - 1); @@ -162,18 +165,15 @@ pub extern fn dma_retrieve(name: CSlice) -> DmaTrace { dcci_slice(&v); let v = Box::new(v); let address = Box::into_raw(v) as *mut Vec as i32; - return DmaTrace { - address, - duration, - }; - }, + return DmaTrace { address, duration }; + } _ => panic!("Expected DmaGetReply after DmaGetRequest!"), } // we have to defer raising error as we have to drop the message first... artiq_raise!("DMAError", "DMA trace not found"); } -pub extern fn dma_playback(timestamp: i64, ptr: i32) { +pub extern "C" fn dma_playback(timestamp: i64, ptr: i32) { unsafe { let v = Box::from_raw(ptr as *mut Vec); let padding = ALIGNMENT - v.as_ptr() as usize % ALIGNMENT; @@ -197,16 +197,23 @@ pub extern fn dma_playback(timestamp: i64, ptr: i32) { let channel = csr::rtio_dma::error_channel_read(); csr::rtio_dma::error_write(1); if error & 1 != 0 { - artiq_raise!("RTIOUnderflow", + artiq_raise!( + "RTIOUnderflow", "RTIO underflow at {1} mu, channel {rtio_channel_info:0}", - channel as i64, timestamp as i64, 0); + channel as i64, + timestamp as i64, + 0 + ); } if error & 2 != 0 { - artiq_raise!("RTIODestinationUnreachable", + artiq_raise!( + "RTIODestinationUnreachable", "RTIO destination unreachable, output, at {1} mu, channel {rtio_channel_info:0}", - channel as i64, timestamp as i64, 0); + channel as i64, + timestamp as i64, + 0 + ); } } } } - diff --git a/src/runtime/src/kernel/mod.rs b/src/runtime/src/kernel/mod.rs index 3e6a900..9f88297 100644 --- a/src/runtime/src/kernel/mod.rs +++ b/src/runtime/src/kernel/mod.rs @@ -1,15 +1,16 @@ +use alloc::{string::String, vec::Vec}; use core::ptr; -use alloc::{vec::Vec, string::String}; -use libcortex_a9::{mutex::Mutex, sync_channel, semaphore::Semaphore}; +use libcortex_a9::{mutex::Mutex, semaphore::Semaphore, sync_channel}; + use crate::eh_artiq; mod control; pub use control::Control; -pub mod core1; mod api; -mod rpc; +pub mod core1; mod dma; +mod rpc; pub use dma::DmaRecorder; mod cache; @@ -21,7 +22,7 @@ pub struct RPCException { pub file: u32, pub line: i32, pub column: i32, - pub function: u32 + pub function: u32, } #[derive(Debug, Clone)] @@ -31,11 +32,16 @@ pub enum Message { LoadFailed, StartRequest, KernelFinished(u8), - KernelException(&'static [Option>], - &'static [eh_artiq::StackPointerBacktrace], - &'static [(usize, usize)], - u8), - RpcSend { is_async: bool, data: Vec }, + KernelException( + &'static [Option>], + &'static [eh_artiq::StackPointerBacktrace], + &'static [(usize, usize)], + u8, + ), + RpcSend { + is_async: bool, + data: Vec, + }, RpcRecvRequest(*mut ()), RpcRecvReply(Result), @@ -64,4 +70,3 @@ static mut KERNEL_CHANNEL_1TO0: Option> = pub static mut KERNEL_IMAGE: *const core1::KernelImage = ptr::null(); static INIT_LOCK: Mutex<()> = Mutex::new(()); - diff --git a/src/runtime/src/kernel/rpc.rs b/src/runtime/src/kernel/rpc.rs index 496105a..b016c59 100644 --- a/src/runtime/src/kernel/rpc.rs +++ b/src/runtime/src/kernel/rpc.rs @@ -1,14 +1,11 @@ //! Kernel-side RPC API use alloc::vec::Vec; + use cslice::CSlice; -use crate::eh_artiq; -use crate::rpc::send_args; -use super::{ - KERNEL_CHANNEL_0TO1, KERNEL_CHANNEL_1TO0, - Message, -}; +use super::{Message, KERNEL_CHANNEL_0TO1, KERNEL_CHANNEL_1TO0}; +use crate::{eh_artiq, rpc::send_args}; fn rpc_send_common(is_async: bool, service: u32, tag: &CSlice, data: *const *const ()) { let core1_tx = unsafe { KERNEL_CHANNEL_1TO0.as_mut().unwrap() }; @@ -17,15 +14,15 @@ fn rpc_send_common(is_async: bool, service: u32, tag: &CSlice, data: *const core1_tx.send(Message::RpcSend { is_async, data: buffer }); } -pub extern fn rpc_send(service: u32, tag: &CSlice, data: *const *const ()) { +pub extern "C" fn rpc_send(service: u32, tag: &CSlice, data: *const *const ()) { rpc_send_common(false, service, tag, data); } -pub extern fn rpc_send_async(service: u32, tag: &CSlice, data: *const *const ()) { +pub extern "C" fn rpc_send_async(service: u32, tag: &CSlice, data: *const *const ()) { rpc_send_common(true, service, tag, data); } -pub extern fn rpc_recv(slot: *mut ()) -> usize { +pub extern "C" fn rpc_recv(slot: *mut ()) -> usize { let reply = unsafe { let core1_rx = KERNEL_CHANNEL_0TO1.as_mut().unwrap(); let core1_tx = KERNEL_CHANNEL_1TO0.as_mut().unwrap(); @@ -36,15 +33,15 @@ pub extern fn rpc_recv(slot: *mut ()) -> usize { Message::RpcRecvReply(Ok(alloc_size)) => alloc_size, Message::RpcRecvReply(Err(exception)) => unsafe { eh_artiq::raise(&eh_artiq::Exception { - id: exception.id, - file: CSlice::new(exception.file as *const u8, usize::MAX), - line: exception.line as u32, - column: exception.column as u32, + id: exception.id, + file: CSlice::new(exception.file as *const u8, usize::MAX), + line: exception.line as u32, + column: exception.column as u32, function: CSlice::new(exception.function as *const u8, usize::MAX), - message: CSlice::new(exception.message as *const u8, usize::MAX), - param: exception.param + message: CSlice::new(exception.message as *const u8, usize::MAX), + param: exception.param, }) }, - _ => panic!("received unexpected reply to RpcRecvRequest: {:?}", reply) + _ => panic!("received unexpected reply to RpcRecvRequest: {:?}", reply), } } diff --git a/src/runtime/src/main.rs b/src/runtime/src/main.rs index faef0a6..5eefd0b 100644 --- a/src/runtime/src/main.rs +++ b/src/runtime/src/main.rs @@ -1,6 +1,6 @@ #![no_std] #![no_main] -#![recursion_limit="1024"] // for futures_util::select! +#![recursion_limit = "1024"] // for futures_util::select! #![feature(alloc_error_handler)] #![feature(panic_info_message)] #![feature(c_variadic)] @@ -12,25 +12,32 @@ #[macro_use] extern crate alloc; -use log::{info, warn, error}; - -use libboard_zynq::{timer::GlobalTimer, mpcore, gic}; -use libasync::{task, block_async}; -use libsupport_zynq::ram; -use nb; -use void::Void; -use libconfig::Config; -use libcortex_a9::l2c::enable_l2_cache; -use libboard_artiq::{logger, identifier_read, pl}; +use libasync::{block_async, task}; #[cfg(feature = "target_kasli_soc")] use libboard_artiq::io_expander; +use libboard_artiq::{identifier_read, logger, pl}; +use libboard_zynq::{gic, mpcore, timer::GlobalTimer}; +use libconfig::Config; +use libcortex_a9::l2c::enable_l2_cache; +use libsupport_zynq::ram; +use log::{error, info, warn}; +use nb; +use void::Void; const ASYNC_ERROR_COLLISION: u8 = 1 << 0; const ASYNC_ERROR_BUSY: u8 = 1 << 1; const ASYNC_ERROR_SEQUENCE_ERROR: u8 = 1 << 2; -mod proto_async; +mod analyzer; mod comms; +mod eh_artiq; +mod i2c; +mod irq; +mod kernel; +mod mgmt; +mod moninj; +mod panic; +mod proto_async; mod rpc; #[cfg(ki_impl = "csr")] #[path = "rtio_csr.rs"] @@ -38,16 +45,8 @@ mod rtio; #[cfg(ki_impl = "acp")] #[path = "rtio_acp.rs"] mod rtio; -mod rtio_mgt; mod rtio_clocking; -mod kernel; -mod moninj; -mod eh_artiq; -mod panic; -mod mgmt; -mod analyzer; -mod irq; -mod i2c; +mod rtio_mgt; static mut SEEN_ASYNC_ERRORS: u8 = 0; @@ -74,15 +73,27 @@ async fn report_async_rtio_errors() { let errors = pl::csr::rtio_core::async_error_read(); if errors & ASYNC_ERROR_COLLISION != 0 { let channel = pl::csr::rtio_core::collision_channel_read(); - error!("RTIO collision involving channel 0x{:04x}:{}", channel, rtio_mgt::resolve_channel_name(channel as u32)); + error!( + "RTIO collision involving channel 0x{:04x}:{}", + channel, + rtio_mgt::resolve_channel_name(channel as u32) + ); } if errors & ASYNC_ERROR_BUSY != 0 { let channel = pl::csr::rtio_core::busy_channel_read(); - error!("RTIO busy error involving channel 0x{:04x}:{}", channel, rtio_mgt::resolve_channel_name(channel as u32)); + error!( + "RTIO busy error involving channel 0x{:04x}:{}", + channel, + rtio_mgt::resolve_channel_name(channel as u32) + ); } if errors & ASYNC_ERROR_SEQUENCE_ERROR != 0 { let channel = pl::csr::rtio_core::sequence_error_channel_read(); - error!("RTIO sequence error involving channel 0x{:04x}:{}", channel, rtio_mgt::resolve_channel_name(channel as u32)); + error!( + "RTIO sequence error involving channel 0x{:04x}:{}", + channel, + rtio_mgt::resolve_channel_name(channel as u32) + ); } SEEN_ASYNC_ERRORS = errors; pl::csr::rtio_core::async_error_write(errors); @@ -90,18 +101,14 @@ async fn report_async_rtio_errors() { } } - - -static mut LOG_BUFFER: [u8; 1<<17] = [0; 1<<17]; +static mut LOG_BUFFER: [u8; 1 << 17] = [0; 1 << 17]; #[no_mangle] pub fn main_core0() { enable_l2_cache(0x8); let mut timer = GlobalTimer::start(); - let buffer_logger = unsafe { - logger::BufferLogger::new(&mut LOG_BUFFER[..]) - }; + let buffer_logger = unsafe { logger::BufferLogger::new(&mut LOG_BUFFER[..]) }; buffer_logger.set_uart_log_level(log::LevelFilter::Info); buffer_logger.register(); log::set_max_level(log::LevelFilter::Info); @@ -137,7 +144,7 @@ pub fn main_core0() { Config::new_dummy() } }; - + rtio_clocking::init(&mut timer, &cfg); task::spawn(report_async_rtio_errors()); diff --git a/src/runtime/src/mgmt.rs b/src/runtime/src/mgmt.rs index ecce8d2..bfeed9b 100644 --- a/src/runtime/src/mgmt.rs +++ b/src/runtime/src/mgmt.rs @@ -1,16 +1,17 @@ +use alloc::{rc::Rc, string::String, vec::Vec}; +use core::cell::RefCell; + use futures::{future::poll_fn, task::Poll}; use libasync::{smoltcp::TcpStream, task}; -use libboard_zynq::{smoltcp, slcr}; -use libconfig::Config; -use core::cell::RefCell; -use alloc::{rc::Rc, vec::Vec, string::String}; -use log::{self, info, debug, warn, error, LevelFilter}; - use libboard_artiq::logger::{BufferLogger, LogBufferRef}; -use crate::proto_async::*; +use libboard_zynq::{slcr, smoltcp}; +use libconfig::Config; +use log::{self, debug, error, info, warn, LevelFilter}; use num_derive::FromPrimitive; use num_traits::FromPrimitive; +use crate::proto_async::*; + #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Error { NetworkError(smoltcp::Error), @@ -24,10 +25,10 @@ type Result = core::result::Result; impl core::fmt::Display for Error { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { match self { - &Error::NetworkError(error) => write!(f, "network error: {}", error), + &Error::NetworkError(error) => write!(f, "network error: {}", error), &Error::UnknownLogLevel(lvl) => write!(f, "unknown log level {}", lvl), - &Error::UnexpectedPattern => write!(f, "unexpected pattern"), - &Error::UnrecognizedPacket => write!(f, "unrecognized packet"), + &Error::UnexpectedPattern => write!(f, "unexpected pattern"), + &Error::UnrecognizedPacket => write!(f, "unrecognized packet"), } } } @@ -74,9 +75,7 @@ async fn read_log_level_filter(stream: &mut TcpStream) -> Result(f: F) -> LogBufferRef<'static> -where - F: Fn(&LogBufferRef) -> bool, -{ +where F: Fn(&LogBufferRef) -> bool { poll_fn(|ctx| { let logger = unsafe { BufferLogger::get_logger().as_mut().unwrap() }; match logger.buffer() { @@ -112,10 +111,7 @@ async fn read_key(stream: &mut TcpStream) -> Result { Ok(String::from_utf8(buffer).unwrap()) } -async fn handle_connection( - stream: &mut TcpStream, - pull_id: Rc>, - cfg: Rc) -> Result<()> { +async fn handle_connection(stream: &mut TcpStream, pull_id: Rc>, cfg: Rc) -> Result<()> { if !expect(&stream, b"ARTIQ management\n").await? { return Err(Error::UnexpectedPattern); } @@ -163,7 +159,7 @@ async fn handle_connection( logger.set_buffer_log_level(LevelFilter::Trace); } } - }, + } Request::SetLogFilter => { let lvl = read_log_level_filter(stream).await?; info!("Changing log level to {}", lvl); @@ -174,10 +170,7 @@ async fn handle_connection( let lvl = read_log_level_filter(stream).await?; info!("Changing UART log level to {}", lvl); unsafe { - BufferLogger::get_logger() - .as_ref() - .unwrap() - .set_uart_log_level(lvl); + BufferLogger::get_logger().as_ref().unwrap().set_uart_log_level(lvl); } write_i8(stream, Reply::Success as i8).await?; } @@ -193,16 +186,12 @@ async fn handle_connection( warn!("read error: no such key"); write_i8(stream, Reply::Error as i8).await?; } - }, + } Request::ConfigWrite => { let key = read_key(stream).await?; debug!("write key: {}", key); let len = read_i32(stream).await?; - let len = if len <= 0 { - 0 - } else { - len as usize - }; + let len = if len <= 0 { 0 } else { len as usize }; let mut buffer = Vec::with_capacity(len); unsafe { buffer.set_len(len); @@ -217,7 +206,7 @@ async fn handle_connection( error!("failed to write: {:?}", value); write_i8(stream, Reply::Error as i8).await?; } - }, + } Request::ConfigRemove => { let key = read_key(stream).await?; debug!("erase key: {}", key); @@ -229,7 +218,7 @@ async fn handle_connection( warn!("erase failed"); write_i8(stream, Reply::Error as i8).await?; } - }, + } Request::Reboot => { info!("rebooting"); write_i8(stream, Reply::RebootImminent as i8).await?; diff --git a/src/runtime/src/moninj.rs b/src/runtime/src/moninj.rs index 5b13606..966534c 100644 --- a/src/runtime/src/moninj.rs +++ b/src/runtime/src/moninj.rs @@ -1,26 +1,23 @@ -use core::{fmt, cell::RefCell}; use alloc::{collections::BTreeMap, rc::Rc}; -use log::{debug, info, warn}; -use void::Void; +use core::{cell::RefCell, fmt}; +use futures::{pin_mut, select_biased, FutureExt}; +use libasync::{block_async, nb, smoltcp::TcpStream, task}; use libboard_artiq::drtio_routing; - -use libboard_zynq::{smoltcp, timer::GlobalTimer, time::Milliseconds}; -use libasync::{task, smoltcp::TcpStream, block_async, nb}; +use libboard_zynq::{smoltcp, time::Milliseconds, timer::GlobalTimer}; use libcortex_a9::mutex::Mutex; - +use log::{debug, info, warn}; use num_derive::{FromPrimitive, ToPrimitive}; use num_traits::{FromPrimitive, ToPrimitive}; -use futures::{pin_mut, select_biased, FutureExt}; +use void::Void; use crate::proto_async::*; - #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Error { NetworkError(smoltcp::Error), UnexpectedPattern, - UnrecognizedPacket + UnrecognizedPacket, } pub type Result = core::result::Result; @@ -29,8 +26,8 @@ impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { &Error::NetworkError(error) => write!(f, "network error: {}", error), - &Error::UnexpectedPattern => write!(f, "unexpected pattern"), - &Error::UnrecognizedPacket => write!(f, "unrecognized packet"), + &Error::UnexpectedPattern => write!(f, "unexpected pattern"), + &Error::UnrecognizedPacket => write!(f, "unrecognized packet"), } } } @@ -46,60 +43,102 @@ enum HostMessage { MonitorProbe = 0, MonitorInjection = 3, Inject = 1, - GetInjectionStatus = 2 + GetInjectionStatus = 2, } #[derive(Debug, FromPrimitive, ToPrimitive)] enum DeviceMessage { MonitorStatus = 0, - InjectionStatus = 1 + InjectionStatus = 1, } #[cfg(has_drtio)] mod remote_moninj { - use super::*; use libboard_artiq::drtioaux_async; - use crate::rtio_mgt::drtio; use log::error; - pub async fn read_probe(aux_mutex: &Rc>, timer: GlobalTimer, linkno: u8, destination: u8, channel: i32, probe: i8) -> i64 { - let reply = drtio::aux_transact(aux_mutex, linkno, &drtioaux_async::Packet::MonitorRequest { - destination: destination, - channel: channel as _, - probe: probe as _}, - timer).await; + use super::*; + use crate::rtio_mgt::drtio; + + pub async fn read_probe( + aux_mutex: &Rc>, + timer: GlobalTimer, + linkno: u8, + destination: u8, + channel: i32, + probe: i8, + ) -> i64 { + let reply = drtio::aux_transact( + aux_mutex, + linkno, + &drtioaux_async::Packet::MonitorRequest { + destination: destination, + channel: channel as _, + probe: probe as _, + }, + timer, + ) + .await; match reply { Ok(drtioaux_async::Packet::MonitorReply { value }) => return value as i64, Ok(packet) => error!("received unexpected aux packet: {:?}", packet), - Err("link went down") => { debug!("link is down"); }, - Err(e) => error!("aux packet error ({})", e) + Err("link went down") => { + debug!("link is down"); + } + Err(e) => error!("aux packet error ({})", e), } 0 } - pub async fn inject(aux_mutex: &Rc>, _timer: GlobalTimer, linkno: u8, destination: u8, channel: i32, overrd: i8, value: i8) { + pub async fn inject( + aux_mutex: &Rc>, + _timer: GlobalTimer, + linkno: u8, + destination: u8, + channel: i32, + overrd: i8, + value: i8, + ) { let _lock = aux_mutex.lock(); - drtioaux_async::send(linkno, &drtioaux_async::Packet::InjectionRequest { - destination: destination, - channel: channel as _, - overrd: overrd as _, - value: value as _ - }).await.unwrap(); + drtioaux_async::send( + linkno, + &drtioaux_async::Packet::InjectionRequest { + destination: destination, + channel: channel as _, + overrd: overrd as _, + value: value as _, + }, + ) + .await + .unwrap(); } - pub async fn read_injection_status(aux_mutex: &Rc>, timer: GlobalTimer, linkno: u8, destination: u8, channel: i32, overrd: i8) -> i8 { - let reply = drtio::aux_transact(aux_mutex, - linkno, + pub async fn read_injection_status( + aux_mutex: &Rc>, + timer: GlobalTimer, + linkno: u8, + destination: u8, + channel: i32, + overrd: i8, + ) -> i8 { + let reply = drtio::aux_transact( + aux_mutex, + linkno, &drtioaux_async::Packet::InjectionStatusRequest { destination: destination, channel: channel as _, - overrd: overrd as _}, - timer).await; + overrd: overrd as _, + }, + timer, + ) + .await; match reply { Ok(drtioaux_async::Packet::InjectionStatusReply { value }) => return value as i8, Ok(packet) => error!("received unexpected aux packet: {:?}", packet), - Err("link went down") => { debug!("link is down"); }, - Err(e) => error!("aux packet error ({})", e) + Err("link went down") => { + debug!("link is down"); + } + Err(e) => error!("aux packet error ({})", e), } 0 } @@ -157,8 +196,12 @@ macro_rules! dispatch { }} } -async fn handle_connection(stream: &TcpStream, timer: GlobalTimer, - _aux_mutex: &Rc>, _routing_table: &drtio_routing::RoutingTable) -> Result<()> { +async fn handle_connection( + stream: &TcpStream, + timer: GlobalTimer, + _aux_mutex: &Rc>, + _routing_table: &drtio_routing::RoutingTable, +) -> Result<()> { if !expect(&stream, b"ARTIQ moninj\n").await? { return Err(Error::UnexpectedPattern); } diff --git a/src/runtime/src/panic.rs b/src/runtime/src/panic.rs index 9d5ba3b..7ec2a21 100644 --- a/src/runtime/src/panic.rs +++ b/src/runtime/src/panic.rs @@ -1,14 +1,13 @@ -use libboard_zynq::{print, println}; -use libregister::RegisterR; -use libcortex_a9::regs::MPIDR; -use unwind::backtrace; - #[cfg(feature = "target_kasli_soc")] use libboard_zynq::error_led::ErrorLED; -use crate::comms::soft_panic_main; -use log::error; -use libboard_zynq::timer::GlobalTimer; +use libboard_zynq::{print, println, timer::GlobalTimer}; use libconfig::Config; +use libcortex_a9::regs::MPIDR; +use libregister::RegisterR; +use log::error; +use unwind::backtrace; + +use crate::comms::soft_panic_main; static mut PANICKED: [bool; 2] = [false; 2]; static mut SOFT_PANICKED: bool = false; @@ -68,9 +67,7 @@ fn soft_panic(info: &core::panic::PanicInfo) -> ! { let timer = GlobalTimer::start(); let cfg = match Config::new() { Ok(cfg) => cfg, - Err(_) => { - Config::new_dummy() - } + Err(_) => Config::new_dummy(), }; soft_panic_main(timer, cfg); -} \ No newline at end of file +} diff --git a/src/runtime/src/proto_async.rs b/src/runtime/src/proto_async.rs index f084eec..d109520 100644 --- a/src/runtime/src/proto_async.rs +++ b/src/runtime/src/proto_async.rs @@ -1,8 +1,7 @@ -use core::cmp::min; -use core::cell::RefCell; +use core::{cell::RefCell, cmp::min}; -use libboard_zynq::smoltcp; use libasync::smoltcp::TcpStream; +use libboard_zynq::smoltcp; type Result = core::result::Result; @@ -14,25 +13,27 @@ enum RecvState { pub async fn expect(stream: &TcpStream, pattern: &[u8]) -> Result { let mut state = RecvState::NeedsMore(0, true); loop { - state = stream.recv(|buf| { - let mut consumed = 0; - if let RecvState::NeedsMore(mut cur_index, _) = state { - for b in buf.iter() { - consumed += 1; - if *b == pattern[cur_index] { - if cur_index + 1 == pattern.len() { - return (consumed, RecvState::Completed(true)); + state = stream + .recv(|buf| { + let mut consumed = 0; + if let RecvState::NeedsMore(mut cur_index, _) = state { + for b in buf.iter() { + consumed += 1; + if *b == pattern[cur_index] { + if cur_index + 1 == pattern.len() { + return (consumed, RecvState::Completed(true)); + } + } else { + return (consumed, RecvState::Completed(false)); } - } else { - return (consumed, RecvState::Completed(false)); + cur_index += 1; } - cur_index += 1; + (consumed, RecvState::NeedsMore(cur_index, true)) + } else { + unreachable!(); } - (consumed, RecvState::NeedsMore(cur_index, true)) - } else { - unreachable!(); - } - }).await?; + }) + .await?; if let RecvState::Completed(result) = state { return Ok(result); } @@ -40,15 +41,11 @@ pub async fn expect(stream: &TcpStream, pattern: &[u8]) -> Result { } pub async fn read_bool(stream: &TcpStream) -> Result { - Ok(stream.recv(|buf| { - (1, buf[0] != 0) - }).await?) + Ok(stream.recv(|buf| (1, buf[0] != 0)).await?) } pub async fn read_i8(stream: &TcpStream) -> Result { - Ok(stream.recv(|buf| { - (1, buf[0] as i8) - }).await?) + Ok(stream.recv(|buf| (1, buf[0] as i8)).await?) } pub async fn read_i32(stream: &TcpStream) -> Result { @@ -68,12 +65,14 @@ pub async fn read_chunk(stream: &TcpStream, destination: &mut [u8]) -> Result<() let destination = RefCell::new(destination); let mut done = 0; while done < total { - let count = stream.recv(|buf| { - let mut destination = destination.borrow_mut(); - let count = min(total - done, buf.len()); - destination[done..done + count].copy_from_slice(&buf[..count]); - (count, count) - }).await?; + let count = stream + .recv(|buf| { + let mut destination = destination.borrow_mut(); + let count = min(total - done, buf.len()); + destination[done..done + count].copy_from_slice(&buf[..count]); + (count, count) + }) + .await?; done += count; } Ok(()) diff --git a/src/runtime/src/rpc.rs b/src/runtime/src/rpc.rs index 44b6394..3db2477 100644 --- a/src/runtime/src/rpc.rs +++ b/src/runtime/src/rpc.rs @@ -1,18 +1,17 @@ -use core::str; -use core::future::Future; -use cslice::{CSlice, CMutSlice}; -use log::trace; -use byteorder::{NativeEndian, ByteOrder}; - -use core_io::{Write, Error}; -use libboard_zynq::smoltcp; -use libasync::smoltcp::TcpStream; use alloc::boxed::Box; -use async_recursion::async_recursion; +use core::{future::Future, str}; +use async_recursion::async_recursion; +use byteorder::{ByteOrder, NativeEndian}; +use core_io::{Error, Write}; +use cslice::{CMutSlice, CSlice}; use io::proto::ProtoWrite; +use libasync::smoltcp::TcpStream; +use libboard_zynq::smoltcp; +use log::trace; + +use self::tag::{split_tag, Tag, TagIterator}; use crate::proto_async; -use self::tag::{Tag, TagIterator, split_tag}; #[inline] fn round_up(val: usize, power_of_two: usize) -> usize { @@ -52,17 +51,17 @@ async unsafe fn recv_elements( elt_tag: Tag<'async_recursion>, length: usize, storage: *mut (), - alloc: &(impl Fn(usize) -> F + 'async_recursion) + alloc: &(impl Fn(usize) -> F + 'async_recursion), ) -> Result<(), smoltcp::Error> where - F: Future, + F: Future, { // List of simple types are special-cased in the protocol for performance. match elt_tag { Tag::Bool => { let dest = core::slice::from_raw_parts_mut(storage as *mut u8, length); proto_async::read_chunk(stream, dest).await?; - }, + } Tag::Int32 => { let ptr = storage as *mut u32; let dest = core::slice::from_raw_parts_mut(ptr as *mut u8, length * 4); @@ -70,7 +69,7 @@ where drop(dest); let dest = core::slice::from_raw_parts_mut(ptr, length); NativeEndian::from_slice_u32(dest); - }, + } Tag::Int64 | Tag::Float64 => { let ptr = storage as *mut u64; let dest = core::slice::from_raw_parts_mut(ptr as *mut u8, length * 8); @@ -78,7 +77,7 @@ where drop(dest); let dest = core::slice::from_raw_parts_mut(ptr, length); NativeEndian::from_slice_u64(dest); - }, + } _ => { let mut data = storage; for _ in 0..length { @@ -95,36 +94,37 @@ where /// invoked any number of times with the size of the required allocation as a parameter /// (which is assumed to be correctly aligned for all payload types). #[async_recursion(?Send)] -async unsafe fn recv_value(stream: &TcpStream, tag: Tag<'async_recursion>, data: &mut *mut (), - alloc: &(impl Fn(usize) -> F + 'async_recursion)) - -> Result<(), smoltcp::Error> - where F: Future +async unsafe fn recv_value( + stream: &TcpStream, + tag: Tag<'async_recursion>, + data: &mut *mut (), + alloc: &(impl Fn(usize) -> F + 'async_recursion), +) -> Result<(), smoltcp::Error> +where + F: Future, { macro_rules! consume_value { - ($ty:ty, |$ptr:ident| $map:expr) => ({ + ($ty:ty, | $ptr:ident | $map:expr) => {{ let $ptr = align_ptr_mut::<$ty>(*data); *data = $ptr.offset(1) as *mut (); $map - }) + }}; } match tag { Tag::None => Ok(()), - Tag::Bool => - consume_value!(i8, |ptr| { - *ptr = proto_async::read_i8(stream).await?; - Ok(()) - }), - Tag::Int32 => - consume_value!(i32, |ptr| { - *ptr = proto_async::read_i32(stream).await?; - Ok(()) - }), - Tag::Int64 | Tag::Float64 => - consume_value!(i64, |ptr| { - *ptr = proto_async::read_i64(stream).await?; - Ok(()) - }), + Tag::Bool => consume_value!(i8, |ptr| { + *ptr = proto_async::read_i8(stream).await?; + Ok(()) + }), + Tag::Int32 => consume_value!(i32, |ptr| { + *ptr = proto_async::read_i32(stream).await?; + Ok(()) + }), + Tag::Int64 | Tag::Float64 => consume_value!(i64, |ptr| { + *ptr = proto_async::read_i64(stream).await?; + Ok(()) + }), Tag::String | Tag::Bytes | Tag::ByteArray => { consume_value!(CMutSlice, |ptr| { let length = proto_async::read_i32(stream).await? as usize; @@ -148,7 +148,10 @@ async unsafe fn recv_value(stream: &TcpStream, tag: Tag<'async_recursion>, da } Tag::List(it) => { #[repr(C)] - struct List { elements: *mut (), length: usize } + struct List { + elements: *mut (), + length: usize, + } consume_value!(*mut List, |ptr_to_list| { let tag = it.clone().next().expect("truncated tag"); let length = proto_async::read_i32(stream).await? as usize; @@ -180,7 +183,7 @@ async unsafe fn recv_value(stream: &TcpStream, tag: Tag<'async_recursion>, da for _ in 0..num_dims { let len = proto_async::read_i32(stream).await? as usize; total_len *= len; - consume_value!(usize, |ptr| *ptr = len ) + consume_value!(usize, |ptr| *ptr = len) } // Allocate backing storage for elements; deserialize them. @@ -198,14 +201,18 @@ async unsafe fn recv_value(stream: &TcpStream, tag: Tag<'async_recursion>, da Ok(()) } Tag::Keyword(_) => unreachable!(), - Tag::Object => unreachable!() + Tag::Object => unreachable!(), } } -pub async fn recv_return(stream: &TcpStream, tag_bytes: &[u8], data: *mut (), - alloc: &impl Fn(usize) -> F) - -> Result<(), smoltcp::Error> - where F: Future +pub async fn recv_return( + stream: &TcpStream, + tag_bytes: &[u8], + data: *mut (), + alloc: &impl Fn(usize) -> F, +) -> Result<(), smoltcp::Error> +where + F: Future, { let mut it = TagIterator::new(tag_bytes); trace!("recv ...->{}", it); @@ -217,10 +224,8 @@ pub async fn recv_return(stream: &TcpStream, tag_bytes: &[u8], data: *mut (), Ok(()) } -unsafe fn send_elements(writer: &mut W, elt_tag: Tag, length: usize, data: *const ()) - -> Result<(), Error> - where W: Write + ?Sized -{ +unsafe fn send_elements(writer: &mut W, elt_tag: Tag, length: usize, data: *const ()) -> Result<(), Error> +where W: Write + ?Sized { writer.write_u8(elt_tag.as_u8())?; match elt_tag { // we cannot use NativeEndian::from_slice_i32 as the data is not mutable, @@ -228,15 +233,15 @@ unsafe fn send_elements(writer: &mut W, elt_tag: Tag, length: usize, data: *c Tag::Bool => { let slice = core::slice::from_raw_parts(data as *const u8, length); writer.write_all(slice)?; - }, + } Tag::Int32 => { let slice = core::slice::from_raw_parts(data as *const u8, length * 4); writer.write_all(slice)?; - }, + } Tag::Int64 | Tag::Float64 => { let slice = core::slice::from_raw_parts(data as *const u8, length * 8); writer.write_all(slice)?; - }, + } _ => { let mut data = data; for _ in 0..length { @@ -247,36 +252,26 @@ unsafe fn send_elements(writer: &mut W, elt_tag: Tag, length: usize, data: *c Ok(()) } -unsafe fn send_value(writer: &mut W, tag: Tag, data: &mut *const ()) - -> Result<(), Error> - where W: Write + ?Sized -{ +unsafe fn send_value(writer: &mut W, tag: Tag, data: &mut *const ()) -> Result<(), Error> +where W: Write + ?Sized { macro_rules! consume_value { - ($ty:ty, |$ptr:ident| $map:expr) => ({ + ($ty:ty, | $ptr:ident | $map:expr) => {{ let $ptr = align_ptr::<$ty>(*data); *data = $ptr.offset(1) as *const (); $map - }) + }}; } writer.write_u8(tag.as_u8())?; match tag { Tag::None => Ok(()), - Tag::Bool => - consume_value!(u8, |ptr| - writer.write_u8(*ptr)), - Tag::Int32 => - consume_value!(u32, |ptr| - writer.write_u32(*ptr)), - Tag::Int64 | Tag::Float64 => - consume_value!(u64, |ptr| - writer.write_u64(*ptr)), - Tag::String => - consume_value!(CSlice, |ptr| - writer.write_string(str::from_utf8((*ptr).as_ref()).unwrap())), - Tag::Bytes | Tag::ByteArray => - consume_value!(CSlice, |ptr| - writer.write_bytes((*ptr).as_ref())), + Tag::Bool => consume_value!(u8, |ptr| writer.write_u8(*ptr)), + Tag::Int32 => consume_value!(u32, |ptr| writer.write_u32(*ptr)), + Tag::Int64 | Tag::Float64 => consume_value!(u64, |ptr| writer.write_u64(*ptr)), + Tag::String => consume_value!(CSlice, |ptr| { + writer.write_string(str::from_utf8((*ptr).as_ref()).unwrap()) + }), + Tag::Bytes | Tag::ByteArray => consume_value!(CSlice, |ptr| writer.write_bytes((*ptr).as_ref())), Tag::Tuple(it, arity) => { let mut it = it.clone(); writer.write_u8(arity)?; @@ -291,7 +286,10 @@ unsafe fn send_value(writer: &mut W, tag: Tag, data: &mut *const ()) } Tag::List(it) => { #[repr(C)] - struct List { elements: *const (), length: u32 } + struct List { + elements: *const (), + length: u32, + } consume_value!(&List, |ptr| { let length = (**ptr).length as usize; writer.write_u32((*ptr).length)?; @@ -301,7 +299,7 @@ unsafe fn send_value(writer: &mut W, tag: Tag, data: &mut *const ()) } Tag::Array(it, num_dims) => { writer.write_u8(num_dims)?; - consume_value!(*const(), |buffer| { + consume_value!(*const (), |buffer| { let elt_tag = it.clone().next().expect("truncated tag"); let mut total_len = 1; @@ -324,7 +322,9 @@ unsafe fn send_value(writer: &mut W, tag: Tag, data: &mut *const ()) } Tag::Keyword(it) => { #[repr(C)] - struct Keyword<'a> { name: CSlice<'a, u8> } + struct Keyword<'a> { + name: CSlice<'a, u8>, + } consume_value!(Keyword, |ptr| { writer.write_string(str::from_utf8((*ptr).name.as_ref()).unwrap())?; let tag = it.clone().next().expect("truncated tag"); @@ -336,17 +336,16 @@ unsafe fn send_value(writer: &mut W, tag: Tag, data: &mut *const ()) } Tag::Object => { #[repr(C)] - struct Object { id: u32 } - consume_value!(*const Object, |ptr| - writer.write_u32((**ptr).id)) + struct Object { + id: u32, + } + consume_value!(*const Object, |ptr| writer.write_u32((**ptr).id)) } } } -pub fn send_args(writer: &mut W, service: u32, tag_bytes: &[u8], data: *const *const ()) - -> Result<(), Error> - where W: Write + ?Sized -{ +pub fn send_args(writer: &mut W, service: u32, tag_bytes: &[u8], data: *const *const ()) -> Result<(), Error> +where W: Write + ?Sized { let (arg_tags_bytes, return_tag_bytes) = split_tag(tag_bytes); let mut args_it = TagIterator::new(arg_tags_bytes); @@ -359,7 +358,7 @@ pub fn send_args(writer: &mut W, service: u32, tag_bytes: &[u8], data: *const let mut data = unsafe { *data.offset(index) }; unsafe { send_value(writer, arg_tag, &mut data)? }; } else { - break + break; } } writer.write_u8(0)?; @@ -372,10 +371,10 @@ mod tag { use core::fmt; pub fn split_tag(tag_bytes: &[u8]) -> (&[u8], &[u8]) { - let tag_separator = - tag_bytes.iter() - .position(|&b| b == b':') - .expect("tag without a return separator"); + let tag_separator = tag_bytes + .iter() + .position(|&b| b == b':') + .expect("tag without a return separator"); let (arg_tags_bytes, rest) = tag_bytes.split_at(tag_separator); let return_tag_bytes = &rest[1..]; (arg_tags_bytes, return_tag_bytes) @@ -396,7 +395,7 @@ mod tag { Array(TagIterator<'a>, u8), Range(TagIterator<'a>), Keyword(TagIterator<'a>), - Object + Object, } impl<'a> Tag<'a> { @@ -431,14 +430,15 @@ mod tag { Tag::Tuple(it, arity) => { let it = it.clone(); it.take(arity.into()).map(|t| t.alignment()).max().unwrap() - }, + } Tag::Range(it) => { let it = it.clone(); it.take(3).map(|t| t.alignment()).max().unwrap() } // the ptr/length(s) pair is basically CSlice - Tag::Bytes | Tag::String | Tag::ByteArray | Tag::List(_) | Tag::Array(_, _) => - core::mem::align_of::>(), + Tag::Bytes | Tag::String | Tag::ByteArray | Tag::List(_) | Tag::Array(_, _) => { + core::mem::align_of::>() + } Tag::Keyword(_) => unreachable!("Tag::Keyword should not appear in composite types"), Tag::Object => core::mem::align_of::(), } @@ -484,7 +484,7 @@ mod tag { #[derive(Debug, Clone, Copy)] pub struct TagIterator<'a> { - data: &'a [u8] + data: &'a [u8], } impl<'a> TagIterator<'a> { @@ -492,13 +492,14 @@ mod tag { TagIterator { data } } - fn sub(&mut self, count: u8) -> TagIterator<'a> { let data = self.data; for _ in 0..count { self.next().expect("truncated tag"); } - TagIterator { data: &data[..(data.len() - self.data.len())] } + TagIterator { + data: &data[..(data.len() - self.data.len())], + } } } @@ -507,7 +508,7 @@ mod tag { fn next(&mut self) -> Option> { if self.data.len() == 0 { - return None + return None; } let tag_byte = self.data[0]; @@ -535,7 +536,7 @@ mod tag { b'r' => Tag::Range(self.sub(1)), b'k' => Tag::Keyword(self.sub(1)), b'O' => Tag::Object, - _ => unreachable!() + _ => unreachable!(), }) } } @@ -552,22 +553,14 @@ mod tag { } match tag { - Tag::None => - write!(f, "None")?, - Tag::Bool => - write!(f, "Bool")?, - Tag::Int32 => - write!(f, "Int32")?, - Tag::Int64 => - write!(f, "Int64")?, - Tag::Float64 => - write!(f, "Float64")?, - Tag::String => - write!(f, "String")?, - Tag::Bytes => - write!(f, "Bytes")?, - Tag::ByteArray => - write!(f, "ByteArray")?, + Tag::None => write!(f, "None")?, + Tag::Bool => write!(f, "Bool")?, + Tag::Int32 => write!(f, "Int32")?, + Tag::Int64 => write!(f, "Int64")?, + Tag::Float64 => write!(f, "Float64")?, + Tag::String => write!(f, "String")?, + Tag::Bytes => write!(f, "Bytes")?, + Tag::ByteArray => write!(f, "ByteArray")?, Tag::Tuple(it, _) => { write!(f, "Tuple(")?; it.fmt(f)?; @@ -593,8 +586,7 @@ mod tag { it.fmt(f)?; write!(f, ")")?; } - Tag::Object => - write!(f, "Object")?, + Tag::Object => write!(f, "Object")?, } } diff --git a/src/runtime/src/rtio_acp.rs b/src/runtime/src/rtio_acp.rs index f08c517..5b90514 100644 --- a/src/runtime/src/rtio_acp.rs +++ b/src/runtime/src/rtio_acp.rs @@ -1,19 +1,18 @@ -use cslice::CSlice; -use vcell::VolatileCell; -use libcortex_a9::asm; -use crate::artiq_raise; use core::sync::atomic::{fence, Ordering}; -use crate::pl::csr; -use crate::rtio_mgt::resolve_channel_name; +use cslice::CSlice; +use libcortex_a9::asm; +use vcell::VolatileCell; -pub const RTIO_O_STATUS_WAIT: i32 = 1; -pub const RTIO_O_STATUS_UNDERFLOW: i32 = 2; -pub const RTIO_O_STATUS_DESTINATION_UNREACHABLE: i32 = 4; -pub const RTIO_I_STATUS_WAIT_EVENT: i32 = 1; -pub const RTIO_I_STATUS_OVERFLOW: i32 = 2; -pub const RTIO_I_STATUS_WAIT_STATUS: i32 = 4; // TODO -pub const RTIO_I_STATUS_DESTINATION_UNREACHABLE: i32 = 8; +use crate::{artiq_raise, pl::csr, rtio_mgt::resolve_channel_name}; + +pub const RTIO_O_STATUS_WAIT: i32 = 1; +pub const RTIO_O_STATUS_UNDERFLOW: i32 = 2; +pub const RTIO_O_STATUS_DESTINATION_UNREACHABLE: i32 = 4; +pub const RTIO_I_STATUS_WAIT_EVENT: i32 = 1; +pub const RTIO_I_STATUS_OVERFLOW: i32 = 2; +pub const RTIO_I_STATUS_WAIT_STATUS: i32 = 4; // TODO +pub const RTIO_I_STATUS_DESTINATION_UNREACHABLE: i32 = 8; #[repr(C)] pub struct TimestampedData { @@ -47,10 +46,10 @@ static mut TRANSACTION_BUFFER: Transaction = Transaction { reply_timestamp: VolatileCell::new(0), padding0: [0; 2], padding1: [0; 2], - padding2: [0; 2] + padding2: [0; 2], }; -pub extern fn init() { +pub extern "C" fn init() { unsafe { csr::rtio_core::reset_write(1); csr::rtio::engine_addr_base_write(&TRANSACTION_BUFFER as *const Transaction as u32); @@ -58,7 +57,7 @@ pub extern fn init() { } } -pub extern fn get_counter() -> i64 { +pub extern "C" fn get_counter() -> i64 { unsafe { csr::rtio::counter_update_write(1); csr::rtio::counter_read() as i64 @@ -67,15 +66,15 @@ pub extern fn get_counter() -> i64 { static mut NOW: i64 = 0; -pub extern fn now_mu() -> i64 { +pub extern "C" fn now_mu() -> i64 { unsafe { NOW } } -pub extern fn at_mu(t: i64) { +pub extern "C" fn at_mu(t: i64) { unsafe { NOW = t } } -pub extern fn delay_mu(dt: i64) { +pub extern "C" fn delay_mu(dt: i64) { unsafe { NOW += dt } } @@ -87,18 +86,34 @@ unsafe fn process_exceptional_status(channel: i32, status: i32) { while csr::rtio::o_status_read() as i32 & RTIO_O_STATUS_WAIT != 0 {} } if status & RTIO_O_STATUS_UNDERFLOW != 0 { - artiq_raise!("RTIOUnderflow", - format!("RTIO underflow at {{1}} mu, channel 0x{:04x}:{}, slack {{2}} mu", channel, resolve_channel_name(channel as u32)), - channel as i64, timestamp, timestamp - get_counter()); + artiq_raise!( + "RTIOUnderflow", + format!( + "RTIO underflow at {{1}} mu, channel 0x{:04x}:{}, slack {{2}} mu", + channel, + resolve_channel_name(channel as u32) + ), + channel as i64, + timestamp, + timestamp - get_counter() + ); } if status & RTIO_O_STATUS_DESTINATION_UNREACHABLE != 0 { - artiq_raise!("RTIODestinationUnreachable", - format!("RTIO destination unreachable, output, at {{0}} mu, channel 0x{:04x}:{}", channel, resolve_channel_name(channel as u32)), - timestamp, channel as i64, 0); + artiq_raise!( + "RTIODestinationUnreachable", + format!( + "RTIO destination unreachable, output, at {{0}} mu, channel 0x{:04x}:{}", + channel, + resolve_channel_name(channel as u32) + ), + timestamp, + channel as i64, + 0 + ); } } -pub extern fn output(target: i32, data: i32) { +pub extern "C" fn output(target: i32, data: i32) { unsafe { // Clear status so we can observe response TRANSACTION_BUFFER.reply_status.set(0); @@ -126,7 +141,7 @@ pub extern fn output(target: i32, data: i32) { } } -pub extern fn output_wide(target: i32, data: CSlice) { +pub extern "C" fn output_wide(target: i32, data: CSlice) { unsafe { // Clear status so we can observe response TRANSACTION_BUFFER.reply_status.set(0); @@ -143,7 +158,7 @@ pub extern fn output_wide(target: i32, data: CSlice) { loop { status = TRANSACTION_BUFFER.reply_status.get(); if status != 0 { - break + break; } } @@ -154,8 +169,8 @@ pub extern fn output_wide(target: i32, data: CSlice) { } } -pub extern fn input_timestamp(timeout: i64, channel: i32) -> i64 { - unsafe { +pub extern "C" fn input_timestamp(timeout: i64, channel: i32) -> i64 { + unsafe { // Clear status so we can observe response TRANSACTION_BUFFER.reply_status.set(0); @@ -171,29 +186,45 @@ pub extern fn input_timestamp(timeout: i64, channel: i32) -> i64 { loop { status = TRANSACTION_BUFFER.reply_status.get(); if status != 0 { - break + break; } } if status & RTIO_I_STATUS_OVERFLOW != 0 { - artiq_raise!("RTIOOverflow", - format!("RTIO input overflow on channel 0x{:04x}:{}", channel, resolve_channel_name(channel as u32)), - channel as i64, 0, 0); + artiq_raise!( + "RTIOOverflow", + format!( + "RTIO input overflow on channel 0x{:04x}:{}", + channel, + resolve_channel_name(channel as u32) + ), + channel as i64, + 0, + 0 + ); } if status & RTIO_I_STATUS_WAIT_EVENT != 0 { - return -1 + return -1; } if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 { - artiq_raise!("RTIODestinationUnreachable", - format!("RTIO destination unreachable, input, on channel 0x{:04x}:{}", channel, resolve_channel_name(channel as u32)), - channel as i64, 0, 0); + artiq_raise!( + "RTIODestinationUnreachable", + format!( + "RTIO destination unreachable, input, on channel 0x{:04x}:{}", + channel, + resolve_channel_name(channel as u32) + ), + channel as i64, + 0, + 0 + ); } TRANSACTION_BUFFER.reply_timestamp.get() } } -pub extern fn input_data(channel: i32) -> i32 { +pub extern "C" fn input_data(channel: i32) -> i32 { unsafe { TRANSACTION_BUFFER.reply_status.set(0); @@ -209,26 +240,42 @@ pub extern fn input_data(channel: i32) -> i32 { loop { status = TRANSACTION_BUFFER.reply_status.get(); if status != 0 { - break + break; } } if status & RTIO_I_STATUS_OVERFLOW != 0 { - artiq_raise!("RTIOOverflow", - format!("RTIO input overflow on channel 0x{:04x}:{}", channel, resolve_channel_name(channel as u32)), - channel as i64, 0, 0); + artiq_raise!( + "RTIOOverflow", + format!( + "RTIO input overflow on channel 0x{:04x}:{}", + channel, + resolve_channel_name(channel as u32) + ), + channel as i64, + 0, + 0 + ); } if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 { - artiq_raise!("RTIODestinationUnreachable", - format!("RTIO destination unreachable, input, on channel 0x{:04x}:{}", channel, resolve_channel_name(channel as u32)), - channel as i64, 0, 0); + artiq_raise!( + "RTIODestinationUnreachable", + format!( + "RTIO destination unreachable, input, on channel 0x{:04x}:{}", + channel, + resolve_channel_name(channel as u32) + ), + channel as i64, + 0, + 0 + ); } TRANSACTION_BUFFER.reply_data.get() } } -pub extern fn input_timestamped_data(timeout: i64, channel: i32) -> TimestampedData { +pub extern "C" fn input_timestamped_data(timeout: i64, channel: i32) -> TimestampedData { unsafe { TRANSACTION_BUFFER.reply_status.set(0); @@ -244,19 +291,35 @@ pub extern fn input_timestamped_data(timeout: i64, channel: i32) -> TimestampedD loop { status = TRANSACTION_BUFFER.reply_status.get(); if status != 0 { - break + break; } } if status & RTIO_I_STATUS_OVERFLOW != 0 { - artiq_raise!("RTIOOverflow", - format!("RTIO input overflow on channel 0x{:04x}:{}", channel, resolve_channel_name(channel as u32)), - channel as i64, 0, 0); + artiq_raise!( + "RTIOOverflow", + format!( + "RTIO input overflow on channel 0x{:04x}:{}", + channel, + resolve_channel_name(channel as u32) + ), + channel as i64, + 0, + 0 + ); } if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 { - artiq_raise!("RTIODestinationUnreachable", - format!("RTIO destination unreachable, input, on channel 0x{:04x}:{}", channel, resolve_channel_name(channel as u32)), - channel as i64, 0, 0); + artiq_raise!( + "RTIODestinationUnreachable", + format!( + "RTIO destination unreachable, input, on channel 0x{:04x}:{}", + channel, + resolve_channel_name(channel as u32) + ), + channel as i64, + 0, + 0 + ); } TimestampedData { diff --git a/src/runtime/src/rtio_clocking.rs b/src/runtime/src/rtio_clocking.rs index 5340e6d..880cc08 100644 --- a/src/runtime/src/rtio_clocking.rs +++ b/src/runtime/src/rtio_clocking.rs @@ -1,14 +1,15 @@ -use log::{info, warn}; -use libboard_zynq::timer::GlobalTimer; use embedded_hal::blocking::delay::DelayMs; -use libconfig::Config; use libboard_artiq::pl; #[cfg(has_si5324)] +use libboard_artiq::si5324; +#[cfg(has_si5324)] use libboard_zynq::i2c::I2c; +use libboard_zynq::timer::GlobalTimer; +use libconfig::Config; +use log::{info, warn}; + #[cfg(has_si5324)] use crate::i2c; -#[cfg(has_si5324)] -use libboard_artiq::si5324; #[derive(Debug, PartialEq, Copy, Clone)] #[allow(non_camel_case_types)] @@ -37,22 +38,21 @@ fn get_rtio_clock_cfg(cfg: &Config) -> RtioClock { "ext0_synth0_10to125" => RtioClock::Ext0_Synth0_10to125, "ext0_synth0_100to125" => RtioClock::Ext0_Synth0_100to125, "ext0_synth0_125to125" => RtioClock::Ext0_Synth0_125to125, - _ => { + _ => { warn!("Unrecognised rtio_clock setting. Falling back to default."); - RtioClock::Default + RtioClock::Default } }; - } - else { + } else { warn!("error reading configuration. Falling back to default."); } if res == RtioClock::Default { - #[cfg(rtio_frequency="100.0")] + #[cfg(rtio_frequency = "100.0")] { warn!("Using default configuration - internal 100MHz RTIO clock."); return RtioClock::Int_100; } - #[cfg(rtio_frequency="125.0")] + #[cfg(rtio_frequency = "125.0")] { warn!("Using default configuration - internal 125MHz RTIO clock."); return RtioClock::Int_125; @@ -85,16 +85,14 @@ fn init_rtio(timer: &mut GlobalTimer) { pl::csr::rtio_core::reset_phy_write(1); } info!("SYS PLL locked"); - } #[cfg(has_drtio)] -fn init_drtio(timer: &mut GlobalTimer) -{ +fn init_drtio(timer: &mut GlobalTimer) { unsafe { pl::csr::drtio_transceiver::stable_clkin_write(1); } - + timer.delay_ms(20); // wait for CPLL/QPLL/SYS PLL lock let clk = unsafe { pl::csr::sys_crg::current_clock_read() }; if clk == 1 { @@ -115,116 +113,126 @@ const SI5324_EXT_INPUT: si5324::Input = si5324::Input::Ckin1; #[cfg(has_si5324)] fn setup_si5324(i2c: &mut I2c, timer: &mut GlobalTimer, clk: RtioClock) { let (si5324_settings, si5324_ref_input) = match clk { - RtioClock::Ext0_Synth0_10to125 => { // 125 MHz output from 10 MHz CLKINx reference, 504 Hz BW + RtioClock::Ext0_Synth0_10to125 => { + // 125 MHz output from 10 MHz CLKINx reference, 504 Hz BW info!("using 10MHz reference to make 125MHz RTIO clock with PLL"); ( si5324::FrequencySettings { - n1_hs : 10, - nc1_ls : 4, - n2_hs : 10, - n2_ls : 300, - n31 : 6, - n32 : 6, - bwsel : 4, - crystal_as_ckin2: false + n1_hs: 10, + nc1_ls: 4, + n2_hs: 10, + n2_ls: 300, + n31: 6, + n32: 6, + bwsel: 4, + crystal_as_ckin2: false, }, - SI5324_EXT_INPUT + SI5324_EXT_INPUT, ) - }, - RtioClock::Ext0_Synth0_100to125 => { // 125MHz output, from 100MHz CLKINx reference, 586 Hz loop bandwidth + } + RtioClock::Ext0_Synth0_100to125 => { + // 125MHz output, from 100MHz CLKINx reference, 586 Hz loop bandwidth info!("using 100MHz reference to make 125MHz RTIO clock with PLL"); ( si5324::FrequencySettings { - n1_hs : 10, - nc1_ls : 4, - n2_hs : 10, - n2_ls : 260, - n31 : 52, - n32 : 52, - bwsel : 4, - crystal_as_ckin2: false + n1_hs: 10, + nc1_ls: 4, + n2_hs: 10, + n2_ls: 260, + n31: 52, + n32: 52, + bwsel: 4, + crystal_as_ckin2: false, }, - SI5324_EXT_INPUT + SI5324_EXT_INPUT, ) - }, - RtioClock::Ext0_Synth0_125to125 => { // 125MHz output, from 125MHz CLKINx reference, 606 Hz loop bandwidth + } + RtioClock::Ext0_Synth0_125to125 => { + // 125MHz output, from 125MHz CLKINx reference, 606 Hz loop bandwidth info!("using 125MHz reference to make 125MHz RTIO clock with PLL"); ( si5324::FrequencySettings { - n1_hs : 5, - nc1_ls : 8, - n2_hs : 7, - n2_ls : 360, - n31 : 63, - n32 : 63, - bwsel : 4, - crystal_as_ckin2: false + n1_hs: 5, + nc1_ls: 8, + n2_hs: 7, + n2_ls: 360, + n31: 63, + n32: 63, + bwsel: 4, + crystal_as_ckin2: false, }, - SI5324_EXT_INPUT + SI5324_EXT_INPUT, ) - }, - RtioClock::Int_150 => { // 150MHz output, from crystal + } + RtioClock::Int_150 => { + // 150MHz output, from crystal info!("using internal 150MHz RTIO clock"); ( si5324::FrequencySettings { - n1_hs : 9, - nc1_ls : 4, - n2_hs : 10, - n2_ls : 33732, - n31 : 7139, - n32 : 7139, - bwsel : 3, - crystal_as_ckin2: true + n1_hs: 9, + nc1_ls: 4, + n2_hs: 10, + n2_ls: 33732, + n31: 7139, + n32: 7139, + bwsel: 3, + crystal_as_ckin2: true, }, - si5324::Input::Ckin2 + si5324::Input::Ckin2, ) - }, - RtioClock::Int_100 => { // 100MHz output, from crystal + } + RtioClock::Int_100 => { + // 100MHz output, from crystal info!("using internal 100MHz RTIO clock"); ( si5324::FrequencySettings { - n1_hs : 9, - nc1_ls : 6, - n2_hs : 10, - n2_ls : 33732, - n31 : 7139, - n32 : 7139, - bwsel : 3, - crystal_as_ckin2: true + n1_hs: 9, + nc1_ls: 6, + n2_hs: 10, + n2_ls: 33732, + n31: 7139, + n32: 7139, + bwsel: 3, + crystal_as_ckin2: true, }, - si5324::Input::Ckin2 + si5324::Input::Ckin2, ) - }, - RtioClock::Int_125 => { // 125MHz output, from crystal, 7 Hz + } + RtioClock::Int_125 => { + // 125MHz output, from crystal, 7 Hz info!("using internal 125MHz RTIO clock"); ( si5324::FrequencySettings { - n1_hs : 10, - nc1_ls : 4, - n2_hs : 10, - n2_ls : 19972, - n31 : 4565, - n32 : 4565, - bwsel : 4, - crystal_as_ckin2: true + n1_hs: 10, + nc1_ls: 4, + n2_hs: 10, + n2_ls: 19972, + n31: 4565, + n32: 4565, + bwsel: 4, + crystal_as_ckin2: true, }, - si5324::Input::Ckin2 + si5324::Input::Ckin2, ) - }, - _ => { // same setting as Int_125, but fallback to default - warn!("rtio_clock setting '{:?}' is unsupported. Falling back to default internal 125MHz RTIO clock.", clk); + } + _ => { + // same setting as Int_125, but fallback to default + warn!( + "rtio_clock setting '{:?}' is unsupported. Falling back to default internal 125MHz RTIO clock.", + clk + ); ( si5324::FrequencySettings { - n1_hs : 10, - nc1_ls : 4, - n2_hs : 10, - n2_ls : 19972, - n31 : 4565, - n32 : 4565, - bwsel : 4, - crystal_as_ckin2: true + n1_hs: 10, + nc1_ls: 4, + n2_hs: 10, + n2_ls: 19972, + n31: 4565, + n32: 4565, + bwsel: 4, + crystal_as_ckin2: true, }, - si5324::Input::Ckin2 + si5324::Input::Ckin2, ) } }; @@ -232,7 +240,6 @@ fn setup_si5324(i2c: &mut I2c, timer: &mut GlobalTimer, clk: RtioClock) { } pub fn init(timer: &mut GlobalTimer, cfg: &Config) { - let clk = get_rtio_clock_cfg(cfg); #[cfg(has_si5324)] { @@ -248,4 +255,4 @@ pub fn init(timer: &mut GlobalTimer, cfg: &Config) { #[cfg(not(has_drtio))] init_rtio(timer); -} \ No newline at end of file +} diff --git a/src/runtime/src/rtio_csr.rs b/src/runtime/src/rtio_csr.rs index 7534a12..2934aca 100644 --- a/src/runtime/src/rtio_csr.rs +++ b/src/runtime/src/rtio_csr.rs @@ -1,18 +1,16 @@ use core::ptr::{read_volatile, write_volatile}; + use cslice::CSlice; -use crate::artiq_raise; +use crate::{artiq_raise, pl::csr, rtio_mgt::resolve_channel_name}; -use crate::pl::csr; -use crate::rtio_mgt::resolve_channel_name; - -pub const RTIO_O_STATUS_WAIT: u8 = 1; -pub const RTIO_O_STATUS_UNDERFLOW: u8 = 2; -pub const RTIO_O_STATUS_DESTINATION_UNREACHABLE: u8 = 4; -pub const RTIO_I_STATUS_WAIT_EVENT: u8 = 1; -pub const RTIO_I_STATUS_OVERFLOW: u8 = 2; -pub const RTIO_I_STATUS_WAIT_STATUS: u8 = 4; -pub const RTIO_I_STATUS_DESTINATION_UNREACHABLE: u8 = 8; +pub const RTIO_O_STATUS_WAIT: u8 = 1; +pub const RTIO_O_STATUS_UNDERFLOW: u8 = 2; +pub const RTIO_O_STATUS_DESTINATION_UNREACHABLE: u8 = 4; +pub const RTIO_I_STATUS_WAIT_EVENT: u8 = 1; +pub const RTIO_I_STATUS_OVERFLOW: u8 = 2; +pub const RTIO_I_STATUS_WAIT_STATUS: u8 = 4; +pub const RTIO_I_STATUS_DESTINATION_UNREACHABLE: u8 = 8; #[repr(C)] pub struct TimestampedData { @@ -20,32 +18,30 @@ pub struct TimestampedData { data: i32, } -pub extern fn init() { +pub extern "C" fn init() { unsafe { csr::rtio_core::reset_write(1); } } -pub extern fn get_counter() -> i64 { +pub extern "C" fn get_counter() -> i64 { unsafe { csr::rtio::counter_update_write(1); csr::rtio::counter_read() as i64 } } -pub extern fn now_mu() -> i64 { - unsafe { - csr::rtio::now_read() as i64 - } +pub extern "C" fn now_mu() -> i64 { + unsafe { csr::rtio::now_read() as i64 } } -pub extern fn at_mu(t: i64) { +pub extern "C" fn at_mu(t: i64) { unsafe { csr::rtio::now_write(t as u64); } } -pub extern fn delay_mu(dt: i64) { +pub extern "C" fn delay_mu(dt: i64) { unsafe { csr::rtio::now_write(csr::rtio::now_read() + dt as u64); } @@ -56,13 +52,13 @@ pub extern fn delay_mu(dt: i64) { pub unsafe fn rtio_o_data_write(offset: usize, data: u32) { write_volatile( csr::rtio::O_DATA_ADDR.offset((csr::rtio::O_DATA_SIZE - 1 - offset) as isize), - data); + data, + ); } #[inline(always)] pub unsafe fn rtio_i_data_read(offset: usize) -> u32 { - read_volatile( - csr::rtio::I_DATA_ADDR.offset((csr::rtio::I_DATA_SIZE - 1 - offset) as isize)) + read_volatile(csr::rtio::I_DATA_ADDR.offset((csr::rtio::I_DATA_SIZE - 1 - offset) as isize)) } #[inline(never)] @@ -72,18 +68,34 @@ unsafe fn process_exceptional_status(channel: i32, status: u8) { while csr::rtio::o_status_read() & RTIO_O_STATUS_WAIT != 0 {} } if status & RTIO_O_STATUS_UNDERFLOW != 0 { - artiq_raise!("RTIOUnderflow", - format!("RTIO underflow at {{1}} mu, channel 0x{:04x}:{}, slack {{2}} mu", channel, resolve_channel_name(channel as u32)), - channel as i64, timestamp, timestamp - get_counter()); + artiq_raise!( + "RTIOUnderflow", + format!( + "RTIO underflow at {{1}} mu, channel 0x{:04x}:{}, slack {{2}} mu", + channel, + resolve_channel_name(channel as u32) + ), + channel as i64, + timestamp, + timestamp - get_counter() + ); } if status & RTIO_O_STATUS_DESTINATION_UNREACHABLE != 0 { - artiq_raise!("RTIODestinationUnreachable", - format!("RTIO destination unreachable, output, at {{0}} mu, channel 0x{:04x}:{}", channel, resolve_channel_name(channel as u32)), - timestamp, channel as i64, 0); + artiq_raise!( + "RTIODestinationUnreachable", + format!( + "RTIO destination unreachable, output, at {{0}} mu, channel 0x{:04x}:{}", + channel, + resolve_channel_name(channel as u32) + ), + timestamp, + channel as i64, + 0 + ); } } -pub extern fn output(target: i32, data: i32) { +pub extern "C" fn output(target: i32, data: i32) { unsafe { csr::rtio::target_write(target as u32); // writing target clears o_data @@ -95,7 +107,7 @@ pub extern fn output(target: i32, data: i32) { } } -pub extern fn output_wide(target: i32, data: CSlice) { +pub extern "C" fn output_wide(target: i32, data: CSlice) { unsafe { csr::rtio::target_write(target as u32); // writing target clears o_data @@ -109,7 +121,7 @@ pub extern fn output_wide(target: i32, data: CSlice) { } } -pub extern fn input_timestamp(timeout: i64, channel: i32) -> i64 { +pub extern "C" fn input_timestamp(timeout: i64, channel: i32) -> i64 { unsafe { csr::rtio::target_write((channel as u32) << 8); csr::rtio::i_timeout_write(timeout as u64); @@ -120,24 +132,40 @@ pub extern fn input_timestamp(timeout: i64, channel: i32) -> i64 { } if status & RTIO_I_STATUS_OVERFLOW != 0 { - artiq_raise!("RTIOOverflow", - format!("RTIO input overflow on channel 0x{:04x}:{}", channel, resolve_channel_name(channel as u32)), - channel as i64, 0, 0); + artiq_raise!( + "RTIOOverflow", + format!( + "RTIO input overflow on channel 0x{:04x}:{}", + channel, + resolve_channel_name(channel as u32) + ), + channel as i64, + 0, + 0 + ); } if status & RTIO_I_STATUS_WAIT_EVENT != 0 { - return -1 + return -1; } if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 { - artiq_raise!("RTIODestinationUnreachable", - format!("RTIO destination unreachable, input, on channel 0x{:04x}:{}", channel, resolve_channel_name(channel as u32)), - channel as i64, 0, 0); + artiq_raise!( + "RTIODestinationUnreachable", + format!( + "RTIO destination unreachable, input, on channel 0x{:04x}:{}", + channel, + resolve_channel_name(channel as u32) + ), + channel as i64, + 0, + 0 + ); } csr::rtio::i_timestamp_read() as i64 } } -pub extern fn input_data(channel: i32) -> i32 { +pub extern "C" fn input_data(channel: i32) -> i32 { unsafe { csr::rtio::target_write((channel as u32) << 8); csr::rtio::i_timeout_write(0xffffffff_ffffffff); @@ -148,21 +176,37 @@ pub extern fn input_data(channel: i32) -> i32 { } if status & RTIO_I_STATUS_OVERFLOW != 0 { - artiq_raise!("RTIOOverflow", - format!("RTIO input overflow on channel 0x{:04x}:{}", channel, resolve_channel_name(channel as u32)), - channel as i64, 0, 0); + artiq_raise!( + "RTIOOverflow", + format!( + "RTIO input overflow on channel 0x{:04x}:{}", + channel, + resolve_channel_name(channel as u32) + ), + channel as i64, + 0, + 0 + ); } if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 { - artiq_raise!("RTIODestinationUnreachable", - format!("RTIO destination unreachable, input, on channel 0x{:04x}:{}", channel, resolve_channel_name(channel as u32)), - channel as i64, 0, 0); + artiq_raise!( + "RTIODestinationUnreachable", + format!( + "RTIO destination unreachable, input, on channel 0x{:04x}:{}", + channel, + resolve_channel_name(channel as u32) + ), + channel as i64, + 0, + 0 + ); } rtio_i_data_read(0) as i32 } } -pub extern fn input_timestamped_data(timeout: i64, channel: i32) -> TimestampedData { +pub extern "C" fn input_timestamped_data(timeout: i64, channel: i32) -> TimestampedData { unsafe { csr::rtio::target_write((channel as u32) << 8); csr::rtio::i_timeout_write(timeout as u64); @@ -173,22 +217,38 @@ pub extern fn input_timestamped_data(timeout: i64, channel: i32) -> TimestampedD } if status & RTIO_I_STATUS_OVERFLOW != 0 { - artiq_raise!("RTIOOverflow", - format!("RTIO input overflow on channel 0x{:04x}:{}", channel, resolve_channel_name(channel as u32)), - channel as i64, 0, 0); + artiq_raise!( + "RTIOOverflow", + format!( + "RTIO input overflow on channel 0x{:04x}:{}", + channel, + resolve_channel_name(channel as u32) + ), + channel as i64, + 0, + 0 + ); } if status & RTIO_I_STATUS_WAIT_EVENT != 0 { - return TimestampedData { timestamp: -1, data: 0 } + return TimestampedData { timestamp: -1, data: 0 }; } if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 { - artiq_raise!("RTIODestinationUnreachable", - format!("RTIO destination unreachable, input, on channel 0x{:04x}:{}", channel, resolve_channel_name(channel as u32)), - channel as i64, 0, 0); + artiq_raise!( + "RTIODestinationUnreachable", + format!( + "RTIO destination unreachable, input, on channel 0x{:04x}:{}", + channel, + resolve_channel_name(channel as u32) + ), + channel as i64, + 0, + 0 + ); } TimestampedData { timestamp: csr::rtio::i_timestamp_read() as i64, - data: rtio_i_data_read(0) as i32 + data: rtio_i_data_read(0) as i32, } } } diff --git a/src/runtime/src/rtio_mgt.rs b/src/runtime/src/rtio_mgt.rs index 9b14700..9a75d20 100644 --- a/src/runtime/src/rtio_mgt.rs +++ b/src/runtime/src/rtio_mgt.rs @@ -1,33 +1,32 @@ +use alloc::{collections::BTreeMap, rc::Rc, string::String}; use core::cell::RefCell; -use alloc::rc::Rc; -use alloc::collections::BTreeMap; -use alloc::string::String; -use libboard_zynq::timer::GlobalTimer; -use libboard_artiq::{pl::csr, drtio_routing}; -use libcortex_a9::mutex::Mutex; -use libconfig::Config; + use io::{Cursor, ProtoRead}; +use libboard_artiq::{drtio_routing, pl::csr}; +use libboard_zynq::timer::GlobalTimer; +use libconfig::Config; +use libcortex_a9::mutex::Mutex; use log::error; static mut RTIO_DEVICE_MAP: BTreeMap = BTreeMap::new(); - #[cfg(has_drtio)] pub mod drtio { - use super::*; - use crate::{SEEN_ASYNC_ERRORS, ASYNC_ERROR_BUSY, ASYNC_ERROR_SEQUENCE_ERROR, ASYNC_ERROR_COLLISION}; - use libboard_artiq::drtioaux_async; - use libboard_artiq::drtioaux_async::Packet; - use libboard_artiq::drtioaux::Error; - use log::{warn, error, info}; use embedded_hal::blocking::delay::DelayMs; - use libasync::{task, delay}; + use libasync::{delay, task}; + use libboard_artiq::{drtioaux::Error, drtioaux_async, drtioaux_async::Packet}; use libboard_zynq::time::Milliseconds; + use log::{error, info, warn}; - pub fn startup(aux_mutex: &Rc>, - routing_table: &Rc>, - up_destinations: &Rc>, - timer: GlobalTimer) { + use super::*; + use crate::{ASYNC_ERROR_BUSY, ASYNC_ERROR_COLLISION, ASYNC_ERROR_SEQUENCE_ERROR, SEEN_ASYNC_ERRORS}; + + pub fn startup( + aux_mutex: &Rc>, + routing_table: &Rc>, + up_destinations: &Rc>, + timer: GlobalTimer, + ) { let aux_mutex = aux_mutex.clone(); let routing_table = routing_table.clone(); let up_destinations = up_destinations.clone(); @@ -39,9 +38,7 @@ pub mod drtio { async fn link_rx_up(linkno: u8) -> bool { let linkno = linkno as usize; - unsafe { - (csr::DRTIO[linkno].rx_up_read)() == 1 - } + unsafe { (csr::DRTIO[linkno].rx_up_read)() == 1 } } async fn recv_aux_timeout(linkno: u8, timeout: u64, timer: GlobalTimer) -> Result { @@ -55,8 +52,12 @@ pub mod drtio { } } - pub async fn aux_transact(aux_mutex: &Mutex, linkno: u8, request: &Packet, - timer: GlobalTimer) -> Result { + pub async fn aux_transact( + aux_mutex: &Mutex, + linkno: u8, + request: &Packet, + timer: GlobalTimer, + ) -> Result { if !link_rx_up(linkno).await { return Err("link went down"); } @@ -79,7 +80,7 @@ pub mod drtio { let mut count = 0; loop { if !link_rx_up(linkno).await { - return 0 + return 0; } count += 1; if count > 100 { @@ -115,13 +116,23 @@ pub mod drtio { } } - async fn load_routing_table(aux_mutex: &Rc>, linkno: u8, routing_table: &drtio_routing::RoutingTable, - timer: GlobalTimer) -> Result<(), &'static str> { + async fn load_routing_table( + aux_mutex: &Rc>, + linkno: u8, + routing_table: &drtio_routing::RoutingTable, + timer: GlobalTimer, + ) -> Result<(), &'static str> { for i in 0..drtio_routing::DEST_COUNT { - let reply = aux_transact(aux_mutex, linkno, &Packet::RoutingSetPath { - destination: i as u8, - hops: routing_table.0[i] - }, timer).await?; + let reply = aux_transact( + aux_mutex, + linkno, + &Packet::RoutingSetPath { + destination: i as u8, + hops: routing_table.0[i], + }, + timer, + ) + .await?; if reply != Packet::RoutingAck { return Err("unexpected reply"); } @@ -129,10 +140,13 @@ pub mod drtio { Ok(()) } - async fn set_rank(aux_mutex: &Rc>, linkno: u8, rank: u8, timer: GlobalTimer) -> Result<(), &'static str> { - let reply = aux_transact(aux_mutex, linkno, &Packet::RoutingSetRank { - rank: rank - }, timer).await?; + async fn set_rank( + aux_mutex: &Rc>, + linkno: u8, + rank: u8, + timer: GlobalTimer, + ) -> Result<(), &'static str> { + let reply = aux_transact(aux_mutex, linkno, &Packet::RoutingSetRank { rank: rank }, timer).await?; if reply != Packet::RoutingAck { return Err("unexpected reply"); } @@ -146,8 +160,11 @@ pub mod drtio { (csr::DRTIO[linkno].force_destination_write)(1); (csr::DRTIO[linkno].o_get_buffer_space_write)(1); while (csr::DRTIO[linkno].o_wait_read)() == 1 {} - info!("[DEST#{}] buffer space is {}", - destination, (csr::DRTIO[linkno].o_dbg_buffer_space_read)()); + info!( + "[DEST#{}] buffer space is {}", + destination, + (csr::DRTIO[linkno].o_dbg_buffer_space_read)() + ); (csr::DRTIO[linkno].force_destination_write)(0); } } @@ -157,7 +174,7 @@ pub mod drtio { match drtioaux_async::recv(linkno).await { Ok(Some(packet)) => warn!("[LINK#{}] unsolicited aux packet: {:?}", linkno, packet), Ok(None) => (), - Err(_) => warn!("[LINK#{}] aux packet error", linkno) + Err(_) => warn!("[LINK#{}] aux packet error", linkno), } } @@ -182,9 +199,12 @@ pub mod drtio { } } - async fn destination_set_up(routing_table: &drtio_routing::RoutingTable, - up_destinations: &Rc>, - destination: u8, up: bool) { + async fn destination_set_up( + routing_table: &drtio_routing::RoutingTable, + up_destinations: &Rc>, + destination: u8, + up: bool, + ) { let mut up_destinations = up_destinations.borrow_mut(); up_destinations[destination as usize] = up; if up { @@ -201,10 +221,13 @@ pub mod drtio { up_destinations[destination as usize] } - async fn destination_survey(aux_mutex: &Rc>, routing_table: &drtio_routing::RoutingTable, - up_links: &[bool], - up_destinations: &Rc>, - timer: GlobalTimer) { + async fn destination_survey( + aux_mutex: &Rc>, + routing_table: &drtio_routing::RoutingTable, + up_links: &[bool], + up_destinations: &Rc>, + timer: GlobalTimer, + ) { for destination in 0..drtio_routing::DEST_COUNT { let hop = routing_table.0[destination][0]; let destination = destination as u8; @@ -218,44 +241,72 @@ pub mod drtio { let linkno = hop - 1; if destination_up(up_destinations, destination).await { if up_links[linkno as usize] { - let reply = aux_transact(aux_mutex, linkno, &Packet::DestinationStatusRequest { - destination: destination - }, timer).await; + let reply = aux_transact( + aux_mutex, + linkno, + &Packet::DestinationStatusRequest { + destination: destination, + }, + timer, + ) + .await; match reply { - Ok(Packet::DestinationDownReply) => - destination_set_up(routing_table, up_destinations, destination, false).await, + Ok(Packet::DestinationDownReply) => { + destination_set_up(routing_table, up_destinations, destination, false).await + } Ok(Packet::DestinationOkReply) => (), - Ok(Packet::DestinationSequenceErrorReply { channel }) =>{ - error!("[DEST#{}] RTIO sequence error involving channel 0x{:04x}:{}", destination, channel, resolve_channel_name(channel as u32)); + Ok(Packet::DestinationSequenceErrorReply { channel }) => { + error!( + "[DEST#{}] RTIO sequence error involving channel 0x{:04x}:{}", + destination, + channel, + resolve_channel_name(channel as u32) + ); unsafe { SEEN_ASYNC_ERRORS |= ASYNC_ERROR_SEQUENCE_ERROR }; } - Ok(Packet::DestinationCollisionReply { channel }) =>{ - error!("[DEST#{}] RTIO collision involving channel 0x{:04x}:{}", destination, channel, resolve_channel_name(channel as u32)); + Ok(Packet::DestinationCollisionReply { channel }) => { + error!( + "[DEST#{}] RTIO collision involving channel 0x{:04x}:{}", + destination, + channel, + resolve_channel_name(channel as u32) + ); unsafe { SEEN_ASYNC_ERRORS |= ASYNC_ERROR_COLLISION }; } - Ok(Packet::DestinationBusyReply { channel }) =>{ - error!("[DEST#{}] RTIO busy error involving channel 0x{:04x}:{}", destination, channel, resolve_channel_name(channel as u32)); + Ok(Packet::DestinationBusyReply { channel }) => { + error!( + "[DEST#{}] RTIO busy error involving channel 0x{:04x}:{}", + destination, + channel, + resolve_channel_name(channel as u32) + ); unsafe { SEEN_ASYNC_ERRORS |= ASYNC_ERROR_BUSY }; } Ok(packet) => error!("[DEST#{}] received unexpected aux packet: {:?}", destination, packet), - Err(e) => error!("[DEST#{}] communication failed ({})", destination, e) + Err(e) => error!("[DEST#{}] communication failed ({})", destination, e), } } else { destination_set_up(routing_table, up_destinations, destination, false).await; } } else { if up_links[linkno as usize] { - let reply = aux_transact(aux_mutex, linkno, &Packet::DestinationStatusRequest { - destination: destination - }, timer).await; + let reply = aux_transact( + aux_mutex, + linkno, + &Packet::DestinationStatusRequest { + destination: destination, + }, + timer, + ) + .await; match reply { Ok(Packet::DestinationDownReply) => (), Ok(Packet::DestinationOkReply) => { destination_set_up(routing_table, up_destinations, destination, true).await; init_buffer_space(destination as u8, linkno).await; - }, + } Ok(packet) => error!("[DEST#{}] received unexpected aux packet: {:?}", destination, packet), - Err(e) => error!("[DEST#{}] communication failed ({})", destination, e) + Err(e) => error!("[DEST#{}] communication failed ({})", destination, e), } } } @@ -263,10 +314,12 @@ pub mod drtio { } } - pub async fn link_task(aux_mutex: &Rc>, - routing_table: &drtio_routing::RoutingTable, - up_destinations: &Rc>, - timer: GlobalTimer) { + pub async fn link_task( + aux_mutex: &Rc>, + routing_table: &drtio_routing::RoutingTable, + up_destinations: &Rc>, + timer: GlobalTimer, + ) { let mut up_links = [false; csr::DRTIO.len()]; loop { for linkno in 0..csr::DRTIO.len() { @@ -327,12 +380,11 @@ pub mod drtio { for linkno in 0..csr::DRTIO.len() { let linkno = linkno as u8; if task::block_on(link_rx_up(linkno)) { - let reply = task::block_on(aux_transact(&aux_mutex, linkno, - &Packet::ResetRequest, timer)); + let reply = task::block_on(aux_transact(&aux_mutex, linkno, &Packet::ResetRequest, timer)); match reply { Ok(Packet::ResetAck) => (), Ok(_) => error!("[LINK#{}] reset failed, received unexpected aux packet", linkno), - Err(e) => error!("[LINK#{}] reset failed, aux packet error ({})", linkno, e) + Err(e) => error!("[LINK#{}] reset failed, aux packet error ({})", linkno, e), } } } @@ -341,53 +393,67 @@ pub mod drtio { fn read_device_map(cfg: &Config) -> BTreeMap { let mut device_map: BTreeMap = BTreeMap::new(); - let _ = cfg.read("device_map").and_then(|raw_bytes| { - let mut bytes_cr = Cursor::new(raw_bytes); - let size = bytes_cr.read_u32().unwrap(); - for _ in 0..size { - let channel = bytes_cr.read_u32().unwrap(); - let device_name = bytes_cr.read_string().unwrap(); - if let Some(old_entry) = device_map.insert(channel, device_name.clone()) { - error!("read_device_map: conflicting entries for channel {}: `{}` and `{}`", - channel, old_entry, device_name); + let _ = cfg + .read("device_map") + .and_then(|raw_bytes| { + let mut bytes_cr = Cursor::new(raw_bytes); + let size = bytes_cr.read_u32().unwrap(); + for _ in 0..size { + let channel = bytes_cr.read_u32().unwrap(); + let device_name = bytes_cr.read_string().unwrap(); + if let Some(old_entry) = device_map.insert(channel, device_name.clone()) { + error!( + "read_device_map: conflicting entries for channel {}: `{}` and `{}`", + channel, old_entry, device_name + ); + } } - } - Ok(()) - } ).or_else(|err| { - error!("read_device_map: error reading `device_map` from config: {}", err); - Err(err) - }); + Ok(()) + }) + .or_else(|err| { + error!("read_device_map: error reading `device_map` from config: {}", err); + Err(err) + }); device_map } fn _resolve_channel_name(channel: u32, device_map: &BTreeMap) -> String { match device_map.get(&channel) { Some(val) => val.clone(), - None => String::from("unknown") + None => String::from("unknown"), } } pub fn resolve_channel_name(channel: u32) -> String { - _resolve_channel_name(channel, unsafe{&RTIO_DEVICE_MAP}) + _resolve_channel_name(channel, unsafe { &RTIO_DEVICE_MAP }) } #[cfg(not(has_drtio))] pub mod drtio { use super::*; - pub fn startup(_aux_mutex: &Rc>, _routing_table: &Rc>, - _up_destinations: &Rc>, _timer: GlobalTimer) {} - + pub fn startup( + _aux_mutex: &Rc>, + _routing_table: &Rc>, + _up_destinations: &Rc>, + _timer: GlobalTimer, + ) { + } + #[allow(dead_code)] pub fn reset(_aux_mutex: Rc>, mut _timer: GlobalTimer) {} } -pub fn startup(aux_mutex: &Rc>, - routing_table: &Rc>, - up_destinations: &Rc>, - timer: GlobalTimer, - cfg: &Config) { - unsafe { RTIO_DEVICE_MAP = read_device_map(cfg); } +pub fn startup( + aux_mutex: &Rc>, + routing_table: &Rc>, + up_destinations: &Rc>, + timer: GlobalTimer, + cfg: &Config, +) { + unsafe { + RTIO_DEVICE_MAP = read_device_map(cfg); + } drtio::startup(aux_mutex, routing_table, up_destinations, timer); unsafe { csr::rtio_core::reset_phy_write(1); diff --git a/src/rustfmt.toml b/src/rustfmt.toml new file mode 100644 index 0000000..d41ec2f --- /dev/null +++ b/src/rustfmt.toml @@ -0,0 +1,68 @@ +max_width = 120 +hard_tabs = false +tab_spaces = 4 +newline_style = "Auto" +use_small_heuristics = "Default" +indent_style = "Block" +wrap_comments = false +format_code_in_doc_comments = false +comment_width = 100 +normalize_comments = false +normalize_doc_attributes = false +license_template_path = "" +format_strings = true +format_macro_matchers = true +format_macro_bodies = true +empty_item_single_line = true +struct_lit_single_line = true +fn_single_line = false +where_single_line = true +imports_indent = "Visual" +imports_layout = "Mixed" +merge_imports = true +group_imports = "StdExternalCrate" +reorder_imports = true +reorder_modules = true +reorder_impl_items = false +type_punctuation_density = "Wide" +space_before_colon = false +space_after_colon = true +spaces_around_ranges = false +binop_separator = "Front" +remove_nested_parens = true +combine_control_expr = true +overflow_delimited_expr = false +struct_field_align_threshold = 0 +enum_discrim_align_threshold = 0 +match_arm_blocks = true +match_arm_leading_pipes = "Never" +force_multiline_blocks = false +fn_args_layout = "Tall" +brace_style = "SameLineWhere" +control_brace_style = "AlwaysSameLine" +trailing_semicolon = true +trailing_comma = "Vertical" +match_block_trailing_comma = false +blank_lines_upper_bound = 1 +blank_lines_lower_bound = 0 +edition = "2018" +version = "Two" +inline_attribute_width = 0 +merge_derives = true +use_try_shorthand = false +use_field_init_shorthand = false +force_explicit_abi = true +condense_wildcard_suffixes = false +color = "Auto" +required_version = "1.4.32" +unstable_features = false +disable_all_formatting = false +skip_children = false +hide_parse_errors = false +error_on_line_overflow = false +error_on_unformatted = false +report_todo = "Never" +report_fixme = "Never" +ignore = [] +emit_mode = "Files" +make_backup = false \ No newline at end of file diff --git a/src/satman/src/main.rs b/src/satman/src/main.rs index 1c00651..aac0fdc 100644 --- a/src/satman/src/main.rs +++ b/src/satman/src/main.rs @@ -8,30 +8,34 @@ extern crate log; extern crate embedded_hal; -extern crate libboard_zynq; extern crate libboard_artiq; -extern crate libsupport_zynq; +extern crate libboard_zynq; extern crate libcortex_a9; extern crate libregister; +extern crate libsupport_zynq; extern crate unwind; extern crate alloc; -use libboard_zynq::{i2c::I2c, timer::GlobalTimer, time::Milliseconds, print, println, mpcore, gic, stdio}; -use libsupport_zynq::ram; -#[cfg(has_si5324)] -use libboard_artiq::si5324; -#[cfg(feature = "target_kasli_soc")] -use libboard_artiq::io_expander; -use libboard_artiq::{pl::csr, drtio_routing, drtioaux, logger, identifier_read}; -use libcortex_a9::{spin_lock_yield, interrupt_handler, regs::{MPIDR, SP}, notify_spin_lock, asm, l2c::enable_l2_cache}; -use libregister::{RegisterW, RegisterR}; -#[cfg(feature = "target_kasli_soc")] -use libboard_zynq::error_led::ErrorLED; +use core::sync::atomic::{AtomicBool, Ordering}; use embedded_hal::blocking::delay::DelayUs; -use core::sync::atomic::{AtomicBool, Ordering}; +#[cfg(feature = "target_kasli_soc")] +use libboard_artiq::io_expander; +#[cfg(has_si5324)] +use libboard_artiq::si5324; +use libboard_artiq::{drtio_routing, drtioaux, identifier_read, logger, pl::csr}; +#[cfg(feature = "target_kasli_soc")] +use libboard_zynq::error_led::ErrorLED; +use libboard_zynq::{gic, i2c::I2c, mpcore, print, println, stdio, time::Milliseconds, timer::GlobalTimer}; +use libcortex_a9::{asm, interrupt_handler, + l2c::enable_l2_cache, + notify_spin_lock, + regs::{MPIDR, SP}, + spin_lock_yield}; +use libregister::{RegisterR, RegisterW}; +use libsupport_zynq::ram; mod repeater; @@ -48,9 +52,7 @@ fn drtiosat_reset_phy(reset: bool) { } fn drtiosat_link_rx_up() -> bool { - unsafe { - csr::drtiosat::rx_up_read() == 1 - } + unsafe { csr::drtiosat::rx_up_read() == 1 } } fn drtiosat_tsc_loaded() -> bool { @@ -63,7 +65,6 @@ fn drtiosat_tsc_loaded() -> bool { } } - #[cfg(has_drtio_routing)] macro_rules! forward { ($routing_table:expr, $destination:expr, $rank:expr, $repeaters:expr, $packet:expr, $timer:expr) => {{ @@ -76,22 +77,26 @@ macro_rules! forward { return Err(drtioaux::Error::RoutingError); } } - }} + }}; } #[cfg(not(has_drtio_routing))] macro_rules! forward { - ($routing_table:expr, $destination:expr, $rank:expr, $repeaters:expr, $packet:expr, $timer:expr) => {} + ($routing_table:expr, $destination:expr, $rank:expr, $repeaters:expr, $packet:expr, $timer:expr) => {}; } -fn process_aux_packet(_repeaters: &mut [repeater::Repeater], - _routing_table: &mut drtio_routing::RoutingTable, _rank: &mut u8, - packet: drtioaux::Packet, timer: &mut GlobalTimer, i2c: &mut I2c) -> Result<(), drtioaux::Error> { +fn process_aux_packet( + _repeaters: &mut [repeater::Repeater], + _routing_table: &mut drtio_routing::RoutingTable, + _rank: &mut u8, + packet: drtioaux::Packet, + timer: &mut GlobalTimer, + i2c: &mut I2c, +) -> Result<(), drtioaux::Error> { // In the code below, *_chan_sel_write takes an u8 if there are fewer than 256 channels, // and u16 otherwise; hence the `as _` conversion. match packet { - drtioaux::Packet::EchoRequest => - drtioaux::send(0, &drtioaux::Packet::EchoReply), + drtioaux::Packet::EchoRequest => drtioaux::send(0, &drtioaux::Packet::EchoReply), drtioaux::Packet::ResetRequest => { info!("resetting RTIO"); drtiosat_reset(true); @@ -103,9 +108,11 @@ fn process_aux_packet(_repeaters: &mut [repeater::Repeater], } } drtioaux::send(0, &drtioaux::Packet::ResetAck) - }, + } - drtioaux::Packet::DestinationStatusRequest { destination: _destination } => { + drtioaux::Packet::DestinationStatusRequest { + destination: _destination, + } => { #[cfg(has_drtio_routing)] let hop = _routing_table.0[_destination as usize][*_rank as usize]; #[cfg(not(has_drtio_routing))] @@ -122,26 +129,22 @@ fn process_aux_packet(_repeaters: &mut [repeater::Repeater], channel = csr::drtiosat::sequence_error_channel_read(); csr::drtiosat::rtio_error_write(1); } - drtioaux::send(0, - &drtioaux::Packet::DestinationSequenceErrorReply { channel })?; + drtioaux::send(0, &drtioaux::Packet::DestinationSequenceErrorReply { channel })?; } else if errors & 2 != 0 { let channel; unsafe { channel = csr::drtiosat::collision_channel_read(); csr::drtiosat::rtio_error_write(2); } - drtioaux::send(0, - &drtioaux::Packet::DestinationCollisionReply { channel })?; + drtioaux::send(0, &drtioaux::Packet::DestinationCollisionReply { channel })?; } else if errors & 4 != 0 { let channel; unsafe { channel = csr::drtiosat::busy_channel_read(); csr::drtiosat::rtio_error_write(4); } - drtioaux::send(0, - &drtioaux::Packet::DestinationBusyReply { channel })?; - } - else { + drtioaux::send(0, &drtioaux::Packet::DestinationBusyReply { channel })?; + } else { drtioaux::send(0, &drtioaux::Packet::DestinationOkReply)?; } } @@ -152,15 +155,20 @@ fn process_aux_packet(_repeaters: &mut [repeater::Repeater], let hop = hop as usize; if hop <= csr::DRTIOREP.len() { let repno = hop - 1; - match _repeaters[repno].aux_forward(&drtioaux::Packet::DestinationStatusRequest { - destination: _destination - }, timer) { + match _repeaters[repno].aux_forward( + &drtioaux::Packet::DestinationStatusRequest { + destination: _destination, + }, + timer, + ) { Ok(()) => (), - Err(drtioaux::Error::LinkDown) => drtioaux::send(0, &drtioaux::Packet::DestinationDownReply)?, + Err(drtioaux::Error::LinkDown) => { + drtioaux::send(0, &drtioaux::Packet::DestinationDownReply)? + } Err(e) => { drtioaux::send(0, &drtioaux::Packet::DestinationDownReply)?; error!("aux error when handling destination status request: {:?}", e); - }, + } } } else { drtioaux::send(0, &drtioaux::Packet::DestinationDownReply)?; @@ -200,15 +208,18 @@ fn process_aux_packet(_repeaters: &mut [repeater::Repeater], } #[cfg(not(has_drtio_routing))] - drtioaux::Packet::RoutingSetPath { destination: _, hops: _ } => { - drtioaux::send(0, &drtioaux::Packet::RoutingAck) - } + drtioaux::Packet::RoutingSetPath { + destination: _, + hops: _, + } => drtioaux::send(0, &drtioaux::Packet::RoutingAck), #[cfg(not(has_drtio_routing))] - drtioaux::Packet::RoutingSetRank { rank: _ } => { - drtioaux::send(0, &drtioaux::Packet::RoutingAck) - } + drtioaux::Packet::RoutingSetRank { rank: _ } => drtioaux::send(0, &drtioaux::Packet::RoutingAck), - drtioaux::Packet::MonitorRequest { destination: _destination, channel: _channel, probe: _probe } => { + drtioaux::Packet::MonitorRequest { + destination: _destination, + channel: _channel, + probe: _probe, + } => { forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer); let value; #[cfg(has_rtio_moninj)] @@ -224,9 +235,13 @@ fn process_aux_packet(_repeaters: &mut [repeater::Repeater], } let reply = drtioaux::Packet::MonitorReply { value: value }; drtioaux::send(0, &reply) - }, - drtioaux::Packet::InjectionRequest { destination: _destination, channel: _channel, - overrd: _overrd, value: _value } => { + } + drtioaux::Packet::InjectionRequest { + destination: _destination, + channel: _channel, + overrd: _overrd, + value: _value, + } => { forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer); #[cfg(has_rtio_moninj)] unsafe { @@ -235,9 +250,12 @@ fn process_aux_packet(_repeaters: &mut [repeater::Repeater], csr::rtio_moninj::inj_value_write(value); } Ok(()) - }, - drtioaux::Packet::InjectionStatusRequest { destination: _destination, - channel: _channel, overrd: _overrd } => { + } + drtioaux::Packet::InjectionStatusRequest { + destination: _destination, + channel: _channel, + overrd: _overrd, + } => { forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer); let value; #[cfg(has_rtio_moninj)] @@ -251,44 +269,87 @@ fn process_aux_packet(_repeaters: &mut [repeater::Repeater], value = 0; } drtioaux::send(0, &drtioaux::Packet::InjectionStatusReply { value: value }) - }, + } - drtioaux::Packet::I2cStartRequest { destination: _destination, busno: _busno } => { + drtioaux::Packet::I2cStartRequest { + destination: _destination, + busno: _busno, + } => { forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer); let succeeded = i2c.start().is_ok(); drtioaux::send(0, &drtioaux::Packet::I2cBasicReply { succeeded: succeeded }) } - drtioaux::Packet::I2cRestartRequest { destination: _destination, busno: _busno } => { + drtioaux::Packet::I2cRestartRequest { + destination: _destination, + busno: _busno, + } => { forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer); let succeeded = i2c.restart().is_ok(); drtioaux::send(0, &drtioaux::Packet::I2cBasicReply { succeeded: succeeded }) } - drtioaux::Packet::I2cStopRequest { destination: _destination, busno: _busno } => { + drtioaux::Packet::I2cStopRequest { + destination: _destination, + busno: _busno, + } => { forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer); let succeeded = i2c.stop().is_ok(); drtioaux::send(0, &drtioaux::Packet::I2cBasicReply { succeeded: succeeded }) } - drtioaux::Packet::I2cWriteRequest { destination: _destination, busno: _busno, data } => { + drtioaux::Packet::I2cWriteRequest { + destination: _destination, + busno: _busno, + data, + } => { forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer); match i2c.write(data) { - Ok(ack) => drtioaux::send(0, - &drtioaux::Packet::I2cWriteReply { succeeded: true, ack: ack }), - Err(_) => drtioaux::send(0, - &drtioaux::Packet::I2cWriteReply { succeeded: false, ack: false }) + Ok(ack) => drtioaux::send( + 0, + &drtioaux::Packet::I2cWriteReply { + succeeded: true, + ack: ack, + }, + ), + Err(_) => drtioaux::send( + 0, + &drtioaux::Packet::I2cWriteReply { + succeeded: false, + ack: false, + }, + ), } } - drtioaux::Packet::I2cReadRequest { destination: _destination, busno: _busno, ack } => { + drtioaux::Packet::I2cReadRequest { + destination: _destination, + busno: _busno, + ack, + } => { forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer); match i2c.read(ack) { - Ok(data) => drtioaux::send(0, - &drtioaux::Packet::I2cReadReply { succeeded: true, data: data }), - Err(_) => drtioaux::send(0, - &drtioaux::Packet::I2cReadReply { succeeded: false, data: 0xff }) + Ok(data) => drtioaux::send( + 0, + &drtioaux::Packet::I2cReadReply { + succeeded: true, + data: data, + }, + ), + Err(_) => drtioaux::send( + 0, + &drtioaux::Packet::I2cReadReply { + succeeded: false, + data: 0xff, + }, + ), } } - drtioaux::Packet::I2cSwitchSelectRequest { destination: _destination, busno: _busno, address, mask } => { + drtioaux::Packet::I2cSwitchSelectRequest { + destination: _destination, + busno: _busno, + address, + mask, + } => { forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer); - let ch = match mask { //decode from mainline, PCA9548-centric API + let ch = match mask { + //decode from mainline, PCA9548-centric API 0x00 => None, 0x01 => Some(0), 0x02 => Some(1), @@ -298,28 +359,39 @@ fn process_aux_packet(_repeaters: &mut [repeater::Repeater], 0x20 => Some(5), 0x40 => Some(6), 0x80 => Some(7), - _ => { return drtioaux::send(0, &drtioaux::Packet::I2cBasicReply { succeeded: false }); } + _ => return drtioaux::send(0, &drtioaux::Packet::I2cBasicReply { succeeded: false }), }; let succeeded = i2c.pca954x_select(address, ch).is_ok(); drtioaux::send(0, &drtioaux::Packet::I2cBasicReply { succeeded: succeeded }) } - drtioaux::Packet::SpiSetConfigRequest { destination: _destination, busno: _busno, - flags: _flags, length: _length, div: _div, cs: _cs } => { + drtioaux::Packet::SpiSetConfigRequest { + destination: _destination, + busno: _busno, + flags: _flags, + length: _length, + div: _div, + cs: _cs, + } => { forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer); // todo: reimplement when/if SPI is available //let succeeded = spi::set_config(busno, flags, length, div, cs).is_ok(); - drtioaux::send(0, - &drtioaux::Packet::SpiBasicReply { succeeded: false }) - }, - drtioaux::Packet::SpiWriteRequest { destination: _destination, busno: _busno, data: _data } => { + drtioaux::send(0, &drtioaux::Packet::SpiBasicReply { succeeded: false }) + } + drtioaux::Packet::SpiWriteRequest { + destination: _destination, + busno: _busno, + data: _data, + } => { forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer); // todo: reimplement when/if SPI is available //let succeeded = spi::write(busno, data).is_ok(); - drtioaux::send(0, - &drtioaux::Packet::SpiBasicReply { succeeded: false }) + drtioaux::send(0, &drtioaux::Packet::SpiBasicReply { succeeded: false }) } - drtioaux::Packet::SpiReadRequest { destination: _destination, busno: _busno } => { + drtioaux::Packet::SpiReadRequest { + destination: _destination, + busno: _busno, + } => { forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer); // todo: reimplement when/if SPI is available // match spi::read(busno) { @@ -328,8 +400,13 @@ fn process_aux_packet(_repeaters: &mut [repeater::Repeater], // Err(_) => drtioaux::send(0, // &drtioaux::Packet::SpiReadReply { succeeded: false, data: 0 }) // } - drtioaux::send(0, - &drtioaux::Packet::SpiReadReply { succeeded: false, data: 0 }) + drtioaux::send( + 0, + &drtioaux::Packet::SpiReadReply { + succeeded: false, + data: 0, + }, + ) } _ => { @@ -339,20 +416,23 @@ fn process_aux_packet(_repeaters: &mut [repeater::Repeater], } } -fn process_aux_packets(repeaters: &mut [repeater::Repeater], - routing_table: &mut drtio_routing::RoutingTable, rank: &mut u8, - timer: &mut GlobalTimer, i2c: &mut I2c) { - let result = - drtioaux::recv(0).and_then(|packet| { - if let Some(packet) = packet { - process_aux_packet(repeaters, routing_table, rank, packet, timer, i2c) - } else { - Ok(()) - } - }); +fn process_aux_packets( + repeaters: &mut [repeater::Repeater], + routing_table: &mut drtio_routing::RoutingTable, + rank: &mut u8, + timer: &mut GlobalTimer, + i2c: &mut I2c, +) { + let result = drtioaux::recv(0).and_then(|packet| { + if let Some(packet) = packet { + process_aux_packet(repeaters, routing_table, rank, packet, timer, i2c) + } else { + Ok(()) + } + }); match result { Ok(()) => (), - Err(e) => warn!("aux packet error ({:?})", e) + Err(e) => warn!("aux packet error ({:?})", e), } } @@ -372,7 +452,10 @@ fn drtiosat_process_errors() { unsafe { destination = csr::drtiosat::buffer_space_timeout_dest_read(); } - error!("timeout attempting to get buffer space from CRI, destination=0x{:02x}", destination) + error!( + "timeout attempting to get buffer space from CRI, destination=0x{:02x}", + destination + ) } if errors & 8 != 0 { let channel; @@ -383,8 +466,13 @@ fn drtiosat_process_errors() { timestamp_event = csr::drtiosat::underflow_timestamp_event_read() as i64; timestamp_counter = csr::drtiosat::underflow_timestamp_counter_read() as i64; } - error!("write underflow, channel={}, timestamp={}, counter={}, slack={}", - channel, timestamp_event, timestamp_counter, timestamp_event-timestamp_counter); + error!( + "write underflow, channel={}, timestamp={}, counter={}, slack={}", + channel, + timestamp_event, + timestamp_counter, + timestamp_event - timestamp_counter + ); } if errors & 16 != 0 { error!("write overflow"); @@ -404,42 +492,38 @@ fn hardware_tick(ts: &mut u64, timer: &mut GlobalTimer) { } #[cfg(all(has_si5324, rtio_frequency = "125.0"))] -const SI5324_SETTINGS: si5324::FrequencySettings - = si5324::FrequencySettings { - n1_hs : 5, - nc1_ls : 8, - n2_hs : 7, - n2_ls : 360, - n31 : 63, - n32 : 63, - bwsel : 4, - crystal_as_ckin2: true +const SI5324_SETTINGS: si5324::FrequencySettings = si5324::FrequencySettings { + n1_hs: 5, + nc1_ls: 8, + n2_hs: 7, + n2_ls: 360, + n31: 63, + n32: 63, + bwsel: 4, + crystal_as_ckin2: true, }; #[cfg(all(has_si5324, rtio_frequency = "100.0"))] -const SI5324_SETTINGS: si5324::FrequencySettings - = si5324::FrequencySettings { - n1_hs : 5, - nc1_ls : 10, - n2_hs : 10, - n2_ls : 250, - n31 : 50, - n32 : 50, - bwsel : 4, - crystal_as_ckin2: true +const SI5324_SETTINGS: si5324::FrequencySettings = si5324::FrequencySettings { + n1_hs: 5, + nc1_ls: 10, + n2_hs: 10, + n2_ls: 250, + n31: 50, + n32: 50, + bwsel: 4, + crystal_as_ckin2: true, }; -static mut LOG_BUFFER: [u8; 1<<17] = [0; 1<<17]; +static mut LOG_BUFFER: [u8; 1 << 17] = [0; 1 << 17]; #[no_mangle] -pub extern fn main_core0() -> i32 { +pub extern "C" fn main_core0() -> i32 { enable_l2_cache(0x8); let mut timer = GlobalTimer::start(); - let buffer_logger = unsafe { - logger::BufferLogger::new(&mut LOG_BUFFER[..]) - }; + let buffer_logger = unsafe { logger::BufferLogger::new(&mut LOG_BUFFER[..]) }; buffer_logger.set_uart_log_level(log::LevelFilter::Info); buffer_logger.register(); log::set_max_level(log::LevelFilter::Info); @@ -491,7 +575,7 @@ pub extern fn main_core0() -> i32 { let mut repeaters = [repeater::Repeater::default(); 0]; for i in 0..repeaters.len() { repeaters[i] = repeater::Repeater::new(i as u8); - } + } let mut routing_table = drtio_routing::RoutingTable::default_empty(); let mut rank = 1; @@ -553,7 +637,7 @@ extern "C" { } interrupt_handler!(IRQ, irq, __irq_stack0_start, __irq_stack1_start, { - if MPIDR.read().cpu_id() == 1{ + if MPIDR.read().cpu_id() == 1 { let mpcore = mpcore::RegisterBlock::mpcore(); let mut gic = gic::InterruptController::gic(mpcore); let id = gic.get_interrupt_id(); @@ -566,7 +650,7 @@ interrupt_handler!(IRQ, irq, __irq_stack0_start, __irq_stack1_start, { notify_spin_lock(); main_core1(); } - stdio::drop_uart(); + stdio::drop_uart(); } loop {} }); @@ -593,18 +677,21 @@ pub fn main_core1() { } #[no_mangle] -pub extern fn exception(_vect: u32, _regs: *const u32, pc: u32, ea: u32) { - +pub extern "C" fn exception(_vect: u32, _regs: *const u32, pc: u32, ea: u32) { fn hexdump(addr: u32) { let addr = (addr - addr % 4) as *const u32; - let mut ptr = addr; + let mut ptr = addr; println!("@ {:08p}", ptr); for _ in 0..4 { print!("+{:04x}: ", ptr as usize - addr as usize); - print!("{:08x} ", unsafe { *ptr }); ptr = ptr.wrapping_offset(1); - print!("{:08x} ", unsafe { *ptr }); ptr = ptr.wrapping_offset(1); - print!("{:08x} ", unsafe { *ptr }); ptr = ptr.wrapping_offset(1); - print!("{:08x}\n", unsafe { *ptr }); ptr = ptr.wrapping_offset(1); + print!("{:08x} ", unsafe { *ptr }); + ptr = ptr.wrapping_offset(1); + print!("{:08x} ", unsafe { *ptr }); + ptr = ptr.wrapping_offset(1); + print!("{:08x} ", unsafe { *ptr }); + ptr = ptr.wrapping_offset(1); + print!("{:08x}\n", unsafe { *ptr }); + ptr = ptr.wrapping_offset(1); } } @@ -654,7 +741,7 @@ extern "C" { } #[no_mangle] -extern fn dl_unwind_find_exidx(_pc: *const u32, len_ptr: *mut u32) -> *const u32 { +extern "C" fn dl_unwind_find_exidx(_pc: *const u32, len_ptr: *mut u32) -> *const u32 { let length; let start: *const u32; unsafe { diff --git a/src/satman/src/repeater.rs b/src/satman/src/repeater.rs index ed12365..2a20b30 100644 --- a/src/satman/src/repeater.rs +++ b/src/satman/src/repeater.rs @@ -1,19 +1,16 @@ -use libboard_artiq::{drtioaux, drtio_routing}; -use libboard_zynq::timer::GlobalTimer; - -#[cfg(has_drtio_routing)] -use libboard_artiq::{pl::csr}; -#[cfg(has_drtio_routing)] -use libboard_zynq::time::Milliseconds; #[cfg(has_drtio_routing)] use embedded_hal::prelude::_embedded_hal_blocking_delay_DelayUs; +#[cfg(has_drtio_routing)] +use libboard_artiq::pl::csr; +use libboard_artiq::{drtio_routing, drtioaux}; +#[cfg(has_drtio_routing)] +use libboard_zynq::time::Milliseconds; +use libboard_zynq::timer::GlobalTimer; #[cfg(has_drtio_routing)] fn rep_link_rx_up(repno: u8) -> bool { let repno = repno as usize; - unsafe { - (csr::DRTIOREP[repno].rx_up_read)() == 1 - } + unsafe { (csr::DRTIOREP[repno].rx_up_read)() == 1 } } #[cfg(has_drtio_routing)] @@ -23,12 +20,14 @@ enum RepeaterState { SendPing { ping_count: u16 }, WaitPingReply { ping_count: u16, timeout: Milliseconds }, Up, - Failed + Failed, } #[cfg(has_drtio_routing)] impl Default for RepeaterState { - fn default() -> RepeaterState { RepeaterState::Down } + fn default() -> RepeaterState { + RepeaterState::Down + } } #[cfg(has_drtio_routing)] @@ -36,7 +35,7 @@ impl Default for RepeaterState { pub struct Repeater { repno: u8, auxno: u8, - state: RepeaterState + state: RepeaterState, } #[cfg(has_drtio_routing)] @@ -45,7 +44,7 @@ impl Repeater { Repeater { repno: repno, auxno: repno + 1, - state: RepeaterState::Down + state: RepeaterState::Down, } } @@ -54,8 +53,7 @@ impl Repeater { self.state == RepeaterState::Up } - pub fn service(&mut self, routing_table: &drtio_routing::RoutingTable, rank: u8, - timer: &mut GlobalTimer) { + pub fn service(&mut self, routing_table: &drtio_routing::RoutingTable, rank: u8, timer: &mut GlobalTimer) { self.process_local_errors(); match self.state { @@ -70,7 +68,7 @@ impl Repeater { drtioaux::send(self.auxno, &drtioaux::Packet::EchoRequest).unwrap(); self.state = RepeaterState::WaitPingReply { ping_count: ping_count + 1, - timeout: timer.get_time() + Milliseconds(100) + timeout: timer.get_time() + Milliseconds(100), } } else { error!("[REP#{}] link RX went down during ping", self.repno); @@ -132,7 +130,7 @@ impl Repeater { match drtioaux::recv(self.auxno) { Ok(Some(packet)) => warn!("[REP#{}] unsolicited aux packet: {:?}", self.repno, packet), Ok(None) => (), - Err(_) => warn!("[REP#{}] aux packet error", self.repno) + Err(_) => warn!("[REP#{}] aux packet error", self.repno), } } @@ -155,14 +153,20 @@ impl Repeater { cmd = (csr::DRTIOREP[repno].command_missed_cmd_read)(); chan_sel = (csr::DRTIOREP[repno].command_missed_chan_sel_read)(); } - error!("[REP#{}] CRI command missed, cmd={}, chan_sel=0x{:06x}", repno, cmd, chan_sel) + error!( + "[REP#{}] CRI command missed, cmd={}, chan_sel=0x{:06x}", + repno, cmd, chan_sel + ) } if errors & 8 != 0 { let destination; unsafe { destination = (csr::DRTIOREP[repno].buffer_space_timeout_dest_read)(); } - error!("[REP#{}] timeout attempting to get remote buffer space, destination=0x{:02x}", repno, destination); + error!( + "[REP#{}] timeout attempting to get remote buffer space, destination=0x{:02x}", + repno, destination + ); } unsafe { (csr::DRTIOREP[repno].protocol_error_write)(errors); @@ -181,7 +185,7 @@ impl Repeater { match drtioaux::recv(self.auxno) { Ok(Some(packet)) => return Ok(packet), Ok(None) => (), - Err(e) => return Err(e) + Err(e) => return Err(e), } } } @@ -217,15 +221,24 @@ impl Repeater { } } - pub fn set_path(&self, destination: u8, hops: &[u8; drtio_routing::MAX_HOPS], timer: &mut GlobalTimer) -> Result<(), drtioaux::Error> { + pub fn set_path( + &self, + destination: u8, + hops: &[u8; drtio_routing::MAX_HOPS], + timer: &mut GlobalTimer, + ) -> Result<(), drtioaux::Error> { if self.state != RepeaterState::Up { return Ok(()); } - drtioaux::send(self.auxno, &drtioaux::Packet::RoutingSetPath { - destination: destination, - hops: *hops - }).unwrap(); + drtioaux::send( + self.auxno, + &drtioaux::Packet::RoutingSetPath { + destination: destination, + hops: *hops, + }, + ) + .unwrap(); let reply = self.recv_aux_timeout(200, timer)?; if reply != drtioaux::Packet::RoutingAck { return Err(drtioaux::Error::UnexpectedReply); @@ -233,7 +246,11 @@ impl Repeater { Ok(()) } - pub fn load_routing_table(&self, routing_table: &drtio_routing::RoutingTable, timer: &mut GlobalTimer) -> Result<(), drtioaux::Error> { + pub fn load_routing_table( + &self, + routing_table: &drtio_routing::RoutingTable, + timer: &mut GlobalTimer, + ) -> Result<(), drtioaux::Error> { for i in 0..drtio_routing::DEST_COUNT { self.set_path(i as u8, &routing_table.0[i], timer)?; } @@ -244,9 +261,7 @@ impl Repeater { if self.state != RepeaterState::Up { return Ok(()); } - drtioaux::send(self.auxno, &drtioaux::Packet::RoutingSetRank { - rank: rank - }).unwrap(); + drtioaux::send(self.auxno, &drtioaux::Packet::RoutingSetRank { rank: rank }).unwrap(); let reply = self.recv_aux_timeout(200, timer)?; if reply != drtioaux::Packet::RoutingAck { return Err(drtioaux::Error::UnexpectedReply); @@ -256,9 +271,13 @@ impl Repeater { pub fn rtio_reset(&self, timer: &mut GlobalTimer) -> Result<(), drtioaux::Error> { let repno = self.repno as usize; - unsafe { (csr::DRTIOREP[repno].reset_write)(1); } + unsafe { + (csr::DRTIOREP[repno].reset_write)(1); + } timer.delay_us(100); - unsafe { (csr::DRTIOREP[repno].reset_write)(0); } + unsafe { + (csr::DRTIOREP[repno].reset_write)(0); + } if self.state != RepeaterState::Up { return Ok(()); @@ -275,16 +294,21 @@ impl Repeater { #[cfg(not(has_drtio_routing))] #[derive(Clone, Copy, Default)] -pub struct Repeater { -} +pub struct Repeater {} #[cfg(not(has_drtio_routing))] impl Repeater { - pub fn new(_repno: u8) -> Repeater { Repeater::default() } + pub fn new(_repno: u8) -> Repeater { + Repeater::default() + } - pub fn service(&self, _routing_table: &drtio_routing::RoutingTable, _rank: u8, _timer: &mut GlobalTimer) { } + pub fn service(&self, _routing_table: &drtio_routing::RoutingTable, _rank: u8, _timer: &mut GlobalTimer) {} - pub fn sync_tsc(&self, _timer: &mut GlobalTimer) -> Result<(), drtioaux::Error> { Ok(()) } + pub fn sync_tsc(&self, _timer: &mut GlobalTimer) -> Result<(), drtioaux::Error> { + Ok(()) + } - pub fn rtio_reset(&self, _timer: &mut GlobalTimer) -> Result<(), drtioaux::Error> { Ok(()) } + pub fn rtio_reset(&self, _timer: &mut GlobalTimer) -> Result<(), drtioaux::Error> { + Ok(()) + } }