summaryrefslogtreecommitdiffstats
path: root/platforms
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2015-07-03 13:49:16 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-07-03 17:09:44 +1000
commitef50b5f5ad2834996eabc7e10885659a1ef65196 (patch)
treeee96305dfa1f6254e6d212de9592ed243eda4380 /platforms
parent545c2d925d92ce0c0f50436596e5f6bb2cda8b81 (diff)
downloadtalos-skiboot-ef50b5f5ad2834996eabc7e10885659a1ef65196.tar.gz
talos-skiboot-ef50b5f5ad2834996eabc7e10885659a1ef65196.zip
plat/qemu: Add simple qemu platform
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@kernel.crashing.org> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'platforms')
-rw-r--r--platforms/Makefile.inc3
-rw-r--r--platforms/qemu/Makefile.inc6
-rw-r--r--platforms/qemu/qemu.c143
3 files changed, 151 insertions, 1 deletions
diff --git a/platforms/Makefile.inc b/platforms/Makefile.inc
index 12c82c8e..90cd0f1c 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 00000000..11a44dbd
--- /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 00000000..43e12213
--- /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@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@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,
+};
OpenPOWER on IntegriCloud