Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/artiq
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: c6a57d20435d
Choose a base ref
...
head repository: m-labs/artiq
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 1cbb187136be
Choose a head ref
  • 2 commits
  • 6 files changed
  • 1 contributor

Commits on Sep 30, 2016

  1. Copy the full SHA
    7cfa667 View commit details
  2. runtime: eliminate va_list from kernel interface.

    whitequark committed Sep 30, 2016
    Copy the full SHA
    1cbb187 View commit details
Showing with 91 additions and 76 deletions.
  1. +9 −5 artiq/compiler/transforms/llvm_ir_generator.py
  2. +18 −24 artiq/runtime/kloader.c
  3. +50 −38 artiq/runtime/ksupport.c
  4. +1 −1 artiq/runtime/ksupport.h
  5. +5 −5 artiq/runtime/messages.h
  6. +8 −3 artiq/runtime/session.c
14 changes: 9 additions & 5 deletions artiq/compiler/transforms/llvm_ir_generator.py
Original file line number Diff line number Diff line change
@@ -19,6 +19,7 @@
lli64 = ll.IntType(64)
lldouble = ll.DoubleType()
llptr = ll.IntType(8).as_pointer()
llptrptr = ll.IntType(8).as_pointer().as_pointer()
llmetadata = ll.MetaData()


@@ -349,8 +350,7 @@ def llbuiltin(self, name):
elif name == "strcmp":
llty = ll.FunctionType(lli32, [llptr, llptr])
elif name == "send_rpc":
llty = ll.FunctionType(llvoid, [lli32, llptr],
var_arg=True)
llty = ll.FunctionType(llvoid, [lli32, llptr, llptrptr])
elif name == "recv_rpc":
llty = ll.FunctionType(lli32, [llptr])
elif name == "now":
@@ -1233,7 +1233,8 @@ def ret_error_handler(typ):
llstackptr = self.llbuilder.call(self.llbuiltin("llvm.stacksave"), [],
name="rpc.stack")

llargs = []
llargs = self.llbuilder.alloca(llptr, ll.Constant(lli32, len(args)),
name="rpc.args")
for index, arg in enumerate(args):
if builtins.is_none(arg.type):
llargslot = self.llbuilder.alloca(ll.LiteralStructType([]),
@@ -1243,10 +1244,13 @@ def ret_error_handler(typ):
llargslot = self.llbuilder.alloca(llarg.type,
name="rpc.arg{}".format(index))
self.llbuilder.store(llarg, llargslot)
llargs.append(llargslot)
llargslot = self.llbuilder.bitcast(llargslot, llptr)

llargptr = self.llbuilder.gep(llargs, [ll.Constant(lli32, index)])
self.llbuilder.store(llargslot, llargptr)

self.llbuilder.call(self.llbuiltin("send_rpc"),
[llservice, lltag] + llargs)
[llservice, lltag, llargs])

# Don't waste stack space on saved arguments.
self.llbuilder.call(self.llbuiltin("llvm.stackrestore"), [llstackptr])
42 changes: 18 additions & 24 deletions artiq/runtime/kloader.c
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
#include <string.h>
#include <generated/csr.h>

#include <dyld.h>

#include "kloader.h"
#include "log.h"
#include "clock.h"
#include "flash_storage.h"
#include "mailbox.h"
#include "messages.h"

static void start_kernel_cpu(struct msg_load_request *msg)
int kloader_load_library(const void *library)
{
if(!kernel_cpu_reset_read()) {
core_log("BUG: attempted to load kernel library while kernel CPU is running\n");
return 0;
}

// Stop kernel CPU before messing with its code.
kernel_cpu_reset_write(1);

@@ -22,22 +25,15 @@ static void start_kernel_cpu(struct msg_load_request *msg)
&_binary_ksupport_elf_end - &_binary_ksupport_elf_start);

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

