Calculate and use PCI BAR memory sizes in most drivers.
This commit is contained in:
+8
-2
@@ -23,14 +23,20 @@ fn main() {
|
||||
let bar_str = args.next().expect("ahcid: no address provided");
|
||||
let bar = usize::from_str_radix(&bar_str, 16).expect("ahcid: failed to parse address");
|
||||
|
||||
let bar_size_str = args.next().expect("ahcid: no address size provided");
|
||||
let bar_size = usize::from_str_radix(&bar_str, 16).expect("ahcid: failed to parse address size");
|
||||
|
||||
let irq_str = args.next().expect("ahcid: no irq provided");
|
||||
let irq = irq_str.parse::<u8>().expect("ahcid: failed to parse irq");
|
||||
|
||||
print!("{}", format!(" + AHCI {} on: {:X} IRQ: {}\n", name, bar, irq));
|
||||
print!("{}", format!(" + AHCI {} on: {:X} size: {} IRQ: {}\n", name, bar, bar_size, irq));
|
||||
|
||||
// Daemonize
|
||||
if unsafe { syscall::clone(0).unwrap() } == 0 {
|
||||
let address = unsafe { syscall::physmap(bar, 4096, PHYSMAP_WRITE | PHYSMAP_NO_CACHE).expect("ahcid: failed to map address") };
|
||||
let address = unsafe {
|
||||
syscall::physmap(bar, bar_size, PHYSMAP_WRITE | PHYSMAP_NO_CACHE)
|
||||
.expect("ahcid: failed to map address")
|
||||
};
|
||||
{
|
||||
let scheme_name = format!("disk/{}", name);
|
||||
let socket_fd = syscall::open(
|
||||
|
||||
+1
-2
@@ -2,5 +2,4 @@
|
||||
name = "E1000 NIC"
|
||||
class = 2
|
||||
ids = { 0x8086 = [0x1004, 0x100e, 0x100f, 0x1503] }
|
||||
command = ["e1000d", "$NAME", "$BAR0", "$IRQ"]
|
||||
|
||||
command = ["e1000d", "$NAME", "$BAR0", "$BARSIZE0", "$IRQ"]
|
||||
|
||||
+5
-2
@@ -68,10 +68,13 @@ fn main() {
|
||||
let bar_str = args.next().expect("e1000d: no address provided");
|
||||
let bar = usize::from_str_radix(&bar_str, 16).expect("e1000d: failed to parse address");
|
||||
|
||||
let bar_size_str = args.next().expect("e1000d: no address size provided");
|
||||
let bar_size = usize::from_str_radix(&bar_str, 16).expect("e1000d: failed to parse address size");
|
||||
|
||||
let irq_str = args.next().expect("e1000d: no irq provided");
|
||||
let irq = irq_str.parse::<u8>().expect("e1000d: failed to parse irq");
|
||||
|
||||
println!(" + E1000 {} on: {:X} IRQ: {}", name, bar, irq);
|
||||
println!(" + E1000 {} on: {:X} size: {} IRQ: {}", name, bar, bar_size, irq);
|
||||
|
||||
// Daemonize
|
||||
if unsafe { syscall::clone(0).unwrap() } == 0 {
|
||||
@@ -91,7 +94,7 @@ fn main() {
|
||||
let mut irq_file = unsafe { File::from_raw_fd(irq_fd as RawFd) };
|
||||
|
||||
let address = unsafe {
|
||||
syscall::physmap(bar, 128 * 1024, PHYSMAP_WRITE | PHYSMAP_NO_CACHE)
|
||||
syscall::physmap(bar, bar_size, PHYSMAP_WRITE | PHYSMAP_NO_CACHE)
|
||||
.expect("e1000d: failed to map address")
|
||||
};
|
||||
{
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
name = "AHCI storage"
|
||||
class = 1
|
||||
subclass = 6
|
||||
command = ["ahcid", "$NAME", "$BAR5", "$IRQ"]
|
||||
command = ["ahcid", "$NAME", "$BAR5", "$BARSIZE5", "$IRQ"]
|
||||
|
||||
# bgad
|
||||
[[drivers]]
|
||||
@@ -27,7 +27,7 @@ command = ["bgad", "$NAME", "$BAR0"]
|
||||
name = "NVME storage"
|
||||
class = 1
|
||||
subclass = 8
|
||||
command = ["nvmed", "$NAME", "$BAR0", "$IRQ"]
|
||||
command = ["nvmed", "$NAME", "$BAR0", "$BARSIZE0", "$IRQ"]
|
||||
|
||||
# vboxd
|
||||
[[drivers]]
|
||||
|
||||
+8
-3
@@ -26,15 +26,20 @@ fn main() {
|
||||
let bar_str = args.next().expect("nvmed: no address provided");
|
||||
let bar = usize::from_str_radix(&bar_str, 16).expect("nvmed: failed to parse address");
|
||||
|
||||
let bar_size_str = args.next().expect("nvmed: no address size provided");
|
||||
let bar_size = usize::from_str_radix(&bar_str, 16).expect("nvmed: failed to parse address size");
|
||||
|
||||
let irq_str = args.next().expect("nvmed: no irq provided");
|
||||
let irq = irq_str.parse::<u8>().expect("nvmed: failed to parse irq");
|
||||
|
||||
print!("{}", format!(" + NVME {} on: {:X} IRQ: {}\n", name, bar, irq));
|
||||
print!("{}", format!(" + NVME {} on: {:X} size: {} IRQ: {}\n", name, bar, bar_size, irq));
|
||||
|
||||
// Daemonize
|
||||
if unsafe { syscall::clone(0).unwrap() } == 0 {
|
||||
//TODO: Figure out correct size of mapping, not just 256 * 1024
|
||||
let address = unsafe { syscall::physmap(bar, 256 * 1024, PHYSMAP_WRITE | PHYSMAP_NO_CACHE).expect("nvmed: failed to map address") };
|
||||
let address = unsafe {
|
||||
syscall::physmap(bar, bar_size, PHYSMAP_WRITE | PHYSMAP_NO_CACHE)
|
||||
.expect("nvmed: failed to map address")
|
||||
};
|
||||
{
|
||||
let event_fd = syscall::open("event:", syscall::O_RDWR | syscall::O_CLOEXEC)
|
||||
.expect("nvmed: failed to open event queue");
|
||||
|
||||
+50
-12
@@ -13,7 +13,7 @@ use std::process::Command;
|
||||
use syscall::iopl;
|
||||
|
||||
use crate::config::Config;
|
||||
use crate::pci::{Pci, PciClass, PciHeader, PciHeaderError, PciHeaderType};
|
||||
use crate::pci::{Pci, PciBar, PciClass, PciHeader, PciHeaderError, PciHeaderType};
|
||||
|
||||
mod config;
|
||||
mod pci;
|
||||
@@ -82,7 +82,7 @@ fn handle_parsed_header(config: &Config, pci: &Pci, bus_num: u8,
|
||||
if let Some(ref ids) = driver.ids {
|
||||
let mut device_found = false;
|
||||
for (vendor, devices) in ids {
|
||||
let vendor_without_prefix = vendor.trim_left_matches("0x");
|
||||
let vendor_without_prefix = vendor.trim_start_matches("0x");
|
||||
let vendor = i64::from_str_radix(vendor_without_prefix, 16).unwrap() as u16;
|
||||
|
||||
if vendor != header.vendor_id() { continue; }
|
||||
@@ -130,6 +130,42 @@ fn handle_parsed_header(config: &Config, pci: &Pci, bus_num: u8,
|
||||
pci.write(bus_num, dev_num, func_num, 0x3C, data);
|
||||
}
|
||||
|
||||
// Find BAR sizes
|
||||
let mut bars = [PciBar::None; 6];
|
||||
let mut bar_sizes = [0; 6];
|
||||
unsafe {
|
||||
let count = match header.header_type() {
|
||||
PciHeaderType::GENERAL => 6,
|
||||
PciHeaderType::PCITOPCI => 2,
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
for i in 0..count {
|
||||
bars[i] = header.get_bar(i);
|
||||
|
||||
let offset = 0x10 + (i as u8) * 4;
|
||||
|
||||
let original = pci.read(bus_num, dev_num, func_num, offset);
|
||||
pci.write(bus_num, dev_num, func_num, offset, 0xFFFFFFFF);
|
||||
|
||||
let new = pci.read(bus_num, dev_num, func_num, offset);
|
||||
pci.write(bus_num, dev_num, func_num, offset, original);
|
||||
|
||||
let masked = if new & 1 == 1 {
|
||||
new & 0xFFFFFFFC
|
||||
} else {
|
||||
new & 0xFFFFFFF0
|
||||
};
|
||||
|
||||
let size = !masked + 1;
|
||||
bar_sizes[i] = if size <= 1 {
|
||||
0
|
||||
} else {
|
||||
size
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: find a better way to pass the header data down to the
|
||||
// device driver, making passing the capabilities list etc
|
||||
// posible.
|
||||
@@ -142,16 +178,18 @@ fn handle_parsed_header(config: &Config, pci: &Pci, bus_num: u8,
|
||||
"$DEV" => format!("{:>02X}", dev_num),
|
||||
"$FUNC" => format!("{:>02X}", func_num),
|
||||
"$NAME" => format!("pci-{:>02X}.{:>02X}.{:>02X}", bus_num, dev_num, func_num),
|
||||
"$BAR0" => format!("{}", header.get_bar(0)),
|
||||
"$BAR1" => format!("{}", header.get_bar(1)),
|
||||
"$BAR2" if header.header_type() == PciHeaderType::GENERAL =>
|
||||
format!("{}", header.get_bar(2)),
|
||||
"$BAR3" if header.header_type() == PciHeaderType::GENERAL =>
|
||||
format!("{}", header.get_bar(3)),
|
||||
"$BAR4" if header.header_type() == PciHeaderType::GENERAL =>
|
||||
format!("{}", header.get_bar(4)),
|
||||
"$BAR5" if header.header_type() == PciHeaderType::GENERAL =>
|
||||
format!("{}", header.get_bar(5)),
|
||||
"$BAR0" => format!("{}", bars[0]),
|
||||
"$BAR1" => format!("{}", bars[1]),
|
||||
"$BAR2" => format!("{}", bars[2]),
|
||||
"$BAR3" => format!("{}", bars[3]),
|
||||
"$BAR4" => format!("{}", bars[4]),
|
||||
"$BAR5" => format!("{}", bars[5]),
|
||||
"$BARSIZE0" => format!("{:>08X}", bar_sizes[0]),
|
||||
"$BARSIZE1" => format!("{:>08X}", bar_sizes[1]),
|
||||
"$BARSIZE2" => format!("{:>08X}", bar_sizes[2]),
|
||||
"$BARSIZE3" => format!("{:>08X}", bar_sizes[3]),
|
||||
"$BARSIZE4" => format!("{:>08X}", bar_sizes[4]),
|
||||
"$BARSIZE5" => format!("{:>08X}", bar_sizes[5]),
|
||||
"$IRQ" => format!("{}", irq),
|
||||
"$VENID" => format!("{:>04X}", header.vendor_id()),
|
||||
"$DEVID" => format!("{:>04X}", header.device_id()),
|
||||
|
||||
@@ -2,5 +2,4 @@
|
||||
name = "RTL8168 NIC"
|
||||
class = 2
|
||||
ids = { 0x10ec = [0x8168] }
|
||||
command = ["rtl8168d", "$NAME", "$BAR2", "$IRQ"]
|
||||
|
||||
command = ["rtl8168d", "$NAME", "$BAR2", "$BARSIZE2", "$IRQ"]
|
||||
|
||||
@@ -68,10 +68,13 @@ fn main() {
|
||||
let bar_str = args.next().expect("rtl8168d: no address provided");
|
||||
let bar = usize::from_str_radix(&bar_str, 16).expect("rtl8168d: failed to parse address");
|
||||
|
||||
let bar_size_str = args.next().expect("rtl8168d: no address size provided");
|
||||
let bar_size = usize::from_str_radix(&bar_str, 16).expect("rtl8168d: failed to parse address size");
|
||||
|
||||
let irq_str = args.next().expect("rtl8168d: no irq provided");
|
||||
let irq = irq_str.parse::<u8>().expect("rtl8168d: failed to parse irq");
|
||||
|
||||
println!(" + RTL8168 {} on: {:X}, IRQ: {}", name, bar, irq);
|
||||
println!(" + RTL8168 {} on: {:X} size: {} IRQ: {}", name, bar, bar_size, irq);
|
||||
|
||||
// Daemonize
|
||||
if unsafe { syscall::clone(0).unwrap() } == 0 {
|
||||
@@ -91,7 +94,7 @@ fn main() {
|
||||
let mut irq_file = unsafe { File::from_raw_fd(irq_fd as RawFd) };
|
||||
|
||||
let address = unsafe {
|
||||
syscall::physmap(bar, 256, PHYSMAP_WRITE | PHYSMAP_NO_CACHE)
|
||||
syscall::physmap(bar, bar_size, PHYSMAP_WRITE | PHYSMAP_NO_CACHE)
|
||||
.expect("rtl8168d: failed to map address")
|
||||
};
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user