forked from M-Labs/artiq
talk to ICAP primitive to restart gateware (#1733)
This commit is contained in:
parent
97e994700b
commit
6b88ea563d
|
@ -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)
|
||||
|
|
|
@ -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 {}
|
||||
}
|
||||
|
|
|
@ -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 {}
|
||||
}
|
||||
|
|
|
@ -71,7 +71,6 @@ pub enum Request {
|
|||
StopProfiler,
|
||||
GetProfile,
|
||||
|
||||
Hotswap(Vec<u8>),
|
||||
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,
|
||||
|
|
|
@ -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.");
|
||||
|
|
|
@ -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<SchedError>> {
|
|||
})?;
|
||||
}
|
||||
|
||||
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<SchedError>> {
|
|||
|
||||
profiler::stop();
|
||||
warn!("restarting");
|
||||
unsafe { boot::reset() }
|
||||
unsafe { spiflash::reload(); }
|
||||
}
|
||||
|
||||
Request::DebugAllocator =>
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue