Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
D
drivers
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Liam Naddell
drivers
Commits
aaafbbad
Commit
aaafbbad
authored
May 20, 2018
by
Jeremy Soller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update e1000d to new event
parent
32a58c3b
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
100 additions
and
81 deletions
+100
-81
e1000d/src/device.rs
e1000d/src/device.rs
+75
-53
e1000d/src/main.rs
e1000d/src/main.rs
+25
-28
No files found.
e1000d/src/device.rs
View file @
aaafbbad
use
std
::{
cmp
,
mem
,
ptr
,
slice
,
thread
,
time
};
use
std
::{
cmp
,
mem
,
ptr
,
slice
,
thread
};
use
std
::
collections
::
BTreeMap
;
use
netutils
::
setcfg
;
use
syscall
::
error
::{
Error
,
EACCES
,
EINVAL
,
EWOULDBLOCK
,
Result
};
use
syscall
::
error
::{
Error
,
EACCES
,
E
BADF
,
E
INVAL
,
EWOULDBLOCK
,
Result
};
use
syscall
::
flag
::
O_NONBLOCK
;
use
syscall
::
io
::
Dma
;
use
syscall
::
scheme
::
Scheme
;
use
syscall
::
scheme
::
Scheme
Mut
;
const
CTRL
:
u32
=
0x00
;
const
CTRL_LRST
:
u32
=
1
<<
3
;
...
...
@@ -98,29 +99,41 @@ pub struct Intel8254x {
receive_buffer
:
[
Dma
<
[
u8
;
16384
]
>
;
16
],
receive_ring
:
Dma
<
[
Rd
;
16
]
>
,
transmit_buffer
:
[
Dma
<
[
u8
;
16384
]
>
;
16
],
transmit_ring
:
Dma
<
[
Td
;
16
]
>
transmit_ring
:
Dma
<
[
Td
;
16
]
>
,
next_id
:
usize
,
pub
handles
:
BTreeMap
<
usize
,
usize
>
,
}
impl
Scheme
for
Intel8254x
{
fn
open
(
&
self
,
_
path
:
&
[
u8
],
flags
:
usize
,
uid
:
u32
,
_
gid
:
u32
)
->
Result
<
usize
>
{
impl
Scheme
Mut
for
Intel8254x
{
fn
open
(
&
mut
self
,
_
path
:
&
[
u8
],
flags
:
usize
,
uid
:
u32
,
_
gid
:
u32
)
->
Result
<
usize
>
{
if
uid
==
0
{
Ok
(
flags
)
self
.next_id
+=
1
;
self
.handles
.insert
(
self
.next_id
,
flags
);
Ok
(
self
.next_id
)
}
else
{
Err
(
Error
::
new
(
EACCES
))
}
}
fn
dup
(
&
self
,
id
:
usize
,
buf
:
&
[
u8
])
->
Result
<
usize
>
{
fn
dup
(
&
mut
self
,
id
:
usize
,
buf
:
&
[
u8
])
->
Result
<
usize
>
{
if
!
buf
.is_empty
()
{
return
Err
(
Error
::
new
(
EINVAL
));
}
Ok
(
id
)
let
flags
=
{
let
flags
=
self
.handles
.get
(
&
id
)
.ok_or
(
Error
::
new
(
EBADF
))
?
;
*
flags
};
self
.next_id
+=
1
;
self
.handles
.insert
(
self
.next_id
,
flags
);
Ok
(
self
.next_id
)
}
fn
read
(
&
self
,
id
:
usize
,
buf
:
&
mut
[
u8
])
->
Result
<
usize
>
{
let
head
=
unsafe
{
self
.read
(
RDH
)
};
let
mut
tail
=
unsafe
{
self
.read
(
RDT
)
};
fn
read
(
&
mut
self
,
id
:
usize
,
buf
:
&
mut
[
u8
])
->
Result
<
usize
>
{
let
flags
=
self
.handles
.get
(
&
id
)
.ok_or
(
Error
::
new
(
EBADF
))
?
;
let
head
=
unsafe
{
self
.read_reg
(
RDH
)
};
let
mut
tail
=
unsafe
{
self
.read_reg
(
RDT
)
};
tail
+=
1
;
if
tail
>=
self
.receive_ring
.len
()
as
u32
{
...
...
@@ -140,23 +153,25 @@ impl Scheme for Intel8254x {
i
+=
1
;
}
unsafe
{
self
.write
(
RDT
,
tail
)
};
unsafe
{
self
.write
_reg
(
RDT
,
tail
)
};
return
Ok
(
i
);
}
}
if
id
&
O_NONBLOCK
==
O_NONBLOCK
{
if
flags
&
O_NONBLOCK
==
O_NONBLOCK
{
Ok
(
0
)
}
else
{
Err
(
Error
::
new
(
EWOULDBLOCK
))
}
}
fn
write
(
&
self
,
_
id
:
usize
,
buf
:
&
[
u8
])
->
Result
<
usize
>
{
fn
write
(
&
mut
self
,
id
:
usize
,
buf
:
&
[
u8
])
->
Result
<
usize
>
{
let
_
flags
=
self
.handles
.get
(
&
id
)
.ok_or
(
Error
::
new
(
EBADF
))
?
;
loop
{
let
head
=
unsafe
{
self
.read
(
TDH
)
};
let
mut
tail
=
unsafe
{
self
.read
(
TDT
)
};
let
head
=
unsafe
{
self
.read
_reg
(
TDH
)
};
let
mut
tail
=
unsafe
{
self
.read
_reg
(
TDT
)
};
let
old_tail
=
tail
;
tail
+=
1
;
...
...
@@ -183,7 +198,7 @@ impl Scheme for Intel8254x {
i
+=
1
;
}
unsafe
{
self
.write
(
TDT
,
tail
)
};
unsafe
{
self
.write
_reg
(
TDT
,
tail
)
};
while
td
.status
==
0
{
thread
::
yield_now
();
...
...
@@ -194,11 +209,14 @@ impl Scheme for Intel8254x {
}
}
fn
fevent
(
&
self
,
_
id
:
usize
,
_
flags
:
usize
)
->
Result
<
usize
>
{
Ok
(
0
)
fn
fevent
(
&
mut
self
,
id
:
usize
,
_
flags
:
usize
)
->
Result
<
usize
>
{
let
_
flags
=
self
.handles
.get
(
&
id
)
.ok_or
(
Error
::
new
(
EBADF
))
?
;
Ok
(
id
)
}
fn
fpath
(
&
self
,
_
id
:
usize
,
buf
:
&
mut
[
u8
])
->
Result
<
usize
>
{
fn
fpath
(
&
mut
self
,
id
:
usize
,
buf
:
&
mut
[
u8
])
->
Result
<
usize
>
{
let
_
flags
=
self
.handles
.get
(
&
id
)
.ok_or
(
Error
::
new
(
EBADF
))
?
;
let
mut
i
=
0
;
let
scheme_path
=
b
"network:"
;
while
i
<
buf
.len
()
&&
i
<
scheme_path
.len
()
{
...
...
@@ -208,11 +226,13 @@ impl Scheme for Intel8254x {
Ok
(
i
)
}
fn
fsync
(
&
self
,
_
id
:
usize
)
->
Result
<
usize
>
{
fn
fsync
(
&
mut
self
,
id
:
usize
)
->
Result
<
usize
>
{
let
_
flags
=
self
.handles
.get
(
&
id
)
.ok_or
(
Error
::
new
(
EBADF
))
?
;
Ok
(
0
)
}
fn
close
(
&
self
,
_
id
:
usize
)
->
Result
<
usize
>
{
fn
close
(
&
mut
self
,
id
:
usize
)
->
Result
<
usize
>
{
self
.handles
.remove
(
&
id
)
.ok_or
(
Error
::
new
(
EBADF
))
?
;
Ok
(
0
)
}
}
...
...
@@ -230,7 +250,9 @@ impl Intel8254x {
Dma
::
zeroed
()
?
,
Dma
::
zeroed
()
?
,
Dma
::
zeroed
()
?
,
Dma
::
zeroed
()
?
,
Dma
::
zeroed
()
?
,
Dma
::
zeroed
()
?
,
Dma
::
zeroed
()
?
,
Dma
::
zeroed
()
?
,
Dma
::
zeroed
()
?
,
Dma
::
zeroed
()
?
,
Dma
::
zeroed
()
?
,
Dma
::
zeroed
()
?
],
transmit_ring
:
Dma
::
zeroed
()
?
transmit_ring
:
Dma
::
zeroed
()
?
,
next_id
:
0
,
handles
:
BTreeMap
::
new
()
};
module
.init
();
...
...
@@ -239,13 +261,13 @@ impl Intel8254x {
}
pub
unsafe
fn
irq
(
&
self
)
->
bool
{
let
icr
=
self
.read
(
ICR
);
let
icr
=
self
.read
_reg
(
ICR
);
icr
!=
0
}
pub
fn
next_read
(
&
self
)
->
usize
{
let
head
=
unsafe
{
self
.read
(
RDH
)
};
let
mut
tail
=
unsafe
{
self
.read
(
RDT
)
};
let
head
=
unsafe
{
self
.read
_reg
(
RDH
)
};
let
mut
tail
=
unsafe
{
self
.read
_reg
(
RDT
)
};
tail
+=
1
;
if
tail
>=
self
.receive_ring
.len
()
as
u32
{
...
...
@@ -262,27 +284,27 @@ impl Intel8254x {
0
}
pub
unsafe
fn
read
(
&
self
,
register
:
u32
)
->
u32
{
pub
unsafe
fn
read
_reg
(
&
self
,
register
:
u32
)
->
u32
{
ptr
::
read_volatile
((
self
.base
+
register
as
usize
)
as
*
mut
u32
)
}
pub
unsafe
fn
write
(
&
self
,
register
:
u32
,
data
:
u32
)
->
u32
{
pub
unsafe
fn
write
_reg
(
&
self
,
register
:
u32
,
data
:
u32
)
->
u32
{
ptr
::
write_volatile
((
self
.base
+
register
as
usize
)
as
*
mut
u32
,
data
);
ptr
::
read_volatile
((
self
.base
+
register
as
usize
)
as
*
mut
u32
)
}
pub
unsafe
fn
flag
(
&
self
,
register
:
u32
,
flag
:
u32
,
value
:
bool
)
{
if
value
{
self
.write
(
register
,
self
.read
(
register
)
|
flag
);
self
.write
_reg
(
register
,
self
.read_reg
(
register
)
|
flag
);
}
else
{
self
.write
(
register
,
self
.read
(
register
)
&
(
0xFFFFFFFF
-
flag
)
);
self
.write
_reg
(
register
,
self
.read_reg
(
register
)
&
!
flag
);
}
}
pub
unsafe
fn
init
(
&
mut
self
)
{
self
.flag
(
CTRL
,
CTRL_RST
,
true
);
while
self
.read
(
CTRL
)
&
CTRL_RST
==
CTRL_RST
{
print!
(
" - Waiting for reset: {:X}
\n
"
,
self
.read
(
CTRL
));
while
self
.read
_reg
(
CTRL
)
&
CTRL_RST
==
CTRL_RST
{
print!
(
" - Waiting for reset: {:X}
\n
"
,
self
.read
_reg
(
CTRL
));
}
// Enable auto negotiate, link, clear reset, do not Invert Loss-Of Signal
...
...
@@ -290,18 +312,18 @@ impl Intel8254x {
self
.flag
(
CTRL
,
CTRL_LRST
|
CTRL_PHY_RST
|
CTRL_ILOS
,
false
);
// No flow control
self
.write
(
FCAH
,
0
);
self
.write
(
FCAL
,
0
);
self
.write
(
FCT
,
0
);
self
.write
(
FCTTV
,
0
);
self
.write
_reg
(
FCAH
,
0
);
self
.write
_reg
(
FCAL
,
0
);
self
.write
_reg
(
FCT
,
0
);
self
.write
_reg
(
FCTTV
,
0
);
// Do not use VLANs
self
.flag
(
CTRL
,
CTRL_VME
,
false
);
// TODO: Clear statistical counters
let
mac_low
=
self
.read
(
RAL0
);
let
mac_high
=
self
.read
(
RAH0
);
let
mac_low
=
self
.read
_reg
(
RAL0
);
let
mac_high
=
self
.read
_reg
(
RAH0
);
let
mac
=
[
mac_low
as
u8
,
(
mac_low
>>
8
)
as
u8
,
(
mac_low
>>
16
)
as
u8
,
...
...
@@ -320,24 +342,24 @@ impl Intel8254x {
self
.receive_ring
[
i
]
.buffer
=
self
.receive_buffer
[
i
]
.physical
()
as
u64
;
}
self
.write
(
RDBAH
,
(
self
.receive_ring
.physical
()
>>
32
)
as
u32
);
self
.write
(
RDBAL
,
self
.receive_ring
.physical
()
as
u32
);
self
.write
(
RDLEN
,
(
self
.receive_ring
.len
()
*
mem
::
size_of
::
<
Rd
>
())
as
u32
);
self
.write
(
RDH
,
0
);
self
.write
(
RDT
,
self
.receive_ring
.len
()
as
u32
-
1
);
self
.write
_reg
(
RDBAH
,
(
self
.receive_ring
.physical
()
>>
32
)
as
u32
);
self
.write
_reg
(
RDBAL
,
self
.receive_ring
.physical
()
as
u32
);
self
.write
_reg
(
RDLEN
,
(
self
.receive_ring
.len
()
*
mem
::
size_of
::
<
Rd
>
())
as
u32
);
self
.write
_reg
(
RDH
,
0
);
self
.write
_reg
(
RDT
,
self
.receive_ring
.len
()
as
u32
-
1
);
// Transmit Buffer
for
i
in
0
..
self
.transmit_ring
.len
()
{
self
.transmit_ring
[
i
]
.buffer
=
self
.transmit_buffer
[
i
]
.physical
()
as
u64
;
}
self
.write
(
TDBAH
,
(
self
.transmit_ring
.physical
()
>>
32
)
as
u32
);
self
.write
(
TDBAL
,
self
.transmit_ring
.physical
()
as
u32
);
self
.write
(
TDLEN
,
(
self
.transmit_ring
.len
()
*
mem
::
size_of
::
<
Td
>
())
as
u32
);
self
.write
(
TDH
,
0
);
self
.write
(
TDT
,
0
);
self
.write
_reg
(
TDBAH
,
(
self
.transmit_ring
.physical
()
>>
32
)
as
u32
);
self
.write
_reg
(
TDBAL
,
self
.transmit_ring
.physical
()
as
u32
);
self
.write
_reg
(
TDLEN
,
(
self
.transmit_ring
.len
()
*
mem
::
size_of
::
<
Td
>
())
as
u32
);
self
.write
_reg
(
TDH
,
0
);
self
.write
_reg
(
TDT
,
0
);
self
.write
(
IMS
,
IMS_RXT
|
IMS_RX
|
IMS_RXDMT
|
IMS_RXSEQ
);
// | IMS_LSC | IMS_TXQE | IMS_TXDW
self
.write
_reg
(
IMS
,
IMS_RXT
|
IMS_RX
|
IMS_RXDMT
|
IMS_RXSEQ
);
// | IMS_LSC | IMS_TXQE | IMS_TXDW
self
.flag
(
RCTL
,
RCTL_EN
,
true
);
self
.flag
(
RCTL
,
RCTL_UPE
,
true
);
...
...
@@ -359,10 +381,10 @@ impl Intel8254x {
// TIPG Packet Gap
// TODO ...
while
self
.read
(
STATUS
)
&
2
!=
2
{
print!
(
" - Waiting for link up: {:X}
\n
"
,
self
.read
(
STATUS
));
while
self
.read
_reg
(
STATUS
)
&
2
!=
2
{
print!
(
" - Waiting for link up: {:X}
\n
"
,
self
.read
_reg
(
STATUS
));
}
print!
(
" - Link is up with speed {}
\n
"
,
match
(
self
.read
(
STATUS
)
>>
6
)
&
0b11
{
print!
(
" - Link is up with speed {}
\n
"
,
match
(
self
.read
_reg
(
STATUS
)
>>
6
)
&
0b11
{
0b00
=>
"10 Mb/s"
,
0b01
=>
"100 Mb/s"
,
_
=>
"1000 Mb/s"
,
...
...
e1000d/src/main.rs
View file @
aaafbbad
...
...
@@ -12,7 +12,7 @@ use std::os::unix::io::{AsRawFd, FromRawFd};
use
std
::
sync
::
Arc
;
use
event
::
EventQueue
;
use
syscall
::{
Packet
,
Scheme
,
MAP_WRITE
};
use
syscall
::{
Packet
,
Scheme
Mut
,
MAP_WRITE
};
use
syscall
::
error
::
EWOULDBLOCK
;
pub
mod
device
;
...
...
@@ -40,7 +40,7 @@ fn main() {
let
address
=
unsafe
{
syscall
::
physmap
(
bar
,
128
*
1024
,
MAP_WRITE
)
.expect
(
"e1000d: failed to map address"
)
};
{
let
device
=
Arc
::
new
(
unsafe
{
device
::
Intel8254x
::
new
(
address
)
.expect
(
"e1000d: failed to allocate device"
)
}
);
let
device
=
Arc
::
new
(
RefCell
::
new
(
unsafe
{
device
::
Intel8254x
::
new
(
address
)
.expect
(
"e1000d: failed to allocate device"
)
})
);
let
mut
event_queue
=
EventQueue
::
<
usize
>
::
new
()
.expect
(
"e1000d: failed to create event queue"
);
...
...
@@ -54,14 +54,14 @@ fn main() {
event_queue
.add
(
irq_file
.as_raw_fd
(),
move
|
_
event
|
->
Result
<
Option
<
usize
>>
{
let
mut
irq
=
[
0
;
8
];
irq_file
.read
(
&
mut
irq
)
?
;
if
unsafe
{
device_irq
.irq
()
}
{
if
unsafe
{
device_irq
.
borrow
()
.
irq
()
}
{
irq_file
.write
(
&
mut
irq
)
?
;
let
mut
todo
=
todo_irq
.borrow_mut
();
let
mut
i
=
0
;
while
i
<
todo
.len
()
{
let
a
=
todo
[
i
]
.a
;
device_irq
.handle
(
&
mut
todo
[
i
]);
device_irq
.
borrow_mut
()
.
handle
(
&
mut
todo
[
i
]);
if
todo
[
i
]
.a
==
(
-
EWOULDBLOCK
)
as
usize
{
todo
[
i
]
.a
=
a
;
i
+=
1
;
...
...
@@ -71,7 +71,7 @@ fn main() {
}
}
let
next_read
=
device_irq
.next_read
();
let
next_read
=
device_irq
.
borrow
()
.
next_read
();
if
next_read
>
0
{
return
Ok
(
Some
(
next_read
));
}
...
...
@@ -79,6 +79,7 @@ fn main() {
Ok
(
None
)
})
.expect
(
"e1000d: failed to catch events on IRQ file"
);
let
device_packet
=
device
.clone
();
let
socket_packet
=
socket
.clone
();
event_queue
.add
(
socket_fd
,
move
|
_
event
|
->
Result
<
Option
<
usize
>>
{
loop
{
...
...
@@ -88,7 +89,7 @@ fn main() {
}
let
a
=
packet
.a
;
device
.handle
(
&
mut
packet
);
device
_packet
.borrow_mut
()
.handle
(
&
mut
packet
);
if
packet
.a
==
(
-
EWOULDBLOCK
)
as
usize
{
packet
.a
=
a
;
todo
.borrow_mut
()
.push
(
packet
);
...
...
@@ -97,7 +98,7 @@ fn main() {
}
}
let
next_read
=
device
.next_read
();
let
next_read
=
device
_packet
.borrow
()
.next_read
();
if
next_read
>
0
{
return
Ok
(
Some
(
next_read
));
}
...
...
@@ -105,35 +106,31 @@ fn main() {
Ok
(
None
)
})
.expect
(
"e1000d: failed to catch events on scheme file"
);
let
send_events
=
|
event_count
|
{
for
(
handle_id
,
_
handle
)
in
device
.borrow
()
.handles
.iter
()
{
socket
.borrow_mut
()
.write
(
&
Packet
{
id
:
0
,
pid
:
0
,
uid
:
0
,
gid
:
0
,
a
:
syscall
::
number
::
SYS_FEVENT
,
b
:
*
handle_id
,
c
:
syscall
::
flag
::
EVENT_READ
,
d
:
event_count
})
.expect
(
"e1000d: failed to write event"
);
}
};
for
event_count
in
event_queue
.trigger_all
(
event
::
Event
{
fd
:
0
,
flags
:
0
,
})
.expect
(
"e1000d: failed to trigger events"
)
{
socket
.borrow_mut
()
.write
(
&
Packet
{
id
:
0
,
pid
:
0
,
uid
:
0
,
gid
:
0
,
a
:
syscall
::
number
::
SYS_FEVENT
,
b
:
0
,
c
:
syscall
::
flag
::
EVENT_READ
,
d
:
event_count
})
.expect
(
"e1000d: failed to write event"
);
send_events
(
event_count
);
}
loop
{
let
event_count
=
event_queue
.run
()
.expect
(
"e1000d: failed to handle events"
);
socket
.borrow_mut
()
.write
(
&
Packet
{
id
:
0
,
pid
:
0
,
uid
:
0
,
gid
:
0
,
a
:
syscall
::
number
::
SYS_FEVENT
,
b
:
0
,
c
:
syscall
::
flag
::
EVENT_READ
,
d
:
event_count
})
.expect
(
"e1000d: failed to write event"
);
send_events
(
event_count
);
}
}
unsafe
{
let
_
=
syscall
::
physunmap
(
address
);
}
...
...
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