Skip to content

Commit 18106cc

Browse files
committedApr 21, 2015
comm: refactor to support lwip event model
1 parent 9f52277 commit 18106cc

20 files changed

+830
-623
lines changed
 

Diff for: ‎artiq/coredevice/comm_generic.py

+77-83
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
import struct
2-
import zlib
32
import logging
43
from enum import Enum
54
from fractions import Fraction
65

7-
from artiq.language import units
86
from artiq.coredevice.runtime import Environment
97
from artiq.coredevice import runtime_exceptions
108
from artiq.language import core as core_language
@@ -15,33 +13,30 @@
1513

1614

1715
class _H2DMsgType(Enum):
18-
LINK_MESSAGE = 1
19-
20-
REQUEST_IDENT = 2
16+
LOG_REQUEST = 1
17+
IDENT_REQUEST = 2
2118
SWITCH_CLOCK = 3
2219

2320
LOAD_OBJECT = 4
2421
RUN_KERNEL = 5
22+
23+
RPC_REPLY = 6
2524

2625

2726
class _D2HMsgType(Enum):
28-
MESSAGE_UNRECOGNIZED = 1
29-
LOG = 2
30-
31-
IDENT = 3
32-
CLOCK_SWITCH_COMPLETED = 4
33-
CLOCK_SWITCH_FAILED = 5
27+
LOG_REPLY = 1
28+
IDENT_REPLY = 2
29+
CLOCK_SWITCH_COMPLETED = 3
30+
CLOCK_SWITCH_FAILED = 4
3431

35-
OBJECT_LOADED = 6
36-
OBJECT_INCORRECT_LENGTH = 7
37-
OBJECT_CRC_FAILED = 8
38-
OBJECT_UNRECOGNIZED = 9
32+
LOAD_COMPLETED = 5
33+
LOAD_FAILED = 6
3934

40-
KERNEL_FINISHED = 10
41-
KERNEL_STARTUP_FAILED = 11
42-
KERNEL_EXCEPTION = 12
35+
KERNEL_FINISHED = 7
36+
KERNEL_STARTUP_FAILED = 8
37+
KERNEL_EXCEPTION = 9
4338

44-
RPC_REQUEST = 13
39+
RPC_REQUEST = 10
4540

4641

4742
class UnsupportedDevice(Exception):
@@ -71,103 +66,95 @@ def write(self, data):
7166
raise NotImplementedError
7267
#
7368

74-
def _read(self, length):
75-
self.open()
76-
return self.read(length)
77-
78-
def _write(self, data):
69+
def _read_header(self):
7970
self.open()
80-
self.write(data)
8171

82-
def _get_device_msg(self):
83-
while True:
84-
(reply, ) = struct.unpack("B", self._read(1))
85-
msg = _D2HMsgType(reply)
86-
if msg == _D2HMsgType.LOG:
87-
(length, ) = struct.unpack(">h", self._read(2))
88-
log_message = ""
89-
for i in range(length):
90-
(c, ) = struct.unpack("B", self._read(1))
91-
log_message += chr(c)
92-
logger.info("DEVICE LOG: %s", log_message)
72+
sync_count = 0
73+
while sync_count < 4:
74+
(c, ) = struct.unpack("B", self.read(1))
75+
if c == 0x5a:
76+
sync_count += 1
9377
else:
94-
logger.debug("message received: %r", msg)
95-
return msg
78+
sync_count = 0
79+
length, tyv = struct.unpack(">lB", self.read(5))
80+
ty = _D2HMsgType(tyv)
81+
logger.debug("receiving message: type=%r length=%d", ty, length)
82+
return length, ty
83+
84+
def _write_header(self, length, ty):
85+
self.open()
86+
logger.debug("sending message: type=%r length=%d", ty, length)
87+
self.write(struct.pack(">llB", 0x5a5a5a5a, length, ty.value))
9688

9789
def get_runtime_env(self):
98-
self._write(struct.pack(">lb", 0x5a5a5a5a,
99-
_H2DMsgType.REQUEST_IDENT.value))
100-
msg = self._get_device_msg()
101-
if msg != _D2HMsgType.IDENT:
102-
raise IOError("Incorrect reply from device: {}".format(msg))
103-
(reply, ) = struct.unpack("B", self._read(1))
90+
self._write_header(9, _H2DMsgType.IDENT_REQUEST)
91+
_, ty = self._read_header()
92+
if ty != _D2HMsgType.IDENT_REPLY:
93+
raise IOError("Incorrect reply from device: {}".format(ty))
94+
(reply, ) = struct.unpack("B", self.read(1))
10495
runtime_id = chr(reply)
10596
for i in range(3):
106-
(reply, ) = struct.unpack("B", self._read(1))
97+
(reply, ) = struct.unpack("B", self.read(1))
10798
runtime_id += chr(reply)
10899
if runtime_id != "AROR":
109100
raise UnsupportedDevice("Unsupported runtime ID: {}"
110101
.format(runtime_id))
111102
return Environment()
112103

113104
def switch_clock(self, external):
114-
self._write(struct.pack(
115-
">lbb", 0x5a5a5a5a, _H2DMsgType.SWITCH_CLOCK.value,
116-
int(external)))
117-
msg = self._get_device_msg()
118-
if msg != _D2HMsgType.CLOCK_SWITCH_COMPLETED:
119-
raise IOError("Incorrect reply from device: {}".format(msg))
105+
self._write_header(10, _H2DMsgType.SWITCH_CLOCK)
106+
self.write(struct.pack("B", int(external)))
107+
_, ty = self._read_header()
108+
if ty != _D2HMsgType.CLOCK_SWITCH_COMPLETED:
109+
raise IOError("Incorrect reply from device: {}".format(ty))
120110

121111
def load(self, kcode):
122-
self._write(struct.pack(
123-
">lblL",
124-
0x5a5a5a5a, _H2DMsgType.LOAD_OBJECT.value,
125-
len(kcode), zlib.crc32(kcode)))
126-
self._write(kcode)
127-
msg = self._get_device_msg()
128-
if msg != _D2HMsgType.OBJECT_LOADED:
129-
raise IOError("Incorrect reply from device: "+str(msg))
112+
self._write_header(len(kcode) + 9, _H2DMsgType.LOAD_OBJECT)
113+
self.write(kcode)
114+
_, ty = self._read_header()
115+
if ty != _D2HMsgType.LOAD_COMPLETED:
116+
raise IOError("Incorrect reply from device: "+str(ty))
130117

131118
def run(self, kname):
132-
self._write(struct.pack(
133-
">lbl", 0x5a5a5a5a, _H2DMsgType.RUN_KERNEL.value, len(kname)))
134-
for c in kname:
135-
self._write(struct.pack(">B", ord(c)))
119+
self._write_header(len(kname) + 9, _H2DMsgType.RUN_KERNEL)
120+
self.write(bytes(kname, "ascii"))
136121
logger.debug("running kernel: %s", kname)
137122

138123
def _receive_rpc_values(self):
139124
r = []
140125
while True:
141-
type_tag = chr(struct.unpack(">B", self._read(1))[0])
126+
type_tag = chr(struct.unpack("B", self.read(1))[0])
142127
if type_tag == "\x00":
143128
return r
144129
if type_tag == "n":
145130
r.append(None)
146131
if type_tag == "b":
147-
r.append(bool(struct.unpack(">B", self._read(1))[0]))
132+
r.append(bool(struct.unpack("B", self.read(1))[0]))
148133
if type_tag == "i":
149-
r.append(struct.unpack(">l", self._read(4))[0])
134+
r.append(struct.unpack(">l", self.read(4))[0])
150135
if type_tag == "I":
151-
r.append(struct.unpack(">q", self._read(8))[0])
136+
r.append(struct.unpack(">q", self.read(8))[0])
152137
if type_tag == "f":
153-
r.append(struct.unpack(">d", self._read(8))[0])
138+
r.append(struct.unpack(">d", self.read(8))[0])
154139
if type_tag == "F":
155-
n, d = struct.unpack(">qq", self._read(16))
140+
n, d = struct.unpack(">qq", self.read(16))
156141
r.append(Fraction(n, d))
157142
if type_tag == "l":
158143
r.append(self._receive_rpc_values())
159144

160145
def _serve_rpc(self, rpc_wrapper, rpc_map, user_exception_map):
161-
rpc_num = struct.unpack(">h", self._read(2))[0]
146+
rpc_num = struct.unpack(">l", self.read(4))[0]
162147
args = self._receive_rpc_values()
163148
logger.debug("rpc service: %d %r", rpc_num, args)
164149
eid, r = rpc_wrapper.run_rpc(
165150
user_exception_map, rpc_map[rpc_num], args)
166-
self._write(struct.pack(">ll", eid, r))
167-
logger.debug("rpc service: %d %r == %r", rpc_num, args, r)
151+
self._write_header(9+2*4, _H2DMsgType.RPC_REPLY)
152+
self.write(struct.pack(">ll", eid, r))
153+
logger.debug("rpc service: %d %r == %r (eid %d)", rpc_num, args,
154+
r, eid)
168155

169156
def _serve_exception(self, rpc_wrapper, user_exception_map):
170-
eid, p0, p1, p2 = struct.unpack(">lqqq", self._read(4+3*8))
157+
eid, p0, p1, p2 = struct.unpack(">lqqq", self.read(4+3*8))
171158
rpc_wrapper.filter_rpc_exception(eid)
172159
if eid < core_language.first_user_eid:
173160
exception = runtime_exceptions.exception_map[eid]
@@ -179,17 +166,24 @@ def _serve_exception(self, rpc_wrapper, user_exception_map):
179166
def serve(self, rpc_map, user_exception_map):
180167
rpc_wrapper = RPCWrapper()
181168
while True:
182-
msg = self._get_device_msg()
183-
if msg == _D2HMsgType.RPC_REQUEST:
169+
_, ty = self._read_header()
170+
if ty == _D2HMsgType.RPC_REQUEST:
184171
self._serve_rpc(rpc_wrapper, rpc_map, user_exception_map)
185-
elif msg == _D2HMsgType.KERNEL_EXCEPTION:
172+
elif ty == _D2HMsgType.KERNEL_EXCEPTION:
186173
self._serve_exception(rpc_wrapper, user_exception_map)
187-
elif msg == _D2HMsgType.KERNEL_FINISHED:
174+
elif ty == _D2HMsgType.KERNEL_FINISHED:
188175
return
189176
else:
190-
raise IOError("Incorrect request from device: "+str(msg))
191-
192-
def send_link_message(self, data):
193-
self._write(struct.pack(
194-
">lb", 0x5a5a5a5a, _H2DMsgType.LINK_MESSAGE.value))
195-
self._write(data)
177+
raise IOError("Incorrect request from device: "+str(ty))
178+
179+
def get_log(self):
180+
self._write_header(9, _H2DMsgType.LOG_REQUEST)
181+
length, ty = self._read_header()
182+
if ty != _D2HMsgType.LOG_REPLY:
183+
raise IOError("Incorrect request from device: "+str(ty))
184+
r = ""
185+
for i in range(length - 9):
186+
c = struct.unpack("B", self.read(1))[0]
187+
if c:
188+
r += chr(c)
189+
return r

Diff for: ‎artiq/coredevice/comm_serial.py

+2-29
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,12 @@ class DBKeys:
1717
def open(self):
1818
if hasattr(self, "port"):
1919
return
20-
self.port = serial.serial_for_url(self.serial_dev, baudrate=115200)
21-
self.port.flush()
22-
self.set_remote_baud(self.baud_rate)
23-
self.set_baud(self.baud_rate)
20+
self.port = serial.serial_for_url(self.serial_dev,
21+
baudrate=self.baud_rate)
2422

2523
def close(self):
2624
if not hasattr(self, "port"):
2725
return
28-
self.set_remote_baud(115200)
2926
self.port.close()
3027
del self.port
3128

