From c7af4b1e68ea06136b1474976df8ea2e9528b2b3 Mon Sep 17 00:00:00 2001 From: Sonny Rao Date: Mon, 25 Jun 2018 18:51:03 -0700 Subject: 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 Reviewed-on: https://chromium-review.googlesource.com/1115728 Reviewed-by: Sonny Rao --- aarch64/src/fdt.rs | 7 +++++++ aarch64/src/lib.rs | 36 ++++++++++++++---------------------- 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, num_cpus: u32) -> Result<(), Box> fn create_serial_node(fdt: &mut Vec) -> Result<(), Box> { 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>> { 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>)> { - // 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, -- cgit 1.4.1