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
|
StopProfiler = 10
|
||||||
GetProfile = 11
|
GetProfile = 11
|
||||||
|
|
||||||
Hotswap = 4
|
|
||||||
Reboot = 5
|
Reboot = 5
|
||||||
|
|
||||||
DebugAllocator = 8
|
DebugAllocator = 8
|
||||||
|
@ -224,11 +223,6 @@ class CommMgmt:
|
||||||
|
|
||||||
return hits, edges
|
return hits, edges
|
||||||
|
|
||||||
def hotswap(self, firmware):
|
|
||||||
self._write_header(Request.Hotswap)
|
|
||||||
self._write_bytes(firmware)
|
|
||||||
self._read_expect(Reply.RebootImminent)
|
|
||||||
|
|
||||||
def reboot(self):
|
def reboot(self):
|
||||||
self._write_header(Request.Reboot)
|
self._write_header(Request.Reboot)
|
||||||
self._read_expect(Reply.RebootImminent)
|
self._read_expect(Reply.RebootImminent)
|
||||||
|
|
|
@ -1,14 +1,5 @@
|
||||||
use super::{irq, cache};
|
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) -> ! {
|
pub unsafe fn jump(addr: usize) -> ! {
|
||||||
irq::set_ie(false);
|
irq::set_ie(false);
|
||||||
cache::flush_cpu_icache();
|
cache::flush_cpu_icache();
|
||||||
|
@ -18,32 +9,3 @@ pub unsafe fn jump(addr: usize) -> ! {
|
||||||
"# : : "r"(addr) : : "volatile");
|
"# : : "r"(addr) : : "volatile");
|
||||||
loop {}
|
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..];
|
data = &data[size..];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub unsafe fn reload () -> ! {
|
||||||
|
csr::icap::iprog_write(1);
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
|
|
@ -71,7 +71,6 @@ pub enum Request {
|
||||||
StopProfiler,
|
StopProfiler,
|
||||||
GetProfile,
|
GetProfile,
|
||||||
|
|
||||||
Hotswap(Vec<u8>),
|
|
||||||
Reboot,
|
Reboot,
|
||||||
|
|
||||||
DebugAllocator,
|
DebugAllocator,
|
||||||
|
@ -138,7 +137,6 @@ impl Request {
|
||||||
10 => Request::StopProfiler,
|
10 => Request::StopProfiler,
|
||||||
11 => Request::GetProfile,
|
11 => Request::GetProfile,
|
||||||
|
|
||||||
4 => Request::Hotswap(reader.read_bytes()?),
|
|
||||||
5 => Request::Reboot,
|
5 => Request::Reboot,
|
||||||
|
|
||||||
8 => Request::DebugAllocator,
|
8 => Request::DebugAllocator,
|
||||||
|
|
|
@ -30,7 +30,7 @@ use core::cell::RefCell;
|
||||||
use core::convert::TryFrom;
|
use core::convert::TryFrom;
|
||||||
use smoltcp::wire::IpCidr;
|
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)]
|
#[cfg(has_ethmac)]
|
||||||
use board_misoc::ethmac;
|
use board_misoc::ethmac;
|
||||||
#[cfg(has_drtio)]
|
#[cfg(has_drtio)]
|
||||||
|
@ -332,11 +332,11 @@ pub fn panic_impl(info: &core::panic::PanicInfo) -> ! {
|
||||||
println!("{:#08x}", ip - 2 * 4);
|
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...");
|
println!("restarting...");
|
||||||
unsafe {
|
unsafe {
|
||||||
kernel::stop();
|
kernel::stop();
|
||||||
boot::reset();
|
spiflash::reload();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
println!("halting.");
|
println!("halting.");
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use log::{self, LevelFilter};
|
use log::{self, LevelFilter};
|
||||||
|
|
||||||
use io::{Write, ProtoWrite, Error as IoError};
|
use io::{Write, ProtoWrite, Error as IoError};
|
||||||
use board_misoc::{config, boot};
|
use board_misoc::{config, spiflash};
|
||||||
use logger_artiq::BufferLogger;
|
use logger_artiq::BufferLogger;
|
||||||
use mgmt_proto::*;
|
use mgmt_proto::*;
|
||||||
use sched::{Io, TcpListener, TcpStream, Error as SchedError};
|
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 => {
|
Request::Reboot => {
|
||||||
Reply::RebootImminent.write_to(stream)?;
|
Reply::RebootImminent.write_to(stream)?;
|
||||||
stream.close()?;
|
stream.close()?;
|
||||||
|
@ -160,7 +151,7 @@ fn worker(io: &Io, stream: &mut TcpStream) -> Result<(), Error<SchedError>> {
|
||||||
|
|
||||||
profiler::stop();
|
profiler::stop();
|
||||||
warn!("restarting");
|
warn!("restarting");
|
||||||
unsafe { boot::reset() }
|
unsafe { spiflash::reload(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
Request::DebugAllocator =>
|
Request::DebugAllocator =>
|
||||||
|
|
|
@ -84,13 +84,7 @@ def get_argparser():
|
||||||
|
|
||||||
# booting
|
# booting
|
||||||
t_boot = tools.add_parser("reboot",
|
t_boot = tools.add_parser("reboot",
|
||||||
help="reboot the currently running firmware")
|
help="reboot the running system")
|
||||||
|
|
||||||
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")
|
|
||||||
|
|
||||||
# profiling
|
# profiling
|
||||||
t_profile = tools.add_parser("profile",
|
t_profile = tools.add_parser("profile",
|
||||||
|
@ -180,9 +174,6 @@ def main():
|
||||||
if args.tool == "reboot":
|
if args.tool == "reboot":
|
||||||
mgmt.reboot()
|
mgmt.reboot()
|
||||||
|
|
||||||
if args.tool == "hotswap":
|
|
||||||
mgmt.hotswap(args.image.read())
|
|
||||||
|
|
||||||
if args.tool == "profile":
|
if args.tool == "profile":
|
||||||
if args.action == "start":
|
if args.action == "start":
|
||||||
mgmt.start_profiler(args.interval, args.hits_size, args.edges_size)
|
mgmt.start_profiler(args.interval, args.hits_size, args.edges_size)
|
||||||
|
|
Loading…
Reference in New Issue