Skip to content

Commit

Permalink
comm: refactor to support lwip event model
Browse files Browse the repository at this point in the history
sbourdeauducq committed Apr 21, 2015
1 parent 9f52277 commit 18106cc
Showing 20 changed files with 830 additions and 623 deletions.
160 changes: 77 additions & 83 deletions artiq/coredevice/comm_generic.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import struct
import zlib
import logging
from enum import Enum
from fractions import Fraction

from artiq.language import units
from artiq.coredevice.runtime import Environment
from artiq.coredevice import runtime_exceptions
from artiq.language import core as core_language
@@ -15,33 +13,30 @@


class _H2DMsgType(Enum):
LINK_MESSAGE = 1

REQUEST_IDENT = 2
LOG_REQUEST = 1
IDENT_REQUEST = 2
SWITCH_CLOCK = 3

LOAD_OBJECT = 4
RUN_KERNEL = 5

RPC_REPLY = 6


class _D2HMsgType(Enum):
MESSAGE_UNRECOGNIZED = 1
LOG = 2

IDENT = 3
CLOCK_SWITCH_COMPLETED = 4
CLOCK_SWITCH_FAILED = 5
LOG_REPLY = 1
IDENT_REPLY = 2
CLOCK_SWITCH_COMPLETED = 3
CLOCK_SWITCH_FAILED = 4

OBJECT_LOADED = 6
OBJECT_INCORRECT_LENGTH = 7
OBJECT_CRC_FAILED = 8
OBJECT_UNRECOGNIZED = 9
LOAD_COMPLETED = 5
LOAD_FAILED = 6

KERNEL_FINISHED = 10
KERNEL_STARTUP_FAILED = 11
KERNEL_EXCEPTION = 12
KERNEL_FINISHED = 7
KERNEL_STARTUP_FAILED = 8
KERNEL_EXCEPTION = 9

RPC_REQUEST = 13
RPC_REQUEST = 10


class UnsupportedDevice(Exception):
@@ -71,103 +66,95 @@ def write(self, data):
raise NotImplementedError
#

def _read(self, length):
self.open()
return self.read(length)

def _write(self, data):
def _read_header(self):
self.open()
self.write(data)

def _get_device_msg(self):
while True:
(reply, ) = struct.unpack("B", self._read(1))
msg = _D2HMsgType(reply)
if msg == _D2HMsgType.LOG:
(length, ) = struct.unpack(">h", self._read(2))
log_message = ""
for i in range(length):
(c, ) = struct.unpack("B", self._read(1))
log_message += chr(c)
logger.info("DEVICE LOG: %s", log_message)
sync_count = 0
while sync_count < 4:
(c, ) = struct.unpack("B", self.read(1))
if c == 0x5a:
sync_count += 1
else:
logger.debug("message received: %r", msg)
return msg
sync_count = 0
length, tyv = struct.unpack(">lB", self.read(5))
ty = _D2HMsgType(tyv)
logger.debug("receiving message: type=%r length=%d", ty, length)
return length, ty

def _write_header(self, length, ty):
self.open()
logger.debug("sending message: type=%r length=%d", ty, length)
self.write(struct.pack(">llB", 0x5a5a5a5a, length, ty.value))

def get_runtime_env(self):
self._write(struct.pack(">lb", 0x5a5a5a5a,
_H2DMsgType.REQUEST_IDENT.value))
msg = self._get_device_msg()
if msg != _D2HMsgType.IDENT:
raise IOError("Incorrect reply from device: {}".format(msg))
(reply, ) = struct.unpack("B", self._read(1))
self._write_header(9, _H2DMsgType.IDENT_REQUEST)
_, ty = self._read_header()
if ty != _D2HMsgType.IDENT_REPLY:
raise IOError("Incorrect reply from device: {}".format(ty))
(reply, ) = struct.unpack("B", self.read(1))
runtime_id = chr(reply)
for i in range(3):
(reply, ) = struct.unpack("B", self._read(1))
(reply, ) = struct.unpack("B", self.read(1))
runtime_id += chr(reply)
if runtime_id != "AROR":
raise UnsupportedDevice("Unsupported runtime ID: {}"
.format(runtime_id))
return Environment()

