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
4c6d6f25
Commit
4c6d6f25
authored
May 08, 2018
by
Federico Vaga
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
sw:*: update firmware framework buffer feature
Signed-off-by:
Federico Vaga
<
federico.vaga@cern.ch
>
parent
6ebae692
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
110 additions
and
134 deletions
+110
-134
mockturtle-framework.c
software/firmware/framework/mockturtle-framework.c
+38
-68
libmockturtle-rt-msg.c
software/lib/libmockturtle-rt-msg.c
+57
-63
mockturtle-buffer.c
software/tools/mockturtle-buffer.c
+15
-3
No files found.
software/firmware/framework/mockturtle-framework.c
View file @
4c6d6f25
...
...
@@ -49,10 +49,11 @@ static int rt_version_getter(struct trtl_fw_msg *msg_i, struct trtl_fw_msg *msg_
/**
* 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.
* it
get/set one of the declared buffers
*/
static
int
trtl_fw_buffer
_getter
(
struct
trtl_fw_msg
*
msg_i
,
struct
trtl_fw_msg
*
msg_o
)
static
int
trtl_fw_buffer
(
struct
trtl_fw_msg
*
msg_i
,
struct
trtl_fw_msg
*
msg_o
)
{
struct
trtl_fw_buffer
*
buf
;
unsigned
int
offset
=
0
,
index
,
size
;
uint32_t
*
din
;
uint32_t
*
dout
;
...
...
@@ -62,83 +63,52 @@ static int trtl_fw_buffer_getter(struct trtl_fw_msg *msg_i, struct trtl_fw_msg *
}
/* Only synchronous */
if
(
!
(
msg_i
->
header
->
flags
&
TRTL_HMQ_HEADER_FLAG_SYNC
))
if
(
msg_i
->
header
->
msg_id
==
TRTL_MSG_ID_VAR_GET
&&
!
(
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
;
if
(
msg_o
)
{
dout
=
msg_o
->
payload
;
msg_o
->
header
->
msg_id
=
TRTL_MSG_ID_BUF_GET
;
msg_o
->
header
->
len
=
msg_i
->
header
->
len
;
}
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
);
index
=
din
[
offset
+
0
];
size
=
din
[
offset
+
1
];
if
(
index
>=
app
.
n_buffers
)
{
pr_error
(
"%s: TLV %d buffer unknown %d
\n\r
"
,
__func__
,
index
,
index
);
return
-
EINVAL
;
}
buf
=
&
app
.
buffers
[
index
];
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_fw_msg
*
msg_i
,
struct
trtl_fw_msg
*
msg_o
)
{
unsigned
int
offset
=
0
,
index
,
size
;
uint32_t
*
din
;
if
(
!
HAS_MOCKTURTLE_FRAMEWORK_BUFFER_ENABLE
)
{
return
-
EPERM
;
}
if
(
size
>
buf
->
len
)
{
pr_error
(
"%s: buffer %d len %d not correct max %"
PRId32
"
\n\r
"
,
__func__
,
index
,
size
,
buf
->
len
);
return
-
EINVAL
;
}
din
=
msg_i
->
payload
;
pr_debug
(
"%s buffer %d len %d (%ld) Addr 0x%p
\n\r
"
,
__func__
,
index
,
size
,
buf
->
len
,
buf
->
buf
);
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
);
switch
(
msg_i
->
header
->
msg_id
)
{
case
TRTL_MSG_ID_BUF_SET
:
memcpy
(
buf
->
buf
,
&
din
[
offset
+
2
],
size
);
/* After a set we always read back => get */
case
TRTL_MSG_ID_BUF_GET
:
dout
[
offset
+
0
]
=
index
;
dout
[
offset
+
1
]
=
size
;
memcpy
(
&
dout
[
offset
+
2
],
buf
->
buf
,
size
);
break
;
default:
return
-
EINVAL
;
}
offset
+=
(
size
/
4
);
/* Next TLV record */
offset
+=
(
2
+
(
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
;
}
...
...
@@ -228,8 +198,8 @@ static trtl_fw_action_t *trtl_actions_in[] = {
[
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
,
[
TRTL_MSG_ID_VAR_GET
-
__TRTL_MSG_ID_MAX_USER
]
=
trtl_fw_variable
,
[
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
,
[
TRTL_MSG_ID_BUF_SET
-
__TRTL_MSG_ID_MAX_USER
]
=
trtl_fw_buffer
,
[
TRTL_MSG_ID_BUF_GET
-
__TRTL_MSG_ID_MAX_USER
]
=
trtl_fw_buffer
,
};
...
...
software/lib/libmockturtle-rt-msg.c
View file @
4c6d6f25
...
...
@@ -88,7 +88,7 @@ static int __trtl_fw_variable(struct trtl_dev *trtl,
unsigned
int
idx_hmq
,
uint32_t
*
variables
,
unsigned
int
n_variables
,
u
nsigned
in
t
msg_id
)
u
int8_
t
msg_id
)
{
struct
trtl_desc
*
wdesc
=
(
struct
trtl_desc
*
)
trtl
;
struct
trtl_msg
msg
;
...
...
@@ -200,21 +200,13 @@ int trtl_fw_variable_get(struct trtl_dev *trtl,
}
/**
* It sends/receives a set of structures within TLV records.
* This function will change the header content, in particular it will change
* the following fields: msg_id, len
* @param[in] trtl device token
* @param[in] idx_cpu CPU index
* @param[in] idx_hmq HMQ index
* @param[in] tlv the complete buffer
* @param[in] n_tlv number of tlv structures
*/
int
trtl_fw_buffer_set
(
struct
trtl_dev
*
trtl
,
unsigned
int
idx_cpu
,
unsigned
int
idx_hmq
,
struct
trtl_tlv
*
tlv
,
unsigned
int
n_tlv
)
static
int
__trtl_fw_buffer
(
struct
trtl_dev
*
trtl
,
unsigned
int
idx_cpu
,
unsigned
int
idx_hmq
,
struct
trtl_tlv
*
tlv
,
unsigned
int
n_tlv
,
uint8_t
msg_id
)
{
struct
trtl_msg
msg
;
struct
trtl_desc
*
wdesc
=
(
struct
trtl_desc
*
)
trtl
;
...
...
@@ -225,32 +217,72 @@ int trtl_fw_buffer_set(struct trtl_dev *trtl,
/* Validate */
for
(
i
=
0
;
i
<
n_tlv
;
++
i
)
{
total_size
+=
8
;
/* 32bit for type and size */
total_size
+=
(
sizeof
(
uint32_t
)
*
2
)
;
/* 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
)
{
if
(
total_size
>
TRTL_CONFIG_ROM_MQ_SIZE_PAYLOAD
(
sizes
)
*
4
||
tlv
->
size
>
TRTL_MAX_PAYLOAD_SIZE
*
4
)
{
errno
=
EINVAL
;
return
-
1
;
}
}
memset
(
&
msg
,
0
,
sizeof
(
struct
trtl_msg
));
msg
.
hdr
.
msg_id
=
msg_id
;
msg
.
hdr
.
seq
=
wdesc
->
seq
;
msg
.
hdr
.
sync_id
=
msg
.
hdr
.
seq
;
msg
.
hdr
.
flags
=
TRTL_HMQ_HEADER_FLAG_RPC
;
msg
.
hdr
.
len
=
total_size
/
sizeof
(
uint32_t
);
/* 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
));
msg
.
data
[
offset
++
]
=
tlv
[
i
].
type
;
msg
.
data
[
offset
++
]
=
tlv
[
i
].
size
;
memcpy
(
&
msg
.
data
[
offset
],
tlv
[
i
].
buf
,
tlv
[
i
].
size
);
offset
+=
(
tlv
->
size
/
sizeof
(
uint32_t
));
}
err
=
trtl_msg_sync
(
trtl
,
idx_cpu
,
idx_hmq
,
&
msg
,
&
msg
,
trtl_default_timeout_ms
);
if
(
err
<=
0
)
if
(
err
<
0
)
return
-
1
;
if
(
msg
.
hdr
.
msg_id
!=
TRTL_MSG_ID_BUF_GET
)
{
/* Yes, it answers with GET even on SET */
errno
=
ETRTL_INVALID_MESSAGE
;
return
-
1
;
}
/* Copy back buffers */
for
(
offset
=
0
,
i
=
0
;
i
<
n_tlv
;
++
i
)
{
tlv
[
i
].
type
=
msg
.
data
[
offset
++
];
tlv
[
i
].
size
=
msg
.
data
[
offset
++
];
memcpy
(
tlv
[
i
].
buf
,
&
msg
.
data
[
offset
],
tlv
[
i
].
size
);
offset
+=
(
tlv
->
size
/
sizeof
(
uint32_t
));
}
return
0
;
}
/**
* It sends/receives a set of structures within TLV records.
* This function will change the header content, in particular it will change
* the following fields: msg_id, len
* @param[in] trtl device token
* @param[in] idx_cpu CPU index
* @param[in] idx_hmq HMQ index
* @param[in] tlv the complete buffer
* @param[in] n_tlv number of tlv structures
*/
int
trtl_fw_buffer_set
(
struct
trtl_dev
*
trtl
,
unsigned
int
idx_cpu
,
unsigned
int
idx_hmq
,
struct
trtl_tlv
*
tlv
,
unsigned
int
n_tlv
)
{
return
__trtl_fw_buffer
(
trtl
,
idx_cpu
,
idx_hmq
,
tlv
,
n_tlv
,
TRTL_MSG_ID_BUF_SET
);
}
/**
* It receives a set of structures within TLV records.
...
...
@@ -269,46 +301,8 @@ int trtl_fw_buffer_get(struct trtl_dev *trtl,
struct
trtl_tlv
*
tlv
,
unsigned
int
n_tlv
)
{
struct
trtl_msg
msg
;
struct
trtl_desc
*
wdesc
=
(
struct
trtl_desc
*
)
trtl
;
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
;
return
__trtl_fw_buffer
(
trtl
,
idx_cpu
,
idx_hmq
,
tlv
,
n_tlv
,
TRTL_MSG_ID_BUF_GET
);
}
...
...
software/tools/mockturtle-buffer.c
View file @
4c6d6f25
...
...
@@ -25,12 +25,12 @@ static void help(char *name)
{
fprintf
(
stderr
,
"
\n
"
);
fprintf
(
stderr
,
"%s -D 0x<hex-number> -i <number> -
o <number> -s
<number> [read <idx> <size> <idx> <size> ...] [write <idx> <size> <value> ... <value>]
\n\n
"
,
"%s -D 0x<hex-number> -i <number> -
c <number> -q
<number> [read <idx> <size> <idx> <size> ...] [write <idx> <size> <value> ... <value>]
\n\n
"
,
name
);
fprintf
(
stderr
,
"It reads/writes variables on a HMQ
\n\n
"
);
fprintf
(
stderr
,
"-D device identificator in hexadecimal format
\n
"
);
fprintf
(
stderr
,
"-
i slot index where send
\n
"
);
fprintf
(
stderr
,
"-
o slot index where receive
\n
"
);
fprintf
(
stderr
,
"-
c CPU core index
\n
"
);
fprintf
(
stderr
,
"-
q HMQ index
\n
"
);
fprintf
(
stderr
,
"-h show this help
\n
"
);
fprintf
(
stderr
,
"
\n
"
);
fprintf
(
stderr
,
"write mode accept only 1 buffer
\n
"
);
...
...
@@ -180,6 +180,18 @@ int main(int argc, char *argv[])
trtl_strerror
(
errno
));
break
;
}
for
(
i
=
0
;
i
<
n_tlv
;
++
i
)
{
fprintf
(
stdout
,
"Buffer index: %d
\n
"
,
tlv
[
i
].
type
);
fprintf
(
stdout
,
"Buffer size : %zd
\n
"
,
tlv
[
i
].
size
);
fprintf
(
stdout
,
"Buffer data :"
);
data
=
tlv
[
i
].
buf
;
for
(
k
=
0
;
k
<
tlv
[
i
].
size
/
4
;
++
k
)
{
fprintf
(
stdout
,
" %08x"
,
data
[
k
]);
if
((
k
&
0x3
)
==
0x3
)
fprintf
(
stdout
,
"
\n
"
);
}
fprintf
(
stdout
,
"
\n
"
);
}
/* trtl_print_payload(&hdr, tlv); */
break
;
case
OP_WRITE
:
...
...
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