Skip to content

Commit a579b10

Browse files
committedAug 28, 2014
soc/runtime: split main.c, add gcd64
1 parent 4de670b commit a579b10

14 files changed

+301
-210
lines changed
 

‎soc/runtime/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ include $(MSCDIR)/software/common.mak
33
BOARD=papilio_pro
44
SERIAL=/dev/ttyUSB1
55

6-
OBJECTS=isr.o elf_loader.o main.o
6+
OBJECTS=isr.o elf_loader.o symbols.o corecom_serial.o gpio.o rtio.o dds.o main.o
77

88
all: runtime.bin
99

‎soc/runtime/corecom.h

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#ifndef __CORECOM_H
2+
#define __CORECOM_H
3+
4+
int ident_and_download_kernel(void *buffer, int maxlength);
5+
int rpc(int rpc_num, int n_args, ...);
6+
void kernel_finished(void);
7+
8+
#endif /* __CORECOM_H */

‎soc/runtime/corecom_serial.c

+128
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
#include <stdarg.h>
2+
#include <crc.h>
3+
#include <uart.h>
4+
#include <generated/csr.h>
5+
6+
#include "corecom.h"
7+
8+
enum {
9+
MSGTYPE_REQUEST_IDENT = 0x01,
10+
MSGTYPE_LOAD_KERNEL = 0x02,
11+
MSGTYPE_KERNEL_FINISHED = 0x03,
12+
MSGTYPE_RPC_REQUEST = 0x04,
13+
};
14+
15+
static int receive_int(void)
16+
{
17+
unsigned int r;
18+
int i;
19+
20+
r = 0;
21+
for(i=0;i<4;i++) {
22+
r <<= 8;
23+
r |= (unsigned char)uart_read();
24+
}
25+
return r;
26+
}
27+
28+
static char receive_char(void)
29+
{
30+
return uart_read();
31+
}
32+
33+
static void send_int(int x)
34+
{
35+
int i;
36+
37+
for(i=0;i<4;i++) {
38+
uart_write((x & 0xff000000) >> 24);
39+
x <<= 8;
40+
}
41+
}
42+
43+
static void send_sint(short int i)
44+
{
45+
uart_write((i >> 8) & 0xff);
46+
uart_write(i & 0xff);
47+
}
48+
49+
static void send_char(char c)
50+
{
51+
uart_write(c);
52+
}
53+
54+
static void receive_sync(void)
55+
{
56+
char c;
57+
int recognized;
58+
59+
recognized = 0;
60+
while(recognized < 4) {
61+
c = uart_read();
62+
if(c == 0x5a)
63+
recognized++;
64+
else
65+
recognized = 0;
66+
}
67+
}
68+
69+
static void send_sync(void)
70+
{
71+
send_int(0x5a5a5a5a);
72+
}
73+
74+
int ident_and_download_kernel(void *buffer, int maxlength)
75+
{
76+
int length;
77+
unsigned int crc;
78+
int i;
79+
char msgtype;
80+
unsigned char *_buffer = buffer;
81+
82+
while(1) {
83+
receive_sync();
84+
msgtype = receive_char();
85+
if(msgtype == MSGTYPE_REQUEST_IDENT) {
86+
send_int(0x41524f52); /* "AROR" - ARTIQ runtime on OpenRISC */
87+
send_int(1000000000000LL/identifier_frequency_read()); /* RTIO clock period in picoseconds */
88+
} else if(msgtype == MSGTYPE_LOAD_KERNEL) {
89+
length = receive_int();
90+
if(length > maxlength) {
91+
send_char(0x4c); /* Incorrect length */
92+
return -1;
93+
}
94+
crc = receive_int();
95+
for(i=0;i<length;i++)
96+
_buffer[i] = receive_char();
97+
if(crc32(buffer, length) != crc) {
98+
send_char(0x43); /* CRC failed */
99+
return -1;
100+
}
101+
send_char(0x4f); /* kernel reception OK */
102+
return length;
103+
} else
104+
return -1;
105+
}
106+
}
107+
108+
int rpc(int rpc_num, int n_args, ...)
109+
{
110+
send_sync();
111+
send_char(MSGTYPE_RPC_REQUEST);
112+
send_sint(rpc_num);
113+
send_char(n_args);
114+
115+
va_list args;
116+
va_start(args, n_args);
117+
while(n_args--)
118+
send_int(va_arg(args, int));
119+
va_end(args);
120+
121+
return receive_int();
122+
}
123+
124+
void kernel_finished(void)
125+
{
126+
send_sync();
127+
send_char(MSGTYPE_KERNEL_FINISHED);
128+
}

‎soc/runtime/dds.c

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#include <hw/common.h>
2+
3+
#include "dds.h"
4+
5+
#define DDS_FTW0 0x0a
6+
#define DDS_FTW1 0x0b
7+
#define DDS_FTW2 0x0c
8+
#define DDS_FTW3 0x0d
9+
#define DDS_FUD 0x40
10+
#define DDS_GPIO 0x41
11+
12+
#define DDS_READ(addr) \
13+
MMPTR(0xb0000000 + (addr)*4)
14+
15+
#define DDS_WRITE(addr, data) \
16+
MMPTR(0xb0000000 + (addr)*4) = data
17+
18+
void dds_init(void)
19+
{
20+
int i;
21+
22+
DDS_WRITE(DDS_GPIO, 1 << 7);
23+
24+
for(i=0;i<8;i++) {
25+
DDS_WRITE(DDS_GPIO, i);
26+
DDS_WRITE(0x00, 0x78);
27+
DDS_WRITE(0x01, 0x00);
28+
DDS_WRITE(0x02, 0x00);
29+
DDS_WRITE(0x03, 0x00);
30+
DDS_WRITE(DDS_FUD, 0);
31+
}
32+
}
33+
34+
void dds_program(int channel, int ftw)
35+
{
36+
DDS_WRITE(DDS_GPIO, channel);
37+
DDS_WRITE(DDS_FTW0, ftw & 0xff);
38+
DDS_WRITE(DDS_FTW1, (ftw >> 8) & 0xff);
39+
DDS_WRITE(DDS_FTW2, (ftw >> 16) & 0xff);
40+
DDS_WRITE(DDS_FTW3, (ftw >> 24) & 0xff);
41+
DDS_WRITE(DDS_FUD, 0);
42+
}

‎soc/runtime/dds.h

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#ifndef __DDS_H
2+
#define __DDS_H
3+
4+
void dds_init(void);
5+
void dds_program(int channel, int ftw);
6+
7+
#endif /* __DDS_H */

