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:
|
||||
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:
|
||||
"""Core device driver.
|
||||
|
||||
|
@ -108,3 +120,15 @@ class Core:
|
|||
min_now = rtio_get_counter() + 125000
|
||||
if now_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):
|
||||
def __init__(self, platform,
|
||||
exec_address=0x40800000,
|
||||
exec_address=0x42000000,
|
||||
main_mem_origin=0x40000000,
|
||||
l2_size=8192):
|
||||
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 \
|
||||
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$(LIBUNWIND_DIRECTORY) \
|
||||
-I$(LIBUNWIND_DIRECTORY)/../unwinder/include \
|
||||
|
@ -31,10 +32,11 @@ runtime.elf: $(OBJECTS)
|
|||
-N -o $@ \
|
||||
../libbase/crt0-$(CPU).o \
|
||||
$(OBJECTS) \
|
||||
-L../libbase \
|
||||
-L../libcompiler_rt \
|
||||
-L../libbase \
|
||||
-L../liballoc \
|
||||
-L../liblwip \
|
||||
-lbase -lcompiler_rt -llwip
|
||||
-lbase -lcompiler_rt -lalloc -llwip
|
||||
@chmod -x $@
|
||||
|
||||
ksupport.elf: $(OBJECTS_KSUPPORT)
|
||||
|
@ -48,7 +50,7 @@ ksupport.elf: $(OBJECTS_KSUPPORT)
|
|||
-L../libcompiler_rt \
|
||||
-L../libunwind \
|
||||
-L../libdyld \
|
||||
-lbase -lcompiler_rt -lunwind -ldyld
|
||||
-lbase -lcompiler_rt -ldyld -lunwind
|
||||
@chmod -x $@
|
||||
|
||||
ksupport_data.o: ksupport.elf
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
#include "artiq_personality.h"
|
||||
|
||||
#define KERNELCPU_EXEC_ADDRESS 0x40800000
|
||||
#define KERNELCPU_PAYLOAD_ADDRESS 0x40820000
|
||||
#define KERNELCPU_EXEC_ADDRESS 0x42000000
|
||||
#define KERNELCPU_PAYLOAD_ADDRESS 0x42020000
|
||||
#define KERNELCPU_LAST_ADDRESS (0x4fffffff - 1024*1024)
|
||||
#define KSUPPORT_HEADER_SIZE 0x80
|
||||
|
||||
|
|
|
@ -122,6 +122,10 @@ static const struct symbol runtime_exports[] = {
|
|||
{"dds_batch_exit", &dds_batch_exit},
|
||||
{"dds_set", &dds_set},
|
||||
|
||||
{"cache_get", &cache_get},
|
||||
{"cache_put", &cache_put},
|
||||
{"cache_clear", &cache_clear},
|
||||
|
||||
/* end */
|
||||
{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, ...)
|
||||
{
|
||||
struct msg_log request;
|
||||
|
|
|
@ -1,12 +1,20 @@
|
|||
#ifndef __KSTARTUP_H
|
||||
#define __KSTARTUP_H
|
||||
|
||||
struct artiq_list {
|
||||
int32_t length;
|
||||
int32_t *elements;
|
||||
};
|
||||
|
||||
long long int now_init(void);
|
||||
void now_save(long long int now);
|
||||
int watchdog_set(int ms);
|
||||
void watchdog_clear(int id);
|
||||
void send_rpc(int service, const char *tag, ...);
|
||||
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 log(const char *fmt, ...);
|
||||
|
||||
|
|
|
@ -3,11 +3,12 @@ ENTRY(_start)
|
|||
|
||||
INCLUDE generated/regions.ld
|
||||
|
||||
/* First 8M of main memory are reserved for runtime code/data
|
||||
* then comes kernel memory. First 128K of kernel memory are for support code.
|
||||
/* First 32M of main memory are reserved for runtime
|
||||
* code/data/heap, then comes kernel memory.
|
||||
* First 128K of kernel memory are for support code.
|
||||
*/
|
||||
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,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <alloc.h>
|
||||
#include <irq.h>
|
||||
#include <uart.h>
|
||||
#include <console.h>
|
||||
|
@ -263,6 +264,8 @@ static int check_test_mode(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
extern void _fheap, _eheap;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
irq_setmask(0);
|
||||
|
@ -271,6 +274,7 @@ int main(void)
|
|||
|
||||
puts("ARTIQ runtime built "__DATE__" "__TIME__"\n");
|
||||
|
||||
alloc_give(&_fheap, &_eheap - &_fheap);
|
||||
clock_init();
|
||||
rtiocrg_init();
|
||||
puts("Press 't' to enter test mode...");
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
enum {
|
||||
MESSAGE_TYPE_LOAD_REPLY,
|
||||
|
@ -18,6 +19,10 @@ enum {
|
|||
MESSAGE_TYPE_RPC_RECV_REQUEST,
|
||||
MESSAGE_TYPE_RPC_RECV_REPLY,
|
||||
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_BRG_READY,
|
||||
|
@ -105,6 +110,29 @@ struct msg_rpc_batch {
|
|||
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 {
|
||||
int type;
|
||||
const char *fmt;
|
||||
|
|
|
@ -7,7 +7,7 @@ INCLUDE generated/regions.ld
|
|||
* ld does not allow this expression here.
|
||||
*/
|
||||
MEMORY {
|
||||
runtime : ORIGIN = 0x40000000, LENGTH = 0x800000 /* 8M */
|
||||
runtime : ORIGIN = 0x40000000, LENGTH = 0x2000000 /* 32M */
|
||||
}
|
||||
|
||||
/* Kernel memory space start right after the runtime,
|
||||
|
@ -65,5 +65,7 @@ SECTIONS
|
|||
*(.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;
|
||||
}
|
||||
|
||||
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 */
|
||||
static int process_kmsg(struct msg_base *umsg)
|
||||
{
|
||||
|
@ -984,6 +994,60 @@ static int process_kmsg(struct msg_base *umsg)
|
|||
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: {
|
||||
log("Received invalid message type %d from kernel CPU",
|
||||
umsg->type);
|
||||
|
|
Loading…
Reference in New Issue