Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Integrate libdyld and libunwind.
Browse files Browse the repository at this point in the history
It is currently possible to run the idle experiment, and it
can raise and catch exceptions, but exceptions are not yet
propagated across RPC boundaries.
whitequark committed Aug 2, 2015
1 parent 6db93b3 commit 122b3b0
Showing 22 changed files with 401 additions and 793 deletions.
4 changes: 2 additions & 2 deletions artiq/coredevice/comm_generic.py
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@ class _H2DMsgType(Enum):
IDENT_REQUEST = 2
SWITCH_CLOCK = 3

LOAD_OBJECT = 4
LOAD_LIBRARY = 4
RUN_KERNEL = 5

RPC_REPLY = 6
@@ -124,7 +124,7 @@ def switch_clock(self, external):
raise IOError("Incorrect reply from device: {}".format(ty))

def load(self, kcode):
self._write_header(len(kcode) + 9, _H2DMsgType.LOAD_OBJECT)
self._write_header(len(kcode) + 9, _H2DMsgType.LOAD_LIBRARY)
self.write(kcode)
_, ty = self._read_header()
if ty != _D2HMsgType.LOAD_COMPLETED:
35 changes: 21 additions & 14 deletions soc/runtime/Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
include $(MSCDIR)/software/common.mak

OBJECTS := isr.o flash_storage.o clock.o rtiocrg.o elf_loader.o services.o session.o log.o test_mode.o kloader.o bridge_ctl.o mailbox.o ksupport_data.o net_server.o moninj.o main.o
OBJECTS_KSUPPORT := ksupport.o exception_jmp.o exceptions.o mailbox.o bridge.o rtio.o ttl.o dds.o
OBJECTS := isr.o clock.o rtiocrg.o flash_storage.o mailbox.o \
session.o log.o moninj.o net_server.o bridge_ctl.o \
ksupport_data.o kloader.o test_mode.o main.o
OBJECTS_KSUPPORT := ksupport.o artiq_personality.o mailbox.o \
bridge.o rtio.o ttl.o dds.o

CFLAGS += -Ilwip/src/include -Iliblwip
CFLAGS += -I$(MSCDIR)/software/include/dyld \
-I$(MSCDIR)/software/unwinder/include \
-I$(MSCDIR)/software/libunwind \
-Ilwip/src/include -Iliblwip

all: runtime.bin runtime.fbi

@@ -19,7 +25,7 @@ all: runtime.bin runtime.fbi

runtime.elf: $(OBJECTS) libs
$(LD) $(LDFLAGS) \
-T linker.ld \
-T runtime.ld \
-N -o $@ \
$(MSCDIR)/software/libbase/crt0-$(CPU).o \
$(OBJECTS) \
@@ -29,24 +35,23 @@ runtime.elf: $(OBJECTS) libs
-lbase -lcompiler-rt -llwip
@chmod -x $@

ksupport.elf: $(OBJECTS_KSUPPORT)
ksupport.elf: $(OBJECTS_KSUPPORT) libs
$(LD) $(LDFLAGS) \
--eh-frame-hdr \
-T ksupport.ld \
-N -o $@ \
$(MSCDIR)/software/libbase/crt0-$(CPU).o \
$^ \
$(OBJECTS_KSUPPORT) \
-L$(MSCDIR)/software/libbase \
-L$(MSCDIR)/software/libcompiler-rt \
-lcompiler-rt
-L$(MSCDIR)/software/libunwind \
-L$(MSCDIR)/software/libdyld \
-lbase -lcompiler-rt -lunwind -ldyld
@chmod -x $@

ksupport_data.o: ksupport.bin
ksupport_data.o: ksupport.elf
$(LD) -r -b binary -o $@ $<

service_table.h: ksupport.elf gen_service_table.py
@echo " GEN " $@ && ./gen_service_table.py ksupport.elf > $@

services.c: service_table.h

main.o: main.c
$(compile-dep)

@@ -58,13 +63,15 @@ main.o: main.c

libs:
$(MAKE) -C $(MSCDIR)/software/libcompiler-rt
$(MAKE) -C $(MSCDIR)/software/libunwind
$(MAKE) -C $(MSCDIR)/software/libbase
$(MAKE) -C $(MSCDIR)/software/libdyld
$(MAKE) -C liblwip

