Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ycai
simbricks
Commits
c0cfa6df
Commit
c0cfa6df
authored
Jun 09, 2020
by
Antoine Kaufmann
Browse files
add ethernet protocol
parent
48328bbb
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
337 additions
and
29 deletions
+337
-29
corundum/corundum_verilator.cpp
corundum/corundum_verilator.cpp
+1
-1
dummy_nic/dummy_nic.c
dummy_nic/dummy_nic.c
+1
-1
nicsim_common/include/nicsim.h
nicsim_common/include/nicsim.h
+11
-1
nicsim_common/nicsim.c
nicsim_common/nicsim.c
+200
-26
proto/cosim_eth_proto.h
proto/cosim_eth_proto.h
+124
-0
No files found.
corundum/corundum_verilator.cpp
View file @
c0cfa6df
...
@@ -610,7 +610,7 @@ int main(int argc, char *argv[])
...
@@ -610,7 +610,7 @@ int main(int argc, char *argv[])
di
.
pci_revision
=
0x00
;
di
.
pci_revision
=
0x00
;
di
.
pci_msi_nvecs
=
32
;
di
.
pci_msi_nvecs
=
32
;
if
(
nicsim_init
(
&
di
,
"/tmp/cosim-pci"
,
"/dev/shm/dummy_nic_shm"
))
{
if
(
nicsim_init
(
&
di
,
"/tmp/cosim-pci"
,
NULL
,
"/dev/shm/dummy_nic_shm"
))
{
return
EXIT_FAILURE
;
return
EXIT_FAILURE
;
}
}
...
...
dummy_nic/dummy_nic.c
View file @
c0cfa6df
...
@@ -126,7 +126,7 @@ int main(int argc, char *argv[])
...
@@ -126,7 +126,7 @@ int main(int argc, char *argv[])
di
.
pci_revision
=
0x00
;
di
.
pci_revision
=
0x00
;
di
.
pci_msi_nvecs
=
0x00
;
di
.
pci_msi_nvecs
=
0x00
;
if
(
nicsim_init
(
&
di
,
"/tmp/cosim-pci"
,
"/dev/shm/dummy_nic_shm"
))
{
if
(
nicsim_init
(
&
di
,
"/tmp/cosim-pci"
,
NULL
,
"/dev/shm/dummy_nic_shm"
))
{
return
EXIT_FAILURE
;
return
EXIT_FAILURE
;
}
}
...
...
nicsim_common/include/nicsim.h
View file @
c0cfa6df
...
@@ -25,15 +25,25 @@
...
@@ -25,15 +25,25 @@
#define COSIM_NICSIM_H_
#define COSIM_NICSIM_H_
#include <cosim_pcie_proto.h>
#include <cosim_pcie_proto.h>
#include <cosim_eth_proto.h>
int
nicsim_init
(
struct
cosim_pcie_proto_dev_intro
*
di
,
int
nicsim_init
(
struct
cosim_pcie_proto_dev_intro
*
di
,
const
char
*
uxsocket_path
,
const
char
*
shm_path
);
const
char
*
pci_socket_path
,
const
char
*
eth_socket_path
,
const
char
*
shm_path
);
void
nicsim_cleanup
(
void
);
void
nicsim_cleanup
(
void
);
volatile
union
cosim_pcie_proto_h2d
*
nicif_h2d_poll
(
void
);
volatile
union
cosim_pcie_proto_h2d
*
nicif_h2d_poll
(
void
);
void
nicif_h2d_done
(
volatile
union
cosim_pcie_proto_h2d
*
msg
);
void
nicif_h2d_done
(
volatile
union
cosim_pcie_proto_h2d
*
msg
);
void
nicif_h2d_next
(
void
);
void
nicif_h2d_next
(
void
);
volatile
union
cosim_pcie_proto_d2h
*
nicsim_d2h_alloc
(
void
);
volatile
union
cosim_pcie_proto_d2h
*
nicsim_d2h_alloc
(
void
);
volatile
union
cosim_eth_proto_n2d
*
nicif_n2d_poll
(
void
);
void
nicif_n2d_done
(
volatile
union
cosim_eth_proto_n2d
*
msg
);
void
nicif_n2d_next
(
void
);
volatile
union
cosim_eth_proto_d2n
*
nicsim_d2n_alloc
(
void
);
#endif
/* ndef COSIM_NICSIM_H_ */
#endif
/* ndef COSIM_NICSIM_H_ */
nicsim_common/nicsim.c
View file @
c0cfa6df
...
@@ -25,6 +25,7 @@
...
@@ -25,6 +25,7 @@
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/socket.h>
#include <poll.h>
#include <unistd.h>
#include <unistd.h>
#include <nicsim.h>
#include <nicsim.h>
...
@@ -37,63 +38,189 @@
...
@@ -37,63 +38,189 @@
#define H2D_ELEN (4096 + 64)
#define H2D_ELEN (4096 + 64)
#define H2D_ENUM 1024
#define H2D_ENUM 1024
#define D2N_ELEN (2048 + 64)
#define D2N_ENUM 1024
#define N2D_ELEN (2048 + 64)
#define N2D_ENUM 1024
static
uint8_t
*
d2h_queue
;
static
uint8_t
*
d2h_queue
;
static
size_t
d2h_pos
;
static
size_t
d2h_pos
;
static
size_t
d2h_off
;
/* offset in shm region */
static
uint8_t
*
h2d_queue
;
static
uint8_t
*
h2d_queue
;
static
size_t
h2d_pos
;
static
size_t
h2d_pos
;
static
size_t
h2d_off
;
/* offset in shm region */
static
uint8_t
*
d2n_queue
;
static
size_t
d2n_pos
;
static
size_t
d2n_off
;
/* offset in shm region */
static
uint8_t
*
n2d_queue
;
static
size_t
n2d_pos
;
static
size_t
n2d_off
;
/* offset in shm region */
static
int
shm_fd
=
-
1
;
static
int
pci_cfd
=
-
1
;
static
int
pci_cfd
=
-
1
;
static
int
eth_cfd
=
-
1
;
int
nicsim_init
(
struct
cosim_pcie_proto_dev_intro
*
di
,
static
int
accept_pci
(
struct
cosim_pcie_proto_dev_intro
*
di
,
int
pci_lfd
)
const
char
*
uxsocket_path
,
const
char
*
shm_path
)
{
{
int
shm_fd
,
pci_lfd
;
if
((
pci_cfd
=
accept
(
pci_lfd
,
NULL
,
NULL
))
<
0
)
{
size_t
d2h_off
,
h2d_off
;
return
-
1
;
void
*
shmptr
;
}
close
(
pci_lfd
);
printf
(
"pci connection accepted
\n
"
);
if
((
shm_fd
=
shm_create
(
shm_path
,
32
*
1024
*
1024
,
&
shmptr
))
<
0
)
{
di
->
d2h_offset
=
d2h_off
;
di
->
d2h_elen
=
D2H_ELEN
;
di
->
d2h_nentries
=
D2H_ENUM
;
di
->
h2d_offset
=
h2d_off
;
di
->
h2d_elen
=
H2D_ELEN
;
di
->
h2d_nentries
=
H2D_ENUM
;
if
(
uxsocket_send
(
pci_cfd
,
di
,
sizeof
(
*
di
),
shm_fd
))
{
return
-
1
;
return
-
1
;
}
}
printf
(
"pci intro sent
\n
"
);
return
0
;
}
static
int
accept_eth
(
int
eth_lfd
)
{
struct
cosim_eth_proto_dev_intro
di
;
if
((
pci_lfd
=
uxsocket_init
(
uxsocket_path
))
<
0
)
{
if
((
eth_cfd
=
accept
(
eth_lfd
,
NULL
,
NULL
))
<
0
)
{
return
-
1
;
return
-
1
;
}
}
close
(
eth_lfd
);
printf
(
"eth connection accepted
\n
"
);
memset
(
&
di
,
0
,
sizeof
(
di
));
di
.
flags
=
0
;
di
.
d2n_offset
=
d2n_off
;
di
.
d2n_elen
=
D2N_ELEN
;
di
.
d2n_nentries
=
D2N_ENUM
;
if
((
pci_cfd
=
accept
(
pci_lfd
,
NULL
,
NULL
))
<
0
)
{
di
.
n2d_offset
=
n2d_off
;
di
.
n2d_elen
=
N2D_ELEN
;
di
.
n2d_nentries
=
N2D_ENUM
;
if
(
uxsocket_send
(
eth_cfd
,
&
di
,
sizeof
(
di
),
shm_fd
))
{
return
-
1
;
}
printf
(
"eth intro sent
\n
"
);
return
0
;
}
static
int
accept_conns
(
struct
cosim_pcie_proto_dev_intro
*
di
,
int
pci_lfd
,
int
eth_lfd
)
{
struct
pollfd
pfds
[
2
];
int
await_pci
=
pci_lfd
!=
-
1
;
int
await_eth
=
eth_lfd
!=
-
1
;
int
ret
;
while
(
await_pci
||
await_eth
)
{
if
(
await_pci
&&
await_eth
)
{
/* we're waiting on both fds */
pfds
[
0
].
fd
=
pci_lfd
;
pfds
[
1
].
fd
=
eth_lfd
;
pfds
[
0
].
events
=
pfds
[
1
].
events
=
POLLIN
;
pfds
[
0
].
revents
=
pfds
[
1
].
revents
=
0
;
ret
=
poll
(
pfds
,
2
,
-
1
);
if
(
ret
<
0
)
{
perror
(
"poll failed"
);
return
-
1
;
}
if
(
pfds
[
0
].
revents
)
{
if
(
accept_pci
(
di
,
pci_lfd
)
!=
0
)
return
-
1
;
await_pci
=
0
;
}
if
(
pfds
[
1
].
revents
)
{
if
(
accept_eth
(
pci_lfd
)
!=
0
)
return
-
1
;
await_eth
=
0
;
}
}
else
if
(
await_pci
)
{
/* waiting just on pci */
if
(
accept_pci
(
di
,
pci_lfd
)
!=
0
)
return
-
1
;
await_pci
=
0
;
}
else
{
/* waiting just on ethernet */
if
(
accept_eth
(
eth_lfd
)
!=
0
)
return
-
1
;
await_eth
=
0
;
}
}
return
0
;
}
int
nicsim_init
(
struct
cosim_pcie_proto_dev_intro
*
di
,
const
char
*
pci_socket_path
,
const
char
*
eth_socket_path
,
const
char
*
shm_path
)
{
int
pci_lfd
=
-
1
,
eth_lfd
=
-
1
;
void
*
shmptr
;
/* ready in memory queues */
if
((
shm_fd
=
shm_create
(
shm_path
,
32
*
1024
*
1024
,
&
shmptr
))
<
0
)
{
return
-
1
;
return
-
1
;
}
}
close
(
pci_lfd
);
printf
(
"connection accepted
\n
"
);
d2h_off
=
0
;
d2h_off
=
0
;
h2d_off
=
(
uint64_t
)
D2H_ELEN
*
D2H_ENUM
;
h2d_off
=
d2h_off
+
(
uint64_t
)
D2H_ELEN
*
D2H_ENUM
;
d2n_off
=
h2d_off
+
(
uint64_t
)
H2D_ELEN
*
H2D_ENUM
;
n2d_off
=
d2n_off
+
(
uint64_t
)
D2N_ELEN
*
D2N_ENUM
;
d2h_queue
=
(
uint8_t
*
)
shmptr
+
d2h_off
;
d2h_queue
=
(
uint8_t
*
)
shmptr
+
d2h_off
;
h2d_queue
=
(
uint8_t
*
)
shmptr
+
h2d_off
;
h2d_queue
=
(
uint8_t
*
)
shmptr
+
h2d_off
;
d2n_queue
=
(
uint8_t
*
)
shmptr
+
d2n_off
;
n2d_queue
=
(
uint8_t
*
)
shmptr
+
n2d_off
;
d2h_pos
=
h2d_pos
=
0
;
d2h_pos
=
h2d_pos
=
d2n_pos
=
n2d_pos
=
0
;
di
->
d2h_offset
=
d2h_off
;
di
->
d2h_elen
=
D2H_ELEN
;
di
->
d2h_nentries
=
D2H_ENUM
;
di
->
h2d_offset
=
h2d_off
;
/* get listening sockets ready */
di
->
h2d_elen
=
H2D_ELEN
;
if
(
pci_socket_path
!=
NULL
)
{
di
->
h2d_nentries
=
H2D_ENUM
;
if
((
pci_lfd
=
uxsocket_init
(
pci_socket_path
))
<
0
)
{
return
-
1
;
}
}
if
(
eth_socket_path
!=
NULL
)
{
if
((
eth_lfd
=
uxsocket_init
(
eth_socket_path
))
<
0
)
{
return
-
1
;
}
}
if
(
uxsocket_send
(
pci_cfd
,
di
,
sizeof
(
*
di
),
shm_fd
))
{
/* accept connection fds */
if
(
accept_conns
(
di
,
pci_lfd
,
eth_lfd
)
!=
0
)
{
return
-
1
;
return
-
1
;
}
}
printf
(
"connection sent
\n
"
);
/* receive introductions from other end */
struct
cosim_pcie_proto_host_intro
hi
;
if
(
pci_socket_path
!=
NULL
)
{
if
(
recv
(
pci_cfd
,
&
hi
,
sizeof
(
hi
),
0
)
!=
sizeof
(
hi
))
{
struct
cosim_pcie_proto_host_intro
hi
;
return
-
1
;
if
(
recv
(
pci_cfd
,
&
hi
,
sizeof
(
hi
),
0
)
!=
sizeof
(
hi
))
{
return
-
1
;
}
printf
(
"pci host info received
\n
"
);
}
if
(
eth_socket_path
!=
NULL
)
{
struct
cosim_eth_proto_net_intro
ni
;
if
(
recv
(
eth_cfd
,
&
ni
,
sizeof
(
ni
),
0
)
!=
sizeof
(
ni
))
{
return
-
1
;
}
printf
(
"eth net info received
\n
"
);
}
}
printf
(
"host info received
\n
"
);
return
0
;
return
0
;
}
}
...
@@ -101,8 +228,12 @@ int nicsim_init(struct cosim_pcie_proto_dev_intro *di,
...
@@ -101,8 +228,12 @@ int nicsim_init(struct cosim_pcie_proto_dev_intro *di,
void
nicsim_cleanup
(
void
)
void
nicsim_cleanup
(
void
)
{
{
close
(
pci_cfd
);
close
(
pci_cfd
);
close
(
eth_cfd
);
}
}
/******************************************************************************/
/* PCI */
volatile
union
cosim_pcie_proto_h2d
*
nicif_h2d_poll
(
void
)
volatile
union
cosim_pcie_proto_h2d
*
nicif_h2d_poll
(
void
)
{
{
volatile
union
cosim_pcie_proto_h2d
*
msg
=
volatile
union
cosim_pcie_proto_h2d
*
msg
=
...
@@ -144,3 +275,46 @@ volatile union cosim_pcie_proto_d2h *nicsim_d2h_alloc(void)
...
@@ -144,3 +275,46 @@ volatile union cosim_pcie_proto_d2h *nicsim_d2h_alloc(void)
return
msg
;
return
msg
;
}
}
/******************************************************************************/
/* Ethernet */
volatile
union
cosim_eth_proto_n2d
*
nicif_n2d_poll
(
void
)
{
volatile
union
cosim_eth_proto_n2d
*
msg
=
(
volatile
union
cosim_eth_proto_n2d
*
)
(
n2d_queue
+
n2d_pos
*
N2D_ELEN
);
/* message not ready */
if
((
msg
->
dummy
.
own_type
&
COSIM_ETH_PROTO_N2D_OWN_MASK
)
!=
COSIM_ETH_PROTO_N2D_OWN_DEV
)
return
NULL
;
return
msg
;
}
void
nicif_n2d_done
(
volatile
union
cosim_eth_proto_n2d
*
msg
)
{
msg
->
dummy
.
own_type
=
(
msg
->
dummy
.
own_type
&
COSIM_ETH_PROTO_N2D_MSG_MASK
)
|
COSIM_ETH_PROTO_N2D_OWN_NET
;
}
void
nicif_n2d_next
(
void
)
{
n2d_pos
=
(
n2d_pos
+
1
)
%
N2D_ENUM
;
}
volatile
union
cosim_eth_proto_d2n
*
nicsim_d2n_alloc
(
void
)
{
volatile
union
cosim_eth_proto_d2n
*
msg
=
(
volatile
union
cosim_eth_proto_d2n
*
)
(
d2n_queue
+
d2n_pos
*
D2N_ELEN
);
if
((
msg
->
dummy
.
own_type
&
COSIM_ETH_PROTO_D2N_OWN_MASK
)
!=
COSIM_ETH_PROTO_D2N_OWN_DEV
)
{
return
NULL
;
}
d2n_pos
=
(
d2n_pos
+
1
)
%
D2N_ENUM
;
return
msg
;
}
proto/cosim_eth_proto.h
0 → 100644
View file @
c0cfa6df
#ifndef COSIM_ETH_PROTO_H_
#define COSIM_ETH_PROTO_H_
#include <stdint.h>
/******************************************************************************/
/* Initialization messages on Unix socket */
/** in dev_intro.flags to indicate that sender supports issuing syncs. */
#define COSIM_ETH_PROTO_FLAGS_DI_SYNC (1 << 0)
/**
* welcome message sent by device to network. This message comes with the shared
* memory file descriptor attached.
*/
struct
cosim_eth_proto_dev_intro
{
/** flags: see COSIM_ETH_PROTO_FLAGS_DI_* */
uint64_t
flags
;
/** offset of the device-to-network queue in shared memory region */
uint64_t
d2n_offset
;
/** size of an entry in the device-to-network queue in bytes */
uint64_t
d2n_elen
;
/** total device-to-network queue length in #entries */
uint64_t
d2n_nentries
;
/** offset of the net-to-device queue in shared memory region */
uint64_t
n2d_offset
;
/** size of an entry in the net-to-device queue in bytes */
uint64_t
n2d_elen
;
/** total net-to-device queue length in #entries */
uint64_t
n2d_nentries
;
}
__attribute__
((
packed
));
#define COSIM_ETH_PROTO_FLAGS_IN_SYNC (1 << 0)
/** welcome message sent by network to device */
struct
cosim_eth_proto_net_intro
{
/** flags: see COSIM_ETH_PROTO_FLAGS_IN_* */
uint64_t
flags
;
}
__attribute__
((
packed
));
/******************************************************************************/
/* Messages on in-memory device to network channel */
/** Mask for ownership bit in own_type field */
#define COSIM_ETH_PROTO_D2N_OWN_MASK 0x80
/** Message is owned by device */
#define COSIM_ETH_PROTO_D2N_OWN_DEV 0x00
/** Message is owned by network */
#define COSIM_ETH_PROTO_D2N_OWN_NET 0x80
/** Mask for type value in own_type field */
#define COSIM_ETH_PROTO_D2N_MSG_MASK 0x7f
#define COSIM_ETH_PROTO_D2N_MSG_SYNC 0x1
#define COSIM_ETH_PROTO_D2N_MSG_SEND 0x2
struct
cosim_eth_proto_d2n_dummy
{
uint8_t
pad
[
63
];
uint8_t
own_type
;
}
__attribute__
((
packed
));
struct
cosim_eth_proto_d2n_sync
{
uint64_t
timestamp
;
uint8_t
pad
[
55
];
uint8_t
own_type
;
}
__attribute__
((
packed
));
struct
cosim_eth_proto_d2n_send
{
uint16_t
len
;
uint8_t
port
;
uint8_t
pad
[
60
];
uint8_t
own_type
;
uint8_t
data
[];
}
__attribute__
((
packed
));
union
cosim_eth_proto_d2n
{
struct
cosim_eth_proto_d2n_dummy
dummy
;
struct
cosim_eth_proto_d2n_sync
sync
;
struct
cosim_eth_proto_d2n_send
send
;
};
/******************************************************************************/
/* Messages on in-memory network to device channel */
#define COSIM_ETH_PROTO_N2D_OWN_MASK 0x80
/** Message is owned by host */
#define COSIM_ETH_PROTO_N2D_OWN_NET 0x00
/** Message is owned by device */
#define COSIM_ETH_PROTO_N2D_OWN_DEV 0x80
#define COSIM_ETH_PROTO_N2D_MSG_MASK 0x7f
#define COSIM_ETH_PROTO_N2D_MSG_SYNC 0x1
#define COSIM_ETH_PROTO_N2D_MSG_RECV 0x2
struct
cosim_eth_proto_n2d_dummy
{
uint8_t
pad
[
63
];
uint8_t
own_type
;
}
__attribute__
((
packed
));
struct
cosim_eth_proto_n2d_sync
{
uint64_t
timestamp
;
uint8_t
pad
[
55
];
uint8_t
own_type
;
}
__attribute__
((
packed
));
struct
cosim_eth_proto_n2d_recv
{
uint16_t
len
;
uint8_t
port
;
uint8_t
pad
[
60
];
uint8_t
own_type
;
uint8_t
data
[];
};
union
cosim_eth_proto_n2d
{
struct
cosim_eth_proto_n2d_dummy
dummy
;
struct
cosim_eth_proto_n2d_sync
sync
;
struct
cosim_eth_proto_n2d_recv
recv
;
};
#endif
/* ndef COSIM_ETH_PROTO_H_ */
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