From: Waldemar Kozaczuk <[email protected]>
Committer: Waldemar Kozaczuk <[email protected]>
Branch: master

arm on firecracker: detect and enable mmio isa early console

This patch adds logic to detect memory-mapped serial console
configuration in DTB tree and enable it when running OSv
on arm version of firecracker.

Signed-off-by: Waldemar Kozaczuk <[email protected]>

---
diff --git a/arch/aarch64/arch-dtb.cc b/arch/aarch64/arch-dtb.cc
--- a/arch/aarch64/arch-dtb.cc
+++ b/arch/aarch64/arch-dtb.cc
@@ -189,6 +189,36 @@ u64 dtb_get_uart(int *irqid)
     return retval;
 }
 
+u64 dtb_get_mmio_serial_console(int *irqid)
+{
+    int node;
+    struct dtb_int_spec int_spec[1];
+    u64 address;
+
+    if (!dtb)
+        return 0;
+
+    node = fdt_node_offset_by_compatible(dtb, -1, "ns16550a");
+    if (node < 0)
+        return 0;
+
+    const char *node_name = fdt_get_name(dtb, node, NULL);
+    if (!node_name) {
+        return 0;
+    }
+
+    if (sscanf(node_name,"uart@%x", &address) != 1) {
+        return 0;
+    }
+
+    if( !dtb_get_int_spec(node, int_spec, 1)) {
+        return 0;
+    };
+
+    *irqid = int_spec[0].irq_id;
+    return address;
+}
+
 /* this gets the virtual timer irq, we are not interested
  * about the other timers.
  */
diff --git a/arch/aarch64/arch-dtb.hh b/arch/aarch64/arch-dtb.hh
--- a/arch/aarch64/arch-dtb.hh
+++ b/arch/aarch64/arch-dtb.hh
@@ -49,6 +49,14 @@ size_t dtb_get_phys_memory(u64 *addr);
  */
 u64 dtb_get_uart(int *irqid);
 
+/* u64 dtb_get_mmio_serial_console(int *irqid)
+ *
+ * return the base address of the serial console and writes the
+ * irqid of the interrupt to irqid,
+ * or returns zero on failure.
+ */
+u64 dtb_get_mmio_serial_console(int *irqid);
+
 /* int gdb_get_timer_irq()
  *
  * returns the irqid of the virtual timer from the dtb,
diff --git a/arch/aarch64/arch-setup.cc b/arch/aarch64/arch-setup.cc
--- a/arch/aarch64/arch-setup.cc
+++ b/arch/aarch64/arch-setup.cc
@@ -25,6 +25,7 @@
 #include "drivers/pl011.hh"
 #include "early-console.hh"
 #include <osv/pci.hh>
+#include "drivers/mmio-isa-serial.hh"
 
 #include <alloca.h>
 
@@ -47,8 +48,9 @@ void arch_setup_pci()
     /* linear_map [TTBR0 - PCI config space] */
     u64 pci_cfg;
     size_t pci_cfg_len;
-    if (!dtb_get_pci_cfg(&pci_cfg, &pci_cfg_len))
-       return;
+    if (!dtb_get_pci_cfg(&pci_cfg, &pci_cfg_len)) {
+        return;
+    }
 
     pci::set_pci_cfg(pci_cfg, pci_cfg_len);
     pci_cfg = pci::get_pci_cfg(&pci_cfg_len);
@@ -91,7 +93,7 @@ void arch_setup_free_memory()
     mmu::linear_map((void *)mmu::mem_addr, (mmu::phys)mmu::mem_addr,
                     addr - mmu::mem_addr);
 
-    if (!is_xen()) {
+    if (console::PL011_Console::active) {
         /* linear_map [TTBR0 - UART] */
         addr = (mmu::phys)console::aarch64_console.pl011.get_base_addr();
         mmu::linear_map((void *)addr, addr, 0x1000, mmu::page_size,
@@ -116,6 +118,8 @@ void arch_setup_free_memory()
     osv::parse_cmdline(cmdline);
 
     mmu::switch_to_runtime_page_tables();
+
+    console::mmio_isa_serial_console::memory_map();
 }
 
 void arch_setup_tls(void *tls, const elf::tls_data& info)
@@ -179,15 +183,28 @@ void arch_init_drivers()
 
 void arch_init_early_console()
 {
+    console::mmio_isa_serial_console::_phys_mmio_address = 0;
+
     if (is_xen()) {
         new (&console::aarch64_console.xen) console::XEN_Console();
         console::arch_early_console = console::aarch64_console.xen;
         return;
     }
 
+    int irqid;
+    u64 mmio_serial_address = dtb_get_mmio_serial_console(&irqid);
+    if (mmio_serial_address) {
+        console::mmio_isa_serial_console::early_init(mmio_serial_address);
+
+        new (&console::aarch64_console.isa_serial) 
console::mmio_isa_serial_console();
+        console::aarch64_console.isa_serial.set_irqid(irqid);
+        console::arch_early_console = console::aarch64_console.isa_serial;
+        return;
+    }
+
     new (&console::aarch64_console.pl011) console::PL011_Console();
     console::arch_early_console = console::aarch64_console.pl011;
-    int irqid;
+    console::PL011_Console::active = true;
     u64 addr = dtb_get_uart(&irqid);
     if (!addr) {
         /* keep using default addresses */
diff --git a/arch/aarch64/early-console.hh b/arch/aarch64/early-console.hh
--- a/arch/aarch64/early-console.hh
+++ b/arch/aarch64/early-console.hh
@@ -11,12 +11,15 @@
 #include <drivers/console-driver.hh>
 #include <drivers/pl011.hh>
 #include <drivers/xenconsole.hh>
+#include <drivers/mmio-isa-serial.hh>
+
 
 namespace console {
 
 union AARCH64_Console {
     PL011_Console pl011;
     XEN_Console xen;
+    mmio_isa_serial_console isa_serial;
 
     AARCH64_Console() {};  /* placement new is used to initialize object */
     ~AARCH64_Console() {}; /* won't ever be called */
diff --git a/drivers/pl011.cc b/drivers/pl011.cc
--- a/drivers/pl011.cc
+++ b/drivers/pl011.cc
@@ -25,6 +25,8 @@ enum {
     UARTICR   = 0x044
 };
 
+bool PL011_Console::active = false;
+
 void PL011_Console::set_base_addr(u64 addr)
 {
     uart = (char *)addr;
diff --git a/drivers/pl011.hh b/drivers/pl011.hh
--- a/drivers/pl011.hh
+++ b/drivers/pl011.hh
@@ -25,6 +25,7 @@ public:
     u64 get_base_addr();
     void set_irqid(int irqid);
 
+    static bool active;
 private:
     virtual void dev_start();
     virtual const char *thread_name() { return "pl011-input"; }

-- 
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/osv-dev/000000000000ee60c505a9128a9b%40google.com.

Reply via email to