refactor(io): use MmioBus as the x86 IO bus

There is no need to introduce a new module to model the IO bus.
MMIO and IO are basically the same thing except the address width.

Signed-off-by: Changyuan Lyu <changyuanl@google.com>
This commit is contained in:
Changyuan Lyu 2024-04-25 23:04:11 -07:00 committed by Lencerf
parent ee37fa2af9
commit 0580084834
2 changed files with 7 additions and 67 deletions

View file

@ -13,7 +13,6 @@
// limitations under the License.
mod addressable;
pub mod io;
pub mod mmio;
pub mod ram;
@ -27,12 +26,9 @@ use crate::hv::{self, VmEntry, VmMemory};
use ram::UserMem;
use addressable::{Addressable, SlotBackend};
use io::IoBus;
use mmio::{Mmio, MmioBus};
use mmio::{Mmio, MmioBus, MmioRegion};
use ram::RamBus;
use self::io::IoDev;
use crate::arch::layout::{
MEM_64_START, MMIO_32_START, PCIE_CONFIG_END, PCIE_CONFIG_START, RAM_32_END,
};
@ -98,7 +94,7 @@ pub struct Allocator {
pub struct Memory {
ram_bus: Arc<RamBus>,
mmio_bus: MmioBus,
io_bus: IoBus,
io_bus: MmioBus,
// TODO do we need a global lock?
allocator: Mutex<Allocator>,
}
@ -125,7 +121,7 @@ impl Memory {
ram_bus: Arc::new(RamBus::new(vm_memory)),
mmio_bus: MmioBus::new(),
allocator: Mutex::new(Allocator::default()),
io_bus: IoBus::new(),
io_bus: MmioBus::new(),
}
}
@ -197,7 +193,7 @@ impl Memory {
}
#[cfg(target_arch = "x86_64")]
pub fn add_io_dev(&self, port: Option<u16>, dev: IoDev) -> Result<u16, Error> {
pub fn add_io_dev(&self, port: Option<u16>, dev: MmioRegion) -> Result<u16, Error> {
let mut allocator = self.allocator.lock()?;
let port = match port {
Some(port) => {
@ -221,7 +217,7 @@ impl Memory {
port as u16
}
};
self.io_bus.add(port, dev)?;
self.io_bus.add(port as usize, dev)?;
Ok(port)
}
@ -306,13 +302,13 @@ impl Memory {
}
}
if let Some(val) = write {
match self.io_bus.write(port, size, val) {
match self.io_bus.write(port as usize, size, val as u64) {
Ok(()) => Ok(VmEntry::None),
Err(Error::Action(action)) => self.handle_action(action),
Err(e) => Err(e),
}
} else {
let data = self.io_bus.read(port, size)?;
let data = self.io_bus.read(port as usize, size)? as u32;
Ok(VmEntry::Io { data })
}
}

View file

@ -1,56 +0,0 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use std::sync::{Arc, RwLock};
use super::mmio::{Mmio, MmioRange};
use super::Result;
#[derive(Debug)]
pub struct IoBus {
inner: RwLock<MmioRange>,
}
pub type IoDev = Arc<dyn Mmio + Send + Sync + 'static>;
impl Default for IoBus {
fn default() -> Self {
Self::new()
}
}
impl IoBus {
pub fn new() -> IoBus {
Self {
inner: RwLock::new(MmioRange::with_size(u16::MAX as usize)),
}
}
pub(super) fn add(&self, port: u16, dev: IoDev) -> Result<()> {
let mut inner = self.inner.write()?;
let dev = inner.add(port as usize, dev)?;
dev.mapped(port as usize)?;
Ok(())
}
pub fn read(&self, port: u16, size: u8) -> Result<u32> {
let inner = self.inner.read()?;
inner.read(port as usize, size).map(|v| v as u32)
}
pub fn write(&self, port: u16, size: u8, val: u32) -> Result<()> {
let inner = self.inner.read()?;
inner.write(port as usize, size, val as u64)
}
}