From 2b2ebb5354e51dde2096adbf33c2fbcdd844dc3a Mon Sep 17 00:00:00 2001 From: mwojcik Date: Tue, 7 May 2024 14:59:08 +0800 Subject: [PATCH] aux: increase max payload size --- src/libboard_artiq/src/drtioaux.rs | 29 ++++-------------------- src/libboard_artiq/src/drtioaux_async.rs | 17 ++++---------- src/libboard_artiq/src/drtioaux_proto.rs | 4 +++- src/libio/cursor.rs | 10 +++++--- 4 files changed, 19 insertions(+), 41 deletions(-) diff --git a/src/libboard_artiq/src/drtioaux.rs b/src/libboard_artiq/src/drtioaux.rs index 4731b77..9e27ac9 100644 --- a/src/libboard_artiq/src/drtioaux.rs +++ b/src/libboard_artiq/src/drtioaux.rs @@ -1,9 +1,10 @@ +use core::slice; + use core_io::{Error as IoError, ErrorKind as IoErrorKind}; use crc; use io::{proto::{ProtoRead, ProtoWrite}, Cursor}; use libboard_zynq::{time::Milliseconds, timer::GlobalTimer}; -use libcortex_a9::asm::dmb; pub use crate::drtioaux_proto::Packet; use crate::{drtioaux_proto::Error as ProtocolError, mem::mem::DRTIOAUX_MEM, pl::csr::DRTIOAUX}; @@ -56,19 +57,6 @@ pub fn has_rx_error(linkno: u8) -> bool { } } -pub fn copy_work_buffer(src: *mut u32, dst: *mut u32, len: isize) { - // AXI writes must be 4-byte aligned (drtio proto doesn't care for that), - // 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) { - *dst.offset(i) = *src.offset(i); - //data memory barrier to prevent bursts - dmb(); - } - } -} - fn receive(linkno: u8, f: F) -> Result, Error> where F: FnOnce(&[u8]) -> Result { let linkidx = linkno as usize; @@ -76,13 +64,7 @@ where F: FnOnce(&[u8]) -> Result { if (DRTIOAUX[linkidx].aux_rx_present_read)() == 1 { let read_ptr = (DRTIOAUX[linkidx].aux_read_pointer_read)() as usize; let ptr = (DRTIOAUX_MEM[linkidx].base + DRTIOAUX_MEM[linkidx].size / 2 + read_ptr * 0x400) as *mut u32; - // work buffer to accomodate axi burst reads - // buffer at maximum proto packet size, not maximum gateware supported size - // to minimize copying time - const LEN: usize = 512; - let mut buf: [u8; LEN] = [0; LEN]; - copy_work_buffer(ptr, buf.as_mut_ptr() as *mut u32, LEN as isize); - let result = f(&buf); + let result = f(slice::from_raw_parts(ptr as *mut u8, 0x400 as usize)); (DRTIOAUX[linkidx].aux_rx_present_write)(1); Ok(Some(result?)) } else { @@ -133,10 +115,7 @@ where F: FnOnce(&mut [u8]) -> Result { unsafe { while (DRTIOAUX[linkno].aux_tx_read)() != 0 {} let ptr = DRTIOAUX_MEM[linkno].base as *mut u32; - // work buffer, works with unaligned mem access - let mut buf: [u8; 1024] = [0; 1024]; - let len = f(&mut buf)?; - copy_work_buffer(buf.as_mut_ptr() as *mut u32, ptr, len as isize); + let len = f(slice::from_raw_parts_mut(ptr as *mut u8, 0x400 as usize))?; (DRTIOAUX[linkno].aux_tx_length_write)(len as u16); (DRTIOAUX[linkno].aux_tx_write)(1); Ok(()) diff --git a/src/libboard_artiq/src/drtioaux_async.rs b/src/libboard_artiq/src/drtioaux_async.rs index 0a400c8..08f18cf 100644 --- a/src/libboard_artiq/src/drtioaux_async.rs +++ b/src/libboard_artiq/src/drtioaux_async.rs @@ -1,3 +1,5 @@ +use core::slice; + use core_io::{Error as IoError, ErrorKind as IoErrorKind}; use crc; use io::{proto::{ProtoRead, ProtoWrite}, @@ -8,7 +10,7 @@ use nb; use void::Void; pub use crate::drtioaux_proto::Packet; -use crate::{drtioaux::{copy_work_buffer, has_rx_error, Error}, +use crate::{drtioaux::{has_rx_error, Error}, mem::mem::DRTIOAUX_MEM, pl::csr::DRTIOAUX}; @@ -40,13 +42,7 @@ where F: FnOnce(&[u8]) -> Result { if (DRTIOAUX[linkidx].aux_rx_present_read)() == 1 { let read_ptr = (DRTIOAUX[linkidx].aux_read_pointer_read)() as usize; let ptr = (DRTIOAUX_MEM[linkidx].base + DRTIOAUX_MEM[linkidx].size / 2 + read_ptr * 0x400) as *mut u32; - // work buffer to accomodate axi burst reads - // buffer at maximum proto packet size, not maximum gateware supported size - // to minimize required copying time - const LEN: usize = 512; - let mut buf: [u8; LEN] = [0; LEN]; - copy_work_buffer(ptr, buf.as_mut_ptr() as *mut u32, LEN as isize); - let result = f(&buf); + let result = f(slice::from_raw_parts(ptr as *mut u8, 0x400 as usize)); (DRTIOAUX[linkidx].aux_rx_present_write)(1); Ok(Some(result?)) } else { @@ -106,10 +102,7 @@ where F: FnOnce(&mut [u8]) -> Result { unsafe { let _ = block_async!(tx_ready(linkno)).await; let ptr = DRTIOAUX_MEM[linkno].base as *mut u32; - // work buffer, works with unaligned mem access - let mut buf: [u8; 1024] = [0; 1024]; - let len = f(&mut buf)?; - copy_work_buffer(buf.as_mut_ptr() as *mut u32, ptr, len as isize); + let len = f(slice::from_raw_parts_mut(ptr as *mut u8, 0x400 as usize))?; (DRTIOAUX[linkno].aux_tx_length_write)(len as u16); (DRTIOAUX[linkno].aux_tx_write)(1); Ok(()) diff --git a/src/libboard_artiq/src/drtioaux_proto.rs b/src/libboard_artiq/src/drtioaux_proto.rs index 1b5272a..cc649dd 100644 --- a/src/libboard_artiq/src/drtioaux_proto.rs +++ b/src/libboard_artiq/src/drtioaux_proto.rs @@ -1,9 +1,11 @@ use core_io::{Error as IoError, Read, Write}; use io::proto::{ProtoRead, ProtoWrite}; +const MAX_PACKET: usize = 1024; + // maximum size of arbitrary payloads // used by satellite -> master analyzer, subkernel exceptions -pub const SAT_PAYLOAD_MAX_SIZE: usize = /*max size*/512 - /*CRC*/4 - /*packet ID*/1 - /*last*/1 - /*length*/2; +pub const SAT_PAYLOAD_MAX_SIZE: usize = /*max size*/MAX_PACKET - /*CRC*/4 - /*packet ID*/1 - /*last*/1 - /*length*/2; // used by DDMA, subkernel program data (need to provide extra ID and destination) pub const MASTER_PAYLOAD_MAX_SIZE: usize = SAT_PAYLOAD_MAX_SIZE - /*source*/1 - /*destination*/1 - /*ID*/4; diff --git a/src/libio/cursor.rs b/src/libio/cursor.rs index e239022..bd397ac 100644 --- a/src/libio/cursor.rs +++ b/src/libio/cursor.rs @@ -45,7 +45,10 @@ 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()); - buf[..len].copy_from_slice(&data[..len]); + // ``copy_from_slice`` generates AXI bursts, use a regular loop instead + for i in 0..len { + buf[i] = data[i]; + } self.pos += len; Ok(len) } @@ -55,7 +58,9 @@ 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()); - data[..len].copy_from_slice(&buf[..len]); + for i in 0..len { + data[i] = buf[i]; + } self.pos += len; Ok(len) } @@ -68,7 +73,6 @@ impl Write for Cursor<&mut [u8]> { #[cfg(feature = "alloc")] impl Write for Cursor> { - #[inline] fn write(&mut self, buf: &[u8]) -> Result { self.inner.extend_from_slice(buf); Ok(buf.len())