Skip to content

Commit 9ac5924

Browse files
authored
Merge pull request #1 from fslongjin/wuyujian-patch-virtio-net
bugfix: 初始化BAR之后,未正确设置command register的问题
2 parents 6dd9344 + 49f2716 commit 9ac5924

File tree

3 files changed

+53
-16
lines changed

3 files changed

+53
-16
lines changed

kernel/src/driver/pci/pci.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ bitflags! {
4747

4848
bitflags! {
4949
/// The command register in PCI configuration space.
50-
pub struct Command: u16 {
50+
pub struct CommandRegister: u16 {
5151
/// The device can respond to I/O Space accesses.
5252
const IO_SPACE = 1 << 0;
5353
/// The device can respond to Memory Space accesses.
@@ -311,6 +311,7 @@ impl Default for PciDeviceBar {
311311
pub fn pci_bar_init(device_function: DeviceFunction) -> Result<PciDeviceBar, PciError> {
312312
let mut device_bar: PciDeviceBar = PciDeviceBar::default();
313313
let mut bar_index_ignore: u8 = 255;
314+
314315
for bar_index in 0..6 {
315316
if bar_index == bar_index_ignore {
316317
continue;
@@ -435,6 +436,12 @@ pub fn pci_bar_init(device_function: DeviceFunction) -> Result<PciDeviceBar, Pci
435436
_ => {}
436437
}
437438
}
439+
440+
// 设置command register,使得设备能够使用它的BAR
441+
set_command_register(
442+
&device_function,
443+
CommandRegister::IO_SPACE | CommandRegister::MEMORY_SPACE | CommandRegister::BUS_MASTER,
444+
);
438445
kdebug!("pci_device_bar:{}", device_bar);
439446
return Ok(device_bar);
440447
}
@@ -493,3 +500,19 @@ impl Iterator for CapabilityIterator {
493500
})
494501
}
495502
}
503+
504+
/// @brief 设置PCI Config Space里面的Command Register
505+
///
506+
/// @param device_function 设备
507+
/// @param value command register要被设置成的值
508+
pub fn set_command_register(device_function: &DeviceFunction, value: CommandRegister) {
509+
unsafe {
510+
pci_write_config(
511+
device_function.bus,
512+
device_function.device,
513+
device_function.function,
514+
STATUS_COMMAND_OFFSET,
515+
value.bits().into(),
516+
);
517+
}
518+
}

kernel/src/driver/virtio/transport_pci.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::driver::pci::pci::{
66
capabilities_offset, pci_bar_init, CapabilityIterator, DeviceFunction, PciDeviceBar, PciError,
77
PCI_CAP_ID_VNDR,
88
};
9-
use crate::include::bindings::bindings::pci_read_config;
9+
use crate::include::bindings::bindings::{pci_read_config, pci_write_config};
1010
use core::{
1111
fmt::{self, Display, Formatter},
1212
mem::{align_of, size_of},
@@ -122,6 +122,7 @@ impl PciTransport {
122122
device_function: device_function,
123123
next_capability_offset: capabilities_offset(device_function),
124124
};
125+
125126
let device_bar = pci_bar_init(device_function)?;
126127

127128
for capability in device_capability {

kernel/src/driver/virtio/virtio.rs

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::transport_pci::PciTransport;
22
use super::virtio_impl::HalImpl;
33
use crate::driver::pci::pci::DeviceFunction;
4-
use crate::include::bindings::bindings::{get_virtio_net_device, false_};
4+
use crate::include::bindings::bindings::get_virtio_net_device;
55
use crate::{kdebug, kerror, kwarn};
66
use alloc::{boxed::Box, collections::LinkedList};
77
use virtio_drivers::device::net::VirtIONet;
@@ -90,29 +90,42 @@ fn virtio_net<T: Transport>(transport: T) {
9090
return;
9191
}
9292
};
93+
9394
let mut buf = [0u8; 0x100];
9495
// let len = match driver_net.recv(&mut buf)
9596
// {
9697
// Ok(len) =>{len},
9798
// Err(_) =>{kerror!("virtio_net recv failed");return;}
9899
// };
99-
match driver_net.can_send()
100-
{
101-
true=>{ kdebug!("can send");},
102-
false=>{ kdebug!("can not send");},
100+
match driver_net.can_send() {
101+
true => {
102+
kdebug!("can send");
103+
}
104+
false => {
105+
kdebug!("can not send");
106+
}
103107
}
104-
match driver_net.can_recv()
105-
{
106-
true=>{ kdebug!("can recv")},
107-
false=>{ kdebug!("can not recv");}
108+
match driver_net.can_recv() {
109+
true => {
110+
kdebug!("can recv")
111+
}
112+
false => {
113+
kdebug!("can not recv");
114+
}
108115
}
109-
let len=100;
116+
117+
let len = 100;
110118
kdebug!("recv: {:?}", &buf[..len]);
111-
match driver_net.send(&buf[..len])
112-
{
113-
Ok(_) =>{kdebug!("virtio_net send success");},
114-
Err(_) =>{kerror!("virtio_net send failed");return;},
119+
match driver_net.send(&buf[..len]) {
120+
Ok(_) => {
121+
kdebug!("virtio_net send success");
122+
}
123+
Err(_) => {
124+
kerror!("virtio_net send failed");
125+
return;
126+
}
115127
}
128+
116129
let mac = driver_net.mac();
117130
kdebug!("virtio_net MAC={:?}", mac);
118131
kdebug!("virtio-net test finished");

0 commit comments

Comments
 (0)