@@ -42,27 +39,3 @@ def write(self, data):
4239
written = self.port.write(data[pos:])
4340
remaining -= written
4441
pos += written
45-
46-
def set_baud(self, baud):
47-
self.port.baudrate = baud
48-
self.port.flush()
49-
logger.debug("local baud rate set to %d", baud)
50-
51-
def set_remote_baud(self, baud):
52-
self.send_link_message(struct.pack(">l", baud))
53-
handshake = 0
54-
fails = 0
55-
while handshake < 4:
56-
(recv, ) = struct.unpack("B", self.read(1))
57-
if recv == 0x5a:
58-
handshake += 1
59-
else:
60-
# FIXME: when loading immediately after a board reset,
61-
# we erroneously get some zeros back.
62-
logger.warning("unexpected sync character: %02x", recv)
63-
handshake = 0
64-
if recv != 0:
65-
fails += 1
66-
if fails > 3:
67-
raise IOError("Baudrate ack failed")
68-
logger.debug("remote baud rate set to %d", baud)

Diff for: ‎soc/runtime/Makefile

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
include $(MSCDIR)/software/common.mak
22

3-
OBJECTS := isr.o elf_loader.o services.o comm_serial.o test_mode.o main.o
3+
OBJECTS := isr.o elf_loader.o services.o session.o log.o test_mode.o kloader.o main.o
44
OBJECTS_KSUPPORT := exception_jmp.o exceptions.o rtio.o dds.o
55

66
# NOTE: this does not handle dependencies well. Run "make clean"
77
# when switching between UP and AMP.
88
UNIPROCESSOR := $(shell printf "\#include <generated/csr.h>\nCSR_KERNEL_CPU_BASE" | $(CC_normal) $(CFLAGS) -E - | tail -n 1 | grep -c CSR_KERNEL_CPU_BASE)
99

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

Diff for: ‎soc/runtime/comm.h

-23
This file was deleted.

Diff for: ‎soc/runtime/comm_serial.c

-292
This file was deleted.

Diff for: ‎soc/runtime/elf_loader.c

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include <string.h>
22

3-
#include "comm.h"
3+
#include "log.h"
44
#include "elf_loader.h"
55

66
#define EI_NIDENT 16
@@ -85,11 +85,11 @@ struct elf32_sym {
8585

8686
#define SANITIZE_OFFSET_SIZE(offset, size) \
8787
if(offset > 0x10000000) { \
88-
comm_log("Incorrect offset in ELF data"); \
88+
log("Incorrect offset in ELF data"); \
8989
return 0; \
9090
} \
9191
if((offset + size) > elf_length) { \
92-
comm_log("Attempted to access past the end of ELF data"); \
92+
log("Attempted to access past the end of ELF data"); \
9393
return 0; \
9494
}
9595

@@ -121,7 +121,7 @@ static int fixup(void *dest, int dest_length, struct elf32_rela *rela, void *tar
121121
val = _target - (_dest + offset);
122122
_dest[offset] = (_dest[offset] & 0xfc000000) | (val & 0x03ffffff);
123123
} else
124-
comm_log("Unsupported relocation type: %d", type);
124+
log("Unsupported relocation type: %d", type);
125125
return 1;
126126
}
127127

@@ -141,15 +141,15 @@ int load_elf(symbol_resolver resolver, symbol_callback callback, void *elf_data,
141141
/* validate ELF */
142142
GET_POINTER_SAFE(ehdr, struct elf32_ehdr, 0);
143143
if(memcmp(ehdr->ident, elf_magic_header, sizeof(elf_magic_header)) != 0) {
144-
comm_log("Incorrect ELF header");
144+
log("Incorrect ELF header");
145145
return 0;
146146
}
147147
if(ehdr->type != ET_REL) {
148-
comm_log("ELF is not relocatable");
148+
log("ELF is not relocatable");
149149
return 0;
150150
}
151151
if(ehdr->machine != EM_OR1K) {
152-
comm_log("ELF is for a different machine");
152+
log("ELF is for a different machine");
153153
return 0;
154154
}
155155

@@ -190,7 +190,7 @@ int load_elf(symbol_resolver resolver, symbol_callback callback, void *elf_data,
190190

191191
/* load .text section */
192192
if(textsize > dest_length) {
193-
comm_log(".text section is too large");
193+
log(".text section is too large");
194194
return 0;
195195
}
196196
memcpy(dest, (char *)elf_data + textoff, textsize);
@@ -209,13 +209,13 @@ int load_elf(symbol_resolver resolver, symbol_callback callback, void *elf_data,
209209
name = (char *)elf_data + strtaboff + sym->name;
210210
target = resolver(name);
211211
if(target == NULL) {
212-
comm_log("Undefined symbol: %s", name);
212+
log("Undefined symbol: %s", name);
213213
return 0;
214214
}
215215
if(!fixup(dest, dest_length, rela, target))
216216
return 0;
217217
} else {
218-
comm_log("Unsupported relocation");
218+
log("Unsupported relocation");
219219
return 0;
220220
}
221221
}

Diff for: ‎soc/runtime/exceptions.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include <generated/csr.h>
22

3-
#include "comm.h"
3+
#include "log.h"
44
#include "exceptions.h"
55

66
#define MAX_EXCEPTION_CONTEXTS 64
@@ -52,7 +52,7 @@ void exception_raise_params(int id,
5252
stored_params[2] = p2;
5353
exception_longjmp(exception_contexts[--ec_top].jb);
5454
} else {
55-
comm_log("ERROR: uncaught exception, ID=%d\n", id);
55+
log("ERROR: uncaught exception, ID=%d\n", id);
5656
while(1);
5757
}
5858
}