def switch_clock(self, external):
self._write(struct.pack(
">lbb", 0x5a5a5a5a, _H2DMsgType.SWITCH_CLOCK.value,
int(external)))
msg = self._get_device_msg()
if msg != _D2HMsgType.CLOCK_SWITCH_COMPLETED:
raise IOError("Incorrect reply from device: {}".format(msg))
self._write_header(10, _H2DMsgType.SWITCH_CLOCK)
self.write(struct.pack("B", int(external)))
_, ty = self._read_header()
if ty != _D2HMsgType.CLOCK_SWITCH_COMPLETED:
raise IOError("Incorrect reply from device: {}".format(ty))

def load(self, kcode):
self._write(struct.pack(
">lblL",
0x5a5a5a5a, _H2DMsgType.LOAD_OBJECT.value,
len(kcode), zlib.crc32(kcode)))
self._write(kcode)
msg = self._get_device_msg()
if msg != _D2HMsgType.OBJECT_LOADED:
raise IOError("Incorrect reply from device: "+str(msg))
self._write_header(len(kcode) + 9, _H2DMsgType.LOAD_OBJECT)
self.write(kcode)
_, ty = self._read_header()
if ty != _D2HMsgType.LOAD_COMPLETED:
raise IOError("Incorrect reply from device: "+str(ty))

def run(self, kname):
self._write(struct.pack(
">lbl", 0x5a5a5a5a, _H2DMsgType.RUN_KERNEL.value, len(kname)))
for c in kname:
self._write(struct.pack(">B", ord(c)))
self._write_header(len(kname) + 9, _H2DMsgType.RUN_KERNEL)
self.write(bytes(kname, "ascii"))
logger.debug("running kernel: %s", kname)

def _receive_rpc_values(self):
r = []
while True:
type_tag = chr(struct.unpack(">B", self._read(1))[0])
type_tag = chr(struct.unpack("B", self.read(1))[0])
if type_tag == "\x00":
return r
if type_tag == "n":
r.append(None)
if type_tag == "b":
r.append(bool(struct.unpack(">B", self._read(1))[0]))
r.append(bool(struct.unpack("B", self.read(1))[0]))
if type_tag == "i":
r.append(struct.unpack(">l", self._read(4))[0])
r.append(struct.unpack(">l", self.read(4))[0])
if type_tag == "I":
r.append(struct.unpack(">q", self._read(8))[0])
r.append(struct.unpack(">q", self.read(8))[0])
if type_tag == "f":
r.append(struct.unpack(">d", self._read(8))[0])
r.append(struct.unpack(">d", self.read(8))[0])
if type_tag == "F":
n, d = struct.unpack(">qq", self._read(16))
n, d = struct.unpack(">qq", self.read(16))
r.append(Fraction(n, d))
if type_tag == "l":
r.append(self._receive_rpc_values())

def _serve_rpc(self, rpc_wrapper, rpc_map, user_exception_map):
rpc_num = struct.unpack(">h", self._read(2))[0]
rpc_num = struct.unpack(">l", self.read(4))[0]
args = self._receive_rpc_values()
logger.debug("rpc service: %d %r", rpc_num, args)
eid, r = rpc_wrapper.run_rpc(
user_exception_map, rpc_map[rpc_num], args)
self._write(struct.pack(">ll", eid, r))
logger.debug("rpc service: %d %r == %r", rpc_num, args, r)
self._write_header(9+2*4, _H2DMsgType.RPC_REPLY)
self.write(struct.pack(">ll", eid, r))
logger.debug("rpc service: %d %r == %r (eid %d)", rpc_num, args,
r, eid)

