mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-06 02:25:23 +00:00
pci_root: Don't assume register bit number is eight
In pcie enhanced configuration access, register bit number is 12, in order to support such PciConfigAddress, this commit make register bit number variable, it could be 8 or 12 decided by caller. BUG=b:197877871 TEST=tools/presubmit Change-Id: I96a317896b9536742534bee86f0e8f1acc323292 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/3305940 Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Daniel Verkamp <dverkamp@chromium.org> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
This commit is contained in:
parent
e061930706
commit
2b286f4305
3 changed files with 40 additions and 23 deletions
|
@ -317,7 +317,7 @@ fn create_pci_nodes(
|
|||
|
||||
for (address, irq_num, irq_pin) in pci_irqs.iter() {
|
||||
// PCI_DEVICE(3)
|
||||
interrupts.push(address.to_config_address(0));
|
||||
interrupts.push(address.to_config_address(0, 8));
|
||||
interrupts.push(0);
|
||||
interrupts.push(0);
|
||||
|
||||
|
|
|
@ -392,7 +392,7 @@ impl arch::LinuxArch for AArch64 {
|
|||
(devices::AARCH64_GIC_NR_IRQS - AARCH64_IRQ_BASE) as usize,
|
||||
)
|
||||
.map_err(Error::CreatePciRoot)?;
|
||||
let pci_bus = Arc::new(Mutex::new(PciConfigMmio::new(pci)));
|
||||
let pci_bus = Arc::new(Mutex::new(PciConfigMmio::new(pci, 8)));
|
||||
|
||||
let (platform_devices, _others): (Vec<_>, Vec<_>) = others
|
||||
.into_iter()
|
||||
|
|
|
@ -70,21 +70,22 @@ impl Display for PciAddress {
|
|||
}
|
||||
|
||||
impl PciAddress {
|
||||
const BUS_OFFSET: usize = 16;
|
||||
const BUS_MASK: u32 = 0x00ff;
|
||||
const DEVICE_OFFSET: usize = 11;
|
||||
const DEVICE_BITS_NUM: usize = 5;
|
||||
const DEVICE_MASK: u32 = 0x1f;
|
||||
const FUNCTION_OFFSET: usize = 8;
|
||||
const FUNCTION_BITS_NUM: usize = 3;
|
||||
const FUNCTION_MASK: u32 = 0x07;
|
||||
const REGISTER_OFFSET: usize = 2;
|
||||
const REGISTER_MASK: u32 = 0x3f;
|
||||
|
||||
/// Construct PciAddress and register tuple from CONFIG_ADDRESS value.
|
||||
pub fn from_config_address(config_address: u32) -> (Self, usize) {
|
||||
let bus = ((config_address >> Self::BUS_OFFSET) & Self::BUS_MASK) as u8;
|
||||
let dev = ((config_address >> Self::DEVICE_OFFSET) & Self::DEVICE_MASK) as u8;
|
||||
let func = ((config_address >> Self::FUNCTION_OFFSET) & Self::FUNCTION_MASK) as u8;
|
||||
let register = ((config_address >> Self::REGISTER_OFFSET) & Self::REGISTER_MASK) as usize;
|
||||
pub fn from_config_address(config_address: u32, register_bits_num: usize) -> (Self, usize) {
|
||||
let bus_offset = register_bits_num + Self::FUNCTION_BITS_NUM + Self::DEVICE_BITS_NUM;
|
||||
let bus = ((config_address >> bus_offset) & Self::BUS_MASK) as u8;
|
||||
let dev_offset = register_bits_num + Self::FUNCTION_BITS_NUM;
|
||||
let dev = ((config_address >> dev_offset) & Self::DEVICE_MASK) as u8;
|
||||
let func = ((config_address >> register_bits_num) & Self::FUNCTION_MASK) as u8;
|
||||
let register_mask: u32 = (1_u32 << (register_bits_num - Self::REGISTER_OFFSET)) - 1;
|
||||
let register = ((config_address >> Self::REGISTER_OFFSET) & register_mask) as usize;
|
||||
|
||||
(PciAddress { bus, dev, func }, register)
|
||||
}
|
||||
|
@ -105,16 +106,21 @@ impl PciAddress {
|
|||
}
|
||||
|
||||
/// Encode PciAddress into CONFIG_ADDRESS value.
|
||||
pub fn to_config_address(&self, register: usize) -> u32 {
|
||||
((Self::BUS_MASK & self.bus as u32) << Self::BUS_OFFSET)
|
||||
| ((Self::DEVICE_MASK & self.dev as u32) << Self::DEVICE_OFFSET)
|
||||
| ((Self::FUNCTION_MASK & self.func as u32) << Self::FUNCTION_OFFSET)
|
||||
| ((Self::REGISTER_MASK & register as u32) << Self::REGISTER_OFFSET)
|
||||
pub fn to_config_address(&self, register: usize, register_bits_num: usize) -> u32 {
|
||||
let bus_offset = register_bits_num + Self::FUNCTION_BITS_NUM + Self::DEVICE_BITS_NUM;
|
||||
let dev_offset = register_bits_num + Self::FUNCTION_BITS_NUM;
|
||||
let register_mask: u32 = (1_u32 << (register_bits_num - Self::REGISTER_OFFSET)) - 1;
|
||||
((Self::BUS_MASK & self.bus as u32) << bus_offset)
|
||||
| ((Self::DEVICE_MASK & self.dev as u32) << dev_offset)
|
||||
| ((Self::FUNCTION_MASK & self.func as u32) << register_bits_num)
|
||||
| ((register_mask & register as u32) << Self::REGISTER_OFFSET)
|
||||
}
|
||||
|
||||
/// Convert B:D:F PCI address to unsigned 32 bit integer
|
||||
pub fn to_u32(&self) -> u32 {
|
||||
self.to_config_address(0) >> Self::FUNCTION_OFFSET
|
||||
((Self::BUS_MASK & self.bus as u32) << (Self::FUNCTION_BITS_NUM + Self::DEVICE_BITS_NUM))
|
||||
| ((Self::DEVICE_MASK & self.dev as u32) << Self::FUNCTION_BITS_NUM)
|
||||
| (Self::FUNCTION_MASK & self.func as u32)
|
||||
}
|
||||
|
||||
/// Returns true if the address points to PCI root host-bridge.
|
||||
|
@ -266,6 +272,8 @@ pub struct PciConfigIo {
|
|||
}
|
||||
|
||||
impl PciConfigIo {
|
||||
const REGISTER_BITS_NUM: usize = 8;
|
||||
|
||||
pub fn new(pci_root: PciRoot) -> Self {
|
||||
PciConfigIo {
|
||||
pci_root,
|
||||
|
@ -279,7 +287,8 @@ impl PciConfigIo {
|
|||
return 0xffff_ffff;
|
||||
}
|
||||
|
||||
let (address, register) = PciAddress::from_config_address(self.config_address);
|
||||
let (address, register) =
|
||||
PciAddress::from_config_address(self.config_address, Self::REGISTER_BITS_NUM);
|
||||
self.pci_root.config_space_read(address, register)
|
||||
}
|
||||
|
||||
|
@ -289,7 +298,8 @@ impl PciConfigIo {
|
|||
return;
|
||||
}
|
||||
|
||||
let (address, register) = PciAddress::from_config_address(self.config_address);
|
||||
let (address, register) =
|
||||
PciAddress::from_config_address(self.config_address, Self::REGISTER_BITS_NUM);
|
||||
self.pci_root
|
||||
.config_space_write(address, register, offset, data)
|
||||
}
|
||||
|
@ -359,20 +369,27 @@ impl BusDevice for PciConfigIo {
|
|||
pub struct PciConfigMmio {
|
||||
/// PCI root bridge.
|
||||
pci_root: PciRoot,
|
||||
/// Register bit number in config address.
|
||||
register_bit_num: usize,
|
||||
}
|
||||
|
||||
impl PciConfigMmio {
|
||||
pub fn new(pci_root: PciRoot) -> Self {
|
||||
PciConfigMmio { pci_root }
|
||||
pub fn new(pci_root: PciRoot, register_bit_num: usize) -> Self {
|
||||
PciConfigMmio {
|
||||
pci_root,
|
||||
register_bit_num,
|
||||
}
|
||||
}
|
||||
|
||||
fn config_space_read(&self, config_address: u32) -> u32 {
|
||||
let (address, register) = PciAddress::from_config_address(config_address);
|
||||
let (address, register) =
|
||||
PciAddress::from_config_address(config_address, self.register_bit_num);
|
||||
self.pci_root.config_space_read(address, register)
|
||||
}
|
||||
|
||||
fn config_space_write(&mut self, config_address: u32, offset: u64, data: &[u8]) {
|
||||
let (address, register) = PciAddress::from_config_address(config_address);
|
||||
let (address, register) =
|
||||
PciAddress::from_config_address(config_address, self.register_bit_num);
|
||||
self.pci_root
|
||||
.config_space_write(address, register, offset, data)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue