Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
S
Software for White Rabbit PTP Core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
31
Issues
31
List
Board
Labels
Milestones
Merge Requests
4
Merge Requests
4
CI / CD
CI / CD
Pipelines
Schedules
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
Software for White Rabbit PTP Core
Commits
12688ef9
Commit
12688ef9
authored
Apr 08, 2022
by
Tristan Gingold
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add wrpc-load utility to load/save a firmware image
parent
a5431365
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
289 additions
and
0 deletions
+289
-0
Makefile
tools/Makefile
+4
-0
wrpc-load.c
tools/wrpc-load.c
+285
-0
No files found.
tools/Makefile
View file @
12688ef9
...
...
@@ -12,6 +12,7 @@ ALL += pfilter-builder
ALL
+=
mapper
ALL
+=
wrpc-vuart
ALL
+=
wrpc-gdbserver
ALL
+=
wrpc-load
ALL
+=
wr-streamers
ALL
+=
wrpc-diags
ALL
+=
gensdbfs
...
...
@@ -84,6 +85,9 @@ wrpc-vuart: wrpc-vuart.o vuart_lib.o
wrpc-gdbserver
:
wrpc-gdbserver.o vuart_lib.o
$(CC)
$(CFLAGS)
-Werror
$^
$(LDFLAGS)
-o
$@
wrpc-load
:
wrpc-load.o
$(CC)
$(CFLAGS)
$^
$(LDFLAGS)
-o
$@
pfilter-builder
:
pfilter-builder.c
$(CC)
$(CFLAGS)
-include
../include/generated/autoconf.h
\
$@
.c
$(LDFLAGS)
-o
$@
...
...
tools/wrpc-load.c
0 → 100644
View file @
12688ef9
/*
* SPDX-License-Identifier: GPL-3.0-or-later
* SPDX-FileCopyrightText: 2019 CERN (home.cern)
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <getopt.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <poll.h>
#include <stdbool.h>
#include <time.h>
#include <limits.h>
#include "libdevmap.h"
#include "hw/wrc_cpu_csr.h"
static
int
verbose
;
static
uint32_t
wrc_readl
(
struct
mapping_desc
*
desc
,
unsigned
reg
)
{
uint32_t
r
=
*
(
volatile
uint32_t
*
)(
desc
->
base
+
reg
);
if
(
desc
->
is_be
)
return
ntohl
(
r
);
else
return
r
;
}
static
void
wrc_writel
(
struct
mapping_desc
*
desc
,
unsigned
reg
,
uint32_t
value
)
{
if
(
desc
->
is_be
)
value
=
htonl
(
value
);
*
(
volatile
uint32_t
*
)(
desc
->
base
+
reg
)
=
value
;
}
static
void
wrc_cpu_reset
(
struct
mapping_desc
*
desc
,
unsigned
int
rst
)
{
wrc_writel
(
desc
,
0xb00
+
WRC_CPU_CSR_REG_RESET
,
rst
);
}
static
void
wrc_write_uaddr
(
struct
mapping_desc
*
desc
,
unsigned
int
addr
)
{
wrc_writel
(
desc
,
0xb00
+
WRC_CPU_CSR_REG_UADDR
,
addr
>>
2
);
}
static
void
wrc_write_buf
(
struct
mapping_desc
*
desc
,
const
unsigned
char
*
buf
,
unsigned
len
,
unsigned
addr
)
{
if
((
len
&
0x03
)
!=
0
||
(
addr
&
0x03
)
!=
0
)
abort
();
while
(
len
>
0
)
{
uint32_t
v
;
wrc_write_uaddr
(
desc
,
addr
);
/* Use BE. */
v
=
(
buf
[
3
]
<<
0
)
|
(
buf
[
2
]
<<
8
)
|
(
buf
[
1
]
<<
16
)
|
(
buf
[
0
]
<<
24
);
wrc_writel
(
desc
,
0xb00
+
WRC_CPU_CSR_REG_UDATA
,
v
);
if
(
verbose
)
printf
(
"Write %08x at %08x
\n
"
,
v
,
addr
);
len
-=
4
;
addr
+=
4
;
buf
+=
4
;
}
}
static
int
wrc_load_firmware
(
struct
mapping_desc
*
desc
,
const
char
*
filename
)
{
int
fd
;
unsigned
char
hdr
[
4
];
unsigned
char
buf
[
1024
];
ssize_t
res
;
unsigned
addr
;
fd
=
open
(
filename
,
O_RDONLY
);
if
(
fd
<
0
)
{
fprintf
(
stderr
,
"cannot open %s
\n
"
,
filename
);
return
-
1
;
}
res
=
read
(
fd
,
hdr
,
sizeof
(
hdr
));
if
(
res
!=
sizeof
(
hdr
))
{
fprintf
(
stderr
,
"cannot read %s
\n
"
,
filename
);
goto
err_close
;
}
if
(
hdr
[
0
]
==
0x7f
&&
hdr
[
1
]
==
'E'
&&
hdr
[
2
]
==
'L'
&&
hdr
[
3
]
==
'F'
)
{
fprintf
(
stderr
,
"ELF file %s not yet handled
\n
"
,
filename
);
goto
err_close
;
}
addr
=
0
;
wrc_write_buf
(
desc
,
hdr
,
sizeof
(
hdr
),
addr
);
addr
+=
sizeof
(
hdr
);
while
(
1
)
{
res
=
read
(
fd
,
buf
,
sizeof
(
buf
));
if
(
res
<=
0
)
break
;
wrc_write_buf
(
desc
,
buf
,
res
,
addr
);
addr
+=
res
;
}
printf
(
"%u KB written
\n
"
,
addr
/
1024
);
close
(
fd
);
return
0
;
err_close:
close
(
fd
);
return
-
1
;
}
static
int
wrc_save_firmware
(
struct
mapping_desc
*
desc
,
const
char
*
filename
)
{
int
fd
;
unsigned
length
=
0x20000
;
unsigned
char
buf
[
1024
];
ssize_t
res
;
unsigned
addr
;
fd
=
open
(
filename
,
O_WRONLY
);
if
(
fd
<
0
)
{
fprintf
(
stderr
,
"cannot open %s
\n
"
,
filename
);
return
-
1
;
}
for
(
addr
=
0
;
addr
<
length
;)
{
unsigned
l
=
length
-
addr
;
unsigned
off
;
if
(
l
>
sizeof
(
buf
))
l
=
sizeof
(
buf
);
for
(
off
=
0
;
off
<
l
;
off
+=
4
)
{
unsigned
int
v
;
wrc_write_uaddr
(
desc
,
addr
);
v
=
wrc_readl
(
desc
,
0xb00
+
WRC_CPU_CSR_REG_UDATA
);
/* Use BE */
buf
[
off
+
0
]
=
v
>>
24
;
buf
[
off
+
1
]
=
v
>>
16
;
buf
[
off
+
2
]
=
v
>>
8
;
buf
[
off
+
3
]
=
v
>>
0
;
addr
+=
4
;
}
res
=
write
(
fd
,
buf
,
l
);
if
(
res
!=
l
)
{
fprintf
(
stderr
,
"write failure
\n
"
);
close
(
fd
);
return
-
1
;
}
}
printf
(
"%u KB written to %s
\n
"
,
length
/
1024
,
filename
);
close
(
fd
);
return
0
;
}
static
void
wrc_dump
(
struct
mapping_desc
*
desc
,
unsigned
addr
,
unsigned
len
)
{
unsigned
off
;
off
=
0
;
for
(
off
=
0
;
off
<
len
;
off
+=
4
)
{
uint32_t
v
;
if
((
off
&
0x0f
)
==
0
)
printf
(
"%08x:"
,
addr
+
off
);
wrc_write_uaddr
(
desc
,
addr
+
off
);
v
=
wrc_readl
(
desc
,
0xb00
+
WRC_CPU_CSR_REG_UDATA
);
printf
(
" %08x"
,
v
);
if
((
off
&
0x0f
)
==
0xc
)
printf
(
"
\n
"
);
}
if
((
off
&
0x0f
)
!=
0xc
)
printf
(
"
\n
"
);
}
static
void
wrpc_load_help
(
char
*
prog
)
{
const
char
*
mapping_help_str
;
mapping_help_str
=
dev_mapping_help
();
fprintf
(
stderr
,
"%s [-v] [-h] [-s] filename
\n
"
,
prog
);
fprintf
(
stderr
,
"%s
\n
"
,
mapping_help_str
);
fprintf
(
stderr
,
"(offset should be 0, address is the wrpc registers base)
\n
"
);
fprintf
(
stderr
,
"Only for risc-v
\n
"
);
fprintf
(
stderr
,
"Use -s to save memory to a file
\n
"
);
}
int
main
(
int
argc
,
char
*
argv
[])
{
int
c
;
const
char
*
filename
;
struct
mapping_args
*
map_args
;
struct
mapping_desc
*
mdesc
=
NULL
;
enum
{
CMD_LOAD
,
CMD_DUMP
,
CMD_SAVE
}
cmd
;
map_args
=
dev_parse_mapping_args
(
&
argc
,
argv
);
if
(
!
map_args
)
{
wrpc_load_help
(
argv
[
0
]);
return
1
;
}
cmd
=
CMD_LOAD
;
while
((
c
=
getopt
(
argc
,
argv
,
"h:vds"
))
!=
-
1
)
{
switch
(
c
)
{
case
'h'
:
case
'?'
:
wrpc_load_help
(
argv
[
0
]);
exit
(
EXIT_SUCCESS
);
break
;
case
'd'
:
cmd
=
CMD_DUMP
;
break
;
case
's'
:
cmd
=
CMD_SAVE
;
break
;
case
'v'
:
verbose
++
;
break
;
}
}
if
(((
cmd
==
CMD_LOAD
||
cmd
==
CMD_SAVE
)
&&
(
optind
!=
argc
-
1
))
||
(
cmd
==
CMD_DUMP
&&
optind
!=
argc
))
{
wrpc_load_help
(
argv
[
0
]);
return
2
;
}
filename
=
argv
[
optind
];
mdesc
=
dev_map
(
map_args
,
getpagesize
());
if
(
!
mdesc
)
{
fprintf
(
stderr
,
"%s: failed to map: %s
\n
"
,
argv
[
0
],
strerror
(
errno
));
return
1
;
}
/* Reset */
wrc_cpu_reset
(
mdesc
,
1
<<
0
);
switch
(
cmd
)
{
case
CMD_LOAD
:
/* Load */
wrc_load_firmware
(
mdesc
,
filename
);
break
;
case
CMD_SAVE
:
/* Save */
wrc_save_firmware
(
mdesc
,
filename
);
break
;
case
CMD_DUMP
:
/* TODO: specify offset and length */
wrc_dump
(
mdesc
,
0
,
0x200
);
break
;
}
/* Start */
wrc_cpu_reset
(
mdesc
,
0
);
return
0
;
}
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