Skip to content

Commit 6a5f58e

Browse files
committedApr 16, 2015
runtime: support test mode on AMP
1 parent 546996f commit 6a5f58e

File tree

7 files changed

+311
-69
lines changed

7 files changed

+311
-69
lines changed
 

Diff for: ‎soc/runtime/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ UNIPROCESSOR := $(shell printf "\#include <generated/csr.h>\nCSR_KERNEL_CPU_BASE
99

1010
ifeq ($(UNIPROCESSOR),0)
1111
OBJECTS += mailbox.o kernelcpu.o ksupport_data.o
12-
OBJECTS_KSUPPORT += mailbox.o ksupport.o
12+
OBJECTS_KSUPPORT += mailbox.o bridge.o ksupport.o
1313
CFLAGS += -DARTIQ_AMP
1414
SERVICE_TABLE_INPUT = ksupport.elf
1515
else

Diff for: ‎soc/runtime/bridge.c

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#include "mailbox.h"
2+
#include "messages.h"
3+
#include "rtio.h"
4+
#include "dds.h"
5+
#include "bridge.h"
6+
7+
static void send_ready(void)
8+
{
9+
struct msg_base msg;
10+
11+
msg.type = MESSAGE_TYPE_BRG_READY;
12+
mailbox_send_and_wait(&msg);
13+
}
14+
15+
void bridge_main(void)
16+
{
17+
struct msg_base *umsg;
18+
19+
send_ready();
20+
while(1) {
21+
umsg = mailbox_wait_and_receive();
22+
switch(umsg->type) {
23+
case MESSAGE_TYPE_BRG_TTL_OUT: {
24+
struct msg_brg_ttl_out *msg;
25+
26+
msg = (struct msg_brg_ttl_out *)umsg;
27+
rtio_init();
28+
rtio_set_oe(rtio_get_counter() + 8000, msg->channel, 1);
29+
rtio_set_o(rtio_get_counter() + 8000, msg->channel, msg->value);
30+
mailbox_acknowledge();
31+
break;
32+
}
33+
case MESSAGE_TYPE_BRG_DDS_SEL: {
34+
struct msg_brg_dds_sel *msg;
35+
36+
msg = (struct msg_brg_dds_sel *)umsg;
37+
DDS_WRITE(DDS_GPIO, msg->channel);
38+
mailbox_acknowledge();
39+
break;
40+
}
41+
case MESSAGE_TYPE_BRG_DDS_RESET: {
42+
unsigned int g;
43+
44+
g = DDS_READ(DDS_GPIO);
45+
DDS_WRITE(DDS_GPIO, g | (1 << 7));
46+
DDS_WRITE(DDS_GPIO, g);
47+
48+
mailbox_acknowledge();
49+
break;
50+
}
51+
case MESSAGE_TYPE_BRG_DDS_READ_REQUEST: {
52+
struct msg_brg_dds_read_request *msg;
53+
struct msg_brg_dds_read_reply rmsg;
54+
55+
msg = (struct msg_brg_dds_read_request *)umsg;
56+
rmsg.type = MESSAGE_TYPE_BRG_DDS_READ_REPLY;
57+
rmsg.data = DDS_READ(msg->address);
58+
mailbox_send_and_wait(&rmsg);
59+
break;
60+
}
61+
case MESSAGE_TYPE_BRG_DDS_WRITE: {
62+
struct msg_brg_dds_write *msg;
63+
64+
msg = (struct msg_brg_dds_write *)umsg;
65+
DDS_WRITE(msg->address, msg->data);
66+
mailbox_acknowledge();
67+
break;
68+
}
69+
case MESSAGE_TYPE_BRG_DDS_FUD:
70+
rtio_init();
71+
rtio_fud(rtio_get_counter() + 8000);
72+
mailbox_acknowledge();
73+
break;
74+
default:
75+
mailbox_acknowledge();
76+
break;
77+
}
78+
}
79+
}

Diff for: ‎soc/runtime/bridge.h

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#ifndef __BRIDGE_H
2+
#define __BRIDGE_H
3+
4+
void bridge_main(void);
5+
6+
#endif /* __BRIDGE_H */

Diff for: ‎soc/runtime/ksupport.c

+24-20
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include <stdarg.h>
22

33
#include "exceptions.h"
4+
#include "bridge.h"
45
#include "mailbox.h"
56
#include "messages.h"
67
#include "rtio.h"
@@ -31,26 +32,29 @@ int main(void)
3132
kernel_function k;
3233
void *jb;
3334

34-
jb = exception_push();
35-
if(exception_setjmp(jb)) {
36-
struct msg_exception msg;
37-
38-
msg.type = MESSAGE_TYPE_EXCEPTION;
39-
msg.eid = exception_getid(msg.eparams);
40-
mailbox_send_and_wait(&msg);
41-
} else {
42-
struct msg_finished msg;
43-
44-
k = mailbox_receive();
45-
if(!k)
46-
exception_raise(EID_INTERNAL_ERROR);
47-
dds_init();
48-
rtio_init();
49-
k();
50-
exception_pop(1);
51-
52-
msg.type = MESSAGE_TYPE_FINISHED;
53-
mailbox_send_and_wait(&msg);
35+
k = mailbox_receive();
36+
37+
if(k == NULL)
38+
bridge_main();
39+
else {
40+
jb = exception_push();
41+
if(exception_setjmp(jb)) {
42+
struct msg_exception msg;
43+
44+
msg.type = MESSAGE_TYPE_EXCEPTION;
45+
msg.eid = exception_getid(msg.eparams);
46+
mailbox_send_and_wait(&msg);
47+
} else {
48+
struct msg_base msg;
49+
50+
dds_init();
51+
rtio_init();
52+
k();
53+
exception_pop(1);
54+
55+
msg.type = MESSAGE_TYPE_FINISHED;
56+
mailbox_send_and_wait(&msg);
57+
}
5458
}
5559
while(1);
5660
}

Diff for: ‎soc/runtime/main.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ static int load_object(void *buffer, int length)
7070

7171

7272
#ifdef ARTIQ_AMP
73-
static int process_msg(struct msg_unknown *umsg, int *eid, long long int *eparams)
73+
static int process_msg(struct msg_base *umsg, int *eid, long long int *eparams)
7474
{
7575
int i;
7676

@@ -129,7 +129,7 @@ static int run_kernel(const char *kernel_name, int *eid, long long int *eparams)
129129
#ifdef ARTIQ_AMP
130130
kernelcpu_start(k);
131131
while(1) {
132-
struct msg_unknown *umsg;
132+
struct msg_base *umsg;
133133

134134
umsg = mailbox_receive();
135135
r = KERNEL_RUN_INVALID_STATUS;

Diff for: ‎soc/runtime/messages.h

+41-5
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,24 @@ enum {
88
MESSAGE_TYPE_EXCEPTION,
99
MESSAGE_TYPE_RPC_REQUEST,
1010
MESSAGE_TYPE_RPC_REPLY,
11-
MESSAGE_TYPE_LOG
12-
};
11+
MESSAGE_TYPE_LOG,
1312

14-
struct msg_unknown {
15-
int type;
13+
MESSAGE_TYPE_BRG_READY,
14+
MESSAGE_TYPE_BRG_TTL_OUT,
15+
MESSAGE_TYPE_BRG_DDS_SEL,
16+
MESSAGE_TYPE_BRG_DDS_RESET,
17+
MESSAGE_TYPE_BRG_DDS_READ_REQUEST,
18+
MESSAGE_TYPE_BRG_DDS_READ_REPLY,
19+
MESSAGE_TYPE_BRG_DDS_WRITE,
20+
MESSAGE_TYPE_BRG_DDS_FUD,
1621
};
1722

18-
struct msg_finished {
23+
struct msg_base {
1924
int type;
2025
};
2126

27+
/* kernel messages */
28+
2229
struct msg_exception {
2330
int type;
2431
int eid;
@@ -43,4 +50,33 @@ struct msg_log {
4350
va_list args;
4451
};
4552

53+
/* bridge messages */
54+
55+
struct msg_brg_ttl_out {
56+
int type;
57+
int channel;
58+
int value;
59+
};
60+
61+
struct msg_brg_dds_sel {
62+
int type;
63+
int channel;
64+
};
65+
66+
struct msg_brg_dds_read_request {
67+
int type;
68+
unsigned int address;
69+
};
70+
71+
struct msg_brg_dds_read_reply {
72+
int type;
73+
unsigned int data;
74+
};
75+
76+
struct msg_brg_dds_write {
77+
int type;
78+
unsigned int address;
79+
unsigned int data;
80+
};
81+
4682
#endif /* __MESSAGES_H */

Diff for: ‎soc/runtime/test_mode.c

+158-41
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,136 @@
1313

1414
#ifdef ARTIQ_AMP
1515

16-
#warning TODO
16+
#include "kernelcpu.h"
17+
#include "mailbox.h"
18+
#include "messages.h"
1719

18-
void test_main(void)
20+
static void amp_bridge_init(void)
21+
{
22+
struct msg_base *umsg;
23+
24+
kernelcpu_start(NULL);
25+
26+
while(1) {
27+
umsg = mailbox_wait_and_receive();
28+
if(umsg->type == MESSAGE_TYPE_BRG_READY) {
29+
printf("AMP bridge ready\n");
30+
mailbox_acknowledge();
31+
break;
32+
} else {
33+
printf("Warning: unexpected message %d from AMP bridge\n", umsg->type);
34+
mailbox_acknowledge();
35+
}
36+
}
37+
}
38+
39+
static void p_ttlout(int n, int value)
40+
{
41+
struct msg_brg_ttl_out msg;
42+
43+
msg.type = MESSAGE_TYPE_BRG_TTL_OUT;
44+
msg.channel = n;
45+
msg.value = value;
46+
mailbox_send_and_wait(&msg);
47+
}
48+
49+
static void p_ddssel(int channel)
50+
{
51+
struct msg_brg_dds_sel msg;
52+
53+
msg.type = MESSAGE_TYPE_BRG_DDS_SEL;
54+
msg.channel = channel;
55+
mailbox_send_and_wait(&msg);
56+
}
57+
58+
static void p_ddsreset(void)
59+
{
60+
struct msg_base msg;
61+
62+
msg.type = MESSAGE_TYPE_BRG_DDS_RESET;
63+
mailbox_send_and_wait(&msg);
64+
}
65+
66+
static unsigned int p_ddsread(unsigned int address)
67+
{
68+
struct msg_brg_dds_read_request msg;
69+
struct msg_brg_dds_read_reply *rmsg;
70+
unsigned int r;
71+
72+
msg.type = MESSAGE_TYPE_BRG_DDS_READ_REQUEST;
73+
msg.address = address;
74+
mailbox_send(&msg);
75+
while(1) {
76+
rmsg = mailbox_wait_and_receive();
77+
if(rmsg->type == MESSAGE_TYPE_BRG_DDS_READ_REPLY) {
78+
r = rmsg->data;
79+
mailbox_acknowledge();
80+
return r;
81+
} else {
82+
printf("Warning: unexpected message %d from AMP bridge\n", rmsg->type);
83+
mailbox_acknowledge();
84+
}
85+
}
86+
}
87+
88+
static void p_ddswrite(unsigned int address, unsigned int data)
89+
{
90+
struct msg_brg_dds_write msg;
91+
92+
msg.type = MESSAGE_TYPE_BRG_DDS_WRITE;
93+
msg.address = address;
94+
msg.data = data;
95+
mailbox_send_and_wait(&msg);
96+
}
97+
98+
static void p_ddsfud(void)
99+
{
100+
struct msg_base msg;
101+
102+
msg.type = MESSAGE_TYPE_BRG_DDS_FUD;
103+
mailbox_send_and_wait(&msg);
104+
}
105+
106+
#else /* ARTIQ_AMP */
107+
108+
static void p_ttlout(int n, int value)
109+
{
110+
rtio_init();
111+
rtio_set_oe(rtio_get_counter() + 8000, n2, 1);
112+
rtio_set_o(rtio_get_counter() + 8000, n2, value2);
113+
}
114+
115+
static void p_ddssel(int channel)
116+
{
117+
DDS_WRITE(DDS_GPIO, n2);
118+
}
119+
120+
static void p_ddsreset(void)
121+
{
122+
unsigned int g;
123+
124+
g = DDS_READ(DDS_GPIO);
125+
DDS_WRITE(DDS_GPIO, g | (1 << 7));
126+
DDS_WRITE(DDS_GPIO, g);
127+
}
128+
129+
static unsigned int p_ddsread(unsigned int address)
130+
{
131+
return DDS_READ(address);
132+
}
133+
134+
static void p_ddswrite(unsigned int address, unsigned int data)
135+
{
136+
DDS_WRITE(address, data);
137+
}
138+
139+
static void p_ddsfud(void)
19140
{
20-
printf("Not implemented yet for AMP systems\n");
141+
rtio_init();
142+
rtio_fud(rtio_get_counter() + 8000);
21143
}
22144

23-
#else
145+
#endif /* ARTIQ_AMP */
24146

25147
static void leds(char *value)
26148
{
@@ -81,9 +203,7 @@ static void ttlout(char *n, char *value)
81203
return;
82204
}
83205

84-
rtio_init();
85-
rtio_set_oe(rtio_get_counter() + 8000, n2, 1);
86-
rtio_set_o(rtio_get_counter() + 8000, n2, value2);
206+
p_ttlout(n2, value2);
87207
}
88208

89209
static void ddssel(char *n)
@@ -102,7 +222,7 @@ static void ddssel(char *n)
102222
return;
103223
}
104224

105-
DDS_WRITE(DDS_GPIO, n2);
225+
p_ddssel(n2);
106226
}
107227

108228
static void ddsw(char *addr, char *value)
@@ -126,7 +246,7 @@ static void ddsw(char *addr, char *value)
126246
return;
127247
}
128248

129-
DDS_WRITE(addr2, value2);
249+
p_ddswrite(addr2, value2);
130250
}
131251

132252
static void ddsr(char *addr)
@@ -145,13 +265,12 @@ static void ddsr(char *addr)
145265
return;
146266
}
147267

148-
printf("0x%02x\n", DDS_READ(addr2));
268+
printf("0x%02x\n", p_ddsread(addr2));
149269
}
150270

151271
static void ddsfud(void)
152272
{
153-
rtio_init();
154-
rtio_fud(rtio_get_counter() + 8000);
273+
p_ddsfud();
155274
}
156275

157276
static void ddsftw(char *n, char *ftw)
@@ -175,31 +294,27 @@ static void ddsftw(char *n, char *ftw)
175294
return;
176295
}
177296

178-
DDS_WRITE(DDS_GPIO, n2);
179-
DDS_WRITE(DDS_FTW0, ftw2 & 0xff);
180-
DDS_WRITE(DDS_FTW1, (ftw2 >> 8) & 0xff);
181-
DDS_WRITE(DDS_FTW2, (ftw2 >> 16) & 0xff);
182-
DDS_WRITE(DDS_FTW3, (ftw2 >> 24) & 0xff);
183-
ddsfud();
297+
p_ddssel(n2);
298+
p_ddswrite(DDS_FTW0, ftw2 & 0xff);
299+
p_ddswrite(DDS_FTW1, (ftw2 >> 8) & 0xff);
300+
p_ddswrite(DDS_FTW2, (ftw2 >> 16) & 0xff);
301+
p_ddswrite(DDS_FTW3, (ftw2 >> 24) & 0xff);
302+
p_ddsfud();
184303
}
185304

