forked from M-Labs/artiq
corecom_serial: support ident and runtime environment creation
This commit is contained in:
parent
6f28ab2cc6
commit
17fab6f024
|
@ -1,9 +1,17 @@
|
||||||
import os, termios, struct
|
import os, termios, struct
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
|
||||||
|
from artiq.language import units
|
||||||
|
from artiq.devices.runtime import Environment
|
||||||
|
|
||||||
|
class UnsupportedDevice(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
class _MsgType(Enum):
|
class _MsgType(Enum):
|
||||||
KERNEL_FINISHED = 0x01
|
REQUEST_IDENT = 0x01
|
||||||
RPC_REQUEST = 0x02
|
LOAD_KERNEL = 0x02
|
||||||
|
KERNEL_FINISHED = 0x03
|
||||||
|
RPC_REQUEST = 0x04
|
||||||
|
|
||||||
def _write_exactly(f, data):
|
def _write_exactly(f, data):
|
||||||
remaining = len(data)
|
remaining = len(data)
|
||||||
|
@ -47,9 +55,8 @@ class CoreCom:
|
||||||
def __exit__(self, type, value, traceback):
|
def __exit__(self, type, value, traceback):
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
def run(self, kcode):
|
def get_runtime_env(self):
|
||||||
_write_exactly(self.port, struct.pack(">ll", 0x5a5a5a5a, len(kcode)))
|
_write_exactly(self.port, struct.pack(">lb", 0x5a5a5a5a, _MsgType.REQUEST_IDENT.value))
|
||||||
_write_exactly(self.port, kcode)
|
|
||||||
# FIXME: when loading immediately after a board reset, we erroneously get some zeros back.
|
# FIXME: when loading immediately after a board reset, we erroneously get some zeros back.
|
||||||
# Ignore them with a warning for now.
|
# Ignore them with a warning for now.
|
||||||
spurious_zero_count = 0
|
spurious_zero_count = 0
|
||||||
|
@ -57,12 +64,26 @@ class CoreCom:
|
||||||
(reply, ) = struct.unpack("b", _read_exactly(self.port, 1))
|
(reply, ) = struct.unpack("b", _read_exactly(self.port, 1))
|
||||||
if reply == 0:
|
if reply == 0:
|
||||||
spurious_zero_count += 1
|
spurious_zero_count += 1
|
||||||
elif reply == 0x4f:
|
|
||||||
break
|
|
||||||
else:
|
else:
|
||||||
raise IOError("Incorrect reply from device: "+hex(reply))
|
break
|
||||||
if spurious_zero_count:
|
if spurious_zero_count:
|
||||||
print("Warning: received {} spurious zeros".format(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):
|
def _wait_sync(self):
|
||||||
recognized = 0
|
recognized = 0
|
||||||
|
|
|
@ -12,8 +12,10 @@
|
||||||
#include "elf_loader.h"
|
#include "elf_loader.h"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
MSGTYPE_KERNEL_FINISHED = 0x01,
|
MSGTYPE_REQUEST_IDENT = 0x01,
|
||||||
MSGTYPE_RPC_REQUEST = 0x02,
|
MSGTYPE_LOAD_KERNEL = 0x02,
|
||||||
|
MSGTYPE_KERNEL_FINISHED = 0x03,
|
||||||
|
MSGTYPE_RPC_REQUEST = 0x04,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int receive_int(void)
|
static int receive_int(void)
|
||||||
|
@ -75,20 +77,30 @@ static void send_sync(void)
|
||||||
send_int(0x5a5a5a5a);
|
send_int(0x5a5a5a5a);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int download_kernel(void *buffer, int maxlength)
|
static int ident_and_download_kernel(void *buffer, int maxlength)
|
||||||
{
|
{
|
||||||
int length;
|
int length;
|
||||||
int i;
|
int i;
|
||||||
|
char msgtype;
|
||||||
unsigned char *_buffer = buffer;
|
unsigned char *_buffer = buffer;
|
||||||
|
|
||||||
receive_sync();
|
while(1) {
|
||||||
length = receive_int();
|
receive_sync();
|
||||||
if(length > maxlength)
|
msgtype = receive_char();
|
||||||
return -1;
|
if(msgtype == MSGTYPE_REQUEST_IDENT) {
|
||||||
for(i=0;i<length;i++)
|
send_int(0x41524f52); /* "AROR" - ARTIQ runtime on OpenRISC */
|
||||||
_buffer[i] = receive_char();
|
send_int(1000000000000LL/identifier_frequency_read()); /* RTIO clock period in picoseconds */
|
||||||
send_char(0x4f);
|
} else if(msgtype == MSGTYPE_LOAD_KERNEL) {
|
||||||
return length;
|
length = receive_int();
|
||||||
|
if(length > maxlength)
|
||||||
|
return -1;
|
||||||
|
for(i=0;i<length;i++)
|
||||||
|
_buffer[i] = receive_char();
|
||||||
|
send_char(0x4f); /* kernel reception OK */
|
||||||
|
return length;
|
||||||
|
} else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rpc(int rpc_num, int n_args, ...)
|
static int rpc(int rpc_num, int n_args, ...)
|
||||||
|
@ -134,7 +146,7 @@ int main(void)
|
||||||
puts("ARTIQ runtime built "__DATE__" "__TIME__"\n");
|
puts("ARTIQ runtime built "__DATE__" "__TIME__"\n");
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
length = download_kernel(kbuf, sizeof(kbuf));
|
length = ident_and_download_kernel(kbuf, sizeof(kbuf));
|
||||||
if(length > 0) {
|
if(length > 0) {
|
||||||
if(load_elf(syscalls, kbuf, length, kcode, sizeof(kcode))) {
|
if(load_elf(syscalls, kbuf, length, kcode, sizeof(kcode))) {
|
||||||
flush_cpu_icache();
|
flush_cpu_icache();
|
||||||
|
|
Loading…
Reference in New Issue