summary refs log tree commit diff
diff options
context:
space:
mode:
authorSonny Rao <sonnyrao@chromium.org>2018-06-25 18:51:03 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-10-12 15:16:54 -0700
commitc7af4b1e68ea06136b1474976df8ea2e9528b2b3 (patch)
treec604aa4838fd825b08b6bcaa31d576d2a2223442
parent06a7779e675eb2439672f7abf4fc92ba44085a0a (diff)
downloadcrosvm-c7af4b1e68ea06136b1474976df8ea2e9528b2b3.tar
crosvm-c7af4b1e68ea06136b1474976df8ea2e9528b2b3.tar.gz
crosvm-c7af4b1e68ea06136b1474976df8ea2e9528b2b3.tar.bz2
crosvm-c7af4b1e68ea06136b1474976df8ea2e9528b2b3.tar.lz
crosvm-c7af4b1e68ea06136b1474976df8ea2e9528b2b3.tar.xz
crosvm-c7af4b1e68ea06136b1474976df8ea2e9528b2b3.tar.zst
crosvm-c7af4b1e68ea06136b1474976df8ea2e9528b2b3.zip
aarch64: add arm serial input support
Wire up the serial device interrupt on aarch64 so stdin works.

BUG=chromium:890956
TEST=Verify serial console works on kevin

Change-Id: Ifcafecb10d443f0100f047d0a2ec545c24e718af
Signed-off-by: Daniel Verkamp <dverkamp@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1115728
Reviewed-by: Sonny Rao <sonnyrao@chromium.org>
-rw-r--r--aarch64/src/fdt.rs7
-rw-r--r--aarch64/src/lib.rs36
2 files changed, 21 insertions, 22 deletions
diff --git a/aarch64/src/fdt.rs b/aarch64/src/fdt.rs
index c6e5f6a..97f3c61 100644
--- a/aarch64/src/fdt.rs
+++ b/aarch64/src/fdt.rs
@@ -29,6 +29,7 @@ use AARCH64_RTC_SIZE;
 
 // These are serial device related constants.
 use AARCH64_SERIAL_ADDR;
+use AARCH64_SERIAL_IRQ;
 use AARCH64_SERIAL_SIZE;
 use AARCH64_SERIAL_SPEED;
 