‎soc/runtime/elf_loader.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ struct elf32_sym {
8989
SANITIZE_OFFSET_SIZE(offset, sizeof(target_type)); \
9090
target = (target_type *)((char *)elf_data + offset)
9191

92-
static void *find_symbol(const struct symbol *symbols, const char *name)
92+
void *find_symbol(const struct symbol *symbols, const char *name)
9393
{
9494
int i;
9595

@@ -117,7 +117,7 @@ static int fixup(void *dest, int dest_length, struct elf32_rela *rela, void *tar
117117
return 1;
118118
}
119119

120-
int load_elf(const struct symbol *symbols, void *elf_data, int elf_length, void *dest, int dest_length)
120+
int load_elf(symbol_resolver resolver, void *elf_data, int elf_length, void *dest, int dest_length)
121121
{
122122
struct elf32_ehdr *ehdr;
123123
struct elf32_shdr *strtable;
@@ -199,7 +199,7 @@ int load_elf(const struct symbol *symbols, void *elf_data, int elf_length, void
199199
void *target;
200200

201201
name = (char *)elf_data + strtaboff + sym->name;
202-
target = find_symbol(symbols, name);
202+
target = resolver(name);
203203
if(target == NULL) {
204204
printf("Undefined symbol: %s\n", name);
205205
return 0;

‎soc/runtime/elf_loader.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ struct symbol {
66
void *target;
77
};
88

9-
int load_elf(const struct symbol *symbols, void *elf_data, int elf_length, void *dest, int dest_length);
9+
void *find_symbol(const struct symbol *symbols, const char *name);
10+
11+
typedef void * (*symbol_resolver)(const char *name);
12+
int load_elf(symbol_resolver resolver, void *elf_data, int elf_length, void *dest, int dest_length);
1013

1114
#endif /* __ELF_LOADER_H */

‎soc/runtime/gpio.c

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#include <generated/csr.h>
2+
3+
#include "gpio.h"
4+
5+
void gpio_set(int channel, int value)
6+
{
7+
static int csr_value;
8+
9+
if(value)
10+
csr_value |= 1 << channel;
11+
else
12+
csr_value &= ~(1 << channel);
13+
leds_out_write(csr_value);
14+
}

‎soc/runtime/gpio.h

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#ifndef __GPIO_H
2+
#define __GPIO_H
3+
4+
void gpio_set(int channel, int value);
5+
6+
#endif /* __GPIO_H */

‎soc/runtime/main.c

+9-205
Original file line numberDiff line numberDiff line change
@@ -1,208 +1,13 @@
11
#include <stdio.h>
2-
#include <stdlib.h>
3-
#include <string.h>
4-
#include <stdarg.h>
5-
#include <crc.h>
6-
72
#include <irq.h>
83
#include <uart.h>
9-
#include <console.h>
104
#include <system.h>
11-
#include <hw/common.h>
12-
#include <generated/csr.h>
135

6+
#include "corecom.h"
147
#include "elf_loader.h"
15-
16-
enum {
17-
MSGTYPE_REQUEST_IDENT = 0x01,
18-
MSGTYPE_LOAD_KERNEL = 0x02,
19-
MSGTYPE_KERNEL_FINISHED = 0x03,
20-
MSGTYPE_RPC_REQUEST = 0x04,
21-
};
22-
23-
static int receive_int(void)
24-
{
25-
unsigned int r;
26-
int i;
27-
28-
r = 0;
29-
for(i=0;i<4;i++) {
30-
r <<= 8;
31-
r |= (unsigned char)uart_read();
32-
}
33-
return r;
34-
}
35-
36-
static char receive_char(void)
37-
{
38-
return uart_read();
39-
}
40-
41-
static void send_int(int x)
42-
{
43-
int i;
44-
45-
for(i=0;i<4;i++) {
46-
uart_write((x & 0xff000000) >> 24);
47-
x <<= 8;
48-
}
49-
}
50-
51-
static void send_sint(short int i)
52-
{
53-
uart_write((i >> 8) & 0xff);
54-
uart_write(i & 0xff);
55-
}
56-
57-
static void send_char(char c)
58-
{
59-
uart_write(c);
60-
}
61-
62-
static void receive_sync(void)
63-
{
64-
char c;
65-
int recognized;
66-
67-
recognized = 0;
68-
while(recognized < 4) {
69-
c = uart_read();
70-
if(c == 0x5a)
71-
recognized++;
72-
else
73-
recognized = 0;
74-
}
75-
}
76-
77-
static void send_sync(void)
78-
{
79-
send_int(0x5a5a5a5a);
80-
}
81-
82-
static int ident_and_download_kernel(void *buffer, int maxlength)
83-
{
84-
int length;
85-
unsigned int crc;
86-
int i;
87-
char msgtype;
88-
unsigned char *_buffer = buffer;
89-
90-
while(1) {
91-
receive_sync();
92-
msgtype = receive_char();
93-
if(msgtype == MSGTYPE_REQUEST_IDENT) {
94-
send_int(0x41524f52); /* "AROR" - ARTIQ runtime on OpenRISC */
95-
send_int(1000000000000LL/identifier_frequency_read()); /* RTIO clock period in picoseconds */
96-
} else if(msgtype == MSGTYPE_LOAD_KERNEL) {
97-
length = receive_int();
98-
if(length > maxlength) {
99-
send_char(0x4c); /* Incorrect length */
100-
return -1;
101-
}
102-
crc = receive_int();
103-
for(i=0;i<length;i++)
104-
_buffer[i] = receive_char();
105-
if(crc32(buffer, length) != crc) {
106-
send_char(0x43); /* CRC failed */
107-
return -1;
108-
}
109-
send_char(0x4f); /* kernel reception OK */
110-
return length;
111-
} else
112-
return -1;
113-
}
114-
}
115-
116-
static int rpc(int rpc_num, int n_args, ...)
117-
{
118-
send_sync();
119-
send_char(MSGTYPE_RPC_REQUEST);
120-
send_sint(rpc_num);
121-
send_char(n_args);
122-
123-
va_list args;
124-
va_start(args, n_args);
125-
while(n_args--)
126-
send_int(va_arg(args, int));
127-
va_end(args);
128-
129-
return receive_int();
130-
}
131-
132-
static void gpio_set(int channel, int value)
133-
{
134-
static int csr_value;
135-
136-
if(value)
137-
csr_value |= 1 << channel;
138-
else
139-
csr_value &= ~(1 << channel);
140-
leds_out_write(csr_value);
141-
}
142-
143-
static void rtio_set(long long int timestamp, int channel, int value)
144-
{
145-
rtio_reset_write(0);
146-
rtio_chan_sel_write(channel);
147-
rtio_o_timestamp_write(timestamp);
148-
rtio_o_value_write(value);
149-
while(!rtio_o_writable_read());
150-
rtio_o_we_write(1);
151-
}
152-
153-
static void rtio_sync(int channel)
154-
{
155-
rtio_chan_sel_write(channel);
156-
while(rtio_o_level_read() != 0);
157-
}
158-
159-
#define DDS_FTW0 0x0a
160-
#define DDS_FTW1 0x0b
161-
#define DDS_FTW2 0x0c
162-
#define DDS_FTW3 0x0d
163-
#define DDS_FUD 0x40
164-
#define DDS_GPIO 0x41
165-
166-
#define DDS_READ(addr) \
167-
MMPTR(0xb0000000 + (addr)*4)
168-
169-
#define DDS_WRITE(addr, data) \
170-
MMPTR(0xb0000000 + (addr)*4) = data
171-
172-
static void dds_program(int channel, int ftw)
173-
{
174-
DDS_WRITE(DDS_GPIO, channel);
175-
DDS_WRITE(DDS_FTW0, ftw & 0xff);
176-
DDS_WRITE(DDS_FTW1, (ftw >> 8) & 0xff);
177-
DDS_WRITE(DDS_FTW2, (ftw >> 16) & 0xff);
178-
DDS_WRITE(DDS_FTW3, (ftw >> 24) & 0xff);
179-
DDS_WRITE(DDS_FUD, 0);
180-
}
181-
182-
static const struct symbol syscalls[] = {
183-
{"__syscall_rpc", rpc},
184-
{"__syscall_gpio_set", gpio_set},
185-
{"__syscall_rtio_set", rtio_set},
186-
{"__syscall_rtio_sync", rtio_sync},
187-
{"__syscall_dds_program", dds_program},
188-
{NULL, NULL}
189-
};
190-
191-
static void dds_init(void)
192-
{
193-
int i;
194-
195-
DDS_WRITE(DDS_GPIO, 1 << 7);
196-
197-
for(i=0;i<8;i++) {
198-
DDS_WRITE(DDS_GPIO, i);
199-
DDS_WRITE(0x00, 0x78);
200-
DDS_WRITE(0x01, 0x00);
201-
DDS_WRITE(0x02, 0x00);
202-
DDS_WRITE(0x03, 0x00);
203-
DDS_WRITE(DDS_FUD, 0);
204-
}
205-
}
8+
#include "symbols.h"
9+
#include "rtio.h"
10+
#include "dds.h"
20611

20712
typedef void (*kernel_function)(void);
20813

@@ -222,16 +27,15 @@ int main(void)
22227
while(1) {
22328
length = ident_and_download_kernel(kbuf, sizeof(kbuf));
22429
if(length > 0) {
225-
if(load_elf(syscalls, kbuf, length, kcode, sizeof(kcode))) {
226-
flush_cpu_icache();
30+
if(load_elf(resolve_symbol, kbuf, length, kcode, sizeof(kcode))) {
31+
rtio_init();
22732
dds_init();
33+
flush_cpu_icache();
22834
k();
229-
rtio_reset_write(1);
230-
send_sync();
231-
send_char(MSGTYPE_KERNEL_FINISHED);
35+
kernel_finished();
23236
}
23337
}
23438
}
235-
39+
23640
return 0;
23741
}

‎soc/runtime/rtio.c

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#include <generated/csr.h>
2+
3+
#include "rtio.h"
4+
5+
void rtio_init(void)
6+
{
7+
rtio_reset_write(1);
8+
}
9+
10+
void rtio_set(long long int timestamp, int channel, int value)
11+
{
12+
rtio_reset_write(0);
13+
rtio_chan_sel_write(channel);
14+
rtio_o_timestamp_write(timestamp);
15+
rtio_o_value_write(value);
16+
while(!rtio_o_writable_read());
17+
rtio_o_we_write(1);
18+
}
19+
20+
void rtio_sync(int channel)
21+
{
22+
rtio_chan_sel_write(channel);
23+
while(rtio_o_level_read() != 0);
24+
}

‎soc/runtime/rtio.h

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#ifndef __RTIO_H
2+
#define __RTIO_H
3+
4+
void rtio_init(void);
5+
void rtio_set(long long int timestamp, int channel, int value);
6+
void rtio_sync(int channel);
7+
8+
#endif /* __RTIO_H */

‎soc/runtime/symbols.c

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#include <string.h>
2+
3+
#include "elf_loader.h"
4+
#include "corecom.h"
5+
#include "gpio.h"
6+
#include "rtio.h"
7+
#include "dds.h"
8+
#include "symbols.h"
9+
10+
static const struct symbol syscalls[] = {
11+
{"rpc", rpc},
12+
{"gpio_set", gpio_set},
13+
{"rtio_set", rtio_set},
14+
{"rtio_sync", rtio_sync},
15+
{"dds_program", dds_program},
16+
{NULL, NULL}
17+
};
18+
19+
static long long int gcd64(long long int a, long long int b)
20+
{
21+
long long int c;
22+
23+
while(a) {
24+
c = a;
25+
a = b % a;
26+
b = c;
27+
}
28+
return b;
29+
}
30+
31+
static const struct symbol arithmetic[] = {
32+
{"__gcd64", gcd64},
33+
{NULL, NULL}
34+
};
35+
36+
void *resolve_symbol(const char *name)
37+
{
38+
if(strncmp(name, "__syscall_", 10) == 0)
39+
return find_symbol(syscalls, name + 10);
40+
return find_symbol(arithmetic, name);
41+
}

‎soc/runtime/symbols.h

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#ifndef __SYMBOLS_H
2+
#define __SYMBOLS_H
3+
4+
void *resolve_symbol(const char *name);
5+
6+
#endif /* __SYMBOLS_H */

0 commit comments

Comments
 (0)
Please sign in to comment.