Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
S
Simple PCIe FMC carrier SPEC - Software
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
3
Issues
3
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
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
Simple PCIe FMC carrier SPEC - Software
Commits
2a2d523f
Commit
2a2d523f
authored
Mar 11, 2022
by
Adam Wujek
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
tools/spec-cl: add support of uRV/RISCV
Signed-off-by:
Adam Wujek
<
dev_public@wujek.eu
>
parent
f22fff86
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
177 additions
and
9 deletions
+177
-9
spec-cl.c
tools/spec-cl.c
+72
-9
speclib.c
tools/speclib.c
+98
-0
speclib.h
tools/speclib.h
+7
-0
No files found.
tools/spec-cl.c
View file @
2a2d523f
/*
* A tool to program our soft-core (LM32) within the SPEC.
* A tool to program our soft-core (
uRV and
LM32) within the SPEC.
*/
#include <stdio.h>
...
...
@@ -17,14 +17,25 @@ static void print_version(char *pname)
printf
(
"%s
\n
"
,
libspec_version_s
);
}
enum
cpu_type
{
unknown
=
0
,
lm32
,
riscv
};
int
main
(
int
argc
,
char
**
argv
)
{
int
bus
=
-
1
,
dev_fn
=
-
1
,
c
;
uint32_t
lm32_base
=
0x80000
;
uint32_t
urv_csr_base
=
0x80000
;
uint32_t
cpu_base
=
0x0
;
enum
cpu_type
cpu_type
=
lm32
;
/* make it backward compatible */
void
*
card
;
int
read_mode
=
0
;
size_t
read_size
=
0
;
while
((
c
=
getopt
(
argc
,
argv
,
"b:d:c:V"
))
!=
-
1
)
while
((
c
=
getopt
(
argc
,
argv
,
"b:d:c:
ilrs:
V"
))
!=
-
1
)
{
switch
(
c
)
{
...
...
@@ -35,7 +46,22 @@ int main(int argc, char **argv)
sscanf
(
optarg
,
"%i"
,
&
dev_fn
);
break
;
case
'c'
:
sscanf
(
optarg
,
"%i"
,
&
lm32_base
);
sscanf
(
optarg
,
"%i"
,
&
cpu_base
);
break
;
case
'i'
:
/* RISCV mode */
cpu_type
=
riscv
;
break
;
case
'l'
:
/* LM32 mode */
cpu_type
=
lm32
;
break
;
case
'r'
:
read_mode
=
1
;
break
;
case
's'
:
/* read size */
sscanf
(
optarg
,
"%li"
,
&
read_size
);
break
;
case
'V'
:
print_version
(
argv
[
0
]);
...
...
@@ -43,16 +69,35 @@ int main(int argc, char **argv)
default:
fprintf
(
stderr
,
"Use:
\"
%s [-V] [-b bus] [-d devfn] "
"[-c lm32 base address] <lm32_program.bin>
\"\n
"
,
"[-c <base address>] [-l|-s] "
"<program.bin>
\"\n
"
"-l - load into LM32 memory (default)
\n
"
"-i - load into uRV(RISCV)
\n
"
"-r - read memory from uRV(RISCV) into a file <program.bin>
\n
"
" NOTE: It will trigger the restart of the uRV core after the read!
\n
"
"-s <size>
\n
"
,
argv
[
0
]);
fprintf
(
stderr
,
"%s loads the binary into LM32 or uRV(RISCV) "
"memory
\n
"
"By default, the first available SPEC is used "
"and the LM32 is assumed at 0x%x.
\n
"
,
lm32_base
);
"and the LM32 mode is assumed. The default "
"load address for the LM32 is 0x%x, for the "
"uRV CPU CSR is 0x%x.
\n
"
,
argv
[
0
],
lm32_base
,
urv_csr_base
);
exit
(
1
);
}
}
if
(
!
cpu_base
)
{
/* Custom address not specified, use the default
* depending on the CPU type */
if
(
cpu_type
==
lm32
)
cpu_base
=
lm32_base
;
if
(
cpu_type
==
riscv
)
cpu_base
=
urv_csr_base
;
}
if
(
optind
>=
argc
)
{
fprintf
(
stderr
,
"%s: Expected binary name after options.
\n
"
,
argv
[
0
]);
...
...
@@ -68,9 +113,27 @@ int main(int argc, char **argv)
exit
(
1
);
}
if
(
spec_load_lm32
(
card
,
argv
[
optind
],
lm32_base
)
<
0
)
{
fprintf
(
stderr
,
"%s: Loader failure.
\n
"
,
argv
[
0
]);
if
(
read_mode
)
{
if
(
cpu_type
!=
riscv
)
{
fprintf
(
stderr
,
"%s: read of memory (-r parameter) can"
" be used only for RISCV architecture. "
"Exiting...
\n
"
,
argv
[
0
]);
exit
(
0
);
}
spec_dump_urv_mem
(
card
,
argv
[
optind
],
urv_csr_base
,
read_size
);
exit
(
0
);
}
if
(
cpu_type
==
lm32
&&
spec_load_lm32
(
card
,
argv
[
optind
],
urv_csr_base
)
<
0
)
{
fprintf
(
stderr
,
"%s: LM32 Loader failure.
\n
"
,
argv
[
0
]);
exit
(
1
);
}
if
(
cpu_type
==
riscv
&&
spec_load_urv
(
card
,
argv
[
optind
],
urv_csr_base
)
<
0
)
{
fprintf
(
stderr
,
"%s: RISCV Loader failure.
\n
"
,
argv
[
0
]);
exit
(
1
);
}
...
...
tools/speclib.c
View file @
2a2d523f
...
...
@@ -19,6 +19,10 @@
#include "loader-ll.h"
#include "wb_uart.h"
#define WRC_CPU_CSR_RESET 0x20900
#define WRC_CPU_CSR_UADDR 0x20904
#define WRC_CPU_CSR_UDATA 0x20908
const
char
*
const
libspec_version_s
=
"libspec version: "
GIT_VERSION
;
struct
spec_private
{
...
...
@@ -414,6 +418,100 @@ int spec_load_lm32(void *card, const char *filename, uint32_t base_addr)
return
0
;
}
int
spec_load_urv
(
void
*
card
,
const
char
*
filename
,
uint32_t
base_addr
)
{
char
*
buf
;
uint32_t
*
ibuf
;
size_t
size
;
int
i
;
buf
=
load_binary_file
(
filename
,
&
size
);
if
(
!
buf
)
return
-
1
;
/* Phew... we are there, finally */
spec_writel
(
card
,
0x1deadbee
,
base_addr
+
0x20400
);
while
(
!
(
spec_readl
(
card
,
base_addr
+
0x20400
)
&
(
1
<<
28
))
);
spec_writel
(
card
,
1
,
base_addr
+
WRC_CPU_CSR_RESET
);
ibuf
=
(
uint32_t
*
)
buf
;
for
(
i
=
0
;
i
<
(
size
+
3
)
/
4
;
i
++
)
{
spec_writel
(
card
,
i
,
base_addr
+
WRC_CPU_CSR_UADDR
);
spec_writel
(
card
,
htonl
(
ibuf
[
i
]),
base_addr
+
WRC_CPU_CSR_UDATA
);
}
sync
();
for
(
i
=
0
;
i
<
(
size
+
3
)
/
4
;
i
++
)
{
spec_writel
(
card
,
i
,
base_addr
+
WRC_CPU_CSR_UADDR
);
uint32_t
r
=
spec_readl
(
card
,
base_addr
+
WRC_CPU_CSR_UDATA
);
if
(
r
!=
htonl
(
ibuf
[
i
]))
{
fprintf
(
stderr
,
"programming error at %x "
"(expected %08x, found %08x)
\n
"
,
i
*
4
,
htonl
(
ibuf
[
i
]),
r
);
return
-
1
;
}
}
sync
();
spec_writel
(
card
,
0x0deadbee
,
base_addr
+
0x20400
);
spec_writel
(
card
,
0
,
base_addr
+
WRC_CPU_CSR_RESET
);
return
0
;
}
int
spec_dump_urv_mem
(
void
*
card
,
const
char
*
filename
,
uint32_t
base_addr
,
size_t
size
)
{
size_t
def_size
=
192
*
1024
;
int
i
,
tmp
;
uint32_t
r
;
FILE
*
f
;
if
(
!
size
)
size
=
def_size
;
f
=
fopen
(
filename
,
"w"
);
if
(
!
f
)
{
fprintf
(
stderr
,
"%s: %s
\n
"
,
filename
,
strerror
(
errno
));
return
-
1
;
}
spec_writel
(
card
,
0x1deadbee
,
base_addr
+
0x20400
);
while
(
!
(
spec_readl
(
card
,
base_addr
+
0x20400
)
&
(
1
<<
28
))
);
spec_writel
(
card
,
1
,
base_addr
+
WRC_CPU_CSR_RESET
);
for
(
i
=
0
;
i
<
(
size
+
3
)
/
4
;
i
++
)
{
spec_writel
(
card
,
i
,
base_addr
+
WRC_CPU_CSR_UADDR
);
r
=
spec_readl
(
card
,
base_addr
+
WRC_CPU_CSR_UDATA
);
/* Change the endianness to reflect the same byte order as
* written binary into memory */
r
=
ntohl
(
r
);
tmp
=
fwrite
(
&
r
,
1
,
sizeof
(
r
),
f
);
if
(
tmp
<
0
)
{
fprintf
(
stderr
,
"writing %s: %s
\n
"
,
filename
,
strerror
(
errno
));
return
-
1
;
}
}
sync
();
spec_writel
(
card
,
0x0deadbee
,
base_addr
+
0x20400
);
spec_writel
(
card
,
0
,
base_addr
+
WRC_CPU_CSR_RESET
);
fclose
(
f
);
printf
(
"0x%lx bytes written to the file %s
\n
"
,
size
,
filename
);
return
0
;
}
int
spec_vuart_init
(
void
*
card
,
uint32_t
base_addr
)
{
struct
spec_private
*
p
=
(
struct
spec_private
*
)
card
;
...
...
tools/speclib.h
View file @
2a2d523f
...
...
@@ -39,6 +39,13 @@ int spec_load_bitstream_buffer(void *card, void *buf, size_t size);
WARNING: using improper base address/FPGA firmware will freeze the computer. */
int
spec_load_lm32
(
void
*
card
,
const
char
*
filename
,
uint32_t
base_addr
);
/* Loads the WRC RISCV firmware into card [card] from file [filename]. starting at
address [base_addr]. Returns 0 on success.
WARNING: using improper base address/FPGA firmware will freeze the computer. */
int
spec_load_urv
(
void
*
card
,
const
char
*
filename
,
uint32_t
base_addr
);
int
spec_dump_urv_mem
(
void
*
card
,
const
char
*
filename
,
uint32_t
base_addr
,
size_t
size
);
/* Raw I/O to BAR4 (Wishbone) */
void
spec_writel
(
void
*
card
,
uint32_t
data
,
uint32_t
addr
);
uint32_t
spec_readl
(
void
*
card
,
uint32_t
addr
);
...
...
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