From 62fdc75d2d64fe53e6129bb97bfbc6ee3799af54 Mon Sep 17 00:00:00 2001 From: whitequark Date: Sun, 2 Aug 2015 06:41:05 +0300 Subject: [PATCH] Integrate libdyld and libunwind. 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. --- artiq/coredevice/comm_generic.py | 4 +- soc/runtime/Makefile | 35 +-- soc/runtime/artiq_personality.c | 4 +- soc/runtime/bridge.c | 2 +- soc/runtime/dds.c | 8 +- soc/runtime/elf_loader.c | 240 -------------------- soc/runtime/elf_loader.h | 16 -- soc/runtime/exception_jmp.S | 37 ---- soc/runtime/exceptions.c | 58 ----- soc/runtime/exceptions.h | 25 --- soc/runtime/gen_service_table.py | 65 ------ soc/runtime/kloader.c | 140 +++++------- soc/runtime/kloader.h | 15 +- soc/runtime/ksupport.c | 305 +++++++++++++++++++++----- soc/runtime/ksupport.h | 12 + soc/runtime/ksupport.ld | 27 ++- soc/runtime/messages.h | 20 +- soc/runtime/rtio.h | 8 +- soc/runtime/{linker.ld => runtime.ld} | 20 +- soc/runtime/services.c | 78 ------- soc/runtime/services.h | 6 - soc/runtime/session.c | 35 ++- soc/runtime/ttl.c | 5 +- 23 files changed, 433 insertions(+), 732 deletions(-) delete mode 100644 soc/runtime/elf_loader.c delete mode 100644 soc/runtime/elf_loader.h delete mode 100644 soc/runtime/exception_jmp.S delete mode 100644 soc/runtime/exceptions.c delete mode 100644 soc/runtime/exceptions.h delete mode 100755 soc/runtime/gen_service_table.py create mode 100644 soc/runtime/ksupport.h rename soc/runtime/{linker.ld => runtime.ld} (71%) delete mode 100644 soc/runtime/services.c delete mode 100644 soc/runtime/services.h diff --git a/artiq/coredevice/comm_generic.py b/artiq/coredevice/comm_generic.py index 88fee184b..2daa24cdc 100644 --- a/artiq/coredevice/comm_generic.py +++ b/artiq/coredevice/comm_generic.py @@ -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 @@ class CommGeneric: 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: diff --git a/soc/runtime/Makefile b/soc/runtime/Makefile index 36fb42b2b..acab0e96e 100644 --- a/soc/runtime/Makefile +++ b/soc/runtime/Makefile @@ -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 diff --git a/soc/runtime/artiq_personality.c b/soc/runtime/artiq_personality.c index 9220c0e38..2dc2350a5 100644 --- a/soc/runtime/artiq_personality.c +++ b/soc/runtime/artiq_personality.c @@ -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; diff --git a/soc/runtime/bridge.c b/soc/runtime/bridge.c index 78083a16f..c371f6232 100644 --- a/soc/runtime/bridge.c +++ b/soc/runtime/bridge.c @@ -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) diff --git a/soc/runtime/dds.c b/soc/runtime/dds.c index 5f9f8650e..de744e624 100644 --- a/soc/runtime/dds.c +++ b/soc/runtime/dds.c @@ -1,7 +1,7 @@ #include #include -#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; diff --git a/soc/runtime/elf_loader.c b/soc/runtime/elf_loader.c deleted file mode 100644 index 8604381e8..000000000 --- a/soc/runtime/elf_loader.c +++ /dev/null @@ -1,240 +0,0 @@ -#include - -#include "log.h" -#include "elf_loader.h" - -#define EI_NIDENT 16 - -struct elf32_ehdr { - unsigned char ident[EI_NIDENT]; /* ident bytes */ - unsigned short type; /* file type */ - unsigned short machine; /* target machine */ - unsigned int version; /* file version */ - unsigned int entry; /* start address */ - unsigned int phoff; /* phdr file offset */ - unsigned int shoff; /* shdr file offset */ - unsigned int flags; /* file flags */ - unsigned short ehsize; /* sizeof ehdr */ - unsigned short phentsize; /* sizeof phdr */ - unsigned short phnum; /* number phdrs */ - unsigned short shentsize; /* sizeof shdr */ - unsigned short shnum; /* number shdrs */ - unsigned short shstrndx; /* shdr string index */ -} __attribute__((packed)); - -static const unsigned char elf_magic_header[] = { - 0x7f, 0x45, 0x4c, 0x46, /* 0x7f, 'E', 'L', 'F' */ - 0x01, /* Only 32-bit objects. */ - 0x02, /* Only big-endian. */ - 0x01, /* Only ELF version 1. */ -}; - -#define ET_NONE 0 /* Unknown type. */ -#define ET_REL 1 /* Relocatable. */ -#define ET_EXEC 2 /* Executable. */ -#define ET_DYN 3 /* Shared object. */ -#define ET_CORE 4 /* Core file. */ - -#define EM_OR1K 0x005c - -struct elf32_shdr { - unsigned int name; /* section name */ - unsigned int type; /* SHT_... */ - unsigned int flags; /* SHF_... */ - unsigned int addr; /* virtual address */ - unsigned int offset; /* file offset */ - unsigned int size; /* section size */ - unsigned int link; /* misc info */ - unsigned int info; /* misc info */ - unsigned int addralign; /* memory alignment */ - unsigned int entsize; /* entry size if table */ -} __attribute__((packed)); - -struct elf32_name { - char name[12]; -} __attribute__((packed)); - -struct elf32_rela { - unsigned int offset; /* Location to be relocated. */ - unsigned int info; /* Relocation type and symbol index. */ - int addend; /* Addend. */ -} __attribute__((packed)); - -#define ELF32_R_SYM(info) ((info) >> 8) -#define ELF32_R_TYPE(info) ((unsigned char)(info)) - -#define R_OR1K_INSN_REL_26 6 - -struct elf32_sym { - unsigned int name; /* String table index of name. */ - unsigned int value; /* Symbol value. */ - unsigned int size; /* Size of associated object. */ - unsigned char info; /* Type and binding information. */ - unsigned char other; /* Reserved (not used). */ - unsigned short shndx; /* Section index of symbol. */ -} __attribute__((packed)); - -#define STT_NOTYPE 0 -#define STT_OBJECT 1 -#define STT_FUNC 2 -#define STT_SECTION 3 -#define STT_FILE 4 - -#define ELF32_ST_TYPE(info) ((info) & 0x0f) - - -#define SANITIZE_OFFSET_SIZE(offset, size) \ - if(offset > 0x10000000) { \ - log("Incorrect offset in ELF data"); \ - return 0; \ - } \ - if((offset + size) > elf_length) { \ - log("Attempted to access past the end of ELF data"); \ - return 0; \ - } - -#define GET_POINTER_SAFE(target, target_type, offset) \ - SANITIZE_OFFSET_SIZE(offset, sizeof(target_type)); \ - target = (target_type *)((char *)elf_data + offset) - -void *find_symbol(const struct symbol *symbols, const char *name) -{ - int i; - - i = 0; - while((symbols[i].name != NULL) && (strcmp(symbols[i].name, name) != 0)) - i++; - return symbols[i].target; -} - -static int fixup(void *dest, int dest_length, struct elf32_rela *rela, void *target) -{ - int type, offset; - unsigned int *_dest = dest; - unsigned int *_target = target; - - type = ELF32_R_TYPE(rela->info); - offset = rela->offset/4; - if(type == R_OR1K_INSN_REL_26) { - int val; - - val = _target - (_dest + offset); - _dest[offset] = (_dest[offset] & 0xfc000000) | (val & 0x03ffffff); - } else - log("Unsupported relocation type: %d", type); - return 1; -} - -int load_elf(symbol_resolver resolver, symbol_callback callback, void *elf_data, int elf_length, void *dest, int dest_length) -{ - struct elf32_ehdr *ehdr; - struct elf32_shdr *strtable; - unsigned int shdrptr; - int i; - - unsigned int textoff, textsize; - unsigned int textrelaoff, textrelasize; - unsigned int symtaboff, symtabsize; - unsigned int strtaboff, strtabsize; - - - /* validate ELF */ - GET_POINTER_SAFE(ehdr, struct elf32_ehdr, 0); - if(memcmp(ehdr->ident, elf_magic_header, sizeof(elf_magic_header)) != 0) { - log("Incorrect ELF header"); - return 0; - } - if(ehdr->type != ET_REL) { - log("ELF is not relocatable"); - return 0; - } - if(ehdr->machine != EM_OR1K) { - log("ELF is for a different machine"); - return 0; - } - - /* extract section info */ - GET_POINTER_SAFE(strtable, struct elf32_shdr, ehdr->shoff + ehdr->shentsize*ehdr->shstrndx); - textoff = textsize = 0; - textrelaoff = textrelasize = 0; - symtaboff = symtabsize = 0; - strtaboff = strtabsize = 0; - shdrptr = ehdr->shoff; - for(i=0;ishnum;i++) { - struct elf32_shdr *shdr; - struct elf32_name *name; - - GET_POINTER_SAFE(shdr, struct elf32_shdr, shdrptr); - GET_POINTER_SAFE(name, struct elf32_name, strtable->offset + shdr->name); - - if(strncmp(name->name, ".text", 5) == 0) { - textoff = shdr->offset; - textsize = shdr->size; - } else if(strncmp(name->name, ".rela.text", 10) == 0) { - textrelaoff = shdr->offset; - textrelasize = shdr->size; - } else if(strncmp(name->name, ".symtab", 7) == 0) { - symtaboff = shdr->offset; - symtabsize = shdr->size; - } else if(strncmp(name->name, ".strtab", 7) == 0) { - strtaboff = shdr->offset; - strtabsize = shdr->size; - } - - shdrptr += ehdr->shentsize; - } - SANITIZE_OFFSET_SIZE(textoff, textsize); - SANITIZE_OFFSET_SIZE(textrelaoff, textrelasize); - SANITIZE_OFFSET_SIZE(symtaboff, symtabsize); - SANITIZE_OFFSET_SIZE(strtaboff, strtabsize); - - /* load .text section */ - if(textsize > dest_length) { - log(".text section is too large"); - return 0; - } - memcpy(dest, (char *)elf_data + textoff, textsize); - - /* process .text relocations */ - for(i=0;iinfo)); - if(sym->name != 0) { - char *name; - void *target; - - name = (char *)elf_data + strtaboff + sym->name; - target = resolver(name); - if(target == NULL) { - log("Undefined symbol: %s", name); - return 0; - } - if(!fixup(dest, dest_length, rela, target)) - return 0; - } else { - log("Unsupported relocation"); - return 0; - } - } - - /* list provided functions via callback */ - for(i=0;iinfo) == STT_FUNC) && (sym->name != 0)) { - char *name; - void *target; - - name = (char *)elf_data + strtaboff + sym->name; - target = (char *)dest + sym->value; - if(!callback(name, target)) - return 0; - } - } - - return 1; -} diff --git a/soc/runtime/elf_loader.h b/soc/runtime/elf_loader.h deleted file mode 100644 index a116e0851..000000000 --- a/soc/runtime/elf_loader.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __ELF_LOADER_H -#define __ELF_LOADER_H - -struct symbol { - char *name; - void *target; -}; - -typedef void * (*symbol_resolver)(const char *); -typedef int (*symbol_callback)(const char *, void *); - -void *find_symbol(const struct symbol *symbols, const char *name); -/* elf_data must be aligned on a 32-bit boundary */ -int load_elf(symbol_resolver resolver, symbol_callback callback, void *elf_data, int elf_length, void *dest, int dest_length); - -#endif /* __ELF_LOADER_H */ diff --git a/soc/runtime/exception_jmp.S b/soc/runtime/exception_jmp.S deleted file mode 100644 index 014422960..000000000 --- a/soc/runtime/exception_jmp.S +++ /dev/null @@ -1,37 +0,0 @@ -.global exception_setjmp -.type exception_setjmp, @function -exception_setjmp: - l.sw 0(r3), r1 - l.sw 4(r3), r2 - l.sw 8(r3), r9 - l.sw 12(r3), r10 - l.sw 16(r3), r14 - l.sw 20(r3), r16 - l.sw 24(r3), r18 - l.sw 28(r3), r20 - l.sw 32(r3), r22 - l.sw 36(r3), r24 - l.sw 40(r3), r26 - l.sw 44(r3), r28 - l.sw 48(r3), r30 - l.jr r9 - l.ori r11, r0, 0 - -.global exception_longjmp -.type exception_longjmp, @function -exception_longjmp: - l.lwz r1, 0(r3) - l.lwz r2, 4(r3) - l.lwz r9, 8(r3) - l.lwz r10, 12(r3) - l.lwz r14, 16(r3) - l.lwz r16, 20(r3) - l.lwz r18, 24(r3) - l.lwz r20, 28(r3) - l.lwz r22, 32(r3) - l.lwz r24, 36(r3) - l.lwz r26, 40(r3) - l.lwz r28, 44(r3) - l.lwz r30, 48(r3) - l.jr r9 - l.ori r11, r0, 1 diff --git a/soc/runtime/exceptions.c b/soc/runtime/exceptions.c deleted file mode 100644 index 5c82f5c43..000000000 --- a/soc/runtime/exceptions.c +++ /dev/null @@ -1,58 +0,0 @@ -#include - -#include "log.h" -#include "exceptions.h" - -#define MAX_EXCEPTION_CONTEXTS 64 - -struct exception_context { - void *jb[13]; -}; - -static struct exception_context exception_contexts[MAX_EXCEPTION_CONTEXTS]; -static int ec_top; -static int stored_id; -static long long int stored_params[3]; - -void *exception_push(void) -{ - if(ec_top >= MAX_EXCEPTION_CONTEXTS) - exception_raise(EID_INTERNAL_ERROR); - return exception_contexts[ec_top++].jb; -} - -void exception_pop(int levels) -{ - ec_top -= levels; -} - -int exception_getid(long long int *eparams) -{ - int i; - - if(eparams) - for(i=0;i<3;i++) - eparams[i] = stored_params[i]; - return stored_id; -} - -void exception_raise(int id) -{ - exception_raise_params(id, 0, 0, 0); -} - -void exception_raise_params(int id, - long long int p0, long long int p1, - long long int p2) -{ - if(ec_top > 0) { - stored_id = id; - stored_params[0] = p0; - stored_params[1] = p1; - stored_params[2] = p2; - exception_longjmp(exception_contexts[--ec_top].jb); - } else { - log("ERROR: uncaught exception, ID=%d\n", id); - while(1); - } -} diff --git a/soc/runtime/exceptions.h b/soc/runtime/exceptions.h deleted file mode 100644 index 1c820c060..000000000 --- a/soc/runtime/exceptions.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef __EXCEPTIONS_H -#define __EXCEPTIONS_H - -enum { - EID_NONE = 0, - EID_INTERNAL_ERROR = 1, - EID_RPC_EXCEPTION = 2, - EID_RTIO_UNDERFLOW = 3, - EID_RTIO_SEQUENCE_ERROR = 4, - EID_RTIO_OVERFLOW = 5, - EID_DDS_BATCH_ERROR = 6, -}; - -int exception_setjmp(void *jb) __attribute__((returns_twice)); -void exception_longjmp(void *jb) __attribute__((noreturn)); - -void *exception_push(void); -void exception_pop(int levels); -int exception_getid(long long int *eparams); -void exception_raise(int id) __attribute__((noreturn)); -void exception_raise_params(int id, - long long int p0, long long int p1, - long long int p2) __attribute__((noreturn)); - -#endif /* __EXCEPTIONS_H */ diff --git a/soc/runtime/gen_service_table.py b/soc/runtime/gen_service_table.py deleted file mode 100755 index 27ae562b0..000000000 --- a/soc/runtime/gen_service_table.py +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env python3 - -import sys - -from elftools.elf.elffile import ELFFile - - -services = [ - ("syscalls", [ - ("now_init", "now_init"), - ("now_save", "now_save"), - - ("watchdog_set", "watchdog_set"), - ("watchdog_clear", "watchdog_clear"), - - ("rpc", "rpc"), - - ("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"), - ]), - - ("eh", [ - ("setjmp", "exception_setjmp"), - ("push", "exception_push"), - ("pop", "exception_pop"), - ("getid", "exception_getid"), - ("raise", "exception_raise"), - ]) -] - - -def print_service_table(ksupport_elf_filename): - with open(ksupport_elf_filename, "rb") as f: - elf = ELFFile(f) - symtab = elf.get_section_by_name(b".symtab") - symbols = {symbol.name: symbol.entry.st_value - for symbol in symtab.iter_symbols()} - for name, contents in services: - print("static const struct symbol {}[] = {{".format(name)) - for name, value in contents: - print(" {{\"{}\", (void *)0x{:08x}}}," - .format(name, symbols[bytes(value, "ascii")])) - print(" {NULL, NULL}") - print("};") - - -def main(): - if len(sys.argv) == 2: - print_service_table(sys.argv[1]) - else: - print("Incorrect number of command line arguments") - sys.exit(1) - -if __name__ == "__main__": - main() diff --git a/soc/runtime/kloader.c b/soc/runtime/kloader.c index 136fd7cbb..ea8e4f5df 100644 --- a/soc/runtime/kloader.c +++ b/soc/runtime/kloader.c @@ -1,120 +1,82 @@ #include #include +#include + +#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 symtab_init(void) +static void start_kernel_cpu(struct msg_load_request *msg) { - memset(symtab, 0, sizeof(symtab)); - _symtab_count = 0; - _symtab_strptr = _symtab_strings; + // 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 int symtab_add(const char *name, void *target) +void kloader_start_bridge() { - 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++; + start_kernel_cpu(NULL); +} - 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++; +static int load_or_start_kernel(void *library, const char *kernel) +{ + 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; } 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); + + return load_or_start_kernel(library, NULL); } -kernel_function kloader_find(const char *name) +int kloader_start_kernel(const char *name) { - return find_symbol(symtab, name); + return load_or_start_kernel(NULL, name); } -extern char _binary_ksupport_bin_start; -extern char _binary_ksupport_bin_end; - -static void start_kernel_cpu(void *addr) +int kloader_start_idle_kernel(void) { - 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) -{ - char buffer[32*1024]; - int len; - kernel_function k; - - 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); + char buffer[32*1024]; + int length; + + 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; } diff --git a/soc/runtime/kloader.h b/soc/runtime/kloader.h index ceefbc89d..08036456c 100644 --- a/soc/runtime/kloader.h +++ b/soc/runtime/kloader.h @@ -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); diff --git a/soc/runtime/ksupport.c b/soc/runtime/ksupport.c index 8e8677059..c7d465c26 100644 --- a/soc/runtime/ksupport.c +++ b/soc/runtime/ksupport.c @@ -1,67 +1,254 @@ #include +#include +#include -#include "exceptions.h" -#include "bridge.h" +#include +#include +#include +#include + +#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" +/* 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; -void exception_handler(unsigned long vect, unsigned long *sp); -void exception_handler(unsigned long vect, unsigned long *sp) +/* 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 = "", + .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 = "", + .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; + struct msg_load_request *msg = mailbox_receive(); - k = mailbox_receive(); - - if(k == NULL) + if(msg == NULL) { bridge_main(); - else { - jb = exception_push(); - if(exception_setjmp(jb)) { - struct msg_exception msg; + while(1); + } - 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); + 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, ...) diff --git a/soc/runtime/ksupport.h b/soc/runtime/ksupport.h new file mode 100644 index 000000000..b78f934f8 --- /dev/null +++ b/soc/runtime/ksupport.h @@ -0,0 +1,12 @@ +#ifndef __KSTARTUP_H +#define __KSTARTUP_H + +long long int now_init(void); +void now_save(long long int now); +int watchdog_set(int ms); +void watchdog_clear(int id); +int rpc(int rpc_num, ...); +void lognonl(const char *fmt, ...); +void log(const char *fmt, ...); + +#endif /* __KSTARTUP_H */ diff --git a/soc/runtime/ksupport.ld b/soc/runtime/ksupport.ld index 3cc585399..9f9ca4bb9 100644 --- a/soc/runtime/ksupport.ld +++ b/soc/runtime/ksupport.ld @@ -4,10 +4,10 @@ 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, @@ -15,6 +15,13 @@ MEMORY { */ 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 : @@ -22,7 +29,7 @@ SECTIONS _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 + } } diff --git a/soc/runtime/messages.h b/soc/runtime/messages.h index b0685105d..4b633a5d5 100644 --- a/soc/runtime/messages.h +++ b/soc/runtime/messages.h @@ -2,8 +2,10 @@ #define __MESSAGES_H #include +#include 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; }; diff --git a/soc/runtime/rtio.h b/soc/runtime/rtio.h index be1591554..4545d302c 100644 --- a/soc/runtime/rtio.h +++ b/soc/runtime/rtio.h @@ -2,7 +2,7 @@ #define __RTIO_H #include -#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); } } diff --git a/soc/runtime/linker.ld b/soc/runtime/runtime.ld similarity index 71% rename from soc/runtime/linker.ld rename to soc/runtime/runtime.ld index 4a4217f1e..dacfe535d 100644 --- a/soc/runtime/linker.ld +++ b/soc/runtime/runtime.ld @@ -10,6 +10,13 @@ MEMORY { runtime : ORIGIN = 0x40000000, LENGTH = 0x400000 /* 4M */ } +/* First 4M of main memory are reserved for runtime code/data + * then comes kernel memory. First 32K of kernel memory are for support code. + */ +MEMORY { + kernel : ORIGIN = 0x40400000, LENGTH = 0x8000 +} + /* Kernel memory space start right after the runtime, * and ends before the runtime stack. * Runtime stack is always at the end of main_ram. @@ -17,6 +24,11 @@ MEMORY { */ PROVIDE(_fstack = 0x40000000 + LENGTH(main_ram) - 4); +/* On AMP systems, kernel stack is at the end of main RAM, + * before the runtime stack. Leave 1M for runtime stack. + */ +PROVIDE(_kernel_fstack = 0x40000000 + LENGTH(main_ram) - 1024*1024 - 4); + SECTIONS { .text : @@ -58,6 +70,12 @@ SECTIONS . = ALIGN(4); _ebss = .; . = ALIGN(8); - _heapstart = .; } > runtime + + /DISCARD/ : + { + *(.eh_frame) + } + + _heapstart = .; } diff --git a/soc/runtime/services.c b/soc/runtime/services.c deleted file mode 100644 index 74bdeef71..000000000 --- a/soc/runtime/services.c +++ /dev/null @@ -1,78 +0,0 @@ -#include - -#include "elf_loader.h" -#include "session.h" -#include "clock.h" -#include "ttl.h" -#include "dds.h" -#include "exceptions.h" -#include "services.h" - -#include "service_table.h" - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wimplicit-int" -extern __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; -#pragma GCC diagnostic pop - -static const struct symbol 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}, - {NULL, NULL} -}; - -void *resolve_service_symbol(const char *name) -{ - if(strncmp(name, "__", 2) != 0) - return NULL; - name += 2; - if(strncmp(name, "syscall_", 8) == 0) - return find_symbol(syscalls, name + 8); - if(strncmp(name, "eh_", 3) == 0) - return find_symbol(eh, name + 3); - return find_symbol(compiler_rt, name); -} diff --git a/soc/runtime/services.h b/soc/runtime/services.h deleted file mode 100644 index 9c9dcf630..000000000 --- a/soc/runtime/services.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __SERVICES_H -#define __SERVICES_H - -void *resolve_service_symbol(const char *name); - -#endif /* __SERVICES_H */ diff --git a/soc/runtime/session.c b/soc/runtime/session.c index c0908639c..511cd8353 100644 --- a/soc/runtime/session.c +++ b/soc/runtime/session.c @@ -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) { diff --git a/soc/runtime/ttl.c b/soc/runtime/ttl.c index 387b977b1..577ab1eeb 100644 --- a/soc/runtime/ttl.c +++ b/soc/runtime/ttl.c @@ -1,6 +1,6 @@ #include -#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) {