diff --git a/README.rst b/README.rst index 537745b9a..216c77ba1 100644 --- a/README.rst +++ b/README.rst @@ -29,7 +29,7 @@ Website: https://m-labs.hk/artiq License ======= -Copyright (C) 2014-2021 M-Labs Limited. +Copyright (C) 2014-2022 M-Labs Limited. ARTIQ is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by diff --git a/artiq/coredevice/phaser.py b/artiq/coredevice/phaser.py index baadd8db8..b456266eb 100644 --- a/artiq/coredevice/phaser.py +++ b/artiq/coredevice/phaser.py @@ -478,8 +478,7 @@ class Phaser: * :const:`PHASER_STA_TRF1_LD`: Quadrature upconverter 1 lock detect * :const:`PHASER_STA_TERM0`: ADC channel 0 termination indicator * :const:`PHASER_STA_TERM1`: ADC channel 1 termination indicator - * :const:`PHASER_STA_SPI_IDLE`: SPI machine is idle and data registers - can be read/written + * :const:`PHASER_STA_SPI_IDLE`: SPI machine is idle and data registers can be read/written :return: Status register """ @@ -769,10 +768,11 @@ class PhaserChannel: * multiple oscillators (in the coredevice phy), * an interpolation chain and digital upconverter (DUC) on Phaser, * several channel-specific settings in the DAC: + * quadrature modulation compensation QMC * numerically controlled oscillator NCO or coarse mixer CMIX, - * the analog quadrature upconverter (in the Phaser-Upconverter hardware - variant), and + + * the analog quadrature upconverter (in the Phaser-Upconverter hardware variant), and * a digitally controlled step attenuator. Attributes: diff --git a/artiq/firmware/bootloader/main.rs b/artiq/firmware/bootloader/main.rs index 8c428bedb..555f8b0b6 100644 --- a/artiq/firmware/bootloader/main.rs +++ b/artiq/firmware/bootloader/main.rs @@ -493,7 +493,7 @@ pub extern fn main() -> i32 { println!(r"|_| |_|_|____/ \___/ \____|"); println!(""); println!("MiSoC Bootloader"); - println!("Copyright (c) 2017-2021 M-Labs Limited"); + println!("Copyright (c) 2017-2022 M-Labs Limited"); println!(""); #[cfg(has_ethmac)] diff --git a/artiq/firmware/ksupport/lib.rs b/artiq/firmware/ksupport/lib.rs index 1a1528494..2e7346c19 100644 --- a/artiq/firmware/ksupport/lib.rs +++ b/artiq/firmware/ksupport/lib.rs @@ -15,7 +15,7 @@ extern crate proto_artiq; extern crate riscv; use core::{mem, ptr, slice, str, convert::TryFrom}; -use cslice::{CSlice, AsCSlice}; +use cslice::CSlice; use io::Cursor; use dyld::Library; use board_artiq::{mailbox, rpc_queue}; @@ -190,13 +190,12 @@ fn terminate(exceptions: &'static [Option>], } #[unwind(aborts)] -extern fn cache_get<'a>(ret: &'a mut CSlice, key: &CSlice) -> &'a CSlice<'a, i32> { +extern fn cache_get<'a>(key: &CSlice) -> *const CSlice<'a, i32> { send(&CacheGetRequest { key: str::from_utf8(key.as_ref()).unwrap() }); recv!(&CacheGetReply { value } => { - *ret = value.as_c_slice(); - ret + value }) } diff --git a/artiq/firmware/libproto_artiq/kernel_proto.rs b/artiq/firmware/libproto_artiq/kernel_proto.rs index 3021447ec..8b07ea46b 100644 --- a/artiq/firmware/libproto_artiq/kernel_proto.rs +++ b/artiq/firmware/libproto_artiq/kernel_proto.rs @@ -1,4 +1,5 @@ use core::fmt; +use cslice::CSlice; use dyld; pub const KERNELCPU_EXEC_ADDRESS: usize = 0x45000000; @@ -53,7 +54,7 @@ pub enum Message<'a> { RpcFlush, CacheGetRequest { key: &'a str }, - CacheGetReply { value: &'static [i32] }, + CacheGetReply { value: *const CSlice<'static, i32> }, CachePutRequest { key: &'a str, value: &'a [i32] }, CachePutReply { succeeded: bool }, diff --git a/artiq/firmware/libproto_artiq/rpc_proto.rs b/artiq/firmware/libproto_artiq/rpc_proto.rs index a93a0e82c..5750d524e 100644 --- a/artiq/firmware/libproto_artiq/rpc_proto.rs +++ b/artiq/firmware/libproto_artiq/rpc_proto.rs @@ -70,16 +70,17 @@ unsafe fn recv_value(reader: &mut R, tag: Tag, data: &mut *mut (), Tag::List(it) => { #[repr(C)] struct List { elements: *mut (), length: u32 } - consume_value!(List, |ptr| { - (*ptr).length = reader.read_u32()?; - let length = (*ptr).length as usize; - + consume_value!(*mut List, |ptr| { let tag = it.clone().next().expect("truncated tag"); let padding = if let Tag::Int64 | Tag::Float64 = tag { 4 } else { 0 }; - let mut data = alloc(tag.size() * length + padding)?; - data = data.offset(alignment_offset(tag.alignment() as isize, data as isize)); + let length = reader.read_u32()? as usize; + let data = alloc(tag.size() * length + padding + 8)? as *mut u8; + *ptr = data as *mut List; + let ptr = data as *mut List; + let mut data = data.offset(8 + alignment_offset(tag.alignment() as isize, data as isize)) as *mut (); + (*ptr).length = length as u32; (*ptr).elements = data; match tag { Tag::Bool => { @@ -221,11 +222,11 @@ unsafe fn send_value(writer: &mut W, tag: Tag, data: &mut *const ()) Tag::List(it) => { #[repr(C)] struct List { elements: *const (), length: u32 } - consume_value!(List, |ptr| { - let length = (*ptr).length as usize; - writer.write_u32((*ptr).length)?; + consume_value!(&List, |ptr| { + let length = (**ptr).length as usize; + writer.write_u32((**ptr).length)?; let tag = it.clone().next().expect("truncated tag"); - let mut data = (*ptr).elements; + let mut data = (**ptr).elements; writer.write_u8(tag.as_u8())?; match tag { // we cannot use NativeEndian::from_slice_i32 as the data is not mutable, diff --git a/artiq/firmware/runtime/cache.rs b/artiq/firmware/runtime/cache.rs index a950fab3b..ba6898653 100644 --- a/artiq/firmware/runtime/cache.rs +++ b/artiq/firmware/runtime/cache.rs @@ -1,27 +1,50 @@ use alloc::{vec::Vec, string::String, collections::btree_map::BTreeMap}; +use cslice::{CSlice, AsCSlice}; +use core::mem::transmute; -#[derive(Debug)] struct Entry { data: Vec, + slice: CSlice<'static, i32>, borrowed: bool } -#[derive(Debug)] +impl core::fmt::Debug for Entry { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("Entry") + .field("data", &self.data) + .field("borrowed", &self.borrowed) + .finish() + } +} + pub struct Cache { - entries: BTreeMap + entries: BTreeMap, + empty: CSlice<'static, i32>, +} + +impl core::fmt::Debug for Cache { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("Cache") + .field("entries", &self.entries) + .finish() + } } impl Cache { pub fn new() -> Cache { - Cache { entries: BTreeMap::new() } + let empty_vec = vec![]; + let empty = unsafe { + transmute::, CSlice<'static, i32>>(empty_vec.as_c_slice()) + }; + Cache { entries: BTreeMap::new(), empty } } - pub fn get(&mut self, key: &str) -> *const [i32] { + pub fn get(&mut self, key: &str) -> *const CSlice<'static, i32> { match self.entries.get_mut(key) { - None => &[], + None => &self.empty, Some(ref mut entry) => { entry.borrowed = true; - &entry.data[..] + &entry.slice } } } @@ -32,12 +55,21 @@ impl Cache { Some(ref mut entry) => { if entry.borrowed { return Err(()) } entry.data = Vec::from(data); + unsafe { + entry.slice = transmute::, CSlice<'static, i32>>( + entry.data.as_c_slice()); + } return Ok(()) } } + let data = Vec::from(data); + let slice = unsafe { + transmute::, CSlice<'static, i32>>(data.as_c_slice()) + }; self.entries.insert(String::from(key), Entry { - data: Vec::from(data), + data, + slice, borrowed: false }); Ok(()) diff --git a/artiq/firmware/runtime/session.rs b/artiq/firmware/runtime/session.rs index bf374eb5d..aec47afe1 100644 --- a/artiq/firmware/runtime/session.rs +++ b/artiq/firmware/runtime/session.rs @@ -418,7 +418,7 @@ fn process_kern_message(io: &Io, aux_mutex: &Mutex, kern_send(io, &kern::CacheGetReply { // Zing! This transmute is only safe because we dynamically track // whether the kernel has borrowed any values from the cache. - value: unsafe { mem::transmute::<*const [i32], &'static [i32]>(value) } + value: unsafe { mem::transmute(value) } }) } diff --git a/doc/manual/conf.py b/doc/manual/conf.py index ad0a85689..61680750c 100644 --- a/doc/manual/conf.py +++ b/doc/manual/conf.py @@ -94,7 +94,7 @@ master_doc = 'index' # General information about the project. project = 'ARTIQ' -copyright = '2014-2021, M-Labs Limited' +copyright = '2014-2022, M-Labs Limited' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the diff --git a/doc/manual/core_device.rst b/doc/manual/core_device.rst index fa3466d32..6ba064e52 100644 --- a/doc/manual/core_device.rst +++ b/doc/manual/core_device.rst @@ -165,10 +165,12 @@ Clocking ++++++++ The KC705 in standalone variants supports an internal 125 MHz RTIO clock (based on its crystal oscillator, or external reference for PLL for DRTIO variants) and an external clock, that can be selected using the ``rtio_clock`` configuration entry. Valid values are: + * ``int_125`` - internal crystal oscillator, 125 MHz output (default), * ``ext0_bypass`` - external clock. KC705 in DRTIO variants and Kasli generates the RTIO clock using a PLL locked either to an internal crystal or to an external frequency reference. Valid values are: + * ``int_125`` - internal crystal oscillator using PLL, 125 MHz output (default), * ``int_100`` - internal crystal oscillator using PLL, 100 MHz output, * ``int_150`` - internal crystal oscillator using PLL, 150 MHz output, diff --git a/doc/manual/introduction.rst b/doc/manual/introduction.rst index 7dcc2f802..23eaa98a9 100644 --- a/doc/manual/introduction.rst +++ b/doc/manual/introduction.rst @@ -27,4 +27,4 @@ Website: https://m-labs.hk/artiq `Cite ARTIQ `_ as ``Bourdeauducq, Sébastien et al. (2016). ARTIQ 1.0. Zenodo. 10.5281/zenodo.51303``. -Copyright (C) 2014-2021 M-Labs Limited. Licensed under GNU LGPL version 3+. +Copyright (C) 2014-2022 M-Labs Limited. Licensed under GNU LGPL version 3+.