[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