186305
static void ddsreset(void)
187306
{
188-
unsigned int g;
189-
190-
g = DDS_READ(DDS_GPIO);
191-
DDS_WRITE(DDS_GPIO, g | (1 << 7));
192-
DDS_WRITE(DDS_GPIO, g);
307+
p_ddsreset();
193308
}
194309

195310
static void ddsinit(void)
196311
{
197-
ddsreset();
198-
DDS_WRITE(0x00, 0x78);
199-
DDS_WRITE(0x01, 0x00);
200-
DDS_WRITE(0x02, 0x00);
201-
DDS_WRITE(0x03, 0x00);
202-
ddsfud();
312+
p_ddsreset();
313+
p_ddswrite(0x00, 0x78);
314+
p_ddswrite(0x01, 0x00);
315+
p_ddswrite(0x02, 0x00);
316+
p_ddswrite(0x03, 0x00);
317+
p_ddsfud();
203318
}
204319

205320
static void ddstest_one(unsigned int i)
@@ -211,20 +326,20 @@ static void ddstest_one(unsigned int i)
211326
};
212327
unsigned int f, g, j;
213328

214-
DDS_WRITE(DDS_GPIO, i);
329+
p_ddssel(i);
215330
ddsinit();
216331

217332
for(j=0; j<12; j++) {
218333
f = v[j];
219-
DDS_WRITE(0x0a, f & 0xff);
220-
DDS_WRITE(0x0b, (f >> 8) & 0xff);
221-
DDS_WRITE(0x0c, (f >> 16) & 0xff);
222-
DDS_WRITE(0x0d, (f >> 24) & 0xff);
223-
ddsfud();
224-
g = DDS_READ(0x0a);
225-
g |= DDS_READ(0x0b) << 8;
226-
g |= DDS_READ(0x0c) << 16;
227-
g |= DDS_READ(0x0d) << 24;
334+
p_ddswrite(0x0a, f & 0xff);
335+
p_ddswrite(0x0b, (f >> 8) & 0xff);
336+
p_ddswrite(0x0c, (f >> 16) & 0xff);
337+
p_ddswrite(0x0d, (f >> 24) & 0xff);
338+
p_ddsfud();
339+
g = p_ddsread(0x0a);
340+
g |= p_ddsread(0x0b) << 8;
341+
g |= p_ddsread(0x0c) << 16;
342+
g |= p_ddsread(0x0d) << 24;
228343
if(g != f)
229344
printf("readback fail on DDS %d, 0x%08x != 0x%08x\n", i, g, f);
230345
}
@@ -346,11 +461,13 @@ void test_main(void)
346461
{
347462
char buffer[64];
348463

464+
#ifdef ARTIQ_AMP
465+
amp_bridge_init();
466+
#endif
467+
349468
while(1) {
350469
putsnonl("\e[1mtest>\e[0m ");
351470
readstr(buffer, 64);
352471
do_command(buffer);
353472
}
354473
}
355-
356-
#endif /* ARTIQ_AMP */

0 commit comments

Comments
 (0)
Please sign in to comment.