talk to ICAP primitive to restart gateware (#1733)

pull/1740/head
Star Chen 2021-08-05 17:00:31 +08:00 committed by GitHub
parent 97e994700b
commit 6b88ea563d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 11 additions and 70 deletions

View File

@ -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)

View File

@ -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 {}
}

View File

@ -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 {}
}

View File

@ -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,

View File

@ -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.");

View File

@ -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 =>

View File

@ -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)