From ad3aeb5109df4e2191eca7d6d96eb8825901e34d Mon Sep 17 00:00:00 2001 From: mwojcik Date: Wed, 23 Mar 2022 10:41:06 +0800 Subject: [PATCH 1/3] fix (workaround) drtioaux packets being corrupted --- src/libboard_artiq/src/drtioaux.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/libboard_artiq/src/drtioaux.rs b/src/libboard_artiq/src/drtioaux.rs index 4971502..1e2534a 100644 --- a/src/libboard_artiq/src/drtioaux.rs +++ b/src/libboard_artiq/src/drtioaux.rs @@ -66,6 +66,13 @@ pub fn copy_work_buffer(src: *mut u16, dst: *mut u16, len: isize) { *dst.offset(i) = *src.offset(i); *dst.offset(i+1) = *src.offset(i+1); } + // workaround for corrupted writes + // check and re-write + for i in 0..len { + if *dst.offset(i) != *src.offset(i) { + *dst.offset(i) = *src.offset(i); + } + } } } -- 2.44.1 From 77ca0204505696600dcc3b990d9211dbffecb14d Mon Sep 17 00:00:00 2001 From: mwojcik Date: Wed, 30 Mar 2022 17:07:58 +0800 Subject: [PATCH 2/3] drtio: fix garbage data on transmission --- src/libboard_artiq/src/drtioaux.rs | 22 ++++++++-------------- src/libboard_artiq/src/drtioaux_async.rs | 8 ++++---- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/src/libboard_artiq/src/drtioaux.rs b/src/libboard_artiq/src/drtioaux.rs index 1e2534a..33442e1 100644 --- a/src/libboard_artiq/src/drtioaux.rs +++ b/src/libboard_artiq/src/drtioaux.rs @@ -57,21 +57,15 @@ pub fn has_rx_error(linkno: u8) -> bool { } } -pub fn copy_work_buffer(src: *mut u16, dst: *mut u16, len: isize) { +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/2)).step_by(2) { - *dst.offset(i) = *src.offset(i); + for i in (0..(len/4)).step_by(2) { + //mix offsets to prevent bursts *dst.offset(i+1) = *src.offset(i+1); - } - // workaround for corrupted writes - // check and re-write - for i in 0..len { - if *dst.offset(i) != *src.offset(i) { - *dst.offset(i) = *src.offset(i); - } + *dst.offset(i) = *src.offset(i); } } } @@ -82,11 +76,11 @@ fn receive(linkno: u8, f: F) -> Result, Error> let linkidx = linkno as usize; unsafe { if (DRTIOAUX[linkidx].aux_rx_present_read)() == 1 { - let ptr = (DRTIOAUX_MEM[linkidx].base + DRTIOAUX_MEM[linkidx].size / 2) as *mut u16; + let ptr = (DRTIOAUX_MEM[linkidx].base + DRTIOAUX_MEM[linkidx].size / 2) as *mut u32; let len = (DRTIOAUX[linkidx].aux_rx_length_read)() as usize; // work buffer to accomodate axi burst reads let mut buf: [u8; 1024] = [0; 1024]; - copy_work_buffer(ptr, buf.as_mut_ptr() as *mut u16, len as isize); + copy_work_buffer(ptr, buf.as_mut_ptr() as *mut u32, len as isize); let result = f(&buf[0..len]); (DRTIOAUX[linkidx].aux_rx_present_write)(1); Ok(Some(result?)) @@ -140,12 +134,12 @@ fn transmit(linkno: u8, f: F) -> Result<(), Error> let linkno = linkno as usize; unsafe { while (DRTIOAUX[linkno].aux_tx_read)() != 0 {} - let ptr = DRTIOAUX_MEM[linkno].base as *mut u16; + 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 len = f(&mut buf[0..len])?; - copy_work_buffer(buf.as_mut_ptr() as *mut u16, ptr, len as isize); + copy_work_buffer(buf.as_mut_ptr() as *mut u32, ptr, len as isize); (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 cab9791..374bfee 100644 --- a/src/libboard_artiq/src/drtioaux_async.rs +++ b/src/libboard_artiq/src/drtioaux_async.rs @@ -42,11 +42,11 @@ async fn receive(linkno: u8, f: F) -> Result, Error> let linkidx = linkno as usize; unsafe { if (DRTIOAUX[linkidx].aux_rx_present_read)() == 1 { - let ptr = (DRTIOAUX_MEM[linkidx].base + DRTIOAUX_MEM[linkidx].size / 2) as *mut u16; + let ptr = (DRTIOAUX_MEM[linkidx].base + DRTIOAUX_MEM[linkidx].size / 2) as *mut u32; let len = (DRTIOAUX[linkidx].aux_rx_length_read)() as usize; // work buffer to accomodate axi burst reads let mut buf: [u8; 1024] = [0; 1024]; - copy_work_buffer(ptr, buf.as_mut_ptr() as *mut u16, len as isize); + copy_work_buffer(ptr, buf.as_mut_ptr() as *mut u32, len as isize); let result = f(&buf[0..len]); (DRTIOAUX[linkidx].aux_rx_present_write)(1); Ok(Some(result?)) @@ -106,12 +106,12 @@ async fn transmit(linkno: u8, f: F) -> Result<(), Error> let linkno = linkno as usize; unsafe { let _ = block_async!(tx_ready(linkno)).await; - let ptr = DRTIOAUX_MEM[linkno].base as *mut u16; + 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 len = f(&mut buf[0..len])?; - copy_work_buffer(buf.as_mut_ptr() as *mut u16, ptr, len as isize); + copy_work_buffer(buf.as_mut_ptr() as *mut u32, ptr, len as isize); (DRTIOAUX[linkno].aux_tx_length_write)(len as u16); (DRTIOAUX[linkno].aux_tx_write)(1); Ok(()) -- 2.44.1 From 6d47f4ac7e81affda468501ce6afad975417d4e1 Mon Sep 17 00:00:00 2001 From: mwojcik Date: Thu, 31 Mar 2022 12:26:51 +0800 Subject: [PATCH 3/3] drtio: dmb to prevent bursts --- src/libboard_artiq/src/drtioaux.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libboard_artiq/src/drtioaux.rs b/src/libboard_artiq/src/drtioaux.rs index 33442e1..b118a0f 100644 --- a/src/libboard_artiq/src/drtioaux.rs +++ b/src/libboard_artiq/src/drtioaux.rs @@ -3,6 +3,7 @@ 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 libcortex_a9::asm::dmb; use crate::mem::mem::DRTIOAUX_MEM; use crate::pl::csr::DRTIOAUX; use crate::drtioaux_proto::Error as ProtocolError; @@ -62,10 +63,10 @@ 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)).step_by(2) { - //mix offsets to prevent bursts - *dst.offset(i+1) = *src.offset(i+1); + for i in 0..(len/4) { *dst.offset(i) = *src.offset(i); + //data memory barrier to prevent bursts + dmb(); } } } -- 2.44.1