artiq_coreboot: allow hot-rebooting the device.

This commit is contained in:
whitequark 2017-04-11 03:24:24 +00:00
parent 1bd4d13391
commit 296dc3b0c4
5 changed files with 39 additions and 10 deletions

View File

@ -13,6 +13,7 @@ class Request(Enum):
SetLogFilter = 3
Hotswap = 4
Reboot = 5
class Reply(Enum):
@ -20,7 +21,7 @@ class Reply(Enum):
LogContent = 2
HotswapImminent = 3
RebootImminent = 3
class LogLevel(Enum):
@ -130,4 +131,8 @@ class CommMgmt:
def hotswap(self, firmware):
self._write_header(Request.Hotswap)
self._write_bytes(firmware)
self._read_expect(Reply.HotswapImminent)
self._read_expect(Reply.RebootImminent)
def reboot(self):
self._write_header(Request.Reboot)
self._read_expect(Reply.RebootImminent)

View File

@ -12,6 +12,7 @@ pub enum Request {
SetLogFilter(LogLevelFilter),
Hotswap(Vec<u8>),
Reboot,
}
pub enum Reply<'a> {
@ -19,7 +20,7 @@ pub enum Reply<'a> {
LogContent(&'a str),
HotswapImminent,
RebootImminent,
}
impl Request {
@ -42,6 +43,7 @@ impl Request {
Request::SetLogFilter(level)
}
4 => Request::Hotswap(reader.read_bytes()?),
5 => Request::Reboot,
_ => return Err(io::Error::new(io::ErrorKind::InvalidData, "unknown request type"))
})
}
@ -59,7 +61,7 @@ impl<'a> Reply<'a> {
writer.write_string(log)?;
},
Reply::HotswapImminent => {
Reply::RebootImminent => {
writer.write_u8(3)?;
},
}

View File

@ -45,11 +45,18 @@ fn worker(mut stream: &mut TcpStream) -> io::Result<()> {
},
Request::Hotswap(firmware) => {
Reply::HotswapImminent.write_to(stream)?;
Reply::RebootImminent.write_to(stream)?;
stream.close()?;
warn!("hotswapping firmware");
unsafe { board::boot::hotswap(&firmware) }
},
Request::Reboot => {
Reply::RebootImminent.write_to(stream)?;
stream.close()?;
warn!("rebooting");
unsafe { board::boot::reboot() }
}
};
}
}

View File

@ -1,6 +1,7 @@
#!/usr/bin/env python3
import argparse
import sys
import struct
from artiq.tools import verbosity_args, init_logger
@ -10,14 +11,22 @@ from artiq.coredevice.comm_mgmt import CommMgmt
def get_argparser():
parser = argparse.ArgumentParser(description="ARTIQ core device hotswap tool")
parser = argparse.ArgumentParser(description="ARTIQ core device boot tool")
verbosity_args(parser)
parser.add_argument("--device-db", default="device_db.pyon",
help="device database file (default: '%(default)s')")
parser.add_argument("image", metavar="IMAGE", type=argparse.FileType('rb'),
help="runtime image to be executed")
subparsers = parser.add_subparsers(dest="action")
p_reboot = subparsers.add_parser("reboot",
help="reboot the currently running firmware")
p_hotswap = subparsers.add_parser("hotswap",
help="load the specified firmware in RAM")
p_hotswap.add_argument("image", metavar="IMAGE", type=argparse.FileType('rb'),
help="runtime image to be executed")
return parser
@ -29,7 +38,13 @@ def main():
try:
core_addr = device_mgr.get_desc("comm")["arguments"]["host"]
mgmt = CommMgmt(device_mgr, core_addr)
mgmt.hotswap(args.image.read())
if args.action == "reboot":
mgmt.reboot()
elif args.action == "hotswap":
mgmt.hotswap(args.image.read())
else:
print("An action needs to be specified.", file=sys.stderr)
sys.exit(1)
finally:
device_mgr.close_devices()

View File

@ -193,7 +193,7 @@ def main():
logger.info("Hotswapping firmware")
try:
subprocess.check_call(["python3",
"-m", "artiq.frontend.artiq_coreboot",
"-m", "artiq.frontend.artiq_coreboot", "hotswap",
"/tmp/{target}/software/{firmware}/{firmware}.bin"
.format(target=args.target, firmware=firmware)])
except subprocess.CalledProcessError: