[COMMIT osv master] arm on firecracker: detect and enable mmio isa early console

4 views
Skip to first unread message

Commit Bot

unread,
Jun 27, 2020, 11:33:10 AM6/27/20
to osv...@googlegroups.com, Waldemar Kozaczuk
From: Waldemar Kozaczuk <jwkoz...@gmail.com>
Committer: Waldemar Kozaczuk <jwkoz...@gmail.com>
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 <jwkoz...@gmail.com>

---
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"; }
Reply all
Reply to author
Forward
0 new messages