def _serve_exception(self, rpc_wrapper, user_exception_map):
eid, p0, p1, p2 = struct.unpack(">lqqq", self._read(4+3*8))
eid, p0, p1, p2 = struct.unpack(">lqqq", self.read(4+3*8))
rpc_wrapper.filter_rpc_exception(eid)
if eid < core_language.first_user_eid:
exception = runtime_exceptions.exception_map[eid]
@@ -179,17 +166,24 @@ def _serve_exception(self, rpc_wrapper, user_exception_map):
def serve(self, rpc_map, user_exception_map):
rpc_wrapper = RPCWrapper()
while True:
msg = self._get_device_msg()
if msg == _D2HMsgType.RPC_REQUEST:
_, ty = self._read_header()
if ty == _D2HMsgType.RPC_REQUEST:
self._serve_rpc(rpc_wrapper, rpc_map, user_exception_map)
elif msg == _D2HMsgType.KERNEL_EXCEPTION:
elif ty == _D2HMsgType.KERNEL_EXCEPTION:
self._serve_exception(rpc_wrapper, user_exception_map)
elif msg == _D2HMsgType.KERNEL_FINISHED:
elif ty == _D2HMsgType.KERNEL_FINISHED:
return
else:
raise IOError("Incorrect request from device: "+str(msg))

def send_link_message(self, data):
self._write(struct.pack(
">lb", 0x5a5a5a5a, _H2DMsgType.LINK_MESSAGE.value))
self._write(data)
raise IOError("Incorrect request from device: "+str(ty))

def get_log(self):
self._write_header(9, _H2DMsgType.LOG_REQUEST)
length, ty = self._read_header()
if ty != _D2HMsgType.LOG_REPLY:
raise IOError("Incorrect request from device: "+str(ty))
r = ""
for i in range(length - 9):
c = struct.unpack("B", self.read(1))[0]
if c:
r += chr(c)
return r
31 changes: 2 additions & 29 deletions artiq/coredevice/comm_serial.py
Original file line number Diff line number Diff line change
@@ -17,15 +17,12 @@ class DBKeys:
def open(self):
if hasattr(self, "port"):
return
self.port = serial.serial_for_url(self.serial_dev, baudrate=115200)
self.port.flush()
self.set_remote_baud(self.baud_rate)
self.set_baud(self.baud_rate)
self.port = serial.serial_for_url(self.serial_dev,
baudrate=self.baud_rate)

def close(self):
if not hasattr(self, "port"):
return
self.set_remote_baud(115200)
self.port.close()
del self.port

@@ -42,27 +39,3 @@ def write(self, data):
written = self.port.write(data[pos:])
remaining -= written
pos += written

def set_baud(self, baud):
self.port.baudrate = baud
self.port.flush()
logger.debug("local baud rate set to %d", baud)

def set_remote_baud(self, baud):
self.send_link_message(struct.pack(">l", baud))
handshake = 0
fails = 0
while handshake < 4:
(recv, ) = struct.unpack("B", self.read(1))
if recv == 0x5a:
handshake += 1
else:
# FIXME: when loading immediately after a board reset,
# we erroneously get some zeros back.
logger.warning("unexpected sync character: %02x", recv)
handshake = 0
if recv != 0:
fails += 1
if fails > 3:
raise IOError("Baudrate ack failed")
logger.debug("remote baud rate set to %d", baud)
4 changes: 2 additions & 2 deletions soc/runtime/Makefile
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
include $(MSCDIR)/software/common.mak

OBJECTS := isr.o elf_loader.o services.o comm_serial.o test_mode.o main.o
OBJECTS := isr.o elf_loader.o services.o session.o log.o test_mode.o kloader.o main.o
OBJECTS_KSUPPORT := exception_jmp.o exceptions.o rtio.o dds.o

# NOTE: this does not handle dependencies well. Run "make clean"
# when switching between UP and AMP.
UNIPROCESSOR := $(shell printf "\#include <generated/csr.h>\nCSR_KERNEL_CPU_BASE" | $(CC_normal) $(CFLAGS) -E - | tail -n 1 | grep -c CSR_KERNEL_CPU_BASE)

