forked from M-Labs/artiq
Implement core device storage (fixes #219).
This commit is contained in:
parent
1543141cee
commit
9366a29483
|
@ -37,6 +37,18 @@ class CompileError(Exception):
|
||||||
def rtio_get_counter() -> TInt64:
|
def rtio_get_counter() -> TInt64:
|
||||||
raise NotImplementedError("syscall not simulated")
|
raise NotImplementedError("syscall not simulated")
|
||||||
|
|
||||||
|
@syscall
|
||||||
|
def cache_get(TStr) -> TList(TInt32):
|
||||||
|
raise NotImplementedError("syscall not simulated")
|
||||||
|
|
||||||
|
@syscall
|
||||||
|
def cache_put(TStr, TList(TInt32)):
|
||||||
|
raise NotImplementedError("syscall not simulated")
|
||||||
|
|
||||||
|
@syscall
|
||||||
|
def cache_clear(TStr):
|
||||||
|
raise NotImplementedError("syscall not simulated")
|
||||||
|
|
||||||
class Core:
|
class Core:
|
||||||
"""Core device driver.
|
"""Core device driver.
|
||||||
|
|
||||||
|
@ -108,3 +120,15 @@ class Core:
|
||||||
min_now = rtio_get_counter() + 125000
|
min_now = rtio_get_counter() + 125000
|
||||||
if now_mu() < min_now:
|
if now_mu() < min_now:
|
||||||
at_mu(min_now)
|
at_mu(min_now)
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def get_cache(self, key):
|
||||||
|
return cache_get(key)
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def put_cache(self, key, value):
|
||||||
|
return cache_put(key, value)
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def clear_cache(self, key):
|
||||||
|
return cache_clear(key)
|
||||||
|
|
|
@ -7,7 +7,7 @@ from misoc.integration.soc_core import mem_decoder
|
||||||
|
|
||||||
class KernelCPU(Module):
|
class KernelCPU(Module):
|
||||||
def __init__(self, platform,
|
def __init__(self, platform,
|
||||||
exec_address=0x40800000,
|
exec_address=0x42000000,
|
||||||
main_mem_origin=0x40000000,
|
main_mem_origin=0x40000000,
|
||||||
l2_size=8192):
|
l2_size=8192):
|
||||||
self._reset = CSRStorage(reset=1)
|
self._reset = CSRStorage(reset=1)
|
||||||
|
|
|
@ -9,7 +9,8 @@ OBJECTS := isr.o clock.o rtiocrg.o flash_storage.o mailbox.o \
|
||||||
OBJECTS_KSUPPORT := ksupport.o artiq_personality.o mailbox.o \
|
OBJECTS_KSUPPORT := ksupport.o artiq_personality.o mailbox.o \
|
||||||
bridge.o rtio.o ttl.o dds.o
|
bridge.o rtio.o ttl.o dds.o
|
||||||
|
|
||||||
CFLAGS += -I$(MISOC_DIRECTORY)/software/include/dyld \
|
CFLAGS += -I$(LIBALLOC_DIRECTORY) \
|
||||||
|
-I$(MISOC_DIRECTORY)/software/include/dyld \
|
||||||
-I$(LIBDYLD_DIRECTORY)/include \
|
-I$(LIBDYLD_DIRECTORY)/include \
|
||||||
-I$(LIBUNWIND_DIRECTORY) \
|
-I$(LIBUNWIND_DIRECTORY) \
|
||||||
-I$(LIBUNWIND_DIRECTORY)/../unwinder/include \
|
-I$(LIBUNWIND_DIRECTORY)/../unwinder/include \
|
||||||
|
@ -31,10 +32,11 @@ runtime.elf: $(OBJECTS)
|
||||||
-N -o $@ \
|
-N -o $@ \
|
||||||
../libbase/crt0-$(CPU).o \
|
../libbase/crt0-$(CPU).o \
|
||||||
$(OBJECTS) \
|
$(OBJECTS) \
|
||||||
-L../libbase \
|
|
||||||
-L../libcompiler_rt \
|
-L../libcompiler_rt \
|
||||||
|
-L../libbase \
|
||||||
|
-L../liballoc \
|
||||||
-L../liblwip \
|
-L../liblwip \
|
||||||
-lbase -lcompiler_rt -llwip
|
-lbase -lcompiler_rt -lalloc -llwip
|
||||||
@chmod -x $@
|
@chmod -x $@
|
||||||
|
|
||||||
ksupport.elf: $(OBJECTS_KSUPPORT)
|
ksupport.elf: $(OBJECTS_KSUPPORT)
|
||||||
|
@ -48,7 +50,7 @@ ksupport.elf: $(OBJECTS_KSUPPORT)
|
||||||
-L../libcompiler_rt \
|
-L../libcompiler_rt \
|
||||||
-L../libunwind \
|
-L../libunwind \
|
||||||
-L../libdyld \
|
-L../libdyld \
|
||||||
-lbase -lcompiler_rt -lunwind -ldyld
|
-lbase -lcompiler_rt -ldyld -lunwind
|
||||||
@chmod -x $@
|
@chmod -x $@
|
||||||
|
|
||||||
ksupport_data.o: ksupport.elf
|
ksupport_data.o: ksupport.elf
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
|
|
||||||
#include "artiq_personality.h"
|
#include "artiq_personality.h"
|
||||||
|
|
||||||
#define KERNELCPU_EXEC_ADDRESS 0x40800000
|
#define KERNELCPU_EXEC_ADDRESS 0x42000000
|
||||||
#define KERNELCPU_PAYLOAD_ADDRESS 0x40820000
|
#define KERNELCPU_PAYLOAD_ADDRESS 0x42020000
|
||||||
#define KERNELCPU_LAST_ADDRESS (0x4fffffff - 1024*1024)
|
#define KERNELCPU_LAST_ADDRESS (0x4fffffff - 1024*1024)
|
||||||
#define KSUPPORT_HEADER_SIZE 0x80
|
#define KSUPPORT_HEADER_SIZE 0x80
|
||||||
|
|
||||||
|
|
|
@ -122,6 +122,10 @@ static const struct symbol runtime_exports[] = {
|
||||||
{"dds_batch_exit", &dds_batch_exit},
|
{"dds_batch_exit", &dds_batch_exit},
|
||||||
{"dds_set", &dds_set},
|
{"dds_set", &dds_set},
|
||||||
|
|
||||||
|
{"cache_get", &cache_get},
|
||||||
|
{"cache_put", &cache_put},
|
||||||
|
{"cache_clear", &cache_clear},
|
||||||
|
|
||||||
/* end */
|
/* end */
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
@ -444,6 +448,55 @@ void attribute_writeback(void *utypes) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct artiq_list cache_get(const char *key)
|
||||||
|
{
|
||||||
|
struct msg_cache_get_request request;
|
||||||
|
struct msg_cache_get_reply *reply;
|
||||||
|
|
||||||
|
request.type = MESSAGE_TYPE_CACHE_GET_REQUEST;
|
||||||
|
request.key = key;
|
||||||
|
mailbox_send_and_wait(&request);
|
||||||
|
|
||||||
|
reply = mailbox_wait_and_receive();
|
||||||
|
if(reply->type != MESSAGE_TYPE_CACHE_GET_REPLY) {
|
||||||
|
log("Malformed MESSAGE_TYPE_CACHE_GET_REQUEST reply type %d",
|
||||||
|
reply->type);
|
||||||
|
while(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (struct artiq_list) { reply->length, reply->elements };
|
||||||
|
}
|
||||||
|
|
||||||
|
void cache_put(const char *key, struct artiq_list value)
|
||||||
|
{
|
||||||
|
struct msg_cache_put_request request;
|
||||||
|
struct msg_cache_put_reply *reply;
|
||||||
|
|
||||||
|
request.type = MESSAGE_TYPE_CACHE_PUT_REQUEST;
|
||||||
|
request.key = key;
|
||||||
|
request.elements = value.elements;
|
||||||
|
request.length = value.length;
|
||||||
|
mailbox_send_and_wait(&request);
|
||||||
|
|
||||||
|
reply = mailbox_wait_and_receive();
|
||||||
|
if(reply->type != MESSAGE_TYPE_CACHE_PUT_REPLY) {
|
||||||
|
log("Malformed MESSAGE_TYPE_CACHE_PUT_REQUEST reply type %d",
|
||||||
|
reply->type);
|
||||||
|
while(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!reply->succeeded) {
|
||||||
|
artiq_raise_from_c("CacheError",
|
||||||
|
"cannot put into a busy cache row",
|
||||||
|
0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cache_clear(const char *key)
|
||||||
|
{
|
||||||
|
cache_put(key, (struct artiq_list) { 0, NULL });
|
||||||
|
}
|
||||||
|
|
||||||
void lognonl(const char *fmt, ...)
|
void lognonl(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
struct msg_log request;
|
struct msg_log request;
|
||||||
|
|
|
@ -1,12 +1,20 @@
|
||||||
#ifndef __KSTARTUP_H
|
#ifndef __KSTARTUP_H
|
||||||
#define __KSTARTUP_H
|
#define __KSTARTUP_H
|
||||||
|
|
||||||
|
struct artiq_list {
|
||||||
|
int32_t length;
|
||||||
|
int32_t *elements;
|
||||||
|
};
|
||||||
|
|
||||||
long long int now_init(void);
|
long long int now_init(void);
|
||||||
void now_save(long long int now);
|
void now_save(long long int now);
|
||||||
int watchdog_set(int ms);
|
int watchdog_set(int ms);
|
||||||
void watchdog_clear(int id);
|
void watchdog_clear(int id);
|
||||||
void send_rpc(int service, const char *tag, ...);
|
void send_rpc(int service, const char *tag, ...);
|
||||||
int recv_rpc(void *slot);
|
int recv_rpc(void *slot);
|
||||||
|
struct artiq_list cache_get(const char *key);
|
||||||
|
void cache_put(const char *key, struct artiq_list value);
|
||||||
|
void cache_clear(const char *key);
|
||||||
void lognonl(const char *fmt, ...);
|
void lognonl(const char *fmt, ...);
|
||||||
void log(const char *fmt, ...);
|
void log(const char *fmt, ...);
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,12 @@ ENTRY(_start)
|
||||||
|
|
||||||
INCLUDE generated/regions.ld
|
INCLUDE generated/regions.ld
|
||||||
|
|
||||||
/* First 8M of main memory are reserved for runtime code/data
|
/* First 32M of main memory are reserved for runtime
|
||||||
* then comes kernel memory. First 128K of kernel memory are for support code.
|
* code/data/heap, then comes kernel memory.
|
||||||
|
* First 128K of kernel memory are for support code.
|
||||||
*/
|
*/
|
||||||
MEMORY {
|
MEMORY {
|
||||||
ksupport (RWX) : ORIGIN = 0x40800000, LENGTH = 0x20000
|
ksupport (RWX) : ORIGIN = 0x42000000, LENGTH = 0x20000
|
||||||
}
|
}
|
||||||
|
|
||||||
/* On AMP systems, kernel stack is at the end of main RAM,
|
/* On AMP systems, kernel stack is at the end of main RAM,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <alloc.h>
|
||||||
#include <irq.h>
|
#include <irq.h>
|
||||||
#include <uart.h>
|
#include <uart.h>
|
||||||
#include <console.h>
|
#include <console.h>
|
||||||
|
@ -263,6 +264,8 @@ static int check_test_mode(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern void _fheap, _eheap;
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
irq_setmask(0);
|
irq_setmask(0);
|
||||||
|
@ -271,6 +274,7 @@ int main(void)
|
||||||
|
|
||||||
puts("ARTIQ runtime built "__DATE__" "__TIME__"\n");
|
puts("ARTIQ runtime built "__DATE__" "__TIME__"\n");
|
||||||
|
|
||||||
|
alloc_give(&_fheap, &_eheap - &_fheap);
|
||||||
clock_init();
|
clock_init();
|
||||||
rtiocrg_init();
|
rtiocrg_init();
|
||||||
puts("Press 't' to enter test mode...");
|
puts("Press 't' to enter test mode...");
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
MESSAGE_TYPE_LOAD_REPLY,
|
MESSAGE_TYPE_LOAD_REPLY,
|
||||||
|
@ -18,6 +19,10 @@ enum {
|
||||||
MESSAGE_TYPE_RPC_RECV_REQUEST,
|
MESSAGE_TYPE_RPC_RECV_REQUEST,
|
||||||
MESSAGE_TYPE_RPC_RECV_REPLY,
|
MESSAGE_TYPE_RPC_RECV_REPLY,
|
||||||
MESSAGE_TYPE_RPC_BATCH,
|
MESSAGE_TYPE_RPC_BATCH,
|
||||||
|
MESSAGE_TYPE_CACHE_GET_REQUEST,
|
||||||
|
MESSAGE_TYPE_CACHE_GET_REPLY,
|
||||||
|
MESSAGE_TYPE_CACHE_PUT_REQUEST,
|
||||||
|
MESSAGE_TYPE_CACHE_PUT_REPLY,
|
||||||
MESSAGE_TYPE_LOG,
|
MESSAGE_TYPE_LOG,
|
||||||
|
|
||||||
MESSAGE_TYPE_BRG_READY,
|
MESSAGE_TYPE_BRG_READY,
|
||||||
|
@ -105,6 +110,29 @@ struct msg_rpc_batch {
|
||||||
void *ptr;
|
void *ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct msg_cache_get_request {
|
||||||
|
int type;
|
||||||
|
const char *key;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct msg_cache_get_reply {
|
||||||
|
int type;
|
||||||
|
size_t length;
|
||||||
|
int32_t *elements;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct msg_cache_put_request {
|
||||||
|
int type;
|
||||||
|
const char *key;
|
||||||
|
size_t length;
|
||||||
|
int32_t *elements;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct msg_cache_put_reply {
|
||||||
|
int type;
|
||||||
|
int succeeded;
|
||||||
|
};
|
||||||
|
|
||||||
struct msg_log {
|
struct msg_log {
|
||||||
int type;
|
int type;
|
||||||
const char *fmt;
|
const char *fmt;
|
||||||
|
|
|
@ -7,7 +7,7 @@ INCLUDE generated/regions.ld
|
||||||
* ld does not allow this expression here.
|
* ld does not allow this expression here.
|
||||||
*/
|
*/
|
||||||
MEMORY {
|
MEMORY {
|
||||||
runtime : ORIGIN = 0x40000000, LENGTH = 0x800000 /* 8M */
|
runtime : ORIGIN = 0x40000000, LENGTH = 0x2000000 /* 32M */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Kernel memory space start right after the runtime,
|
/* Kernel memory space start right after the runtime,
|
||||||
|
@ -65,5 +65,7 @@ SECTIONS
|
||||||
*(.eh_frame)
|
*(.eh_frame)
|
||||||
}
|
}
|
||||||
|
|
||||||
_heapstart = .;
|
_fheap = .;
|
||||||
|
. += 0x1800000;
|
||||||
|
_eheap = .;
|
||||||
}
|
}
|
||||||
|
|
|
@ -908,6 +908,16 @@ static int send_rpc_request(int service, const char *tag, va_list args)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct cache_row {
|
||||||
|
struct cache_row *next;
|
||||||
|
char *key;
|
||||||
|
size_t length;
|
||||||
|
int32_t *elements;
|
||||||
|
int borrowed;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct cache_row *cache;
|
||||||
|
|
||||||
/* assumes output buffer is empty when called */
|
/* assumes output buffer is empty when called */
|
||||||
static int process_kmsg(struct msg_base *umsg)
|
static int process_kmsg(struct msg_base *umsg)
|
||||||
{
|
{
|
||||||
|
@ -984,6 +994,60 @@ static int process_kmsg(struct msg_base *umsg)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case MESSAGE_TYPE_CACHE_GET_REQUEST: {
|
||||||
|
struct msg_cache_get_request *request = (struct msg_cache_get_request *)umsg;
|
||||||
|
struct msg_cache_get_reply reply;
|
||||||
|
|
||||||
|
reply.type = MESSAGE_TYPE_CACHE_GET_REPLY;
|
||||||
|
reply.length = 0;
|
||||||
|
reply.elements = NULL;
|
||||||
|
|
||||||
|
for(struct cache_row *iter = cache; iter; iter = iter->next) {
|
||||||
|
if(!strcmp(iter->key, request->key)) {
|
||||||
|
reply.length = iter->length;
|
||||||
|
reply.elements = iter->elements;
|
||||||
|
iter->borrowed = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mailbox_send(&reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
case MESSAGE_TYPE_CACHE_PUT_REQUEST: {
|
||||||
|
struct msg_cache_put_request *request = (struct msg_cache_put_request *)umsg;
|
||||||
|
struct msg_cache_put_reply reply;
|
||||||
|
|
||||||
|
reply.type = MESSAGE_TYPE_CACHE_PUT_REPLY;
|
||||||
|
|
||||||
|
struct cache_row *row = NULL;
|
||||||
|
for(struct cache_row *iter = cache; iter; iter = iter->next) {
|
||||||
|
if(!strcmp(iter->key, request->key)) {
|
||||||
|
free(iter->elements);
|
||||||
|
row = iter;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!row) {
|
||||||
|
struct cache_row *row = calloc(1, sizeof(struct cache_row));
|
||||||
|
row->key = calloc(strlen(request->key) + 1, 1);
|
||||||
|
strcpy(row->key, request->key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!row->borrowed) {
|
||||||
|
row->length = request->length;
|
||||||
|
row->elements = calloc(row->length, sizeof(int32_t));
|
||||||
|
memcpy(row->elements, request->elements,
|
||||||
|
sizeof(int32_t) * row->length);
|
||||||
|
reply.succeeded = 1;
|
||||||
|
} else {
|
||||||
|
reply.succeeded = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mailbox_send(&reply);
|
||||||
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
log("Received invalid message type %d from kernel CPU",
|
log("Received invalid message type %d from kernel CPU",
|
||||||
umsg->type);
|
umsg->type);
|
||||||
|
|
Loading…
Reference in New Issue