Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
M
mock-turtle
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
hdl-core-lib
mock-turtle
Commits
475bc35d
Commit
475bc35d
authored
Apr 27, 2018
by
Federico Vaga
Browse files
Options
Browse Files
Download
Plain Diff
sw:rt redesign and re-organization
It compiles ... still to be tested, the HDL is not ready yet
parents
c6c69f99
05f17114
Hide whitespace changes
Inline
Side-by-side
Showing
54 changed files
with
1984 additions
and
2504 deletions
+1984
-2504
fw-ac.c
demos/alarm_clock/firmware/fw-01/fw-ac.c
+8
-41
fw-dg.c
demos/data_generator/firmware/fw-01/fw-dg.c
+9
-39
fw-svec-common.h
...mc-svec-carrier/software/firmware/common/fw-svec-common.h
+1
-1
fw-svec.c
demos/fmc-svec-carrier/software/firmware/fw-02/fw-svec.c
+6
-27
svec-common.h
demos/fmc-svec-carrier/software/include/svec-common.h
+4
-4
libsvec.c
demos/fmc-svec-carrier/software/lib/libsvec.c
+15
-22
libsvec.h
demos/fmc-svec-carrier/software/lib/libsvec.h
+1
-1
mockturtle-svec.c
demos/fmc-svec-carrier/software/tools/mockturtle-svec.c
+2
-3
fw-hello.c
demos/hello_world/firmware/fw-01/fw-hello.c
+1
-1
fw-hellofrm.c
demos/hello_world_framework/firmware/fw-01/fw-hellofrm.c
+5
-25
mockturtle_config.h
software/include/hw/mockturtle_config.h
+0
-52
mockturtle-common.h
software/include/mockturtle-common.h
+0
-198
mockturtle.h
software/include/mockturtle.h
+189
-19
mockturtle-core.c
software/kernel/mockturtle-core.c
+1
-2
mockturtle-drv.h
software/kernel/mockturtle-drv.h
+0
-1
PyMockTurtle.py
software/lib/PyMockTurtle/PyMockTurtle/PyMockTurtle.py
+34
-1
libmockturtle-internal.h
software/lib/libmockturtle-internal.h
+2
-0
libmockturtle-rt-msg.c
software/lib/libmockturtle-rt-msg.c
+205
-210
libmockturtle.c
software/lib/libmockturtle.c
+2
-0
libmockturtle.h
software/lib/libmockturtle.h
+13
-47
Makefile
software/rt/Makefile
+2
-4
mockturtle-framework.c
software/rt/framework/mockturtle-framework.c
+685
-0
mockturtle-framework.h
software/rt/framework/mockturtle-framework.h
+90
-5
mockturtle-frm-action.c
software/rt/framework/mockturtle-frm-action.c
+0
-369
mockturtle-frm-action.h
software/rt/framework/mockturtle-frm-action.h
+0
-63
mockturtle-frm-buffer.h
software/rt/framework/mockturtle-frm-buffer.h
+0
-26
mockturtle-frm-common.h
software/rt/framework/mockturtle-frm-common.h
+0
-56
mockturtle-frm-core.c
software/rt/framework/mockturtle-frm-core.c
+0
-130
mockturtle-frm-debug.c
software/rt/framework/mockturtle-frm-debug.c
+0
-87
mockturtle-frm-debug.h
software/rt/framework/mockturtle-frm-debug.h
+0
-23
mockturtle-frm-mqueue.c
software/rt/framework/mockturtle-frm-mqueue.c
+0
-93
mockturtle-frm-mqueue.h
software/rt/framework/mockturtle-frm-mqueue.h
+0
-81
mockturtle-frm-variable.h
software/rt/framework/mockturtle-frm-variable.h
+0
-32
mockturtle-rt-message.h
software/rt/framework/mockturtle-rt-message.h
+0
-81
mockturtle-rt-common.c
software/rt/lib/mockturtle-rt-common.c
+1
-1
mockturtle-rt-common.h
software/rt/lib/mockturtle-rt-common.h
+0
-148
mockturtle-rt-mqueue.h
software/rt/lib/mockturtle-rt-mqueue.h
+0
-188
mockturtle-rt-serial.h
software/rt/lib/mockturtle-rt-serial.h
+0
-145
mockturtle-rt-smem.h
software/rt/lib/mockturtle-rt-smem.h
+0
-222
mockturtle-rt.h
software/rt/lib/mockturtle-rt.h
+667
-5
printf.c
software/rt/lib/printf.c
+1
-2
mockturtle-buffer.c
software/tools/mockturtle-buffer.c
+7
-7
mockturtle-ping.c
software/tools/mockturtle-ping.c
+4
-6
mockturtle-smem.c
software/tools/mockturtle-smem.c
+1
-1
mockturtle-variable.c
software/tools/mockturtle-variable.c
+2
-2
fw-project.c
...ct-creator/templates/software/firmware/fw-01/fw-project.c
+7
-7
config_rom.c
tests/firmware/config_rom/config_rom.c
+0
-1
cpu-loop.c
tests/firmware/cpu-loop/cpu-loop.c
+0
-2
hmq-async-recv.c
tests/firmware/hmq-async-recv/hmq-async-recv.c
+0
-1
hmq-async-send.c
tests/firmware/hmq-async-send/hmq-async-send.c
+3
-4
hmq-purge.c
tests/firmware/hmq-purge/hmq-purge.c
+8
-9
hmq-sync.c
tests/firmware/hmq-sync/hmq-sync.c
+3
-4
serial.c
tests/firmware/serial/serial.c
+1
-1
sim-verif.c
tests/firmware/sim-verif/sim-verif.c
+4
-4
No files found.
demos/alarm_clock/firmware/fw-01/fw-ac.c
View file @
475bc35d
...
@@ -4,7 +4,6 @@
...
@@ -4,7 +4,6 @@
* License: GPLv3
* License: GPLv3
*/
*/
#include <mockturtle-rt-smem.h>
#include <mockturtle-framework.h>
#include <mockturtle-framework.h>
static
unsigned
int
iteration
;
static
unsigned
int
iteration
;
...
@@ -13,31 +12,6 @@ static unsigned int period = 1000000;
...
@@ -13,31 +12,6 @@ static unsigned int period = 1000000;
static
unsigned
int
alarm_enable
;
static
unsigned
int
alarm_enable
;
static
uint32_t
alarm_iter
;
static
uint32_t
alarm_iter
;
enum
rt_slot_name
{
AC_CMD_IN
=
0
,
AC_CMD_OUT
,
AC_DATA
,
};
static
struct
rt_mq
mq
[]
=
{
[
AC_CMD_IN
]
=
{
.
type
=
TRTL_HMQ
,
.
index
=
0
,
.
flags
=
TRTL_RT_MQ_FLAGS_INPUT
,
},
[
AC_CMD_OUT
]
=
{
.
type
=
TRTL_HMQ
,
.
index
=
0
,
.
flags
=
TRTL_RT_MQ_FLAGS_OUTPUT
,
},
[
AC_DATA
]
=
{
.
type
=
TRTL_HMQ
,
.
index
=
1
,
.
flags
=
TRTL_RT_MQ_FLAGS_OUTPUT
|
TRTL_RT_MQ_FLAGS_CLAIM
,
},
};
enum
ac_variable
{
enum
ac_variable
{
AC_TIME
=
0
,
AC_TIME
=
0
,
AC_PERIOD_UPDATE
,
AC_PERIOD_UPDATE
,
...
@@ -45,7 +19,7 @@ enum ac_variable {
...
@@ -45,7 +19,7 @@ enum ac_variable {
AC_ALARM_ITER
,
AC_ALARM_ITER
,
};
};
static
struct
rt
_variable
variables
[]
=
{
static
struct
trtl_fw
_variable
variables
[]
=
{
[
AC_TIME
]
=
{
[
AC_TIME
]
=
{
.
addr
=
(
void
*
)
&
iteration
,
.
addr
=
(
void
*
)
&
iteration
,
.
mask
=
0xFFFFFFFF
,
.
mask
=
0xFFFFFFFF
,
...
@@ -72,16 +46,13 @@ static struct rt_variable variables[] = {
...
@@ -72,16 +46,13 @@ static struct rt_variable variables[] = {
},
},
};
};
static
struct
rt
_application
app
=
{
static
struct
trtl_fw
_application
app
=
{
.
name
=
"alarm-clk"
,
.
name
=
"alarm-clk"
,
.
version
=
{
.
version
=
{
.
fpga_id
=
CONFIG_FPGA_APPLICATION_ID
,
.
rt_id
=
CONFIG_RT_APPLICATION_ID
,
.
rt_id
=
CONFIG_RT_APPLICATION_ID
,
.
rt_version
=
RT_VERSION
(
0
,
1
),
.
rt_version
=
RT_VERSION
(
0
,
1
),
.
git_version
=
GIT_VERSION
.
git_version
=
GIT_VERSION
},
},
.
mq
=
mq
,
.
n_mq
=
ARRAY_SIZE
(
mq
),
.
variables
=
variables
,
.
variables
=
variables
,
.
n_variables
=
ARRAY_SIZE
(
variables
),
.
n_variables
=
ARRAY_SIZE
(
variables
),
...
@@ -92,18 +63,18 @@ static void ac_update(void)
...
@@ -92,18 +63,18 @@ static void ac_update(void)
{
{
uint32_t
sec
,
cyc
;
uint32_t
sec
,
cyc
;
rt_get
_time
(
&
sec
,
&
cyc
);
trtl_fw
_time
(
&
sec
,
&
cyc
);
if
((
--
period_c
)
==
0
)
{
if
((
--
period_c
)
==
0
)
{
period_c
=
period
;
period_c
=
period
;
trtl_
rt_mq_send_uint32
(
AC_DATA
,
0x12
,
1
,
trtl_
fw_mq_send_uint32
(
TRTL_HMQ
,
0
,
0x12
,
1
,
iteration
);
iteration
);
pr_debug
(
"Iteration %d
\n\r
"
,
iteration
);
pr_debug
(
"Iteration %d
\n\r
"
,
iteration
);
}
}
if
(
alarm_enable
)
{
if
(
alarm_enable
)
{
if
(
alarm_iter
<
iteration
)
{
if
(
alarm_iter
<
iteration
)
{
trtl_
rt_mq_send_uint32
(
AC_DATA
,
0x34
,
2
,
trtl_
fw_mq_send_uint32
(
TRTL_HMQ
,
0
,
0x34
,
2
,
iteration
,
alarm_iter
);
iteration
,
alarm_iter
);
alarm_enable
=
0
;
alarm_enable
=
0
;
alarm_iter
=
0
;
alarm_iter
=
0
;
...
@@ -128,16 +99,12 @@ static void ac_init(void)
...
@@ -128,16 +99,12 @@ static void ac_init(void)
*/
*/
int
main
()
int
main
()
{
{
rt
_init
(
&
app
);
trtl_fw
_init
(
&
app
);
ac_init
();
ac_init
();
while
(
1
)
{
while
(
1
)
{
/*
/* Handle all messages incoming from HMQ 0 as actions */
* Handle all messages incoming from slot
trtl_fw_mq_action_dispatch
(
TRTL_HMQ
,
0
);
* AC_CMD_IN
* as actions
*/
rt_mq_action_dispatch
(
AC_CMD_IN
);
ac_update
();
ac_update
();
}
}
...
...
demos/data_generator/firmware/fw-01/fw-dg.c
View file @
475bc35d
...
@@ -22,36 +22,11 @@ static struct dg_conf dg_conf;
...
@@ -22,36 +22,11 @@ static struct dg_conf dg_conf;
static
uint32_t
dg_last_sample_idx
;
static
uint32_t
dg_last_sample_idx
;
static
uint32_t
dg_last_sample
=
1
;
static
uint32_t
dg_last_sample
=
1
;
enum
rt_slot_name
{
DG_MQ_CMD_IN
=
0
,
DG_MQ_CMD_OUT
,
DG_MQ_DATA
,
};
static
struct
rt_mq
mq
[]
=
{
[
DG_MQ_CMD_IN
]
=
{
.
type
=
TRTL_HMQ
,
.
index
=
0
,
.
flags
=
TRTL_RT_MQ_FLAGS_INPUT
,
},
[
DG_MQ_CMD_OUT
]
=
{
.
type
=
TRTL_HMQ
,
.
index
=
0
,
.
flags
=
TRTL_RT_MQ_FLAGS_OUTPUT
,
},
[
DG_MQ_DATA
]
=
{
.
type
=
TRTL_HMQ
,
.
index
=
1
,
.
flags
=
TRTL_RT_MQ_FLAGS_OUTPUT
|
TRTL_RT_MQ_FLAGS_CLAIM
,
},
};
enum
dg_variable
{
enum
dg_variable
{
DG_PERIOD_UPDATE
=
0
,
DG_PERIOD_UPDATE
=
0
,
};
};
static
struct
rt
_variable
variables
[]
=
{
static
struct
trtl_fw
_variable
variables
[]
=
{
[
DG_PERIOD_UPDATE
]
=
{
[
DG_PERIOD_UPDATE
]
=
{
.
addr
=
(
void
*
)
&
period
,
.
addr
=
(
void
*
)
&
period
,
.
mask
=
0xFFFFFFFF
,
.
mask
=
0xFFFFFFFF
,
...
@@ -65,7 +40,7 @@ enum dg_structures {
...
@@ -65,7 +40,7 @@ enum dg_structures {
DG_CONF
,
DG_CONF
,
};
};
struct
rt
_buffer
buffers
[]
=
{
struct
trtl_fw
_buffer
buffers
[]
=
{
[
DG_DATA
]
=
{
[
DG_DATA
]
=
{
.
buf
=
dg_data
,
.
buf
=
dg_data
,
.
len
=
sizeof
(
dg_data
),
.
len
=
sizeof
(
dg_data
),
...
@@ -76,16 +51,13 @@ struct rt_buffer buffers[] = {
...
@@ -76,16 +51,13 @@ struct rt_buffer buffers[] = {
},
},
};
};
static
struct
rt
_application
app
=
{
static
struct
trtl_fw
_application
app
=
{
.
name
=
"data-gen"
,
.
name
=
"data-gen"
,
.
version
=
{
.
version
=
{
.
fpga_id
=
CONFIG_FPGA_APPLICATION_ID
,
.
rt_id
=
CONFIG_RT_APPLICATION_ID
,
.
rt_id
=
CONFIG_RT_APPLICATION_ID
,
.
rt_version
=
RT_VERSION
(
0
,
1
),
.
rt_version
=
RT_VERSION
(
0
,
1
),
.
git_version
=
GIT_VERSION
.
git_version
=
GIT_VERSION
},
},
.
mq
=
mq
,
.
n_mq
=
ARRAY_SIZE
(
mq
),
.
variables
=
variables
,
.
variables
=
variables
,
.
n_variables
=
ARRAY_SIZE
(
variables
),
.
n_variables
=
ARRAY_SIZE
(
variables
),
...
@@ -109,7 +81,9 @@ static void generate_sample(void)
...
@@ -109,7 +81,9 @@ static void generate_sample(void)
dg_last_sample_idx
+
1
,
DG_BUF_SIZE
,
dg_last_sample
);
dg_last_sample_idx
+
1
,
DG_BUF_SIZE
,
dg_last_sample
);
dg_data
[
dg_last_sample_idx
]
=
dg_last_sample
;
dg_data
[
dg_last_sample_idx
]
=
dg_last_sample
;
dg_last_sample_idx
=
++
dg_last_sample_idx
&
(
DG_BUF_SIZE
-
1
);
dg_last_sample_idx
++
;
dg_last_sample_idx
&=
(
DG_BUF_SIZE
-
1
);
}
}
static
void
dg_update
(
void
)
static
void
dg_update
(
void
)
...
@@ -139,16 +113,12 @@ static void dg_init(void)
...
@@ -139,16 +113,12 @@ static void dg_init(void)
*/
*/
int
main
()
int
main
()
{
{
rt
_init
(
&
app
);
trtl_fw
_init
(
&
app
);
dg_init
();
dg_init
();
while
(
1
)
{
while
(
1
)
{
/*
/* Handle all messages incoming from HMQ 0 as actions */
* Handle all messages incoming from slot
trtl_fw_mq_action_dispatch
(
TRTL_HMQ
,
0
);
* DG_MQ_CMD_IN
* as actions
*/
rt_mq_action_dispatch
(
DG_MQ_CMD_IN
);
dg_update
();
dg_update
();
}
}
...
...
demos/fmc-svec-carrier/software/firmware/common/fw-svec-common.h
View file @
475bc35d
...
@@ -5,7 +5,7 @@
...
@@ -5,7 +5,7 @@
#ifndef __FW_SVEC_COMMON_H__
#ifndef __FW_SVEC_COMMON_H__
#define __FW_SVEC_COMMON_H__
#define __FW_SVEC_COMMON_H__
#include <mockturtle-rt
-smem
.h>
#include <mockturtle-rt.h>
#include <svec-common.h>
#include <svec-common.h>
extern
volatile
int
autosvec_run
;
extern
volatile
int
autosvec_run
;
...
...
demos/fmc-svec-carrier/software/firmware/fw-02/fw-svec.c
View file @
475bc35d
...
@@ -15,33 +15,16 @@
...
@@ -15,33 +15,16 @@
#define GPIO_DDR 0x8
/* Direction Data Register */
#define GPIO_DDR 0x8
/* Direction Data Register */
#define GPIO_PSR 0xC
/* Status Register */
#define GPIO_PSR 0xC
/* Status Register */
enum
rt_slot_name
{
SVEC_CMD_IN
=
0
,
SVEC_CMD_OUT
,
};
struct
rt_mq
mq
[]
=
{
[
SVEC_CMD_IN
]
=
{
.
index
=
0
,
.
flags
=
TRTL_RT_MQ_FLAGS_HMQ
|
TRTL_RT_MQ_FLAGS_INPUT
,
},
[
SVEC_CMD_OUT
]
=
{
.
index
=
0
,
.
flags
=
TRTL_RT_MQ_FLAGS_HMQ
|
TRTL_RT_MQ_FLAGS_OUTPUT
,
},
};
static
struct
svec_structure
svec_struct
;
static
struct
svec_structure
svec_struct
;
struct
rt
_buffer
svec_buffers
[]
=
{
struct
trtl_fw
_buffer
svec_buffers
[]
=
{
[
SVEC_BUF_TEST
]
=
{
[
SVEC_BUF_TEST
]
=
{
.
buf
=
&
svec_struct
,
.
buf
=
&
svec_struct
,
.
len
=
sizeof
(
struct
svec_structure
),
.
len
=
sizeof
(
struct
svec_structure
),
}
}
};
};
struct
rt
_variable
svec_variables
[]
=
{
struct
trtl_fw
_variable
svec_variables
[]
=
{
[
SVEC_VAR_LEMO_STA
]
=
{
[
SVEC_VAR_LEMO_STA
]
=
{
.
addr
=
TRTL_ADDR_DP
(
GPIO_PSR
),
.
addr
=
TRTL_ADDR_DP
(
GPIO_PSR
),
.
mask
=
PIN_LEMO_MASK
,
.
mask
=
PIN_LEMO_MASK
,
...
@@ -85,16 +68,13 @@ struct rt_variable svec_variables[] = {
...
@@ -85,16 +68,13 @@ struct rt_variable svec_variables[] = {
};
};
struct
rt
_application
app
=
{
struct
trtl_fw
_application
app
=
{
.
name
=
"svec-svec"
,
.
name
=
"svec-svec"
,
.
version
=
{
.
version
=
{
.
fpga_id
=
FPGA_APPLICATION_ID
,
.
rt_id
=
RT_APPLICATION_ID
,
.
rt_id
=
RT_APPLICATION_ID
,
.
rt_version
=
RT_VERSION
(
1
,
0
),
.
rt_version
=
RT_VERSION
(
1
,
0
),
.
git_version
=
GIT_VERSION
.
git_version
=
GIT_VERSION
},
},
.
mq
=
mq
,
.
n_mq
=
2
,
.
buffers
=
svec_buffers
,
.
buffers
=
svec_buffers
,
.
n_buffers
=
ARRAY_SIZE
(
svec_buffers
),
.
n_buffers
=
ARRAY_SIZE
(
svec_buffers
),
...
@@ -119,13 +99,12 @@ static void svec_debug_interface(void)
...
@@ -119,13 +99,12 @@ static void svec_debug_interface(void)
*/
*/
int
main
()
int
main
()
{
{
rt
_init
(
&
app
);
trtl_fw
_init
(
&
app
);
svec_debug_interface
();
svec_debug_interface
();
while
(
1
)
{
while
(
1
)
{
/* Handle all messages incoming from slot SVEC_HMQ_IN
/* Handle all messages incoming from HMQ 0 as actions */
as actions */
trtl_fw_mq_action_dispatch
(
TRTL_HMQ
,
0
);
rt_mq_action_dispatch
(
SVEC_CMD_IN
);
}
}
return
0
;
return
0
;
...
...
demos/fmc-svec-carrier/software/include/svec-common.h
View file @
475bc35d
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
#ifndef __SVEC_COMMON_H
#ifndef __SVEC_COMMON_H
#define __SVEC_COMMON_H
#define __SVEC_COMMON_H
#include <mockturtle
-common
.h>
#include <mockturtle.h>
/* HMQ slots used for input */
/* HMQ slots used for input */
...
@@ -18,7 +18,7 @@
...
@@ -18,7 +18,7 @@
#define SVEC_HMQ_OUT 0
#define SVEC_HMQ_OUT 0
/* Variable index - used only by svec-librt */
/* Variable index - used only by svec-librt */
enum
rt
_variable_index
{
enum
trtl_fw
_variable_index
{
SVEC_VAR_LEMO_STA
=
0
,
SVEC_VAR_LEMO_STA
=
0
,
SVEC_VAR_LEMO_DIR
,
SVEC_VAR_LEMO_DIR
,
SVEC_VAR_LEMO_SET
,
SVEC_VAR_LEMO_SET
,
...
@@ -30,14 +30,14 @@ enum rt_variable_index {
...
@@ -30,14 +30,14 @@ enum rt_variable_index {
__SVEC_VAR_MAX
,
__SVEC_VAR_MAX
,
};
};
enum
rt
_buffer_index
{
enum
trtl_fw
_buffer_index
{
SVEC_BUF_TEST
=
0
,
SVEC_BUF_TEST
=
0
,
__SVEC_BUF_MAX
,
__SVEC_BUF_MAX
,
};
};
/* Command and log message IDs */
/* Command and log message IDs */
enum
rt_action_recv_svec
{
enum
rt_action_recv_svec
{
SVEC_ID_LED_SET
=
__RT_ACTION_RECV_STANDARD_NUMBER
,
SVEC_ID_LED_SET
=
0
,
SVEC_ID_LEMO_SET
,
SVEC_ID_LEMO_SET
,
SVEC_ID_LEMO_DIR_SET
,
SVEC_ID_LEMO_DIR_SET
,
SVEC_ID_STATE_GET
,
SVEC_ID_STATE_GET
,
...
...
demos/fmc-svec-carrier/software/lib/libsvec.c
View file @
475bc35d
...
@@ -14,13 +14,6 @@
...
@@ -14,13 +14,6 @@
#include <libmockturtle.h>
#include <libmockturtle.h>
#include <libsvec-internal.h>
#include <libsvec-internal.h>
static
const
struct
trtl_proto_header
hdr_tmpl
=
{
.
rt_app_id
=
0
,
.
slot_io
=
(
SVEC_HMQ_IN
<<
4
)
|
(
SVEC_HMQ_OUT
&
0xF
),
};
const
char
*
svec_errors
[]
=
{
const
char
*
svec_errors
[]
=
{
"Received an invalid answer from white-rabbit-node-code CPU"
,
"Received an invalid answer from white-rabbit-node-code CPU"
,
"Real-Time application does not acknowledge"
,
"Real-Time application does not acknowledge"
,
...
@@ -132,7 +125,7 @@ int svec_lemo_dir_set(struct svec_node *dev, uint32_t value)
...
@@ -132,7 +125,7 @@ int svec_lemo_dir_set(struct svec_node *dev, uint32_t value)
struct
svec_desc
*
svec
=
(
struct
svec_desc
*
)
dev
;
struct
svec_desc
*
svec
=
(
struct
svec_desc
*
)
dev
;
uint32_t
fields
[]
=
{
SVEC_VAR_LEMO_DIR
,
value
};
uint32_t
fields
[]
=
{
SVEC_VAR_LEMO_DIR
,
value
};
return
trtl_
rt
_variable_set
(
svec
->
trtl
,
return
trtl_
fw
_variable_set
(
svec
->
trtl
,
SVEC_CPU_MANUAL
,
SVEC_CPU_MANUAL_HMQ
,
SVEC_CPU_MANUAL
,
SVEC_CPU_MANUAL_HMQ
,
fields
,
1
);
fields
,
1
);
}
}
...
@@ -143,7 +136,7 @@ int svec_lemo_set(struct svec_node *dev, uint32_t value)
...
@@ -143,7 +136,7 @@ int svec_lemo_set(struct svec_node *dev, uint32_t value)
uint32_t
fields
[]
=
{
SVEC_VAR_LEMO_SET
,
value
,
uint32_t
fields
[]
=
{
SVEC_VAR_LEMO_SET
,
value
,
SVEC_VAR_LEMO_CLR
,
~
value
};
SVEC_VAR_LEMO_CLR
,
~
value
};
return
trtl_
rt
_variable_set
(
svec
->
trtl
,
return
trtl_
fw
_variable_set
(
svec
->
trtl
,
SVEC_CPU_MANUAL
,
SVEC_CPU_MANUAL_HMQ
,
SVEC_CPU_MANUAL
,
SVEC_CPU_MANUAL_HMQ
,
fields
,
2
);
fields
,
2
);
}
}
...
@@ -185,7 +178,7 @@ int svec_led_set(struct svec_node *dev, uint32_t value, enum svec_color color)
...
@@ -185,7 +178,7 @@ int svec_led_set(struct svec_node *dev, uint32_t value, enum svec_color color)
uint32_t
fields
[]
=
{
SVEC_VAR_LED_SET
,
real_value
,
uint32_t
fields
[]
=
{
SVEC_VAR_LED_SET
,
real_value
,
SVEC_VAR_LED_CLR
,
~
real_value
};
SVEC_VAR_LED_CLR
,
~
real_value
};
return
trtl_
rt
_variable_set
(
svec
->
trtl
,
return
trtl_
fw
_variable_set
(
svec
->
trtl
,
SVEC_CPU_MANUAL
,
SVEC_CPU_MANUAL_HMQ
,
SVEC_CPU_MANUAL
,
SVEC_CPU_MANUAL_HMQ
,
fields
,
2
);
fields
,
2
);
}
}
...
@@ -202,7 +195,7 @@ int svec_status_get(struct svec_node *dev, struct svec_status *status)
...
@@ -202,7 +195,7 @@ int svec_status_get(struct svec_node *dev, struct svec_status *status)
SVEC_VAR_LEMO_DIR
,
0
};
SVEC_VAR_LEMO_DIR
,
0
};
int
err
;
int
err
;
err
=
trtl_
rt
_variable_get
(
svec
->
trtl
,
err
=
trtl_
fw
_variable_get
(
svec
->
trtl
,
SVEC_CPU_MANUAL
,
SVEC_CPU_MANUAL_HMQ
,
SVEC_CPU_MANUAL
,
SVEC_CPU_MANUAL_HMQ
,
fields
,
3
);
fields
,
3
);
if
(
err
)
if
(
err
)
...
@@ -220,30 +213,30 @@ int svec_run_autosvec(struct svec_node *dev, uint32_t run)
...
@@ -220,30 +213,30 @@ int svec_run_autosvec(struct svec_node *dev, uint32_t run)
struct
svec_desc
*
svec
=
(
struct
svec_desc
*
)
dev
;
struct
svec_desc
*
svec
=
(
struct
svec_desc
*
)
dev
;
uint32_t
fields
[]
=
{
SVEC_VAR_AUTO
,
run
};
uint32_t
fields
[]
=
{
SVEC_VAR_AUTO
,
run
};
return
trtl_
rt
_variable_set
(
svec
->
trtl
,
return
trtl_
fw
_variable_set
(
svec
->
trtl
,
SVEC_CPU_MANUAL
,
SVEC_CPU_MANUAL_HMQ
,
SVEC_CPU_MANUAL
,
SVEC_CPU_MANUAL_HMQ
,
fields
,
1
);
fields
,
1
);
}
}
int
svec_version
(
struct
svec_node
*
dev
,
struct
trtl_
rt
_version
*
version
)
int
svec_version
(
struct
svec_node
*
dev
,
struct
trtl_
fw
_version
*
version
)
{
{
struct
svec_desc
*
svec
=
(
struct
svec_desc
*
)
dev
;
struct
svec_desc
*
svec
=
(
struct
svec_desc
*
)
dev
;
return
trtl_
rt_version_get
(
svec
->
trtl
,
return
trtl_
fw_version
(
svec
->
trtl
,
SVEC_CPU_MANUAL
,
SVEC_CPU_MANUAL_HMQ
,
SVEC_CPU_MANUAL
,
SVEC_CPU_MANUAL_HMQ
,
version
);
version
);
}
}
int
svec_test_struct_get
(
struct
svec_node
*
dev
,
struct
svec_structure
*
test
)
int
svec_test_struct_get
(
struct
svec_node
*
dev
,
struct
svec_structure
*
test
)
{
{
struct
svec_desc
*
svec
=
(
struct
svec_desc
*
)
dev
;
struct
svec_desc
*
svec
=
(
struct
svec_desc
*
)
dev
;
struct
trtl_
structure_
tlv
tlv
=
{
struct
trtl_tlv
tlv
=
{
.
index
=
SVEC_BUF_TEST
,
.
type
=
SVEC_BUF_TEST
,
.
size
=
sizeof
(
struct
svec_structure
),
.
size
=
sizeof
(
struct
svec_structure
),
.
buf
=
test
,
.
buf
=
test
,
};
};
return
trtl_
rt
_buffer_get
(
svec
->
trtl
,
return
trtl_
fw
_buffer_get
(
svec
->
trtl
,
SVEC_CPU_MANUAL
,
SVEC_CPU_MANUAL_HMQ
,
SVEC_CPU_MANUAL
,
SVEC_CPU_MANUAL_HMQ
,
&
tlv
,
1
);
&
tlv
,
1
);
}
}
...
@@ -251,13 +244,13 @@ int svec_test_struct_get(struct svec_node *dev, struct svec_structure *test)
...
@@ -251,13 +244,13 @@ int svec_test_struct_get(struct svec_node *dev, struct svec_structure *test)
int
svec_test_struct_set
(
struct
svec_node
*
dev
,
struct
svec_structure
*
test
)
int
svec_test_struct_set
(
struct
svec_node
*
dev
,
struct
svec_structure
*
test
)
{
{
struct
svec_desc
*
svec
=
(
struct
svec_desc
*
)
dev
;
struct
svec_desc
*
svec
=
(
struct
svec_desc
*
)
dev
;
struct
trtl_
structure_
tlv
tlv
=
{
struct
trtl_tlv
tlv
=
{
.
index
=
SVEC_BUF_TEST
,
.
type
=
SVEC_BUF_TEST
,
.
size
=
sizeof
(
struct
svec_structure
),
.
size
=
sizeof
(
struct
svec_structure
),
.
buf
=
test
,
.
buf
=
test
,
};
};
return
trtl_
rt
_buffer_set
(
svec
->
trtl
,
return
trtl_
fw
_buffer_set
(
svec
->
trtl
,
SVEC_CPU_MANUAL
,
SVEC_CPU_MANUAL_HMQ
,
SVEC_CPU_MANUAL
,
SVEC_CPU_MANUAL_HMQ
,
&
tlv
,
1
);
&
tlv
,
1
);
}
}
demos/fmc-svec-carrier/software/lib/libsvec.h
View file @
475bc35d
...
@@ -56,7 +56,7 @@ extern int svec_lemo_set(struct svec_node *dev, uint32_t value);
...
@@ -56,7 +56,7 @@ extern int svec_lemo_set(struct svec_node *dev, uint32_t value);
extern
int
svec_lemo_dir_set
(
struct
svec_node
*
dev
,
uint32_t
value
);
extern
int
svec_lemo_dir_set
(
struct
svec_node
*
dev
,
uint32_t
value
);
extern
int
svec_status_get
(
struct
svec_node
*
dev
,
struct
svec_status
*
status
);
extern
int
svec_status_get
(
struct
svec_node
*
dev
,
struct
svec_status
*
status
);
extern
int
svec_run_autosvec
(
struct
svec_node
*
dev
,
uint32_t
run
);
extern
int
svec_run_autosvec
(
struct
svec_node
*
dev
,
uint32_t
run
);
extern
int
svec_version
(
struct
svec_node
*
dev
,
struct
trtl_
rt
_version
*
version
);
extern
int
svec_version
(
struct
svec_node
*
dev
,
struct
trtl_
fw
_version
*
version
);
extern
int
svec_test_struct_set
(
struct
svec_node
*
dev
,
extern
int
svec_test_struct_set
(
struct
svec_node
*
dev
,
struct
svec_structure
*
test
);
struct
svec_structure
*
test
);
extern
int
svec_test_struct_get
(
struct
svec_node
*
dev
,
extern
int
svec_test_struct_get
(
struct
svec_node
*
dev
,
...
...
demos/fmc-svec-carrier/software/tools/mockturtle-svec.c
View file @
475bc35d
...
@@ -40,10 +40,9 @@ static void svec_print_status(struct svec_status *status)
...
@@ -40,10 +40,9 @@ static void svec_print_status(struct svec_status *status)
fprintf
(
stdout
,
"
\t
autosvec
\t
%s
\n
"
,
status
->
autosvec
?
"run"
:
"stop"
);
fprintf
(
stdout
,
"
\t
autosvec
\t
%s
\n
"
,
status
->
autosvec
?
"run"
:
"stop"
);
}
}
static
void
svec_print_version
(
struct
trtl_
rt
_version
*
version
)
static
void
svec_print_version
(
struct
trtl_
fw
_version
*
version
)
{
{
fprintf
(
stdout
,
"Version:
\n
"
);
fprintf
(
stdout
,
"Version:
\n
"
);
fprintf
(
stdout
,
"
\t
FPGA: 0x%x
\n
"
,
version
->
fpga_id
);
fprintf
(
stdout
,
"
\t
RT: 0x%x
\n
"
,
version
->
rt_id
);
fprintf
(
stdout
,
"
\t
RT: 0x%x
\n
"
,
version
->
rt_id
);
fprintf
(
stdout
,
"
\t
RT Version: 0x%x
\n
"
,
version
->
rt_version
);
fprintf
(
stdout
,
"
\t
RT Version: 0x%x
\n
"
,
version
->
rt_version
);
fprintf
(
stdout
,
"
\t
Git Version: 0x%x
\n
"
,
version
->
git_version
);
fprintf
(
stdout
,
"
\t
Git Version: 0x%x
\n
"
,
version
->
git_version
);
...
@@ -68,7 +67,7 @@ int main(int argc, char *argv[])
...
@@ -68,7 +67,7 @@ int main(int argc, char *argv[])
char
c
,
c_color
=
0
,
autosvec
=
0
;
char
c
,
c_color
=
0
,
autosvec
=
0
;
int
err
=
0
,
show_status
=
0
,
show_version
=
0
,
structure
=
0
;
int
err
=
0
,
show_status
=
0
,
show_version
=
0
,
structure
=
0
;
enum
svec_color
color
=
SVEC_RED
;
enum
svec_color
color
=
SVEC_RED
;
struct
trtl_
rt
_version
version
;
struct
trtl_
fw
_version
version
;
struct
svec_structure
test
,
test_rb
;
struct
svec_structure
test
,
test_rb
;
while
((
c
=
getopt
(
argc
,
argv
,
"hD:l:L:d:c:sa:vt"
))
!=
-
1
)
{
while
((
c
=
getopt
(
argc
,
argv
,
"hD:l:L:d:c:sa:vt"
))
!=
-
1
)
{
...
...
demos/hello_world/firmware/fw-01/fw-hello.c
View file @
475bc35d
#include <mockturtle-rt
-serial
.h>
#include <mockturtle-rt.h>
int
main
()
int
main
()
{
{
...
...
demos/hello_world_framework/firmware/fw-01/fw-hellofrm.c
View file @
475bc35d
...
@@ -6,32 +6,13 @@
...
@@ -6,32 +6,13 @@
#include <mockturtle-framework.h>
#include <mockturtle-framework.h>
enum
rt_slot_name
{
static
struct
trtl_fw_application
app
=
{
HELLOFRM_CMD_IN
=
0
,
HELLOFRM_CMD_OUT
,
};
static
struct
rt_mq
mq
[]
=
{
[
HELLOFRM_CMD_IN
]
=
{
.
index
=
0
,
.
flags
=
TRTL_RT_MQ_FLAGS_HMQ
|
TRTL_RT_MQ_FLAGS_INPUT
,
},
[
HELLOFRM_CMD_OUT
]
=
{
.
index
=
0
,
.
flags
=
TRTL_RT_MQ_FLAGS_HMQ
|
TRTL_RT_MQ_FLAGS_OUTPUT
,
},
};
static
struct
rt_application
app
=
{
.
name
=
"hellofrm"
,
.
name
=
"hellofrm"
,
.
version
=
{
.
version
=
{
.
fpga_id
=
CONFIG_FPGA_APPLICATION_ID
,
.
rt_id
=
CONFIG_RT_APPLICATION_ID
,
.
rt_id
=
CONFIG_RT_APPLICATION_ID
,
.
rt_version
=
RT_VERSION
(
0
,
1
),
.
rt_version
=
RT_VERSION
(
0
,
1
),
.
git_version
=
GIT_VERSION
.
git_version
=
GIT_VERSION
,
},
},
.
mq
=
mq
,
.
n_mq
=
ARRAY_SIZE
(
mq
),
};
};
/**
/**
...
@@ -39,15 +20,14 @@ static struct rt_application app = {
...
@@ -39,15 +20,14 @@ static struct rt_application app = {
*/
*/
int
main
()
int
main
()
{
{
rt
_init
(
&
app
);
trtl_fw
_init
(
&
app
);
while
(
1
)
{
while
(
1
)
{
/*
/*
* Handle all messages incoming from slot
* Handle all messages incoming from slot 0
* HELLOFRM_CMD_IN
* as actions
* as actions
*/
*/
rt_mq_action_dispatch
(
HELLOFRM_CMD_IN
);
trtl_fw_mq_action_dispatch
(
TRTL_HMQ
,
0
);
}
}
return
0
;
return
0
;
...
...
software/include/hw/mockturtle_config.h
deleted
100644 → 0
View file @
c6c69f99
#ifndef __TRTL_CONFIG_ROM_H__
#define __TRTL_CONFIG_ROM_H__
#define TRTL_CONFIG_ROM_SIGNATURE 0x5452544c
#define TRTL_MAX_CPU 8
/**< Maximum number of CPU core in a bitstream */
#define TRTL_MAX_MQ_CHAN 8
/**< Maximum number of (H|R)MQ slots in a
bitstream */
#define TRTL_CONFIG_ROM_MQ_ENTRIES_SHIFT 16
#define TRTL_CONFIG_ROM_MQ_ENTRIES_MASK 0x00FF0000
#define TRTL_CONFIG_ROM_MQ_PAYLOAD_SHIFT 8
#define TRTL_CONFIG_ROM_MQ_PAYLOAD_MASK 0x0000FF00
#define TRTL_CONFIG_ROM_MQ_HEADER_SHIFT 0
#define TRTL_CONFIG_ROM_MQ_HEADER_MASK 0x000000FF
#define TRTL_CONFIG_ROM_MQ_SIZE_ENTRIES(_size) (1 << ((_size & TRTL_CONFIG_ROM_MQ_ENTRIES_MASK) >> TRTL_CONFIG_ROM_MQ_ENTRIES_SHIFT))
#define TRTL_CONFIG_ROM_MQ_SIZE_PAYLOAD(_size) (1 << ((_size & TRTL_CONFIG_ROM_MQ_PAYLOAD_MASK) >> TRTL_CONFIG_ROM_MQ_PAYLOAD_SHIFT))
#define TRTL_CONFIG_ROM_MQ_SIZE_HEADER(_size) (1 << ((_size & TRTL_CONFIG_ROM_MQ_HEADER_MASK) >> TRTL_CONFIG_ROM_MQ_HEADER_SHIFT))
/**
* The synthesis configuration for a single MQ.
* Note that there is always an input and output channel for each declaration.
*/
struct
trtl_config_rom_mq
{
uint32_t
sizes
;
uint32_t
endpoint_id
;
};
/**
* The synthesis configuration ROM descriptor shows useful configuration
* options during synthesis.
*/
struct
trtl_config_rom
{
uint32_t
signature
;
/**< we expect to see a known value */
uint32_t
version
;
/**< Mock Turtle version */
uint32_t
pad1
[
1
];
uint32_t
clock_freq
;
uint32_t
flags
;
uint32_t
app_id
;
/**< Application ID */
uint32_t
n_cpu
;
/**< number of CPU */
uint32_t
smem_size
;
/**< shared memory size */
uint32_t
mem_size
[
TRTL_MAX_CPU
];
/**< memory size for each CPU */
uint32_t
n_hmq
[
TRTL_MAX_CPU
];
/**< number of HMQ for each CPU */
uint32_t
n_rmq
[
TRTL_MAX_CPU
];
/**< number of RMQ for each CPU */
uint32_t
pad2
[
96
];
struct
trtl_config_rom_mq
hmq
[
TRTL_MAX_CPU
][
TRTL_MAX_MQ_CHAN
];
struct
trtl_config_rom_mq
rmq
[
TRTL_MAX_CPU
][
TRTL_MAX_MQ_CHAN
];
};
#endif
software/include/mockturtle-common.h
deleted
100644 → 0
View file @
c6c69f99
/*
* Copyright (C) 2015-2016 CERN (www.cern.ch)
* Author: Federico Vaga <federico.vaga@cern.ch>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __TRTL_COMMON_H__
#define __TRTL_COMMON_H__
#ifndef __KERNEL__
#include <string.h>
#endif
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(_a) (sizeof(_a) / sizeof(_a[0]))
#endif
#define __TRTL_MSG_ID_MAX_USER 96
#define __TRTL_MSG_ID_MAX 128
/**
* It lists all notification's code.
*/
enum
trtl_cpu_notification
{
TRTL_CPU_NOTIFY_APPLICATION
=
0
,
__TRTL_CPU_NOTIFY_MAX
,
};
/**
* List of Mock Turtle message identifiers for firmware input
*/
enum
trtl_msg_id_i
{
TRTL_MSG_ID_PING
=
__TRTL_MSG_ID_MAX_USER
,
TRTL_MSG_ID_VERS_REQ
,
TRTL_MSG_ID_VAR_SET
,
TRTL_MSG_ID_VAR_GET
,
TRTL_MSG_ID_BUF_SET
,
TRTL_MSG_ID_BUF_GET
,
};
/**
* List of Mock Turtle message identifiers for firmware output
*/
enum
trtl_msg_id_o
{
TRTL_MSG_ID_ACK
=
__TRTL_MSG_ID_MAX_USER
,
TRTL_MSG_ID_NACK
,
TRTL_MSG_ID_VERS_ANS
,
TRTL_MSG_ID_DBG
,
TRTL_MSG_ID_VAR_GET_ANS
,
TRTL_MSG_ID_BUF_GET_ANS
,
};
/**
* Synchronous. When set, the sync_id is valid and the receiver
* must answer with a message with the same sync_id
*/
#define TRTL_HMQ_HEADER_FLAG_SYNC (1 << 0)
/**
* HMQ header descriptor
*/
struct
trtl_hmq_header
{
/* word 0 */
uint16_t
rt_app_id
;
/**< Real-Time application unique identifier */
uint8_t
flags
;
uint8_t
msg_id
;
/**< Message identifier */
/* word 1 */
uint16_t
len
;
/**< message-length */
uint16_t
sync_id
;
/**< synchronous identifier */
/* word 2 */
uint32_t
seq
;
/**< sequence number */
};
/**
* It describes the version running on the embedded CPU
*/
struct
trtl_rt_version
{
uint32_t
fpga_id
;
/**< FPGA identifier expected to run the RT app */
uint32_t
rt_id
;
/**< RT application identifier */
uint32_t
rt_version
;
/**< RT application version*/
uint32_t
git_version
;
/**< git commit SHA1 of the compilation time */
};
enum
rt_action_standard
{
RT_ACTION_RECV_PING
=
0
,
RT_ACTION_RECV_STRUCT_SET
,
RT_ACTION_RECV_STRUCT_GET
,
RT_ACTION_RECV_VERSION
,
RT_ACTION_SEND_ACK
,
RT_ACTION_SEND_NACK
,
RT_ACTION_SEND_STRUCT_GET
,
RT_ACTION_SEND_VERSION
,
RT_ACTION_SEND_DEBUG
,
__RT_ACTION_RECV_STANDARD_NUMBER
,
};
/**< __MAX_ACTION_RECV coming from GCC on compilation */
#define MAX_ACTION_RECV (__MAX_ACTION_RECV + __RT_ACTION_RECV_STANDARD_NUMBER)
/**< __MAX_ACTION_SEND coming from GCC on compilation */
#define MAX_ACTION_SEND (__MAX_ACTION_SEND + __RT_ACTION_SEND_STANDARD_NUMBER)
/* Protocol Definition */
#define TRTL_HEAD_FLAG_REMOTE (1 << 0)
#define TRTL_HEAD_FLAG_SYNC (1 << 1)
#define TRTL_HEAD_FLAG_RPC (1 << 2)
#define TRTL_HEAD_FLAG_PERIODICAL (1 << 3)
/**
* Protocol header definition
*/
struct
trtl_proto_header
{
uint16_t
rt_app_id
;
/**< Real-Time application unique identifier */
uint8_t
msg_id
;
/**< Message identifier */
uint8_t
slot_io
;
/**< Message Queue IO to use
(4bit Input, 4 bit output) */
uint32_t
seq
;
/**< sequence number */
uint8_t
len
;
/**< message data lenght */
uint8_t
flags
;
/**< protocol flags */
uint8_t
unused
;
/**< not used, future use */
uint8_t
trans
;
/**< transaction descriptor - flag and seq number */
uint32_t
time
;
};
/**
* Data structure representing a MockTurtle packet
*/
struct
mturtle_packet
{
/* offset 0x00 */
volatile
struct
trtl_proto_header
header
;
/**< packet header */
/* offset 0x10 */
volatile
uint32_t
payload
[];
/**< packet payload */
};
/**
* It returns the pointer to the MockTurtle packet
* @param[in] buf buffer containing the packet
* @return pointer to the packet
*/
static
inline
struct
mturtle_packet
*
rt_proto_packet_get
(
void
*
buf
)
{
return
(
struct
mturtle_packet
*
)
buf
;
}
/**
* It extracts the header from a raw message
* @param[in] raw_msg raw message
* @param[out] header the header from the message
*/
static
inline
struct
trtl_proto_header
*
rt_proto_header_get
(
void
*
raw_msg
)
{
return
(
struct
trtl_proto_header
*
)
raw_msg
;
}
/**
* It embeds the header from a raw message
* @param[in] raw_msg raw message
* @param[out] header the header from the message
*/
static
inline
void
rt_proto_header_set
(
void
*
raw_msg
,
struct
trtl_proto_header
*
header
)
{
memcpy
(
raw_msg
,
header
,
sizeof
(
struct
trtl_proto_header
));
}
/**
* It returns the pointer where it starts the message payload
* @param[in] raw_msg raw message
* @param[out] header the header from the message
*/
static
inline
void
*
rt_proto_payload_get
(
void
*
raw_msg
)
{
return
((
char
*
)
raw_msg
+
sizeof
(
struct
trtl_proto_header
));
}
#endif
software/include/mockturtle.h
View file @
475bc35d
...
@@ -21,11 +21,123 @@
...
@@ -21,11 +21,123 @@
#define __TRTL_USER_H__
#define __TRTL_USER_H__
/** @file mock-turtle.h */
/** @file mock-turtle.h */
#include "mockturtle-common.h"
#ifndef __KERNEL__
#include <string.h>
#endif
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(_a) (sizeof(_a) / sizeof(_a[0]))
#endif
#define __TRTL_MSG_ID_MAX 128
#define __TRTL_MSG_ID_MAX_TRTL 32
#define __TRTL_MSG_ID_MAX_USER (__TRTL_MSG_ID_MAX - __TRTL_MSG_ID_MAX_TRTL)
/**
* It lists all notification's code.
*/
enum
trtl_cpu_notification
{
TRTL_CPU_NOTIFY_APPLICATION
=
0
,
__TRTL_CPU_NOTIFY_MAX
,
};
/**
* It enumerates the Mock Turtle message ID.
* These IDs starts after the user defined ones
*/
enum
trtl_msg_id
{
TRTL_MSG_ID_UNDEFINED
=
__TRTL_MSG_ID_MAX_USER
,
TRTL_MSG_ID_ERROR
,
TRTL_MSG_ID_PING
,
TRTL_MSG_ID_VER
,
TRTL_MSG_ID_DBG
,
TRTL_MSG_ID_VAR_GET
,
TRTL_MSG_ID_BUF_GET
,
TRTL_MSG_ID_VAR_SET
,
TRTL_MSG_ID_BUF_SET
,
};
/**
* Synchronous. When set, the sync_id is valid and the receiver
* must answer with a message with the same sync_id
*/
#define TRTL_HMQ_HEADER_FLAG_SYNC (1 << 0)
/**
* Acknowledgment. When set, the sync_id is valid and it is the
* same as the sync message previously sent
*/
#define TRTL_HMQ_HEADER_FLAG_ACK (1 << 1)
/**
* Remote Procedure Call. when set the message ID will be used
* to execute a special function by the receiver
*/
#define TRTL_HMQ_HEADER_FLAG_RPC (1 << 2)
/**
* HMQ header descriptor
*/
struct
trtl_hmq_header
{
/* word 0 */
uint16_t
rt_app_id
;
/**< Real-Time application unique identifier */
uint8_t
flags
;
uint8_t
msg_id
;
/**< Message identifier */
/* word 1 */
uint16_t
len
;
/**< message-length */
uint16_t
sync_id
;
/**< synchronous identifier */
/* word 2 */
uint32_t
seq
;
/**< sequence number (automatically set by the library) */
};
#define RT_VERSION_MAJ(_v) ((_v >> 16) & 0xFFFF)
#define RT_VERSION_MIN(_v) (_v & 0xFFFF)
#define RT_VERSION(_a, _b) (((_a & 0xFFFF) << 16) | (_b & 0xFFFF))
/**
* It describes the version running on the embedded CPU
*/
struct
trtl_fw_version
{
uint32_t
rt_id
;
/**< RT application identifier */
uint32_t
rt_version
;
/**< RT application version*/
uint32_t
git_version
;
/**< git commit SHA1 of the compilation time */
};
/**
* Maximum number of CPU core in a bitstream
*/
#define TRTL_MAX_CPU 8
/**
* Maximum number of (H|R)MQ slots in a bitstream
*/
#define TRTL_MAX_MQ_CHAN 8
#define TRTL_MAX_CARRIER 20
/**< Maximum number of WRNC components on a
/**
single computer*/
* Maximum number of Mock Turtle components on a single computer
*/
#define TRTL_MAX_CARRIER 20
/**
* TLV used to embed buffers within a message
*/
struct
trtl_tlv
{
uint32_t
type
;
/**< buffer type */
size_t
size
;
/**< buffer size in byte */
void
*
buf
;
/**< pointer to the buffer */
};
/**
/**
* Maximum number of notifications ID in the driver buffer
* Maximum number of notifications ID in the driver buffer
...
@@ -46,22 +158,13 @@
...
@@ -46,22 +158,13 @@
* that you can use to access the shared memory.
* that you can use to access the shared memory.
*/
*/
enum
trtl_smem_modifier
{
enum
trtl_smem_modifier
{
TRTL_SMEM_DIRECT
=
0
,
/**< direct read/write of the memory */
TRTL_SMEM_TYPE_BASE
=
0
,
/**< no operation */
TRTL_SMEM_ADD
,
/**< on write, atomic ADD to memory content */
TRTL_SMEM_TYPE_ADD
,
/**< atomic addition */
TRTL_SMEM_SUB
,
/**< on write, atomic SUB to memory content */
TRTL_SMEM_TYPE_SUB
,
/**< atomic subtraction */
TRTL_SMEM_OR
,
/**< on write, atomic OR with memory content */
TRTL_SMEM_TYPE_SET
,
/**< atomic bit set */
TRTL_SMEM_CLR_AND
,
/**< on write, atomic AND with complemented memory
TRTL_SMEM_TYPE_CLR
,
/**< atomic bit clear */
content */
TRTL_SMEM_TYPE_FLP
,
/**< atomic bit flip */
TRTL_SMEM_XOR
,
/**< on write, atomic XOR with memory content */
TRTL_SMEM_TYPE_TST_SET
,
/**< atomic test and set */
};
/**
* Messages descriptor
*/
struct
trtl_msg
{
struct
trtl_hmq_header
hdr
;
uint32_t
data
[
TRTL_MAX_PAYLOAD_SIZE
];
/**< payload very maximum size */
};
};
...
@@ -123,4 +226,71 @@ enum trtl_ioctl_commands {
...
@@ -123,4 +226,71 @@ enum trtl_ioctl_commands {
#define TRTL_IOCTL_MSG_FILTER_CLEAN _IOW(TRTL_IOCTL_MAGIC, \
#define TRTL_IOCTL_MSG_FILTER_CLEAN _IOW(TRTL_IOCTL_MAGIC, \
TRTL_MSG_FILTER_CLEAN, \
TRTL_MSG_FILTER_CLEAN, \
struct trtl_msg_filter)
struct trtl_msg_filter)
/**
* Messages descriptor
*/
struct
trtl_msg
{
#ifdef __TRTL_FIRMWARE__
/* Only firmware */
struct
trtl_hmq_header
*
header
;
void
*
payload
;
#else
/* library and kernel */
struct
trtl_hmq_header
hdr
;
uint32_t
data
[
TRTL_MAX_PAYLOAD_SIZE
];
/**< payload very maximum size */
#endif
};
#define TRTL_CONFIG_ROM_MQ_ENTRIES_SHIFT 16
#define TRTL_CONFIG_ROM_MQ_ENTRIES_MASK 0x00FF0000
#define TRTL_CONFIG_ROM_MQ_PAYLOAD_SHIFT 8
#define TRTL_CONFIG_ROM_MQ_PAYLOAD_MASK 0x0000FF00
#define TRTL_CONFIG_ROM_MQ_HEADER_SHIFT 0
#define TRTL_CONFIG_ROM_MQ_HEADER_MASK 0x000000FF
#define TRTL_CONFIG_ROM_MQ_SIZE_ENTRIES(_size) (1 << ((_size & TRTL_CONFIG_ROM_MQ_ENTRIES_MASK) >> TRTL_CONFIG_ROM_MQ_ENTRIES_SHIFT))
#define TRTL_CONFIG_ROM_MQ_SIZE_PAYLOAD(_size) (1 << ((_size & TRTL_CONFIG_ROM_MQ_PAYLOAD_MASK) >> TRTL_CONFIG_ROM_MQ_PAYLOAD_SHIFT))
#define TRTL_CONFIG_ROM_MQ_SIZE_HEADER(_size) (1 << ((_size & TRTL_CONFIG_ROM_MQ_HEADER_MASK) >> TRTL_CONFIG_ROM_MQ_HEADER_SHIFT))
/**
* The synthesis configuration for a single MQ.
* Note that there is always an input and output channel for each declaration.
*/
struct
trtl_config_rom_mq
{
uint32_t
sizes
;
uint32_t
endpoint_id
;
};
/**
* This signature must be present on all the configuration rom
*/
#define TRTL_CONFIG_ROM_SIGNATURE 0x5452544c
/**
* The synthesis configuration ROM descriptor shows useful configuration
* options during synthesis.
*/
struct
trtl_config_rom
{
uint32_t
signature
;
/**< we expect to see a known value */
uint32_t
version
;
/**< Mock Turtle version */
uint32_t
pad1
[
1
];
uint32_t
clock_freq
;
uint32_t
flags
;
uint32_t
app_id
;
/**< Application ID */
uint32_t
n_cpu
;
/**< number of CPU */
uint32_t
smem_size
;
/**< shared memory size */
uint32_t
mem_size
[
TRTL_MAX_CPU
];
/**< memory size for each CPU */
uint32_t
n_hmq
[
TRTL_MAX_CPU
];
/**< number of HMQ for each CPU */
uint32_t
n_rmq
[
TRTL_MAX_CPU
];
/**< number of RMQ for each CPU */
uint32_t
pad2
[
96
];
struct
trtl_config_rom_mq
hmq
[
TRTL_MAX_CPU
][
TRTL_MAX_MQ_CHAN
];
struct
trtl_config_rom_mq
rmq
[
TRTL_MAX_CPU
][
TRTL_MAX_MQ_CHAN
];
};
#endif
#endif
software/kernel/mockturtle-core.c
View file @
475bc35d
...
@@ -28,7 +28,6 @@
...
@@ -28,7 +28,6 @@
#include <hw/mockturtle_cpu_csr.h>
#include <hw/mockturtle_cpu_csr.h>
#include <hw/mockturtle_queue.h>
#include <hw/mockturtle_queue.h>
#include <hw/mockturtle_config.h>
#include "mockturtle-drv.h"
#include "mockturtle-drv.h"
...
@@ -198,7 +197,7 @@ static ssize_t trtl_store_smem_op(struct device *dev,
...
@@ -198,7 +197,7 @@ static ssize_t trtl_store_smem_op(struct device *dev,
if
(
kstrtol
(
buf
,
0
,
&
val
))
if
(
kstrtol
(
buf
,
0
,
&
val
))
return
-
EINVAL
;
return
-
EINVAL
;
if
(
val
<
TRTL_SMEM_
DIRECT
||
val
>
TRTL_SMEM
_ADD
)
{
if
(
val
<
TRTL_SMEM_
TYPE_BASE
||
val
>
TRTL_SMEM_TYPE
_ADD
)
{
dev_err
(
&
trtl
->
dev
,
"Unsupported operation %ld
\n
"
,
val
);
dev_err
(
&
trtl
->
dev
,
"Unsupported operation %ld
\n
"
,
val
);
return
-
EINVAL
;
return
-
EINVAL
;
}
}
...
...
software/kernel/mockturtle-drv.h
View file @
475bc35d
...
@@ -15,7 +15,6 @@
...
@@ -15,7 +15,6 @@
#include "hw/mockturtle_addresses.h"
#include "hw/mockturtle_addresses.h"
#include "hw/mockturtle_queue.h"
#include "hw/mockturtle_queue.h"
#include "hw/mockturtle_config.h"
#include "mockturtle.h"
#include "mockturtle.h"
#define MAX_MQUEUE_SLOTS (TRTL_MAX_HMQ_SLOT / 2)
#define MAX_MQUEUE_SLOTS (TRTL_MAX_HMQ_SLOT / 2)
...
...
software/lib/PyMockTurtle/PyMockTurtle/PyMockTurtle.py
View file @
475bc35d
...
@@ -111,6 +111,14 @@ class TrtlMessage(Structure):
...
@@ -111,6 +111,14 @@ class TrtlMessage(Structure):
return
True
return
True
class
TrtlFirmwareVersion
(
Structure
):
_fields_
=
[
(
"id"
,
c_uint32
),
(
"fw-version"
,
c_uint32
),
(
"git-version"
,
c_uint32
),
]
class
TrtlDevice
(
object
):
class
TrtlDevice
(
object
):
"""It is a Python class that represent a Mock Turtle Device
"""It is a Python class that represent a Mock Turtle Device
"""
"""
...
@@ -229,7 +237,16 @@ class TrtlDevice(object):
...
@@ -229,7 +237,16 @@ class TrtlDevice(object):
]
]
self
.
libtrtl
.
trtl_hmq_flush
.
restype
=
c_int
self
.
libtrtl
.
trtl_hmq_flush
.
restype
=
c_int
self
.
libtrtl
.
trtl_hmq_flush
.
errcheck
=
self
.
errcheck
self
.
libtrtl
.
trtl_hmq_flush
.
errcheck
=
self
.
errcheck
# FW PING
self
.
libtrtl
.
trtl_fw_ping
.
argtypes
=
[
c_void_p
,
c_uint
,
c_uint
]
self
.
libtrtl
.
trtl_fw_ping
.
restype
=
c_int
self
.
libtrtl
.
trtl_fw_ping
.
errcheck
=
self
.
__errcheck_int
# FW VERSION
self
.
libtrtl
.
trtl_fw_version
.
argtypes
=
[
c_void_p
,
c_uint
,
c_uint
,
POINTER
(
TrtlFirmwareVersion
),
]
self
.
libtrtl
.
trtl_fw_version
.
restype
=
c_int
self
.
libtrtl
.
trtl_fw_version
.
errcheck
=
self
.
__errcheck_int
# self.libtrtl.trtl_hmq_filter_add.argtypes = [c_void_p]
# self.libtrtl.trtl_hmq_filter_add.argtypes = [c_void_p]
# self.libtrtl.trtl_hmq_filter_clean.argtypes = [c_void_p]
# self.libtrtl.trtl_hmq_filter_clean.argtypes = [c_void_p]
# # Return
# # Return
...
@@ -326,6 +343,22 @@ class TrtlCpu(object):
...
@@ -326,6 +343,22 @@ class TrtlCpu(object):
self
.
idx_cpu
,
self
.
idx_cpu
,
file_path
.
encode
())
file_path
.
encode
())
def
ping
(
self
,
idx_hmq
):
"""
It pings the firmware running on the CPU
@return True if the firmware is alive, False otherwise
"""
val
=
self
.
libtrtl
.
trtl_fw_ping
(
self
.
trtl_dev
.
tkn
,
self
.
idx_cpu
,
idx_hmq
)
return
True
if
val
==
0
else
False
def
version
(
self
):
version
=
TrtlFirmwareVersion
()
self
.
libtrtl
.
trtl_fw_version
(
self
.
trtl_dev
.
tkn
,
self
.
idx_cpu
,
idx_hmq
,
pointer
(
version
))
return
version
class
TrtlHmq
(
object
):
class
TrtlHmq
(
object
):
"""
"""
...
...
software/lib/libmockturtle-internal.h
View file @
475bc35d
...
@@ -14,6 +14,8 @@
...
@@ -14,6 +14,8 @@
*/
*/
struct
trtl_desc
{
struct
trtl_desc
{
uint32_t
devid
;
uint32_t
devid
;
uint32_t
seq
;
/**< global sequence number for messages sent from
this instance*/
char
name
[
TRTL_NAME_LEN
];
/**< Name of the device */
char
name
[
TRTL_NAME_LEN
];
/**< Name of the device */
char
path
[
TRTL_PATH_LEN
];
/**< path to device */
char
path
[
TRTL_PATH_LEN
];
/**< path to device */
int
fd_dev
;
/**< File Descriptor of the device */
int
fd_dev
;
/**< File Descriptor of the device */
...
...
software/lib/libmockturtle-rt-msg.c
View file @
475bc35d
...
@@ -5,184 +5,61 @@
...
@@ -5,184 +5,61 @@
* SPDX-License-Identifier: LGPL-3.0-or-later
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
*/
#include <libmockturtle.h>
#include <errno.h>
#include <errno.h>
#include <inttypes.h>
#include "libmockturtle-internal.h"
/**
* It embeds the header into the message
* @param[in] msg the trtl message
* @param[in] hdr the header you want to embed into the message
*/
void
trtl_message_header_set
(
struct
trtl_msg
*
msg
,
struct
trtl_proto_header
*
hdr
)
{
memcpy
(
msg
->
data
,
hdr
,
sizeof
(
struct
trtl_proto_header
));
msg
->
hdr
.
len
=
sizeof
(
struct
trtl_proto_header
)
/
4
;
}
/**
* It retrieves the header from the message
* @param[in] msg the trtl message
* @param[out] hdr the header from the message
*/
void
trtl_message_header_get
(
struct
trtl_msg
*
msg
,
struct
trtl_proto_header
*
hdr
)
{
memcpy
(
hdr
,
msg
->
data
,
sizeof
(
struct
trtl_proto_header
));
}
/**
* It packs a message to send to the HMQ. The function uses the header to get
* the payload size. Rembember that the payload length unit is the 32bit word.
* Remind also that the TRTL VHDL code, will convert a given 32bit word between
* little endian and big endian
* @param[out] msg raw message
* @param[in] hdr message header
* @param[in] payload data
*/
void
trtl_message_pack
(
struct
trtl_msg
*
msg
,
struct
trtl_proto_header
*
hdr
,
void
*
payload
)
{
void
*
data
=
msg
->
data
;
trtl_message_header_set
(
msg
,
hdr
);
if
(
!
payload
)
return
;
memcpy
(
data
+
sizeof
(
struct
trtl_proto_header
),
payload
,
hdr
->
len
*
4
);
msg
->
hdr
.
len
+=
hdr
->
len
;
}
/**
* it unpacks a message coming from the HMQ by separating the header from
* the payload. You will find the payload size in the header.
* Rembember that the payload length unit is the 32bit word.
* Remind also that the TRTL VHDL code, will convert a given 32bit word between
* little endian and big endian
* @param[in] msg raw message
* @param[out] hdr message header
* @param[out] payload data
*/
void
trtl_message_unpack
(
struct
trtl_msg
*
msg
,
struct
trtl_proto_header
*
hdr
,
void
*
payload
)
{
void
*
data
=
msg
->
data
;
trtl_message_header_get
(
msg
,
hdr
);
if
(
!
payload
)
return
;
memcpy
(
payload
,
data
+
sizeof
(
struct
trtl_proto_header
),
hdr
->
len
*
4
);
}
/**
* It appends a TLV structure to the given message
* @param[in] msg
* @param[in] hdr message header to use
* @param[in] tlv element to append
*/
void
trtl_message_buffer_push
(
struct
trtl_msg
*
msg
,
struct
trtl_proto_header
*
hdr
,
struct
trtl_structure_tlv
*
tlv
)
{
unsigned
int
offset
=
sizeof
(
struct
trtl_proto_header
)
/
4
+
hdr
->
len
;
void
*
data
;
msg
->
data
[
offset
++
]
=
tlv
->
index
;
msg
->
data
[
offset
++
]
=
tlv
->
size
;
data
=
&
msg
->
data
[
offset
];
memcpy
(
data
,
tlv
->
buf
,
tlv
->
size
);
hdr
->
len
+=
2
+
(
tlv
->
size
/
4
);
trtl_message_header_set
(
msg
,
hdr
);
msg
->
hdr
.
len
=
hdr
->
len
+
sizeof
(
struct
trtl_proto_header
)
/
4
;
}
/**
* A TLV record containing a structure will be take from the message head.
* The function will update the message lenght in the header by removing
* the size occupied by the last record.
*
* @TODO perhaps re think it because it consumes the hdr. It is better to
* keep it safe
* @param[in] msg raw message
* @param[in] offset where start to pop buffers in 32bit words
* @param[in] hdr message header
* @param[out] tlv TLV record containing a structure
*/
off_t
trtl_message_buffer_pop
(
struct
trtl_msg
*
msg
,
off_t
offset
,
struct
trtl_proto_header
*
hdr
,
struct
trtl_structure_tlv
*
tlv
)
{
if
(
offset
>
hdr
->
len
)
{
errno
=
EINVAL
;
return
-
1
;
}
tlv
->
index
=
msg
->
data
[
offset
++
];
tlv
->
size
=
msg
->
data
[
offset
++
];
if
(
tlv
->
size
/
4
>
hdr
->
len
-
2
)
{
/* -2 for intex and size */
errno
=
EINVAL
;
return
-
1
;
/* TLV greater than what is declared in header */
}
memcpy
(
tlv
->
buf
,
&
msg
->
data
[
offset
],
tlv
->
size
);
offset
+=
(
tlv
->
size
/
4
);
return
offset
;
}
/**
/**
* Retrieve the current Real-Time Application version running. This is a
* Retrieve the current Real-Time Application version running. This is a
* synchronous message.
* synchronous message.
* @param[in] trtl device token
* @param[in] trtl device token
* @param[
out] version FPGA, RT and GIT version
* @param[
in] idx_cpu which CPU
* @param[in]
hmq_in hmq slot index where send the message
* @param[in]
idx_hmq which HMQ
* @param[
in] hmq_out hmq slot index where you expect the answer
* @param[
out] version RT id, RT and GIT version
* @return 0 on success, -1 on error and errno is set appropriately
* @return 0 on success, -1 on error and errno is set appropriately
*/
*/
int
trtl_
rt_version_get
(
struct
trtl_dev
*
trtl
,
int
trtl_
fw_version
(
struct
trtl_dev
*
trtl
,
unsigned
int
idx_cpu
,
unsigned
int
idx_cpu
,
unsigned
int
idx_hmq
,
unsigned
int
idx_hmq
,
struct
trtl_rt
_version
*
version
)
struct
trtl_fw
_version
*
version
)
{
{
struct
trtl_msg
msg
;
struct
trtl_msg
msg
;
int
err
;
int
err
;
/* FIXME with new
proto
col redefine messages to ACK/NACK */
/* FIXME with new
hmq
col redefine messages to ACK/NACK */
err
=
trtl_msg_sync
(
trtl
,
idx_cpu
,
idx_hmq
,
&
msg
,
&
msg
,
err
=
trtl_msg_sync
(
trtl
,
idx_cpu
,
idx_hmq
,
&
msg
,
&
msg
,
trtl_default_timeout_ms
);
trtl_default_timeout_ms
);
if
(
err
<=
0
)
if
(
err
<=
0
)
return
-
1
;
return
-
1
;
/* FIXME put the payload in the version field */
memcpy
(
version
,
msg
.
data
,
msg
.
hdr
.
len
*
4
);
return
0
;
return
0
;
}
}
/**
/**
* It checks if
a Real-Time application
is running and answering to messages
* It checks if
firmware core
is running and answering to messages
* @param[in] trtl device token
* @param[in] trtl device token
* @param[in]
hmq_in hmq slot index where send the message
* @param[in]
idx_cpu which CPU
* @param[in]
hmq_out hmq slot index where you expect the answer
* @param[in]
idx_hmq which HMQ
* @return 0 on success, -1 on error and errno is set appropriately
* @return 0 on success, -1 on error and errno is set appropriately
*/
*/
int
trtl_
rt
_ping
(
struct
trtl_dev
*
trtl
,
int
trtl_
fw
_ping
(
struct
trtl_dev
*
trtl
,
unsigned
int
idx_cpu
,
unsigned
int
idx_cpu
,
unsigned
int
idx_hmq
)
unsigned
int
idx_hmq
)
{
{
struct
trtl_desc
*
wdesc
=
(
struct
trtl_desc
*
)
trtl
;
struct
trtl_msg
msg
;
struct
trtl_msg
msg
;
int
err
;
int
err
;
/* FIXME with new protocol redefine messages to ACK/NACK */
memset
(
&
msg
,
0
,
sizeof
(
struct
trtl_msg
));
msg
.
hdr
.
msg_id
=
TRTL_MSG_ID_PING
;
msg
.
hdr
.
seq
=
wdesc
->
seq
;
msg
.
hdr
.
sync_id
=
msg
.
hdr
.
seq
;
err
=
trtl_msg_sync
(
trtl
,
idx_cpu
,
idx_hmq
,
&
msg
,
&
msg
,
err
=
trtl_msg_sync
(
trtl
,
idx_cpu
,
idx_hmq
,
&
msg
,
&
msg
,
trtl_default_timeout_ms
);
trtl_default_timeout_ms
);
if
(
err
<=
0
)
if
(
err
<=
0
)
...
@@ -192,20 +69,6 @@ int trtl_rt_ping(struct trtl_dev *trtl,
...
@@ -192,20 +69,6 @@ int trtl_rt_ping(struct trtl_dev *trtl,
}
}
/**
* Real implementation to read/write variables
*/
static
inline
int
trtl_rt_variable
(
struct
trtl_dev
*
trtl
,
struct
trtl_proto_header
*
hdr
,
uint32_t
*
variables
,
unsigned
int
n_variables
)
{
/* FIXME Re-implement with new protocol */
errno
=
ETRTL_NO_IMPLEMENTATION
;
return
-
1
;
}
/**
/**
* It sends/receive a set of variables to/from the Real-Time application.
* It sends/receive a set of variables to/from the Real-Time application.
*
*
...
@@ -228,21 +91,40 @@ static inline int trtl_rt_variable(struct trtl_dev *trtl,
...
@@ -228,21 +91,40 @@ static inline int trtl_rt_variable(struct trtl_dev *trtl,
* This function will change the header content, in particular it will change
* This function will change the header content, in particular it will change
* the following fields: msg_id, len
* the following fields: msg_id, len
* @param[in] trtl device token
* @param[in] trtl device token
* @param[in|out] hdr header to send on input, header received on output
* @param[in] idx_cpu
* @param[in|out] var variables to get on input, variables values on output
* @param[in] idx_hmq
* @param[in] n_var number of variables to set. In other words,
* @param[in|out] variables on input variable indexes and values.
* the number of indexes you have in the 'variables' fields.
* On output variable indexes and values.
* @param[in] sync set if you want a synchronous message
* @param[in] n_variables number of variables to set. In other words,
* the number of indexes you have in the 'variables' fields
* @return 0 on success, -1 on error and errno is appropriately set.
*/
*/
int
trtl_
rt
_variable_set
(
struct
trtl_dev
*
trtl
,
int
trtl_
fw
_variable_set
(
struct
trtl_dev
*
trtl
,
unsigned
int
idx_cpu
,
unsigned
int
idx_cpu
,
unsigned
int
idx_hmq
,
unsigned
int
idx_hmq
,
uint32_t
*
variables
,
uint32_t
*
variables
,
unsigned
int
n_variables
)
unsigned
int
n_variables
)
{
{
/* FIXME Re-implement with new protocol */
struct
trtl_desc
*
wdesc
=
(
struct
trtl_desc
*
)
trtl
;
errno
=
ETRTL_NO_IMPLEMENTATION
;
struct
trtl_msg
msg
;
return
-
1
;
int
err
;
memset
(
&
msg
,
0
,
sizeof
(
struct
trtl_msg
));
msg
.
hdr
.
msg_id
=
TRTL_MSG_ID_VAR_GET
;
msg
.
hdr
.
seq
=
wdesc
->
seq
;
msg
.
hdr
.
sync_id
=
msg
.
hdr
.
seq
;
memcpy
(
msg
.
data
,
variables
,
sizeof
(
uint32_t
)
*
n_variables
);
err
=
trtl_msg_sync
(
trtl
,
idx_cpu
,
idx_hmq
,
&
msg
,
&
msg
,
trtl_default_timeout_ms
);
if
(
err
<=
0
)
return
-
1
;
memcpy
(
variables
,
msg
.
data
,
sizeof
(
uint32_t
)
*
n_variables
);
return
0
;
}
}
...
@@ -265,20 +147,40 @@ int trtl_rt_variable_set(struct trtl_dev *trtl,
...
@@ -265,20 +147,40 @@ int trtl_rt_variable_set(struct trtl_dev *trtl,
* This function will change the header content, in particular it will change
* This function will change the header content, in particular it will change
* the following fields: msg_id, flags, len
* the following fields: msg_id, flags, len
* @param[in] trtl device token
* @param[in] trtl device token
* @param[in|out] hdr header to send on input, header received on output
* @param[in] idx_cpu
* @param[in|out] var variables to get on input, variables values on output
* @param[in] idx_hmq
* @param[in] n_var number of variables to set. In other words,
* @param[in|out] variables on input variable indexes. On output variable
* indexes and values.
* @param[in] n_variables number of variables to set. In other words,
* the number of indexes you have in the 'variables' fields
* the number of indexes you have in the 'variables' fields
* @return 0 on success, -1 on error and errno is appropriately set.
*/
*/
int
trtl_
rt
_variable_get
(
struct
trtl_dev
*
trtl
,
int
trtl_
fw
_variable_get
(
struct
trtl_dev
*
trtl
,
unsigned
int
idx_cpu
,
unsigned
int
idx_cpu
,
unsigned
int
idx_hmq
,
unsigned
int
idx_hmq
,
uint32_t
*
variables
,
uint32_t
*
variables
,
unsigned
int
n_variables
)
unsigned
int
n_variables
)
{
{
/* FIXME Re-implement with new protocol */
struct
trtl_desc
*
wdesc
=
(
struct
trtl_desc
*
)
trtl
;
errno
=
ETRTL_NO_IMPLEMENTATION
;
struct
trtl_msg
msg
;
return
-
1
;
int
err
;
memset
(
&
msg
,
0
,
sizeof
(
struct
trtl_msg
));
msg
.
hdr
.
msg_id
=
TRTL_MSG_ID_VAR_GET
;
msg
.
hdr
.
seq
=
wdesc
->
seq
;
msg
.
hdr
.
sync_id
=
msg
.
hdr
.
seq
;
memcpy
(
msg
.
data
,
variables
,
sizeof
(
uint32_t
)
*
n_variables
);
err
=
trtl_msg_sync
(
trtl
,
idx_cpu
,
idx_hmq
,
&
msg
,
&
msg
,
trtl_default_timeout_ms
);
if
(
err
<=
0
)
return
-
1
;
memcpy
(
variables
,
msg
.
data
,
sizeof
(
uint32_t
)
*
n_variables
);
return
0
;
}
}
...
@@ -291,17 +193,48 @@ int trtl_rt_variable_get(struct trtl_dev *trtl,
...
@@ -291,17 +193,48 @@ int trtl_rt_variable_get(struct trtl_dev *trtl,
* @param[in|out] tlv structures to get on input, structures values on output
* @param[in|out] tlv structures to get on input, structures values on output
* @param[in] n_tlv number of tlv structures
* @param[in] n_tlv number of tlv structures
*/
*/
int
trtl_
rt
_buffer_set
(
struct
trtl_dev
*
trtl
,
int
trtl_
fw
_buffer_set
(
struct
trtl_dev
*
trtl
,
unsigned
int
idx_cpu
,
unsigned
int
idx_cpu
,
unsigned
int
idx_hmq
,
unsigned
int
idx_hmq
,
struct
trtl_
structure_
tlv
*
tlv
,
struct
trtl_tlv
*
tlv
,
unsigned
int
n_tlv
)
unsigned
int
n_tlv
)
{
{
/* FIXME Re-implement with new protocol */
struct
trtl_msg
msg
;
errno
=
ETRTL_NO_IMPLEMENTATION
;
struct
trtl_desc
*
wdesc
=
(
struct
trtl_desc
*
)
trtl
;
return
-
1
;
unsigned
int
offset
;
unsigned
int
total_size
=
0
;
uint32_t
sizes
;
int
err
,
i
;
/* Validate */
for
(
i
=
0
;
i
<
n_tlv
;
++
i
)
{
total_size
+=
8
;
/* 32bit for type and size */
total_size
+=
tlv
->
size
;
sizes
=
wdesc
->
cfgrom
.
hmq
[
idx_cpu
][
idx_hmq
].
sizes
;
if
(
total_size
>
TRTL_CONFIG_ROM_MQ_SIZE_PAYLOAD
(
sizes
)
*
4
)
{
errno
=
EINVAL
;
return
-
1
;
}
}
/* Copy buffers */
for
(
offset
=
0
,
i
=
0
;
i
<
n_tlv
;
++
i
)
{
msg
.
data
[
offset
+
0
]
=
tlv
[
i
].
type
;
msg
.
data
[
offset
+
1
]
=
tlv
[
i
].
size
;
memcpy
(
&
msg
.
data
[
offset
+
2
],
tlv
[
i
].
buf
,
tlv
[
i
].
size
);
offset
+=
(
2
+
(
tlv
->
size
/
4
));
}
err
=
trtl_msg_sync
(
trtl
,
idx_cpu
,
idx_hmq
,
&
msg
,
&
msg
,
trtl_default_timeout_ms
);
if
(
err
<=
0
)
return
-
1
;
return
0
;
}
}
/**
/**
* It receives a set of structures within TLV records.
* It receives a set of structures within TLV records.
* This function will change the header content, in particular it will change
* This function will change the header content, in particular it will change
...
@@ -311,15 +244,52 @@ int trtl_rt_buffer_set(struct trtl_dev *trtl,
...
@@ -311,15 +244,52 @@ int trtl_rt_buffer_set(struct trtl_dev *trtl,
* @param[in|out] tlv structures to get on input, structures values on output
* @param[in|out] tlv structures to get on input, structures values on output
* @param[in] n_tlv number of tlv structures
* @param[in] n_tlv number of tlv structures
*/
*/
int
trtl_
rt
_buffer_get
(
struct
trtl_dev
*
trtl
,
int
trtl_
fw
_buffer_get
(
struct
trtl_dev
*
trtl
,
unsigned
int
idx_cpu
,
unsigned
int
idx_cpu
,
unsigned
int
idx_hmq
,
unsigned
int
idx_hmq
,
struct
trtl_
structure_
tlv
*
tlv
,
struct
trtl_tlv
*
tlv
,
unsigned
int
n_tlv
)
unsigned
int
n_tlv
)
{
{
/* FIXME Re-implement with new protocol */
struct
trtl_msg
msg
;
errno
=
ETRTL_NO_IMPLEMENTATION
;
struct
trtl_desc
*
wdesc
=
(
struct
trtl_desc
*
)
trtl
;
return
-
1
;
unsigned
int
offset
;
unsigned
int
total_size
=
0
;
uint32_t
sizes
;
int
err
,
i
;
/* Validate */
for
(
i
=
0
;
i
<
n_tlv
;
++
i
)
{
total_size
+=
8
;
/* 32bit for type and size */
total_size
+=
tlv
->
size
;
sizes
=
wdesc
->
cfgrom
.
hmq
[
idx_cpu
][
idx_hmq
].
sizes
;
if
(
total_size
>
TRTL_CONFIG_ROM_MQ_SIZE_PAYLOAD
(
sizes
)
*
4
)
{
errno
=
EINVAL
;
return
-
1
;
}
}
/* Copy buffers - only Type and Length */
for
(
offset
=
0
,
i
=
0
;
i
<
n_tlv
;
++
i
)
{
msg
.
data
[
offset
+
0
]
=
tlv
[
i
].
type
;
msg
.
data
[
offset
+
1
]
=
tlv
[
i
].
size
;
offset
+=
(
2
+
(
tlv
->
size
/
4
));
}
err
=
trtl_msg_sync
(
trtl
,
idx_cpu
,
idx_hmq
,
&
msg
,
&
msg
,
trtl_default_timeout_ms
);
if
(
err
<=
0
)
return
-
1
;
/* Copy back buffers - only Type and Length */
for
(
offset
=
0
,
i
=
0
;
i
<
n_tlv
;
++
i
)
{
tlv
[
i
].
type
=
msg
.
data
[
offset
+
0
];
tlv
[
i
].
size
=
msg
.
data
[
offset
+
1
];
memcpy
(
&
tlv
[
i
].
buf
,
&
msg
.
data
[
offset
+
2
],
tlv
[
i
].
size
);
offset
+=
(
2
+
(
tlv
->
size
/
4
));
}
return
0
;
}
}
...
@@ -327,14 +297,19 @@ int trtl_rt_buffer_get(struct trtl_dev *trtl,
...
@@ -327,14 +297,19 @@ int trtl_rt_buffer_get(struct trtl_dev *trtl,
* It prints the message header in a human readable format
* It prints the message header in a human readable format
* @param[in] h message header
* @param[in] h message header
*/
*/
void
trtl_print_header
(
struct
trtl_
proto_header
*
h
)
void
trtl_print_header
(
struct
trtl_
msg
*
msg
)
{
{
struct
trtl_hmq_header
*
h
=
&
msg
->
hdr
;
fprintf
(
stdout
,
fprintf
(
stdout
,
"
app_id 0x%x | msg_id %d | slot_io 0x%x | seq %d
\n
"
,
"
\t
app_id 0x%04"
PRIx16
" | flags 0x%02"
PRIx8
" | msg_id 0x%02"
PRIx8
"
\r
\n
"
,
h
->
rt_app_id
,
h
->
msg_id
,
h
->
slot_io
,
h
->
seq
);
h
->
rt_app_id
,
h
->
flags
,
h
->
msg_id
);
fprintf
(
stdout
,
fprintf
(
stdout
,
" len %d | flags 0x%x | trans 0x%x | time %d
\n
"
,
"
\t
len 0x%04"
PRIx16
" | sync_id 0x%04"
PRIx16
"
\r\n
"
,
h
->
len
,
h
->
flags
,
h
->
trans
,
h
->
time
);
h
->
len
,
h
->
sync_id
);
fprintf
(
stdout
,
"
\t
len 0x%08"
PRIx32
"
\r\n
"
,
h
->
seq
);
}
}
...
@@ -344,26 +319,55 @@ void trtl_print_header(struct trtl_proto_header *h)
...
@@ -344,26 +319,55 @@ void trtl_print_header(struct trtl_proto_header *h)
* @param[in] h message header
* @param[in] h message header
* @param[in] buf message payload
* @param[in] buf message payload
*/
*/
void
trtl_print_payload
(
struct
trtl_
proto_header
*
h
,
void
*
buf
)
void
trtl_print_payload
(
struct
trtl_
msg
*
msg
)
{
{
uint32_t
*
payload
=
buf
;
int
i
;
int
i
;
switch
(
h
->
msg_id
)
{
switch
(
msg
->
hdr
.
msg_id
)
{
case
TRTL_MSG_ID_VAR_SET
:
case
TRTL_MSG_ID_ERROR
:
fprintf
(
stdout
,
"Error message
\n
"
);
fprintf
(
stdout
,
"Error number: %d
\n
"
,
msg
->
data
[
0
]);
break
;
case
TRTL_MSG_ID_PING
:
fprintf
(
stdout
,
"Ping message
\n
"
);
break
;
case
TRTL_MSG_ID_VER
:
{
struct
trtl_fw_version
*
v
=
(
struct
trtl_fw_version
*
)
msg
->
data
;
fprintf
(
stdout
,
"Version message
\n
"
);
fprintf
(
stdout
,
"Firmware ID: 0x%08"
PRIx32
"
\n
"
,
v
->
rt_id
);
fprintf
(
stdout
,
"Firmware version: %d.%d
\n
"
,
RT_VERSION_MAJ
(
v
->
rt_version
),
RT_VERSION_MIN
(
v
->
rt_version
));
fprintf
(
stdout
,
"git SHA: 0x%08"
PRIx32
"
\n
"
,
v
->
git_version
);
break
;
}
case
TRTL_MSG_ID_DBG
:
fprintf
(
stdout
,
"Debug message
\n
"
);
for
(
i
=
0
;
i
<
msg
->
hdr
.
len
;
++
i
)
{
fprintf
(
stdout
,
"Value %d: 0x%08"
PRIx32
"
\n
"
,
i
,
msg
->
data
[
i
]);
}
break
;
case
TRTL_MSG_ID_VAR_GET
:
case
TRTL_MSG_ID_VAR_GET
:
case
TRTL_MSG_ID_VAR_
GET_ANS
:
case
TRTL_MSG_ID_VAR_
SET
:
for
(
i
=
0
;
i
<
h
->
len
;
i
+=
2
)
{
for
(
i
=
0
;
i
<
msg
->
hdr
.
len
;
i
+=
2
)
{
fprintf
(
stdout
,
"
[%d] 0x%08x
\n
"
,
fprintf
(
stdout
,
"
Variable %"
PRId32
": 0x%08"
PRIx32
"
\n
"
,
payload
[
i
],
payload
[
i
+
1
]);
msg
->
data
[
i
],
msg
->
data
[
i
+
1
]);
}
}
break
;
break
;
case
TRTL_MSG_ID_BUF_SET
:
case
TRTL_MSG_ID_BUF_GET
:
fprintf
(
stdout
,
"Buffer message
\n
"
);
/* TODO */
break
;
default:
default:
for
(
i
=
0
;
i
<
h
->
len
;
++
i
)
{
fprintf
(
stdout
,
"Unknown message
\n
"
);
for
(
i
=
0
;
i
<
msg
->
hdr
.
len
;
++
i
)
{
if
(
i
%
4
==
0
)
if
(
i
%
4
==
0
)
fprintf
(
stdout
,
"
\n
%04d :"
,
i
);
fprintf
(
stdout
,
"
\n
%04d :"
,
i
);
fprintf
(
stdout
,
" 0x%08
x"
,
payload
[
i
]);
fprintf
(
stdout
,
" 0x%08
"
PRIx32
,
msg
->
data
[
i
]);
}
}
break
;
break
;
}
}
}
}
...
@@ -377,15 +381,6 @@ void trtl_print_payload(struct trtl_proto_header *h, void *buf)
...
@@ -377,15 +381,6 @@ void trtl_print_payload(struct trtl_proto_header *h, void *buf)
*/
*/
void
trtl_print_message
(
struct
trtl_msg
*
msg
)
void
trtl_print_message
(
struct
trtl_msg
*
msg
)
{
{
struct
trtl_proto_header
h
;
trtl_print_header
(
msg
);
trtl_print_payload
(
msg
);
trtl_message_unpack
(
msg
,
&
h
,
NULL
);
trtl_print_header
(
&
h
);
if
(
h
.
len
)
{
uint32_t
payload
[
h
.
len
];
trtl_message_unpack
(
msg
,
&
h
,
payload
);
trtl_print_payload
(
&
h
,
payload
);
}
}
}
software/lib/libmockturtle.c
View file @
475bc35d
...
@@ -243,6 +243,8 @@ static struct trtl_dev *__trtl_open(const char *device)
...
@@ -243,6 +243,8 @@ static struct trtl_dev *__trtl_open(const char *device)
}
}
}
}
trtl
->
seq
=
0
;
return
(
struct
trtl_dev
*
)
trtl
;
return
(
struct
trtl_dev
*
)
trtl
;
out_hmq_fd:
out_hmq_fd:
...
...
software/lib/libmockturtle.h
View file @
475bc35d
...
@@ -19,8 +19,6 @@ extern "C" {
...
@@ -19,8 +19,6 @@ extern "C" {
#include <stdint.h>
#include <stdint.h>
#include <stdio.h>
#include <stdio.h>
#include <poll.h>
#include <poll.h>
#include "hw/mockturtle_config.h"
#include "mockturtle-common.h"
#include "mockturtle.h"
#include "mockturtle.h"
extern
const
unsigned
int
trtl_default_timeout_ms
;
extern
const
unsigned
int
trtl_default_timeout_ms
;
...
@@ -98,15 +96,6 @@ enum trtl_error_number {
...
@@ -98,15 +96,6 @@ enum trtl_error_number {
};
};
/**
* TLV structure used to embed structures within a message
*/
struct
trtl_structure_tlv
{
uint32_t
index
;
/**< structure index (type) */
void
*
buf
;
/**< pointer to the structure */
size_t
size
;
/**< structure size in byte */
};
/**
/**
* @file libmockturtle.c
* @file libmockturtle.c
*/
*/
...
@@ -134,8 +123,8 @@ const struct trtl_config_rom *trtl_config_get(struct trtl_dev *trtl);
...
@@ -134,8 +123,8 @@ const struct trtl_config_rom *trtl_config_get(struct trtl_dev *trtl);
* Utilities collection
* Utilities collection
* @{
* @{
*/
*/
extern
void
trtl_print_header
(
struct
trtl_
proto_header
*
h
);
extern
void
trtl_print_header
(
struct
trtl_
msg
*
msg
);
extern
void
trtl_print_payload
(
struct
trtl_
proto_header
*
h
,
void
*
buf
);
extern
void
trtl_print_payload
(
struct
trtl_
msg
*
msg
);
extern
void
trtl_print_message
(
struct
trtl_msg
*
msg
);
extern
void
trtl_print_message
(
struct
trtl_msg
*
msg
);
extern
char
*
trtl_strerror
(
int
err
);
extern
char
*
trtl_strerror
(
int
err
);
/**@}*/
/**@}*/
...
@@ -224,58 +213,35 @@ extern int trtl_smem_write(struct trtl_dev *trtl, uint32_t addr, uint32_t *data,
...
@@ -224,58 +213,35 @@ extern int trtl_smem_write(struct trtl_dev *trtl, uint32_t addr, uint32_t *data,
/**@}*/
/**@}*/
/**
* @defgroup proto Protocol management
* Set of utilities to properly handle the protocol
* @{
*/
extern
void
trtl_message_header_set
(
struct
trtl_msg
*
msg
,
struct
trtl_proto_header
*
hdr
);
extern
void
trtl_message_header_get
(
struct
trtl_msg
*
msg
,
struct
trtl_proto_header
*
hdr
);
extern
void
trtl_message_pack
(
struct
trtl_msg
*
msg
,
struct
trtl_proto_header
*
hdr
,
void
*
payload
);
extern
void
trtl_message_unpack
(
struct
trtl_msg
*
msg
,
struct
trtl_proto_header
*
hdr
,
void
*
payload
);
extern
void
trtl_message_buffer_push
(
struct
trtl_msg
*
msg
,
struct
trtl_proto_header
*
hdr
,
struct
trtl_structure_tlv
*
tlv
);
extern
off_t
trtl_message_buffer_pop
(
struct
trtl_msg
*
msg
,
off_t
offset
,
struct
trtl_proto_header
*
hdr
,
struct
trtl_structure_tlv
*
tlv
);
/**@}*/
/**
/**
* @defgroup rtmsg Real Time service messages
* @defgroup rtmsg Real Time service messages
* Message builders for RT service messages
* Message builders for RT service messages
* @{
* @{
*/
*/
extern
int
trtl_
rt_version_get
(
struct
trtl_dev
*
trtl
,
extern
int
trtl_
fw_version
(
struct
trtl_dev
*
trtl
,
unsigned
int
idx_cpu
,
unsigned
int
idx_cpu
,
unsigned
int
idx_hmq
,
unsigned
int
idx_hmq
,
struct
trtl_rt
_version
*
version
);
struct
trtl_fw
_version
*
version
);
extern
int
trtl_
rt
_ping
(
struct
trtl_dev
*
trtl
,
extern
int
trtl_
fw
_ping
(
struct
trtl_dev
*
trtl
,
unsigned
int
idx_cpu
,
unsigned
int
idx_cpu
,
unsigned
int
idx_hmq
);
unsigned
int
idx_hmq
);
extern
int
trtl_
rt
_variable_set
(
struct
trtl_dev
*
trtl
,
extern
int
trtl_
fw
_variable_set
(
struct
trtl_dev
*
trtl
,
unsigned
int
idx_cpu
,
unsigned
int
idx_cpu
,
unsigned
int
idx_hmq
,
unsigned
int
idx_hmq
,
uint32_t
*
var
,
unsigned
int
n_var
);
uint32_t
*
var
,
unsigned
int
n_var
);
extern
int
trtl_
rt
_variable_get
(
struct
trtl_dev
*
trtl
,
extern
int
trtl_
fw
_variable_get
(
struct
trtl_dev
*
trtl
,
unsigned
int
idx_cpu
,
unsigned
int
idx_cpu
,
unsigned
int
idx_hmq
,
unsigned
int
idx_hmq
,
uint32_t
*
var
,
unsigned
int
n_var
);
uint32_t
*
var
,
unsigned
int
n_var
);
extern
int
trtl_
rt
_buffer_set
(
struct
trtl_dev
*
trtl
,
extern
int
trtl_
fw
_buffer_set
(
struct
trtl_dev
*
trtl
,
unsigned
int
idx_cpu
,
unsigned
int
idx_cpu
,
unsigned
int
idx_hmq
,
unsigned
int
idx_hmq
,
struct
trtl_
structure_
tlv
*
tlv
,
struct
trtl_tlv
*
tlv
,
unsigned
int
n_tlv
);
unsigned
int
n_tlv
);
extern
int
trtl_
rt
_buffer_get
(
struct
trtl_dev
*
trtl
,
extern
int
trtl_
fw
_buffer_get
(
struct
trtl_dev
*
trtl
,
unsigned
int
idx_cpu
,
unsigned
int
idx_cpu
,
unsigned
int
idx_hmq
,
unsigned
int
idx_hmq
,
struct
trtl_
structure_
tlv
*
tlv
,
struct
trtl_tlv
*
tlv
,
unsigned
int
n_tlv
);
unsigned
int
n_tlv
);
/**@}*/
/**@}*/
#ifdef __cplusplus
#ifdef __cplusplus
...
...
software/rt/Makefile
View file @
475bc35d
...
@@ -16,6 +16,7 @@ AUTOCONF = $(CURDIR)/$(BUILDDIR)/include/generated/autoconf.h
...
@@ -16,6 +16,7 @@ AUTOCONF = $(CURDIR)/$(BUILDDIR)/include/generated/autoconf.h
CROSS_COMPILE_TARGET
?=
riscv32-elf-
CROSS_COMPILE_TARGET
?=
riscv32-elf-
# FIXME the mult/div is broken, for the time being remove it completely
# FIXME the mult/div is broken, for the time being remove it completely
# -march=rv32im should be the future option
# -march=rv32im should be the future option
CFLAGS
+=
-D__TRTL_FIRMWARE__
CFLAGS
+=
-mabi
=
ilp32
-march
=
rv32i
-ffunction-sections
-fdata-sections
CFLAGS
+=
-mabi
=
ilp32
-march
=
rv32i
-ffunction-sections
-fdata-sections
LDFLAGS
+=
-lgcc
-lc
-Wl
,--gc-sections
LDFLAGS
+=
-lgcc
-lc
-Wl
,--gc-sections
...
@@ -66,10 +67,7 @@ OBJS += lib/printf.o
...
@@ -66,10 +67,7 @@ OBJS += lib/printf.o
OBJS
+=
lib/mockturtle-rt-common.o
OBJS
+=
lib/mockturtle-rt-common.o
OBJDIR-$(CONFIG_MOCKTURTLE_FRAMEWORK_ENABLE)
+=
framework
OBJDIR-$(CONFIG_MOCKTURTLE_FRAMEWORK_ENABLE)
+=
framework
OBJS-$(CONFIG_MOCKTURTLE_FRAMEWORK_ENABLE)
+=
framework/mockturtle-frm-core.o
OBJS-$(CONFIG_MOCKTURTLE_FRAMEWORK_ENABLE)
+=
framework/mockturtle-framework.o
OBJS-$(CONFIG_MOCKTURTLE_FRAMEWORK_ENABLE)
+=
framework/mockturtle-frm-debug.o
OBJS-$(CONFIG_MOCKTURTLE_FRAMEWORK_ENABLE)
+=
framework/mockturtle-frm-action.o
OBJS-$(CONFIG_MOCKTURTLE_FRAMEWORK_ENABLE)
+=
framework/mockturtle-frm-mqueue.o
OBJDIR
+=
$
(
OBJDIR-y
)
OBJDIR
+=
$
(
OBJDIR-y
)
OBJS
+=
$
(
OBJS-y
)
OBJS
+=
$
(
OBJS-y
)
...
...
software/rt/framework/mockturtle-framework.c
0 → 100644
View file @
475bc35d
/**
* Copyright (C) 2015-2016 CERN (www.cern.ch)
* Author: Federico Vaga <federico.vaga@cern.ch>
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#include <errno.h>
#include <inttypes.h>
#include <stdint.h>
#include <mockturtle-framework.h>
uint32_t
msg_seq
=
0
;
struct
trtl_fw_application
*
_app
;
/**
* It makes the given message an error message
*/
void
trtl_fw_message_error
(
struct
trtl_msg
*
msg
,
int
err
)
{
msg
->
header
->
msg_id
=
TRTL_MSG_ID_ERROR
;
msg
->
header
->
len
=
1
;
((
uint32_t
*
)
msg
->
payload
)[
0
]
=
err
;
}
/**
* This is an @ref trtl_fw_action_t function type. It fills the payload
* witht an answer for the ping message.
*/
static
int
rt_recv_ping
(
struct
trtl_msg
*
msg_i
,
struct
trtl_msg
*
msg_o
)
{
msg_o
->
header
->
msg_id
=
TRTL_MSG_ID_PING
;
return
0
;
}
/**
* This is an @ref trtl_fw_action_t function type. It fills the payload with
* version information.
*/
static
int
rt_version_getter
(
struct
trtl_msg
*
msg_i
,
struct
trtl_msg
*
msg_o
)
{
msg_o
->
header
->
msg_id
=
TRTL_MSG_ID_VER
;
msg_o
->
header
->
len
=
sizeof
(
struct
trtl_fw_version
)
/
4
;
memcpy
(
msg_o
->
payload
,
(
void
*
)
&
_app
->
version
,
sizeof
(
struct
trtl_fw_version
));
return
0
;
}
/**
* This is an @ref trtl_fw_action_t function type. Accorind the message request,
* it copies one of the declared data structure to the output payload.
*/
static
int
trtl_fw_buffer_getter
(
struct
trtl_msg
*
msg_i
,
struct
trtl_msg
*
msg_o
)
{
unsigned
int
offset
=
0
,
index
,
size
;
uint32_t
*
din
;
uint32_t
*
dout
;
if
(
!
HAS_MOCKTURTLE_FRAMEWORK_BUFFER_ENABLE
)
{
return
-
EPERM
;
}
/* Only synchronous */
if
(
!
(
msg_i
->
header
->
flags
&
TRTL_HMQ_HEADER_FLAG_SYNC
))
return
-
EINVAL
;
msg_o
->
header
->
msg_id
=
TRTL_MSG_ID_BUF_GET
;
din
=
msg_i
->
payload
;
dout
=
msg_o
->
payload
;
while
(
offset
<
msg_i
->
header
->
len
)
{
pr_debug
(
"%s: offset %d/%d
\n\r
"
,
__func__
,
offset
,
msg_i
->
header
->
len
);
index
=
din
[
offset
];
dout
[
offset
++
]
=
index
;
size
=
din
[
offset
];
dout
[
offset
++
]
=
size
;
pr_debug
(
"%s Type %d Len %d Addr 0x%p
\n\r
"
,
__func__
,
index
,
size
,
_app
->
buffers
[
index
].
buf
);
if
(
_app
->
buffers
[
index
].
len
==
size
)
{
memcpy
(
&
dout
[
offset
],
(
uint32_t
*
)
_app
->
buffers
[
index
].
buf
,
size
);
}
else
{
pr_error
(
"%s: structure %d len not correct %"
PRId32
" != %d
\n\r
"
,
__func__
,
index
,
_app
->
buffers
[
index
].
len
,
size
);
}
offset
+=
(
size
/
4
);
/* Next TLV record */
}
return
0
;
}
/**
* This is an @ref trtl_fw_action_t function type. Accorind the message request,
* it overwrite a data structure with the one contained in the input
* payload. If the message is syncrnous it will copy back the data structure.
*/
static
int
trtl_fw_buffer_setter
(
struct
trtl_msg
*
msg_i
,
struct
trtl_msg
*
msg_o
)
{
unsigned
int
offset
=
0
,
index
,
size
;
uint32_t
*
din
;
if
(
!
HAS_MOCKTURTLE_FRAMEWORK_BUFFER_ENABLE
)
{
return
-
EPERM
;
}
din
=
msg_i
->
payload
;
while
(
offset
<
msg_i
->
header
->
len
)
{
pr_debug
(
"%s: offset %d/%d
\n\r
"
,
__func__
,
offset
,
msg_i
->
header
->
len
);
index
=
din
[
offset
++
];
size
=
din
[
offset
++
];
pr_debug
(
"%s Type %d Len %d Addr 0x%p
\n\r
"
,
__func__
,
index
,
size
,
_app
->
buffers
[
index
].
buf
);
if
(
_app
->
buffers
[
index
].
len
==
size
)
{
memcpy
((
uint32_t
*
)
_app
->
buffers
[
index
].
buf
,
&
din
[
offset
],
size
);
}
else
{
pr_error
(
"%s:%d structure %d len not correct %"
PRId32
" != %d
\n\r
"
,
__func__
,
__LINE__
,
index
,
_app
->
buffers
[
index
].
len
,
size
);
}
offset
+=
(
size
/
4
);
/* Next TLV record */
}
/* Return back new values. Host can compare with what it sent
to spot errors */
if
(
msg_i
->
header
->
flags
&
TRTL_HMQ_HEADER_FLAG_SYNC
)
return
trtl_fw_buffer_getter
(
msg_i
,
msg_o
);
return
0
;
}
/**
* This is an @ref trtl_fw_action_t function type. Accorind the message request,
* it copies a number of declared variables.
*/
static
int
trtl_fw_variable_getter
(
struct
trtl_msg
*
msg_i
,
struct
trtl_msg
*
msg_o
)
{
struct
trtl_fw_variable
*
var
;
uint32_t
*
dout
,
*
din
,
*
mem
,
val
;
int
i
;
if
(
!
HAS_MOCKTURTLE_FRAMEWORK_VARIABLE_ENABLE
)
{
return
-
EPERM
;
}
/* Only synchronous */
if
(
!
(
msg_i
->
header
->
flags
&
TRTL_HMQ_HEADER_FLAG_SYNC
))
return
-
EINVAL
;
/* we always have a pair of values */
if
(
msg_i
->
header
->
len
&
0x1
)
return
-
EINVAL
;
din
=
msg_i
->
payload
;
dout
=
msg_o
->
payload
;
msg_o
->
header
->
msg_id
=
TRTL_MSG_ID_VAR_GET
;
msg_o
->
header
->
len
=
msg_i
->
header
->
len
;
/* Write all values in the proper place */
for
(
i
=
0
;
i
<
msg_o
->
header
->
len
;
i
+=
2
)
{
if
(
din
[
i
]
>=
_app
->
n_variables
)
{
dout
[
i
]
=
~
0
;
/* Report invalid index */
continue
;
}
dout
[
i
]
=
din
[
i
];
var
=
&
_app
->
variables
[
dout
[
i
]];
mem
=
(
uint32_t
*
)
var
->
addr
;
val
=
(
*
mem
>>
var
->
offset
)
&
var
->
mask
;
dout
[
i
+
1
]
=
val
;
pr_debug
(
"%s index %"
PRIu32
"d/%d | [0x%p] = 0x%08"
PRIx32
" -> 0x%08"
PRIx32
" | index in msg (%d/%d)
\n\r
"
,
__func__
,
dout
[
i
],
_app
->
n_variables
-
1
,
mem
,
*
mem
,
dout
[
i
+
1
],
i
+
1
,
msg_i
->
header
->
len
-
1
);
}
return
0
;
}
/**
* This is an @ref trtl_fw_action_t function type. Accorind the message request,
* it writes a number of declared variables. If the message is synchronous
* it copies back the values in the output payload.
*/
static
int
trtl_fw_variable_setter
(
struct
trtl_msg
*
msg_i
,
struct
trtl_msg
*
msg_o
)
{
struct
trtl_fw_variable
*
var
;
uint32_t
*
din
,
*
mem
,
val
;
int
i
;
if
(
!
HAS_MOCKTURTLE_FRAMEWORK_VARIABLE_ENABLE
)
{
return
-
EPERM
;
}
/* we always have a pair of values */
if
(
msg_i
->
header
->
len
&
0x1
)
return
-
EINVAL
;
din
=
msg_i
->
payload
;
/* Write all values in the proper place */
for
(
i
=
0
;
i
<
msg_i
->
header
->
len
;
i
+=
2
)
{
if
(
din
[
i
]
>=
_app
->
n_variables
)
continue
;
var
=
&
_app
->
variables
[
din
[
i
]];
mem
=
(
uint32_t
*
)
var
->
addr
;
val
=
((
din
[
i
+
1
]
&
var
->
mask
)
<<
var
->
offset
);
if
(
var
->
flags
&
TRTL_FW_VARIABLE_FLAG_FLD
)
*
mem
=
(
*
mem
&
~
var
->
mask
)
|
val
;
else
*
mem
=
val
;
pr_debug
(
"%s index %"
PRIu32
"/%d | [0x%p] = 0x%08"
PRIx32
" <- 0x%08"
PRIx32
" (0x%08"
PRIx32
") | index in msg (%d/%d)
\n\r
"
,
__func__
,
din
[
i
],
_app
->
n_variables
-
1
,
mem
,
*
mem
,
val
,
din
[
i
+
1
],
i
+
1
,
msg_i
->
header
->
len
-
1
);
}
/* Return back new values. Host can compare with what it sent
to spot errors */
if
(
msg_i
->
header
->
flags
&
TRTL_HMQ_HEADER_FLAG_SYNC
)
return
trtl_fw_variable_getter
(
msg_i
,
msg_o
);
return
0
;
}
/**
* List of standard actions
*/
static
trtl_fw_action_t
*
trtl_actions_in
[]
=
{
[
TRTL_MSG_ID_PING
-
__TRTL_MSG_ID_MAX_USER
]
=
rt_recv_ping
,
[
TRTL_MSG_ID_VER
-
__TRTL_MSG_ID_MAX_USER
]
=
rt_version_getter
,
[
TRTL_MSG_ID_VAR_SET
-
__TRTL_MSG_ID_MAX_USER
]
=
trtl_fw_variable_setter
,
[
TRTL_MSG_ID_VAR_GET
-
__TRTL_MSG_ID_MAX_USER
]
=
trtl_fw_variable_getter
,
[
TRTL_MSG_ID_BUF_SET
-
__TRTL_MSG_ID_MAX_USER
]
=
trtl_fw_buffer_setter
,
[
TRTL_MSG_ID_BUF_GET
-
__TRTL_MSG_ID_MAX_USER
]
=
trtl_fw_buffer_getter
,
};
/**
* According to the given message ID it returns the correspondent action
* @param[in] msg_id message id
* @return pointer to action function
*/
static
inline
trtl_fw_action_t
*
rt_action_get
(
unsigned
int
msg_id
)
{
unsigned
int
idx_act
=
msg_id
;
if
(
idx_act
<
__TRTL_MSG_ID_MAX_USER
)
{
/* User Actions */
if
(
idx_act
>=
_app
->
n_actions
||
!
_app
->
actions
[
idx_act
])
{
pr_error
(
"Unknown action (usr) msg_id 0x%x
\n\r
"
,
msg_id
);
return
NULL
;
}
return
_app
->
actions
[
idx_act
];
}
else
{
/* Mock Turtle Standard Actions */
idx_act
-=
__TRTL_MSG_ID_MAX_USER
;
if
(
ARRAY_SIZE
(
trtl_actions_in
)
<
idx_act
)
{
pr_error
(
"Unknown action msg_id 0x%x
\n\r
"
,
msg_id
);
return
NULL
;
}
return
trtl_actions_in
[
idx_act
];
}
}
/**
* It runs the action associated with the given identifier
* @param[in] id action identifier
* @param[in] msg_i input message for the action
* @param[out] msg_o output message from the action
* @return 0 on success. Otherwise an error code
*
* If the action generates an error, the framework will send
* an error message with the error code.
*/
static
inline
int
rt_action_run
(
enum
trtl_mq_type
type
,
unsigned
int
idx_mq
,
struct
trtl_msg
*
msg
)
{
struct
trtl_msg
msg_out
;
trtl_fw_action_t
*
action
=
rt_action_get
(
msg
->
header
->
msg_id
);
int
err
=
0
;
if
(
!
action
)
return
EINVAL
;
if
(
!
(
msg
->
header
->
flags
&
TRTL_HMQ_HEADER_FLAG_SYNC
))
{
/* Asynchronous message, then no output */
return
action
(
msg
,
NULL
);
}
/* Synchronous message */
mq_claim
(
type
,
idx_mq
);
mq_map_out_message
(
type
,
idx_mq
,
&
msg_out
);
/* prepare the header */
msg_out
.
header
->
rt_app_id
=
_app
->
version
.
rt_id
;
msg_out
.
header
->
flags
=
TRTL_HMQ_HEADER_FLAG_ACK
;
msg_out
.
header
->
msg_id
=
0
;
msg_out
.
header
->
len
=
0
;
msg_out
.
header
->
sync_id
=
msg
->
header
->
sync_id
;
msg_out
.
header
->
seq
=
_app
->
seq
++
;
err
=
action
(
msg
,
&
msg_out
);
if
(
err
)
trtl_fw_message_error
(
&
msg_out
,
err
);
trtl_fw_print_message
(
&
msg_out
);
mq_send
(
type
,
idx_mq
);
return
err
;
}
/**
* It dispatch messages coming from a given message queue.
* @param[in] mq_in MQ index within mq declaration in rt_application
* @todo provide support for remote queue
* @return 0 on success. -1 on error
*/
int
trtl_fw_mq_action_dispatch
(
enum
trtl_mq_type
type
,
unsigned
int
idx_mq
)
{
struct
trtl_msg
msg
;
int
err
=
0
;
if
(
type
==
TRTL_RMQ
)
return
-
EPERM
;
/* not supported yet */
/* Check if we have a pending message */
if
(
!
(
mq_poll_in
(
type
)
&
(
1
<<
idx_mq
)))
return
-
EAGAIN
;
/* Map the message */
mq_map_in_message
(
type
,
idx_mq
,
&
msg
);
trtl_fw_print_message
(
&
msg
);
if
(
!
(
msg
.
header
->
flags
&
TRTL_HMQ_HEADER_FLAG_RPC
))
{
return
-
EINVAL
;
}
if
(
msg
.
header
->
rt_app_id
&&
msg
.
header
->
rt_app_id
!=
_app
->
version
.
rt_id
)
{
pr_error
(
"Invalid app id 0x%x
\n\r
"
,
msg
.
header
->
rt_app_id
);
err
=
-
EINVAL
;
goto
out
;
}
/* Run the correspondent action */
err
=
rt_action_run
(
type
,
idx_mq
,
&
msg
);
if
(
err
)
pr_error
(
"Action failure err: %d
\n\r
"
,
err
);
out:
mq_discard
(
type
,
idx_mq
);
return
err
;
}
/**
* It builds and it sends a message over MQ.
* The vargs will be copied into the payload message.
* @param[in] type MQ type
* @param[in] idx_mq MQ index within the declaration
* @param[in] msg_id message identifier
* @param[in] n number of vargs
*/
int
trtl_fw_mq_send_uint32
(
enum
trtl_mq_type
type
,
unsigned
int
idx_mq
,
uint8_t
msg_id
,
unsigned
int
n
,
...)
{
struct
trtl_msg
msg
;
uint32_t
sizes
;
va_list
ap
;
int
i
;
sizes
=
_app
->
cfgrom
->
hmq
[
trtl_get_core_id
()][
idx_mq
].
sizes
;
if
(
n
>
TRTL_CONFIG_ROM_MQ_SIZE_PAYLOAD
(
sizes
))
return
-
EINVAL
;
mq_claim
(
type
,
idx_mq
);
mq_map_out_message
(
type
,
idx_mq
,
&
msg
);
msg
.
header
->
rt_app_id
=
_app
->
version
.
rt_id
;
msg
.
header
->
flags
=
0
;
msg
.
header
->
msg_id
=
msg_id
;
msg
.
header
->
len
=
n
;
msg
.
header
->
seq
=
_app
->
seq
++
;
va_start
(
ap
,
n
);
for
(
i
=
0
;
i
<
msg
.
header
->
len
;
++
i
)
((
uint32_t
*
)
msg
.
payload
)[
i
]
=
va_arg
(
ap
,
uint32_t
);
va_end
(
ap
);
mq_send
(
type
,
idx_mq
);
return
0
;
}
/**
* It builds and it sends a message over MQ.
* The buffer will be copied into the payload message.
* Beware that, internally, it uses trtl_fw_mq_send().
* @param[in] type MQ type
* @param[in] idx_mq MQ index within the declaration
* @param[in] msg_id message identifier
* @param[in] n buffer size in bytes
* @param[in] data buffer to send
*/
int
trtl_fw_mq_send_buf
(
enum
trtl_mq_type
type
,
unsigned
int
idx_mq
,
uint8_t
msg_id
,
unsigned
int
n
,
void
*
data
)
{
struct
trtl_msg
msg
;
uint32_t
sizes
;
sizes
=
_app
->
cfgrom
->
hmq
[
trtl_get_core_id
()][
idx_mq
].
sizes
;
if
((
n
/
4
)
>
TRTL_CONFIG_ROM_MQ_SIZE_PAYLOAD
(
sizes
))
return
-
EINVAL
;
mq_claim
(
type
,
idx_mq
);
mq_map_out_message
(
type
,
idx_mq
,
&
msg
);
msg
.
header
->
rt_app_id
=
_app
->
version
.
rt_id
;
msg
.
header
->
flags
=
0
;
msg
.
header
->
msg_id
=
msg_id
;
msg
.
header
->
len
=
n
/
4
;
msg
.
header
->
seq
=
_app
->
seq
++
;
memcpy
(
msg
.
payload
,
data
,
n
);
mq_send
(
type
,
idx_mq
);
return
0
;
}
/**
* It prints on the serial interface the given message header
* @param[in] h message header to print
*/
void
trtl_fw_print_header
(
struct
trtl_hmq_header
*
h
)
{
if
(
!
HAS_MOCKTURTLE_FRAMEWORK_DEBUG_ENABLE
)
{
return
;
}
pr_debug
(
"
\t
app_id 0x%04"
PRIx16
" | flags 0x%02"
PRIx8
" | msg_id 0x%02"
PRIx8
"
\r\n
"
,
h
->
rt_app_id
,
h
->
flags
,
h
->
msg_id
);
delay
(
1000
);
pr_debug
(
"
\t
len 0x%04"
PRIx16
" | sync_id 0x%04"
PRIx16
"
\r\n
"
,
h
->
len
,
h
->
sync_id
);
delay
(
1000
);
pr_debug
(
"
\t
seq 0x%08"
PRIx32
"
\r\n
"
,
h
->
seq
);
delay
(
1000
);
}
/**
* It prints on the serial interface a buffer
* @param[in] d buffer data
* @param[in] count number of 32bit words to show
*/
void
trtl_fw_print_data
(
uint32_t
*
d
,
unsigned
int
count
)
{
int
i
;
if
(
!
HAS_MOCKTURTLE_FRAMEWORK_DEBUG_ENABLE
)
{
return
;
}
for
(
i
=
0
;
i
<
count
;
i
++
)
{
pr_debug
(
"%s: data[%d] = 0x%"
PRIx32
"
\n\r
"
,
__func__
,
i
,
d
[
i
]);
delay
(
1000
);
}
}
/**
* It prints on the serial console the given message
* @param[in] msg a mock turtle message
*/
void
trtl_fw_print_message
(
struct
trtl_msg
*
msg
)
{
pr_debug
(
"Message
\n\r
"
);
trtl_fw_print_header
(
msg
->
header
);
trtl_fw_print_data
(
msg
->
payload
,
msg
->
header
->
len
);
}
/**
* It get the current time from the internal WRNC timer
* @param[out] seconds
* @param[out] cycles
*/
void
trtl_fw_time
(
uint32_t
*
seconds
,
uint32_t
*
cycles
)
{
*
seconds
=
lr_readl
(
MT_CPU_LR_REG_TAI_SEC
);
*
cycles
=
lr_readl
(
MT_CPU_LR_REG_TAI_CYCLES
);
}
/**
* It validates the user application actions
* @param[in] app the user application
* @return 0 on success. -EINVAL on error
*/
static
inline
int
trtl_fw_init_action
(
struct
trtl_fw_application
*
app
)
{
int
i
;
/* Validate actions */
for
(
i
=
0
;
i
<
_app
->
n_actions
;
++
i
)
{
if
(
i
>
__TRTL_MSG_ID_MAX_USER
)
{
pr_error
(
"Too many actions defined. Maximum '%d'
\n\r
"
,
__TRTL_MSG_ID_MAX_USER
);
return
-
EINVAL
;
}
if
(
_app
->
actions
[
i
]
==
NULL
)
{
pr_error
(
"Undefined action %d
\n\r
"
,
i
);
return
-
EINVAL
;
}
}
return
0
;
}
/**
* It validates the FPGA
* @param[in] app the user application
* @return 0 on success. -EINVAL on error
*/
static
inline
int
trtl_fw_init_fpga
(
struct
trtl_fw_application
*
app
)
{
int
i
,
found
=
0
;
for
(
i
=
0
;
i
<
app
->
fpga_id_compat_n
;
i
++
)
{
if
(
app
->
fpga_id_compat
[
i
]
==
app
->
cfgrom
->
app_id
)
{
found
=
1
;
break
;
}
}
if
(
!
found
)
{
pr_error
(
"
\t
FPGA '0x%"
PRIx32
"' not compatible with RT app: 0x%"
PRIx32
" 0x%"
PRIx32
" (git %"
PRIx32
")
\n\r
"
,
app
->
cfgrom
->
app_id
,
app
->
version
.
rt_id
,
app
->
version
.
rt_version
,
app
->
version
.
git_version
);
return
-
EINVAL
;
}
pr_debug
(
"Running application '%s'
\n\r
"
,
app
->
name
);
pr_debug
(
"
\t
app id
\t
'0x%"
PRIx32
"'
\n\r
"
,
app
->
version
.
rt_id
);
pr_debug
(
"
\t
app version
\t
'%"
PRId32
".%"
PRId32
"'
\n\r
"
,
RT_VERSION_MAJ
(
app
->
version
.
rt_version
),
RT_VERSION_MIN
(
app
->
version
.
rt_version
));
pr_debug
(
"
\t
source id
\t
'0x%"
PRIx32
"'
\n\r
"
,
app
->
version
.
git_version
);
return
0
;
}
/**
* It validates the RMQ and the HMQ
* @param[in] app the user application
* @return 0 on success. -EINVAL on error
*/
static
inline
int
trtl_fw_init_mq
(
struct
trtl_fw_application
*
app
)
{
return
0
;
}
/**
* It validates the RMQ and the HMQ
* @param[in] app the user application
* @return 0 on success. -EINVAL on error
*/
static
inline
int
trtl_fw_init_variables
(
struct
trtl_fw_application
*
app
)
{
int
i
;
pr_debug
(
"Exported Variables
\n\r
"
);
for
(
i
=
0
;
i
<
app
->
n_variables
;
++
i
)
pr_debug
(
"[%d] addr %p | mask 0x%"
PRIx32
" | off %d
\n\r
"
,
i
,
app
->
variables
[
i
].
addr
,
app
->
variables
[
i
].
mask
,
app
->
variables
[
i
].
offset
);
return
0
;
}
/**
* It validates the RMQ and the HMQ
* @param[in] app the user application
* @return 0 on success. -EINVAL on error
*/
static
inline
int
trtl_fw_init_buffers
(
struct
trtl_fw_application
*
app
)
{
int
i
;
pr_debug
(
"Exported Buffers
\n\r
"
);
for
(
i
=
0
;
i
<
app
->
n_buffers
;
++
i
)
pr_debug
(
"[%d] addr %p | len %"
PRId32
"
\n\r
"
,
i
,
app
->
buffers
[
i
].
buf
,
app
->
buffers
[
i
].
len
);
return
0
;
}
/**
* The function initializes the library and it does some compatibility check.
*
* Initialization
* - purge all the output host-message-queue
*
* compatibility checks:
* - check bitstream FPGA ID if compatibile with the application. The value in
* app->version.fpga_id will be updated with the FPGA ID from the bitstream
*
* @param[in] app application declaration
* @return 0 on success. -1 on error
*/
int
trtl_fw_init
(
struct
trtl_fw_application
*
app
)
{
int
err
;
_app
=
app
;
_app
->
seq
=
0
;
_app
->
cfgrom
=
trtl_config_rom_get
();
err
=
trtl_fw_init_action
(
_app
);
if
(
err
)
return
err
;
err
=
trtl_fw_init_fpga
(
_app
);
if
(
err
)
return
err
;
err
=
trtl_fw_init_mq
(
_app
);
if
(
err
)
return
err
;
err
=
trtl_fw_init_buffers
(
_app
);
if
(
err
)
return
err
;
err
=
trtl_fw_init_variables
(
_app
);
if
(
err
)
return
err
;
return
0
;
}
software/rt/framework/mockturtle-framework.h
View file @
475bc35d
...
@@ -10,13 +10,98 @@
...
@@ -10,13 +10,98 @@
#ifndef __TRTL_FW_FRM_H__
#ifndef __TRTL_FW_FRM_H__
#define __TRTL_FW_FRM_H__
#define __TRTL_FW_FRM_H__
#include <inttypes.h>
#include <generated/autoconf.h>
#include <generated/autoconf.h>
#include "mockturtle-rt.h"
#include "mockturtle-rt.h"
#include "mockturtle-frm-action.h"
#include "mockturtle-frm-mqueue.h"
#include "mockturtle-frm-common.h"
/**
#include "mockturtle-frm-debug.h"
* Action prototype type
#include "mockturtle-frm-variable.h"
* @param[in] msg_i input message
* @param[out] msg_o output message
* @return 0 on success. -1 on error
*
* The header for the output message is prepared by the framework.
* The header's fields that the user should touch are
*
* On error the message will be sent anyway to the host. This
* is just in case of future development.
*/
typedef
int
(
trtl_fw_action_t
)(
struct
trtl_msg
*
msg_i
,
struct
trtl_msg
*
msg_o
);
/**
* Variable flag. Register
*/
#define TRTL_FW_VARIABLE_FLAG_FLD (1 << 0)
/**
* Description of a variable that we want to export to the external
* world (host or network).
*/
struct
trtl_fw_variable
{
void
*
addr
;
/**< variable address */
uint32_t
mask
;
/**< variable mask without offset applied */
uint8_t
offset
;
/**< variable offset within the word */
uint32_t
flags
;
/**< variable options */
};
/**
* Description of a buffer that we want to export to the external world
* (host or network)
*/
struct
trtl_fw_buffer
{
void
*
buf
;
/**< structure location */
uint32_t
len
;
/**< data structure lenght */
/* Maybe other option later in time */
};
/**
* Real-Time Application Descriptor
*/
struct
trtl_fw_application
{
const
char
name
[
16
];
/**< Firmware name*/
const
uint32_t
*
fpga_id_compat
;
/**< list of compatible FPGA
application ID */
const
unsigned
int
fpga_id_compat_n
;
/**< number of entry in
the fpga_id_compat list */
const
struct
trtl_fw_version
version
;
/**< version running */
struct
trtl_fw_buffer
*
buffers
;
/**< exported buffers */
unsigned
int
n_buffers
;
/**< number or exported buffers */
struct
trtl_fw_variable
*
variables
;
/**< exported variables */
unsigned
int
n_variables
;
/**< number or exported variables */
trtl_fw_action_t
**
actions
;
/**< list of custum actions */
unsigned
int
n_actions
;
/**< number of custum actions */
unsigned
int
seq
;
/** sequence number reference */
const
struct
trtl_config_rom
*
cfgrom
;
};
extern
struct
trtl_fw_application
*
_app
;
extern
int
trtl_fw_init
(
struct
trtl_fw_application
*
app
);
extern
void
trtl_fw_time
(
uint32_t
*
seconds
,
uint32_t
*
cycles
);
extern
void
trtl_fw_print_header
(
struct
trtl_hmq_header
*
h
);
extern
void
trtl_fw_print_data
(
uint32_t
*
d
,
unsigned
int
count
);
extern
void
trtl_fw_print_message
(
struct
trtl_msg
*
msg
);
extern
int
trtl_fw_mq_send_uint32
(
enum
trtl_mq_type
type
,
unsigned
int
idx_mq
,
uint8_t
msg_id
,
unsigned
int
n
,
...);
extern
int
trtl_fw_mq_send_buf
(
enum
trtl_mq_type
type
,
unsigned
int
idx_mq
,
uint8_t
msg_id
,
unsigned
int
n
,
void
*
data
);
extern
int
trtl_fw_mq_action_dispatch
(
enum
trtl_mq_type
type
,
unsigned
int
idx_mq
);
extern
void
trtl_fw_message_error
(
struct
trtl_msg
*
msg
,
int
err
);
#endif
#endif
/**@}*/
/**@}*/
software/rt/framework/mockturtle-frm-action.c
deleted
100644 → 0
View file @
c6c69f99
/**
* Copyright (C) 2015-2016 CERN (www.cern.ch)
* Author: Federico Vaga <federico.vaga@cern.ch>
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <errno.h>
#include <inttypes.h>
#include <mockturtle-framework.h>
/**
* This is an @ref action_t function type. It fills the payload
* witht an answer for the ping message.
*/
int
rt_recv_ping
(
struct
trtl_proto_header
*
hin
,
void
*
pin
,
struct
trtl_proto_header
*
hout
,
void
*
pout
)
{
rt_send_ack
(
hin
,
pin
,
hout
,
pout
);
return
0
;
}
/**
* This is an @ref action_t function type. It fills the payload with
* version information.
*/
int
rt_version_getter
(
struct
trtl_proto_header
*
hin
,
void
*
pin
,
struct
trtl_proto_header
*
hout
,
void
*
pout
)
{
uint32_t
*
dout
=
pout
;
hout
->
msg_id
=
TRTL_MSG_ID_VERS_ANS
;
hout
->
len
=
sizeof
(
struct
trtl_rt_version
)
/
4
;
memcpy
(
dout
,
(
uint32_t
*
)
&
_app
->
version
,
sizeof
(
struct
trtl_rt_version
));
return
0
;
}
/**
* This is an @ref action_t function type. Accorind the message request,
* it overwrite a data structure with the one contained in the input
* payload. If the message is syncrnous it will copy back the data structure.
*/
int
rt_buffer_setter
(
struct
trtl_proto_header
*
hin
,
void
*
pin
,
struct
trtl_proto_header
*
hout
,
void
*
pout
)
{
unsigned
int
offset
=
0
,
index
,
size
;
uint32_t
*
din
=
pin
;
if
(
!
HAS_MOCKTURTLE_FRAMEWORK_BUFFER_ENABLE
)
{
rt_send_nack
(
hin
,
pin
,
hout
,
NULL
);
return
0
;
}
while
(
offset
<
hin
->
len
)
{
pr_debug
(
"%s: offset %d/%d
\n\r
"
,
__func__
,
offset
,
hin
->
len
);
index
=
din
[
offset
++
];
size
=
din
[
offset
++
];
pr_debug
(
"%s Type %d Len %d Addr 0x%p
\n\r
"
,
__func__
,
index
,
size
,
_app
->
buffers
[
index
].
buf
);
if
(
_app
->
buffers
[
index
].
len
==
size
)
{
memcpy
((
uint32_t
*
)
_app
->
buffers
[
index
].
buf
,
&
din
[
offset
],
size
);
}
else
{
pr_error
(
"%s:%d structure %d len not correct %"
PRId32
" != %d
\n\r
"
,
__func__
,
__LINE__
,
index
,
_app
->
buffers
[
index
].
len
,
size
);
}
offset
+=
(
size
/
4
);
/* Next TLV record */
}
/* Return back new values. Host can compare with what it sent
to spot errors */
if
(
hin
->
flags
&
TRTL_HEAD_FLAG_SYNC
)
return
rt_buffer_getter
(
hin
,
pin
,
hout
,
pout
);
return
0
;
}
/**
* This is an @ref action_t function type. Accorind the message request,
* it copies one of the declared data structure to the output payload.
*/
int
rt_buffer_getter
(
struct
trtl_proto_header
*
hin
,
void
*
pin
,
struct
trtl_proto_header
*
hout
,
void
*
pout
)
{
unsigned
int
offset
=
0
,
index
,
size
;
uint32_t
*
din
=
pin
;
uint32_t
*
dout
=
pout
;
if
(
!
HAS_MOCKTURTLE_FRAMEWORK_BUFFER_ENABLE
)
{
rt_send_nack
(
hin
,
pin
,
hout
,
NULL
);
return
0
;
}
hout
->
msg_id
=
TRTL_MSG_ID_BUF_GET_ANS
;
while
(
offset
<
hin
->
len
)
{
pr_debug
(
"%s: offset %d/%d
\n\r
"
,
__func__
,
offset
,
hin
->
len
);
index
=
din
[
offset
];
dout
[
offset
++
]
=
index
;
size
=
din
[
offset
];
dout
[
offset
++
]
=
size
;
pr_debug
(
"%s Type %d Len %d Addr 0x%p
\n\r
"
,
__func__
,
index
,
size
,
_app
->
buffers
[
index
].
buf
);
if
(
_app
->
buffers
[
index
].
len
==
size
)
{
memcpy
(
&
dout
[
offset
],
(
uint32_t
*
)
_app
->
buffers
[
index
].
buf
,
size
);
}
else
{
pr_error
(
"%s: structure %d len not correct %"
PRId32
" != %d
\n\r
"
,
__func__
,
index
,
_app
->
buffers
[
index
].
len
,
size
);
}
offset
+=
(
size
/
4
);
/* Next TLV record */
}
return
0
;
}
/**
* This is an @ref action_t function type. Accorind the message request,
* it writes a number of declared variables. If the message is synchronous
* it copies back the values in the output payload.
*/
int
rt_variable_setter
(
struct
trtl_proto_header
*
hin
,
void
*
pin
,
struct
trtl_proto_header
*
hout
,
void
*
pout
)
{
struct
rt_variable
*
var
;
uint32_t
*
din
=
pin
,
*
mem
,
val
;
int
i
;
if
(
!
HAS_MOCKTURTLE_FRAMEWORK_VARIABLE_ENABLE
)
{
pr_debug
(
"Variable set action not supported
\n\r
"
);
rt_send_nack
(
hin
,
pin
,
hout
,
NULL
);
return
0
;
}
/* we always have a pair of values */
if
(
hin
->
len
%
2
)
rt_send_nack
(
hin
,
pin
,
hout
,
pout
);
/* Write all values in the proper place */
for
(
i
=
0
;
i
<
hin
->
len
;
i
+=
2
)
{
if
(
din
[
i
]
>=
_app
->
n_variables
)
continue
;
var
=
&
_app
->
variables
[
din
[
i
]];
mem
=
(
uint32_t
*
)
var
->
addr
;
val
=
((
din
[
i
+
1
]
&
var
->
mask
)
<<
var
->
offset
);
if
(
var
->
flags
&
TRTL_RT_VARIABLE_FLAG_FLD
)
*
mem
=
(
*
mem
&
~
var
->
mask
)
|
val
;
else
*
mem
=
val
;
pr_debug
(
"%s index %"
PRIu32
"/%d | [0x%p] = 0x%08"
PRIx32
" <- 0x%08"
PRIx32
" (0x%08"
PRIx32
") | index in msg (%d/%d)
\n\r
"
,
__func__
,
din
[
i
],
_app
->
n_variables
-
1
,
mem
,
*
mem
,
val
,
din
[
i
+
1
],
i
+
1
,
hin
->
len
-
1
);
}
/* Return back new values. Host can compare with what it sent
to spot errors */
if
(
hin
->
flags
&
TRTL_HEAD_FLAG_SYNC
)
return
rt_variable_getter
(
hin
,
pin
,
hout
,
pout
);
return
0
;
}
/**
* This is an @ref action_t function type. Accorind the message request,
* it copies a number of declared variables.
*/
int
rt_variable_getter
(
struct
trtl_proto_header
*
hin
,
void
*
pin
,
struct
trtl_proto_header
*
hout
,
void
*
pout
)
{
struct
rt_variable
*
var
;
uint32_t
*
dout
=
pout
,
*
din
=
pin
,
*
mem
,
val
;
int
i
;
if
(
!
HAS_MOCKTURTLE_FRAMEWORK_VARIABLE_ENABLE
)
{
pr_debug
(
"Variable get action not supported
\n\r
"
);
rt_send_nack
(
hin
,
pin
,
hout
,
NULL
);
return
0
;
}
if
(
!
hout
||
!
pout
)
return
-
1
;
/* we always have a pair of values */
if
(
hin
->
len
%
2
)
return
-
1
;
hout
->
msg_id
=
TRTL_MSG_ID_VAR_GET_ANS
;
/* Write all values in the proper place */
for
(
i
=
0
;
i
<
hout
->
len
;
i
+=
2
)
{
if
(
din
[
i
]
>=
_app
->
n_variables
)
{
dout
[
i
]
=
~
0
;
/* Report invalid index */
continue
;
}
dout
[
i
]
=
din
[
i
];
var
=
&
_app
->
variables
[
dout
[
i
]];
mem
=
(
uint32_t
*
)
var
->
addr
;
val
=
(
*
mem
>>
var
->
offset
)
&
var
->
mask
;
dout
[
i
+
1
]
=
val
;
pr_debug
(
"%s index %"
PRIu32
"d/%d | [0x%p] = 0x%08"
PRIx32
" -> 0x%08"
PRIx32
" | index in msg (%d/%d)
\n\r
"
,
__func__
,
dout
[
i
],
_app
->
n_variables
-
1
,
mem
,
*
mem
,
dout
[
i
+
1
],
i
+
1
,
hin
->
len
-
1
);
}
return
0
;
}
/**
* List of standard actions
*/
static
action_t
*
trtl_actions_in
[]
=
{
rt_recv_ping
,
rt_version_getter
,
rt_variable_setter
,
rt_variable_getter
,
rt_buffer_setter
,
rt_buffer_getter
,
};
/**
* It runs the action associated with the given identifier
* @param[in] id action identifier
* @param[in] msg input message for the action
* @return 0 on success. A negative value on error
*/
static
inline
int
rt_action_run
(
struct
trtl_proto_header
*
hin
,
void
*
pin
)
{
action_t
*
action
;
struct
trtl_msg
out_buf
;
struct
trtl_proto_header
hout
;
void
*
pout
;
int
err
=
0
;
if
(
hin
->
msg_id
>=
__TRTL_MSG_ID_MAX
)
{
pr_error
(
"Invalid Message ID %d
\n\r
"
,
hin
->
msg_id
);
return
-
EINVAL
;
}
if
(
hin
->
msg_id
<
__TRTL_MSG_ID_MAX_USER
)
{
/* User Actions */
if
(
hin
->
msg_id
>=
_app
->
n_actions
||
!
_app
->
actions
[
hin
->
msg_id
])
{
pr_error
(
"Cannot dispatch (usr) msg_id 0x%x
\n\r
"
,
hin
->
msg_id
);
return
-
EINVAL
;
}
action
=
_app
->
actions
[
hin
->
msg_id
];
}
else
{
/* Mock Turtle Standard Actions */
if
(
ARRAY_SIZE
(
trtl_actions_in
)
<
hin
->
msg_id
-
__TRTL_MSG_ID_MAX_USER
)
{
pr_error
(
"Cannot dispatch msg_id 0x%x
\n\r
"
,
hin
->
msg_id
);
return
-
EINVAL
;
}
action
=
trtl_actions_in
[
hin
->
msg_id
-
__TRTL_MSG_ID_MAX_USER
];
}
pr_debug
(
"Message Input
\n\r
"
);
rt_print_header
(
hin
);
rt_print_data
(
pin
,
8
);
if
(
!
(
hin
->
flags
&
TRTL_HEAD_FLAG_SYNC
))
{
/* Asynchronous message, then no output */
return
action
(
hin
,
pin
,
NULL
,
NULL
);
}
/* Synchronous message */
out_buf
=
rt_mq_claim_out
(
hin
);
/* Do not write directly the header on the buffer because it does not
work for fields size different than 32bit */
pout
=
rt_proto_payload_get
((
void
*
)
out_buf
.
data
);
memcpy
((
uint32_t
*
)
&
hout
,
(
uint32_t
*
)
hin
,
sizeof
(
struct
trtl_proto_header
));
err
=
action
(
hin
,
pin
,
&
hout
,
pout
);
if
(
err
)
rt_send_nack
(
hin
,
pin
,
&
hout
,
NULL
);
rt_proto_header_set
((
void
*
)
out_buf
.
data
,
&
hout
);
rt_mq_msg_send
(
&
out_buf
);
pr_debug
(
"Message Output
\n\r
"
);
rt_print_header
(
&
hout
);
rt_print_data
(
pout
,
8
);
return
err
;
}
/**
* It dispatch messages coming from a given message queue.
* @param[in] mq_in MQ index within mq declaration in rt_application
* @todo provide support for remote queue
* @return 0 on success. -1 on error
*/
int
rt_mq_action_dispatch
(
unsigned
int
mq_in
)
{
struct
trtl_proto_header
*
header
;
unsigned
int
mq_in_slot
=
_app
->
mq
[
mq_in
].
index
;
uint32_t
*
msg
;
void
*
pin
;
int
err
=
0
;
/* HMQ control slot empty? */
if
(
_app
->
mq
[
mq_in
].
type
==
TRTL_HMQ
)
{
if
(
!
(
hmq_poll_in
()
&
(
1
<<
mq_in_slot
)))
return
-
EAGAIN
;
}
else
{
return
-
EAGAIN
;
/* Not used now */
}
/* Get the message from the HMQ */
msg
=
mq_map_in_buffer
(
0
,
mq_in_slot
);
pr_debug
(
"Incoming message
\n\r
"
);
rt_print_data
(
msg
,
8
);
header
=
rt_proto_header_get
((
void
*
)
msg
);
rt_print_header
(
header
);
if
(
header
->
rt_app_id
&&
header
->
rt_app_id
!=
_app
->
version
.
rt_id
)
{
pr_error
(
"Not for this application 0x%x
\n\r
"
,
header
->
rt_app_id
);
err
=
-
EINVAL
;
goto
out
;
}
if
(
!
(
header
->
flags
&
TRTL_HEAD_FLAG_RPC
))
{
pr_error
(
"%s: The message is not an RPC
\n
"
,
__func__
);
err
=
-
EINVAL
;
goto
out
;
}
pin
=
rt_proto_payload_get
((
void
*
)
msg
);
/* Run the correspondent action */
err
=
rt_action_run
(
header
,
pin
);
if
(
err
)
pr_error
(
"%s: action failure err: %d
\n\r
"
,
__func__
,
err
);
out:
mq_discard
(
0
,
mq_in_slot
);
return
err
;
}
software/rt/framework/mockturtle-frm-action.h
deleted
100644 → 0
View file @
c6c69f99
/**
* @defgroup framework-action Framework Action
* @{
* @ingroup framework
* @brief Action (RPC)
* @copyright (C) 2015-2016 CERN (www.cern.ch)
* @author Federico Vaga <federico.vaga@cern.ch>
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#ifndef __TRTL_FW_FRM_ACTION_H__
#define __TRTL_FW_FRM_ACTION_H__
/**
* Action prototype type
* @param[in] hin input message header
* @param[in] pin input message payload
* @param[out] hout output message header
* @param[out] pout output message payload
* @return 0 on success. -1 on error
*/
typedef
int
(
action_t
)(
struct
trtl_proto_header
*
hin
,
void
*
pin
,
struct
trtl_proto_header
*
hout
,
void
*
pout
);
/**
* This is an @ref action_t function type. It fills the output payload
* with an acknowledged message
*/
static
inline
void
rt_send_ack
(
struct
trtl_proto_header
*
hin
,
void
*
pin
,
struct
trtl_proto_header
*
hout
,
void
*
pout
)
{
hout
->
msg_id
=
TRTL_MSG_ID_ACK
;
hout
->
len
=
0
;
}
/**
* This is an @ref action_t function type. It fills the output payload
* with a not-acknowledged message
*/
static
inline
void
rt_send_nack
(
struct
trtl_proto_header
*
hin
,
void
*
pin
,
struct
trtl_proto_header
*
hout
,
void
*
pout
)
{
hout
->
msg_id
=
TRTL_MSG_ID_NACK
;
hout
->
len
=
0
;
}
extern
int
rt_recv_ping
(
struct
trtl_proto_header
*
hin
,
void
*
pin
,
struct
trtl_proto_header
*
hout
,
void
*
pout
);
extern
int
rt_version_getter
(
struct
trtl_proto_header
*
hin
,
void
*
pin
,
struct
trtl_proto_header
*
hout
,
void
*
pout
);
extern
int
rt_variable_setter
(
struct
trtl_proto_header
*
hin
,
void
*
pin
,
struct
trtl_proto_header
*
hout
,
void
*
pout
);
extern
int
rt_variable_getter
(
struct
trtl_proto_header
*
hin
,
void
*
pin
,
struct
trtl_proto_header
*
hout
,
void
*
pout
);
extern
int
rt_buffer_setter
(
struct
trtl_proto_header
*
hin
,
void
*
pin
,
struct
trtl_proto_header
*
hout
,
void
*
pout
);
extern
int
rt_buffer_getter
(
struct
trtl_proto_header
*
hin
,
void
*
pin
,
struct
trtl_proto_header
*
hout
,
void
*
pout
);
extern
int
rt_mq_action_dispatch
(
unsigned
int
mq_in
);
#endif
/**@}*/
software/rt/framework/mockturtle-frm-buffer.h
deleted
100644 → 0
View file @
c6c69f99
/**
* @defgroup framework-buffer Framework Buffer
* @{
* @ingroup framework
* @brief Buffer exchange mechanism
* @copyright (C) 2015-2016 CERN (www.cern.ch)
* @author Federico Vaga <federico.vaga@cern.ch>
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#ifndef __TRTL_FW_FRM_BUFFER_H__
#define __TRTL_FW_FRM_BUFFER_H__
/**
* Description of a buffer that we want to export to the external world
* (host or network)
*/
struct
rt_buffer
{
void
*
buf
;
/**< structure location */
uint32_t
len
;
/**< data structure lenght */
/* Maybe other option later in time */
};
#endif
/**@}*/
software/rt/framework/mockturtle-frm-common.h
deleted
100644 → 0
View file @
c6c69f99
/**
* @defgroup framework-common Framework Common Utilities
* @{
* @ingroup framework
* @brief Common Utilities
* @copyright (C) 2015-2016 CERN (www.cern.ch)
* @author Federico Vaga <federico.vaga@cern.ch>
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#ifndef __TRTL_FW_FRM_COMMON_H__
#define __TRTL_FW_FRM_COMMON_H__
#include "mockturtle-frm-action.h"
#include "mockturtle-frm-mqueue.h"
#include "mockturtle-frm-variable.h"
#include "mockturtle-frm-buffer.h"
#define RT_VERSION_MAJ(_v) ((_v >> 16) & 0xFFFF)
#define RT_VERSION_MIN(_v) (_v & 0xFFFF)
#define RT_VERSION(_a, _b) (((_a & 0xFFFF) << 16) | (_b & 0xFFFF))
/**
* Real-Time Application Descriptor
*/
struct
rt_application
{
const
char
name
[
16
];
/**< Firmware name*/
const
uint32_t
*
fpga_id_compat
;
/**< list of compatible FPGA
application ID */
const
unsigned
int
fpga_id_compat_n
;
/**< number of entry in
the fpga_id_compat list */
const
struct
trtl_rt_version
version
;
/**< version running */
struct
rt_mq
*
mq
;
/**< list of used MQ */
uint8_t
n_mq
;
/**< number of available MQ */
struct
rt_buffer
*
buffers
;
/**< exported buffers */
unsigned
int
n_buffers
;
/**< number or exported buffers */
struct
rt_variable
*
variables
;
/**< exported variables */
unsigned
int
n_variables
;
/**< number or exported variables */
action_t
**
actions
;
/**< list of custum actions */
unsigned
int
n_actions
;
/**< number of custum actions */
};
extern
struct
rt_application
*
_app
;
extern
int
rt_init
(
struct
rt_application
*
app
);
extern
void
rt_get_time
(
uint32_t
*
seconds
,
uint32_t
*
cycles
);
#endif
/**@}*/
software/rt/framework/mockturtle-frm-core.c
deleted
100644 → 0
View file @
c6c69f99
/**
* Copyright (C) 2015-2016 CERN (www.cern.ch)
* Author: Federico Vaga <federico.vaga@cern.ch>
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#include <stdint.h>
#include <errno.h>
#include <mockturtle-framework.h>
uint32_t
msg_seq
=
0
;
struct
rt_application
*
_app
;
/**
* It get the current time from the internal WRNC timer
* @param[out] seconds
* @param[out] cycles
*/
void
rt_get_time
(
uint32_t
*
seconds
,
uint32_t
*
cycles
)
{
*
seconds
=
lr_readl
(
MT_CPU_LR_REG_TAI_SEC
);
*
cycles
=
lr_readl
(
MT_CPU_LR_REG_TAI_CYCLES
);
}
/**
* It initilizes the declared MQs
* @param[in] app application declaration
* @return 0 on success. -1 on error
*/
static
inline
int
trtl_rt_init_mq
(
void
)
{
int
i
;
for
(
i
=
0
;
i
<
_app
->
n_mq
;
++
i
)
{
if
(
_app
->
mq
[
i
].
flags
&
TRTL_RT_MQ_FLAGS_OUTPUT
)
{
_app
->
mq
[
i
].
buf
=
mq_map_out_buffer
(
_app
->
mq
[
i
].
type
,
_app
->
mq
[
i
].
index
);
mq_purge
(
_app
->
mq
[
i
].
type
,
_app
->
mq
[
i
].
index
);
if
(
_app
->
mq
[
i
].
flags
&
TRTL_RT_MQ_FLAGS_CLAIM
)
{
mq_claim
(
_app
->
mq
[
i
].
type
,
_app
->
mq
[
i
].
index
);
}
}
else
{
_app
->
mq
[
i
].
buf
=
mq_map_in_buffer
(
_app
->
mq
[
i
].
type
,
_app
->
mq
[
i
].
index
);
}
}
return
0
;
}
/**
* The function initializes the library and it does some compatibility check.
*
* Initialization
* - purge all the output host-message-queue
*
* compatibility checks:
* - check bitstream FPGA ID if compatibile with the application. The value in
* app->version.fpga_id will be updated with the FPGA ID from the bitstream
*
* @param[in] app application declaration
* @return 0 on success. -1 on error
*/
int
rt_init
(
struct
rt_application
*
app
)
{
int
i
,
err
;
uint32_t
*
fpga_id
=
&
app
->
version
.
fpga_id
;
/* in order to overwrite the const */
_app
=
app
;
/* Validate actions */
for
(
i
=
0
;
i
<
_app
->
n_actions
;
++
i
)
{
if
(
i
>
__TRTL_MSG_ID_MAX_USER
)
{
pr_error
(
"Too many actions defined. Maximum '%d'
\n\r
"
,
__TRTL_MSG_ID_MAX_USER
);
return
-
1
;
}
if
(
_app
->
actions
[
i
]
==
NULL
)
{
pr_error
(
"Undefined action %d
\n\r
"
,
i
);
return
-
1
;
}
}
pr_debug
(
"Running application '%s'
\n\r
"
,
_app
->
name
);
/* *fpga_id = 0x1234; /\* TODO read it from the FPGA ID register *\/ */
for
(
i
=
0
;
i
<
app
->
fpga_id_compat_n
;
i
++
)
{
if
(
app
->
fpga_id_compat
[
i
]
==
*
fpga_id
)
break
;
}
if
(
app
->
fpga_id_compat_n
&&
app
->
fpga_id_compat_n
==
i
)
{
pr_error
(
"
\t
FPGA '0x%"
PRIx32
"' not compatible with RT app: 0x%"
PRIx32
" 0x%"
PRIx32
" (git %"
PRIx32
")
\n\r
"
,
_app
->
version
.
fpga_id
,
_app
->
version
.
rt_id
,
_app
->
version
.
rt_version
,
_app
->
version
.
git_version
);
return
-
1
;
}
pr_debug
(
"
\t
app id
\t
'0x%"
PRIx32
"'
\n\r
"
,
_app
->
version
.
rt_id
);
pr_debug
(
"
\t
app version
\t
'%"
PRId32
".%"
PRId32
"'
\n\r
"
,
RT_VERSION_MAJ
(
_app
->
version
.
rt_version
),
RT_VERSION_MIN
(
_app
->
version
.
rt_version
));
pr_debug
(
"
\t
source id
\t
'0x%"
PRIx32
"'
\n\r
"
,
_app
->
version
.
git_version
);
err
=
trtl_rt_init_mq
();
if
(
err
)
return
err
;
#ifdef LIBRT_DEBUG
pr_debug
(
"Exported Variables
\n\r
"
);
for
(
i
=
0
;
i
<
_app
->
n_variables
;
++
i
)
pr_debug
(
"[%d] addr %p | mask 0x%"
PRIx32
" | off %d
\n\r
"
,
i
,
_app
->
variables
[
i
].
addr
,
_app
->
variables
[
i
].
mask
,
_app
->
variables
[
i
].
offset
);
pr_debug
(
"Exported Buffers
\n\r
"
);
for
(
i
=
0
;
i
<
_app
->
n_buffers
;
++
i
)
pr_debug
(
"[%d] addr %p | len %"
PRId32
"
\n\r
"
,
i
,
_app
->
buffers
[
i
].
buf
,
_app
->
buffers
[
i
].
len
);
#endif
return
0
;
}
software/rt/framework/mockturtle-frm-debug.c
deleted
100644 → 0
View file @
c6c69f99
/**
* Copyright (C) 2016 CERN (www.cern.ch)
* Author: Federico Vaga <federico.vaga@cern.ch>
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#include <mockturtle-framework.h>
/**
* The function can be used to send debug information to the host
* trought the HMQ
* @param[in] mq_in MQ index within mq declaration in rt_application
* @param[in] n_values number of variadic arguments
* @return 0 on success. -1 on error
*/
int
rt_send_debug
(
int
mq_in
,
int
n_values
,
...)
{
va_list
ap
;
struct
trtl_msg
out_buf
;
uint32_t
*
buf
;
struct
trtl_proto_header
hdr
=
{
.
rt_app_id
=
_app
->
version
.
rt_id
,
.
msg_id
=
TRTL_MSG_ID_DBG
,
.
slot_io
=
_app
->
mq
[
mq_in
].
index
&
0xF
,
.
seq
=
0
,
.
len
=
n_values
,
.
flags
=
0x0
,
.
trans
=
0x0
,
.
time
=
0x0
,
};
int
i
;
if
(
!
HAS_MOCKTURTLE_FRAMEWORK_DEBUG_ENABLE
)
{
return
0
;
}
out_buf
=
rt_mq_claim_out
(
&
hdr
);
buf
=
(
uint32_t
*
)
rt_proto_payload_get
(
out_buf
.
data
);
va_start
(
ap
,
n_values
);
for
(
i
=
0
;
i
<
hdr
.
len
;
++
i
)
buf
[
i
]
=
va_arg
(
ap
,
uint32_t
);
va_end
(
ap
);
rt_proto_header_set
((
void
*
)
out_buf
.
data
,
&
hdr
);
rt_mq_msg_send
(
&
out_buf
);
return
0
;
}
/**
* It prints on the serial interface the given message header
* @param[in] h message header to print
*/
void
rt_print_header
(
struct
trtl_proto_header
*
h
)
{
if
(
!
HAS_MOCKTURTLE_FRAMEWORK_DEBUG_ENABLE
)
{
return
;
}
pr_debug
(
" app_id 0x%x | msg_id %d | slot_io 0x%x | seq %"
PRIu32
"d
\n\r
"
,
h
->
rt_app_id
,
h
->
msg_id
,
h
->
slot_io
,
h
->
seq
);
delay
(
1000
);
pr_debug
(
" len %d | flags 0x%x | trans 0x%x | time %"
PRIu32
"d
\n\r
"
,
h
->
len
,
h
->
flags
,
h
->
trans
,
h
->
time
);
delay
(
1000
);
}
/**
* It prints on the serial interface a buffer
* @param[in] d buffer data
* @param[in] count number of 32bit words to show
*/
void
rt_print_data
(
uint32_t
*
d
,
unsigned
int
count
)
{
int
i
;
if
(
!
HAS_MOCKTURTLE_FRAMEWORK_DEBUG_ENABLE
)
{
return
;
}
for
(
i
=
0
;
i
<
count
;
i
++
)
{
pr_debug
(
"%s: data[%d] = 0x%"
PRIx32
"
\n\r
"
,
__func__
,
i
,
d
[
i
]);
delay
(
1000
);
}
}
software/rt/framework/mockturtle-frm-debug.h
deleted
100644 → 0
View file @
c6c69f99
/**
* @defgroup framework-debug Framework Debug
* @{
* @ingroup framework
* @brief Debug functions
* @copyright (C) 2015-2016 CERN (www.cern.ch)
* @author Federico Vaga <federico.vaga@cern.ch>
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#ifndef __TRTL_FW_FRM_DEBUG_H__
#define __TRTL_FW_FRM_DEBUG_H__
#include <stdarg.h>
#include "mockturtle-common.h"
extern
int
rt_send_debug
(
int
slot
,
int
n_values
,
...);
extern
void
rt_print_header
(
struct
trtl_proto_header
*
h
);
extern
void
rt_print_data
(
uint32_t
*
d
,
unsigned
int
count
);
#endif
/**@}*/
software/rt/framework/mockturtle-frm-mqueue.c
deleted
100644 → 0
View file @
c6c69f99
/*
* Copyright (C) 2015-2016 CERN (www.cern.ch)
* Author: Federico Vaga <federico.vaga@cern.ch>
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#include <mockturtle-framework.h>
/**
* It sends the MQ content.
* In order to save space the function *does not* perform any
* argument validation. This means that you may crash the system
* if you provide the wrong mq_idx.
* @param[in] mq_idx MQ index within the declaration
* @param[in] count number of bytes to send
*/
void
trtl_rt_mq_send
(
unsigned
int
mq_idx
,
unsigned
int
count
)
{
mq_send
(
_app
->
mq
[
mq_idx
].
type
,
_app
->
mq
[
mq_idx
].
index
);
if
(
_app
->
mq
[
mq_idx
].
flags
&
TRTL_RT_MQ_FLAGS_CLAIM
)
{
mq_claim
(
_app
->
mq
[
mq_idx
].
type
,
_app
->
mq
[
mq_idx
].
index
);
}
}
/**
* It builds and it sends a message over MQ.
* The vargs will be copied into the payload message.
* Beware that, internally, it uses trtl_rt_mq_send().
* @param[in] mq_idx MQ index within the declaration
* @param[in] msg_id message identifier
* @param[in] n number of vargs
*/
void
trtl_rt_mq_send_uint32
(
unsigned
int
mq_idx
,
uint8_t
msg_id
,
unsigned
int
n
,
...)
{
struct
trtl_proto_header
hdr
=
{
.
rt_app_id
=
_app
->
version
.
rt_id
,
.
msg_id
=
msg_id
,
.
slot_io
=
_app
->
mq
[
mq_idx
].
index
&
0xF
,
.
seq
=
msg_seq
++
,
.
len
=
n
,
.
flags
=
0x0
,
.
trans
=
0x0
,
.
time
=
0x0
,
};
void
*
buf
=
_app
->
mq
[
mq_idx
].
buf
;
uint32_t
*
payload
=
rt_proto_payload_get
(
buf
);
va_list
ap
;
int
i
;
va_start
(
ap
,
n
);
for
(
i
=
0
;
i
<
hdr
.
len
;
++
i
)
payload
[
i
]
=
va_arg
(
ap
,
uint32_t
);
va_end
(
ap
);
rt_proto_header_set
(
buf
,
&
hdr
);
trtl_rt_mq_send
(
mq_idx
,
(
sizeof
(
struct
trtl_proto_header
)
/
4
)
+
hdr
.
len
);
}
/**
* It builds and it sends a message over MQ.
* The buffer will be copied into the payload message.
* Beware that, internally, it uses trtl_rt_mq_send().
* @param[in] mq_idx MQ index within the declaration
* @param[in] msg_id message identifier
* @param[in] n buffer size in bytes
* @param[in] data buffer to send
*/
void
trtl_rt_mq_send_buf
(
unsigned
int
mq_idx
,
uint8_t
msg_id
,
unsigned
int
n
,
void
*
data
)
{
struct
trtl_proto_header
hdr
=
{
.
rt_app_id
=
_app
->
version
.
rt_id
,
.
msg_id
=
msg_id
,
.
slot_io
=
_app
->
mq
[
mq_idx
].
index
&
0xF
,
.
seq
=
msg_seq
++
,
.
len
=
n
/
4
,
.
flags
=
0x0
,
.
trans
=
0x0
,
.
time
=
0x0
,
};
void
*
buf
=
_app
->
mq
[
mq_idx
].
buf
;
memcpy
(
rt_proto_payload_get
(
buf
),
data
,
n
);
rt_proto_header_set
(
buf
,
&
hdr
);
trtl_rt_mq_send
(
mq_idx
,
(
sizeof
(
struct
trtl_proto_header
)
/
4
)
+
hdr
.
len
);
}
software/rt/framework/mockturtle-frm-mqueue.h
deleted
100644 → 0
View file @
c6c69f99
/**
* @defgroup framework-mqueue Framework Message Queue
* @{
* @ingroup framework
* @brief Message Queues definitions and functions
* @copyright (C) 2015-2016 CERN (www.cern.ch)
* @author Federico Vaga <federico.vaga@cern.ch>
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#ifndef __TRTL_FW_FRM_MQUEUE_H__
#define __TRTL_FW_FRM_MQUEUE_H__
extern
uint32_t
msg_seq
;
/**
* Description of the message queue
*/
struct
rt_mq
{
enum
trtl_mq_type
type
;
/**< MQ type */
uint8_t
index
;
/**< MQ gateware index */
unsigned
long
flags
;
/**< MQ flag info */
void
*
buf
;
/**< MQ buffer */
};
/**
* MQ Flag. It is RMQ
*/
#define TRTL_RT_MQ_FLAGS_RMQ (1 << 0)
/**
* MQ Flag. It is HMQ
*/
#define TRTL_RT_MQ_FLAGS_HMQ (0)
/**
* MQ Flag. It is output
*/
#define TRTL_RT_MQ_FLAGS_OUTPUT (1 << 1)
/**
* MQ Flags. On output keep claimed.
* This means that as soon as you send a message on a slot,
* the framework will claim the slot immediately.
*/
#define TRTL_RT_MQ_FLAGS_CLAIM (1 << 2)
/**
* MQ Flag. It is input
*/
#define TRTL_RT_MQ_FLAGS_INPUT (0)
/**
* It send the message associate to the given header
* @param[in] msg message to send
*/
static
inline
void
rt_mq_msg_send
(
struct
trtl_msg
*
msg
)
{
struct
trtl_proto_header
*
hdr
;
hdr
=
rt_proto_header_get
((
void
*
)
msg
->
data
);
/* When we are not using sync messages, we use the global
sequence number */
if
(
!
(
hdr
->
flags
&
TRTL_HEAD_FLAG_SYNC
))
hdr
->
seq
=
msg_seq
++
;
mq_send
(
!!
(
hdr
->
flags
&
TRTL_HEAD_FLAG_REMOTE
),
(
hdr
->
slot_io
&
0xF
));
}
extern
void
trtl_rt_mq_send
(
unsigned
int
mq_idx
,
unsigned
int
count
);
extern
void
trtl_rt_mq_send_uint32
(
unsigned
int
mq_idx
,
uint8_t
msg_id
,
unsigned
int
n
,
...);
extern
void
trtl_rt_mq_send_buf
(
unsigned
int
mq_idx
,
uint8_t
msg_id
,
unsigned
int
n
,
void
*
data
);
#endif
/**@}*/
software/rt/framework/mockturtle-frm-variable.h
deleted
100644 → 0
View file @
c6c69f99
/**
* @defgroup framework-variable Framework Variable
* @{
* @ingroup framework
* @brief Variable exchange mechanism
* @copyright (C) 2015-2016 CERN (www.cern.ch)
* @author Federico Vaga <federico.vaga@cern.ch>
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#ifndef __TRTL_FW_FRM_VARIABLE_H__
#define __TRTL_FW_FRM_VARIABLE_H__
/**
* Variable flag. Register
*/
#define TRTL_RT_VARIABLE_FLAG_FLD (1 << 0)
/**
* Description of a variable that we want to export to the external
* world (host or network).
*/
struct
rt_variable
{
void
*
addr
;
/**< variable address */
uint32_t
mask
;
/**< variable mask without offset applied */
uint8_t
offset
;
/**< variable offset within the word */
uint32_t
flags
;
/**< variable options */
};
#endif
/**@}*/
software/rt/framework/mockturtle-rt-message.h
deleted
100644 → 0
View file @
c6c69f99
/*
* Message assembling helper functions
*
* Copyright (C) 2013-2016 CERN (www.cern.ch)
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* Author: Federico Vaga <federico.vaga@cern.ch>
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#ifndef __RT_MESSAGE_H
#define __RT_MESSAGE_H
#include <mockturtle-rt-common.h>
#ifdef MOCKTURTLE_RT
/**
* It claims an output slot. This means that you get exclusive access to
* the slot.
*/
static
inline
struct
trtl_msg
rt_mq_claim_out
(
struct
trtl_proto_header
*
h
)
{
struct
trtl_msg
b
;
int
remote
=
!!
(
h
->
flags
&
TRTL_HEAD_FLAG_REMOTE
);
int
slot
=
h
->
slot_io
&
0xF
;
mq_claim
(
remote
,
slot
);
b
.
data
=
mq_map_out_buffer
(
remote
,
slot
);
b
.
hdr
.
len
=
0
;
return
b
;
}
/**
* Obsolete. Use rt_mq_claim_out
*/
static
inline
struct
trtl_msg
hmq_msg_claim_out
(
int
slot
,
int
max_size
)
{
struct
trtl_proto_header
h
=
{
.
slot_io
=
(
slot
&
0xF
),
.
len
=
max_size
,
};
return
rt_mq_claim_out
(
&
h
);
}
/**
* It claims an input slot. This mean that you get exclusive access to
* the slot
*/
static
inline
struct
trtl_msg
rt_mq_claim_in
(
struct
trtl_proto_header
*
h
)
{
struct
trtl_msg
b
;
int
slot
=
(
h
->
slot_io
>>
4
)
&
0xF
;
b
.
data
=
mq_map_in_buffer
(
0
,
slot
);
b
.
hdr
.
len
=
h
->
len
;
return
b
;
}
/**
* Obsolete. Use rt_mq_claim_in
*/
static
inline
struct
trtl_msg
hmq_msg_claim_in
(
int
slot
,
int
max_size
)
{
struct
trtl_proto_header
h
=
{
.
slot_io
=
(
slot
&
0xF
)
<<
4
,
.
len
=
max_size
,
};
return
rt_mq_claim_in
(
&
h
);
}
#endif
#endif
software/rt/lib/mockturtle-rt-common.c
View file @
475bc35d
...
@@ -10,7 +10,7 @@
...
@@ -10,7 +10,7 @@
#include <stdint.h>
#include <stdint.h>
#include <string.h>
#include <string.h>
#include "mockturtle-rt
-common
.h"
#include "mockturtle-rt.h"
int
putchar
(
int
c
)
int
putchar
(
int
c
)
{
{
...
...
software/rt/lib/mockturtle-rt-common.h
deleted
100644 → 0
View file @
c6c69f99
/**
* @defgroup library-utilities Common Utilities
* @{
* @ingroup library
* @brief Common utilities
* @copyright (C) 2013-2016 CERN (www.cern.ch)
* @author Federico Vaga <federico.vaga@cern.ch>
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#ifndef __TRTL_RT_COMMON_H
#define __TRTL_RT_COMMON_H
#include <stdint.h>
#include <stdio.h>
#include <hw/mockturtle_addresses.h>
#include "hw/mockturtle_cpu_lr.h"
#include <mockturtle-common.h>
#include "mockturtle-rt-serial.h"
struct
trtl_msg
{
struct
trtl_hmq_header
hdr
;
uint32_t
*
data
;
};
/**
* Read a 32bit word value from the given address
* @param[in] addr source address
* @return the value fromt the register
*/
static
inline
uint32_t
readl
(
void
*
addr
)
{
return
*
(
volatile
uint32_t
*
)
(
addr
);
}
/**
* Write a 32bit word value to the given address
* @param[in] value value to write
* @param[in] addr destination address
*/
static
inline
void
writel
(
uint32_t
value
,
void
*
addr
)
{
*
(
volatile
uint32_t
*
)
(
addr
)
=
value
;
}
/**
* Read a 32bit word value from the Dedicated Peripheral address space
* @param[in] reg register offset within the Dedicated Peripheral
* @return the value fromt the register
*/
static
inline
uint32_t
dp_readl
(
uint32_t
reg
)
{
return
readl
(
TRTL_ADDR_DP
(
reg
));
}
/**
* Write a 32bit word value to the Dedicated Peripheral address space
* @param[in] value value to write
* @param[in] reg register offset within the Dedicated Peripheral
*/
static
inline
void
dp_writel
(
uint32_t
value
,
uint32_t
reg
)
{
writel
(
value
,
TRTL_ADDR_DP
(
reg
));
}
/**
* Read 32bit word value from the CPU Local Registers address space
* @param[in] reg register offset within the Local Registers
* @return the value fromt the register
*/
static
inline
uint32_t
lr_readl
(
uint32_t
reg
)
{
return
readl
(
TRTL_ADDR_LR
(
reg
));
}
/**
* Write 32bit word value to the CPU Local Registers address space
* @param[in] value value to write
* @param[in] reg register offset within the Local Registers
*/
static
inline
void
lr_writel
(
uint32_t
value
,
uint32_t
reg
)
{
writel
(
value
,
TRTL_ADDR_LR
(
reg
));
}
/**
* Set a bit in the CPU GPIO Register
* @param[in] pin GPIO pin to set
*/
static
inline
void
gpio_set
(
int
pin
)
{
lr_writel
((
1
<<
pin
),
MT_CPU_LR_REG_GPIO_SET
);
}
/**
* Clear a bit in the CPU GPIO Register
* @param[in] pin GPIO pin to clear
*/
static
inline
void
gpio_clear
(
int
pin
)
{
lr_writel
((
1
<<
pin
),
MT_CPU_LR_REG_GPIO_CLEAR
);
}
/**
* Wait n cycles
* @todo: use Timing Unit, compute it accoring to CPU frequency
* @param[in] n number of cycles to wait
*/
static
inline
void
delay
(
int
n
)
{
int
i
;
for
(
i
=
0
;
i
<
n
;
i
++
)
asm
volatile
(
"nop"
);
}
/**
* It returns a pointer to the config ROM
*/
static
inline
const
struct
trtl_config_rom
*
trtl_config_rom_get
(
void
)
{
return
(
const
struct
trtl_config_rom
*
)(
TRTL_ADDR_CONFIG_ROM_BASE
);
}
/**
* It generates a notification signal (IRQ) to ask the HOST CPU
* to take some action.
*/
static
inline
void
trtl_notify_send
(
enum
trtl_cpu_notification
id
)
{
lr_writel
(
1
,
MT_CPU_LR_REG_NTF_INT
);
}
#endif
/**@}*/
software/rt/lib/mockturtle-rt-mqueue.h
deleted
100644 → 0
View file @
c6c69f99
/**
* @defgroup library-message-queue Message Queue
* @{
* @ingroup library
* @brief Message Queues definitions and functions
* @copyright (C) 2013-2016 CERN (www.cern.ch)
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* @author Federico Vaga <federico.vaga@cern.ch>
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#ifndef __TRTL_RT_MQUEUE_H
#define __TRTL_RT_MQUEUE_H
#include <hw/mockturtle_addresses.h>
#include <hw/mockturtle_queue.h>
#include <hw/mockturtle_cpu_lr.h>
#define TRTL_MQ_SLOT_IN(slot) (TRTL_MQ_BASE_IN + ((slot) << 16))
// Outgoung slot base address, relative to BASE_HMQ
#define TRTL_MQ_SLOT_OUT(slot) (TRTL_MQ_BASE_OUT + ((slot) << 16))
/**
* List of Message Queue types
*/
enum
trtl_mq_type
{
TRTL_HMQ
=
0
,
/**< Host Message Queue - Host-Firmware communication */
TRTL_RMQ
,
/**< Remote Message Queue - Network-Firmware communication */
};
/**
* It gets the Message Queue base address
* @param[in] type MQ type
*/
static
inline
void
*
trtl_mq_base_address
(
enum
trtl_mq_type
type
)
{
return
(
void
*
)(
type
==
TRTL_HMQ
?
TRTL_ADDR_HMQ_BASE
:
TRTL_ADDR_RMQ_BASE
);
}
/**
* It writes on a Message Queue register
* @param[in] type MQ type to use
* @param[val] value to write
* @param[reg] reg register offset
*/
static
inline
void
mq_writel
(
enum
trtl_mq_type
type
,
uint32_t
val
,
uint32_t
reg
)
{
*
(
volatile
uint32_t
*
)(
trtl_mq_base_address
(
type
)
+
reg
)
=
val
;
}
/**
* @copydoc TRTL_MQ_CMD_CLAIM
* @param[in] type MQ type to use
* @param[in] slot slot number
*/
static
inline
void
mq_claim
(
enum
trtl_mq_type
type
,
int
slot
)
{
mq_writel
(
type
,
TRTL_MQ_CMD_CLAIM
,
TRTL_MQ_SLOT_OUT
(
slot
)
+
TRTL_MQ_SLOT_COMMAND
);
}
/**
* @copydoc TRTL_MQ_CMD_PURGE
* @param[in] type MQ type to use
* @param[in] slot slot number
*/
static
inline
void
mq_purge
(
enum
trtl_mq_type
type
,
int
slot
)
{
mq_writel
(
type
,
TRTL_MQ_CMD_PURGE
,
TRTL_MQ_SLOT_OUT
(
slot
)
+
TRTL_MQ_SLOT_COMMAND
);
mq_writel
(
type
,
TRTL_MQ_CMD_PURGE
,
TRTL_MQ_SLOT_IN
(
slot
)
+
TRTL_MQ_SLOT_COMMAND
);
}
/**
* @copydoc TRTL_MQ_CMD_READY
* @param[in] type MQ type to use
* @param[in] slot slot number
*/
static
inline
void
mq_send
(
enum
trtl_mq_type
type
,
int
slot
)
{
mq_writel
(
type
,
TRTL_MQ_CMD_READY
,
TRTL_MQ_SLOT_OUT
(
slot
)
+
TRTL_MQ_SLOT_COMMAND
);
}
/**
* @copydoc TRTL_MQ_CMD_DISCARD
* @param[in] type MQ type to use
* @param[in] slot slot number
*/
static
inline
void
mq_discard
(
enum
trtl_mq_type
type
,
int
slot
)
{
mq_writel
(
type
,
TRTL_MQ_CMD_DISCARD
,
TRTL_MQ_SLOT_IN
(
slot
));
}
/**
* It gets the output slot data field pointer
* @param[in] type MQ type to use
* @param[in] slot slot number
*/
static
inline
void
*
mq_map_out_buffer
(
enum
trtl_mq_type
type
,
int
slot
)
{
return
(
void
*
)
(
trtl_mq_base_address
(
type
)
+
TRTL_MQ_SLOT_OUT
(
slot
)
+
TRTL_MQ_SLOT_DATA_START
);
}
/**
* It gets the input slot data field pointer
* @param[in] type MQ type to use
* @param[in] slot slot number
*/
static
inline
void
*
mq_map_in_buffer
(
enum
trtl_mq_type
type
,
int
slot
)
{
return
(
void
*
)
(
trtl_mq_base_address
(
type
)
+
TRTL_MQ_SLOT_IN
(
slot
)
+
TRTL_MQ_SLOT_DATA_START
);
}
/**
* It gets the output slot header field pointer
* @param[in] type MQ type to use
* @param[in] slot slot number
*/
static
inline
void
*
mq_map_out_header
(
enum
trtl_mq_type
type
,
int
slot
)
{
return
(
void
*
)
(
trtl_mq_base_address
(
type
)
+
TRTL_MQ_SLOT_OUT
(
slot
)
+
TRTL_MQ_SLOT_HEADER_START
);
}
/**
* It gets the input slot header field pointer
* @param[in] type MQ type to use
* @param[in] slot slot number
*/
static
inline
void
*
mq_map_in_header
(
enum
trtl_mq_type
type
,
int
slot
)
{
return
(
void
*
)
(
trtl_mq_base_address
(
type
)
+
TRTL_MQ_SLOT_IN
(
slot
)
+
TRTL_MQ_SLOT_HEADER_START
);
}
/**
* It gets the current status of the input Host Message Queues
*/
static
inline
uint32_t
hmq_poll_in
(
void
)
{
volatile
uint32_t
*
poll
=
(
void
*
)
TRTL_ADDR_LR_BASE
+
MT_CPU_LR_REG_HMQ_STAT
;
return
((
*
poll
&
MT_CPU_LR_HMQ_STAT_IN_MASK
)
>>
MT_CPU_LR_HMQ_STAT_IN_SHIFT
);
}
/**
* It gets the current status of the output Host Message Queues
*/
static
inline
uint32_t
hmq_poll_out
(
void
)
{
volatile
uint32_t
*
poll
=
(
void
*
)
TRTL_ADDR_LR_BASE
+
MT_CPU_LR_REG_HMQ_STAT
;
return
((
*
poll
&
MT_CPU_LR_HMQ_STAT_OUT_MASK
)
>>
MT_CPU_LR_HMQ_STAT_OUT_SHIFT
);
}
/**
* It gets the current status of the input Remote Message Queues
*/
static
inline
uint32_t
rmq_poll_in
(
void
)
{
volatile
uint32_t
*
poll
=
(
void
*
)
TRTL_ADDR_LR_BASE
+
MT_CPU_LR_REG_RMQ_STAT
;
return
((
*
poll
&
MT_CPU_LR_RMQ_STAT_IN_MASK
)
>>
MT_CPU_LR_RMQ_STAT_IN_SHIFT
);
}
/**
* It gets the current status of the output Remote Message Queues
*/
static
inline
uint32_t
rmq_poll_out
(
void
)
{
volatile
uint32_t
*
poll
=
(
void
*
)
TRTL_ADDR_LR_BASE
+
MT_CPU_LR_REG_RMQ_STAT
;
return
((
*
poll
&
MT_CPU_LR_RMQ_STAT_OUT_MASK
)
>>
MT_CPU_LR_RMQ_STAT_OUT_SHIFT
);
}
#endif
/**@}*/
software/rt/lib/mockturtle-rt-serial.h
deleted
100644 → 0
View file @
c6c69f99
/**
* @defgroup library-serial Serial Console
* @{
* @ingroup library
* @brief Serial Console functions
* @copyright (C) 2013-2016 CERN (www.cern.ch)
* @author Alessandro Rubini <rubini@gnudd.com>
* @author Federico Vaga <federico.vaga@cern.ch>
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#ifndef __TRTL_RT_PP_PRINTF_H
#define __TRTL_RT_PP_PRINTF_H
#include <stdarg.h>
#include <generated/autoconf.h>
/**
* Print buffer size. This means that your printf string
* should not exceed this value. If the string exceed this value
* then it will be trouncated.
*/
#define CONFIG_PRINT_BUFSIZE 128
/**
* It prints a string on the serial interface.
* Internally, it uses the puts() function.
* @param[in] fmt string format
* @param[in] ... argument according to the string format
* @return number of printed characters
*/
#if HAS_MOCKTURTLE_LIBRARY_PRINT_ENABLE == 1
extern
int
pp_printf
(
const
char
*
fmt
,
...)
__attribute__
((
format
(
printf
,
1
,
2
)));
#else
static
inline
int
pp_printf
(
const
char
*
fmt
,
...)
{
return
0
;
}
#endif
/**
* It creates a new string according to the given format
* @param[out] s output string
* @param[in] fmt string format
* @param[in] ... argument according to the string format
* @return number of printed characters
*/
#if HAS_MOCKTURTLE_LIBRARY_PRINT_ENABLE == 1
extern
int
pp_sprintf
(
char
*
s
,
const
char
*
fmt
,
...)
__attribute__
((
format
(
printf
,
2
,
3
)));
#else
static
inline
int
pp_sprintf
(
char
*
s
,
const
char
*
fmt
,
...)
{
return
0
;
}
#endif
/**
* It prints a string on the serial interface.
* Internally, it uses the puts() function.
* @param[in] fmt string format
* @param[in] args list of arguments according to the string format
* @return number of printed characters
*/
#if HAS_MOCKTURTLE_LIBRARY_PRINT_ENABLE
extern
int
pp_vprintf
(
const
char
*
fmt
,
va_list
args
);
#else
static
inline
int
pp_vprintf
(
const
char
*
fmt
,
va_list
args
)
{
return
0
;
}
#endif
/**
* It creates a new string according to the given format
* @param[out] buf output string
* @param[in] fmt string format
* @param[in] args list of arguments according to the string format
* @return number of printed characters
*/
#if HAS_MOCKTURTLE_LIBRARY_PRINT_ENABLE == 1
extern
int
pp_vsprintf
(
char
*
buf
,
const
char
*
,
va_list
args
)
__attribute__
((
format
(
printf
,
2
,
0
)));
#else
static
inline
int
pp_vsprintf
(
char
*
buf
,
const
char
*
fmt
,
va_list
args
)
{
return
0
;
}
#endif
/**
* It prints a string on the serial interface only when the support
* for error messages is enable.
*
* Kconfig ->CONFIG_MOCKTURTLE_LIBRARY_PRINT_DEBUG_ENABLE
*
* Internally, it uses the puts() function.
* @param[in] fmt string format
* @param[in] ... argument according to the string format
* @return number of printed characters
*/
#if (HAS_MOCKTURTLE_LIBRARY_PRINT_ENABLE == 1) && (HAS_MOCKTURTLE_LIBRARY_PRINT_DEBUG_ENABLE == 1)
extern
int
pr_debug
(
const
char
*
fmt
,
...)
__attribute__
((
format
(
printf
,
1
,
2
)));
#else
static
inline
int
pr_debug
(
const
char
*
fmt
,
...)
{
return
0
;
}
#endif
/**
* It prints a string on the serial interface only when the support
* for error messages is enable.
*
* Kconfig -> CONFIG_MOCKTURTLE_LIBRARY_PRINT_ERROR_ENABLE
*
* Internally, it uses the puts() function.
* @param[in] fmt string format
* @param[in] ... argument according to the string format
* @return number of printed characters
*/
#if (HAS_MOCKTURTLE_LIBRARY_PRINT_ENABLE == 1) && (HAS_MOCKTURTLE_LIBRARY_PRINT_ERROR_ENABLE == 1)
extern
int
pr_error
(
const
char
*
fmt
,
...)
__attribute__
((
format
(
printf
,
1
,
2
)));
#else
static
inline
int
pr_error
(
const
char
*
fmt
,
...)
{
return
0
;
}
#endif
extern
int
putchar
(
int
c
);
extern
int
puts
(
const
char
*
p
);
/**@}*/
#endif
software/rt/lib/mockturtle-rt-smem.h
deleted
100644 → 0
View file @
c6c69f99
/**
* @defgroup library-shared-memory Shared Memory Utilities
* @{
* @ingroup library
* @brief Shared Memory definitions & API
* @copyright (C) 2013-2016 CERN (www.cern.ch)
* @author Federico Vaga <federico.vaga@cern.ch>
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#ifndef __TRTL_RT_SMEM_H
#define __TRTL_RT_SMEM_H
/**
* List of supported Shared Memory access type
*/
enum
trtl_smem_type
{
TRTL_SMEM_TYPE_BASE
=
0
,
/**< no operation */
TRTL_SMEM_TYPE_ADD
,
/**< atomic addition */
TRTL_SMEM_TYPE_SUB
,
/**< atomic subtraction */
TRTL_SMEM_TYPE_SET
,
/**< atomic bit set */
TRTL_SMEM_TYPE_CLR
,
/**< atomic bit clear */
TRTL_SMEM_TYPE_FLP
,
/**< atomic bit flip */
TRTL_SMEM_TYPE_TST_SET
,
/**< atomic test and set */
};
/**
* Shared Memory Size
*/
#define TRTL_SMEM_SIZE 0x10000
/**
* Shared Memory address for the
* @copydoc TRTL_SMEM_TYPE_BASE
* memory access
*/
#define TRTL_SMEM_RANGE_BASE 0x00000
/**
* It generates the SHM address range for a given SHM type
*/
#define TRTL_SMEM_TYPE_TO_RANGE(_type) \
(TRTL_SMEM_RANGE_BASE + (_type) * TRTL_SMEM_SIZE)
/**
* Shared Memory base address for the
* @copydoc TRTL_SMEM_TYPE_ADD
* memory access
*/
#define TRTL_SMEM_RANGE_ADD \
TRTL_SMEM_TYPE_TO_RANGE(TRTL_SMEM_TYPE_ADD)
/**
* Shared Memory base address for the
* @copydoc TRTL_SMEM_TYPE_SUB
* memory access
*/
#define TRTL_SMEM_RANGE_SUB \
TRTL_SMEM_TYPE_TO_RANGE(TRTL_SMEM_TYPE_SUB)
/**
* Shared Memory address for the
* @copydoc TRTL_SMEM_TYPE_SET
* memory access
*/
#define TRTL_SMEM_RANGE_SET \
TRTL_SMEM_TYPE_TO_RANGE(TRTL_SMEM_TYPE_SET)
/**
* Shared Memory address for the
* @copydoc TRTL_SMEM_TYPE_CLR
* memory access
*/
#define TRTL_SMEM_RANGE_CLEAR \
TRTL_SMEM_TYPE_TO_RANGE(TRTL_SMEM_TYPE_CLR)
/**
* Shared Memory address for the
* @copydoc TRTL_SMEM_TYPE_FLP
* memory access
*/
#define TRTL_SMEM_RANGE_FLIP \
TRTL_SMEM_TYPE_TO_RANGE(TRTL_SMEM_TYPE_FLP)
/**
* Shared Memory address for the
* @copydoc TRTL_SMEM_TYPE_TST_SET
* memory access
*/
#define TRTL_SMEM_RANGE_TEST_AND_SET \
TRTL_SMEM_TYPE_TO_RANGE(TRTL_SMEM_TYPE_TST_SET)
/**
* Compiler attribute to allocate variable on the Share Memory.
* Add this to the variable declaration to put it on the Shared Memory.
*
* SMEM int x;
*/
#define SMEM volatile __attribute__((section(".smem")))
/**
* It performs an operations on the shared memory. What the function
* performs can be summerized as:
*
* (*p) = (*p) <operation-type> x
*
* Use this function only when the operation type that you want to use
* is not supported yet by the library directly. Otherwise,
* use the other functions.
*
* @param[in] p address on the shared memory of the first operator and store location
* @param[in] x second operation argument
* @param[in] type operation type
*/
static
inline
void
__smem_atomic_op
(
volatile
int
*
p
,
int
x
,
enum
trtl_smem_type
type
)
{
*
(
volatile
int
*
)(
p
+
(
TRTL_SMEM_TYPE_TO_RANGE
(
type
)
>>
2
))
=
x
;
}
/**
* It performs an
* @copydoc TRTL_SMEM_TYPE_ADD
*
* (*p) = (*p) + x
*
* @param[in] p address on the shared memory of the first operator and store location
* @param[in] x second operation argument
*/
static
inline
void
smem_atomic_add
(
volatile
int
*
p
,
int
x
)
{
__smem_atomic_op
(
p
,
x
,
TRTL_SMEM_TYPE_ADD
);
}
/**
* It performs an
* @copydoc TRTL_SMEM_TYPE_SUB
*
* (*p) = (*p) - x
*
* @param[in] p address on the shared memory of the first operator and store location
* @param[in] x second operation argument
*/
static
inline
void
smem_atomic_sub
(
volatile
int
*
p
,
int
x
)
{
__smem_atomic_op
(
p
,
x
,
TRTL_SMEM_TYPE_SUB
);
}
/**
* It performs an
* @copydoc TRTL_SMEM_TYPE_SET
*
* (*p) = (*p) | x
*
* @param[in] p address on the shared memory of the first operator and store location
* @param[in] x second operation argument
*/
static
inline
void
smem_atomic_or
(
volatile
int
*
p
,
int
x
)
{
__smem_atomic_op
(
p
,
x
,
TRTL_SMEM_TYPE_SET
);
}
/**
* It performs an
* @copydoc TRTL_SMEM_TYPE_CLR
*
* (*p) = (*p) & (~x)
*
* @param[in] p address on the shared memory of the first operator and store location
* @param[in] x second operation argument
*/
static
inline
void
smem_atomic_and_not
(
volatile
int
*
p
,
int
x
)
{
__smem_atomic_op
(
p
,
x
,
TRTL_SMEM_TYPE_CLR
);
}
/**
* It performs an
* @copydoc TRTL_SMEM_TYPE_FLP
*
* (*p) = (*p) ^ x
*
* @param[in] p address on the shared memory of the first operator and store location
* @param[in] x second operation argument
*/
static
inline
void
smem_atomic_xor
(
int
*
p
,
int
x
)
{
__smem_atomic_op
(
p
,
x
,
TRTL_SMEM_TYPE_FLP
);
}
/**
* It performs an:
* @copydoc TRTL_SMEM_TYPE_TST_SET
*
* val = (*p);
* if (val == 0) {
* (*p) = 1;
* }
* return val;
*
* This is useful to implement mutex
*
* @param[in] p address on the shared memory
* @return the value before the set
*/
static
inline
int
smem_atomic_test_and_set
(
int
*
p
)
{
/* shift right translates range in bytes into range in words */
return
*
(
volatile
int
*
)(
p
+
(
TRTL_SMEM_TYPE_TST_SET
>>
2
));
}
#endif
/**@}*/
software/rt/lib/mockturtle-rt.h
View file @
475bc35d
...
@@ -12,12 +12,674 @@
...
@@ -12,12 +12,674 @@
#define __MOCKTURTLE_RT_H
#define __MOCKTURTLE_RT_H
#include <stdint.h>
#include <stdint.h>
#include <stdarg.h>
#include <generated/autoconf.h>
#include "mockturtle-rt-mqueue.h"
#include <hw/mockturtle_addresses.h>
#include "mockturtle-rt-message.h"
#include <hw/mockturtle_queue.h>
#include "mockturtle-rt-common.h"
#include <hw/mockturtle_cpu_lr.h>
#include "mockturtle-rt-smem.h"
#include "mockturtle-rt-serial.h"
#include <mockturtle.h>
/**
* Print buffer size. This means that your printf string
* should not exceed this value. If the string exceed this value
* then it will be trouncated.
*/
#define CONFIG_PRINT_BUFSIZE 128
/**
* It prints a string on the serial interface.
* Internally, it uses the puts() function.
* @param[in] fmt string format
* @param[in] ... argument according to the string format
* @return number of printed characters
*/
#if HAS_MOCKTURTLE_LIBRARY_PRINT_ENABLE == 1
extern
int
pp_printf
(
const
char
*
fmt
,
...)
__attribute__
((
format
(
printf
,
1
,
2
)));
#else
static
inline
int
pp_printf
(
const
char
*
fmt
,
...)
{
return
0
;
}
#endif
/**
* It creates a new string according to the given format
* @param[out] s output string
* @param[in] fmt string format
* @param[in] ... argument according to the string format
* @return number of printed characters
*/
#if HAS_MOCKTURTLE_LIBRARY_PRINT_ENABLE == 1
extern
int
pp_sprintf
(
char
*
s
,
const
char
*
fmt
,
...)
__attribute__
((
format
(
printf
,
2
,
3
)));
#else
static
inline
int
pp_sprintf
(
char
*
s
,
const
char
*
fmt
,
...)
{
return
0
;
}
#endif
/**
* It prints a string on the serial interface.
* Internally, it uses the puts() function.
* @param[in] fmt string format
* @param[in] args list of arguments according to the string format
* @return number of printed characters
*/
#if HAS_MOCKTURTLE_LIBRARY_PRINT_ENABLE
extern
int
pp_vprintf
(
const
char
*
fmt
,
va_list
args
);
#else
static
inline
int
pp_vprintf
(
const
char
*
fmt
,
va_list
args
)
{
return
0
;
}
#endif
/**
* It creates a new string according to the given format
* @param[out] buf output string
* @param[in] fmt string format
* @param[in] args list of arguments according to the string format
* @return number of printed characters
*/
#if HAS_MOCKTURTLE_LIBRARY_PRINT_ENABLE == 1
extern
int
pp_vsprintf
(
char
*
buf
,
const
char
*
,
va_list
args
)
__attribute__
((
format
(
printf
,
2
,
0
)));
#else
static
inline
int
pp_vsprintf
(
char
*
buf
,
const
char
*
fmt
,
va_list
args
)
{
return
0
;
}
#endif
/**
* It prints a string on the serial interface only when the support
* for error messages is enable.
*
* Kconfig ->CONFIG_MOCKTURTLE_LIBRARY_PRINT_DEBUG_ENABLE
*
* Internally, it uses the puts() function.
* @param[in] fmt string format
* @param[in] ... argument according to the string format
* @return number of printed characters
*/
#if (HAS_MOCKTURTLE_LIBRARY_PRINT_ENABLE == 1) && (HAS_MOCKTURTLE_LIBRARY_PRINT_DEBUG_ENABLE == 1)
extern
int
pr_debug
(
const
char
*
fmt
,
...)
__attribute__
((
format
(
printf
,
1
,
2
)));
#else
static
inline
int
pr_debug
(
const
char
*
fmt
,
...)
{
return
0
;
}
#endif
/**
* It prints a string on the serial interface only when the support
* for error messages is enable.
*
* Kconfig -> CONFIG_MOCKTURTLE_LIBRARY_PRINT_ERROR_ENABLE
*
* Internally, it uses the puts() function.
* @param[in] fmt string format
* @param[in] ... argument according to the string format
* @return number of printed characters
*/
#if (HAS_MOCKTURTLE_LIBRARY_PRINT_ENABLE == 1) && (HAS_MOCKTURTLE_LIBRARY_PRINT_ERROR_ENABLE == 1)
extern
int
pr_error
(
const
char
*
fmt
,
...)
__attribute__
((
format
(
printf
,
1
,
2
)));
#else
static
inline
int
pr_error
(
const
char
*
fmt
,
...)
{
return
0
;
}
#endif
extern
int
putchar
(
int
c
);
extern
int
puts
(
const
char
*
p
);
/**
* Read a 32bit word value from the given address
* @param[in] addr source address
* @return the value fromt the register
*/
static
inline
uint32_t
readl
(
void
*
addr
)
{
return
*
(
volatile
uint32_t
*
)
(
addr
);
}
/**
* Write a 32bit word value to the given address
* @param[in] value value to write
* @param[in] addr destination address
*/
static
inline
void
writel
(
uint32_t
value
,
void
*
addr
)
{
*
(
volatile
uint32_t
*
)
(
addr
)
=
value
;
}
/**
* Read a 32bit word value from the Dedicated Peripheral address space
* @param[in] reg register offset within the Dedicated Peripheral
* @return the value fromt the register
*/
static
inline
uint32_t
dp_readl
(
uint32_t
reg
)
{
return
readl
(
TRTL_ADDR_DP
(
reg
));
}
/**
* Write a 32bit word value to the Dedicated Peripheral address space
* @param[in] value value to write
* @param[in] reg register offset within the Dedicated Peripheral
*/
static
inline
void
dp_writel
(
uint32_t
value
,
uint32_t
reg
)
{
writel
(
value
,
TRTL_ADDR_DP
(
reg
));
}
/**
* Read 32bit word value from the CPU Local Registers address space
* @param[in] reg register offset within the Local Registers
* @return the value fromt the register
*/
static
inline
uint32_t
lr_readl
(
uint32_t
reg
)
{
return
readl
(
TRTL_ADDR_LR
(
reg
));
}
/**
* Write 32bit word value to the CPU Local Registers address space
* @param[in] value value to write
* @param[in] reg register offset within the Local Registers
*/
static
inline
void
lr_writel
(
uint32_t
value
,
uint32_t
reg
)
{
writel
(
value
,
TRTL_ADDR_LR
(
reg
));
}
/**
* Set a bit in the CPU GPIO Register
* @param[in] pin GPIO pin to set
*/
static
inline
void
gpio_set
(
int
pin
)
{
lr_writel
((
1
<<
pin
),
MT_CPU_LR_REG_GPIO_SET
);
}
/**
* Clear a bit in the CPU GPIO Register
* @param[in] pin GPIO pin to clear
*/
static
inline
void
gpio_clear
(
int
pin
)
{
lr_writel
((
1
<<
pin
),
MT_CPU_LR_REG_GPIO_CLEAR
);
}
/**
* It gets the GPIO status
* @param[in] pin GPIO pin to query
* @return the GPIO status
*/
static
inline
unsigned
int
gpio_status
(
int
pin
)
{
return
!!
(
lr_readl
(
MT_CPU_LR_REG_GPIO_IN
)
&
(
1
<<
pin
));
}
/**
* Wait n cycles
* @todo: use Timing Unit, compute it accoring to CPU frequency
* @param[in] n number of cycles to wait
*/
static
inline
void
delay
(
int
n
)
{
int
i
;
for
(
i
=
0
;
i
<
n
;
i
++
)
asm
volatile
(
"nop"
);
}
/**
* It returns a pointer to the config ROM
* @return pointer to the configuration ROM
*/
static
inline
const
struct
trtl_config_rom
*
trtl_config_rom_get
(
void
)
{
return
(
const
struct
trtl_config_rom
*
)(
TRTL_ADDR_CONFIG_ROM_BASE
);
}
/**
* It generates a notification signal (IRQ) to ask the HOST CPU
* to take some action.
* @param[in] id CPU notification identifier
*/
static
inline
void
trtl_notify
(
unsigned
int
id
)
{
lr_writel
(
1
,
MT_CPU_LR_REG_NTF_INT
);
}
/**
* It generates a notification signal (IRQ) to ask the HOST CPU
* to take some action.
* @param[in] id CPU notification identifier
*/
static
inline
void
trtl_notify_user
(
unsigned
int
id
)
{
if
(
id
<
__TRTL_CPU_NOTIFY_MAX
)
{
pr_error
(
"%s invalid user id %d. Replaced with %d
\r\n
"
,
__func__
,
id
,
TRTL_CPU_NOTIFY_APPLICATION
);
id
=
TRTL_CPU_NOTIFY_APPLICATION
;
}
trtl_notify
(
id
);
}
/**
* It returns the core ID on which the firmware is running
* @return the core ID
* @todo implement me
*/
static
inline
uint32_t
trtl_get_core_id
(
void
)
{
return
lr_readl
(
0
);
}
#define TRTL_MQ_SLOT_IN(slot) (TRTL_MQ_BASE_IN + ((slot) << 16))
// Outgoung slot base address, relative to BASE_HMQ
#define TRTL_MQ_SLOT_OUT(slot) (TRTL_MQ_BASE_OUT + ((slot) << 16))
/**
* List of Message Queue types
*/
enum
trtl_mq_type
{
TRTL_HMQ
=
0
,
/**< Host Message Queue - Host-Firmware communication */
TRTL_RMQ
,
/**< Remote Message Queue - Network-Firmware communication */
__TRTL_MAX_MQ_TYPE
,
};
/**
* It gets the Message Queue base address
* @param[in] type MQ type
*/
static
inline
void
*
trtl_mq_base_address
(
enum
trtl_mq_type
type
)
{
return
(
void
*
)(
type
==
TRTL_HMQ
?
TRTL_ADDR_HMQ_BASE
:
TRTL_ADDR_RMQ_BASE
);
}
/**
* It writes on a Message Queue register
* @param[in] type MQ type to use
* @param[val] value to write
* @param[reg] reg register offset
*/
static
inline
void
mq_writel
(
enum
trtl_mq_type
type
,
uint32_t
val
,
uint32_t
reg
)
{
*
(
volatile
uint32_t
*
)(
trtl_mq_base_address
(
type
)
+
reg
)
=
val
;
}
/**
* It gets the output slot data field pointer
* @param[in] type MQ type to use
* @param[in] slot slot number
* @return pointer to the input buffer
*/
static
inline
void
*
mq_map_out_buffer
(
enum
trtl_mq_type
type
,
int
slot
)
{
return
(
void
*
)
(
trtl_mq_base_address
(
type
)
+
TRTL_MQ_SLOT_OUT
(
slot
)
+
TRTL_MQ_SLOT_DATA_START
);
}
/**
* It gets the input slot data field pointer
* @param[in] type MQ type to use
* @param[in] slot slot number
* @return pointer to the input buffer
*/
static
inline
void
*
mq_map_in_buffer
(
enum
trtl_mq_type
type
,
int
slot
)
{
return
(
void
*
)
(
trtl_mq_base_address
(
type
)
+
TRTL_MQ_SLOT_IN
(
slot
)
+
TRTL_MQ_SLOT_DATA_START
);
}
/**
* It gets the output slot header field pointer
* @param[in] type MQ type to use
* @param[in] slot slot number
* @return pointer to the output header
*/
static
inline
void
*
mq_map_out_header
(
enum
trtl_mq_type
type
,
int
slot
)
{
return
(
void
*
)
(
trtl_mq_base_address
(
type
)
+
TRTL_MQ_SLOT_OUT
(
slot
)
+
TRTL_MQ_SLOT_HEADER_START
);
}
/**
* It gets the input slot header field pointer
* @param[in] type MQ type to use
* @param[in] slot slot number
* @return pointer to the input header
*/
static
inline
void
*
mq_map_in_header
(
enum
trtl_mq_type
type
,
int
slot
)
{
return
(
void
*
)
(
trtl_mq_base_address
(
type
)
+
TRTL_MQ_SLOT_IN
(
slot
)
+
TRTL_MQ_SLOT_HEADER_START
);
}
/**
* @copydoc TRTL_MQ_CMD_CLAIM
* @param[in] type MQ type to use
* @param[in] slot slot number
*/
static
inline
void
mq_claim
(
enum
trtl_mq_type
type
,
int
slot
)
{
mq_writel
(
type
,
TRTL_MQ_CMD_CLAIM
,
TRTL_MQ_SLOT_OUT
(
slot
)
+
TRTL_MQ_SLOT_COMMAND
);
}
/**
* @copydoc TRTL_MQ_CMD_PURGE
* @param[in] type MQ type to use
* @param[in] slot slot number
*/
static
inline
void
mq_purge
(
enum
trtl_mq_type
type
,
int
slot
)
{
mq_writel
(
type
,
TRTL_MQ_CMD_PURGE
,
TRTL_MQ_SLOT_OUT
(
slot
)
+
TRTL_MQ_SLOT_COMMAND
);
mq_writel
(
type
,
TRTL_MQ_CMD_PURGE
,
TRTL_MQ_SLOT_IN
(
slot
)
+
TRTL_MQ_SLOT_COMMAND
);
}
/**
* @copydoc TRTL_MQ_CMD_READY
* @param[in] type MQ type to use
* @param[in] slot slot number
*/
static
inline
void
mq_send
(
enum
trtl_mq_type
type
,
int
slot
)
{
mq_writel
(
type
,
TRTL_MQ_CMD_READY
,
TRTL_MQ_SLOT_OUT
(
slot
)
+
TRTL_MQ_SLOT_COMMAND
);
}
/**
* @copydoc TRTL_MQ_CMD_DISCARD
* @param[in] type MQ type to use
* @param[in] slot slot number
*/
static
inline
void
mq_discard
(
enum
trtl_mq_type
type
,
int
slot
)
{
mq_writel
(
type
,
TRTL_MQ_CMD_DISCARD
,
TRTL_MQ_SLOT_IN
(
slot
));
}
/**
* It maps a given MQ for outcoming messages
* @param[in] type MQ type to use
* @param[in] idx_mq MQ index
* @param[out] msg where to map the message
*/
static
inline
void
mq_map_out_message
(
enum
trtl_mq_type
type
,
unsigned
idx_mq
,
struct
trtl_msg
*
msg
)
{
msg
->
header
=
mq_map_out_header
(
type
,
idx_mq
);
msg
->
payload
=
mq_map_out_buffer
(
type
,
idx_mq
);
}
/**
* It maps a given MQ for incoming messages
* @param[in] type MQ type to use
* @param[in] idx_mq MQ index
* @param[out] msg where to map the message
*/
static
inline
void
mq_map_in_message
(
enum
trtl_mq_type
type
,
unsigned
idx_mq
,
struct
trtl_msg
*
msg
)
{
msg
->
header
=
mq_map_in_header
(
type
,
idx_mq
);
msg
->
payload
=
mq_map_in_buffer
(
type
,
idx_mq
);
}
/**
* It gets the current MQ input status
* @return message queues input status bitmask
*/
static
inline
uint32_t
mq_poll_in
(
enum
trtl_mq_type
type
)
{
uint32_t
poll
=
lr_readl
(
MT_CPU_LR_REG_HMQ_STAT
+
(
type
*
4
));
/* HMQ and RMQ have the same format -> use the same mask */
return
((
poll
&
MT_CPU_LR_HMQ_STAT_IN_MASK
)
>>
MT_CPU_LR_HMQ_STAT_IN_SHIFT
);
}
/**
* It gets the current MQ output status
* @return message queues output status bitmask
*/
static
inline
uint32_t
mq_poll_out
(
enum
trtl_mq_type
type
)
{
uint32_t
poll
=
lr_readl
(
MT_CPU_LR_REG_HMQ_STAT
+
(
type
*
4
));
/* HMQ and RMQ have the same format -> use the same mask */
return
((
poll
&
MT_CPU_LR_HMQ_STAT_OUT_MASK
)
>>
MT_CPU_LR_HMQ_STAT_OUT_SHIFT
);
}
/**
* Shared Memory Size
*/
#define TRTL_SMEM_SIZE 0x10000
/**
* Shared Memory address for the
* @copydoc TRTL_SMEM_TYPE_BASE
* memory access
*/
#define TRTL_SMEM_RANGE_BASE 0x00000
/**
* It generates the SHM address range for a given SHM type
*/
#define TRTL_SMEM_TYPE_TO_RANGE(_type) \
(TRTL_SMEM_RANGE_BASE + (_type) * TRTL_SMEM_SIZE)
/**
* Shared Memory base address for the
* @copydoc TRTL_SMEM_TYPE_ADD
* memory access
*/
#define TRTL_SMEM_RANGE_ADD \
TRTL_SMEM_TYPE_TO_RANGE(TRTL_SMEM_TYPE_ADD)
/**
* Shared Memory base address for the
* @copydoc TRTL_SMEM_TYPE_SUB
* memory access
*/
#define TRTL_SMEM_RANGE_SUB \
TRTL_SMEM_TYPE_TO_RANGE(TRTL_SMEM_TYPE_SUB)
/**
* Shared Memory address for the
* @copydoc TRTL_SMEM_TYPE_SET
* memory access
*/
#define TRTL_SMEM_RANGE_SET \
TRTL_SMEM_TYPE_TO_RANGE(TRTL_SMEM_TYPE_SET)
/**
* Shared Memory address for the
* @copydoc TRTL_SMEM_TYPE_CLR
* memory access
*/
#define TRTL_SMEM_RANGE_CLEAR \
TRTL_SMEM_TYPE_TO_RANGE(TRTL_SMEM_TYPE_CLR)
/**
* Shared Memory address for the
* @copydoc TRTL_SMEM_TYPE_FLP
* memory access
*/
#define TRTL_SMEM_RANGE_FLIP \
TRTL_SMEM_TYPE_TO_RANGE(TRTL_SMEM_TYPE_FLP)
/**
* Shared Memory address for the
* @copydoc TRTL_SMEM_TYPE_TST_SET
* memory access
*/
#define TRTL_SMEM_RANGE_TEST_AND_SET \
TRTL_SMEM_TYPE_TO_RANGE(TRTL_SMEM_TYPE_TST_SET)
/**
* Compiler attribute to allocate variable on the Share Memory.
* Add this to the variable declaration to put it on the Shared Memory.
*
* SMEM int x;
*/
#define SMEM volatile __attribute__((section(".smem")))
/**
* It performs an operations on the shared memory. What the function
* performs can be summerized as:
*
* (*p) = (*p) <operation-type> x
*
* Use this function only when the operation type that you want to use
* is not supported yet by the library directly. Otherwise,
* use the other functions.
*
* @param[in] p address on the shared memory of the first operator and store location
* @param[in] x second operation argument
* @param[in] type operation type
*/
static
inline
void
__smem_atomic_op
(
volatile
int
*
p
,
int
x
,
enum
trtl_smem_modifier
type
)
{
*
(
volatile
int
*
)(
p
+
(
TRTL_SMEM_TYPE_TO_RANGE
(
type
)
>>
2
))
=
x
;
}
/**
* It performs an
* @copydoc TRTL_SMEM_TYPE_ADD
*
* (*p) = (*p) + x
*
* @param[in] p address on the shared memory of the first operator and store location
* @param[in] x second operation argument
*/
static
inline
void
smem_atomic_add
(
volatile
int
*
p
,
int
x
)
{
__smem_atomic_op
(
p
,
x
,
TRTL_SMEM_TYPE_ADD
);
}
/**
* It performs an
* @copydoc TRTL_SMEM_TYPE_SUB
*
* (*p) = (*p) - x
*
* @param[in] p address on the shared memory of the first operator and store location
* @param[in] x second operation argument
*/
static
inline
void
smem_atomic_sub
(
volatile
int
*
p
,
int
x
)
{
__smem_atomic_op
(
p
,
x
,
TRTL_SMEM_TYPE_SUB
);
}
/**
* It performs an
* @copydoc TRTL_SMEM_TYPE_SET
*
* (*p) = (*p) | x
*
* @param[in] p address on the shared memory of the first operator and store location
* @param[in] x second operation argument
*/
static
inline
void
smem_atomic_or
(
volatile
int
*
p
,
int
x
)
{
__smem_atomic_op
(
p
,
x
,
TRTL_SMEM_TYPE_SET
);
}
/**
* It performs an
* @copydoc TRTL_SMEM_TYPE_CLR
*
* (*p) = (*p) & (~x)
*
* @param[in] p address on the shared memory of the first operator and store location
* @param[in] x second operation argument
*/
static
inline
void
smem_atomic_and_not
(
volatile
int
*
p
,
int
x
)
{
__smem_atomic_op
(
p
,
x
,
TRTL_SMEM_TYPE_CLR
);
}
/**
* It performs an
* @copydoc TRTL_SMEM_TYPE_FLP
*
* (*p) = (*p) ^ x
*
* @param[in] p address on the shared memory of the first operator and store location
* @param[in] x second operation argument
*/
static
inline
void
smem_atomic_xor
(
int
*
p
,
int
x
)
{
__smem_atomic_op
(
p
,
x
,
TRTL_SMEM_TYPE_FLP
);
}
/**
* It performs an:
* @copydoc TRTL_SMEM_TYPE_TST_SET
*
* val = (*p);
* if (val == 0) {
* (*p) = 1;
* }
* return val;
*
* This is useful to implement mutex
*
* @param[in] p address on the shared memory
* @return the value before the set
*/
static
inline
int
smem_atomic_test_and_set
(
int
*
p
)
{
/* shift right translates range in bytes into range in words */
return
*
(
volatile
int
*
)(
p
+
(
TRTL_SMEM_TYPE_TST_SET
>>
2
));
}
#endif
#endif
/**@}*/
/**@}*/
software/rt/lib/printf.c
View file @
475bc35d
...
@@ -11,8 +11,7 @@
...
@@ -11,8 +11,7 @@
#include <stdarg.h>
#include <stdarg.h>
#include <mockturtle-rt-common.h>
#include <mockturtle-rt.h>
#include <mockturtle-rt-serial.h>
#if HAS_MOCKTURTLE_LIBRARY_PRINT_ENABLE == 1
#if HAS_MOCKTURTLE_LIBRARY_PRINT_ENABLE == 1
...
...
software/tools/mockturtle-buffer.c
View file @
475bc35d
...
@@ -50,7 +50,7 @@ int main(int argc, char *argv[])
...
@@ -50,7 +50,7 @@ int main(int argc, char *argv[])
char
c
;
char
c
;
int
err
,
n
,
dev_id
=
-
1
,
v
,
i
,
k
;
int
err
,
n
,
dev_id
=
-
1
,
v
,
i
,
k
;
enum
operations
mode
;
enum
operations
mode
;
struct
trtl_
structure_
tlv
*
tlv
;
struct
trtl_tlv
*
tlv
;
unsigned
int
n_tlv
,
idx_cpu
=
0
,
idx_hmq
=
0
;;
unsigned
int
n_tlv
,
idx_cpu
=
0
,
idx_hmq
=
0
;;
uint32_t
*
data
;
uint32_t
*
data
;
...
@@ -108,23 +108,23 @@ int main(int argc, char *argv[])
...
@@ -108,23 +108,23 @@ int main(int argc, char *argv[])
else
else
n_tlv
=
1
;
/* Only 1 buffer on write */
n_tlv
=
1
;
/* Only 1 buffer on write */
tlv
=
calloc
(
n_tlv
,
sizeof
(
struct
trtl_
structure_
tlv
));
tlv
=
calloc
(
n_tlv
,
sizeof
(
struct
trtl_tlv
));
if
(
!
tlv
)
{
if
(
!
tlv
)
{
fprintf
(
stderr
,
"Cannot allocate TLV descriptors
\n
"
);
fprintf
(
stderr
,
"Cannot allocate TLV descriptors
\n
"
);
exit
(
1
);
exit
(
1
);
}
}
for
(
i
=
optind
,
v
=
0
;
v
<
n_tlv
;
i
+=
2
,
++
v
)
{
for
(
i
=
optind
,
v
=
0
;
v
<
n_tlv
;
i
+=
2
,
++
v
)
{
n
=
sscanf
(
argv
[
i
],
"%d"
,
&
tlv
[
v
].
index
);
n
=
sscanf
(
argv
[
i
],
"%d"
,
&
tlv
[
v
].
type
);
if
(
n
!=
1
)
{
if
(
n
!=
1
)
{
fprintf
(
stderr
,
fprintf
(
stderr
,
"Invalid
index
: it must be a decimal number (%s)
\n
"
,
"Invalid
type
: it must be a decimal number (%s)
\n
"
,
argv
[
i
]);
argv
[
i
]);
exit
(
1
);
exit
(
1
);
}
}
n
=
sscanf
(
argv
[
i
+
1
],
"%zu"
,
&
tlv
[
v
].
size
);
n
=
sscanf
(
argv
[
i
+
1
],
"%zu"
,
&
tlv
[
v
].
size
);
if
(
n
!=
1
)
{
if
(
n
!=
1
)
{
fprintf
(
stderr
,
fprintf
(
stderr
,
"Invalid
index
: it must be a decimal number (%s)
\n
"
,
"Invalid
size
: it must be a decimal number (%s)
\n
"
,
argv
[
i
+
1
]);
argv
[
i
+
1
]);
exit
(
1
);
exit
(
1
);
}
}
...
@@ -174,7 +174,7 @@ int main(int argc, char *argv[])
...
@@ -174,7 +174,7 @@ int main(int argc, char *argv[])
switch
(
mode
)
{
switch
(
mode
)
{
case
OP_READ
:
case
OP_READ
:
err
=
trtl_
rt
_buffer_get
(
trtl
,
idx_cpu
,
idx_hmq
,
tlv
,
n_tlv
);
err
=
trtl_
fw
_buffer_get
(
trtl
,
idx_cpu
,
idx_hmq
,
tlv
,
n_tlv
);
if
(
err
)
{
if
(
err
)
{
fprintf
(
stderr
,
"Cannot read buffer: %s
\n
"
,
fprintf
(
stderr
,
"Cannot read buffer: %s
\n
"
,
trtl_strerror
(
errno
));
trtl_strerror
(
errno
));
...
@@ -183,7 +183,7 @@ int main(int argc, char *argv[])
...
@@ -183,7 +183,7 @@ int main(int argc, char *argv[])
/* trtl_print_payload(&hdr, tlv); */
/* trtl_print_payload(&hdr, tlv); */
break
;
break
;
case
OP_WRITE
:
case
OP_WRITE
:
err
=
trtl_
rt
_buffer_set
(
trtl
,
idx_cpu
,
idx_hmq
,
tlv
,
n_tlv
);
err
=
trtl_
fw
_buffer_set
(
trtl
,
idx_cpu
,
idx_hmq
,
tlv
,
n_tlv
);
break
;
break
;
}
}
...
...
software/tools/mockturtle-ping.c
View file @
475bc35d
...
@@ -44,11 +44,9 @@ static void help(char *name)
...
@@ -44,11 +44,9 @@ static void help(char *name)
* It prints the given Mock Turtle firmware version
* It prints the given Mock Turtle firmware version
* @param[in] v version to print
* @param[in] v version to print
*/
*/
static
void
trtl_ping_version_print
(
struct
trtl_
rt
_version
*
v
)
static
void
trtl_ping_version_print
(
struct
trtl_
fw
_version
*
v
)
{
{
fprintf
(
stdout
,
"
\t
Firmware Version:
\n
"
);
fprintf
(
stdout
,
"
\t
Firmware Version:
\n
"
);
fprintf
(
stdout
,
"
\t
bitstream_id: 0x%08X
\n
"
,
v
->
fpga_id
);
fprintf
(
stdout
,
"
\t
application_id: 0x%08X
\n
"
,
fprintf
(
stdout
,
"
\t
application_id: 0x%08X
\n
"
,
v
->
rt_id
);
v
->
rt_id
);
fprintf
(
stdout
,
"
\t
firmware_version: 0x%08X
\n
"
,
fprintf
(
stdout
,
"
\t
firmware_version: 0x%08X
\n
"
,
...
@@ -62,7 +60,7 @@ int main(int argc, char *argv[])
...
@@ -62,7 +60,7 @@ int main(int argc, char *argv[])
{
{
struct
trtl_dev
*
trtl
;
struct
trtl_dev
*
trtl
;
uint32_t
dev_id
=
0
,
n
=
1
;
uint32_t
dev_id
=
0
,
n
=
1
;
struct
trtl_
rt
_version
version
;
struct
trtl_
fw
_version
version
;
uint64_t
period
=
0
;
uint64_t
period
=
0
;
int
err
,
f_version
=
0
,
idx_cpu
=
0
,
idx_hmq
=
0
;
int
err
,
f_version
=
0
,
idx_cpu
=
0
,
idx_hmq
=
0
;
char
c
;
char
c
;
...
@@ -118,7 +116,7 @@ int main(int argc, char *argv[])
...
@@ -118,7 +116,7 @@ int main(int argc, char *argv[])
usleep
(
period
);
usleep
(
period
);
/* Try to ping */
/* Try to ping */
err
=
trtl_
rt
_ping
(
trtl
,
idx_cpu
,
idx_hmq
);
err
=
trtl_
fw
_ping
(
trtl
,
idx_cpu
,
idx_hmq
);
if
(
err
)
{
if
(
err
)
{
fprintf
(
stderr
,
fprintf
(
stderr
,
"Ping failed on Device 0x%x CPU %d HMQ %d: %s
\n
"
,
"Ping failed on Device 0x%x CPU %d HMQ %d: %s
\n
"
,
...
@@ -132,7 +130,7 @@ int main(int argc, char *argv[])
...
@@ -132,7 +130,7 @@ int main(int argc, char *argv[])
/* Get the version */
/* Get the version */
if
(
f_version
)
{
if
(
f_version
)
{
trtl_
rt_version_get
(
trtl
,
idx_cpu
,
idx_hmq
,
&
version
);
trtl_
fw_version
(
trtl
,
idx_cpu
,
idx_hmq
,
&
version
);
trtl_ping_version_print
(
&
version
);
trtl_ping_version_print
(
&
version
);
}
}
...
...
software/tools/mockturtle-smem.c
View file @
475bc35d
...
@@ -79,7 +79,7 @@ int main(int argc, char *argv[])
...
@@ -79,7 +79,7 @@ int main(int argc, char *argv[])
break
;
break
;
case
'm'
:
case
'm'
:
sscanf
(
optarg
,
"%d"
,
&
mod
);
sscanf
(
optarg
,
"%d"
,
&
mod
);
if
(
mod
>
TRTL_SMEM_ADD
)
{
if
(
mod
>
TRTL_SMEM_
TYPE_
ADD
)
{
fprintf
(
stderr
,
"Invalid operation mode
\n
"
);
fprintf
(
stderr
,
"Invalid operation mode
\n
"
);
help
();
help
();
exit
(
1
);
exit
(
1
);
...
...
software/tools/mockturtle-variable.c
View file @
475bc35d
...
@@ -146,7 +146,7 @@ int main(int argc, char *argv[])
...
@@ -146,7 +146,7 @@ int main(int argc, char *argv[])
switch
(
mode
)
{
switch
(
mode
)
{
case
OP_READ
:
case
OP_READ
:
err
=
trtl_
rt
_variable_get
(
trtl
,
idx_cpu
,
idx_hmq
,
var
,
n_var
);
err
=
trtl_
fw
_variable_get
(
trtl
,
idx_cpu
,
idx_hmq
,
var
,
n_var
);
if
(
err
)
{
if
(
err
)
{
fprintf
(
stderr
,
"Cannot read variables: %s
\n
"
,
fprintf
(
stderr
,
"Cannot read variables: %s
\n
"
,
trtl_strerror
(
errno
));
trtl_strerror
(
errno
));
...
@@ -158,7 +158,7 @@ int main(int argc, char *argv[])
...
@@ -158,7 +158,7 @@ int main(int argc, char *argv[])
}
}
break
;
break
;
case
OP_WRITE
:
case
OP_WRITE
:
err
=
trtl_
rt
_variable_set
(
trtl
,
idx_cpu
,
idx_hmq
,
var
,
n_var
);
err
=
trtl_
fw
_variable_set
(
trtl
,
idx_cpu
,
idx_hmq
,
var
,
n_var
);
if
(
err
)
{
if
(
err
)
{
fprintf
(
stderr
,
"Cannot write variables: %s
\n
"
,
fprintf
(
stderr
,
"Cannot write variables: %s
\n
"
,
trtl_strerror
(
errno
));
trtl_strerror
(
errno
));
...
...
software/tools/trtl-project-creator/templates/software/firmware/fw-01/fw-project.c
View file @
475bc35d
...
@@ -25,7 +25,7 @@ static struct rt_mq mq[] = {
...
@@ -25,7 +25,7 @@ static struct rt_mq mq[] = {
};
};
static
struct
rt
_variable
variables
[]
=
{
static
struct
trtl_fw
_variable
variables
[]
=
{
/* put here variables that you want to share */
/* put here variables that you want to share */
};
};
...
@@ -33,17 +33,17 @@ static struct rt_structure structures[] = {
...
@@ -33,17 +33,17 @@ static struct rt_structure structures[] = {
/* put here data structures that you want to share */
/* put here data structures that you want to share */
};
};
static
action_t
*
actions
[]
=
{
static
trtl_fw_
action_t
*
actions
[]
=
{
[
RT_ACTION_RECV_PING
]
=
rt_recv_ping
,
[
RT_ACTION_RECV_PING
]
=
rt_recv_ping
,
[
RT_ACTION_RECV_VERSION
]
=
rt_version_getter
,
[
RT_ACTION_RECV_VERSION
]
=
rt_version_getter
,
[
RT_ACTION_RECV_FIELD_SET
]
=
rt
_variable_setter
,
[
RT_ACTION_RECV_FIELD_SET
]
=
trtl_fw
_variable_setter
,
[
RT_ACTION_RECV_FIELD_GET
]
=
rt
_variable_getter
,
[
RT_ACTION_RECV_FIELD_GET
]
=
trtl_fw
_variable_getter
,
[
RT_ACTION_RECV_STRUCT_SET
]
=
rt_structure_setter
,
[
RT_ACTION_RECV_STRUCT_SET
]
=
rt_structure_setter
,
[
RT_ACTION_RECV_STRUCT_GET
]
=
rt_structure_getter
,
[
RT_ACTION_RECV_STRUCT_GET
]
=
rt_structure_getter
,
/* Add your actions here */
/* Add your actions here */
};
};
struct
rt
_application
app
=
{
struct
trtl_fw
_application
app
=
{
.
name
=
"{{short_name}}"
,
.
name
=
"{{short_name}}"
,
.
version
=
{
.
version
=
{
.
fpga_id
=
FPGA_APPLICATION_ID
,
.
fpga_id
=
FPGA_APPLICATION_ID
,
...
@@ -69,7 +69,7 @@ struct rt_application app = {
...
@@ -69,7 +69,7 @@ struct rt_application app = {
*/
*/
int
main
()
int
main
()
{
{
rt
_init
(
&
app
);
trtl_fw
_init
(
&
app
);
while
(
1
)
{
while
(
1
)
{
/*
/*
...
@@ -77,7 +77,7 @@ int main()
...
@@ -77,7 +77,7 @@ int main()
* {{short_name_capital}}_CMD_IN
* {{short_name_capital}}_CMD_IN
* as actions
* as actions
*/
*/
rt
_mq_action_dispatch
({{
short_name_capital
}}
_CMD_IN
);
trtl_fw
_mq_action_dispatch
({{
short_name_capital
}}
_CMD_IN
);
}
}
return
0
;
return
0
;
...
...
tests/firmware/config_rom/config_rom.c
View file @
475bc35d
#include <mockturtle-rt.h>
#include <mockturtle-rt.h>
#include <hw/mockturtle_config.h>
int
main
()
int
main
()
{
{
...
...
tests/firmware/cpu-loop/cpu-loop.c
View file @
475bc35d
#include <mockturtle-rt-serial.h>
int
main
()
int
main
()
{
{
int
sum
=
0
;
int
sum
=
0
;
...
...
tests/firmware/hmq-async-recv/hmq-async-recv.c
View file @
475bc35d
#include <mockturtle-rt.h>
#include <mockturtle-rt.h>
#include <hw/mockturtle_config.h>
int
main
()
int
main
()
{
{
...
...
tests/firmware/hmq-async-send/hmq-async-send.c
View file @
475bc35d
#include <mockturtle-rt.h>
#include <mockturtle-rt.h>
#include <hw/mockturtle_config.h>
int
main
()
int
main
()
...
@@ -21,7 +20,7 @@ int main()
...
@@ -21,7 +20,7 @@ int main()
max_wait_cycle
=
0xFFFF
;
max_wait_cycle
=
0xFFFF
;
while
(
1
)
{
while
(
1
)
{
/* Wait incoming message */
/* Wait incoming message */
while
((
hmq_poll_in
(
)
&
wait
)
!=
wait
)
{
while
((
mq_poll_in
(
TRTL_HMQ
)
&
wait
)
!=
wait
)
{
if
(
--
max_wait_cycle
==
0
)
{
if
(
--
max_wait_cycle
==
0
)
{
pr_error
(
"
\t
NO MESSAGE PENDING h:%d, cnt:0x%x
\r\n
"
,
pr_error
(
"
\t
NO MESSAGE PENDING h:%d, cnt:0x%x
\r\n
"
,
hmq
,
count
);
hmq
,
count
);
...
@@ -31,13 +30,13 @@ int main()
...
@@ -31,13 +30,13 @@ int main()
/* validate message */
/* validate message */
if
(
hdr
->
len
!=
1
||
msg
[
0
]
!=
count
)
{
if
(
hdr
->
len
!=
1
||
msg
[
0
]
!=
count
)
{
pr_error
(
"
\t
h: %d, l:%
l
d, d[0]:0x%lx, cnt:0x%x
\r\n
"
,
pr_error
(
"
\t
h: %d, l:%d, d[0]:0x%lx, cnt:0x%x
\r\n
"
,
hmq
,
hdr
->
len
,
msg
[
0
],
count
);
hmq
,
hdr
->
len
,
msg
[
0
],
count
);
mq_discard
(
TRTL_HMQ
,
hmq
);
mq_discard
(
TRTL_HMQ
,
hmq
);
return
-
1
;
return
-
1
;
}
}
if
(
msg
[
1
]
<
count
)
{
if
(
msg
[
1
]
<
count
)
{
pr_error
(
"
\t
h:%d, l:%
l
d d[1]:0x%lx, cnt:0x%x
\r\n
"
,
pr_error
(
"
\t
h:%d, l:%d d[1]:0x%lx, cnt:0x%x
\r\n
"
,
hmq
,
hdr
->
len
,
msg
[
1
],
count
);
hmq
,
hdr
->
len
,
msg
[
1
],
count
);
mq_discard
(
TRTL_HMQ
,
hmq
);
mq_discard
(
TRTL_HMQ
,
hmq
);
return
-
1
;
return
-
1
;
...
...
tests/firmware/hmq-purge/hmq-purge.c
View file @
475bc35d
#include <mockturtle-rt.h>
#include <mockturtle-rt.h>
#include <hw/mockturtle_config.h>
int
main
()
int
main
()
{
{
...
@@ -11,23 +10,23 @@ int main()
...
@@ -11,23 +10,23 @@ int main()
cpu
=
0
;
cpu
=
0
;
for
(
hmq
=
0
;
hmq
<
cfgrom
->
n_hmq
[
cpu
];
++
hmq
)
{
for
(
hmq
=
0
;
hmq
<
cfgrom
->
n_hmq
[
cpu
];
++
hmq
)
{
if
((
hmq_poll_in
(
)
&
(
1
<<
hmq
))
!=
(
1
<<
hmq
))
{
if
((
mq_poll_in
(
TRTL_HMQ
)
&
(
1
<<
hmq
))
!=
(
1
<<
hmq
))
{
pr_error
(
"HMQ-%d after poll: 0x%
lx
\r\n
"
,
pr_error
(
"HMQ-%d after poll: 0x%
"
PRIx32
"
\r\n
"
,
hmq
,
hmq_poll_in
(
));
hmq
,
mq_poll_in
(
TRTL_HMQ
));
return
-
1
;
return
-
1
;
}
}
mq_purge
(
TRTL_HMQ
,
hmq
);
mq_purge
(
TRTL_HMQ
,
hmq
);
if
((
hmq_poll_in
(
)
&
(
1
<<
hmq
))
==
(
1
<<
hmq
))
{
if
((
mq_poll_in
(
TRTL_HMQ
)
&
(
1
<<
hmq
))
==
(
1
<<
hmq
))
{
pr_error
(
"HMQ-%d after poll: 0x%
lx
\r\n
"
,
pr_error
(
"HMQ-%d after poll: 0x%
"
PRIx32
"
\r\n
"
,
hmq
,
hmq_poll_in
(
));
hmq
,
mq_poll_in
(
TRTL_HMQ
));
return
-
1
;
return
-
1
;
}
}
}
}
if
(
hmq_poll_in
(
)
!=
0
)
{
if
(
mq_poll_in
(
TRTL_HMQ
)
!=
0
)
{
pr_error
(
"END poll: 0x%
lx
\r\n
"
,
hmq_poll_in
(
));
pr_error
(
"END poll: 0x%
"
PRIx32
"
\r\n
"
,
mq_poll_in
(
TRTL_HMQ
));
return
-
1
;
return
-
1
;
}
}
...
...
tests/firmware/hmq-sync/hmq-sync.c
View file @
475bc35d
#include <mockturtle-rt.h>
#include <mockturtle-rt.h>
#include <hw/mockturtle_config.h>
int
main
()
int
main
()
{
{
...
@@ -24,7 +23,7 @@ int main()
...
@@ -24,7 +23,7 @@ int main()
max_wait_cycle
=
0xFFFFFFFF
;
max_wait_cycle
=
0xFFFFFFFF
;
while
(
1
)
{
while
(
1
)
{
/* Wait incoming message */
/* Wait incoming message */
while
((
hmq_poll_in
(
)
&
wait
)
!=
wait
)
{
while
((
mq_poll_in
(
TRTL_HMQ
)
&
wait
)
!=
wait
)
{
if
(
--
max_wait_cycle
==
0
)
{
if
(
--
max_wait_cycle
==
0
)
{
pr_error
(
"
\t
NO MESSAGE PENDING h:%d, cnt:0x%x
\r\n
"
,
pr_error
(
"
\t
NO MESSAGE PENDING h:%d, cnt:0x%x
\r\n
"
,
hmq
,
count
);
hmq
,
count
);
...
@@ -34,13 +33,13 @@ int main()
...
@@ -34,13 +33,13 @@ int main()
/* validate message */
/* validate message */
if
(
hdr_r
->
len
!=
1
||
msg_r
[
0
]
!=
count
)
{
if
(
hdr_r
->
len
!=
1
||
msg_r
[
0
]
!=
count
)
{
pr_error
(
"
\t
h: %d, l:%
l
d, d[0]:0x%lx, cnt:0x%x
\r\n
"
,
pr_error
(
"
\t
h: %d, l:%d, d[0]:0x%lx, cnt:0x%x
\r\n
"
,
hmq
,
hdr_r
->
len
,
msg_r
[
0
],
count
);
hmq
,
hdr_r
->
len
,
msg_r
[
0
],
count
);
mq_discard
(
TRTL_HMQ
,
hmq
);
mq_discard
(
TRTL_HMQ
,
hmq
);
return
-
1
;
return
-
1
;
}
}
if
(
msg_r
[
1
]
<
count
)
{
if
(
msg_r
[
1
]
<
count
)
{
pr_error
(
"
\t
h:%d, l:%
l
d d[1]:0x%lx, cnt:0x%x
\r\n
"
,
pr_error
(
"
\t
h:%d, l:%d d[1]:0x%lx, cnt:0x%x
\r\n
"
,
hmq
,
hdr_r
->
len
,
msg_r
[
1
],
count
);
hmq
,
hdr_r
->
len
,
msg_r
[
1
],
count
);
mq_discard
(
TRTL_HMQ
,
hmq
);
mq_discard
(
TRTL_HMQ
,
hmq
);
return
-
1
;
return
-
1
;
...
...
tests/firmware/serial/serial.c
View file @
475bc35d
#include <mockturtle-rt
-serial
.h>
#include <mockturtle-rt.h>
int
main
()
int
main
()
{
{
...
...
tests/firmware/sim-verif/sim-verif.c
View file @
475bc35d
...
@@ -65,7 +65,7 @@ test_hmq(void)
...
@@ -65,7 +65,7 @@ test_hmq(void)
mq_send
(
TRTL_HMQ
,
0
);
mq_send
(
TRTL_HMQ
,
0
);
// Wait for answer
// Wait for answer
while
((
hmq_poll_in
(
)
&
1
)
==
0
)
while
((
mq_poll_in
(
TRTL_HMQ
)
&
1
)
==
0
)
;
;
if
(
counts
[
cpu
]
!=
v
+
1
)
if
(
counts
[
cpu
]
!=
v
+
1
)
failed
(
'H'
);
failed
(
'H'
);
...
@@ -80,7 +80,7 @@ test_hmq(void)
...
@@ -80,7 +80,7 @@ test_hmq(void)
failed
(
'K'
);
failed
(
'K'
);
mq_discard
(
TRTL_HMQ
,
0
);
mq_discard
(
TRTL_HMQ
,
0
);
if
((
hmq_poll_in
(
)
&
1
)
!=
0
)
if
((
mq_poll_in
(
TRTL_HMQ
)
&
1
)
!=
0
)
failed
(
'k'
);
failed
(
'k'
);
}
}
...
@@ -103,7 +103,7 @@ test_rmq(void)
...
@@ -103,7 +103,7 @@ test_rmq(void)
mq_send
(
TRTL_RMQ
,
0
);
mq_send
(
TRTL_RMQ
,
0
);
// Wait for answer
// Wait for answer
while
((
rmq_poll_in
(
)
&
1
)
==
0
)
while
((
mq_poll_in
(
TRTL_RMQ
)
&
1
)
==
0
)
;
;
// Read answer
// Read answer
...
@@ -116,7 +116,7 @@ test_rmq(void)
...
@@ -116,7 +116,7 @@ test_rmq(void)
failed
(
'r'
);
failed
(
'r'
);
mq_discard
(
TRTL_RMQ
,
0
);
mq_discard
(
TRTL_RMQ
,
0
);
if
((
rmq_poll_in
(
)
&
1
)
!=
0
)
if
((
mq_poll_in
(
TRTL_RMQ
)
&
1
)
!=
0
)
failed
(
's'
);
failed
(
's'
);
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment