diff --git a/artiq/coredevice/comm_mgmt.py b/artiq/coredevice/comm_mgmt.py index 79fde1a81..6a268c8e1 100644 --- a/artiq/coredevice/comm_mgmt.py +++ b/artiq/coredevice/comm_mgmt.py @@ -24,7 +24,6 @@ class Request(Enum): StopProfiler = 10 GetProfile = 11 - Hotswap = 4 Reboot = 5 DebugAllocator = 8 @@ -224,11 +223,6 @@ class CommMgmt: return hits, edges - def hotswap(self, firmware): - self._write_header(Request.Hotswap) - self._write_bytes(firmware) - self._read_expect(Reply.RebootImminent) - def reboot(self): self._write_header(Request.Reboot) self._read_expect(Reply.RebootImminent) diff --git a/artiq/firmware/libboard_misoc/or1k/boot.rs b/artiq/firmware/libboard_misoc/or1k/boot.rs index 51a368e6e..a967c3e66 100644 --- a/artiq/firmware/libboard_misoc/or1k/boot.rs +++ b/artiq/firmware/libboard_misoc/or1k/boot.rs @@ -1,14 +1,5 @@ use super::{irq, cache}; -pub unsafe fn reset() -> ! { - irq::set_ie(false); - asm!(r#" - l.j _reset_handler - l.nop - "# : : : : "volatile"); - loop {} -} - pub unsafe fn jump(addr: usize) -> ! { irq::set_ie(false); cache::flush_cpu_icache(); @@ -18,32 +9,3 @@ pub unsafe fn jump(addr: usize) -> ! { "# : : "r"(addr) : : "volatile"); loop {} } - -pub unsafe fn hotswap(firmware: &[u8]) -> ! { - irq::set_ie(false); - asm!(r#" - # This loop overwrites itself, but it's structured in such a way - # that before that happens, it loads itself into I$$ fully. - l.movhi r4, hi(_reset_handler) - l.ori r4, r4, lo(_reset_handler) - l.or r7, r4, r0 - 0: l.sfnei r5, 0 - l.bf 1f - l.nop - l.jr r7 - l.nop - 1: l.lwz r6, 0(r3) - l.sw 0(r4), r6 - l.addi r3, r3, 4 - l.addi r4, r4, 4 - l.addi r5, r5, -4 - l.bf 0b - l.nop - "# - : - : "{r3}"(firmware.as_ptr() as usize), - "{r5}"(firmware.len()) - : - : "volatile"); - loop {} -} diff --git a/artiq/firmware/libboard_misoc/spiflash.rs b/artiq/firmware/libboard_misoc/spiflash.rs index 3a4e7cb59..7b1244775 100644 --- a/artiq/firmware/libboard_misoc/spiflash.rs +++ b/artiq/firmware/libboard_misoc/spiflash.rs @@ -113,3 +113,8 @@ pub unsafe fn write(mut addr: usize, mut data: &[u8]) { data = &data[size..]; } } + +pub unsafe fn reload () -> ! { + csr::icap::iprog_write(1); + loop {} +} diff --git a/artiq/firmware/libproto_artiq/mgmt_proto.rs b/artiq/firmware/libproto_artiq/mgmt_proto.rs index ffa2a9763..c5937fac6 100644 --- a/artiq/firmware/libproto_artiq/mgmt_proto.rs +++ b/artiq/firmware/libproto_artiq/mgmt_proto.rs @@ -71,7 +71,6 @@ pub enum Request { StopProfiler, GetProfile, - Hotswap(Vec), Reboot, DebugAllocator, @@ -138,7 +137,6 @@ impl Request { 10 => Request::StopProfiler, 11 => Request::GetProfile, - 4 => Request::Hotswap(reader.read_bytes()?), 5 => Request::Reboot, 8 => Request::DebugAllocator, diff --git a/artiq/firmware/runtime/main.rs b/artiq/firmware/runtime/main.rs index 91646cc5e..df103d7ef 100644 --- a/artiq/firmware/runtime/main.rs +++ b/artiq/firmware/runtime/main.rs @@ -30,7 +30,7 @@ use core::cell::RefCell; use core::convert::TryFrom; use smoltcp::wire::IpCidr; -use board_misoc::{csr, irq, ident, clock, boot, config, net_settings}; +use board_misoc::{csr, irq, ident, clock, spiflash, config, net_settings}; #[cfg(has_ethmac)] use board_misoc::ethmac; #[cfg(has_drtio)] @@ -332,11 +332,11 @@ pub fn panic_impl(info: &core::panic::PanicInfo) -> ! { println!("{:#08x}", ip - 2 * 4); }); - if config::read_str("panic_reset", |r| r == Ok("1")) { + if config::read_str("panic_reset", |r| r == Ok("1")) && cfg!(has_spiflash) { println!("restarting..."); unsafe { kernel::stop(); - boot::reset(); + spiflash::reload(); } } else { println!("halting."); diff --git a/artiq/firmware/runtime/mgmt.rs b/artiq/firmware/runtime/mgmt.rs index 3a16e94aa..2f632a7da 100644 --- a/artiq/firmware/runtime/mgmt.rs +++ b/artiq/firmware/runtime/mgmt.rs @@ -1,7 +1,7 @@ use log::{self, LevelFilter}; use io::{Write, ProtoWrite, Error as IoError}; -use board_misoc::{config, boot}; +use board_misoc::{config, spiflash}; use logger_artiq::BufferLogger; use mgmt_proto::*; use sched::{Io, TcpListener, TcpStream, Error as SchedError}; @@ -144,15 +144,6 @@ fn worker(io: &Io, stream: &mut TcpStream) -> Result<(), Error> { })?; } - Request::Hotswap(firmware) => { - Reply::RebootImminent.write_to(stream)?; - stream.close()?; - stream.flush()?; - - profiler::stop(); - warn!("hotswapping firmware"); - unsafe { boot::hotswap(&firmware) } - } Request::Reboot => { Reply::RebootImminent.write_to(stream)?; stream.close()?; @@ -160,7 +151,7 @@ fn worker(io: &Io, stream: &mut TcpStream) -> Result<(), Error> { profiler::stop(); warn!("restarting"); - unsafe { boot::reset() } + unsafe { spiflash::reload(); } } Request::DebugAllocator => diff --git a/artiq/frontend/artiq_coremgmt.py b/artiq/frontend/artiq_coremgmt.py index 542e12925..39baf26cf 100755 --- a/artiq/frontend/artiq_coremgmt.py +++ b/artiq/frontend/artiq_coremgmt.py @@ -84,13 +84,7 @@ def get_argparser(): # booting t_boot = tools.add_parser("reboot", - help="reboot the currently running firmware") - - t_hotswap = tools.add_parser("hotswap", - help="load the specified firmware in RAM") - - t_hotswap.add_argument("image", metavar="IMAGE", type=argparse.FileType("rb"), - help="runtime image to be executed") + help="reboot the running system") # profiling t_profile = tools.add_parser("profile", @@ -180,9 +174,6 @@ def main(): if args.tool == "reboot": mgmt.reboot() - if args.tool == "hotswap": - mgmt.hotswap(args.image.read()) - if args.tool == "profile": if args.action == "start": mgmt.start_profiler(args.interval, args.hits_size, args.edges_size)