clean:
$(MAKE) -C liblwip clean
$(RM) $(OBJECTS) $(OBJECTS:.o=.d) $(OBJECTS_KSUPPORT) $(OBJECTS_KSUPPORT:.o=.d)
$(RM) runtime.elf runtime.bin runtime.fbi .*~ *~
$(RM) service_table.h ksupport.elf ksupport.bin
$(RM) ksupport.elf ksupport.bin

.PHONY: all main.o clean libs load
4 changes: 3 additions & 1 deletion soc/runtime/artiq_personality.c
Original file line number Diff line number Diff line change
@@ -246,7 +246,9 @@ struct artiq_raised_exception {
static struct artiq_raised_exception inflight;

void __artiq_raise(struct artiq_exception *artiq_exn) {
EH_LOG("===> raise (name=%s)", artiq_exn->name);
EH_LOG("===> raise (name=%s, msg=%s, params=[%lld,%lld,%lld])",
artiq_exn->name, artiq_exn->message,
artiq_exn->param[0], artiq_exn->param[1], artiq_exn->param[2]);

memmove(&inflight.artiq, artiq_exn, sizeof(struct artiq_exception));
inflight.unwind.exception_class = ARTIQ_EXCEPTION_CLASS;
2 changes: 1 addition & 1 deletion soc/runtime/bridge.c
Original file line number Diff line number Diff line change
@@ -32,7 +32,7 @@ static void send_ready(void)
struct msg_base msg;

msg.type = MESSAGE_TYPE_BRG_READY;
mailbox_send_and_wait(&msg);
mailbox_send_and_wait(&msg);
}

void bridge_main(void)
8 changes: 4 additions & 4 deletions soc/runtime/dds.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include <generated/csr.h>
#include <stdio.h>

#include "exceptions.h"
#include "artiq_personality.h"
#include "rtio.h"
#include "log.h"
#include "dds.h"
@@ -179,7 +179,7 @@ static struct dds_set_params batch[DDS_MAX_BATCH];
void dds_batch_enter(long long int timestamp)
{
if(batch_mode)
exception_raise(EID_DDS_BATCH_ERROR);
artiq_raise_from_c("DDSBatchError", "DDS batch error", 0, 0, 0);
batch_mode = 1;
batch_count = 0;
batch_ref_time = timestamp;
@@ -191,7 +191,7 @@ void dds_batch_exit(void)
int i;

if(!batch_mode)
exception_raise(EID_DDS_BATCH_ERROR);
artiq_raise_from_c("DDSBatchError", "DDS batch error", 0, 0, 0);
rtio_chan_sel_write(RTIO_DDS_CHANNEL);
/* + FUD time */
now = batch_ref_time - batch_count*(DURATION_PROGRAM + DURATION_WRITE);
@@ -208,7 +208,7 @@ void dds_set(long long int timestamp, int channel,
{
if(batch_mode) {
if(batch_count >= DDS_MAX_BATCH)
exception_raise(EID_DDS_BATCH_ERROR);
artiq_raise_from_c("DDSBatchError", "DDS batch error", 0, 0, 0);
/* timestamp parameter ignored (determined by batch) */
batch[batch_count].channel = channel;
batch[batch_count].ftw = ftw;
240 changes: 0 additions & 240 deletions soc/runtime/elf_loader.c

This file was deleted.

16 changes: 0 additions & 16 deletions soc/runtime/elf_loader.h

This file was deleted.

37 changes: 0 additions & 37 deletions soc/runtime/exception_jmp.S

This file was deleted.

58 changes: 0 additions & 58 deletions soc/runtime/exceptions.c

This file was deleted.

25 changes: 0 additions & 25 deletions soc/runtime/exceptions.h

This file was deleted.

65 changes: 0 additions & 65 deletions soc/runtime/gen_service_table.py

This file was deleted.

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

#include <dyld.h>

#include "kloader.h"
#include "log.h"
#include "flash_storage.h"
#include "mailbox.h"
#include "messages.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 start_kernel_cpu(struct msg_load_request *msg)
{
// Stop kernel CPU before messing with its code.
kernel_cpu_reset_write(1);

// Load kernel support code.
extern void _binary_ksupport_elf_start, _binary_ksupport_elf_end;
memcpy((void *)(KERNELCPU_EXEC_ADDRESS - KSUPPORT_HEADER_SIZE),
&_binary_ksupport_elf_start,
&_binary_ksupport_elf_end - &_binary_ksupport_elf_start);

// Start kernel CPU.
mailbox_send(msg);
kernel_cpu_reset_write(0);
}

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

static int symtab_add(const char *name, void *target)
static int load_or_start_kernel(void *library, const char *kernel)
{
if(_symtab_count >= sizeof(symtab)/sizeof(symtab[0])) {
log("Too many provided symbols in object");
symtab_init();
static struct dyld_info library_info;
struct msg_load_request request = {
.library = library,
.library_info = &library_info,
.kernel = kernel,
};
start_kernel_cpu(&request);

struct msg_load_reply *reply = mailbox_wait_and_receive();
if(reply != NULL && reply->type == MESSAGE_TYPE_LOAD_REPLY) {
log("cannot load/run kernel: %s", reply->error);
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)
int kloader_load_library(void *library)
{
if(!kernel_cpu_reset_read()) {
log("BUG: attempted to load while kernel CPU running");
log("BUG: attempted to load kernel library while kernel CPU is running");
return 0;
}
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);
return load_or_start_kernel(library, NULL);
}

extern char _binary_ksupport_bin_start;
extern char _binary_ksupport_bin_end;

static void start_kernel_cpu(void *addr)
int kloader_start_kernel(const char *name)
{
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);
return load_or_start_kernel(NULL, name);
}

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)
int kloader_start_idle_kernel(void)
{
#if (defined CSR_SPIFLASH_BASE && defined SPIFLASH_PAGE_SIZE)
char buffer[32*1024];
int len;
kernel_function k;
int length;

if(!kernel_cpu_reset_read()) {
log("BUG: attempted to start kernel CPU while already running (idle kernel)");
return;
}
#if (defined CSR_SPIFLASH_BASE && defined SPIFLASH_PAGE_SIZE)
len = fs_read("idle_kernel", buffer, sizeof(buffer), NULL);
if(len <= 0)
return;
if(!kloader_load(buffer, len)) {
log("Failed to load ELF binary for idle kernel");
return;
}
k = kloader_find("run");
if(!k) {
log("Failed to find entry point for ELF kernel");
return;
}
start_kernel_cpu((void *)k);
length = fs_read("idle_kernel", buffer, sizeof(buffer), NULL);
if(length <= 0)
return 0;

return load_or_start_kernel(buffer, "test.__modinit__");
#else
return 0;
#endif
}

@@ -127,7 +89,7 @@ void kloader_stop(void)
int kloader_validate_kpointer(void *p)
{
unsigned int v = (unsigned int)p;
if((v < 0x40400000) || (v > (0x4fffffff - 1024*1024))) {
if((v < KERNELCPU_EXEC_ADDRESS) || (v > KERNELCPU_LAST_ADDRESS)) {
log("Received invalid pointer from kernel CPU: 0x%08x", v);
return 0;
}
15 changes: 7 additions & 8 deletions soc/runtime/kloader.h
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
#ifndef __KLOADER_H
#define __KLOADER_H

#define KERNELCPU_EXEC_ADDRESS 0x40400000
#define KERNELCPU_PAYLOAD_ADDRESS 0x40408000
#define KERNELCPU_EXEC_ADDRESS 0x40400000
#define KERNELCPU_PAYLOAD_ADDRESS 0x40420000
#define KERNELCPU_LAST_ADDRESS (0x4fffffff - 1024*1024)
#define KSUPPORT_HEADER_SIZE 0x80

extern long long int now;

typedef void (*kernel_function)(void);

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

void kloader_start_bridge(void);
void kloader_start_idle_kernel(void);
void kloader_start_user_kernel(kernel_function k);
int kloader_start_idle_kernel(void);
int kloader_start_kernel(const char *name);
void kloader_stop(void);

int kloader_validate_kpointer(void *p);
309 changes: 252 additions & 57 deletions soc/runtime/ksupport.c
Original file line number Diff line number Diff line change
@@ -1,67 +1,254 @@
#include <stdarg.h>
#include <string.h>
#include <stdio.h>

#include "exceptions.h"
#include "bridge.h"
#include <link.h>
#include <dlfcn.h>
#include <dyld.h>
#include <unwind.h>

#include "ksupport.h"
#include "kloader.h"
#include "mailbox.h"
#include "messages.h"
#include "rtio.h"
#include "bridge.h"
#include "artiq_personality.h"
#include "ttl.h"
#include "dds.h"
#include "rtio.h"

/* for the prototypes for watchdog_set() and watchdog_clear() */
#include "clock.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)
/* compiler-rt symbols */
extern void __divsi3, __modsi3, __ledf2, __gedf2, __unorddf2, __eqdf2, __ltdf2,
__nedf2, __gtdf2, __negsf2, __negdf2, __addsf3, __subsf3, __mulsf3,
__divsf3, __lshrdi3, __muldi3, __divdi3, __ashldi3, __ashrdi3,
__udivmoddi4, __floatsisf, __floatunsisf, __fixsfsi, __fixunssfsi,
__adddf3, __subdf3, __muldf3, __divdf3, __floatsidf, __floatunsidf,
__floatdidf, __fixdfsi, __fixdfdi, __fixunsdfsi, __clzsi2, __ctzsi2,
__udivdi3, __umoddi3, __moddi3;

/* artiq_personality symbols */
extern void __artiq_personality;

struct symbol {
const char *name;
void *addr;
};

static const struct symbol runtime_exports[] = {
/* compiler-rt */
{"divsi3", &__divsi3},
{"modsi3", &__modsi3},
{"ledf2", &__ledf2},
{"gedf2", &__gedf2},
{"unorddf2", &__unorddf2},
{"eqdf2", &__eqdf2},
{"ltdf2", &__ltdf2},
{"nedf2", &__nedf2},
{"gtdf2", &__gtdf2},
{"negsf2", &__negsf2},
{"negdf2", &__negdf2},
{"addsf3", &__addsf3},
{"subsf3", &__subsf3},
{"mulsf3", &__mulsf3},
{"divsf3", &__divsf3},
{"lshrdi3", &__lshrdi3},
{"muldi3", &__muldi3},
{"divdi3", &__divdi3},
{"ashldi3", &__ashldi3},
{"ashrdi3", &__ashrdi3},
{"udivmoddi4", &__udivmoddi4},
{"floatsisf", &__floatsisf},
{"floatunsisf", &__floatunsisf},
{"fixsfsi", &__fixsfsi},
{"fixunssfsi", &__fixunssfsi},
{"adddf3", &__adddf3},
{"subdf3", &__subdf3},
{"muldf3", &__muldf3},
{"divdf3", &__divdf3},
{"floatsidf", &__floatsidf},
{"floatunsidf", &__floatunsidf},
{"floatdidf", &__floatdidf},
{"fixdfsi", &__fixdfsi},
{"fixdfdi", &__fixdfdi},
{"fixunsdfsi", &__fixunsdfsi},
{"clzsi2", &__clzsi2},
{"ctzsi2", &__ctzsi2},
{"udivdi3", &__udivdi3},
{"umoddi3", &__umoddi3},
{"moddi3", &__moddi3},

/* exceptions */
{"_Unwind_Resume", &_Unwind_Resume},
{"__artiq_personality", &__artiq_personality},
{"__artiq_raise", &__artiq_raise},
{"__artiq_reraise", &__artiq_reraise},

/* proxified syscalls */
{"now_init", &now_init},
{"now_save", &now_save},

{"watchdog_set", &watchdog_set},
{"watchdog_clear", &watchdog_clear},

{"log", &log},
{"lognonl", &lognonl},
{"rpc", &rpc},

/* direct syscalls */
{"rtio_get_counter", &rtio_get_counter},

{"ttl_set_o", &ttl_set_o},
{"ttl_set_oe", &ttl_set_oe},
{"ttl_set_sensitivity", &ttl_set_sensitivity},
{"ttl_get", &ttl_get},
{"ttl_clock_set", &ttl_clock_set},

{"dds_init", &dds_init},
{"dds_batch_enter", &dds_batch_enter},
{"dds_batch_exit", &dds_batch_exit},
{"dds_set", &dds_set},

/* end */
{NULL, NULL}
};

/* called by libunwind */
int fprintf(FILE *stream, const char *fmt, ...)
{
struct msg_exception msg;
struct msg_log request;

msg.type = MESSAGE_TYPE_EXCEPTION;
msg.eid = EID_INTERNAL_ERROR;
msg.eparams[0] = 256;
msg.eparams[1] = 256;
msg.eparams[2] = 256;
mailbox_send_and_wait(&msg);
while(1);
request.type = MESSAGE_TYPE_LOG;
request.fmt = fmt;
request.no_newline = 1;
va_start(request.args, fmt);
mailbox_send_and_wait(&request);
va_end(request.args);

return 0;
}

typedef void (*kernel_function)(void);
/* called by libunwind */
int dladdr (const void *address, Dl_info *info) {
/* we don't try to resolve names */
return 0;
}

/* called by libunwind */
int dl_iterate_phdr (int (*callback) (struct dl_phdr_info *, size_t, void *), void *data) {
Elf32_Ehdr *ehdr;
struct dl_phdr_info phdr_info;
int retval;

ehdr = (Elf32_Ehdr *)(KERNELCPU_EXEC_ADDRESS - KSUPPORT_HEADER_SIZE);
phdr_info = (struct dl_phdr_info){
.dlpi_addr = 0, /* absolutely linked */
.dlpi_name = "<ksupport>",
.dlpi_phdr = (Elf32_Phdr*) ((intptr_t)ehdr + ehdr->e_phoff),
.dlpi_phnum = ehdr->e_phnum,
};
retval = callback(&phdr_info, sizeof(phdr_info), data);
if(retval)
return retval;

ehdr = (Elf32_Ehdr *)KERNELCPU_PAYLOAD_ADDRESS;
phdr_info = (struct dl_phdr_info){
.dlpi_addr = KERNELCPU_PAYLOAD_ADDRESS,
.dlpi_name = "<kernel>",
.dlpi_phdr = (Elf32_Phdr*) ((intptr_t)ehdr + ehdr->e_phoff),
.dlpi_phnum = ehdr->e_phnum,
};
retval = callback(&phdr_info, sizeof(phdr_info), data);
return retval;
}

static Elf32_Addr resolve_runtime_export(const char *name) {
const struct symbol *sym = runtime_exports;
while(sym->name) {
if(!strcmp(sym->name, name))
return (Elf32_Addr)sym->addr;
++sym;
}
return 0;
}

void exception_handler(unsigned long vect, unsigned long *regs,
unsigned long pc, unsigned long ea);
void exception_handler(unsigned long vect, unsigned long *regs,
unsigned long pc, unsigned long ea)
{
artiq_raise_from_c("InternalError",
"Hardware exception {0} at PC {1}, EA {2}",
vect, pc, ea);
}

int main(void);
int main(void)
{
kernel_function k;
void *jb;

k = mailbox_receive();
struct msg_load_request *msg = mailbox_receive();

if(k == NULL)
if(msg == NULL) {
bridge_main();
else {
jb = exception_push();
if(exception_setjmp(jb)) {
struct msg_exception msg;

msg.type = MESSAGE_TYPE_EXCEPTION;
msg.eid = exception_getid(msg.eparams);
mailbox_send_and_wait(&msg);
} else {
struct msg_base msg;

k();
exception_pop(1);

msg.type = MESSAGE_TYPE_FINISHED;
mailbox_send_and_wait(&msg);
while(1);
}

if(msg->library != NULL) {
const char *error;
if(!dyld_load(msg->library, KERNELCPU_PAYLOAD_ADDRESS,
resolve_runtime_export, msg->library_info, &error)) {
struct msg_load_reply msg = {
.type = MESSAGE_TYPE_LOAD_REPLY,
.error = error
};
mailbox_send(&msg);
while(1);
}
}

void (*kernel)(void) = NULL;
if(msg->kernel != NULL) {
kernel = dyld_lookup(msg->kernel, msg->library_info);
if(kernel == NULL) {
char error[256];
snprintf(error, sizeof(error),
"kernel '%s' not found in library", msg->kernel);
struct msg_load_reply msg = {
.type = MESSAGE_TYPE_LOAD_REPLY,
.error = error
};
mailbox_send(&msg);
while(1);
}
}

mailbox_acknowledge();

if(kernel) {
void (*run_closure)(void *) = msg->library_info->init;
run_closure(kernel);

struct msg_base msg;
msg.type = MESSAGE_TYPE_FINISHED;
mailbox_send_and_wait(&msg);
}

while(1);
}

/* called from __artiq_personality */
void __artiq_terminate(struct artiq_exception *artiq_exn,
struct artiq_backtrace_item *backtrace,
size_t backtrace_size) {
struct msg_exception msg;

msg.type = MESSAGE_TYPE_EXCEPTION;
msg.exception = artiq_exn;
msg.backtrace = backtrace;
msg.backtrace_size = backtrace_size;
mailbox_send(&msg);

while(1);
}

long long int now_init(void);
long long int now_init(void)
{
struct msg_base request;
@@ -72,8 +259,10 @@ long long int now_init(void)
mailbox_send_and_wait(&request);

reply = mailbox_wait_and_receive();
if(reply->type != MESSAGE_TYPE_NOW_INIT_REPLY)
exception_raise_params(EID_INTERNAL_ERROR, 1, 0, 0);
if(reply->type != MESSAGE_TYPE_NOW_INIT_REPLY) {
log("Malformed MESSAGE_TYPE_NOW_INIT_REQUEST reply type");
while(1);
}
now = reply->now;
mailbox_acknowledge();

@@ -85,7 +274,6 @@ long long int now_init(void)
return now;
}

void now_save(long long int now);
void now_save(long long int now)
{
struct msg_now_save request;
@@ -106,8 +294,10 @@ int watchdog_set(int ms)
mailbox_send_and_wait(&request);

reply = mailbox_wait_and_receive();
if(reply->type != MESSAGE_TYPE_WATCHDOG_SET_REPLY)
exception_raise_params(EID_INTERNAL_ERROR, 2, 0, 0);
if(reply->type != MESSAGE_TYPE_WATCHDOG_SET_REPLY) {
log("Malformed MESSAGE_TYPE_WATCHDOG_SET_REQUEST reply type");
while(1);
}
id = reply->id;
mailbox_acknowledge();

@@ -127,7 +317,6 @@ int rpc(int rpc_num, ...)
{
struct msg_rpc_request request;
struct msg_rpc_reply *reply;
int eid, retval;

request.type = MESSAGE_TYPE_RPC_REQUEST;
request.rpc_num = rpc_num;
@@ -136,15 +325,21 @@ int rpc(int rpc_num, ...)
va_end(request.args);

reply = mailbox_wait_and_receive();
if(reply->type != MESSAGE_TYPE_RPC_REPLY)
exception_raise_params(EID_INTERNAL_ERROR, 3, 0, 0);
eid = reply->eid;
retval = reply->retval;
mailbox_acknowledge();
if(reply->type != MESSAGE_TYPE_RPC_REPLY) {
log("Malformed MESSAGE_TYPE_RPC_REPLY reply type");
while(1);
}

if(eid != EID_NONE)
exception_raise(eid);
return retval;
if(reply->exception != NULL) {
struct artiq_exception exception;
memcpy(&exception, reply->exception, sizeof(exception));
mailbox_acknowledge();
__artiq_raise(&exception);
} else {
int retval = reply->retval;
mailbox_acknowledge();
return retval;
}
}

void lognonl(const char *fmt, ...)
27 changes: 22 additions & 5 deletions soc/runtime/ksupport.ld
Original file line number Diff line number Diff line change
@@ -4,25 +4,32 @@ ENTRY(_start)
INCLUDE generated/regions.ld

/* First 4M of main memory are reserved for runtime code/data
* then comes kernel memory. First 32K of kernel memory are for support code.
* then comes kernel memory. First 128K of kernel memory are for support code.
*/
MEMORY {
ksupport : ORIGIN = 0x40400000, LENGTH = 0x8000
ksupport (RWX) : ORIGIN = 0x40400000, LENGTH = 0x20000
}

/* On AMP systems, kernel stack is at the end of main RAM,
* before the runtime stack. Leave 1M for runtime stack.
*/
PROVIDE(_fstack = 0x40000000 + LENGTH(main_ram) - 1024*1024 - 4);

/* Force ld to make the ELF header as loadable. */
PHDRS
{
text PT_LOAD FILEHDR PHDRS;
eh_frame PT_GNU_EH_FRAME;
}

SECTIONS
{
.text :
{
_ftext = .;
*(.text .stub .text.* .gnu.linkonce.t.*)
_etext = .;
} > ksupport
} :text

.rodata :
{
@@ -33,6 +40,16 @@ SECTIONS
_erodata = .;
} > ksupport

.eh_frame :
{
*(.eh_frame)
} :text

.eh_frame_hdr :
{
*(.eh_frame_hdr)
} :text :eh_frame

.data :
{
. = ALIGN(4);
@@ -41,7 +58,7 @@ SECTIONS
*(.data1)
*(.sdata .sdata.* .gnu.linkonce.s.*)
_edata = .;
} > ksupport
}

.bss :
{
@@ -57,5 +74,5 @@ SECTIONS
_ebss = .;
. = ALIGN(8);
_heapstart = .;
} > ksupport
}
}
63 changes: 0 additions & 63 deletions soc/runtime/linker.ld

This file was deleted.

20 changes: 17 additions & 3 deletions soc/runtime/messages.h
Original file line number Diff line number Diff line change
@@ -2,8 +2,10 @@
#define __MESSAGES_H

#include <stdarg.h>
#include <stddef.h>

enum {
MESSAGE_TYPE_LOAD_REPLY,
MESSAGE_TYPE_NOW_INIT_REQUEST,
MESSAGE_TYPE_NOW_INIT_REPLY,
MESSAGE_TYPE_NOW_SAVE,
@@ -34,6 +36,17 @@ struct msg_base {

/* kernel messages */

struct msg_load_request {
void *library;
struct dyld_info *library_info;
const char *kernel;
};

struct msg_load_reply {
int type;
const char *error;
};

struct msg_now_init_reply {
int type;
long long int now;
@@ -46,8 +59,9 @@ struct msg_now_save {

struct msg_exception {
int type;
int eid;
long long int eparams[3];
struct artiq_exception *exception;
struct artiq_backtrace_item *backtrace;
size_t backtrace_size;
};

struct msg_watchdog_set_request {
@@ -73,7 +87,7 @@ struct msg_rpc_request {

struct msg_rpc_reply {
int type;
int eid;
struct artiq_exception *exception;
int retval;
};

8 changes: 5 additions & 3 deletions soc/runtime/rtio.h
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
#define __RTIO_H

#include <generated/csr.h>
#include "exceptions.h"
#include "artiq_personality.h"

#define RTIO_O_STATUS_FULL 1
#define RTIO_O_STATUS_UNDERFLOW 2
@@ -24,12 +24,14 @@ static inline void rtio_write_and_process_status(long long int timestamp, int ch
while(rtio_o_status_read() & RTIO_O_STATUS_FULL);
if(status & RTIO_O_STATUS_UNDERFLOW) {
rtio_o_underflow_reset_write(1);
exception_raise_params(EID_RTIO_UNDERFLOW,
artiq_raise_from_c("RTIOUnderflow",
"RTIO underflow at {0}mu, channel {1}, counter {2}",
timestamp, channel, rtio_get_counter());
}
if(status & RTIO_O_STATUS_SEQUENCE_ERROR) {
rtio_o_sequence_error_reset_write(1);
exception_raise_params(EID_RTIO_SEQUENCE_ERROR,
artiq_raise_from_c("RTIOSequenceError",
"RTIO sequence error at {0}mu, channel {1}",
timestamp, channel, 0);
}
}
78 changes: 0 additions & 78 deletions soc/runtime/services.c

This file was deleted.

6 changes: 0 additions & 6 deletions soc/runtime/services.h

This file was deleted.

35 changes: 16 additions & 19 deletions soc/runtime/session.c
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@
#include "clock.h"
#include "log.h"
#include "kloader.h"
#include "exceptions.h"
#include "artiq_personality.h"
#include "flash_storage.h"
#include "rtiocrg.h"
#include "session.h"
@@ -19,7 +19,7 @@
#define BUFFER_OUT_SIZE (1024*1024)

static int buffer_in_index;
/* The 9th byte (right after the header) of buffer_in must be aligned
/* The 9th byte (right after the header) of buffer_in must be aligned
* to a 32-bit boundary for elf_loader to work.
*/
static struct {
@@ -85,8 +85,8 @@ enum {
REMOTEMSG_TYPE_LOG_REQUEST = 1,
REMOTEMSG_TYPE_IDENT_REQUEST,
REMOTEMSG_TYPE_SWITCH_CLOCK,
REMOTEMSG_TYPE_LOAD_OBJECT,

REMOTEMSG_TYPE_LOAD_LIBRARY,
REMOTEMSG_TYPE_RUN_KERNEL,

REMOTEMSG_TYPE_RPC_REPLY,
@@ -161,23 +161,22 @@ static int process_input(void)
buffer_out[8] = REMOTEMSG_TYPE_CLOCK_SWITCH_FAILED;
submit_output(9);
break;
case REMOTEMSG_TYPE_LOAD_OBJECT:
case REMOTEMSG_TYPE_LOAD_LIBRARY:
if(user_kernel_state >= USER_KERNEL_RUNNING) {
log("Attempted to load new kernel while already running");
log("Attempted to load new kernel library while already running");
buffer_out[8] = REMOTEMSG_TYPE_LOAD_FAILED;
submit_output(9);
break;
break;
}
if(kloader_load(&buffer_in[9], get_in_packet_len() - 8)) {
if(kloader_load_library(&buffer_in[9])) {
buffer_out[8] = REMOTEMSG_TYPE_LOAD_COMPLETED;
user_kernel_state = USER_KERNEL_LOADED;
} else
} else {
buffer_out[8] = REMOTEMSG_TYPE_LOAD_FAILED;
}
submit_output(9);
break;
case REMOTEMSG_TYPE_RUN_KERNEL: {
kernel_function k;

if(user_kernel_state != USER_KERNEL_LOADED) {
log("Attempted to run kernel while not in the LOADED state");
buffer_out[8] = REMOTEMSG_TYPE_KERNEL_STARTUP_FAILED;
@@ -193,16 +192,14 @@ static int process_input(void)
}
buffer_in[buffer_in_index] = 0;

k = kloader_find((char *)&buffer_in[9]);
if(k == NULL) {
watchdog_init();
if(!kloader_start_kernel((char *)&buffer_in[9])) {
log("Failed to find kernel entry point '%s' in object", &buffer_in[9]);
buffer_out[8] = REMOTEMSG_TYPE_KERNEL_STARTUP_FAILED;
submit_output(9);
break;
}

watchdog_init();
kloader_start_user_kernel(k);
user_kernel_state = USER_KERNEL_RUNNING;
break;
}
@@ -215,7 +212,7 @@ static int process_input(void)
}

reply.type = MESSAGE_TYPE_RPC_REPLY;
memcpy(&reply.eid, &buffer_in[9], 4);
// FIXME memcpy(&reply.eid, &buffer_in[9], 4);
memcpy(&reply.retval, &buffer_in[13], 4);
mailbox_send_and_wait(&reply);
user_kernel_state = USER_KERNEL_RUNNING;
@@ -481,8 +478,8 @@ static int process_kmsg(struct msg_base *umsg)
struct msg_exception *msg = (struct msg_exception *)umsg;

buffer_out[8] = REMOTEMSG_TYPE_KERNEL_EXCEPTION;
memcpy(&buffer_out[9], &msg->eid, 4);
memcpy(&buffer_out[13], msg->eparams, 3*8);
// memcpy(&buffer_out[9], &msg->eid, 4);
// memcpy(&buffer_out[13], msg->eparams, 3*8);
submit_output(9+4+3*8);

kloader_stop();
@@ -545,7 +542,7 @@ void session_poll(void **data, int *len)

l = get_out_packet_len();

/* If the output buffer is available,
/* If the output buffer is available,
* check if the kernel CPU has something to transmit.
*/
if(l == 0) {
5 changes: 3 additions & 2 deletions soc/runtime/ttl.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include <generated/csr.h>

#include "exceptions.h"
#include "artiq_personality.h"
#include "rtio.h"
#include "ttl.h"

@@ -40,7 +40,8 @@ long long int ttl_get(int channel, long long int time_limit)
while((status = rtio_i_status_read())) {
if(rtio_i_status_read() & RTIO_I_STATUS_OVERFLOW) {
rtio_i_overflow_reset_write(1);
exception_raise_params(EID_RTIO_OVERFLOW,
artiq_raise_from_c("RTIOOverflow",
"RTIO overflow at channel {0}",
channel, 0, 0);
}
if(rtio_get_counter() >= time_limit) {

0 comments on commit 122b3b0

Please sign in to comment.