static int load_or_start_kernel(const void *library, int run_kernel)
{
static struct dyld_info library_info;
struct msg_load_request request = {
.library = library,
.library_info = &library_info,
.run_kernel = run_kernel,
.type = MESSAGE_TYPE_LOAD_REQUEST,
.library = library,
};
start_kernel_cpu(&request);
mailbox_send(&request);

struct msg_load_reply *reply = mailbox_wait_and_receive();
mailbox_acknowledge();

if(reply->type != MESSAGE_TYPE_LOAD_REPLY) {
core_log("BUG: unexpected reply to load/run request\n");
@@ -52,14 +48,14 @@ static int load_or_start_kernel(const void *library, int run_kernel)
return 1;
}

int kloader_load_library(const void *library)
void kloader_start_kernel()
{
if(!kernel_cpu_reset_read()) {
core_log("BUG: attempted to load kernel library while kernel CPU is running\n");
return 0;
if(kernel_cpu_reset_read()) {
core_log("BUG: attempted to load kernel library while kernel CPU is stopped\n");
return;
}

return load_or_start_kernel(library, 0);
mailbox_acknowledge();
}

void kloader_filter_backtrace(struct artiq_backtrace_item *backtrace,
@@ -78,11 +74,6 @@ void kloader_filter_backtrace(struct artiq_backtrace_item *backtrace,
*backtrace_size = cursor - backtrace;
}

void kloader_start_kernel()
{
load_or_start_kernel(NULL, 1);
}

static int kloader_start_flash_kernel(char *key)
{
#if (defined CSR_SPIFLASH_BASE && defined CONFIG_SPIFLASH_PAGE_SIZE)
@@ -98,7 +89,10 @@ static int kloader_start_flash_kernel(char *key)
return 0;
}

return load_or_start_kernel(buffer, 1);
if(!kloader_load_library(buffer))
return 0;
kloader_start_kernel();
return 1;
#else
return 0;
#endif
88 changes: 50 additions & 38 deletions artiq/runtime/ksupport.c
Original file line number Diff line number Diff line change
@@ -272,13 +272,19 @@ double sqrt(double x)
/* called by libunwind */
int fprintf(FILE *stream, const char *fmt, ...)
{
struct msg_log request;
va_list args;
va_start(args, fmt);

char buf[256];
int len = vscnprintf(buf, sizeof(buf), fmt, args);

va_end(args);

struct msg_log request;
request.type = MESSAGE_TYPE_LOG;
request.fmt = fmt;
va_start(request.args, fmt);
request.buf = buf;
request.len = len;
mailbox_send_and_wait(&request);
va_end(request.args);

return 0;
}
@@ -370,43 +376,39 @@ static void now_save(void)
int main(void);
int main(void)
{
struct msg_load_request *request = mailbox_receive();
static struct dyld_info library_info;

struct msg_load_request *request = mailbox_wait_and_receive();
struct msg_load_reply load_reply = {
.type = MESSAGE_TYPE_LOAD_REPLY,
.error = NULL
};

if(request->library != NULL) {
if(!dyld_load(request->library, KERNELCPU_PAYLOAD_ADDRESS,
resolve_runtime_export, request->library_info,
&load_reply.error)) {
mailbox_send(&load_reply);
while(1);
}

void *__bss_start = dyld_lookup("__bss_start", request->library_info);
void *_end = dyld_lookup("_end", request->library_info);
memset(__bss_start, 0, _end - __bss_start);
if(!dyld_load(request->library, KERNELCPU_PAYLOAD_ADDRESS,
resolve_runtime_export, &library_info,
&load_reply.error)) {
mailbox_send(&load_reply);
while(1);
}

if(request->run_kernel) {
void (*kernel_run)() = request->library_info->init;
void *typeinfo = dyld_lookup("typeinfo", request->library_info);
void *__bss_start = dyld_lookup("__bss_start", &library_info);
void *_end = dyld_lookup("_end", &library_info);
memset(__bss_start, 0, _end - __bss_start);

mailbox_send_and_wait(&load_reply);
void (*kernel_run)() = library_info.init;
void *typeinfo = dyld_lookup("typeinfo", &library_info);

now_init();
kernel_run();
now_save();
mailbox_send_and_wait(&load_reply);

attribute_writeback(typeinfo);
now_init();
kernel_run();
now_save();

struct msg_base finished_reply;
finished_reply.type = MESSAGE_TYPE_FINISHED;
mailbox_send_and_wait(&finished_reply);
} else {
mailbox_send(&load_reply);
}
attribute_writeback(typeinfo);

struct msg_base finished_reply;
finished_reply.type = MESSAGE_TYPE_FINISHED;
mailbox_send_and_wait(&finished_reply);

while(1);
}
@@ -466,7 +468,7 @@ void watchdog_clear(int id)
mailbox_send_and_wait(&request);
}

void send_rpc(int service, const char *tag, ...)
void send_rpc(int service, const char *tag, void **data)
{
struct msg_rpc_send request;

@@ -476,9 +478,8 @@ void send_rpc(int service, const char *tag, ...)
request.type = MESSAGE_TYPE_RPC_BATCH;
request.service = service;
request.tag = tag;
va_start(request.args, tag);
request.data = data;
mailbox_send_and_wait(&request);
va_end(request.args);
}

int recv_rpc(void *slot)
@@ -541,7 +542,12 @@ void attribute_writeback(void *utypes)

if(attr->tag) {
uintptr_t value = (uintptr_t)object + attr->offset;
send_rpc(0, attr->tag, &object, &attr->name, value);
void *args[] = {
&object,
&attr->name,
(void*)value
};
send_rpc(0, attr->tag, args);
}
}
}
@@ -594,11 +600,17 @@ void cache_put(const char *key, struct artiq_list value)

void core_log(const char *fmt, ...)
{
struct msg_log request;
va_list args;
va_start(args, fmt);

char buf[256];
int len = vscnprintf(buf, sizeof(buf), fmt, args);

va_end(args);

struct msg_log request;
request.type = MESSAGE_TYPE_LOG;
request.fmt = fmt;
va_start(request.args, fmt);
request.buf = buf;
request.len = len;
mailbox_send_and_wait(&request);
va_end(request.args);
}
2 changes: 1 addition & 1 deletion artiq/runtime/ksupport.h
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ struct artiq_list {

int watchdog_set(int ms);
void watchdog_clear(int id);
void send_rpc(int service, const char *tag, ...);
void send_rpc(int service, const char *tag, void **data);
int recv_rpc(void *slot);
struct artiq_list cache_get(const char *key);
void cache_put(const char *key, struct artiq_list value);
10 changes: 5 additions & 5 deletions artiq/runtime/messages.h
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@
#include <stdint.h>

enum {
MESSAGE_TYPE_LOAD_REQUEST,
MESSAGE_TYPE_LOAD_REPLY,
MESSAGE_TYPE_NOW_INIT_REQUEST,
MESSAGE_TYPE_NOW_INIT_REPLY,
@@ -33,9 +34,8 @@ struct msg_base {
/* kernel messages */

struct msg_load_request {
int type;
const void *library;
struct dyld_info *library_info;
int run_kernel;
};

struct msg_load_reply {
@@ -79,7 +79,7 @@ struct msg_rpc_send {
int type;
int service;
const char *tag;
va_list args;
void **data;
};

struct msg_rpc_recv_request {
@@ -118,8 +118,8 @@ struct msg_cache_put_reply {

struct msg_log {
int type;
const char *fmt;
va_list args;
const char *buf;
size_t len;
};

#endif /* __MESSAGES_H */
11 changes: 8 additions & 3 deletions artiq/runtime/session.c
Original file line number Diff line number Diff line change
@@ -893,13 +893,13 @@ static int send_rpc_value(const char **tag, void **value)
return 1;
}

static int send_rpc_request(int service, const char *tag, va_list args)
static int send_rpc_request(int service, const char *tag, void **data)
{
out_packet_start(REMOTEMSG_TYPE_RPC_REQUEST);
out_packet_int32(service);

while(*tag != ':') {
void *value = va_arg(args, void*);
void *value = *data++;
if(!kloader_validate_kpointer(value))
return 0;
if(!send_rpc_value(&tag, &value))
@@ -929,6 +929,11 @@ static int process_kmsg(struct msg_base *umsg)
return 0;
if(kloader_is_essential_kmsg(umsg->type))
return 1; /* handled elsewhere */
if(user_kernel_state == USER_KERNEL_LOADED &&
umsg->type == MESSAGE_TYPE_LOAD_REPLY) {
// Kernel standing by.
return 1;
}
if(user_kernel_state == USER_KERNEL_WAIT_RPC &&
umsg->type == MESSAGE_TYPE_RPC_RECV_REQUEST) {
// Handled and acknowledged when we receive
@@ -989,7 +994,7 @@ static int process_kmsg(struct msg_base *umsg)
case MESSAGE_TYPE_RPC_BATCH: {
struct msg_rpc_send *msg = (struct msg_rpc_send *)umsg;

if(!send_rpc_request(msg->service, msg->tag, msg->args)) {
if(!send_rpc_request(msg->service, msg->tag, msg->data)) {
core_log("Failed to send RPC request (service %d, tag %s)\n",
msg->service, msg->tag);
return 0; // restart session