@@ -324,11 +325,17 @@ fn create_timer_node(fdt: &mut Vec<u8>, num_cpus: u32) -> Result<(), Box<Error>>
 
 fn create_serial_node(fdt: &mut Vec<u8>) -> Result<(), Box<Error>> {
     let serial_reg_prop = generate_prop64(&[AARCH64_SERIAL_ADDR, AARCH64_SERIAL_SIZE]);
+    let irq = generate_prop32(&[
+        GIC_FDT_IRQ_TYPE_SPI,
+        AARCH64_SERIAL_IRQ,
+        IRQ_TYPE_EDGE_RISING,
+    ]);
 
     begin_node(fdt, "U6_16550A@3f8")?;
     property_string(fdt, "compatible", "ns16550a")?;
     property(fdt, "reg", &serial_reg_prop)?;
     property_u32(fdt, "clock-frequency", AARCH64_SERIAL_SPEED)?;
+    property(fdt, "interrupts", &irq)?;
     end_node(fdt)?;
 
     Ok(())
diff --git a/aarch64/src/lib.rs b/aarch64/src/lib.rs
index d5bbc0d..8e00f2e 100644
--- a/aarch64/src/lib.rs
+++ b/aarch64/src/lib.rs
@@ -91,14 +91,16 @@ const AARCH64_SERIAL_ADDR: u64 = 0x3F8;
 const AARCH64_SERIAL_SIZE: u64 = 0x8;
 // This was the speed kvmtool used, not sure if it matters.
 const AARCH64_SERIAL_SPEED: u32 = 1843200;
+// The serial device gets the first interrupt line
+// Which gets mapped to the first SPI interrupt (physical 32).
+const AARCH64_SERIAL_IRQ: u32 = 0;
 
 // Place the RTC device at page 2
 const AARCH64_RTC_ADDR: u64 = 0x2000;
 // The RTC device gets one 4k page
 const AARCH64_RTC_SIZE: u64 = 0x1000;
-// The RTC device gets the first interrupt line
-// Which gets mapped to the first SPI interrupt (physical 32).
-const AARCH64_RTC_IRQ: u32 = 0;
+// The RTC device gets the second interrupt line
+const AARCH64_RTC_IRQ: u32 = 1;
 
 // PCI MMIO configuration region base address.
 const AARCH64_PCI_CFG_BASE: u64 = 0x10000;
@@ -110,8 +112,8 @@ const AARCH64_MMIO_BASE: u64 = 0x1010000;
 const AARCH64_MMIO_SIZE: u64 = 0x100000;
 // Each MMIO device gets a 4k page.
 const AARCH64_MMIO_LEN: u64 = 0x1000;
-// Virtio devices start at SPI interrupt number 1
-const AARCH64_IRQ_BASE: u32 = 1;
+// Virtio devices start at SPI interrupt number 2
+const AARCH64_IRQ_BASE: u32 = 2;
 
 #[derive(Debug)]
 pub enum Error {
@@ -227,12 +229,14 @@ impl arch::LinuxArch for AArch64 {
         let pci_bus = Arc::new(Mutex::new(PciConfigMmio::new(pci)));
 
         let exit_evt = EventFd::new().map_err(Error::CreateEventFd)?;
-        let (io_bus, stdio_serial) = Self::setup_io_bus()?;
+
+        // ARM doesn't really use the io bus like x86, so just create an empty bus.
+        let io_bus = devices::Bus::new();
 
         // Create a list of mmio devices to be added.
         let mmio_devs = virtio_devs(&mem, &exit_evt)?;
 
-        Self::add_arch_devs(&mut vm, &mut mmio_bus)?;
+        let stdio_serial = Self::add_arch_devs(&mut vm, &mut mmio_bus)?;
 
         for stub in mmio_devs {
             arch::register_mmio(
@@ -357,11 +361,12 @@ impl AArch64 {
     ///
     /// * `vm` - The vm to add irqs to.
     /// * `bus` - The bus to add devices to.
-    fn add_arch_devs(vm: &mut Vm, bus: &mut Bus) -> Result<()> {
+    fn add_arch_devs(vm: &mut Vm, bus: &mut Bus) -> Result<Arc<Mutex<devices::Serial>>> {
         let rtc_evt = EventFd::new()?;
         vm.register_irqfd(&rtc_evt, AARCH64_RTC_IRQ)?;
 
         let com_evt_1_3 = EventFd::new()?;
+        vm.register_irqfd(&com_evt_1_3, AARCH64_SERIAL_IRQ)?;
         let serial = Arc::new(Mutex::new(devices::Serial::new_out(
             com_evt_1_3.try_clone()?,
             Box::new(stdout()),
@@ -376,7 +381,7 @@ impl AArch64 {
         let rtc = Arc::new(Mutex::new(devices::pl030::Pl030::new(rtc_evt)));
         bus.insert(rtc, AARCH64_RTC_ADDR, AARCH64_RTC_SIZE, false)
             .expect("failed to add rtc device");
-        Ok(())
+        Ok(serial)
     }
 
     /// The creates the interrupt controller device and optionally returns the fd for it.
@@ -467,19 +472,6 @@ impl AArch64 {
         Ok(Some(vgic_fd))
     }
 
-    fn setup_io_bus() -> Result<(devices::Bus, Arc<Mutex<devices::Serial>>)> {
-        // ARM doesn't really use the io bus like x86, instead we have a
-        // separate serial device that is returned as a separate object.
-        let io_bus = devices::Bus::new();
-        let com_evt_1_3 = EventFd::new()?;
-
-        let serial = Arc::new(Mutex::new(devices::Serial::new_out(
-            com_evt_1_3.try_clone()?,
-            Box::new(stdout()),
-        )));
-        Ok((io_bus, serial))
-    }
-
     fn configure_vcpu(
         guest_mem: &GuestMemory,
         _kvm: &Kvm,