Diff for: ‎soc/runtime/gen_service_table.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
services = [
77
("syscalls", [
8-
("rpc", "comm_rpc"),
8+
("rpc", "rpc"),
99
("rtio_set_o", "rtio_set_o"),
1010
("rtio_set_oe", "rtio_set_oe"),
1111
("rtio_set_sensitivity", "rtio_set_sensitivity"),

Diff for: ‎soc/runtime/kernelcpu.c

-24
This file was deleted.

Diff for: ‎soc/runtime/kernelcpu.h

-12
This file was deleted.

Diff for: ‎soc/runtime/kloader.c

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
#include <string.h>
2+
#include <generated/csr.h>
3+
4+
#include "log.h"
5+
#include "mailbox.h"
6+
#include "elf_loader.h"
7+
#include "services.h"
8+
#include "kloader.h"
9+
10+
11+
static struct symbol symtab[128];
12+
static int _symtab_count;
13+
static char _symtab_strings[128*16];
14+
static char *_symtab_strptr;
15+
16+
static void symtab_init(void)
17+
{
18+
memset(symtab, 0, sizeof(symtab));
19+
_symtab_count = 0;
20+
_symtab_strptr = _symtab_strings;
21+
}
22+
23+
static int symtab_add(const char *name, void *target)
24+
{
25+
if(_symtab_count >= sizeof(symtab)/sizeof(symtab[0])) {
26+
log("Too many provided symbols in object");
27+
symtab_init();
28+
return 0;
29+
}
30+
symtab[_symtab_count].name = _symtab_strptr;
31+
symtab[_symtab_count].target = target;
32+
_symtab_count++;
33+
34+
while(1) {
35+
if(_symtab_strptr >= &_symtab_strings[sizeof(_symtab_strings)]) {
36+
log("Provided symbol string table overflow");
37+
symtab_init();
38+
return 0;
39+
}
40+
*_symtab_strptr = *name;
41+
_symtab_strptr++;
42+
if(*name == 0)
43+
break;
44+
name++;
45+
}
46+
47+
return 1;
48+
}
49+
50+
int kloader_load(void *buffer, int length)
51+
{
52+
#ifdef ARTIQ_AMP
53+
if(!kernel_cpu_reset_read()) {
54+
log("BUG: attempted to load while kernel CPU running");
55+
return 0;
56+
}
57+
#endif
58+
symtab_init();
59+
return load_elf(
60+
resolve_service_symbol, symtab_add,
61+
buffer, length, (void *)KERNELCPU_PAYLOAD_ADDRESS, 4*1024*1024);
62+
}
63+
64+
kernel_function kloader_find(const char *name)
65+
{
66+
return find_symbol(symtab, name);
67+
}
68+
69+
#ifdef ARTIQ_AMP
70+
71+
extern char _binary_ksupport_bin_start;
72+
extern char _binary_ksupport_bin_end;
73+
74+
static void start_kernel_cpu(void *addr)
75+
{
76+
memcpy((void *)KERNELCPU_EXEC_ADDRESS, &_binary_ksupport_bin_start,
77+
&_binary_ksupport_bin_end - &_binary_ksupport_bin_start);
78+
mailbox_acknowledge();
79+
mailbox_send(addr);
80+
kernel_cpu_reset_write(0);
81+
}
82+
83+
void kloader_start_bridge(void)
84+
{
85+
start_kernel_cpu(NULL);
86+
}
87+
88+
void kloader_start_user_kernel(kernel_function k)
89+
{
90+
if(!kernel_cpu_reset_read()) {
91+
log("BUG: attempted to start kernel CPU while already running (user kernel)");
92+
return;
93+
}
94+
start_kernel_cpu((void *)k);
95+
}
96+
97+
void kloader_start_idle_kernel(void)
98+
{
99+
if(!kernel_cpu_reset_read()) {
100+
log("BUG: attempted to start kernel CPU while already running (idle kernel)");
101+
return;
102+
}
103+
/* TODO */
104+
}
105+
106+
void kloader_stop_kernel(void)
107+
{
108+
kernel_cpu_reset_write(1);
109+
}
110+
111+
#endif

Diff for: ‎soc/runtime/kloader.h

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#ifndef __KLOADER_H
2+
#define __KLOADER_H
3+
4+
#define KERNELCPU_EXEC_ADDRESS 0x40020000
5+
#define KERNELCPU_PAYLOAD_ADDRESS 0x40024000
6+
7+
typedef void (*kernel_function)(void);
8+
9+
int kloader_load(void *buffer, int length);
10+
kernel_function kloader_find(const char *name);
11+
12+
#ifdef ARTIQ_AMP
13+
void kloader_start_bridge(void);
14+
void kloader_start_idle_kernel(void);
15+
void kloader_start_user_kernel(kernel_function k);
16+
void kloader_stop_kernel(void);
17+
#endif
18+
19+
#endif /* __KLOADER_H */

Diff for: ‎soc/runtime/ksupport.c

+6-4
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
#include "rtio.h"
88
#include "dds.h"
99

10-
/* for the prototypes for comm_rpc and comm_log */
11-
#include "comm.h"
10+
/* for the prototype for rpc() */
11+
#include "session.h"
12+
/* for the prototype for log() */
13+
#include "log.h"
1214

1315
void exception_handler(unsigned long vect, unsigned long *sp);
1416
void exception_handler(unsigned long vect, unsigned long *sp)
@@ -59,7 +61,7 @@ int main(void)
5961
while(1);
6062
}
6163

62-
int comm_rpc(int rpc_num, ...)
64+
int rpc(int rpc_num, ...)
6365
{
6466
struct msg_rpc_request request;
6567
struct msg_rpc_reply *reply;
@@ -83,7 +85,7 @@ int comm_rpc(int rpc_num, ...)
8385
return retval;
8486
}
8587

86-
void comm_log(const char *fmt, ...)
88+
void log(const char *fmt, ...)
8789
{
8890
struct msg_log request;
8991

Diff for: ‎soc/runtime/log.c

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#include <stdarg.h>
2+
#include <stdio.h>
3+
4+
#include "log.h"
5+
6+
static int buffer_index;
7+
static char buffer[LOG_BUFFER_SIZE];
8+
9+
void log_va(const char *fmt, va_list args)
10+
{
11+
char outbuf[256];
12+
int i, len;
13+
14+
len = vscnprintf(outbuf, sizeof(outbuf), fmt, args);
15+
for(i=0;i<len;i++) {
16+
buffer[buffer_index] = outbuf[i];
17+
buffer_index = (buffer_index + 1) % LOG_BUFFER_SIZE;
18+
}
19+
buffer[buffer_index] = '\n';
20+
buffer_index = (buffer_index + 1) % LOG_BUFFER_SIZE;
21+
}
22+
23+
void log(const char *fmt, ...)
24+
{
25+
va_list args;
26+
27+
va_start(args, fmt);
28+
log_va(fmt, args);
29+
va_end(args);
30+
}
31+
32+
void log_get(char *outbuf)
33+
{
34+
int i, j;
35+
36+
j = buffer_index + 1;
37+
for(i=0;i<LOG_BUFFER_SIZE;i++) {
38+
outbuf[i] = buffer[j];
39+
j = (j + 1) % LOG_BUFFER_SIZE;
40+
}
41+
}

Diff for: ‎soc/runtime/log.h

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#ifndef __LOG_H
2+
#define __LOG_H
3+
4+
#include <stdarg.h>
5+
6+
#define LOG_BUFFER_SIZE 4096
7+
8+
void log_va(const char *fmt, va_list args);
9+
void log(const char *fmt, ...);
10+
11+
void log_get(char *outbuf);
12+
13+
#endif /* __LOG_H */

Diff for: ‎soc/runtime/main.c

+26-138
Original file line numberDiff line numberDiff line change
@@ -8,154 +8,42 @@
88
#include <generated/csr.h>
99

1010
#include "test_mode.h"
11-
#include "comm.h"
12-
#include "kernelcpu.h"
13-
#include "elf_loader.h"
14-
#include "exceptions.h"
15-
#include "services.h"
16-
#include "rtio.h"
17-
#include "dds.h"
11+
#include "session.h"
1812

19-
#ifdef ARTIQ_AMP
20-
#include "mailbox.h"
21-
#include "messages.h"
22-
#endif
23-
24-
static struct symbol symtab[128];
25-
static int _symtab_count;
26-
static char _symtab_strings[128*16];
27-
static char *_symtab_strptr;
28-
29-
static void symtab_init(void)
30-
{
31-
memset(symtab, 0, sizeof(symtab));
32-
_symtab_count = 0;
33-
_symtab_strptr = _symtab_strings;
34-
}
35-
36-
static int symtab_add(const char *name, void *target)
13+
void comm_service(void)
3714
{
38-
if(_symtab_count >= sizeof(symtab)/sizeof(symtab[0])) {
39-
comm_log("Too many provided symbols in object");
40-
symtab_init();
41-
return 0;
15+
char *txdata;
16+
int txlen;
17+
static char rxdata;
18+
static int rxpending;
19+
int r, i;
20+
21+
if(!rxpending && uart_read_nonblock()) {
22+
rxdata = uart_read();
23+
rxpending = 1;
4224
}
43-
symtab[_symtab_count].name = _symtab_strptr;
44-
symtab[_symtab_count].target = target;
45-
_symtab_count++;
46-
47-
while(1) {
48-
if(_symtab_strptr >= &_symtab_strings[sizeof(_symtab_strings)]) {
49-
comm_log("Provided symbol string table overflow");
50-
symtab_init();
51-
return 0;
52-
}
53-
*_symtab_strptr = *name;
54-
_symtab_strptr++;
55-
if(*name == 0)
56-
break;
57-
name++;
25+
if(rxpending) {
26+
r = session_input(&rxdata, 1);
27+
if(r > 0)
28+
rxpending = 0;
5829
}
5930

60-
return 1;
61-
}
62-
63-
static int load_object(void *buffer, int length)
64-
{
65-
symtab_init();
66-
return load_elf(
67-
resolve_service_symbol, symtab_add,
68-
buffer, length, (void *)KERNELCPU_PAYLOAD_ADDRESS, 4*1024*1024);
69-
}
70-
71-
72-
#ifdef ARTIQ_AMP
73-
static int process_msg(struct msg_base *umsg, int *eid, long long int *eparams)
74-
{
75-
int i;
76-
77-
switch(umsg->type) {
78-
case MESSAGE_TYPE_FINISHED:
79-
return KERNEL_RUN_FINISHED;
80-
case MESSAGE_TYPE_EXCEPTION: {
81-
struct msg_exception *msg = (struct msg_exception *)umsg;
82-
83-
*eid = msg->eid;
84-
for(i=0;i<3;i++)
85-
eparams[i] = msg->eparams[i];
86-
return KERNEL_RUN_EXCEPTION;
87-
}
88-
case MESSAGE_TYPE_RPC_REQUEST: {
89-
struct msg_rpc_request *msg = (struct msg_rpc_request *)umsg;
90-
struct msg_rpc_reply reply;
91-
92-
reply.type = MESSAGE_TYPE_RPC_REPLY;
93-
comm_rpc_va(msg->rpc_num, msg->args, &reply.eid, &reply.retval);
94-
mailbox_send_and_wait(&reply);
95-
return KERNEL_RUN_INVALID_STATUS;
96-
}
97-
case MESSAGE_TYPE_LOG: {
98-
struct msg_log *msg = (struct msg_log *)umsg;
99-
100-
comm_log(msg->fmt, msg->args);
101-
return KERNEL_RUN_INVALID_STATUS;
102-
}
103-
default:
104-
*eid = EID_INTERNAL_ERROR;
105-
for(i=0;i<3;i++)
106-
eparams[i] = 0;
107-
return KERNEL_RUN_EXCEPTION;
31+
session_poll((void **)&txdata, &txlen);
32+
if(txlen > 0) {
33+
for(i=0;i<txlen;i++)
34+
uart_write(txdata[i]);
35+
session_ack(txlen);
10836
}
10937
}
110-
#endif
11138

112-
typedef void (*kernel_function)(void);
113-
114-
static int run_kernel(const char *kernel_name, int *eid, long long int *eparams)
39+
static void regular_main(void)
11540
{
116-
kernel_function k;
117-
#ifdef ARTIQ_AMP
118-
int r;
119-
#else
120-
void *jb;
121-
#endif
122-
123-
k = find_symbol(symtab, kernel_name);
124-
if(k == NULL) {
125-
comm_log("Failed to find kernel entry point '%s' in object", kernel_name);
126-
return KERNEL_RUN_STARTUP_FAILED;
127-
}
128-
129-
#ifdef ARTIQ_AMP
130-
kernelcpu_start(k);
131-
while(1) {
132-
struct msg_base *umsg;
133-
134-
umsg = mailbox_receive();
135-
r = KERNEL_RUN_INVALID_STATUS;
136-
if(umsg)
137-
r = process_msg(umsg, eid, eparams);
138-
if(r != KERNEL_RUN_INVALID_STATUS)
139-
break;
140-
}
141-
kernelcpu_stop();
142-
return r;
143-
#else
144-
jb = exception_push();
145-
if(exception_setjmp(jb)) {
146-
*eid = exception_getid(eparams);
147-
return KERNEL_RUN_EXCEPTION;
148-
} else {
149-
dds_init();
150-
rtio_init();
151-
flush_cpu_icache();
152-
k();
153-
exception_pop(1);
154-
return KERNEL_RUN_FINISHED;
155-
}
156-
#endif
41+
session_start();
42+
while(1)
43+
comm_service();
15744
}
15845

46+
15947
static void blink_led(void)
16048
{
16149
int i, ev, p;
@@ -208,7 +96,7 @@ int main(void)
20896
test_main();
20997
} else {
21098
puts("Entering regular mode.");
211-
comm_serve(load_object, run_kernel);
99+
regular_main();
212100
}
213101
return 0;
214102
}

Diff for: ‎soc/runtime/services.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#include <string.h>
22

33
#include "elf_loader.h"
4-
#include "comm.h"
4+
#include "session.h"
55
#include "rtio.h"
66
#include "dds.h"
77
#include "exceptions.h"

Diff for: ‎soc/runtime/session.c

+503
Large diffs are not rendered by default.

Diff for: ‎soc/runtime/session.h

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#ifndef __SESSION_H
2+
#define __SESSION_H
3+
4+
void session_start(void);
5+
void session_end(void);
6+
7+
int session_input(void *data, int len);
8+
void session_poll(void **data, int *len);
9+
void session_ack(int len);
10+
11+
int rpc(int rpc_num, ...);
12+
void comm_service(void);
13+
14+
#endif /* __SESSION_H */

Diff for: ‎soc/runtime/test_mode.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@
1212

1313
#ifdef ARTIQ_AMP
1414

15-
#include "kernelcpu.h"
15+
#include "kloader.h"
1616
#include "mailbox.h"
1717
#include "messages.h"
1818

1919
static void amp_bridge_init(void)
2020
{
2121
struct msg_base *umsg;
2222

23-
kernelcpu_start(NULL);
23+
kloader_start_bridge();
2424

2525
while(1) {
2626
umsg = mailbox_wait_and_receive();

0 commit comments

Comments
 (0)
Please sign in to comment.