diff --git a/artiq/firmware/Cargo.lock b/artiq/firmware/Cargo.lock index f129d0d28..5bfb45676 100644 --- a/artiq/firmware/Cargo.lock +++ b/artiq/firmware/Cargo.lock @@ -1,10 +1,13 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +# And yet, manual edits have been made. Crate yanking should be illegal. +version = 3 + [[package]] name = "addr2line" -version = "0.14.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c0929d69e78dd9bf5408269919fcbcaeb2e35e5d43e5815517cdc6a8e11a423" +checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd" dependencies = [ "cpp_demangle", "fallible-iterator", @@ -28,15 +31,20 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.4.8" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0453232ace82dee0dd0b4c87a59bd90f7b53b314f3e0f61fe2ee7c8a16482289" +checksum = "efa60d2eadd8b12a996add391db32bd1153eac697ba4869660c0016353611426" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] [[package]] name = "aho-corasick" -version = "0.7.15" +version = "0.7.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" dependencies = [ "memchr", ] @@ -105,6 +113,7 @@ name = "bootloader" version = "0.0.0" dependencies = [ "addr2line", + "ahash", "board_misoc", "build_misoc", "byteorder", @@ -114,15 +123,18 @@ dependencies = [ "dlmalloc", "fortanix-sgx-abi", "getopts", + "getrandom", "hashbrown", "hermit-abi", - "libc 0.2.79", - "memchr", + "libc 0.2.99", "miniz_oxide 0.4.0", + "object", + "once_cell", "riscv", "rustc-demangle", "smoltcp", "unicode-width", + "version_check", "wasi", ] @@ -144,9 +156,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "cc" -version = "1.0.60" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef611cc68ff783f18535d77ddd080185275713d852c4f5cbb6122c462a7a825c" +checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" [[package]] name = "cfg-if" @@ -162,9 +174,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "compiler_builtins" -version = "0.1.39" +version = "0.1.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3748f82c7d366a0b4950257d19db685d4958d2fa27c6d164a3f069fec42b748b" +checksum = "20b1438ef42c655665a8ab2c1c6d605a305f031d38d9be689ddfef41a20f3aa2" [[package]] name = "cpp_demangle" @@ -205,7 +217,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "332570860c2edf2d57914987bf9e24835425f75825086b6ba7d1e6a3e4f1f254" dependencies = [ - "libc 0.2.79", + "libc 0.2.99", ] [[package]] @@ -265,7 +277,7 @@ name = "fringe" version = "1.2.1" source = "git+https://git.m-labs.hk/M-Labs/libfringe.git?rev=3ecbe5#3ecbe53f7644b18ee46ebd5b2ca12c9cbceec43a" dependencies = [ - "libc 0.2.79", + "libc 0.2.99", ] [[package]] @@ -278,10 +290,21 @@ dependencies = [ ] [[package]] -name = "gimli" -version = "0.23.0" +name = "getrandom" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce" +checksum = "ee8025cf36f917e6a52cce185b7c7177689b838b7ec138364e50cc2277a56cf4" +dependencies = [ + "cfg-if 0.1.10", + "libc 0.2.99", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7" dependencies = [ "fallible-iterator", "stable_deref_trait", @@ -289,20 +312,20 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.9.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00d63df3d41950fb462ed38308eea019113ad1508da725bbedcd0fa5a85ef5f7" +checksum = "362385356d610bd1e5a408ddf8d022041774b683f345a1d2cfcb4f60f8ae2db5" dependencies = [ "ahash", ] [[package]] name = "hermit-abi" -version = "0.1.17" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ - "libc 0.2.79", + "libc 0.2.99", ] [[package]] @@ -343,9 +366,9 @@ version = "0.1.0" [[package]] name = "libc" -version = "0.2.79" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2448f6066e80e3bfc792e9c98bf705b4b0fc6e8ef5b43e5889aff0eaa9c58743" +checksum = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765" [[package]] name = "log" @@ -385,9 +408,9 @@ checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d" [[package]] name = "memchr" -version = "2.3.4" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" [[package]] name = "miniz_oxide" @@ -409,14 +432,20 @@ dependencies = [ [[package]] name = "object" -version = "0.22.0" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397" +checksum = "39f37e50073ccad23b6d09bcb5b263f4e76d3bb6038e4a3c08e52162ffa8abc2" dependencies = [ "flate2", - "wasmparser", + "memchr", ] +[[package]] +name = "once_cell" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" + [[package]] name = "proto_artiq" version = "0.0.0" @@ -439,9 +468,9 @@ checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" [[package]] name = "regex" -version = "1.4.6" +version = "1.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a26af418b574bd56588335b3a3659a65725d4e636eb1016c2f9e3b38c7cc759" +checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d" dependencies = [ "aho-corasick", "memchr", @@ -503,9 +532,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.18" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232" +checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" [[package]] name = "rustc_version" @@ -638,14 +667,14 @@ dependencies = [ "unwind", ] +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "wasmparser" -version = "0.57.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32fddd575d477c6e9702484139cf9f23dcd554b06d185ed0f56c857dd3a47aa6" diff --git a/artiq/firmware/bootloader/Cargo.toml b/artiq/firmware/bootloader/Cargo.toml index 58cf68e33..911864e30 100644 --- a/artiq/firmware/bootloader/Cargo.toml +++ b/artiq/firmware/bootloader/Cargo.toml @@ -20,18 +20,23 @@ smoltcp = { version = "0.8.2", default-features = false, features = ["medium-eth riscv = { version = "0.6.0", features = ["inline-asm"] } # insanity required by using cargo build-std over xbuild with nix +# cargo update does not work thanks to ahash 0.7 problems [dev-dependencies] getopts = "=0.2.21" -libc = "=0.2.79" +libc = "=0.2.99" unicode-width = "=0.1.8" -addr2line = "=0.14.0" -memchr = "=2.3.4" -hashbrown = "=0.9.0" +addr2line = "=0.16.0" +hashbrown = "=0.11.0" # must be injected into lockfile manually +ahash = "=0.7.0" # must be injected into lockfile manually miniz_oxide = "=0.4.0" -rustc-demangle = "=0.1.18" -hermit-abi = "=0.1.17" +rustc-demangle = "=0.1.21" +hermit-abi = "=0.1.19" dlmalloc = "=0.2.1" -wasi = "=0.9.0" fortanix-sgx-abi = "=0.3.3" -cc = "=1.0.60" -compiler_builtins = "=0.1.39" \ No newline at end of file +cc = "=1.0.69" +compiler_builtins = "=0.1.49" +version_check = "=0.9.3" +once_cell = "=1.8.0" +wasi = "=0.9.0" +getrandom = "=0.2.0" +object = "=0.26.2" \ No newline at end of file diff --git a/artiq/firmware/ksupport/eh_artiq.rs b/artiq/firmware/ksupport/eh_artiq.rs index 80d999304..04c6e723e 100644 --- a/artiq/firmware/ksupport/eh_artiq.rs +++ b/artiq/firmware/ksupport/eh_artiq.rs @@ -55,12 +55,14 @@ struct ExceptionBuffer { exception_count: usize, } +const EXCEPTION: uw::_Unwind_Exception = uw::_Unwind_Exception { + exception_class: EXCEPTION_CLASS, + exception_cleanup: cleanup, + private: [0; uw::unwinder_private_data_size], +}; + static mut EXCEPTION_BUFFER: ExceptionBuffer = ExceptionBuffer { - uw_exceptions: [uw::_Unwind_Exception { - exception_class: EXCEPTION_CLASS, - exception_cleanup: cleanup, - private: [0; uw::unwinder_private_data_size], - }; MAX_INFLIGHT_EXCEPTIONS], + uw_exceptions: [EXCEPTION; MAX_INFLIGHT_EXCEPTIONS], exceptions: [None; MAX_INFLIGHT_EXCEPTIONS + 1], exception_stack: [-1; MAX_INFLIGHT_EXCEPTIONS + 1], backtrace: [(0, 0); MAX_BACKTRACE_SIZE], @@ -74,11 +76,7 @@ static mut EXCEPTION_BUFFER: ExceptionBuffer = ExceptionBuffer { }; pub unsafe extern fn reset_exception_buffer(payload_addr: usize) { - EXCEPTION_BUFFER.uw_exceptions = [uw::_Unwind_Exception { - exception_class: EXCEPTION_CLASS, - exception_cleanup: cleanup, - private: [0; uw::unwinder_private_data_size], - }; MAX_INFLIGHT_EXCEPTIONS]; + EXCEPTION_BUFFER.uw_exceptions = [EXCEPTION; MAX_INFLIGHT_EXCEPTIONS]; EXCEPTION_BUFFER.exceptions = [None; MAX_INFLIGHT_EXCEPTIONS + 1]; EXCEPTION_BUFFER.exception_stack = [-1; MAX_INFLIGHT_EXCEPTIONS + 1]; EXCEPTION_BUFFER.backtrace_size = 0; @@ -151,8 +149,7 @@ pub extern fn personality(version: c_int, } #[export_name="__artiq_raise"] -#[unwind(allowed)] -pub unsafe extern fn raise(exception: *const Exception) -> ! { +pub unsafe extern "C-unwind" fn raise(exception: *const Exception) -> ! { let count = EXCEPTION_BUFFER.exception_count; let stack = &mut EXCEPTION_BUFFER.exception_stack; let diff = exception as isize - EXCEPTION_BUFFER.exceptions.as_ptr() as isize; @@ -222,8 +219,7 @@ pub unsafe extern fn raise(exception: *const Exception) -> ! { #[export_name="__artiq_resume"] -#[unwind(allowed)] -pub unsafe extern fn resume() -> ! { +pub unsafe extern "C-unwind" fn resume() -> ! { assert!(EXCEPTION_BUFFER.exception_count != 0); let i = EXCEPTION_BUFFER.exception_stack[EXCEPTION_BUFFER.exception_count - 1]; assert!(i != -1); @@ -233,8 +229,7 @@ pub unsafe extern fn resume() -> ! { } #[export_name="__artiq_end_catch"] -#[unwind(allowed)] -pub unsafe extern fn end_catch() { +pub unsafe extern "C-unwind" fn end_catch() { let mut count = EXCEPTION_BUFFER.exception_count; assert!(count != 0); // we remove all exceptions with SP <= current exception SP diff --git a/artiq/firmware/ksupport/lib.rs b/artiq/firmware/ksupport/lib.rs index 0bbb40df1..42f9de3e5 100644 --- a/artiq/firmware/ksupport/lib.rs +++ b/artiq/firmware/ksupport/lib.rs @@ -1,5 +1,5 @@ -#![feature(lang_items, llvm_asm, panic_unwind, libc, unwind_attributes, - panic_info_message, nll, const_in_array_repeat_expressions)] +#![feature(lang_items, asm, panic_unwind, libc, + panic_info_message, nll, c_unwind)] #![no_std] extern crate libc; @@ -30,8 +30,9 @@ fn send(request: &Message) { } fn recv R>(f: F) -> R { - while mailbox::receive() == 0 {} - let result = f(unsafe { &*(mailbox::receive() as *const Message) }); + let mut msg_ptr = 0; + while msg_ptr == 0 { msg_ptr = mailbox::receive(); } + let result = f(unsafe { &*(msg_ptr as *const Message) }); mailbox::acknowledge(); result } @@ -121,7 +122,6 @@ pub extern fn send_to_rtio_log(text: CSlice) { rtio::log(text.as_ref()) } -#[unwind(aborts)] extern fn rpc_send(service: u32, tag: &CSlice, data: *const *const ()) { while !rpc_queue::empty() {} send(&RpcSend { @@ -132,7 +132,6 @@ extern fn rpc_send(service: u32, tag: &CSlice, data: *const *const ()) { }) } -#[unwind(aborts)] extern fn rpc_send_async(service: u32, tag: &CSlice, data: *const *const ()) { while rpc_queue::full() {} rpc_queue::enqueue(|mut slice| { @@ -170,8 +169,7 @@ extern fn rpc_send_async(service: u32, tag: &CSlice, data: *const *const ()) /// to the maximum required for any of the possible types according to the target ABI). /// /// If the RPC call resulted in an exception, it is reconstructed and raised. -#[unwind(allowed)] -extern fn rpc_recv(slot: *mut ()) -> usize { +extern "C-unwind" fn rpc_recv(slot: *mut ()) -> usize { send(&RpcRecvRequest(slot)); recv!(&RpcRecvReply(ref result) => { match result { @@ -203,7 +201,6 @@ fn terminate(exceptions: &'static [Option>], loop {} } -#[unwind(aborts)] extern fn cache_get<'a>(key: &CSlice) -> *const CSlice<'a, i32> { send(&CacheGetRequest { key: str::from_utf8(key.as_ref()).unwrap() @@ -213,8 +210,7 @@ extern fn cache_get<'a>(key: &CSlice) -> *const CSlice<'a, i32> { }) } -#[unwind(allowed)] -extern fn cache_put(key: &CSlice, list: &CSlice) { +extern "C-unwind" fn cache_put(key: &CSlice, list: &CSlice) { send(&CachePutRequest { key: str::from_utf8(key.as_ref()).unwrap(), value: list.as_ref() @@ -247,8 +243,7 @@ fn dma_record_flush() { } } -#[unwind(allowed)] -extern fn dma_record_start(name: &CSlice) { +extern "C-unwind" fn dma_record_start(name: &CSlice) { let name = str::from_utf8(name.as_ref()).unwrap(); unsafe { @@ -267,8 +262,7 @@ extern fn dma_record_start(name: &CSlice) { } } -#[unwind(allowed)] -extern fn dma_record_stop(duration: i64, enable_ddma: bool) { +extern "C-unwind" fn dma_record_stop(duration: i64, enable_ddma: bool) { unsafe { dma_record_flush(); @@ -290,7 +284,6 @@ extern fn dma_record_stop(duration: i64, enable_ddma: bool) { } } -#[unwind(aborts)] #[inline(always)] unsafe fn dma_record_output_prepare(timestamp: i64, target: i32, words: usize) -> &'static mut [u8] { @@ -327,7 +320,6 @@ unsafe fn dma_record_output_prepare(timestamp: i64, target: i32, data } -#[unwind(aborts)] extern fn dma_record_output(target: i32, word: i32) { unsafe { let timestamp = ((csr::rtio::now_hi_read() as i64) << 32) | (csr::rtio::now_lo_read() as i64); @@ -341,7 +333,6 @@ extern fn dma_record_output(target: i32, word: i32) { } } -#[unwind(aborts)] extern fn dma_record_output_wide(target: i32, words: &CSlice) { assert!(words.len() <= 16); // enforce the hardware limit @@ -360,7 +351,6 @@ extern fn dma_record_output_wide(target: i32, words: &CSlice) { } } -#[unwind(aborts)] extern fn dma_erase(name: &CSlice) { let name = str::from_utf8(name.as_ref()).unwrap(); @@ -374,8 +364,7 @@ struct DmaTrace { uses_ddma: bool, } -#[unwind(allowed)] -extern fn dma_retrieve(name: &CSlice) -> DmaTrace { +extern "C-unwind" fn dma_retrieve(name: &CSlice) -> DmaTrace { let name = str::from_utf8(name.as_ref()).unwrap(); send(&DmaRetrieveRequest { name: name }); @@ -396,8 +385,7 @@ extern fn dma_retrieve(name: &CSlice) -> DmaTrace { } #[cfg(kernel_has_rtio_dma)] -#[unwind(allowed)] -extern fn dma_playback(timestamp: i64, ptr: i32, _uses_ddma: bool) { +extern "C-unwind" fn dma_playback(timestamp: i64, ptr: i32, _uses_ddma: bool) { assert!(ptr % 64 == 0); unsafe { @@ -454,15 +442,13 @@ extern fn dma_playback(timestamp: i64, ptr: i32, _uses_ddma: bool) { } #[cfg(all(not(kernel_has_rtio_dma), not(has_rtio_dma)))] -#[unwind(allowed)] -extern fn dma_playback(_timestamp: i64, _ptr: i32, _uses_ddma: bool) { +extern "C-unwind" fn dma_playback(_timestamp: i64, _ptr: i32, _uses_ddma: bool) { unimplemented!("not(kernel_has_rtio_dma)") } // for satellite (has_rtio_dma but not in kernel) #[cfg(all(not(kernel_has_rtio_dma), has_rtio_dma))] -#[unwind(allowed)] -extern fn dma_playback(timestamp: i64, ptr: i32, _uses_ddma: bool) { +extern "C-unwind" fn dma_playback(timestamp: i64, ptr: i32, _uses_ddma: bool) { // DDMA is always used on satellites, so the `uses_ddma` setting is ignored // StartRemoteRequest reused as "normal" start request send(&DmaStartRemoteRequest { id: ptr as i32, timestamp: timestamp }); @@ -486,8 +472,7 @@ extern fn dma_playback(timestamp: i64, ptr: i32, _uses_ddma: bool) { } -#[unwind(allowed)] -extern fn subkernel_load_run(id: u32, destination: u8, run: bool) { +extern "C-unwind" fn subkernel_load_run(id: u32, destination: u8, run: bool) { send(&SubkernelLoadRunRequest { id: id, destination: destination, run: run }); recv!(&SubkernelLoadRunReply { succeeded } => { if !succeeded { @@ -497,8 +482,7 @@ extern fn subkernel_load_run(id: u32, destination: u8, run: bool) { }); } -#[unwind(allowed)] -extern fn subkernel_await_finish(id: u32, timeout: i64) { +extern "C-unwind" fn subkernel_await_finish(id: u32, timeout: i64) { send(&SubkernelAwaitFinishRequest { id: id, timeout: timeout }); recv!(SubkernelAwaitFinishReply { status } => { match status { @@ -515,7 +499,6 @@ extern fn subkernel_await_finish(id: u32, timeout: i64) { }) } -#[unwind(aborts)] extern fn subkernel_send_message(id: u32, is_return: bool, destination: u8, count: u8, tag: &CSlice, data: *const *const ()) { send(&SubkernelMsgSend { @@ -527,8 +510,7 @@ extern fn subkernel_send_message(id: u32, is_return: bool, destination: u8, }); } -#[unwind(allowed)] -extern fn subkernel_await_message(id: i32, timeout: i64, tags: &CSlice, min: u8, max: u8) -> u8 { +extern "C-unwind" fn subkernel_await_message(id: i32, timeout: i64, tags: &CSlice, min: u8, max: u8) -> u8 { send(&SubkernelMsgRecvRequest { id: id, timeout: timeout, tags: tags.as_ref() }); recv!(SubkernelMsgRecvReply { status, count } => { match status { @@ -653,8 +635,7 @@ pub unsafe fn main() { } #[no_mangle] -#[unwind(allowed)] -pub unsafe extern fn exception(_regs: *const u32) { +pub unsafe extern "C-unwind" fn exception(_regs: *const u32) { let pc = mepc::read(); let cause = mcause::read().cause(); let mtval = mtval::read(); @@ -672,7 +653,6 @@ pub unsafe extern fn exception(_regs: *const u32) { } #[no_mangle] -#[unwind(allowed)] -pub extern fn abort() { +pub extern "C-unwind" fn abort() { panic!("aborted") } diff --git a/artiq/firmware/libboard_artiq/lib.rs b/artiq/firmware/libboard_artiq/lib.rs index f564c98e4..e18dd1ddd 100644 --- a/artiq/firmware/libboard_artiq/lib.rs +++ b/artiq/firmware/libboard_artiq/lib.rs @@ -1,4 +1,4 @@ -#![feature(lang_items, never_type)] +#![feature(asm, lang_items, never_type)] #![no_std] extern crate failure; diff --git a/artiq/firmware/libboard_artiq/mailbox.rs b/artiq/firmware/libboard_artiq/mailbox.rs index 9c1f374f6..fd4ed7d67 100644 --- a/artiq/firmware/libboard_artiq/mailbox.rs +++ b/artiq/firmware/libboard_artiq/mailbox.rs @@ -6,7 +6,11 @@ static mut LAST: usize = 0; pub unsafe fn send(data: usize) { LAST = data; - write_volatile(MAILBOX, data) + // after Rust toolchain update to LLVM12, this empty asm! block is required + // to ensure that the compiler doesn't take any shortcuts + // otherwise, the comm CPU will read garbage data and crash + asm!("", options(preserves_flags, readonly, nostack)); + write_volatile(MAILBOX, data); } pub fn acknowledged() -> bool { diff --git a/artiq/firmware/libboard_misoc/lib.rs b/artiq/firmware/libboard_misoc/lib.rs index 4374a44f9..8f56e3f65 100644 --- a/artiq/firmware/libboard_misoc/lib.rs +++ b/artiq/firmware/libboard_misoc/lib.rs @@ -1,5 +1,4 @@ #![no_std] -#![feature(llvm_asm)] #![feature(asm)] extern crate byteorder; diff --git a/artiq/firmware/libboard_misoc/riscv32/boot.rs b/artiq/firmware/libboard_misoc/riscv32/boot.rs index 0d2254da1..1ef0bd44f 100644 --- a/artiq/firmware/libboard_misoc/riscv32/boot.rs +++ b/artiq/firmware/libboard_misoc/riscv32/boot.rs @@ -2,29 +2,26 @@ use super::{cache, pmp}; use riscv::register::*; pub unsafe fn reset() -> ! { - llvm_asm!(r#" - j _reset_handler - nop - "# : : : : "volatile"); - loop {} + asm!("j _reset_handler", + "nop", + options(nomem, nostack, noreturn) + ); } pub unsafe fn jump(addr: usize) -> ! { cache::flush_cpu_icache(); - llvm_asm!(r#" - jalr x0, 0($0) - nop - "# : : "r"(addr) : : "volatile"); - loop {} + asm!("jalr x0, 0({0})", + "nop", + in(reg) addr, + options(nomem, nostack, noreturn) + ); } pub unsafe fn start_user(addr: usize) -> ! { pmp::enable_user_memory(); mstatus::set_mpp(mstatus::MPP::User); mepc::write(addr); - llvm_asm!( - "mret" - : : : : "volatile" + asm!("mret", + options(nomem, nostack, noreturn) ); - unreachable!() } diff --git a/artiq/firmware/libboard_misoc/riscv32/cache.rs b/artiq/firmware/libboard_misoc/riscv32/cache.rs index 12fc9f3bb..ac0b4ed12 100644 --- a/artiq/firmware/libboard_misoc/riscv32/cache.rs +++ b/artiq/firmware/libboard_misoc/riscv32/cache.rs @@ -7,20 +7,24 @@ use mem; pub fn flush_cpu_icache() { unsafe { - llvm_asm!(r#" - fence.i - nop - nop - nop - nop - nop - "# : : : : "volatile"); + asm!( + "fence.i", + "nop", + "nop", + "nop", + "nop", + "nop", + options(preserves_flags, nostack) + ); } } pub fn flush_cpu_dcache() { unsafe { - llvm_asm!(".word(0x500F)" : : : : "volatile"); + asm!( + ".word(0x500F)", + options(preserves_flags) + ); } } diff --git a/artiq/firmware/libeh/lib.rs b/artiq/firmware/libeh/lib.rs index 4fdc4b880..dfdbf6034 100644 --- a/artiq/firmware/libeh/lib.rs +++ b/artiq/firmware/libeh/lib.rs @@ -1,4 +1,4 @@ -#![feature(lang_items, panic_unwind, libc, unwind_attributes, int_bits_const)] +#![feature(lang_items, panic_unwind, libc)] #![no_std] extern crate cslice; diff --git a/artiq/firmware/libunwind/src/lib.rs b/artiq/firmware/libunwind/src/lib.rs index a087a59ec..5567320c3 100644 --- a/artiq/firmware/libunwind/src/lib.rs +++ b/artiq/firmware/libunwind/src/lib.rs @@ -3,8 +3,8 @@ #![feature(link_cfg)] #![feature(nll)] #![feature(staged_api)] -#![feature(unwind_attributes)] #![feature(static_nobundle)] +#![feature(c_unwind)] #![cfg_attr(not(target_env = "msvc"), feature(libc))] mod libunwind; diff --git a/artiq/firmware/libunwind/src/libunwind.rs b/artiq/firmware/libunwind/src/libunwind.rs index 646bf912e..35a5ed51f 100644 --- a/artiq/firmware/libunwind/src/libunwind.rs +++ b/artiq/firmware/libunwind/src/libunwind.rs @@ -81,9 +81,14 @@ pub type _Unwind_Exception_Cleanup_Fn = all(feature = "llvm-libunwind", any(target_os = "fuchsia", target_os = "linux")), link(name = "unwind", kind = "static") )] -extern "C" { - #[unwind(allowed)] +extern "C-unwind" { pub fn _Unwind_Resume(exception: *mut _Unwind_Exception) -> !; +} +#[cfg_attr( + all(feature = "llvm-libunwind", any(target_os = "fuchsia", target_os = "linux")), + link(name = "unwind", kind = "static") +)] +extern "C" { pub fn _Unwind_DeleteException(exception: *mut _Unwind_Exception); pub fn _Unwind_GetLanguageSpecificData(ctx: *mut _Unwind_Context) -> *mut c_void; pub fn _Unwind_GetRegionStart(ctx: *mut _Unwind_Context) -> _Unwind_Ptr; @@ -230,9 +235,13 @@ if #[cfg(not(all(target_os = "ios", target_arch = "arm")))] { #[cfg_attr(all(feature = "llvm-libunwind", any(target_os = "fuchsia", target_os = "linux")), link(name = "unwind", kind = "static"))] - extern "C" { - #[unwind(allowed)] + extern "C-unwind" { pub fn _Unwind_RaiseException(exception: *mut _Unwind_Exception) -> _Unwind_Reason_Code; + } + #[cfg_attr(all(feature = "llvm-libunwind", + any(target_os = "fuchsia", target_os = "linux")), + link(name = "unwind", kind = "static"))] + extern "C" { pub fn _Unwind_Backtrace(trace: _Unwind_Trace_Fn, trace_argument: *mut c_void) -> _Unwind_Reason_Code; @@ -242,8 +251,7 @@ if #[cfg(not(all(target_os = "ios", target_arch = "arm")))] { #[cfg_attr(all(feature = "llvm-libunwind", any(target_os = "fuchsia", target_os = "linux")), link(name = "unwind", kind = "static"))] - extern "C" { - #[unwind(allowed)] + extern "C-unwind" { pub fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception) -> _Unwind_Reason_Code; } diff --git a/artiq/firmware/riscv32g-unknown-none-elf.json b/artiq/firmware/riscv32g-unknown-none-elf.json index 2a3fb8bfb..5e980f11f 100644 --- a/artiq/firmware/riscv32g-unknown-none-elf.json +++ b/artiq/firmware/riscv32g-unknown-none-elf.json @@ -21,20 +21,6 @@ }, "relro-level": "full", "target-family": "unix", - "target-pointer-width": "32", - "unsupported-abis": [ - "cdecl", - "stdcall", - "fastcall", - "vectorcall", - "thiscall", - "aapcs", - "win64", - "sysv64", - "ptx-kernel", - "msp430-interrupt", - "x86-interrupt", - "amdgpu-kernel" - ] + "target-pointer-width": "32" } \ No newline at end of file diff --git a/artiq/firmware/riscv32ima-unknown-none-elf.json b/artiq/firmware/riscv32ima-unknown-none-elf.json index e41408842..064347edb 100644 --- a/artiq/firmware/riscv32ima-unknown-none-elf.json +++ b/artiq/firmware/riscv32ima-unknown-none-elf.json @@ -13,19 +13,5 @@ "max-atomic-width": 32, "panic-strategy": "unwind", "relocation-model": "static", - "target-pointer-width": "32", - "unsupported-abis": [ - "cdecl", - "stdcall", - "fastcall", - "vectorcall", - "thiscall", - "aapcs", - "win64", - "sysv64", - "ptx-kernel", - "msp430-interrupt", - "x86-interrupt", - "amdgpu-kernel" - ] + "target-pointer-width": "32" } diff --git a/artiq/firmware/runtime/rtio_mgt.rs b/artiq/firmware/runtime/rtio_mgt.rs index f08737691..1bdec0dcb 100644 --- a/artiq/firmware/runtime/rtio_mgt.rs +++ b/artiq/firmware/runtime/rtio_mgt.rs @@ -97,25 +97,25 @@ pub mod drtio { } fn process_async_packets(io: &Io, ddma_mutex: &Mutex, subkernel_mutex: &Mutex, - routing_table: &drtio_routing::RoutingTable, linkno: u8, packet: drtioaux::Packet - ) -> Option { + routing_table: &drtio_routing::RoutingTable, linkno: u8, packet: &drtioaux::Packet + ) -> bool { match packet { // packets to be consumed locally drtioaux::Packet::DmaPlaybackStatus { id, source, destination: 0, error, channel, timestamp } => { - remote_dma::playback_done(io, ddma_mutex, id, source, error, channel, timestamp); - None + remote_dma::playback_done(io, ddma_mutex, *id, *source, *error, *channel, *timestamp); + true }, drtioaux::Packet::SubkernelFinished { id, destination: 0, with_exception, exception_src } => { - subkernel::subkernel_finished(io, subkernel_mutex, id, with_exception, exception_src); - None + subkernel::subkernel_finished(io, subkernel_mutex, *id, *with_exception, *exception_src); + true }, drtioaux::Packet::SubkernelMessage { id, source: from, destination: 0, status, length, data } => { - subkernel::message_handle_incoming(io, subkernel_mutex, id, status, length as usize, &data); + subkernel::message_handle_incoming(io, subkernel_mutex, *id, *status, *length as usize, data); // acknowledge receiving part of the message drtioaux::send(linkno, - &drtioaux::Packet::SubkernelMessageAck { destination: from } + &drtioaux::Packet::SubkernelMessageAck { destination: *from } ).unwrap(); - None + true }, // (potentially) routable packets drtioaux::Packet::DmaAddTraceRequest { destination, .. } | @@ -130,19 +130,19 @@ pub mod drtio { drtioaux::Packet::SubkernelMessageAck { destination, .. } | drtioaux::Packet::DmaPlaybackStatus { destination, .. } | drtioaux::Packet::SubkernelFinished { destination, .. } => { - if destination == 0 { - Some(packet) + if *destination == 0 { + false } else { - let dest_link = routing_table.0[destination as usize][0] - 1; + let dest_link = routing_table.0[*destination as usize][0] - 1; if dest_link == linkno { warn!("[LINK#{}] Re-routed packet would return to the same link, dropping: {:?}", linkno, packet); } else { drtioaux::send(dest_link, &packet).unwrap(); } - None + true } } - other => Some(other) + _ => false } } @@ -153,7 +153,7 @@ pub mod drtio { drtioaux::send(linkno, request).unwrap(); loop { let reply = recv_aux_timeout(io, linkno, 200)?; - if let Some(reply) = process_async_packets(io, ddma_mutex, subkernel_mutex, routing_table, linkno, reply) { + if !process_async_packets(io, ddma_mutex, subkernel_mutex, routing_table, linkno, &reply) { // returns none if it was an async packet return Ok(reply); } @@ -269,7 +269,7 @@ pub mod drtio { loop { match drtioaux::recv(linkno) { Ok(Some(packet)) => { - if let Some(packet) = process_async_packets(&io, ddma_mutex, subkernel_mutex, routing_table, linkno, packet) { + if !process_async_packets(&io, ddma_mutex, subkernel_mutex, routing_table, linkno, &packet) { warn!("[LINK#{}] unsolicited aux packet: {:?}", linkno, packet); } }, diff --git a/artiq/firmware/runtime/session.rs b/artiq/firmware/runtime/session.rs index 388a74337..5478e33ee 100644 --- a/artiq/firmware/runtime/session.rs +++ b/artiq/firmware/runtime/session.rs @@ -243,12 +243,13 @@ pub fn kern_send(io: &Io, request: &kern::Message) -> Result<(), Error(io: &Io, f: F) -> Result> where F: FnOnce(&kern::Message) -> Result> { - io.until(|| mailbox::receive() != 0)?; - if !kernel::validate(mailbox::receive()) { - return Err(Error::InvalidPointer(mailbox::receive())) + let mut msg_ptr = 0; + io.until(|| { msg_ptr = mailbox::receive(); msg_ptr != 0 })?; + if !kernel::validate(msg_ptr) { + return Err(Error::InvalidPointer(msg_ptr)) } - f(unsafe { &*(mailbox::receive() as *const kern::Message) }) + f(unsafe { &*(msg_ptr as *const kern::Message) }) } fn kern_recv_dotrace(reply: &kern::Message) { diff --git a/artiq/firmware/satman/kernel.rs b/artiq/firmware/satman/kernel.rs index 250f6a263..b00861abb 100644 --- a/artiq/firmware/satman/kernel.rs +++ b/artiq/firmware/satman/kernel.rs @@ -1,4 +1,4 @@ -use core::{mem, option::NoneError}; +use core::mem; use alloc::{string::String, format, vec::Vec, collections::btree_map::BTreeMap}; use cslice::AsCSlice; @@ -85,12 +85,6 @@ pub enum Error { DmaError(DmaError), } -impl From for Error { - fn from(_: NoneError) -> Error { - Error::KernelNotFound - } -} - impl From> for Error { fn from(_value: io::Error) -> Error { Error::SubkernelIoError @@ -330,7 +324,7 @@ impl Manager { self.kernels.insert(id, KernelLibrary { library: Vec::new(), complete: false }); - self.kernels.get_mut(&id)? + self.kernels.get_mut(&id).unwrap() } else { kernel } @@ -339,7 +333,7 @@ impl Manager { self.kernels.insert(id, KernelLibrary { library: Vec::new(), complete: false }); - self.kernels.get_mut(&id)? + self.kernels.get_mut(&id).unwrap() }, }; kernel.library.extend(&data[0..data_len]); @@ -404,7 +398,7 @@ impl Manager { if self.current_id == id && self.session.kernel_state == KernelState::Loaded { return Ok(()) } - if !self.kernels.get(&id)?.complete { + if !self.kernels.get(&id).ok_or(Error::KernelNotFound)?.complete { return Err(Error::KernelNotFound) } self.current_id = id; @@ -414,7 +408,7 @@ impl Manager { unsafe { kernel_cpu::start(); - kern_send(&kern::LoadRequest(&self.kernels.get(&id)?.library)).unwrap(); + kern_send(&kern::LoadRequest(&self.kernels.get(&id).unwrap().library)).unwrap(); kern_recv(|reply| { match reply { kern::LoadReply(Ok(())) => { diff --git a/artiq/firmware/satman/main.rs b/artiq/firmware/satman/main.rs index ec0c781bb..e8e26b59e 100644 --- a/artiq/firmware/satman/main.rs +++ b/artiq/firmware/satman/main.rs @@ -1,4 +1,4 @@ -#![feature(never_type, panic_info_message, llvm_asm, default_alloc_error_handler, try_trait)] +#![feature(never_type, panic_info_message, asm, default_alloc_error_handler)] #![no_std] #[macro_use] diff --git a/artiq/test/libartiq_support/lib.rs b/artiq/test/libartiq_support/lib.rs index 4216c85ec..4a940fd70 100644 --- a/artiq/test/libartiq_support/lib.rs +++ b/artiq/test/libartiq_support/lib.rs @@ -1,4 +1,4 @@ -#![feature(libc, panic_unwind, unwind_attributes, rustc_private, int_bits_const, const_in_array_repeat_expressions)] +#![feature(libc, panic_unwind, rustc_private, c_unwind)] #![crate_name = "artiq_support"] #![crate_type = "cdylib"] diff --git a/flake.nix b/flake.nix index a5816e931..000962e3b 100644 --- a/flake.nix +++ b/flake.nix @@ -25,8 +25,8 @@ artiqRev = self.sourceInfo.rev or "unknown"; rustManifest = pkgs.fetchurl { - url = "https://static.rust-lang.org/dist/2021-01-29/channel-rust-nightly.toml"; - sha256 = "sha256-EZKgw89AH4vxaJpUHmIMzMW/80wAFQlfcxRoBD9nz0c="; + url = "https://static.rust-lang.org/dist/2021-09-01/channel-rust-nightly.toml"; + sha256 = "sha256-KYLZHfOkotnM6BZd7CU+vBA3w/VtiWxth3ngJlmA41U="; }; targets = [];