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
d365cd9e
Commit
d365cd9e
authored
Jan 24, 2022
by
Antoine Kaufmann
Browse files
sims/nic/e1000_gem5: add e1000 model from gem5
parent
2ddf5f12
Changes
18
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
6401 additions
and
0 deletions
+6401
-0
sims/nic/e1000_gem5/e1000_gem5.cc
sims/nic/e1000_gem5/e1000_gem5.cc
+214
-0
sims/nic/e1000_gem5/gem5/bitfield.cc
sims/nic/e1000_gem5/gem5/bitfield.cc
+65
-0
sims/nic/e1000_gem5/gem5/bitfield.h
sims/nic/e1000_gem5/gem5/bitfield.h
+313
-0
sims/nic/e1000_gem5/gem5/eth.h
sims/nic/e1000_gem5/gem5/eth.h
+77
-0
sims/nic/e1000_gem5/gem5/inet.cc
sims/nic/e1000_gem5/gem5/inet.cc
+399
-0
sims/nic/e1000_gem5/gem5/inet.h
sims/nic/e1000_gem5/gem5/inet.h
+666
-0
sims/nic/e1000_gem5/gem5/ip.h
sims/nic/e1000_gem5/gem5/ip.h
+453
-0
sims/nic/e1000_gem5/gem5/ip6.h
sims/nic/e1000_gem5/gem5/ip6.h
+183
-0
sims/nic/e1000_gem5/gem5/pktfifo.cc
sims/nic/e1000_gem5/gem5/pktfifo.cc
+62
-0
sims/nic/e1000_gem5/gem5/pktfifo.h
sims/nic/e1000_gem5/gem5/pktfifo.h
+198
-0
sims/nic/e1000_gem5/gem5/tcp.h
sims/nic/e1000_gem5/gem5/tcp.h
+158
-0
sims/nic/e1000_gem5/gem5/udp.h
sims/nic/e1000_gem5/gem5/udp.h
+32
-0
sims/nic/e1000_gem5/i8254xGBe.cc
sims/nic/e1000_gem5/i8254xGBe.cc
+2205
-0
sims/nic/e1000_gem5/i8254xGBe.h
sims/nic/e1000_gem5/i8254xGBe.h
+521
-0
sims/nic/e1000_gem5/i8254xGBe_defs.h
sims/nic/e1000_gem5/i8254xGBe_defs.h
+756
-0
sims/nic/e1000_gem5/rules.mk
sims/nic/e1000_gem5/rules.mk
+34
-0
sims/nic/e1000_gem5/support.h
sims/nic/e1000_gem5/support.h
+64
-0
sims/nic/rules.mk
sims/nic/rules.mk
+1
-0
No files found.
sims/nic/e1000_gem5/e1000_gem5.cc
0 → 100644
View file @
d365cd9e
#include <iostream>
#include <stdarg.h>
#include <simbricks/nicbm/nicbm.h>
#include "sims/nic/e1000_gem5/i8254xGBe.h"
class
Gem5DMAOp
:
public
nicbm
::
DMAOp
,
public
nicbm
::
TimedEvent
{
public:
EventFunctionWrapper
&
ev_
;
Gem5DMAOp
(
EventFunctionWrapper
&
ev
)
:
ev_
(
ev
)
{}
virtual
~
Gem5DMAOp
()
=
default
;
};
/******************************************************************************/
/* nicbm callbacks */
void
IGbE
::
SetupIntro
(
struct
SimbricksProtoPcieDevIntro
&
di
)
{
di
.
bars
[
0
].
len
=
128
*
1024
;
di
.
bars
[
0
].
flags
=
SIMBRICKS_PROTO_PCIE_BAR_64
;
di
.
pci_vendor_id
=
0x8086
;
di
.
pci_device_id
=
0x1075
;
di
.
pci_class
=
0x02
;
di
.
pci_subclass
=
0x00
;
di
.
pci_revision
=
0x01
;
}
void
IGbE
::
RegRead
(
uint8_t
bar
,
uint64_t
addr
,
void
*
dest
,
size_t
len
)
{
read
(
addr
,
len
,
dest
);
// TODO delay!
}
void
IGbE
::
RegWrite
(
uint8_t
bar
,
uint64_t
addr
,
const
void
*
src
,
size_t
len
)
{
write
(
addr
,
len
,
src
);
// TODO delay!
}
void
IGbE
::
DmaComplete
(
nicbm
::
DMAOp
&
op
)
{
Gem5DMAOp
*
dma
=
dynamic_cast
<
Gem5DMAOp
*>
(
&
op
);
dma
->
ev_
.
sched
=
false
;
dma
->
ev_
.
callback
();
if
(
dma
->
write_
)
delete
[]
((
uint8_t
*
)
dma
->
data_
);
delete
dma
;
}
void
IGbE
::
EthRx
(
uint8_t
port
,
const
void
*
data
,
size_t
len
)
{
EthPacketPtr
pp
=
std
::
make_shared
<
EthPacketData
>
(
len
);
pp
->
length
=
len
;
memcpy
(
pp
->
data
,
data
,
len
);
ethRxPkt
(
pp
);
}
void
IGbE
::
Timed
(
nicbm
::
TimedEvent
&
te
)
{
if
(
Gem5DMAOp
*
dma
=
dynamic_cast
<
Gem5DMAOp
*>
(
&
te
))
{
runner_
->
IssueDma
(
*
dma
);
}
else
if
(
EventFunctionWrapper
*
evw
=
dynamic_cast
<
EventFunctionWrapper
*>
(
&
te
))
{
evw
->
sched
=
false
;
evw
->
callback
();
}
else
{
abort
();
}
}
/******************************************************************************/
/* gem5-ish APIs */
void
IGbE
::
schedule
(
EventFunctionWrapper
&
ev
,
Tick
t
)
{
if
(
ev
.
sched
)
{
fprintf
(
stderr
,
"schedule: already scheduled
\n
"
);
abort
();
}
ev
.
time_
=
t
;
ev
.
sched
=
true
;
runner_
->
EventSchedule
(
ev
);
}
void
IGbE
::
reschedule
(
EventFunctionWrapper
&
ev
,
Tick
t
,
bool
always
)
{
if
(
ev
.
sched
)
{
runner_
->
EventCancel
(
ev
);
ev
.
sched
=
false
;
}
else
if
(
!
always
)
{
fprintf
(
stderr
,
"reschedule: not yet scheduled
\n
"
);
abort
();
}
schedule
(
ev
,
t
);
}
void
IGbE
::
deschedule
(
EventFunctionWrapper
&
ev
)
{
if
(
!
ev
.
sched
)
{
fprintf
(
stderr
,
"deschedule: not scheduledd
\n
"
);
abort
();
}
runner_
->
EventCancel
(
ev
);
ev
.
sched
=
false
;
}
void
IGbE
::
intrPost
()
{
runner_
->
IntXIssue
(
true
);
}
void
IGbE
::
intrClear
()
{
runner_
->
IntXIssue
(
false
);
}
void
IGbE
::
dmaWrite
(
Addr
daddr
,
size_t
len
,
EventFunctionWrapper
&
ev
,
const
void
*
buf
,
Tick
delay
)
{
ev
.
sched
=
true
;
Gem5DMAOp
*
op
=
new
Gem5DMAOp
(
ev
);
op
->
data_
=
new
uint8_t
[
len
];
memcpy
(
op
->
data_
,
buf
,
len
);
op
->
len_
=
len
;
op
->
write_
=
true
;
op
->
dma_addr_
=
daddr
;
if
(
delay
==
0
)
{
runner_
->
IssueDma
(
*
op
);
}
else
{
op
->
time_
=
runner_
->
TimePs
()
+
delay
;
runner_
->
EventSchedule
(
*
op
);
}
}
void
IGbE
::
dmaRead
(
Addr
saddr
,
size_t
len
,
EventFunctionWrapper
&
ev
,
void
*
buf
,
Tick
delay
)
{
ev
.
sched
=
true
;
Gem5DMAOp
*
op
=
new
Gem5DMAOp
(
ev
);
op
->
data_
=
buf
;
op
->
len_
=
len
;
op
->
write_
=
false
;
op
->
dma_addr_
=
saddr
;
if
(
delay
==
0
)
{
runner_
->
IssueDma
(
*
op
);
}
else
{
op
->
time_
=
runner_
->
TimePs
()
+
delay
;
runner_
->
EventSchedule
(
*
op
);
}
}
bool
IGbE
::
sendPacket
(
EthPacketPtr
p
)
{
runner_
->
EthSend
(
p
->
data
,
p
->
length
);
ethTxDone
();
return
true
;
}
void
warn
(
const
char
*
fmt
,
...)
{
fprintf
(
stderr
,
"warn: "
);
va_list
va
;
va_start
(
va
,
fmt
);
vfprintf
(
stderr
,
fmt
,
va
);
va_end
(
va
);
}
void
panic
(
const
char
*
fmt
,
...)
{
fprintf
(
stderr
,
"panic: "
);
va_list
va
;
va_start
(
va
,
fmt
);
vfprintf
(
stderr
,
fmt
,
va
);
va_end
(
va
);
abort
();
}
/******************************************************************************/
int
main
(
int
argc
,
char
*
argv
[])
{
IGbEParams
params
;
params
.
rx_fifo_size
=
384
*
1024
;
params
.
tx_fifo_size
=
384
*
1024
;
params
.
fetch_delay
=
10
*
1000
;
params
.
wb_delay
=
10
*
1000
;
params
.
fetch_comp_delay
=
10
*
1000
;
params
.
wb_comp_delay
=
10
*
1000
;
params
.
rx_write_delay
=
0
;
params
.
tx_read_delay
=
0
;
params
.
pio_delay
=
0
;
// TODO
params
.
rx_desc_cache_size
=
64
;
params
.
tx_desc_cache_size
=
64
;
params
.
phy_pid
=
0x02A8
;
params
.
phy_epid
=
0x0380
;
IGbE
*
dev
=
new
IGbE
(
&
params
);
nicbm
::
Runner
*
runner
=
new
nicbm
::
Runner
(
*
dev
);
dev
->
init
();
return
runner
->
RunMain
(
argc
,
argv
);
}
\ No newline at end of file
sims/nic/e1000_gem5/gem5/bitfield.cc
0 → 100644
View file @
d365cd9e
/*
* Copyright (c) 2017 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed hereunder. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "sims/nic/e1000_gem5/gem5/bitfield.h"
/** Lookup table used for High Speed bit reversing */
const
uint8_t
reverseLookUpTable
[]
=
{
0x00
,
0x80
,
0x40
,
0xC0
,
0x20
,
0xA0
,
0x60
,
0xE0
,
0x10
,
0x90
,
0x50
,
0xD0
,
0x30
,
0xB0
,
0x70
,
0xF0
,
0x08
,
0x88
,
0x48
,
0xC8
,
0x28
,
0xA8
,
0x68
,
0xE8
,
0x18
,
0x98
,
0x58
,
0xD8
,
0x38
,
0xB8
,
0x78
,
0xF8
,
0x04
,
0x84
,
0x44
,
0xC4
,
0x24
,
0xA4
,
0x64
,
0xE4
,
0x14
,
0x94
,
0x54
,
0xD4
,
0x34
,
0xB4
,
0x74
,
0xF4
,
0x0C
,
0x8C
,
0x4C
,
0xCC
,
0x2C
,
0xAC
,
0x6C
,
0xEC
,
0x1C
,
0x9C
,
0x5C
,
0xDC
,
0x3C
,
0xBC
,
0x7C
,
0xFC
,
0x02
,
0x82
,
0x42
,
0xC2
,
0x22
,
0xA2
,
0x62
,
0xE2
,
0x12
,
0x92
,
0x52
,
0xD2
,
0x32
,
0xB2
,
0x72
,
0xF2
,
0x0A
,
0x8A
,
0x4A
,
0xCA
,
0x2A
,
0xAA
,
0x6A
,
0xEA
,
0x1A
,
0x9A
,
0x5A
,
0xDA
,
0x3A
,
0xBA
,
0x7A
,
0xFA
,
0x06
,
0x86
,
0x46
,
0xC6
,
0x26
,
0xA6
,
0x66
,
0xE6
,
0x16
,
0x96
,
0x56
,
0xD6
,
0x36
,
0xB6
,
0x76
,
0xF6
,
0x0E
,
0x8E
,
0x4E
,
0xCE
,
0x2E
,
0xAE
,
0x6E
,
0xEE
,
0x1E
,
0x9E
,
0x5E
,
0xDE
,
0x3E
,
0xBE
,
0x7E
,
0xFE
,
0x01
,
0x81
,
0x41
,
0xC1
,
0x21
,
0xA1
,
0x61
,
0xE1
,
0x11
,
0x91
,
0x51
,
0xD1
,
0x31
,
0xB1
,
0x71
,
0xF1
,
0x09
,
0x89
,
0x49
,
0xC9
,
0x29
,
0xA9
,
0x69
,
0xE9
,
0x19
,
0x99
,
0x59
,
0xD9
,
0x39
,
0xB9
,
0x79
,
0xF9
,
0x05
,
0x85
,
0x45
,
0xC5
,
0x25
,
0xA5
,
0x65
,
0xE5
,
0x15
,
0x95
,
0x55
,
0xD5
,
0x35
,
0xB5
,
0x75
,
0xF5
,
0x0D
,
0x8D
,
0x4D
,
0xCD
,
0x2D
,
0xAD
,
0x6D
,
0xED
,
0x1D
,
0x9D
,
0x5D
,
0xDD
,
0x3D
,
0xBD
,
0x7D
,
0xFD
,
0x03
,
0x83
,
0x43
,
0xC3
,
0x23
,
0xA3
,
0x63
,
0xE3
,
0x13
,
0x93
,
0x53
,
0xD3
,
0x33
,
0xB3
,
0x73
,
0xF3
,
0x0B
,
0x8B
,
0x4B
,
0xCB
,
0x2B
,
0xAB
,
0x6B
,
0xEB
,
0x1B
,
0x9B
,
0x5B
,
0xDB
,
0x3B
,
0xBB
,
0x7B
,
0xFB
,
0x07
,
0x87
,
0x47
,
0xC7
,
0x27
,
0xA7
,
0x67
,
0xE7
,
0x17
,
0x97
,
0x57
,
0xD7
,
0x37
,
0xB7
,
0x77
,
0xF7
,
0x0F
,
0x8F
,
0x4F
,
0xCF
,
0x2F
,
0xAF
,
0x6F
,
0xEF
,
0x1F
,
0x9F
,
0x5F
,
0xDF
,
0x3F
,
0xBF
,
0x7F
,
0xFF
};
sims/nic/e1000_gem5/gem5/bitfield.h
0 → 100644
View file @
d365cd9e
/*
* Copyright (c) 2017, 2019 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed hereunder. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __BASE_BITFIELD_HH__
#define __BASE_BITFIELD_HH__
#include <inttypes.h>
#include <cassert>
#include <cstddef>
#include <type_traits>
/** Lookup table used for High Speed bit reversing */
extern
const
uint8_t
reverseLookUpTable
[];
/**
* Generate a 64-bit mask of 'nbits' 1s, right justified. If a number of bits
* greater than 64 is given, it is truncated to 64.
*
* @param nbits The number of bits set in the mask.
*/
inline
uint64_t
mask
(
int
nbits
)
{
return
(
nbits
>=
64
)
?
(
uint64_t
)
-
1LL
:
(
1ULL
<<
nbits
)
-
1
;
}
/**
* Extract the bitfield from position 'first' to 'last' (inclusive)
* from 'val' and right justify it. MSB is numbered 63, LSB is 0.
*/
template
<
class
T
>
inline
T
bits
(
T
val
,
int
first
,
int
last
)
{
int
nbits
=
first
-
last
+
1
;
return
(
val
>>
last
)
&
mask
(
nbits
);
}
/**
* Extract the bit from this position from 'val' and right justify it.
*/
template
<
class
T
>
inline
T
bits
(
T
val
,
int
bit
)
{
return
bits
(
val
,
bit
,
bit
);
}
/**
* Mask off the given bits in place like bits() but without shifting.
* msb = 63, lsb = 0
*/
template
<
class
T
>
inline
T
mbits
(
T
val
,
int
first
,
int
last
)
{
return
val
&
(
mask
(
first
+
1
)
&
~
mask
(
last
));
}
inline
uint64_t
mask
(
int
first
,
int
last
)
{
return
mbits
((
uint64_t
)
-
1LL
,
first
,
last
);
}
/**
* Sign-extend an N-bit value to 64 bits.
*/
template
<
int
N
>
inline
uint64_t
sext
(
uint64_t
val
)
{
int
sign_bit
=
bits
(
val
,
N
-
1
,
N
-
1
);
return
sign_bit
?
(
val
|
~
mask
(
N
))
:
val
;
}
/**
* Returns val with bits first to last set to the LSBs of bit_val
*
* E.g.:
* first: 7
* last: 4
* val: 0xFFFF
* bit_val: 0x0000
* returned: 0xFF0F
*/
template
<
class
T
,
class
B
>
inline
T
insertBits
(
T
val
,
int
first
,
int
last
,
B
bit_val
)
{
T
t_bit_val
=
bit_val
;
T
bmask
=
mask
(
first
-
last
+
1
)
<<
last
;
return
((
t_bit_val
<<
last
)
&
bmask
)
|
(
val
&
~
bmask
);
}
/**
* Overloaded for access to only one bit in value
*/
template
<
class
T
,
class
B
>
inline
T
insertBits
(
T
val
,
int
bit
,
B
bit_val
)
{
return
insertBits
(
val
,
bit
,
bit
,
bit_val
);
}
/**
* A convenience function to replace bits first to last of val with bit_val
* in place.
*/
template
<
class
T
,
class
B
>
inline
void
replaceBits
(
T
&
val
,
int
first
,
int
last
,
B
bit_val
)
{
val
=
insertBits
(
val
,
first
,
last
,
bit_val
);
}
/** Overloaded function to allow to access only 1 bit*/
template
<
class
T
,
class
B
>
inline
void
replaceBits
(
T
&
val
,
int
bit
,
B
bit_val
)
{
val
=
insertBits
(
val
,
bit
,
bit
,
bit_val
);
}
/**
* Takes a variable lenght word and returns the mirrored version
* (Bit by bit, LSB=>MSB).
*
* algorithm from
* http://graphics.stanford.edu/~seander/bithacks.html
* #ReverseBitsByLookupTable
*
* @param val: variable lenght word
* @param size: number of bytes to mirror
* @return mirrored word
*/
template
<
class
T
>
T
reverseBits
(
T
val
,
std
::
size_t
size
=
sizeof
(
T
))
{
static_assert
(
std
::
is_integral
<
T
>::
value
,
"Expecting an integer type"
);
assert
(
size
<=
sizeof
(
T
));
T
output
=
0
;
for
(
auto
byte
=
0
;
byte
<
size
;
byte
++
,
val
=
static_cast
<
T
>
(
val
>>
8
))
{
output
=
(
output
<<
8
)
|
reverseLookUpTable
[
val
&
0xFF
];
}
return
output
;
}
/**
* Returns the bit position of the MSB that is set in the input
*/
inline
int
findMsbSet
(
uint64_t
val
)
{
int
msb
=
0
;
if
(
!
val
)
return
0
;
if
(
bits
(
val
,
63
,
32
))
{
msb
+=
32
;
val
>>=
32
;
}
if
(
bits
(
val
,
31
,
16
))
{
msb
+=
16
;
val
>>=
16
;
}
if
(
bits
(
val
,
15
,
8
))
{
msb
+=
8
;
val
>>=
8
;
}
if
(
bits
(
val
,
7
,
4
))
{
msb
+=
4
;
val
>>=
4
;
}
if
(
bits
(
val
,
3
,
2
))
{
msb
+=
2
;
val
>>=
2
;
}
if
(
bits
(
val
,
1
,
1
))
{
msb
+=
1
;
}
return
msb
;
}
/**
* Returns the bit position of the LSB that is set in the input
*/
inline
int
findLsbSet
(
uint64_t
val
)
{
int
lsb
=
0
;
if
(
!
val
)
return
sizeof
(
val
)
*
8
;
if
(
!
bits
(
val
,
31
,
0
))
{
lsb
+=
32
;
val
>>=
32
;
}
if
(
!
bits
(
val
,
15
,
0
))
{
lsb
+=
16
;
val
>>=
16
;
}
if
(
!
bits
(
val
,
7
,
0
))
{
lsb
+=
8
;
val
>>=
8
;
}
if
(
!
bits
(
val
,
3
,
0
))
{
lsb
+=
4
;
val
>>=
4
;
}
if
(
!
bits
(
val
,
1
,
0
))
{
lsb
+=
2
;
val
>>=
2
;
}
if
(
!
bits
(
val
,
0
,
0
))
{
lsb
+=
1
;
}
return
lsb
;
}
/**
* Checks if a number is a power of two, or zero.
*/
template
<
class
T
>
inline
bool
isPow2
(
T
v
)
{
return
(
v
&
(
v
-
1
))
==
(
T
)
0
;
}
/**
* Returns the number of set ones in the provided value.
* PD algorithm from
* http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
*/
inline
int
popCount
(
uint64_t
val
)
{
#ifndef __has_builtin
#define __has_builtin(foo) 0
#endif
#if defined(__GNUC__) || (defined(__clang__) && __has_builtin(__builtin_popcountl))
return
__builtin_popcountl
(
val
);
#else
const
uint64_t
m1
=
0x5555555555555555
;
// ..010101b
const
uint64_t
m2
=
0x3333333333333333
;
// ..110011b
const
uint64_t
m4
=
0x0f0f0f0f0f0f0f0f
;
// ..001111b
const
uint64_t
sum
=
0x0101010101010101
;
val
-=
(
val
>>
1
)
&
m1
;
// 2 bits count -> 2 bits
val
=
(
val
&
m2
)
+
((
val
>>
2
)
&
m2
);
// 4 bits count -> 4 bits
val
=
(
val
+
(
val
>>
4
))
&
m4
;
// 8 bits count -> 8 bits
return
(
val
*
sum
)
>>
56
;
// horizontal sum
#endif // defined(__GNUC__) || (defined(__clang__) && __has_builtin(__builtin_popcountl))
}
/**
* Align to the next highest power of two.
*
* The number passed in is aligned to the next highest power of two,
* if it is not already a power of two. Please note that if 0 is
* passed in, 0 is returned.
*
* This code has been modified from the following:
* http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
*/
inline
uint64_t
alignToPowerOfTwo
(
uint64_t
val
)
{
val
--
;
val
|=
val
>>
1
;
val
|=
val
>>
2
;
val
|=
val
>>
4
;
val
|=
val
>>
8
;
val
|=
val
>>
16
;
val
|=
val
>>
32
;
val
++
;
return
val
;
};
/**
* Count trailing zeros in a 32-bit value.
*
* @param An input value
* @return The number of trailing zeros or 32 if the value is zero.
*/
inline
int
ctz32
(
uint32_t
value
)
{
return
value
?
__builtin_ctzl
(
value
)
:
32
;
}
/**
* Count trailing zeros in a 64-bit value.
*
* @param An input value
* @return The number of trailing zeros or 64 if the value is zero.
*/
inline
int
ctz64
(
uint64_t
value
)
{
return
value
?
__builtin_ctzll
(
value
)
:
64
;
}
#endif // __BASE_BITFIELD_HH__
sims/nic/e1000_gem5/gem5/eth.h
0 → 100644
View file @
d365cd9e
/*
* eth.h
*
* Ethernet.
*
* Copyright (c) 2000 Dug Song <dugsong@monkey.org>
*
* $Id: eth.h,v 1.15 2004/01/03 08:47:23 dugsong Exp $
*/
#ifndef DNET_ETH_H
#define DNET_ETH_H
#define ETH_ADDR_LEN 6
#define ETH_ADDR_BITS 48
#define ETH_TYPE_LEN 2
#define ETH_CRC_LEN 4
#define ETH_HDR_LEN 14
#define ETH_LEN_MIN 64
/* minimum frame length with CRC */
#define ETH_LEN_MAX 1518
/* maximum frame length with CRC */
#define ETH_MTU (ETH_LEN_MAX - ETH_HDR_LEN - ETH_CRC_LEN)
#define ETH_MIN (ETH_LEN_MIN - ETH_HDR_LEN - ETH_CRC_LEN)
typedef
struct
eth_addr
{
uint8_t
data
[
ETH_ADDR_LEN
];
}
eth_addr_t
;
struct
eth_hdr
{
eth_addr_t
eth_dst
;
/* destination address */
eth_addr_t
eth_src
;
/* source address */
uint16_t
eth_type
;
/* payload type */
};
/*
* Ethernet payload types - http://standards.ieee.org/regauth/ethertype
*/
#define ETH_TYPE_PUP 0x0200
/* PUP protocol */
#define ETH_TYPE_IP 0x0800
/* IP protocol */
#define ETH_TYPE_ARP 0x0806
/* address resolution protocol */
#define ETH_TYPE_REVARP 0x8035
/* reverse addr resolution protocol */
#define ETH_TYPE_8021Q 0x8100
/* IEEE 802.1Q VLAN tagging */
#define ETH_TYPE_IPV6 0x86DD
/* IPv6 protocol */
#define ETH_TYPE_MPLS 0x8847
/* MPLS */
#define ETH_TYPE_MPLS_MCAST 0x8848
/* MPLS Multicast */
#define ETH_TYPE_PPPOEDISC 0x8863
/* PPP Over Ethernet Discovery Stage */
#define ETH_TYPE_PPPOE 0x8864
/* PPP Over Ethernet Session Stage */
#define ETH_TYPE_LOOPBACK 0x9000
/* used to test interfaces */
#define ETH_IS_MULTICAST(ea) (*(ea) & 0x01)
/* is address mcast/bcast? */
#define ETH_ADDR_BROADCAST "\xff\xff\xff\xff\xff\xff"
#define eth_pack_hdr(h, dst, src, type) do { \
struct eth_hdr *eth_pack_p = (struct eth_hdr *)(h); \
memmove(ð_pack_p->eth_dst, &(dst), ETH_ADDR_LEN); \
memmove(ð_pack_p->eth_src, &(src), ETH_ADDR_LEN); \
eth_pack_p->eth_type = htons(type); \
} while (0)
typedef
struct
eth_handle
eth_t
;
__BEGIN_DECLS
eth_t
*
eth_open
(
const
char
*
device
);
int
eth_get
(
eth_t
*
e
,
eth_addr_t
*
ea
);
int
eth_set
(
eth_t
*
e
,
const
eth_addr_t
*
ea
);
size_t
eth_send
(
eth_t
*
e
,
const
void
*
buf
,
size_t
len
);
eth_t
*
eth_close
(
eth_t
*
e
);
char
*
eth_ntop
(
const
eth_addr_t
*
eth
,
char
*
dst
,
size_t
len
);
int
eth_pton
(
const
char
*
src
,
eth_addr_t
*
dst
);
char
*
eth_ntoa
(
const
eth_addr_t
*
eth
);
#define eth_aton eth_pton
__END_DECLS
#endif
/* DNET_ETH_H */
sims/nic/e1000_gem5/gem5/inet.cc
0 → 100644
View file @
d365cd9e
/*
* Copyright (c) 2013 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed hereunder. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* Copyright (c) 2002-2005 The Regents of The University of Michigan
* Copyright (c) 2010 Advanced Micro Devices, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <cstddef>
#include <cstdio>
#include <sstream>
#include <string>
#include "sims/nic/e1000_gem5/support.h"
#include "sims/nic/e1000_gem5/gem5/inet.h"
using
namespace
std
;
EthAddr
::
EthAddr
()
{
memset
(
data
,
0
,
ETH_ADDR_LEN
);
}
EthAddr
::
EthAddr
(
const
uint8_t
ea
[
ETH_ADDR_LEN
])
{
for
(
int
i
=
0
;
i
<
ETH_ADDR_LEN
;
++
i
)
data
[
i
]
=
ea
[
i
];
}
EthAddr
::
EthAddr
(
const
eth_addr
&
ea
)
{
for
(
int
i
=
0
;
i
<
ETH_ADDR_LEN
;
++
i
)
data
[
i
]
=
ea
.
data
[
i
];
}
EthAddr
::
EthAddr
(
const
std
::
string
&
addr
)
{
parse
(
addr
);
}
const
EthAddr
&
EthAddr
::
operator
=
(
const
eth_addr
&
ea
)
{
*
data
=
*
ea
.
data
;
return
*
this
;
}
const
EthAddr
&
EthAddr
::
operator
=
(
const
std
::
string
&
addr
)
{
parse
(
addr
);
return
*
this
;
}
void
EthAddr
::
parse
(
const
std
::
string
&
addr
)
{
// the hack below is to make sure that ETH_ADDR_LEN is 6 otherwise
// the sscanf function won't work.
int
bytes
[
ETH_ADDR_LEN
==
6
?
ETH_ADDR_LEN
:
-
1
];
if
(
sscanf
(
addr
.
c_str
(),
"%x:%x:%x:%x:%x:%x"
,
&
bytes
[
0
],
&
bytes
[
1
],
&
bytes
[
2
],
&
bytes
[
3
],
&
bytes
[
4
],
&
bytes
[
5
])
!=
ETH_ADDR_LEN
)
{
memset
(
data
,
0xff
,
ETH_ADDR_LEN
);
return
;
}
for
(
int
i
=
0
;
i
<
ETH_ADDR_LEN
;
++
i
)
{
if
(
bytes
[
i
]
&
~
0xff
)
{
memset
(
data
,
0xff
,
ETH_ADDR_LEN
);
return
;
}
data
[
i
]
=
bytes
[
i
];
}
}
string
EthAddr
::
string
()
const
{
stringstream
stream
;
stream
<<
*
this
;
return
stream
.
str
();
}
bool
operator
==
(
const
EthAddr
&
left
,
const
EthAddr
&
right
)
{
return
!
memcmp
(
left
.
bytes
(),
right
.
bytes
(),
ETH_ADDR_LEN
);
}
ostream
&
operator
<<
(
ostream
&
stream
,
const
EthAddr
&
ea
)
{
const
uint8_t
*
a
=
ea
.
addr
();
stream
<<
a
[
0
]
<<
":"
<<
a
[
1
]
<<
":"
<<
a
[
2
]
<<
":"
<<
a
[
3
]
<<
":"
<<
a
[
4
]
<<
":"
<<
a
[
5
];
return
stream
;
}
string
IpAddress
::
string
()
const
{
stringstream
stream
;
stream
<<
*
this
;
return
stream
.
str
();
}
bool
operator
==
(
const
IpAddress
&
left
,
const
IpAddress
&
right
)
{
return
left
.
ip
()
==
right
.
ip
();
}
ostream
&
operator
<<
(
ostream
&
stream
,
const
IpAddress
&
ia
)
{
uint32_t
ip
=
ia
.
ip
();
stream
<<
(
uint8_t
)(
ip
>>
24
)
<<
"."
<<
(
uint8_t
)(
ip
>>
16
)
<<
"."
<<
(
uint8_t
)(
ip
>>
8
)
<<
"."
<<
(
uint8_t
)(
ip
>>
0
);
return
stream
;
}
string
IpNetmask
::
string
()
const
{
stringstream
stream
;
stream
<<
*
this
;
return
stream
.
str
();
}
bool
operator
==
(
const
IpNetmask
&
left
,
const
IpNetmask
&
right
)
{
return
(
left
.
ip
()
==
right
.
ip
())
&&
(
left
.
netmask
()
==
right
.
netmask
());
}
ostream
&
operator
<<
(
ostream
&
stream
,
const
IpNetmask
&
in
)
{
stream
<<
(
const
IpAddress
&
)
in
<<
"/"
<<
in
.
netmask
();
return
stream
;
}
string
IpWithPort
::
string
()
const
{
stringstream
stream
;
stream
<<
*
this
;
return
stream
.
str
();
}
bool
operator
==
(
const
IpWithPort
&
left
,
const
IpWithPort
&
right
)
{
return
(
left
.
ip
()
==
right
.
ip
())
&&
(
left
.
port
()
==
right
.
port
());
}
ostream
&
operator
<<
(
ostream
&
stream
,
const
IpWithPort
&
iwp
)
{
stream
<<
(
const
IpAddress
&
)
iwp
<<
":"
<<
iwp
.
port
();
return
stream
;
}
uint16_t
cksum
(
const
IpPtr
&
ptr
)
{
int
sum
=
ip_cksum_add
(
ptr
->
bytes
(),
ptr
->
hlen
(),
0
);
return
ip_cksum_carry
(
sum
);
}
uint16_t
__tu_cksum
(
const
IpPtr
&
ip
)
{
int
tcplen
=
ip
->
len
()
-
ip
->
hlen
();
int
sum
=
ip_cksum_add
(
ip
->
payload
(),
tcplen
,
0
);
sum
=
ip_cksum_add
(
&
ip
->
ip_src
,
8
,
sum
);
// source and destination
sum
+=
htons
(
ip
->
ip_p
+
tcplen
);
return
ip_cksum_carry
(
sum
);
}
uint16_t
__tu_cksum6
(
const
Ip6Ptr
&
ip6
)
{
int
tcplen
=
ip6
->
plen
()
-
ip6
->
extensionLength
();
int
sum
=
ip_cksum_add
(
ip6
->
payload
(),
tcplen
,
0
);
sum
=
ip_cksum_add
(
ip6
->
src
(),
32
,
sum
);
sum
+=
htons
(
ip6
->
proto
()
+
tcplen
);
return
ip_cksum_carry
(
sum
);
}
uint16_t
cksum
(
const
TcpPtr
&
tcp
)
{
if
(
IpPtr
(
tcp
.
packet
()))
{
return
__tu_cksum
(
IpPtr
(
tcp
.
packet
()));
}
else
if
(
Ip6Ptr
(
tcp
.
packet
()))
{
return
__tu_cksum6
(
Ip6Ptr
(
tcp
.
packet
()));
}
else
{
panic
(
"Unrecognized IP packet format"
);
}
// Should never reach here
return
0
;
}
uint16_t
cksum
(
const
UdpPtr
&
udp
)
{
if
(
IpPtr
(
udp
.
packet
()))
{
return
__tu_cksum
(
IpPtr
(
udp
.
packet
()));
}
else
if
(
Ip6Ptr
(
udp
.
packet
()))
{
return
__tu_cksum6
(
Ip6Ptr
(
udp
.
packet
()));
}
else
{
panic
(
"Unrecognized IP packet format"
);
}
return
0
;
}
bool
IpHdr
::
options
(
vector
<
const
IpOpt
*>
&
vec
)
const
{
vec
.
clear
();
const
uint8_t
*
data
=
bytes
()
+
sizeof
(
struct
ip_hdr
);
int
all
=
hlen
()
-
sizeof
(
struct
ip_hdr
);
while
(
all
>
0
)
{
const
IpOpt
*
opt
=
(
const
IpOpt
*
)
data
;
int
len
=
opt
->
len
();
if
(
all
<
len
)
return
false
;
vec
.
push_back
(
opt
);
all
-=
len
;
data
+=
len
;
}
return
true
;
}
#define IP6_EXTENSION(nxt) (nxt == IP_PROTO_HOPOPTS) ? true : \
(nxt == IP_PROTO_ROUTING) ? true : \
(nxt == IP_PROTO_FRAGMENT) ? true : \
(nxt == IP_PROTO_AH) ? true : \
(nxt == IP_PROTO_ESP) ? true: \
(nxt == IP_PROTO_DSTOPTS) ? true : false
/* Scan the IP6 header for all header extensions
* and return the number of headers found
*/
int
Ip6Hdr
::
extensionLength
()
const
{
const
uint8_t
*
data
=
bytes
()
+
IP6_HDR_LEN
;
uint8_t
nxt
=
ip6_nxt
;
int
len
=
0
;
int
all
=
plen
();
while
(
IP6_EXTENSION
(
nxt
))
{
const
Ip6Opt
*
ext
=
(
const
Ip6Opt
*
)
data
;
nxt
=
ext
->
nxt
();
len
+=
ext
->
len
();
data
+=
ext
->
len
();
all
-=
ext
->
len
();
assert
(
all
>=
0
);
}
return
len
;
}
/* Scan the IP6 header for a particular extension
* header type and return a pointer to it if it
* exists, otherwise return NULL
*/
const
Ip6Opt
*
Ip6Hdr
::
getExt
(
uint8_t
ext_type
)
const
{
const
uint8_t
*
data
=
bytes
()
+
IP6_HDR_LEN
;
uint8_t
nxt
=
ip6_nxt
;
Ip6Opt
*
opt
=
NULL
;
int
all
=
plen
();
while
(
IP6_EXTENSION
(
nxt
))
{
opt
=
(
Ip6Opt
*
)
data
;
if
(
nxt
==
ext_type
)
{
break
;
}
nxt
=
opt
->
nxt
();
data
+=
opt
->
len
();
all
-=
opt
->
len
();
opt
=
NULL
;
assert
(
all
>=
0
);
}
return
(
const
Ip6Opt
*
)
opt
;
}
/* Scan the IP6 header and any extension headers
* to find what type of Layer 4 header exists
* after this header
*/
uint8_t
Ip6Hdr
::
proto
()
const
{
const
uint8_t
*
data
=
bytes
()
+
IP6_HDR_LEN
;
uint8_t
nxt
=
ip6_nxt
;
int
all
=
plen
();
while
(
IP6_EXTENSION
(
nxt
))
{
const
Ip6Opt
*
ext
=
(
const
Ip6Opt
*
)
data
;
nxt
=
ext
->
nxt
();
data
+=
ext
->
len
();
all
-=
ext
->
len
();
assert
(
all
>=
0
);
}
return
nxt
;
}
bool
TcpHdr
::
options
(
vector
<
const
TcpOpt
*>
&
vec
)
const
{
vec
.
clear
();
const
uint8_t
*
data
=
bytes
()
+
sizeof
(
struct
tcp_hdr
);
int
all
=
off
()
-
sizeof
(
struct
tcp_hdr
);
while
(
all
>
0
)
{
const
TcpOpt
*
opt
=
(
const
TcpOpt
*
)
data
;
int
len
=
opt
->
len
();
if
(
all
<
len
)
return
false
;
vec
.
push_back
(
opt
);
all
-=
len
;
data
+=
len
;
}
return
true
;
}
int
hsplit
(
const
EthPacketPtr
&
ptr
)
{
int
split_point
=
0
;
IpPtr
ip
(
ptr
);
Ip6Ptr
ip6
(
ptr
);
if
(
ip
)
{
split_point
=
ip
.
pstart
();
TcpPtr
tcp
(
ip
);
if
(
tcp
)
split_point
=
tcp
.
pstart
();
UdpPtr
udp
(
ip
);
if
(
udp
)
split_point
=
udp
.
pstart
();
}
else
if
(
ip6
)
{
split_point
=
ip6
.
pstart
();
TcpPtr
tcp
(
ip6
);
if
(
tcp
)
split_point
=
tcp
.
pstart
();
UdpPtr
udp
(
ip6
);
if
(
udp
)
split_point
=
udp
.
pstart
();
}
return
split_point
;
}
\ No newline at end of file
sims/nic/e1000_gem5/gem5/inet.h
0 → 100644
View file @
d365cd9e
This diff is collapsed.
Click to expand it.
sims/nic/e1000_gem5/gem5/ip.h
0 → 100644
View file @
d365cd9e
/*
* ip.h
*
* Internet Protocol (RFC 791).
*
* Copyright (c) 2000 Dug Song <dugsong@monkey.org>
*
* $Id: ip.h,v 1.23 2003/03/16 17:39:17 dugsong Exp $
*/
#ifndef DNET_IP_H
#define DNET_IP_H
#define IP_ADDR_LEN 4
/* IP address length */
#define IP_ADDR_BITS 32
/* IP address bits */
#define IP_HDR_LEN 20
/* base IP header length */
#define IP_OPT_LEN 2
/* base IP option length */
#define IP_OPT_LEN_MAX 40
#define IP_HDR_LEN_MAX (IP_HDR_LEN + IP_OPT_LEN_MAX)
#define IP_LEN_MAX 65535
#define IP_LEN_MIN IP_HDR_LEN
typedef
uint32_t
ip_addr_t
;
#ifndef __GNUC__
# define __attribute__(x)
# pragma pack(1)
#endif
/*
* IP header, without options
*/
struct
ip_hdr
{
#if DNET_BYTESEX == DNET_BIG_ENDIAN
uint8_t
ip_v
:
4
,
/* version */
ip_hl:
4
;
/* header length (incl any options) */
#elif DNET_BYTESEX == DNET_LIL_ENDIAN
uint8_t
ip_hl
:
4
,
ip_v:
4
;
#else
# error "need to include <dnet.h>"
#endif
uint8_t
ip_tos
;
/* type of service */
uint16_t
ip_len
;
/* total length (incl header) */
uint16_t
ip_id
;
/* identification */
uint16_t
ip_off
;
/* fragment offset and flags */
uint8_t
ip_ttl
;
/* time to live */
uint8_t
ip_p
;
/* protocol */
uint16_t
ip_sum
;
/* checksum */
ip_addr_t
ip_src
;
/* source address */
ip_addr_t
ip_dst
;
/* destination address */
}
__attribute__
((
packed
));
/*
* Type of service (ip_tos), RFC 1349 ("obsoleted by RFC 2474")
*/
#define IP_TOS_DEFAULT 0x00
/* default */
#define IP_TOS_LOWDELAY 0x10
/* low delay */
#define IP_TOS_THROUGHPUT 0x08
/* high throughput */
#define IP_TOS_RELIABILITY 0x04
/* high reliability */
#define IP_TOS_LOWCOST 0x02
/* low monetary cost - XXX */
#define IP_TOS_ECT 0x02
/* ECN-capable transport */
#define IP_TOS_CE 0x01
/* congestion experienced */
/*
* IP precedence (high 3 bits of ip_tos), hopefully unused
*/
#define IP_TOS_PREC_ROUTINE 0x00
#define IP_TOS_PREC_PRIORITY 0x20
#define IP_TOS_PREC_IMMEDIATE 0x40
#define IP_TOS_PREC_FLASH 0x60
#define IP_TOS_PREC_FLASHOVERRIDE 0x80
#define IP_TOS_PREC_CRITIC_ECP 0xa0
#define IP_TOS_PREC_INTERNETCONTROL 0xc0
#define IP_TOS_PREC_NETCONTROL 0xe0
/*
* Fragmentation flags (ip_off)
*/
#define IP_RF 0x8000
/* reserved */
#define IP_DF 0x4000
/* don't fragment */
#define IP_MF 0x2000
/* more fragments (not last frag) */
#define IP_OFFMASK 0x1fff
/* mask for fragment offset */
/*
* Time-to-live (ip_ttl), seconds
*/
#define IP_TTL_DEFAULT 64
/* default ttl, RFC 1122, RFC 1340 */
#define IP_TTL_MAX 255
/* maximum ttl */
/*
* Protocol (ip_p) - http://www.iana.org/assignments/protocol-numbers
*/
#define IP_PROTO_IP 0
/* dummy for IP */
#define IP_PROTO_HOPOPTS IP_PROTO_IP
/* IPv6 hop-by-hop options */
#define IP_PROTO_ICMP 1
/* ICMP */
#define IP_PROTO_IGMP 2
/* IGMP */
#define IP_PROTO_GGP 3
/* gateway-gateway protocol */
#define IP_PROTO_IPIP 4
/* IP in IP */
#define IP_PROTO_ST 5
/* ST datagram mode */
#define IP_PROTO_TCP 6
/* TCP */
#define IP_PROTO_CBT 7
/* CBT */
#define IP_PROTO_EGP 8
/* exterior gateway protocol */
#define IP_PROTO_IGP 9
/* interior gateway protocol */
#define IP_PROTO_BBNRCC 10
/* BBN RCC monitoring */
#define IP_PROTO_NVP 11
/* Network Voice Protocol */
#define IP_PROTO_PUP 12
/* PARC universal packet */
#define IP_PROTO_ARGUS 13
/* ARGUS */
#define IP_PROTO_EMCON 14
/* EMCON */
#define IP_PROTO_XNET 15
/* Cross Net Debugger */
#define IP_PROTO_CHAOS 16
/* Chaos */
#define IP_PROTO_UDP 17
/* UDP */
#define IP_PROTO_MUX 18
/* multiplexing */
#define IP_PROTO_DCNMEAS 19
/* DCN measurement */
#define IP_PROTO_HMP 20
/* Host Monitoring Protocol */
#define IP_PROTO_PRM 21
/* Packet Radio Measurement */
#define IP_PROTO_IDP 22
/* Xerox NS IDP */
#define IP_PROTO_TRUNK1 23
/* Trunk-1 */
#define IP_PROTO_TRUNK2 24
/* Trunk-2 */
#define IP_PROTO_LEAF1 25
/* Leaf-1 */
#define IP_PROTO_LEAF2 26
/* Leaf-2 */
#define IP_PROTO_RDP 27
/* "Reliable Datagram" proto */
#define IP_PROTO_IRTP 28
/* Inet Reliable Transaction */
#define IP_PROTO_TP 29
/* ISO TP class 4 */
#define IP_PROTO_NETBLT 30
/* Bulk Data Transfer */
#define IP_PROTO_MFPNSP 31
/* MFE Network Services */
#define IP_PROTO_MERITINP 32
/* Merit Internodal Protocol */
#define IP_PROTO_SEP 33
/* Sequential Exchange proto */
#define IP_PROTO_3PC 34
/* Third Party Connect proto */
#define IP_PROTO_IDPR 35
/* Interdomain Policy Route */
#define IP_PROTO_XTP 36
/* Xpress Transfer Protocol */
#define IP_PROTO_DDP 37
/* Datagram Delivery Proto */
#define IP_PROTO_CMTP 38
/* IDPR Ctrl Message Trans */
#define IP_PROTO_TPPP 39
/* TP++ Transport Protocol */
#define IP_PROTO_IL 40
/* IL Transport Protocol */
#define IP_PROTO_IPV6 41
/* IPv6 */
#define IP_PROTO_SDRP 42
/* Source Demand Routing */
#define IP_PROTO_ROUTING 43
/* IPv6 routing header */
#define IP_PROTO_FRAGMENT 44
/* IPv6 fragmentation header */
#define IP_PROTO_RSVP 46
/* Reservation protocol */
#define IP_PROTO_GRE 47
/* General Routing Encap */
#define IP_PROTO_MHRP 48
/* Mobile Host Routing */
#define IP_PROTO_ENA 49
/* ENA */
#define IP_PROTO_ESP 50
/* Encap Security Payload */
#define IP_PROTO_AH 51
/* Authentication Header */
#define IP_PROTO_INLSP 52
/* Integated Net Layer Sec */
#define IP_PROTO_SWIPE 53
/* SWIPE */
#define IP_PROTO_NARP 54
/* NBMA Address Resolution */
#define IP_PROTO_MOBILE 55
/* Mobile IP, RFC 2004 */
#define IP_PROTO_TLSP 56
/* Transport Layer Security */
#define IP_PROTO_SKIP 57
/* SKIP */
#define IP_PROTO_ICMPV6 58
/* ICMP for IPv6 */
#define IP_PROTO_NONE 59
/* IPv6 no next header */
#define IP_PROTO_DSTOPTS 60
/* IPv6 destination options */
#define IP_PROTO_ANYHOST 61
/* any host internal proto */
#define IP_PROTO_CFTP 62
/* CFTP */
#define IP_PROTO_ANYNET 63
/* any local network */
#define IP_PROTO_EXPAK 64
/* SATNET and Backroom EXPAK */
#define IP_PROTO_KRYPTOLAN 65
/* Kryptolan */
#define IP_PROTO_RVD 66
/* MIT Remote Virtual Disk */
#define IP_PROTO_IPPC 67
/* Inet Pluribus Packet Core */
#define IP_PROTO_DISTFS 68
/* any distributed fs */
#define IP_PROTO_SATMON 69
/* SATNET Monitoring */
#define IP_PROTO_VISA 70
/* VISA Protocol */
#define IP_PROTO_IPCV 71
/* Inet Packet Core Utility */
#define IP_PROTO_CPNX 72
/* Comp Proto Net Executive */
#define IP_PROTO_CPHB 73
/* Comp Protocol Heart Beat */
#define IP_PROTO_WSN 74
/* Wang Span Network */
#define IP_PROTO_PVP 75
/* Packet Video Protocol */
#define IP_PROTO_BRSATMON 76
/* Backroom SATNET Monitor */
#define IP_PROTO_SUNND 77
/* SUN ND Protocol */
#define IP_PROTO_WBMON 78
/* WIDEBAND Monitoring */
#define IP_PROTO_WBEXPAK 79
/* WIDEBAND EXPAK */
#define IP_PROTO_EON 80
/* ISO CNLP */
#define IP_PROTO_VMTP 81
/* Versatile Msg Transport*/
#define IP_PROTO_SVMTP 82
/* Secure VMTP */
#define IP_PROTO_VINES 83
/* VINES */
#define IP_PROTO_TTP 84
/* TTP */
#define IP_PROTO_NSFIGP 85
/* NSFNET-IGP */
#define IP_PROTO_DGP 86
/* Dissimilar Gateway Proto */
#define IP_PROTO_TCF 87
/* TCF */
#define IP_PROTO_EIGRP 88
/* EIGRP */
#define IP_PROTO_OSPF 89
/* Open Shortest Path First */
#define IP_PROTO_SPRITERPC 90
/* Sprite RPC Protocol */
#define IP_PROTO_LARP 91
/* Locus Address Resolution */
#define IP_PROTO_MTP 92
/* Multicast Transport Proto */
#define IP_PROTO_AX25 93
/* AX.25 Frames */
#define IP_PROTO_IPIPENCAP 94
/* yet-another IP encap */
#define IP_PROTO_MICP 95
/* Mobile Internet Ctrl */
#define IP_PROTO_SCCSP 96
/* Semaphore Comm Sec Proto */
#define IP_PROTO_ETHERIP 97
/* Ethernet in IPv4 */
#define IP_PROTO_ENCAP 98
/* encapsulation header */
#define IP_PROTO_ANYENC 99
/* private encryption scheme */
#define IP_PROTO_GMTP 100
/* GMTP */
#define IP_PROTO_IFMP 101
/* Ipsilon Flow Mgmt Proto */
#define IP_PROTO_PNNI 102
/* PNNI over IP */
#define IP_PROTO_PIM 103
/* Protocol Indep Multicast */
#define IP_PROTO_ARIS 104
/* ARIS */
#define IP_PROTO_SCPS 105
/* SCPS */
#define IP_PROTO_QNX 106
/* QNX */
#define IP_PROTO_AN 107
/* Active Networks */
#define IP_PROTO_IPCOMP 108
/* IP Payload Compression */
#define IP_PROTO_SNP 109
/* Sitara Networks Protocol */
#define IP_PROTO_COMPAQPEER 110
/* Compaq Peer Protocol */
#define IP_PROTO_IPXIP 111
/* IPX in IP */
#define IP_PROTO_VRRP 112
/* Virtual Router Redundancy */
#define IP_PROTO_PGM 113
/* PGM Reliable Transport */
#define IP_PROTO_ANY0HOP 114
/* 0-hop protocol */
#define IP_PROTO_L2TP 115
/* Layer 2 Tunneling Proto */
#define IP_PROTO_DDX 116
/* D-II Data Exchange (DDX) */
#define IP_PROTO_IATP 117
/* Interactive Agent Xfer */
#define IP_PROTO_STP 118
/* Schedule Transfer Proto */
#define IP_PROTO_SRP 119
/* SpectraLink Radio Proto */
#define IP_PROTO_UTI 120
/* UTI */
#define IP_PROTO_SMP 121
/* Simple Message Protocol */
#define IP_PROTO_SM 122
/* SM */
#define IP_PROTO_PTP 123
/* Performance Transparency */
#define IP_PROTO_ISIS 124
/* ISIS over IPv4 */
#define IP_PROTO_FIRE 125
/* FIRE */
#define IP_PROTO_CRTP 126
/* Combat Radio Transport */
#define IP_PROTO_CRUDP 127
/* Combat Radio UDP */
#define IP_PROTO_SSCOPMCE 128
/* SSCOPMCE */
#define IP_PROTO_IPLT 129
/* IPLT */
#define IP_PROTO_SPS 130
/* Secure Packet Shield */
#define IP_PROTO_PIPE 131
/* Private IP Encap in IP */
#define IP_PROTO_SCTP 132
/* Stream Ctrl Transmission */
#define IP_PROTO_FC 133
/* Fibre Channel */
#define IP_PROTO_RSVPIGN 134
/* RSVP-E2E-IGNORE */
#define IP_PROTO_RAW 255
/* Raw IP packets */
#define IP_PROTO_RESERVED IP_PROTO_RAW
/* Reserved */
#define IP_PROTO_MAX 255
/*
* Option types (opt_type) - http://www.iana.org/assignments/ip-parameters
*/
#define IP_OPT_CONTROL 0x00
/* control */
#define IP_OPT_DEBMEAS 0x40
/* debugging & measurement */
#define IP_OPT_COPY 0x80
/* copy into all fragments */
#define IP_OPT_RESERVED1 0x20
#define IP_OPT_RESERVED2 0x60
#define IP_OPT_EOL 0
/* end of option list */
#define IP_OPT_NOP 1
/* no operation */
#define IP_OPT_SEC (2|IP_OPT_COPY)
/* DoD basic security */
#define IP_OPT_LSRR (3|IP_OPT_COPY)
/* loose source route */
#define IP_OPT_TS (4|IP_OPT_DEBMEAS)
/* timestamp */
#define IP_OPT_ESEC (5|IP_OPT_COPY)
/* DoD extended security */
#define IP_OPT_CIPSO (6|IP_OPT_COPY)
/* commercial security */
#define IP_OPT_RR 7
/* record route */
#define IP_OPT_SATID (8|IP_OPT_COPY)
/* stream ID (obsolete) */
#define IP_OPT_SSRR (9|IP_OPT_COPY)
/* strict source route */
#define IP_OPT_ZSU 10
/* experimental measurement */
#define IP_OPT_MTUP 11
/* MTU probe */
#define IP_OPT_MTUR 12
/* MTU reply */
#define IP_OPT_FINN (13|IP_OPT_COPY|IP_OPT_DEBMEAS)
/* exp flow control */
#define IP_OPT_VISA (14|IP_OPT_COPY)
/* exp access control */
#define IP_OPT_ENCODE 15
/* ??? */
#define IP_OPT_IMITD (16|IP_OPT_COPY)
/* IMI traffic descriptor */
#define IP_OPT_EIP (17|IP_OPT_COPY)
/* extended IP, RFC 1385 */
#define IP_OPT_TR (18|IP_OPT_DEBMEAS)
/* traceroute */
#define IP_OPT_ADDEXT (19|IP_OPT_COPY)
/* IPv7 ext addr, RFC 1475 */
#define IP_OPT_RTRALT (20|IP_OPT_COPY)
/* router alert, RFC 2113 */
#define IP_OPT_SDB (21|IP_OPT_COPY)
/* directed bcast, RFC 1770 */
#define IP_OPT_NSAPA (22|IP_OPT_COPY)
/* NSAP addresses */
#define IP_OPT_DPS (23|IP_OPT_COPY)
/* dynamic packet state */
#define IP_OPT_UMP (24|IP_OPT_COPY)
/* upstream multicast */
#define IP_OPT_MAX 25
#define IP_OPT_COPIED(o) ((o) & 0x80)
#define IP_OPT_CLASS(o) ((o) & 0x60)
#define IP_OPT_NUMBER(o) ((o) & 0x1f)
#define IP_OPT_TYPEONLY(o) ((o) == IP_OPT_EOL || (o) == IP_OPT_NOP)
/*
* Security option data - RFC 791, 3.1
*/
struct
ip_opt_data_sec
{
uint16_t
s
;
/* security */
uint16_t
c
;
/* compartments */
uint16_t
h
;
/* handling restrictions */
uint8_t
tcc
[
3
];
/* transmission control code */
}
__attribute__
((
__packed__
));
#define IP_OPT_SEC_UNCLASS 0x0000
/* unclassified */
#define IP_OPT_SEC_CONFID 0xf135
/* confidential */
#define IP_OPT_SEC_EFTO 0x789a
/* EFTO */
#define IP_OPT_SEC_MMMM 0xbc4d
/* MMMM */
#define IP_OPT_SEC_PROG 0x5e26
/* PROG */
#define IP_OPT_SEC_RESTR 0xaf13
/* restricted */
#define IP_OPT_SEC_SECRET 0xd788
/* secret */
#define IP_OPT_SEC_TOPSECRET 0x6bc5
/* top secret */
/*
* {Loose Source, Record, Strict Source} Route option data - RFC 791, 3.1
*/
struct
ip_opt_data_rr
{
uint8_t
ptr
;
/* from start of option, >= 4 */
uint32_t
iplist
__flexarr
;
/* list of IP addresses */
}
__attribute__
((
__packed__
));
/*
* Timestamp option data - RFC 791, 3.1
*/
struct
ip_opt_data_ts
{
uint8_t
ptr
;
/* from start of option, >= 5 */
#if DNET_BYTESEX == DNET_BIG_ENDIAN
uint8_t
oflw
:
4
,
/* number of IPs skipped */
flg:
4
;
/* address[ / timestamp] flag */
#elif DNET_BYTESEX == DNET_LIL_ENDIAN
uint8_t
flg
:
4
,
oflw:
4
;
#endif
uint32_t
ipts
__flexarr
;
/* IP address [/ timestamp] pairs */
}
__attribute__
((
__packed__
));
#define IP_OPT_TS_TSONLY 0
/* timestamps only */
#define IP_OPT_TS_TSADDR 1
/* IP address / timestamp pairs */
#define IP_OPT_TS_PRESPEC 3
/* IP address / zero timestamp pairs */
/*
* Traceroute option data - RFC 1393, 2.2
*/
struct
ip_opt_data_tr
{
uint16_t
id
;
/* ID number */
uint16_t
ohc
;
/* outbound hop count */
uint16_t
rhc
;
/* return hop count */
uint32_t
origip
;
/* originator IP address */
}
__attribute__
((
__packed__
));
/*
* IP option (following IP header)
*/
struct
ip_opt
{
uint8_t
opt_type
;
/* option type */
uint8_t
opt_len
;
/* option length >= IP_OPT_LEN */
union
ip_opt_data
{
struct
ip_opt_data_sec
sec
;
/* IP_OPT_SEC */
struct
ip_opt_data_rr
rr
;
/* IP_OPT_{L,S}RR */
struct
ip_opt_data_ts
ts
;
/* IP_OPT_TS */
uint16_t
satid
;
/* IP_OPT_SATID */
uint16_t
mtu
;
/* IP_OPT_MTU{P,R} */
struct
ip_opt_data_tr
tr
;
/* IP_OPT_TR */
uint32_t
addext
[
2
];
/* IP_OPT_ADDEXT */
uint16_t
rtralt
;
/* IP_OPT_RTRALT */
uint32_t
sdb
[
9
];
/* IP_OPT_SDB */
uint8_t
data8
[
IP_OPT_LEN_MAX
-
IP_OPT_LEN
];
}
opt_data
;
}
__attribute__
((
__packed__
));
#ifndef __GNUC__
# pragma pack()
#endif
/*
* Classful addressing
*/
#define IP_CLASSA(i) (((uint32_t)(i) & htonl(0x80000000)) == \
htonl(0x00000000))
#define IP_CLASSA_NET (htonl(0xff000000))
#define IP_CLASSA_NSHIFT 24
#define IP_CLASSA_HOST (htonl(0x00ffffff))
#define IP_CLASSA_MAX 128
#define IP_CLASSB(i) (((uint32_t)(i) & htonl(0xc0000000)) == \
htonl(0x80000000))
#define IP_CLASSB_NET (htonl(0xffff0000))
#define IP_CLASSB_NSHIFT 16
#define IP_CLASSB_HOST (htonl(0x0000ffff))
#define IP_CLASSB_MAX 65536
#define IP_CLASSC(i) (((uint32_t)(i) & htonl(0xe0000000)) == \
htonl(0xc0000000))
#define IP_CLASSC_NET (htonl(0xffffff00))
#define IP_CLASSC_NSHIFT 8
#define IP_CLASSC_HOST (htonl(0x000000ff))
#define IP_CLASSD(i) (((uint32_t)(i) & htonl(0xf0000000)) == \
htonl(0xe0000000))
/* These ones aren't really net and host fields, but routing needn't know. */
#define IP_CLASSD_NET (htonl(0xf0000000))
#define IP_CLASSD_NSHIFT 28
#define IP_CLASSD_HOST (htonl(0x0fffffff))
#define IP_MULTICAST(i) IP_CLASSD(i)
#define IP_EXPERIMENTAL(i) (((uint32_t)(i) & htonl(0xf0000000)) == \
htonl(0xf0000000))
#define IP_BADCLASS(i) (((uint32_t)(i) & htonl(0xf0000000)) == \
htonl(0xf0000000))
#define IP_LOCAL_GROUP(i) (((uint32_t)(i) & htonl(0xffffff00)) == \
htonl(0xe0000000))
/*
* Reserved addresses
*/
#define IP_ADDR_ANY (htonl(0x00000000))
/* 0.0.0.0 */
#define IP_ADDR_BROADCAST (htonl(0xffffffff))
/* 255.255.255.255 */
#define IP_ADDR_LOOPBACK (htonl(0x7f000001))
/* 127.0.0.1 */
#define IP_ADDR_MCAST_ALL (htonl(0xe0000001))
/* 224.0.0.1 */
#define IP_ADDR_MCAST_LOCAL (htonl(0xe00000ff))
/* 224.0.0.225 */
#define ip_pack_hdr(hdr, tos, len, id, off, ttl, p, src, dst) do { \
struct ip_hdr *ip_pack_p = (struct ip_hdr *)(hdr); \
ip_pack_p->ip_v = 4; ip_pack_p->ip_hl = 5; \
ip_pack_p->ip_tos = tos; ip_pack_p->ip_len = htons(len); \
ip_pack_p->ip_id = htons(id); ip_pack_p->ip_off = htons(off); \
ip_pack_p->ip_ttl = ttl; ip_pack_p->ip_p = p; \
ip_pack_p->ip_src = src; ip_pack_p->ip_dst = dst; \
} while (0)
typedef
struct
ip_handle
ip_t
;
__BEGIN_DECLS
ip_t
*
ip_open
(
void
);
size_t
ip_send
(
ip_t
*
i
,
const
void
*
buf
,
size_t
len
);
ip_t
*
ip_close
(
ip_t
*
i
);
char
*
ip_ntop
(
const
ip_addr_t
*
ip
,
char
*
dst
,
size_t
len
);
int
ip_pton
(
const
char
*
src
,
ip_addr_t
*
dst
);
char
*
ip_ntoa
(
const
ip_addr_t
*
ip
);
#define ip_aton ip_pton
size_t
ip_add_option
(
void
*
buf
,
size_t
len
,
int
proto
,
const
void
*
optbuf
,
size_t
optlen
);
void
ip_checksum
(
void
*
buf
,
size_t
len
);
inline
int
ip_cksum_add
(
const
void
*
buf
,
size_t
len
,
int
cksum
)
{
uint16_t
*
sp
=
(
uint16_t
*
)
buf
;
int
sn
;
sn
=
len
/
2
;
do
{
cksum
+=
*
sp
++
;
}
while
(
--
sn
>
0
);
if
(
len
&
1
)
cksum
+=
htons
(
*
(
u_char
*
)
sp
<<
8
);
return
(
cksum
);
}
inline
uint16_t
ip_cksum_carry
(
int
x
)
{
x
=
(
x
>>
16
)
+
(
x
&
0xffff
);
return
~
(
x
+
(
x
>>
16
))
&
0xffff
;
}
__END_DECLS
#endif
/* DNET_IP_H */
sims/nic/e1000_gem5/gem5/ip6.h
0 → 100644
View file @
d365cd9e
/*
* ip6.h
*
* Internet Protocol, Version 6 (RFC 2460).
*
* Copyright (c) 2002 Dug Song <dugsong@monkey.org>
*
* $Id: ip6.h,v 1.6 2004/02/23 10:01:15 dugsong Exp $
*/
#ifndef DNET_IP6_H
#define DNET_IP6_H
#define IP6_ADDR_LEN 16
#define IP6_ADDR_BITS 128
#define IP6_HDR_LEN 40
/* IPv6 header length */
#define IP6_LEN_MIN IP6_HDR_LEN
#define IP6_LEN_MAX 65535
/* non-jumbo payload */
#define IP6_MTU_MIN 1280
/* minimum MTU (1024 + 256) */
typedef
struct
ip6_addr
{
uint8_t
data
[
IP6_ADDR_LEN
];
}
ip6_addr_t
;
#ifndef __GNUC__
# define __attribute__(x)
# pragma pack(1)
#endif
/*
* IPv6 header
*/
struct
ip6_hdr
{
union
{
struct
ip6_hdr_ctl
{
uint32_t
ip6_un1_flow
;
/* 20 bits of flow ID */
uint16_t
ip6_un1_plen
;
/* payload length */
uint8_t
ip6_un1_nxt
;
/* next header */
uint8_t
ip6_un1_hlim
;
/* hop limit */
}
ip6_un1
;
uint8_t
ip6_un2_vfc
;
/* 4 bits version, top 4 bits class */
}
ip6_ctlun
;
ip6_addr_t
ip6_src
;
ip6_addr_t
ip6_dst
;
}
__attribute__
((
__packed__
));
#define ip6_vfc ip6_ctlun.ip6_un2_vfc
#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow
#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen
#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt
/* IP_PROTO_* */
#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim
#define IP6_VERSION 0x60
#define IP6_VERSION_MASK 0xf0
/* ip6_vfc version */
#if DNET_BYTESEX == DNET_BIG_ENDIAN
#define IP6_FLOWINFO_MASK 0x0fffffff
/* ip6_flow info (28 bits) */
#define IP6_FLOWLABEL_MASK 0x000fffff
/* ip6_flow label (20 bits) */
#elif DNET_BYTESEX == DNET_LIL_ENDIAN
#define IP6_FLOWINFO_MASK 0xffffff0f
/* ip6_flow info (28 bits) */
#define IP6_FLOWLABEL_MASK 0xffff0f00
/* ip6_flow label (20 bits) */
#endif
/*
* Hop limit (ip6_hlim)
*/
#define IP6_HLIM_DEFAULT 64
#define IP6_HLIM_MAX 255
/*
* Preferred extension header order from RFC 2460, 4.1:
*
* IP_PROTO_IPV6, IP_PROTO_HOPOPTS, IP_PROTO_DSTOPTS, IP_PROTO_ROUTING,
* IP_PROTO_FRAGMENT, IP_PROTO_AH, IP_PROTO_ESP, IP_PROTO_DSTOPTS, IP_PROTO_*
*/
/*
* Routing header data (IP_PROTO_ROUTING)
*/
struct
ip6_ext_data_routing
{
uint8_t
type
;
/* routing type */
uint8_t
segleft
;
/* segments left */
/* followed by routing type specific data */
}
__attribute__
((
__packed__
));
struct
ip6_ext_data_routing0
{
uint8_t
type
;
/* always zero */
uint8_t
segleft
;
/* segments left */
uint8_t
reserved
;
/* reserved field */
uint8_t
slmap
[
3
];
/* strict/loose bit map */
ip6_addr_t
addr
[
1
];
/* up to 23 addresses */
}
__attribute__
((
__packed__
));
/*
* Fragment header data (IP_PROTO_FRAGMENT)
*/
struct
ip6_ext_data_fragment
{
uint16_t
offlg
;
/* offset, reserved, and flag */
uint32_t
ident
;
/* identification */
}
__attribute__
((
__packed__
));
/*
* Fragmentation offset, reserved, and flags (offlg)
*/
#if DNET_BYTESEX == DNET_BIG_ENDIAN
#define IP6_OFF_MASK 0xfff8
/* mask out offset from offlg */
#define IP6_RESERVED_MASK 0x0006
/* reserved bits in offlg */
#define IP6_MORE_FRAG 0x0001
/* more-fragments flag */
#elif DNET_BYTESEX == DNET_LIL_ENDIAN
#define IP6_OFF_MASK 0xf8ff
/* mask out offset from offlg */
#define IP6_RESERVED_MASK 0x0600
/* reserved bits in offlg */
#define IP6_MORE_FRAG 0x0100
/* more-fragments flag */
#endif
/*
* Option types, for IP_PROTO_HOPOPTS, IP_PROTO_DSTOPTS headers
*/
#define IP6_OPT_PAD1 0x00
/* 00 0 00000 */
#define IP6_OPT_PADN 0x01
/* 00 0 00001 */
#define IP6_OPT_JUMBO 0xC2
/* 11 0 00010 = 194 */
#define IP6_OPT_JUMBO_LEN 6
#define IP6_OPT_RTALERT 0x05
/* 00 0 00101 */
#define IP6_OPT_RTALERT_LEN 4
#define IP6_OPT_RTALERT_MLD 0
/* Datagram contains an MLD message */
#define IP6_OPT_RTALERT_RSVP 1
/* Datagram contains an RSVP message */
#define IP6_OPT_RTALERT_ACTNET 2
/* contains an Active Networks msg */
#define IP6_OPT_LEN_MIN 2
#define IP6_OPT_TYPE(o) ((o) & 0xC0)
/* high 2 bits of opt_type */
#define IP6_OPT_TYPE_SKIP 0x00
/* continue processing on failure */
#define IP6_OPT_TYPE_DISCARD 0x40
/* discard packet on failure */
#define IP6_OPT_TYPE_FORCEICMP 0x80
/* discard and send ICMP on failure */
#define IP6_OPT_TYPE_ICMP 0xC0
/* ...only if non-multicast dst */
#define IP6_OPT_MUTABLE 0x20
/* option data may change en route */
/*
* Extension header (chained via {ip6,ext}_nxt, following IPv6 header)
*/
struct
ip6_ext_hdr
{
uint8_t
ext_nxt
;
/* next header */
uint8_t
ext_len
;
/* following length in units of 8 octets */
union
{
struct
ip6_ext_data_routing
routing
;
struct
ip6_ext_data_fragment
fragment
;
}
ext_data
;
}
__attribute__
((
__packed__
));
#ifndef __GNUC__
# pragma pack()
#endif
/*
* Reserved addresses
*/
#define IP6_ADDR_UNSPEC \
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
#define IP6_ADDR_LOOPBACK \
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"
#define ip6_pack_hdr(hdr, fc, fl, plen, nxt, hlim, src, dst) do { \
struct ip6_hdr *ip6 = (struct ip6_hdr *)(hdr); \
ip6->ip6_flow = htonl(((uint32_t)(fc) << 28) & \
(IP6_FLOWLABEL_MASK | (fl))); \
ip6->ip6_vfc = (IP6_VERSION | ((fc) >> 4)); \
ip6->ip6_plen = htons((plen)); \
ip6->ip6_nxt = (nxt); ip6->ip6_hlim = (hlim); \
memmove(&ip6->ip6_src, &(src), IP6_ADDR_LEN); \
memmove(&ip6->ip6_dst, &(dst), IP6_ADDR_LEN); \
} while (0);
__BEGIN_DECLS
char
*
ip6_ntop
(
const
ip6_addr_t
*
ip6
,
char
*
dst
,
size_t
size
);
int
ip6_pton
(
const
char
*
src
,
ip6_addr_t
*
dst
);
char
*
ip6_ntoa
(
const
ip6_addr_t
*
ip6
);
#define ip6_aton ip6_pton
void
ip6_checksum
(
void
*
buf
,
size_t
len
);
__END_DECLS
#endif
/* DNET_IP6_H */
sims/nic/e1000_gem5/gem5/pktfifo.cc
0 → 100644
View file @
d365cd9e
/*
* Copyright (c) 2004-2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "sims/nic/e1000_gem5/gem5/pktfifo.h"
using
namespace
std
;
bool
PacketFifo
::
copyout
(
void
*
dest
,
unsigned
offset
,
unsigned
len
)
{
char
*
data
=
(
char
*
)
dest
;
if
(
offset
+
len
>=
size
())
return
false
;
iterator
i
=
fifo
.
begin
();
iterator
end
=
fifo
.
end
();
while
(
len
>
0
)
{
EthPacketPtr
&
pkt
=
i
->
packet
;
while
(
offset
>=
pkt
->
length
)
{
offset
-=
pkt
->
length
;
++
i
;
}
if
(
i
==
end
)
panic
(
"invalid fifo"
);
unsigned
size
=
min
(
pkt
->
length
-
offset
,
len
);
memcpy
(
data
,
pkt
->
data
,
size
);
offset
=
0
;
len
-=
size
;
data
+=
size
;
++
i
;
}
return
true
;
}
\ No newline at end of file
sims/nic/e1000_gem5/gem5/pktfifo.h
0 → 100644
View file @
d365cd9e
/*
* Copyright (c) 2004-2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __DEV_NET_PKTFIFO_HH__
#define __DEV_NET_PKTFIFO_HH__
#include <iosfwd>
#include <list>
#include <string>
#include "sims/nic/e1000_gem5/support.h"
struct
EthPacket
;
struct
PacketFifoEntry
{
EthPacketPtr
packet
;
uint64_t
number
;
unsigned
slack
;
int
priv
;
PacketFifoEntry
()
{
clear
();
}
PacketFifoEntry
(
const
PacketFifoEntry
&
s
)
:
packet
(
s
.
packet
),
number
(
s
.
number
),
slack
(
s
.
slack
),
priv
(
s
.
priv
)
{
}
PacketFifoEntry
(
EthPacketPtr
p
,
uint64_t
n
)
:
packet
(
p
),
number
(
n
),
slack
(
0
),
priv
(
-
1
)
{
}
void
clear
()
{
packet
=
NULL
;
number
=
0
;
slack
=
0
;
priv
=
-
1
;
}
};
class
PacketFifo
{
public:
typedef
std
::
list
<
PacketFifoEntry
>
fifo_list
;
typedef
fifo_list
::
iterator
iterator
;
typedef
fifo_list
::
const_iterator
const_iterator
;
protected:
std
::
list
<
PacketFifoEntry
>
fifo
;
uint64_t
_counter
;
unsigned
_maxsize
;
unsigned
_size
;
unsigned
_reserved
;
public:
explicit
PacketFifo
(
int
max
)
:
_counter
(
0
),
_maxsize
(
max
),
_size
(
0
),
_reserved
(
0
)
{}
virtual
~
PacketFifo
()
{}
unsigned
packets
()
const
{
return
fifo
.
size
();
}
unsigned
maxsize
()
const
{
return
_maxsize
;
}
unsigned
size
()
const
{
return
_size
;
}
unsigned
reserved
()
const
{
return
_reserved
;
}
unsigned
avail
()
const
{
return
_maxsize
-
_size
-
_reserved
;
}
bool
empty
()
const
{
return
size
()
<=
0
;
}
bool
full
()
const
{
return
avail
()
<=
0
;
}
unsigned
reserve
(
unsigned
len
=
0
)
{
assert
(
avail
()
>=
len
);
_reserved
+=
len
;
return
_reserved
;
}
iterator
begin
()
{
return
fifo
.
begin
();
}
iterator
end
()
{
return
fifo
.
end
();
}
const_iterator
begin
()
const
{
return
fifo
.
begin
();
}
const_iterator
end
()
const
{
return
fifo
.
end
();
}
EthPacketPtr
front
()
{
return
fifo
.
begin
()
->
packet
;
}
bool
push
(
EthPacketPtr
ptr
)
{
assert
(
ptr
->
length
);
assert
(
_reserved
<=
ptr
->
length
);
if
(
avail
()
<
ptr
->
length
-
_reserved
)
return
false
;
_size
+=
ptr
->
length
;
PacketFifoEntry
entry
;
entry
.
packet
=
ptr
;
entry
.
number
=
_counter
++
;
fifo
.
push_back
(
entry
);
_reserved
=
0
;
return
true
;
}
void
pop
()
{
if
(
empty
())
return
;
iterator
entry
=
fifo
.
begin
();
_size
-=
entry
->
packet
->
length
;
_size
-=
entry
->
slack
;
entry
->
packet
=
NULL
;
fifo
.
pop_front
();
}
void
clear
()
{
for
(
iterator
i
=
begin
();
i
!=
end
();
++
i
)
i
->
clear
();
fifo
.
clear
();
_size
=
0
;
_reserved
=
0
;
}
void
remove
(
iterator
i
)
{
if
(
i
!=
fifo
.
begin
())
{
iterator
prev
=
i
;
--
prev
;
assert
(
prev
!=
fifo
.
end
());
prev
->
slack
+=
i
->
packet
->
length
;
prev
->
slack
+=
i
->
slack
;
}
else
{
_size
-=
i
->
packet
->
length
;
_size
-=
i
->
slack
;
}
i
->
clear
();
fifo
.
erase
(
i
);
}
bool
copyout
(
void
*
dest
,
unsigned
offset
,
unsigned
len
);
int
countPacketsBefore
(
const_iterator
i
)
const
{
if
(
i
==
fifo
.
end
())
return
0
;
return
i
->
number
-
fifo
.
begin
()
->
number
;
}
int
countPacketsAfter
(
const_iterator
i
)
const
{
auto
end
=
fifo
.
end
();
if
(
i
==
end
)
return
0
;
return
(
--
end
)
->
number
-
i
->
number
;
}
void
check
()
const
{
unsigned
total
=
0
;
for
(
auto
i
=
begin
();
i
!=
end
();
++
i
)
total
+=
i
->
packet
->
length
+
i
->
slack
;
if
(
total
!=
_size
)
panic
(
"total (%d) is not == to size (%d)
\n
"
,
total
,
_size
);
}
};
#endif // __DEV_NET_PKTFIFO_HH__
sims/nic/e1000_gem5/gem5/tcp.h
0 → 100644
View file @
d365cd9e
/*
* tcp.h
*
* Transmission Control Protocol (RFC 793).
*
* Copyright (c) 2000 Dug Song <dugsong@monkey.org>
*
* $Id: tcp.h,v 1.17 2004/02/23 10:02:11 dugsong Exp $
*/
#ifndef DNET_TCP_H
#define DNET_TCP_H
#define TCP_HDR_LEN 20
/* base TCP header length */
#define TCP_OPT_LEN 2
/* base TCP option length */
#define TCP_OPT_LEN_MAX 40
#define TCP_HDR_LEN_MAX (TCP_HDR_LEN + TCP_OPT_LEN_MAX)
#ifndef __GNUC__
# define __attribute__(x)
# pragma pack(1)
#endif
/*
* TCP header, without options
*/
struct
tcp_hdr
{
uint16_t
th_sport
;
/* source port */
uint16_t
th_dport
;
/* destination port */
uint32_t
th_seq
;
/* sequence number */
uint32_t
th_ack
;
/* acknowledgment number */
#if DNET_BYTESEX == DNET_BIG_ENDIAN
uint8_t
th_off
:
4
,
/* data offset */
th_x2:
4
;
/* (unused) */
#elif DNET_BYTESEX == DNET_LIL_ENDIAN
uint8_t
th_x2
:
4
,
th_off:
4
;
#else
# error "need to include <dnet.h>"
#endif
uint8_t
th_flags
;
/* control flags */
uint16_t
th_win
;
/* window */
uint16_t
th_sum
;
/* checksum */
uint16_t
th_urp
;
/* urgent pointer */
}
__attribute__
((
packed
));
/*
* TCP control flags (th_flags)
*/
#define TH_FIN 0x01
/* end of data */
#define TH_SYN 0x02
/* synchronize sequence numbers */
#define TH_RST 0x04
/* reset connection */
#define TH_PUSH 0x08
/* push */
#define TH_ACK 0x10
/* acknowledgment number set */
#define TH_URG 0x20
/* urgent pointer set */
#define TH_ECE 0x40
/* ECN echo, RFC 3168 */
#define TH_CWR 0x80
/* congestion window reduced */
#define TCP_PORT_MAX 65535
/* maximum port */
#define TCP_WIN_MAX 65535
/* maximum (unscaled) window */
/*
* Sequence number comparison macros
*/
#define TCP_SEQ_LT(a,b) ((int)((a)-(b)) < 0)
#define TCP_SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0)
#define TCP_SEQ_GT(a,b) ((int)((a)-(b)) > 0)
#define TCP_SEQ_GEQ(a,b) ((int)((a)-(b)) >= 0)
/*
* TCP FSM states
*/
#define TCP_STATE_CLOSED 0
/* closed */
#define TCP_STATE_LISTEN 1
/* listening from connection */
#define TCP_STATE_SYN_SENT 2
/* active, have sent SYN */
#define TCP_STATE_SYN_RECEIVED 3
/* have sent and received SYN */
#define TCP_STATE_ESTABLISHED 4
/* established */
#define TCP_STATE_CLOSE_WAIT 5
/* rcvd FIN, waiting for close */
#define TCP_STATE_FIN_WAIT_1 6
/* have closed, sent FIN */
#define TCP_STATE_CLOSING 7
/* closed xchd FIN, await FIN-ACK */
#define TCP_STATE_LAST_ACK 8
/* had FIN and close, await FIN-ACK */
#define TCP_STATE_FIN_WAIT_2 9
/* have closed, FIN is acked */
#define TCP_STATE_TIME_WAIT 10
/* in 2*MSL quiet wait after close */
#define TCP_STATE_MAX 11
/*
* Options (opt_type) - http://www.iana.org/assignments/tcp-parameters
*/
#define TCP_OPT_EOL 0
/* end of option list */
#define TCP_OPT_NOP 1
/* no operation */
#define TCP_OPT_MSS 2
/* maximum segment size */
#define TCP_OPT_WSCALE 3
/* window scale factor, RFC 1072 */
#define TCP_OPT_SACKOK 4
/* SACK permitted, RFC 2018 */
#define TCP_OPT_SACK 5
/* SACK, RFC 2018 */
#define TCP_OPT_ECHO 6
/* echo (obsolete), RFC 1072 */
#define TCP_OPT_ECHOREPLY 7
/* echo reply (obsolete), RFC 1072 */
#define TCP_OPT_TIMESTAMP 8
/* timestamp, RFC 1323 */
#define TCP_OPT_POCONN 9
/* partial order conn, RFC 1693 */
#define TCP_OPT_POSVC 10
/* partial order service, RFC 1693 */
#define TCP_OPT_CC 11
/* connection count, RFC 1644 */
#define TCP_OPT_CCNEW 12
/* CC.NEW, RFC 1644 */
#define TCP_OPT_CCECHO 13
/* CC.ECHO, RFC 1644 */
#define TCP_OPT_ALTSUM 14
/* alt checksum request, RFC 1146 */
#define TCP_OPT_ALTSUMDATA 15
/* alt checksum data, RFC 1146 */
#define TCP_OPT_SKEETER 16
/* Skeeter */
#define TCP_OPT_BUBBA 17
/* Bubba */
#define TCP_OPT_TRAILSUM 18
/* trailer checksum */
#define TCP_OPT_MD5 19
/* MD5 signature, RFC 2385 */
#define TCP_OPT_SCPS 20
/* SCPS capabilities */
#define TCP_OPT_SNACK 21
/* selective negative acks */
#define TCP_OPT_REC 22
/* record boundaries */
#define TCP_OPT_CORRUPT 23
/* corruption experienced */
#define TCP_OPT_SNAP 24
/* SNAP */
#define TCP_OPT_TCPCOMP 26
/* TCP compression filter */
#define TCP_OPT_MAX 27
#define TCP_OPT_TYPEONLY(type) \
((type) == TCP_OPT_EOL || (type) == TCP_OPT_NOP)
/*
* TCP option (following TCP header)
*/
struct
tcp_opt
{
uint8_t
opt_type
;
/* option type */
uint8_t
opt_len
;
/* option length >= TCP_OPT_LEN */
union
tcp_opt_data
{
uint16_t
mss
;
/* TCP_OPT_MSS */
uint8_t
wscale
;
/* TCP_OPT_WSCALE */
uint16_t
sack
[
19
];
/* TCP_OPT_SACK */
uint32_t
echo
;
/* TCP_OPT_ECHO{REPLY} */
uint32_t
timestamp
[
2
];
/* TCP_OPT_TIMESTAMP */
uint32_t
cc
;
/* TCP_OPT_CC{NEW,ECHO} */
uint8_t
cksum
;
/* TCP_OPT_ALTSUM */
uint8_t
md5
[
16
];
/* TCP_OPT_MD5 */
uint8_t
data8
[
TCP_OPT_LEN_MAX
-
TCP_OPT_LEN
];
}
opt_data
;
}
__attribute__
((
__packed__
));
#ifndef __GNUC__
# pragma pack()
#endif
#define tcp_pack_hdr(hdr, sport, dport, seq, ack, flags, win, urp) do { \
struct tcp_hdr *tcp_pack_p = (struct tcp_hdr *)(hdr); \
tcp_pack_p->th_sport = htons(sport); \
tcp_pack_p->th_dport = htons(dport); \
tcp_pack_p->th_seq = htonl(seq); \
tcp_pack_p->th_ack = htonl(ack); \
tcp_pack_p->th_x2 = 0; tcp_pack_p->th_off = 5; \
tcp_pack_p->th_flags = flags; \
tcp_pack_p->th_win = htons(win); \
tcp_pack_p->th_urp = htons(urp); \
} while (0)
#endif
/* DNET_TCP_H */
sims/nic/e1000_gem5/gem5/udp.h
0 → 100644
View file @
d365cd9e
/*
* udp.h
*
* User Datagram Protocol (RFC 768).
*
* Copyright (c) 2000 Dug Song <dugsong@monkey.org>
*
* $Id: udp.h,v 1.8 2002/04/02 05:05:39 dugsong Exp $
*/
#ifndef DNET_UDP_H
#define DNET_UDP_H
#define UDP_HDR_LEN 8
struct
udp_hdr
{
uint16_t
uh_sport
;
/* source port */
uint16_t
uh_dport
;
/* destination port */
uint16_t
uh_ulen
;
/* udp length (including header) */
uint16_t
uh_sum
;
/* udp checksum */
};
#define UDP_PORT_MAX 65535
#define udp_pack_hdr(hdr, sport, dport, ulen) do { \
struct udp_hdr *udp_pack_p = (struct udp_hdr *)(hdr); \
udp_pack_p->uh_sport = htons(sport); \
udp_pack_p->uh_dport = htons(dport); \
udp_pack_p->uh_ulen = htons(ulen); \
} while (0)
#endif
/* DNET_UDP_H */
sims/nic/e1000_gem5/i8254xGBe.cc
0 → 100644
View file @
d365cd9e
This diff is collapsed.
Click to expand it.
sims/nic/e1000_gem5/i8254xGBe.h
0 → 100644
View file @
d365cd9e
/*
* Copyright (c) 2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* @file
* Device model for Intel's 8254x line of gigabit ethernet controllers.
*/
#ifndef __DEV_NET_I8254XGBE_HH__
#define __DEV_NET_I8254XGBE_HH__
#include <deque>
#include <string>
#include "sims/nic/e1000_gem5/support.h"
#include "sims/nic/e1000_gem5/gem5/pktfifo.h"
#include "sims/nic/e1000_gem5/gem5/inet.h"
#include "sims/nic/e1000_gem5/i8254xGBe_defs.h"
struct
IGbEParams
{
int
rx_fifo_size
;
int
tx_fifo_size
;
Tick
fetch_delay
,
wb_delay
;
Tick
fetch_comp_delay
,
wb_comp_delay
;
Tick
rx_write_delay
,
tx_read_delay
;
Tick
pio_delay
;
uint16_t
phy_pid
;
uint16_t
phy_epid
;
int
rx_desc_cache_size
;
int
tx_desc_cache_size
;
};
class
IGbE
:
public
nicbm
::
Runner
::
Device
{
protected:
Tick
curTick
()
{
return
runner_
->
TimePs
();
}
virtual
void
SetupIntro
(
struct
SimbricksProtoPcieDevIntro
&
di
);
virtual
void
RegRead
(
uint8_t
bar
,
uint64_t
addr
,
void
*
dest
,
size_t
len
);
virtual
void
RegWrite
(
uint8_t
bar
,
uint64_t
addr
,
const
void
*
src
,
size_t
len
);
virtual
void
DmaComplete
(
nicbm
::
DMAOp
&
op
);
virtual
void
EthRx
(
uint8_t
port
,
const
void
*
data
,
size_t
len
);
virtual
void
Timed
(
nicbm
::
TimedEvent
&
te
);
void
schedule
(
EventFunctionWrapper
&
ev
,
Tick
t
);
void
reschedule
(
EventFunctionWrapper
&
ev
,
Tick
t
,
bool
always
=
false
);
void
deschedule
(
EventFunctionWrapper
&
ev
);
void
intrPost
();
void
intrClear
();
void
dmaWrite
(
Addr
daddr
,
size_t
len
,
EventFunctionWrapper
&
ev
,
const
void
*
buf
,
Tick
delay
);
void
dmaRead
(
Addr
saddr
,
size_t
len
,
EventFunctionWrapper
&
ev
,
void
*
buf
,
Tick
delay
);
bool
sendPacket
(
EthPacketPtr
p
);
private:
const
IGbEParams
&
params_
;
// device registers
iGbReg
::
Regs
regs
;
// eeprom data, status and control bits
int
eeOpBits
,
eeAddrBits
,
eeDataBits
;
uint8_t
eeOpcode
,
eeAddr
;
uint16_t
flash
[
iGbReg
::
EEPROM_SIZE
];
// packet fifos
PacketFifo
rxFifo
;
PacketFifo
txFifo
;
// Packet that we are currently putting into the txFifo
EthPacketPtr
txPacket
;
// Should to Rx/Tx State machine tick?
bool
inTick
;
bool
rxTick
;
bool
txTick
;
bool
txFifoTick
;
bool
rxDmaPacket
;
// Number of bytes copied from current RX packet
unsigned
pktOffset
;
// Delays in managaging descriptors
Tick
fetchDelay
,
wbDelay
;
Tick
fetchCompDelay
,
wbCompDelay
;
Tick
rxWriteDelay
,
txReadDelay
;
Tick
pioDelay
;
unsigned
cacheBlockSize
()
const
{
return
64
;
}
// Event and function to deal with RDTR timer expiring
void
rdtrProcess
()
{
rxDescCache
.
writeback
(
0
);
DPRINTF
(
EthernetIntr
,
"Posting RXT interrupt because RDTR timer expired
\n
"
);
postInterrupt
(
iGbReg
::
IT_RXT
);
}
EventFunctionWrapper
rdtrEvent
;
// Event and function to deal with RADV timer expiring
void
radvProcess
()
{
rxDescCache
.
writeback
(
0
);
DPRINTF
(
EthernetIntr
,
"Posting RXT interrupt because RADV timer expired
\n
"
);
postInterrupt
(
iGbReg
::
IT_RXT
);
}
EventFunctionWrapper
radvEvent
;
// Event and function to deal with TADV timer expiring
void
tadvProcess
()
{
txDescCache
.
writeback
(
0
);
DPRINTF
(
EthernetIntr
,
"Posting TXDW interrupt because TADV timer expired
\n
"
);
postInterrupt
(
iGbReg
::
IT_TXDW
);
}
EventFunctionWrapper
tadvEvent
;
// Event and function to deal with TIDV timer expiring
void
tidvProcess
()
{
txDescCache
.
writeback
(
0
);
DPRINTF
(
EthernetIntr
,
"Posting TXDW interrupt because TIDV timer expired
\n
"
);
postInterrupt
(
iGbReg
::
IT_TXDW
);
}
EventFunctionWrapper
tidvEvent
;
// Main event to tick the device
void
tick
();
EventFunctionWrapper
tickEvent
;
uint64_t
macAddr
;
void
rxStateMachine
();
void
txStateMachine
();
void
txWire
();
/** Write an interrupt into the interrupt pending register and check mask
* and interrupt limit timer before sending interrupt to CPU
* @param t the type of interrupt we are posting
* @param now should we ignore the interrupt limiting timer
*/
void
postInterrupt
(
iGbReg
::
IntTypes
t
,
bool
now
=
false
);
/** Check and see if changes to the mask register have caused an interrupt
* to need to be sent or perhaps removed an interrupt cause.
*/
void
chkInterrupt
();
/** Send an interrupt to the cpu
*/
void
delayIntEvent
();
void
cpuPostInt
();
// Event to moderate interrupts
EventFunctionWrapper
interEvent
;
/** Clear the interupt line to the cpu
*/
void
cpuClearInt
();
Tick
intClock
()
{
return
1024
*
1024
;
/* 1us */
}
/** This function is used to restart the clock so it can handle things like
* draining and resume in one place. */
void
restartClock
();
/** Check if all the draining things that need to occur have occured and
* handle the drain event if so.
*/
//void checkDrain();
void
anBegin
(
std
::
string
sm
,
std
::
string
st
,
int
flags
=
0
)
{
}
void
anQ
(
std
::
string
sm
,
std
::
string
q
)
{
}
void
anDq
(
std
::
string
sm
,
std
::
string
q
)
{
}
void
anPq
(
std
::
string
sm
,
std
::
string
q
,
int
num
=
1
)
{
}
void
anRq
(
std
::
string
sm
,
std
::
string
q
,
int
num
=
1
)
{
}
void
anWe
(
std
::
string
sm
,
std
::
string
q
)
{}
void
anWf
(
std
::
string
sm
,
std
::
string
q
)
{}
template
<
class
T
>
class
DescCache
{
protected:
virtual
Addr
descBase
()
const
=
0
;
virtual
long
descHead
()
const
=
0
;
virtual
long
descTail
()
const
=
0
;
virtual
long
descLen
()
const
=
0
;
virtual
void
updateHead
(
long
h
)
=
0
;
virtual
void
enableSm
()
=
0
;
virtual
void
actionAfterWb
()
{}
virtual
void
fetchAfterWb
()
=
0
;
typedef
std
::
deque
<
T
*>
CacheType
;
CacheType
usedCache
;
CacheType
unusedCache
;
T
*
fetchBuf
;
T
*
wbBuf
;
// Pointer to the device we cache for
IGbE
*
igbe
;
// Name of this descriptor cache
std
::
string
_name
;
// How far we've cached
int
cachePnt
;
// The size of the descriptor cache
int
size
;
// How many descriptors we are currently fetching
int
curFetching
;
// How many descriptors we are currently writing back
int
wbOut
;
// if the we wrote back to the end of the descriptor ring and are going
// to have to wrap and write more
bool
moreToWb
;
// What the alignment is of the next descriptor writeback
Addr
wbAlignment
;
/** The packet that is currently being dmad to memory if any */
EthPacketPtr
pktPtr
;
/** Shortcut for DMA address translation */
Addr
pciToDma
(
Addr
a
)
{
return
a
;
}
public:
/** Annotate sm*/
std
::
string
annSmFetch
,
annSmWb
,
annUnusedDescQ
,
annUsedCacheQ
,
annUsedDescQ
,
annUnusedCacheQ
,
annDescQ
;
DescCache
(
IGbE
*
i
,
const
std
::
string
n
,
int
s
);
virtual
~
DescCache
();
std
::
string
name
()
{
return
_name
;
}
/** If the address/len/head change when we've got descriptors that are
* dirty that is very bad. This function checks that we don't and if we
* do panics.
*/
void
areaChanged
();
void
writeback
(
Addr
aMask
);
void
writeback1
();
EventFunctionWrapper
wbDelayEvent
;
/** Fetch a chunk of descriptors into the descriptor cache.
* Calls fetchComplete when the memory system returns the data
*/
void
fetchDescriptors
();
void
fetchDescriptors1
();
EventFunctionWrapper
fetchDelayEvent
;
/** Called by event when dma to read descriptors is completed
*/
void
fetchComplete
();
EventFunctionWrapper
fetchEvent
;
/** Called by event when dma to writeback descriptors is completed
*/
void
wbComplete
();
EventFunctionWrapper
wbEvent
;
/* Return the number of descriptors left in the ring, so the device has
* a way to figure out if it needs to interrupt.
*/
unsigned
descLeft
()
const
{
unsigned
left
=
unusedCache
.
size
();
if
(
cachePnt
>
descTail
())
left
+=
(
descLen
()
-
cachePnt
+
descTail
());
else
left
+=
(
descTail
()
-
cachePnt
);
return
left
;
}
/* Return the number of descriptors used and not written back.
*/
unsigned
descUsed
()
const
{
return
usedCache
.
size
();
}
/* Return the number of cache unused descriptors we have. */
unsigned
descUnused
()
const
{
return
unusedCache
.
size
();
}
/* Get into a state where the descriptor address/head/etc colud be
* changed */
void
reset
();
virtual
bool
hasOutstandingEvents
()
{
return
wbEvent
.
scheduled
()
||
fetchEvent
.
scheduled
();
}
};
class
RxDescCache
:
public
DescCache
<
iGbReg
::
RxDesc
>
{
protected:
Addr
descBase
()
const
override
{
return
igbe
->
regs
.
rdba
();
}
long
descHead
()
const
override
{
return
igbe
->
regs
.
rdh
();
}
long
descLen
()
const
override
{
return
igbe
->
regs
.
rdlen
()
>>
4
;
}
long
descTail
()
const
override
{
return
igbe
->
regs
.
rdt
();
}
void
updateHead
(
long
h
)
override
{
igbe
->
regs
.
rdh
(
h
);
}
void
enableSm
()
override
;
void
fetchAfterWb
()
override
{
if
(
!
igbe
->
rxTick
)
fetchDescriptors
();
}
bool
pktDone
;
/** Variable to head with header/data completion events */
int
splitCount
;
/** Bytes of packet that have been copied, so we know when to
set EOP */
unsigned
bytesCopied
;
public:
RxDescCache
(
IGbE
*
i
,
std
::
string
n
,
int
s
);
/** Write the given packet into the buffer(s) pointed to by the
* descriptor and update the book keeping. Should only be called when
* there are no dma's pending.
* @param packet ethernet packet to write
* @param pkt_offset bytes already copied from the packet to memory
* @return pkt_offset + number of bytes copied during this call
*/
int
writePacket
(
EthPacketPtr
packet
,
int
pkt_offset
);
/** Called by event when dma to write packet is completed
*/
void
pktComplete
();
/** Check if the dma on the packet has completed and RX state machine
* can continue
*/
bool
packetDone
();
EventFunctionWrapper
pktEvent
;
// Event to handle issuing header and data write at the same time
// and only callking pktComplete() when both are completed
void
pktSplitDone
();
EventFunctionWrapper
pktHdrEvent
;
EventFunctionWrapper
pktDataEvent
;
bool
hasOutstandingEvents
()
override
;
};
friend
class
RxDescCache
;
RxDescCache
rxDescCache
;
class
TxDescCache
:
public
DescCache
<
iGbReg
::
TxDesc
>
{
protected:
Addr
descBase
()
const
override
{
return
igbe
->
regs
.
tdba
();
}
long
descHead
()
const
override
{
return
igbe
->
regs
.
tdh
();
}
long
descTail
()
const
override
{
return
igbe
->
regs
.
tdt
();
}
long
descLen
()
const
override
{
return
igbe
->
regs
.
tdlen
()
>>
4
;
}
void
updateHead
(
long
h
)
override
{
igbe
->
regs
.
tdh
(
h
);
}
void
enableSm
()
override
;
void
actionAfterWb
()
override
;
void
fetchAfterWb
()
override
{
if
(
!
igbe
->
txTick
)
fetchDescriptors
();
}
bool
pktDone
;
bool
isTcp
;
bool
pktWaiting
;
bool
pktMultiDesc
;
Addr
completionAddress
;
bool
completionEnabled
;
uint32_t
descEnd
;
// tso variables
bool
useTso
;
Addr
tsoHeaderLen
;
Addr
tsoMss
;
Addr
tsoTotalLen
;
Addr
tsoUsedLen
;
Addr
tsoPrevSeq
;
Addr
tsoPktPayloadBytes
;
bool
tsoLoadedHeader
;
bool
tsoPktHasHeader
;
uint8_t
tsoHeader
[
256
];
Addr
tsoDescBytesUsed
;
Addr
tsoCopyBytes
;
int
tsoPkts
;
public:
TxDescCache
(
IGbE
*
i
,
std
::
string
n
,
int
s
);
/** Tell the cache to DMA a packet from main memory into its buffer and
* return the size the of the packet to reserve space in tx fifo.
* @return size of the packet
*/
unsigned
getPacketSize
(
EthPacketPtr
p
);
void
getPacketData
(
EthPacketPtr
p
);
void
processContextDesc
();
/** Return the number of dsecriptors in a cache block for threshold
* operations.
*/
unsigned
descInBlock
(
unsigned
num_desc
)
{
return
num_desc
/
igbe
->
cacheBlockSize
()
/
sizeof
(
iGbReg
::
TxDesc
);
}
/** Ask if the packet has been transfered so the state machine can give
* it to the fifo.
* @return packet available in descriptor cache
*/
bool
packetAvailable
();
/** Ask if we are still waiting for the packet to be transfered.
* @return packet still in transit.
*/
bool
packetWaiting
()
{
return
pktWaiting
;
}
/** Ask if this packet is composed of multiple descriptors
* so even if we've got data, we need to wait for more before
* we can send it out.
* @return packet can't be sent out because it's a multi-descriptor
* packet
*/
bool
packetMultiDesc
()
{
return
pktMultiDesc
;}
/** Called by event when dma to write packet is completed
*/
void
pktComplete
();
EventFunctionWrapper
pktEvent
;
void
headerComplete
();
EventFunctionWrapper
headerEvent
;
void
completionWriteback
(
Addr
a
,
bool
enabled
)
{
DPRINTF
(
EthernetDesc
,
"Completion writeback Addr: %#lx enabled: %d
\n
"
,
a
,
enabled
);
completionAddress
=
a
;
completionEnabled
=
enabled
;
}
bool
hasOutstandingEvents
()
override
;
void
nullCallback
()
{
DPRINTF
(
EthernetDesc
,
"Completion writeback complete
\n
"
);
}
EventFunctionWrapper
nullEvent
;
};
friend
class
TxDescCache
;
TxDescCache
txDescCache
;
public:
typedef
IGbEParams
Params
;
const
Params
*
params
()
const
{
return
&
params_
;
}
IGbE
(
const
Params
*
params
);
~
IGbE
();
void
init
();
Tick
lastInterrupt
;
Tick
read
(
Addr
addr
,
uint8_t
len
,
void
*
dst
);
Tick
write
(
Addr
addr
,
uint8_t
len
,
const
void
*
src
);
bool
ethRxPkt
(
EthPacketPtr
packet
);
void
ethTxDone
();
};
#endif //__DEV_NET_I8254XGBE_HH__
sims/nic/e1000_gem5/i8254xGBe_defs.h
0 → 100644
View file @
d365cd9e
This diff is collapsed.
Click to expand it.
sims/nic/e1000_gem5/rules.mk
0 → 100644
View file @
d365cd9e
# Copyright 2021 Max Planck Institute for Software Systems, and
# National University of Singapore
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
include
mk/subdir_pre.mk
bin_e1000_gem5
:=
$(d)
e1000_gem5
OBJS
:=
$(
addprefix
$(d)
,e1000_gem5.o i8254xGBe.o gem5/bitfield.o gem5/inet.o
\
gem5/pktfifo.o
)
$(bin_e1000_gem5)
:
$(OBJS) $(lib_nicbm) $(lib_nicif)
CLEAN
:=
$(bin_e1000_gem5)
$(OBJS)
ALL
:=
$(bin_e1000_gem5)
include
mk/subdir_post.mk
sims/nic/e1000_gem5/support.h
0 → 100644
View file @
d365cd9e
#ifndef SIMS_NIC_E1000_GEM5_SUPPORT_H_
#define SIMS_NIC_E1000_GEM5_SUPPORT_H_
#include <arpa/inet.h>
#include <functional>
#include <memory>
#include <simbricks/nicbm/nicbm.h>
#define DNET_LIL_ENDIAN 42
#define DNET_BYTESEX DNET_LIL_ENDIAN
//#define DEBUG_E1000
#ifdef DEBUG_E1000
# define DPRINTF(x,y...) fprintf(stderr, #x ": " y)
#else
# define DPRINTF(x,y...) do { } while (0)
#endif
typedef
uint64_t
Addr
;
typedef
uint64_t
Tick
;
#define ETH_ADDR_LEN 6
class
Gem5TimerEv
;
class
EthPacketData
{
public:
unsigned
length
;
uint8_t
*
data
;
EthPacketData
(
unsigned
len
)
:
length
(
0
),
data
(
new
uint8_t
[
len
])
{
}
~
EthPacketData
()
{
delete
[]
data
;
}
};
typedef
std
::
shared_ptr
<
EthPacketData
>
EthPacketPtr
;
class
EventFunctionWrapper
:
public
nicbm
::
TimedEvent
{
public:
bool
sched
;
std
::
function
<
void
(
void
)
>
callback
;
std
::
string
_name
;
EventFunctionWrapper
(
const
std
::
function
<
void
(
void
)
>
&
callback
,
const
std
::
string
&
name
)
:
sched
(
false
),
callback
(
callback
),
_name
(
name
)
{
}
virtual
~
EventFunctionWrapper
()
=
default
;
bool
scheduled
()
{
return
sched
;
}
};
static
inline
uint16_t
htobe
(
uint16_t
x
)
{
return
htons
(
x
);
}
static
inline
uint16_t
htole
(
uint16_t
x
)
{
return
x
;
}
void
warn
(
const
char
*
fmt
,
...);
void
panic
(
const
char
*
fmt
,
...);
#endif // SIMS_NIC_E1000_GEM5_SUPPORT_H_
\ No newline at end of file
sims/nic/rules.mk
View file @
d365cd9e
...
...
@@ -24,6 +24,7 @@ include mk/subdir_pre.mk
$(eval
$(call
subdir,corundum))
$(eval
$(call
subdir,corundum_bm))
$(eval
$(call
subdir,e1000_gem5))
$(eval
$(call
subdir,i40e_bm))
include
mk/subdir_post.mk
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