[Skiboot] [PATCH 1/2] plat/qemu: Add simple qemu platform
Benjamin Herrenschmidt
benh at kernel.crashing.org
Fri Jul 3 13:49:16 AEST 2015
This adds support for running under qemu "powernv" platform, which
is currently available via the qemu repository at:
https://github.com/ozbenh/qemu branch "powernv"
qemu can't yet create DT entries for ISA devices so we hard wire the UART
and RTC devices in the device-tree like we do with other platforms.
Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
---
core/chip.c | 2 +-
platforms/Makefile.inc | 3 +-
platforms/qemu/Makefile.inc | 6 ++
platforms/qemu/qemu.c | 143 ++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 152 insertions(+), 2 deletions(-)
create mode 100644 platforms/qemu/Makefile.inc
create mode 100644 platforms/qemu/qemu.c
diff --git a/core/chip.c b/core/chip.c
index 00eba41..f2f1a96 100644
--- a/core/chip.c
+++ b/core/chip.c
@@ -77,7 +77,7 @@ void init_chips(void)
prlog(PR_NOTICE, "CHIP: Detected Mambo simulator\n");
}
if (dt_node_is_compatible(dt_root, "qemu,powernv")) {
- proc_chip_quirks |= QUIRK_NO_CHIPTOD | QUIRK_NO_PBA | QUIRK_NO_OCC_IRQ;
+ proc_chip_quirks |= QUIRK_NO_CHIPTOD | QUIRK_NO_PBA;
prlog(PR_NOTICE, "CHIP: Detected Qemu simulator\n");
}
diff --git a/platforms/Makefile.inc b/platforms/Makefile.inc
index 12c82c8..90cd0f1 100644
--- a/platforms/Makefile.inc
+++ b/platforms/Makefile.inc
@@ -7,5 +7,6 @@ include $(SRC)/$(PLATDIR)/ibm-fsp/Makefile.inc
include $(SRC)/$(PLATDIR)/rhesus/Makefile.inc
include $(SRC)/$(PLATDIR)/astbmc/Makefile.inc
include $(SRC)/$(PLATDIR)/mambo/Makefile.inc
+include $(SRC)/$(PLATDIR)/qemu/Makefile.inc
-$(PLATFORMS): $(IBM_FSP) $(RHESUS) $(ASTBMC) $(MAMBO)
+$(PLATFORMS): $(IBM_FSP) $(RHESUS) $(ASTBMC) $(MAMBO) $(QEMU)
diff --git a/platforms/qemu/Makefile.inc b/platforms/qemu/Makefile.inc
new file mode 100644
index 0000000..11a44db
--- /dev/null
+++ b/platforms/qemu/Makefile.inc
@@ -0,0 +1,6 @@
+SUBDIRS += $(PLATDIR)/qemu
+
+QEMU_OBJS = qemu.o
+QEMU = $(PLATDIR)/qemu/built-in.o
+$(QEMU): $(QEMU_OBJS:%=$(PLATDIR)/qemu/%)
+
diff --git a/platforms/qemu/qemu.c b/platforms/qemu/qemu.c
new file mode 100644
index 0000000..43e1221
--- /dev/null
+++ b/platforms/qemu/qemu.c
@@ -0,0 +1,143 @@
+/* Copyright 2013-2014 IBM Corp.
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+
+#include <skiboot.h>
+#include <device.h>
+#include <lpc.h>
+#include <console.h>
+#include <opal.h>
+#include <psi.h>
+
+static void qemu_init(void)
+{
+ /* Setup UART console for use by Linux via OPAL API */
+ if (!dummy_console_enabled())
+ uart_setup_opal_console();
+}
+
+static void qemu_dt_fixup_uart(struct dt_node *lpc)
+{
+ /*
+ * The official OF ISA/LPC binding is a bit odd, it prefixes
+ * the unit address for IO with "i". It uses 2 cells, the first
+ * one indicating IO vs. Memory space (along with bits to
+ * represent aliasing).
+ *
+ * We pickup that binding and add to it "2" as a indication
+ * of FW space.
+ *
+ * TODO: Probe the UART instead if the LPC bus allows for it
+ */
+ struct dt_node *uart;
+ char namebuf[32];
+#define UART_IO_BASE 0x3f8
+#define UART_IO_COUNT 8
+#define UART_LPC_IRQ 4
+
+ snprintf(namebuf, sizeof(namebuf), "serial at i%x", UART_IO_BASE);
+ uart = dt_new(lpc, namebuf);
+
+ dt_add_property_cells(uart, "reg",
+ 1, /* IO space */
+ UART_IO_BASE, UART_IO_COUNT);
+ dt_add_property_strings(uart, "compatible",
+ "ns16550",
+ "pnpPNP,501");
+ dt_add_property_cells(uart, "clock-frequency", 1843200);
+ dt_add_property_cells(uart, "current-speed", 115200);
+ dt_add_property_cells(uart, "interrupts", UART_LPC_IRQ);
+ dt_add_property_cells(uart, "interrupt-parent", lpc->phandle);
+
+ /*
+ * This is needed by Linux for some obscure reasons,
+ * we'll eventually need to sanitize it but in the meantime
+ * let's make sure it's there
+ */
+ dt_add_property_strings(uart, "device_type", "serial");
+}
+
+/*
+ * This adds the legacy RTC device to the device-tree
+ * for Linux to use
+ */
+static void qemu_dt_fixup_rtc(struct dt_node *lpc)
+{
+ struct dt_node *rtc;
+ char namebuf[32];
+
+ /*
+ * Follows the structure expected by the kernel file
+ * arch/powerpc/sysdev/rtc_cmos_setup.c
+ */
+ snprintf(namebuf, sizeof(namebuf), "rtc at i%x", 0x70);
+ rtc = dt_new(lpc, namebuf);
+ dt_add_property_string(rtc, "compatible", "pnpPNP,b00");
+ dt_add_property_cells(rtc, "reg",
+ 1, /* IO space */
+ 0x70, 2);
+}
+
+static void qemu_dt_fixup(void)
+{
+ struct dt_node *n, *primary_lpc = NULL;
+
+ /* Find the primary LPC bus */
+ dt_for_each_compatible(dt_root, n, "ibm,power8-lpc") {
+ if (!primary_lpc || dt_has_node_property(n, "primary", NULL))
+ primary_lpc = n;
+ if (dt_has_node_property(n, "#address-cells", NULL))
+ break;
+ }
+
+ if (!primary_lpc)
+ return;
+
+ qemu_dt_fixup_rtc(primary_lpc);
+ qemu_dt_fixup_uart(primary_lpc);
+}
+
+static void qemu_ext_irq_serirq_cpld(unsigned int chip_id)
+{
+ lpc_all_interrupts(chip_id);
+}
+
+static bool qemu_probe(void)
+{
+ if (!dt_node_is_compatible(dt_root, "qemu,powernv"))
+ return false;
+
+ /* Add missing bits of device-tree such as the UART */
+ qemu_dt_fixup();
+
+ psi_set_external_irq_policy(EXTERNAL_IRQ_POLICY_SKIBOOT);
+
+ /*
+ * Setup UART and use it as console. For now, we
+ * don't expose the interrupt as we know it's not
+ * working properly yet
+ */
+ uart_init(true);
+
+ return true;
+}
+
+DECLARE_PLATFORM(qemu) = {
+ .name = "Qemu",
+ .probe = qemu_probe,
+ .init = qemu_init,
+ .external_irq = qemu_ext_irq_serirq_cpld,
+};
More information about the Skiboot
mailing list