From 17fab6f024e9b0a7c68c5e1f751701d38779ce9f Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Tue, 15 Jul 2014 11:21:31 -0600 Subject: [PATCH] corecom_serial: support ident and runtime environment creation --- artiq/devices/corecom_serial.py | 37 ++++++++++++++++++++++++++------- soc/runtime/main.c | 36 +++++++++++++++++++++----------- 2 files changed, 53 insertions(+), 20 deletions(-) diff --git a/artiq/devices/corecom_serial.py b/artiq/devices/corecom_serial.py index 9d3712c34..84ee55c79 100644 --- a/artiq/devices/corecom_serial.py +++ b/artiq/devices/corecom_serial.py @@ -1,9 +1,17 @@ import os, termios, struct from enum import Enum +from artiq.language import units +from artiq.devices.runtime import Environment + +class UnsupportedDevice(Exception): + pass + class _MsgType(Enum): - KERNEL_FINISHED = 0x01 - RPC_REQUEST = 0x02 + REQUEST_IDENT = 0x01 + LOAD_KERNEL = 0x02 + KERNEL_FINISHED = 0x03 + RPC_REQUEST = 0x04 def _write_exactly(f, data): remaining = len(data) @@ -47,9 +55,8 @@ class CoreCom: def __exit__(self, type, value, traceback): self.close() - def run(self, kcode): - _write_exactly(self.port, struct.pack(">ll", 0x5a5a5a5a, len(kcode))) - _write_exactly(self.port, kcode) + def get_runtime_env(self): + _write_exactly(self.port, struct.pack(">lb", 0x5a5a5a5a, _MsgType.REQUEST_IDENT.value)) # FIXME: when loading immediately after a board reset, we erroneously get some zeros back. # Ignore them with a warning for now. spurious_zero_count = 0 @@ -57,12 +64,26 @@ class CoreCom: (reply, ) = struct.unpack("b", _read_exactly(self.port, 1)) if reply == 0: spurious_zero_count += 1 - elif reply == 0x4f: - break else: - raise IOError("Incorrect reply from device: "+hex(reply)) + break if spurious_zero_count: print("Warning: received {} spurious zeros".format(spurious_zero_count)) + runtime_id = chr(reply) + for i in range(3): + (reply, ) = struct.unpack("b", _read_exactly(self.port, 1)) + runtime_id += chr(reply) + if runtime_id != "AROR": + raise UnsupportedDevice("Unsupported runtime ID: "+runtime_id) + (ref_period, ) = struct.unpack(">l", _read_exactly(self.port, 4)) + return Environment(ref_period*units.ps) + + def run(self, kcode): + _write_exactly(self.port, struct.pack(">lbl", + 0x5a5a5a5a, _MsgType.LOAD_KERNEL.value, len(kcode))) + _write_exactly(self.port, kcode) + (reply, ) = struct.unpack("b", _read_exactly(self.port, 1)) + if reply != 0x4f: + raise IOError("Incorrect reply from device: "+hex(reply)) def _wait_sync(self): recognized = 0 diff --git a/soc/runtime/main.c b/soc/runtime/main.c index f1f5697a0..1707b9e01 100644 --- a/soc/runtime/main.c +++ b/soc/runtime/main.c @@ -12,8 +12,10 @@ #include "elf_loader.h" enum { - MSGTYPE_KERNEL_FINISHED = 0x01, - MSGTYPE_RPC_REQUEST = 0x02, + MSGTYPE_REQUEST_IDENT = 0x01, + MSGTYPE_LOAD_KERNEL = 0x02, + MSGTYPE_KERNEL_FINISHED = 0x03, + MSGTYPE_RPC_REQUEST = 0x04, }; static int receive_int(void) @@ -75,20 +77,30 @@ static void send_sync(void) send_int(0x5a5a5a5a); } -static int download_kernel(void *buffer, int maxlength) +static int ident_and_download_kernel(void *buffer, int maxlength) { int length; int i; + char msgtype; unsigned char *_buffer = buffer; - receive_sync(); - length = receive_int(); - if(length > maxlength) - return -1; - for(i=0;i maxlength) + return -1; + for(i=0;i 0) { if(load_elf(syscalls, kbuf, length, kcode, sizeof(kcode))) { flush_cpu_icache();