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 SetLogFilter = 3
Hotswap = 4 Hotswap = 4
Reboot = 5
class Reply(Enum): class Reply(Enum):
@ -20,7 +21,7 @@ class Reply(Enum):
LogContent = 2 LogContent = 2
HotswapImminent = 3 RebootImminent = 3
class LogLevel(Enum): class LogLevel(Enum):
@ -130,4 +131,8 @@ class CommMgmt:
def hotswap(self, firmware): def hotswap(self, firmware):
self._write_header(Request.Hotswap) self._write_header(Request.Hotswap)
self._write_bytes(firmware) 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), SetLogFilter(LogLevelFilter),
Hotswap(Vec<u8>), Hotswap(Vec<u8>),
Reboot,
} }
pub enum Reply<'a> { pub enum Reply<'a> {
@ -19,7 +20,7 @@ pub enum Reply<'a> {
LogContent(&'a str), LogContent(&'a str),
HotswapImminent, RebootImminent,
} }
impl Request { impl Request {
@ -42,6 +43,7 @@ impl Request {
Request::SetLogFilter(level) Request::SetLogFilter(level)
} }
4 => Request::Hotswap(reader.read_bytes()?), 4 => Request::Hotswap(reader.read_bytes()?),
5 => Request::Reboot,
_ => return Err(io::Error::new(io::ErrorKind::InvalidData, "unknown request type")) _ => return Err(io::Error::new(io::ErrorKind::InvalidData, "unknown request type"))
}) })
} }
@ -59,7 +61,7 @@ impl<'a> Reply<'a> {
writer.write_string(log)?; writer.write_string(log)?;
}, },
Reply::HotswapImminent => { Reply::RebootImminent => {
writer.write_u8(3)?; writer.write_u8(3)?;
}, },
} }

View File

@ -45,11 +45,18 @@ fn worker(mut stream: &mut TcpStream) -> io::Result<()> {
}, },
Request::Hotswap(firmware) => { Request::Hotswap(firmware) => {
Reply::HotswapImminent.write_to(stream)?; Reply::RebootImminent.write_to(stream)?;
stream.close()?; stream.close()?;
warn!("hotswapping firmware"); warn!("hotswapping firmware");
unsafe { board::boot::hotswap(&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 #!/usr/bin/env python3
import argparse import argparse
import sys
import struct import struct
from artiq.tools import verbosity_args, init_logger from artiq.tools import verbosity_args, init_logger
@ -10,14 +11,22 @@ from artiq.coredevice.comm_mgmt import CommMgmt
def get_argparser(): def get_argparser():
parser = argparse.ArgumentParser(description="ARTIQ core device hotswap tool") parser = argparse.ArgumentParser(description="ARTIQ core device boot tool")
verbosity_args(parser) verbosity_args(parser)
parser.add_argument("--device-db", default="device_db.pyon", parser.add_argument("--device-db", default="device_db.pyon",
help="device database file (default: '%(default)s')") help="device database file (default: '%(default)s')")
parser.add_argument("image", metavar="IMAGE", type=argparse.FileType('rb'), subparsers = parser.add_subparsers(dest="action")
help="runtime image to be executed")
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 return parser
@ -29,7 +38,13 @@ def main():
try: try:
core_addr = device_mgr.get_desc("comm")["arguments"]["host"] core_addr = device_mgr.get_desc("comm")["arguments"]["host"]
mgmt = CommMgmt(device_mgr, core_addr) 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: finally:
device_mgr.close_devices() device_mgr.close_devices()

View File

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