Skip to content

Commit 9366a29

Browse files
author
whitequark
committedJan 10, 2016
Implement core device storage (fixes #219).
1 parent 1543141 commit 9366a29

File tree

11 files changed

+198
-12
lines changed

11 files changed

+198
-12
lines changed
 

Diff for: ‎artiq/coredevice/core.py

+24
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,18 @@ def __str__(self):
3737
def rtio_get_counter() -> TInt64:
3838
raise NotImplementedError("syscall not simulated")
3939

40+
@syscall
41+
def cache_get(TStr) -> TList(TInt32):
42+
raise NotImplementedError("syscall not simulated")
43+
44+
@syscall
45+
def cache_put(TStr, TList(TInt32)):
46+
raise NotImplementedError("syscall not simulated")
47+
48+
@syscall
49+
def cache_clear(TStr):
50+
raise NotImplementedError("syscall not simulated")
51+
4052
class Core:
4153
"""Core device driver.
4254
@@ -108,3 +120,15 @@ def break_realtime(self):
108120
min_now = rtio_get_counter() + 125000
109121
if now_mu() < min_now:
110122
at_mu(min_now)
123+
124+
@kernel
125+
def get_cache(self, key):
126+
return cache_get(key)
127+
128+
@kernel
129+
def put_cache(self, key, value):
130+
return cache_put(key, value)
131+
132+
@kernel
133+
def clear_cache(self, key):
134+
return cache_clear(key)

Diff for: ‎artiq/gateware/amp/kernel_cpu.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
class KernelCPU(Module):
99
def __init__(self, platform,
10-
exec_address=0x40800000,
10+
exec_address=0x42000000,
1111
main_mem_origin=0x40000000,
1212
l2_size=8192):
1313
self._reset = CSRStorage(reset=1)

Diff for: ‎artiq/runtime/Makefile

+6-4
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ OBJECTS := isr.o clock.o rtiocrg.o flash_storage.o mailbox.o \
99
OBJECTS_KSUPPORT := ksupport.o artiq_personality.o mailbox.o \
1010
bridge.o rtio.o ttl.o dds.o
1111

12-
CFLAGS += -I$(MISOC_DIRECTORY)/software/include/dyld \
12+
CFLAGS += -I$(LIBALLOC_DIRECTORY) \
13+
-I$(MISOC_DIRECTORY)/software/include/dyld \
1314
-I$(LIBDYLD_DIRECTORY)/include \
1415
-I$(LIBUNWIND_DIRECTORY) \
1516
-I$(LIBUNWIND_DIRECTORY)/../unwinder/include \
@@ -31,10 +32,11 @@ runtime.elf: $(OBJECTS)
3132
-N -o $@ \
3233
../libbase/crt0-$(CPU).o \
3334
$(OBJECTS) \
34-
-L../libbase \
3535
-L../libcompiler_rt \
36+
-L../libbase \
37+
-L../liballoc \
3638
-L../liblwip \
37-
-lbase -lcompiler_rt -llwip
39+
-lbase -lcompiler_rt -lalloc -llwip
3840
@chmod -x $@
3941

4042
ksupport.elf: $(OBJECTS_KSUPPORT)
@@ -48,7 +50,7 @@ ksupport.elf: $(OBJECTS_KSUPPORT)
4850
-L../libcompiler_rt \
4951
-L../libunwind \
5052
-L../libdyld \
51-
-lbase -lcompiler_rt -lunwind -ldyld
53+
-lbase -lcompiler_rt -ldyld -lunwind
5254
@chmod -x $@
5355

5456
ksupport_data.o: ksupport.elf

Diff for: ‎artiq/runtime/kloader.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33

44
#include "artiq_personality.h"
55

6-
#define KERNELCPU_EXEC_ADDRESS 0x40800000
7-
#define KERNELCPU_PAYLOAD_ADDRESS 0x40820000
6+
#define KERNELCPU_EXEC_ADDRESS 0x42000000
7+
#define KERNELCPU_PAYLOAD_ADDRESS 0x42020000
88
#define KERNELCPU_LAST_ADDRESS (0x4fffffff - 1024*1024)
99
#define KSUPPORT_HEADER_SIZE 0x80
1010

Diff for: ‎artiq/runtime/ksupport.c

+53
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ static const struct symbol runtime_exports[] = {
122122
{"dds_batch_exit", &dds_batch_exit},
123123
{"dds_set", &dds_set},
124124

125+
{"cache_get", &cache_get},
126+
{"cache_put", &cache_put},
127+
{"cache_clear", &cache_clear},
128+
125129
/* end */
126130
{NULL, NULL}
127131
};
@@ -444,6 +448,55 @@ void attribute_writeback(void *utypes) {
444448
}
445449
}
446450

451+
struct artiq_list cache_get(const char *key)
452+
{
453+
struct msg_cache_get_request request;
454+
struct msg_cache_get_reply *reply;
455+
456+
request.type = MESSAGE_TYPE_CACHE_GET_REQUEST;
457+
request.key = key;
458+
mailbox_send_and_wait(&request);
459+
460+
reply = mailbox_wait_and_receive();
461+
if(reply->type != MESSAGE_TYPE_CACHE_GET_REPLY) {
462+
log("Malformed MESSAGE_TYPE_CACHE_GET_REQUEST reply type %d",
463+
reply->type);
464+
while(1);
465+
}
466+
467+
return (struct artiq_list) { reply->length, reply->elements };
468+
}
469+
470+
void cache_put(const char *key, struct artiq_list value)
471+
{
472+
struct msg_cache_put_request request;
473+
struct msg_cache_put_reply *reply;
474+
475+
request.type = MESSAGE_TYPE_CACHE_PUT_REQUEST;
476+
request.key = key;
477+
request.elements = value.elements;
478+
request.length = value.length;
479+
mailbox_send_and_wait(&request);
480+
481+
reply = mailbox_wait_and_receive();
482+
if(reply->type != MESSAGE_TYPE_CACHE_PUT_REPLY) {
483+
log("Malformed MESSAGE_TYPE_CACHE_PUT_REQUEST reply type %d",
484+
reply->type);
485+
while(1);
486+
}
487+
488+
if(!reply->succeeded) {
489+
artiq_raise_from_c("CacheError",
490+
"cannot put into a busy cache row",
491+
0, 0, 0);
492+
}
493+
}
494+
495+
void cache_clear(const char *key)
496+
{
497+
cache_put(key, (struct artiq_list) { 0, NULL });
498+
}
499+
447500
void lognonl(const char *fmt, ...)
448501
{
449502
struct msg_log request;

Diff for: ‎artiq/runtime/ksupport.h

+8
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
11
#ifndef __KSTARTUP_H
22
#define __KSTARTUP_H
33

4+
struct artiq_list {
5+
int32_t length;
6+
int32_t *elements;
7+
};
8+
49
long long int now_init(void);
510
void now_save(long long int now);
611
int watchdog_set(int ms);
712
void watchdog_clear(int id);
813
void send_rpc(int service, const char *tag, ...);
914
int recv_rpc(void *slot);
15+
struct artiq_list cache_get(const char *key);
16+
void cache_put(const char *key, struct artiq_list value);
17+
void cache_clear(const char *key);
1018
void lognonl(const char *fmt, ...);
1119
void log(const char *fmt, ...);
1220

Diff for: ‎artiq/runtime/ksupport.ld

+4-3
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ ENTRY(_start)
33

44
INCLUDE generated/regions.ld
55

6-
/* First 8M of main memory are reserved for runtime code/data
7-
* then comes kernel memory. First 128K of kernel memory are for support code.
6+
/* First 32M of main memory are reserved for runtime
7+
* code/data/heap, then comes kernel memory.
8+
* First 128K of kernel memory are for support code.
89
*/
910
MEMORY {
10-
ksupport (RWX) : ORIGIN = 0x40800000, LENGTH = 0x20000
11+
ksupport (RWX) : ORIGIN = 0x42000000, LENGTH = 0x20000
1112
}
1213

1314
/* On AMP systems, kernel stack is at the end of main RAM,

Diff for: ‎artiq/runtime/main.c

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <stdio.h>
22
#include <string.h>
3+
#include <alloc.h>
34
#include <irq.h>
45
#include <uart.h>
56
#include <console.h>
@@ -263,6 +264,8 @@ static int check_test_mode(void)
263264
return 0;
264265
}
265266

267+
extern void _fheap, _eheap;
268+
266269
int main(void)
267270
{
268271
irq_setmask(0);
@@ -271,6 +274,7 @@ int main(void)
271274

272275
puts("ARTIQ runtime built "__DATE__" "__TIME__"\n");
273276

277+
alloc_give(&_fheap, &_eheap - &_fheap);
274278
clock_init();
275279
rtiocrg_init();
276280
puts("Press 't' to enter test mode...");

Diff for: ‎artiq/runtime/messages.h

+28
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include <stdarg.h>
55
#include <stddef.h>
6+
#include <stdint.h>
67

78
enum {
89
MESSAGE_TYPE_LOAD_REPLY,
@@ -18,6 +19,10 @@ enum {
1819
MESSAGE_TYPE_RPC_RECV_REQUEST,
1920
MESSAGE_TYPE_RPC_RECV_REPLY,
2021
MESSAGE_TYPE_RPC_BATCH,
22+
MESSAGE_TYPE_CACHE_GET_REQUEST,
23+
MESSAGE_TYPE_CACHE_GET_REPLY,
24+
MESSAGE_TYPE_CACHE_PUT_REQUEST,
25+
MESSAGE_TYPE_CACHE_PUT_REPLY,
2126
MESSAGE_TYPE_LOG,
2227

2328
MESSAGE_TYPE_BRG_READY,
@@ -105,6 +110,29 @@ struct msg_rpc_batch {
105110
void *ptr;
106111
};
107112

113+
struct msg_cache_get_request {
114+
int type;
115+
const char *key;
116+
};
117+
118+
struct msg_cache_get_reply {
119+
int type;
120+
size_t length;
121+
int32_t *elements;
122+
};
123+
124+
struct msg_cache_put_request {
125+
int type;
126+
const char *key;
127+
size_t length;
128+
int32_t *elements;
129+
};
130+
131+
struct msg_cache_put_reply {
132+
int type;
133+
int succeeded;
134+
};
135+
108136
struct msg_log {
109137
int type;
110138
const char *fmt;

Diff for: ‎artiq/runtime/runtime.ld

+4-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ INCLUDE generated/regions.ld
77
* ld does not allow this expression here.
88
*/
99
MEMORY {
10-
runtime : ORIGIN = 0x40000000, LENGTH = 0x800000 /* 8M */
10+
runtime : ORIGIN = 0x40000000, LENGTH = 0x2000000 /* 32M */
1111
}
1212

1313
/* Kernel memory space start right after the runtime,
@@ -65,5 +65,7 @@ SECTIONS
6565
*(.eh_frame)
6666
}
6767

68-
_heapstart = .;
68+
_fheap = .;
69+
. += 0x1800000;
70+
_eheap = .;
6971
}

Diff for: ‎artiq/runtime/session.c

+64
Original file line numberDiff line numberDiff line change
@@ -908,6 +908,16 @@ static int send_rpc_request(int service, const char *tag, va_list args)
908908
return 1;
909909
}
910910

911+
struct cache_row {
912+
struct cache_row *next;
913+
char *key;
914+
size_t length;
915+
int32_t *elements;
916+
int borrowed;
917+
};
918+
919+
static struct cache_row *cache;
920+
911921
/* assumes output buffer is empty when called */
912922
static int process_kmsg(struct msg_base *umsg)
913923
{
@@ -984,6 +994,60 @@ static int process_kmsg(struct msg_base *umsg)
984994
break;
985995
}
986996

997+
case MESSAGE_TYPE_CACHE_GET_REQUEST: {
998+
struct msg_cache_get_request *request = (struct msg_cache_get_request *)umsg;
999+
struct msg_cache_get_reply reply;
1000+
1001+
reply.type = MESSAGE_TYPE_CACHE_GET_REPLY;
1002+
reply.length = 0;
1003+
reply.elements = NULL;
1004+
1005+
for(struct cache_row *iter = cache; iter; iter = iter->next) {
1006+
if(!strcmp(iter->key, request->key)) {
1007+
reply.length = iter->length;
1008+
reply.elements = iter->elements;
1009+
iter->borrowed = 1;
1010+
break;
1011+
}
1012+
}
1013+
1014+
mailbox_send(&reply);
1015+
}
1016+
1017+
case MESSAGE_TYPE_CACHE_PUT_REQUEST: {
1018+
struct msg_cache_put_request *request = (struct msg_cache_put_request *)umsg;
1019+
struct msg_cache_put_reply reply;
1020+
1021+
reply.type = MESSAGE_TYPE_CACHE_PUT_REPLY;
1022+
1023+
struct cache_row *row = NULL;
1024+
for(struct cache_row *iter = cache; iter; iter = iter->next) {
1025+
if(!strcmp(iter->key, request->key)) {
1026+
free(iter->elements);
1027+
row = iter;
1028+
break;
1029+
}
1030+
}
1031+
1032+
if(!row) {
1033+
struct cache_row *row = calloc(1, sizeof(struct cache_row));
1034+
row->key = calloc(strlen(request->key) + 1, 1);
1035+
strcpy(row->key, request->key);
1036+
}
1037+
1038+
if(!row->borrowed) {
1039+
row->length = request->length;
1040+
row->elements = calloc(row->length, sizeof(int32_t));
1041+
memcpy(row->elements, request->elements,
1042+
sizeof(int32_t) * row->length);
1043+
reply.succeeded = 1;
1044+
} else {
1045+
reply.succeeded = 0;
1046+
}
1047+
1048+
mailbox_send(&reply);
1049+
}
1050+
9871051
default: {
9881052
log("Received invalid message type %d from kernel CPU",
9891053
umsg->type);

0 commit comments

Comments
 (0)
Please sign in to comment.