ifeq ($(UNIPROCESSOR),0)
OBJECTS += mailbox.o kernelcpu.o ksupport_data.o
OBJECTS += mailbox.o ksupport_data.o
OBJECTS_KSUPPORT += mailbox.o bridge.o ksupport.o
CFLAGS += -DARTIQ_AMP
SERVICE_TABLE_INPUT = ksupport.elf
23 changes: 0 additions & 23 deletions soc/runtime/comm.h

This file was deleted.

292 changes: 0 additions & 292 deletions soc/runtime/comm_serial.c

This file was deleted.

20 changes: 10 additions & 10 deletions soc/runtime/elf_loader.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include <string.h>

#include "comm.h"
#include "log.h"
#include "elf_loader.h"

#define EI_NIDENT 16
@@ -85,11 +85,11 @@ struct elf32_sym {

#define SANITIZE_OFFSET_SIZE(offset, size) \
if(offset > 0x10000000) { \
comm_log("Incorrect offset in ELF data"); \
log("Incorrect offset in ELF data"); \
return 0; \
} \
if((offset + size) > elf_length) { \
comm_log("Attempted to access past the end of ELF data"); \
log("Attempted to access past the end of ELF data"); \
return 0; \
}

@@ -121,7 +121,7 @@ static int fixup(void *dest, int dest_length, struct elf32_rela *rela, void *tar
val = _target - (_dest + offset);
_dest[offset] = (_dest[offset] & 0xfc000000) | (val & 0x03ffffff);
} else
comm_log("Unsupported relocation type: %d", type);
log("Unsupported relocation type: %d", type);
return 1;
}

@@ -141,15 +141,15 @@ int load_elf(symbol_resolver resolver, symbol_callback callback, void *elf_data,
/* validate ELF */
GET_POINTER_SAFE(ehdr, struct elf32_ehdr, 0);
if(memcmp(ehdr->ident, elf_magic_header, sizeof(elf_magic_header)) != 0) {
comm_log("Incorrect ELF header");
log("Incorrect ELF header");
return 0;
}
if(ehdr->type != ET_REL) {
comm_log("ELF is not relocatable");
log("ELF is not relocatable");
return 0;
}
if(ehdr->machine != EM_OR1K) {
comm_log("ELF is for a different machine");
log("ELF is for a different machine");
return 0;
}

@@ -190,7 +190,7 @@ int load_elf(symbol_resolver resolver, symbol_callback callback, void *elf_data,

/* load .text section */
if(textsize > dest_length) {
comm_log(".text section is too large");
log(".text section is too large");
return 0;
}
memcpy(dest, (char *)elf_data + textoff, textsize);
@@ -209,13 +209,13 @@ int load_elf(symbol_resolver resolver, symbol_callback callback, void *elf_data,
name = (char *)elf_data + strtaboff + sym->name;
target = resolver(name);
if(target == NULL) {
comm_log("Undefined symbol: %s", name);
log("Undefined symbol: %s", name);
return 0;
}
if(!fixup(dest, dest_length, rela, target))
return 0;
} else {
comm_log("Unsupported relocation");
log("Unsupported relocation");
return 0;
}
}
4 changes: 2 additions & 2 deletions soc/runtime/exceptions.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include <generated/csr.h>

#include "comm.h"
#include "log.h"
#include "exceptions.h"

#define MAX_EXCEPTION_CONTEXTS 64
@@ -52,7 +52,7 @@ void exception_raise_params(int id,
stored_params[2] = p2;
exception_longjmp(exception_contexts[--ec_top].jb);
} else {
comm_log("ERROR: uncaught exception, ID=%d\n", id);
log("ERROR: uncaught exception, ID=%d\n", id);
while(1);
}
}
2 changes: 1 addition & 1 deletion soc/runtime/gen_service_table.py
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@

