Skip to content

Commit

Permalink
Move cam_offset method to Cam enum.
Browse files Browse the repository at this point in the history
It may be useful for other ConfigurationAccess implementations.
  • Loading branch information
qwandor committed Nov 6, 2024
1 parent 17a1026 commit dc92205
Showing 1 changed file with 22 additions and 20 deletions.
42 changes: 22 additions & 20 deletions src/transport/pci/bus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,26 @@ impl Cam {
Self::Ecam => 0x10000000,
}
}

/// Returns the offset in bytes within the CAM region for the given device, function and
/// register.
pub fn cam_offset(self, device_function: DeviceFunction, register_offset: u8) -> u32 {
assert!(device_function.valid());

let bdf = (device_function.bus as u32) << 8
| (device_function.device as u32) << 3
| device_function.function as u32;
let address =
bdf << match self {
Cam::MmioCam => 8,
Cam::Ecam => 12,
} | register_offset as u32;
// Ensure that address is within range.
assert!(address < self.size());
// Ensure that address is word-aligned.
assert!(address & 0x3 == 0);
address
}
}

impl<C: ConfigurationAccess> PciRoot<C> {
Expand Down Expand Up @@ -324,29 +344,11 @@ impl MmioCam {
cam,
}
}

fn cam_offset(&self, device_function: DeviceFunction, register_offset: u8) -> u32 {
assert!(device_function.valid());

let bdf = (device_function.bus as u32) << 8
| (device_function.device as u32) << 3
| device_function.function as u32;
let address =
bdf << match self.cam {
Cam::MmioCam => 8,
Cam::Ecam => 12,
} | register_offset as u32;
// Ensure that address is within range.
assert!(address < self.cam.size());
// Ensure that address is word-aligned.
assert!(address & 0x3 == 0);
address
}
}

impl ConfigurationAccess for MmioCam {
fn read_word(&self, device_function: DeviceFunction, register_offset: u8) -> u32 {
let address = self.cam_offset(device_function, register_offset);
let address = self.cam.cam_offset(device_function, register_offset);
// Safe because both the `mmio_base` and the address offset are properly aligned, and the
// resulting pointer is within the MMIO range of the CAM.
unsafe {
Expand All @@ -356,7 +358,7 @@ impl ConfigurationAccess for MmioCam {
}

fn write_word(&mut self, device_function: DeviceFunction, register_offset: u8, data: u32) {
let address = self.cam_offset(device_function, register_offset);
let address = self.cam.cam_offset(device_function, register_offset);
// Safe because both the `mmio_base` and the address offset are properly aligned, and the
// resulting pointer is within the MMIO range of the CAM.
unsafe {
Expand Down

0 comments on commit dc92205

Please sign in to comment.