services = [
("syscalls", [
("rpc", "comm_rpc"),
("rpc", "rpc"),
("rtio_set_o", "rtio_set_o"),
("rtio_set_oe", "rtio_set_oe"),
("rtio_set_sensitivity", "rtio_set_sensitivity"),
24 changes: 0 additions & 24 deletions soc/runtime/kernelcpu.c

This file was deleted.

12 changes: 0 additions & 12 deletions soc/runtime/kernelcpu.h

This file was deleted.

111 changes: 111 additions & 0 deletions soc/runtime/kloader.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#include <string.h>
#include <generated/csr.h>

#include "log.h"
#include "mailbox.h"
#include "elf_loader.h"
#include "services.h"
#include "kloader.h"


static struct symbol symtab[128];
static int _symtab_count;
static char _symtab_strings[128*16];
static char *_symtab_strptr;

static void symtab_init(void)
{
memset(symtab, 0, sizeof(symtab));
_symtab_count = 0;
_symtab_strptr = _symtab_strings;
}

static int symtab_add(const char *name, void *target)
{
if(_symtab_count >= sizeof(symtab)/sizeof(symtab[0])) {
log("Too many provided symbols in object");
symtab_init();
return 0;
}
symtab[_symtab_count].name = _symtab_strptr;
symtab[_symtab_count].target = target;
_symtab_count++;

while(1) {
if(_symtab_strptr >= &_symtab_strings[sizeof(_symtab_strings)]) {
log("Provided symbol string table overflow");
symtab_init();
return 0;
}
*_symtab_strptr = *name;
_symtab_strptr++;
if(*name == 0)
break;
name++;
}

return 1;
}

int kloader_load(void *buffer, int length)
{
#ifdef ARTIQ_AMP
if(!kernel_cpu_reset_read()) {
log("BUG: attempted to load while kernel CPU running");
return 0;
}
#endif
symtab_init();
return load_elf(
resolve_service_symbol, symtab_add,
buffer, length, (void *)KERNELCPU_PAYLOAD_ADDRESS, 4*1024*1024);
}

kernel_function kloader_find(const char *name)
{
return find_symbol(symtab, name);
}

#ifdef ARTIQ_AMP

extern char _binary_ksupport_bin_start;
extern char _binary_ksupport_bin_end;

static void start_kernel_cpu(void *addr)
{
memcpy((void *)KERNELCPU_EXEC_ADDRESS, &_binary_ksupport_bin_start,
&_binary_ksupport_bin_end - &_binary_ksupport_bin_start);
mailbox_acknowledge();
mailbox_send(addr);
kernel_cpu_reset_write(0);
}

void kloader_start_bridge(void)
{
start_kernel_cpu(NULL);
}

void kloader_start_user_kernel(kernel_function k)
{
if(!kernel_cpu_reset_read()) {
log("BUG: attempted to start kernel CPU while already running (user kernel)");
return;
}
start_kernel_cpu((void *)k);
}

void kloader_start_idle_kernel(void)
{
if(!kernel_cpu_reset_read()) {
log("BUG: attempted to start kernel CPU while already running (idle kernel)");
return;
}
/* TODO */
}

void kloader_stop_kernel(void)
{
kernel_cpu_reset_write(1);
}

#endif
19 changes: 19 additions & 0 deletions soc/runtime/kloader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#ifndef __KLOADER_H
#define __KLOADER_H

#define KERNELCPU_EXEC_ADDRESS 0x40020000
#define KERNELCPU_PAYLOAD_ADDRESS 0x40024000

typedef void (*kernel_function)(void);

int kloader_load(void *buffer, int length);
kernel_function kloader_find(const char *name);

#ifdef ARTIQ_AMP
void kloader_start_bridge(void);
void kloader_start_idle_kernel(void);
void kloader_start_user_kernel(kernel_function k);
void kloader_stop_kernel(void);
#endif

#endif /* __KLOADER_H */
10 changes: 6 additions & 4 deletions soc/runtime/ksupport.c
Original file line number Diff line number Diff line change
@@ -7,8 +7,10 @@
#include "rtio.h"
#include "dds.h"

/* for the prototypes for comm_rpc and comm_log */
#include "comm.h"
/* for the prototype for rpc() */
#include "session.h"
/* for the prototype for log() */
#include "log.h"

void exception_handler(unsigned long vect, unsigned long *sp);
void exception_handler(unsigned long vect, unsigned long *sp)
@@ -59,7 +61,7 @@ int main(void)
while(1);
}

int comm_rpc(int rpc_num, ...)
int rpc(int rpc_num, ...)
{
struct msg_rpc_request request;
struct msg_rpc_reply *reply;
@@ -83,7 +85,7 @@ int comm_rpc(int rpc_num, ...)
return retval;
}

void comm_log(const char *fmt, ...)
void log(const char *fmt, ...)
{
struct msg_log request;

41 changes: 41 additions & 0 deletions soc/runtime/log.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#include <stdarg.h>
#include <stdio.h>

#include "log.h"

static int buffer_index;
static char buffer[LOG_BUFFER_SIZE];

void log_va(const char *fmt, va_list args)
{
char outbuf[256];
int i, len;

len = vscnprintf(outbuf, sizeof(outbuf), fmt, args);
for(i=0;i<len;i++) {
buffer[buffer_index] = outbuf[i];
buffer_index = (buffer_index + 1) % LOG_BUFFER_SIZE;
}
buffer[buffer_index] = '\n';
buffer_index = (buffer_index + 1) % LOG_BUFFER_SIZE;
}

void log(const char *fmt, ...)
{
va_list args;

va_start(args, fmt);
log_va(fmt, args);
va_end(args);
}

void log_get(char *outbuf)
{
int i, j;

j = buffer_index + 1;
for(i=0;i<LOG_BUFFER_SIZE;i++) {
outbuf[i] = buffer[j];
j = (j + 1) % LOG_BUFFER_SIZE;
}
}
13 changes: 13 additions & 0 deletions soc/runtime/log.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#ifndef __LOG_H
#define __LOG_H

#include <stdarg.h>

#define LOG_BUFFER_SIZE 4096

void log_va(const char *fmt, va_list args);
void log(const char *fmt, ...);

void log_get(char *outbuf);

#endif /* __LOG_H */
164 changes: 26 additions & 138 deletions soc/runtime/main.c
Original file line number Diff line number Diff line change
@@ -8,154 +8,42 @@
#include <generated/csr.h>

#include "test_mode.h"
#include "comm.h"
#include "kernelcpu.h"
#include "elf_loader.h"
#include "exceptions.h"
#include "services.h"
#include "rtio.h"
#include "dds.h"
#include "session.h"

#ifdef ARTIQ_AMP
#include "mailbox.h"
#include "messages.h"
#endif

static struct symbol symtab[128];
static int _symtab_count;
static char _symtab_strings[128*16];
static char *_symtab_strptr;

static void symtab_init(void)
{
memset(symtab, 0, sizeof(symtab));
_symtab_count = 0;
_symtab_strptr = _symtab_strings;
}

static int symtab_add(const char *name, void *target)
void comm_service(void)
{
if(_symtab_count >= sizeof(symtab)/sizeof(symtab[0])) {
comm_log("Too many provided symbols in object");
symtab_init();
return 0;
char *txdata;
int txlen;
static char rxdata;
static int rxpending;
int r, i;

if(!rxpending && uart_read_nonblock()) {
rxdata = uart_read();
rxpending = 1;
}
symtab[_symtab_count].name = _symtab_strptr;
symtab[_symtab_count].target = target;
_symtab_count++;

while(1) {
if(_symtab_strptr >= &_symtab_strings[sizeof(_symtab_strings)]) {
comm_log("Provided symbol string table overflow");
symtab_init();
return 0;
}
*_symtab_strptr = *name;
_symtab_strptr++;
if(*name == 0)
break;
name++;
if(rxpending) {
r = session_input(&rxdata, 1);
if(r > 0)
rxpending = 0;
}

return 1;
}

static int load_object(void *buffer, int length)
{
symtab_init();
return load_elf(
resolve_service_symbol, symtab_add,
buffer, length, (void *)KERNELCPU_PAYLOAD_ADDRESS, 4*1024*1024);
}


#ifdef ARTIQ_AMP
static int process_msg(struct msg_base *umsg, int *eid, long long int *eparams)
{
int i;

switch(umsg->type) {
case MESSAGE_TYPE_FINISHED:
return KERNEL_RUN_FINISHED;
case MESSAGE_TYPE_EXCEPTION: {
struct msg_exception *msg = (struct msg_exception *)umsg;

*eid = msg->eid;
for(i=0;i<3;i++)
eparams[i] = msg->eparams[i];
return KERNEL_RUN_EXCEPTION;
}
case MESSAGE_TYPE_RPC_REQUEST: {
struct msg_rpc_request *msg = (struct msg_rpc_request *)umsg;
struct msg_rpc_reply reply;

reply.type = MESSAGE_TYPE_RPC_REPLY;
comm_rpc_va(msg->rpc_num, msg->args, &reply.eid, &reply.retval);
mailbox_send_and_wait(&reply);
return KERNEL_RUN_INVALID_STATUS;
}
case MESSAGE_TYPE_LOG: {
struct msg_log *msg = (struct msg_log *)umsg;

comm_log(msg->fmt, msg->args);
return KERNEL_RUN_INVALID_STATUS;
}
default:
*eid = EID_INTERNAL_ERROR;
for(i=0;i<3;i++)
eparams[i] = 0;
return KERNEL_RUN_EXCEPTION;
session_poll((void **)&txdata, &txlen);
if(txlen > 0) {
for(i=0;i<txlen;i++)
uart_write(txdata[i]);
session_ack(txlen);
}
}
#endif

typedef void (*kernel_function)(void);

static int run_kernel(const char *kernel_name, int *eid, long long int *eparams)
static void regular_main(void)
{
kernel_function k;
#ifdef ARTIQ_AMP
int r;
#else
void *jb;
#endif

k = find_symbol(symtab, kernel_name);
if(k == NULL) {
comm_log("Failed to find kernel entry point '%s' in object", kernel_name);
return KERNEL_RUN_STARTUP_FAILED;
}

#ifdef ARTIQ_AMP
kernelcpu_start(k);
while(1) {
struct msg_base *umsg;

umsg = mailbox_receive();
r = KERNEL_RUN_INVALID_STATUS;
if(umsg)
r = process_msg(umsg, eid, eparams);
if(r != KERNEL_RUN_INVALID_STATUS)
break;
}
kernelcpu_stop();
return r;
#else
jb = exception_push();
if(exception_setjmp(jb)) {
*eid = exception_getid(eparams);
return KERNEL_RUN_EXCEPTION;
} else {
dds_init();
rtio_init();
flush_cpu_icache();
k();
exception_pop(1);
return KERNEL_RUN_FINISHED;
}
#endif
session_start();
while(1)
comm_service();
}


static void blink_led(void)
{
int i, ev, p;
@@ -208,7 +96,7 @@ int main(void)
test_main();
} else {
puts("Entering regular mode.");
comm_serve(load_object, run_kernel);
regular_main();
}
return 0;
}
2 changes: 1 addition & 1 deletion soc/runtime/services.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include <string.h>

#include "elf_loader.h"
#include "comm.h"
#include "session.h"
#include "rtio.h"
#include "dds.h"
#include "exceptions.h"
503 changes: 503 additions & 0 deletions soc/runtime/session.c

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions soc/runtime/session.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifndef __SESSION_H
#define __SESSION_H

void session_start(void);
void session_end(void);

int session_input(void *data, int len);
void session_poll(void **data, int *len);
void session_ack(int len);

int rpc(int rpc_num, ...);
void comm_service(void);

#endif /* __SESSION_H */
4 changes: 2 additions & 2 deletions soc/runtime/test_mode.c
Original file line number Diff line number Diff line change
@@ -12,15 +12,15 @@

#ifdef ARTIQ_AMP

#include "kernelcpu.h"
#include "kloader.h"
#include "mailbox.h"
#include "messages.h"

static void amp_bridge_init(void)
{
struct msg_base *umsg;

kernelcpu_start(NULL);
kloader_start_bridge();

while(1) {
umsg = mailbox_wait_and_receive();

0 comments on commit 18106cc

Please sign in to comment.