All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexander Graf <agraf@suse.de>
To: "qemu-ppc@nongnu.org list:PowerPC" <qemu-ppc@nongnu.org>
Cc: Peter Maydell <peter.maydell@linaro.org>,
	qemu-devel Developers <qemu-devel@nongnu.org>
Subject: [Qemu-devel] [PATCH 1/9] PlatBus: Add Platform Bus
Date: Mon, 22 Jul 2013 19:50:03 +0200	[thread overview]
Message-ID: <1374515411-43818-2-git-send-email-agraf@suse.de> (raw)
In-Reply-To: <1374515411-43818-1-git-send-email-agraf@suse.de>

The platform bus is a very simple bus, similar to SysBus. However it has
a linear IRQ range that platform devices can attach to. It also provdes
mechanisms to dynamically place IO regions.

This patch implements the bus logic itself.

Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/platbus/platbus.c         | 107 +++++++++++++++++++++++++++++++++++++++++++
 include/hw/platbus/platbus.h |  86 ++++++++++++++++++++++++++++++++++
 2 files changed, 193 insertions(+)
 create mode 100644 hw/platbus/platbus.c
 create mode 100644 include/hw/platbus/platbus.h

diff --git a/hw/platbus/platbus.c b/hw/platbus/platbus.c
new file mode 100644
index 0000000..769eb5d
--- /dev/null
+++ b/hw/platbus/platbus.c
@@ -0,0 +1,107 @@
+/*
+ * Generic platform bus with dynamic IRQ and IO placement
+ *
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * Authors: Alexander Graf,   <agraf@suse.de>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of  the GNU General  Public License as published by
+ * the Free Software Foundation;  either version 2 of the  License, or
+ * (at your option) any later version.
+ *
+ * The platform bus is a very simple bus, similar to SysBus. However it has
+ * a linear IRQ range that platform devices can attach to. It also provdes
+ * mechanisms to dynamically place IO regions.
+ *
+ * Hence platform bus devices can be easily instantiated using -device from
+ * the command line.
+ */
+
+#include "qemu-common.h"
+#include "hw/platbus/platbus.h"
+
+int platbus_map_irq(PlatBusState *s, uint32_t *irqn, qemu_irq *irq)
+{
+    if (*irqn == (uint32_t)PLATBUS_DYNAMIC) {
+        /* Find the first available IRQ */
+        *irqn = find_first_zero_bit(s->used_irqs, PLATBUS_MAX_IRQ);
+    }
+
+    if ((*irqn >= PLATBUS_MAX_IRQ) || test_and_set_bit(*irqn, s->used_irqs)) {
+        hw_error("PlatBus: IRQ %d is already allocated or no free IRQ left",
+                 *irqn);
+    }
+
+    *irq = s->irqs[*irqn];
+
+    return 0;
+}
+
+void platbus_add_irq(PlatBusState *s, uint32_t irqn)
+{
+    clear_bit(irqn, s->used_irqs);
+}
+
+int platbus_map_region(PlatBusState *s, uint64_t *addr, MemoryRegion *mem)
+{
+    uint64_t size = memory_region_size(mem);
+    uint64_t size_pages = (size + ((1 << 12) - 1)) >> 12;
+    int page;
+    int i;
+
+    page = *addr >> 12;
+    if (*addr == (uint64_t)PLATBUS_DYNAMIC) {
+        uint64_t size_pages_align;
+
+        /* Align the region to at least its own size granularity */
+        if (is_power_of_2(size_pages)) {
+            size_pages_align = size_pages;
+        } else {
+            size_pages_align = pow2floor(size_pages) << 1;
+        }
+
+        /* Find the first available region that fits */
+        page = bitmap_find_next_zero_area(s->used_mem, PLATBUS_HOLE_PAGES, 0,
+                                          size_pages, size_pages_align);
+
+        *addr = (uint64_t)page << 12;
+    }
+
+    if (page >= PLATBUS_HOLE_PAGES || test_bit(page, s->used_mem) ||
+        (find_next_bit(s->used_mem, PLATBUS_HOLE_PAGES, page) < size_pages)) {
+        hw_error("PlatBus: Memory [%"PRIx64":%"PRIx64" is already allocated or "
+                 "no slot left", *addr, size);
+    }
+
+    for (i = page; i < (page + size_pages); i++) {
+        set_bit(i, s->used_mem);
+    }
+
+    memory_region_add_subregion(&s->mem, *addr, mem);
+
+    return 0;
+}
+
+static void platbus_init(Object *obj)
+{
+    PlatBusState *s = PLAT_BUS(obj);
+
+    QTAILQ_INIT(&s->devices);
+    bitmap_fill(s->used_irqs, PLATBUS_MAX_IRQ);
+    memory_region_init(&s->mem, NULL, "platbus", PLATBUS_HOLE);
+}
+
+static const TypeInfo platbus_type_info = {
+    .name = TYPE_PLAT_BUS,
+    .parent = TYPE_BUS,
+    .instance_size = sizeof(PlatBusState),
+    .instance_init = platbus_init,
+};
+
+static void platbus_register_types(void)
+{
+    type_register_static(&platbus_type_info);
+}
+
+type_init(platbus_register_types)
diff --git a/include/hw/platbus/platbus.h b/include/hw/platbus/platbus.h
new file mode 100644
index 0000000..d260fb8
--- /dev/null
+++ b/include/hw/platbus/platbus.h
@@ -0,0 +1,86 @@
+/*
+ * Generic platform bus with dynamic IRQ and IO placement
+ *
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * Authors: Alexander Graf,   <agraf@suse.de>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of  the GNU General  Public License as published by
+ * the Free Software Foundation;  either version 2 of the  License, or
+ * (at your option) any later version.
+ */
+
+#ifndef QEMU_HW_PLATBUS_PLATBUS_H
+#define QEMU_HW_PLATBUS_PLATBUS_H
+
+#include "qemu-common.h"
+#include "hw/qdev.h"
+#include "qemu/bitmap.h"
+/* for QDEV_MAX_IRQ */
+#include "hw/sysbus.h"
+
+#define PLATBUS_MAX_IRQ QDEV_MAX_IRQ
+#define PLATBUS_DYNAMIC -1LL
+#define PLATBUS_HOLE (128ULL * 1024 * 1024) /* 128 MB */
+#define PLATBUS_HOLE_PAGES (PLATBUS_HOLE >> 12)
+
+#define TYPE_PLAT_BUS "platbus"
+#define PLAT_BUS(obj) OBJECT_CHECK(PlatBusState, (obj), TYPE_PLAT_BUS)
+
+typedef struct PlatBusState {
+    /*< private >*/
+    BusState parent_obj;
+    qemu_irq irqs[PLATBUS_MAX_IRQ];
+    DECLARE_BITMAP(used_irqs, PLATBUS_MAX_IRQ);
+    DECLARE_BITMAP(used_mem, PLATBUS_HOLE_PAGES);
+    /*< public >*/
+
+    QTAILQ_HEAD(, PlatBusDeviceState) devices;
+    MemoryRegion mem;
+} PlatBusState;
+
+/**
+ * platbus_map_region:
+ * @s: Bus to map the region to
+ * @addr: Pointer to the offset inside the platform bus address range we want to
+ *        map to. Should be PLATBUS_DYNAMIC if the bus is supposed to give us an
+ *        address. Gets written back with the actually mapped address.
+ * @mem: Pointer to a properly initialized MemoryRegion which should get mapped
+ *       into the platform bus's address space. Does not get modified.
+ *
+ * Tell the platform bus to map a device's memory region into the platform bus's
+ * address range.
+ *
+ * Returns: 0 on success. Negative values on error.
+ */
+int platbus_map_region(PlatBusState *s, uint64_t *addr, MemoryRegion *mem);
+
+/**
+ * platbus_map_region:
+ * @s: Bus to map the IRQ to
+ * @irqn: Pointer to the IRQ inside the platform bus IRQ range we want to
+ *        map to. Should be PLATBUS_DYNAMIC if the bus is supposed to give us an
+ *        IRQ number. Gets written back with the actually mapped IRQ.
+ * @irq: Pointer to a qemu_irq field. Gets populated with a real qemu_irq when
+ *       the mapping gets successfully established.
+ *
+ * Tell the platform bus to map a device's IRQ into the platform bus's IRQ range.
+ *
+ * Returns: 0 on success. Negative values on error.
+ */
+int platbus_map_irq(PlatBusState *s, uint32_t *irqn, qemu_irq *irq);
+
+/**
+ * platbus_add_irq:
+ * @s: Bus to map the IRQ to
+ * @irqn: IRQ number that gets declared valid
+ *
+ * Tell the platform bus that one of its internal IRQ lines was successfully
+ * populated with a usable qemu_irq object.
+ *
+ * Returns: 0 on success. Negative values on error.
+ */
+void platbus_add_irq(PlatBusState *s, uint32_t irqn);
+
+#endif /* !QEMU_HW_PLATBUS_PLATBUS_H */
-- 
1.8.1.4

  reply	other threads:[~2013-07-22 17:50 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-07-22 17:50 [Qemu-devel] [PATCH 0/9] Add platform bus Alexander Graf
2013-07-22 17:50 ` Alexander Graf [this message]
2013-07-22 17:50 ` [Qemu-devel] [PATCH 2/9] PlatBus: Add abstract Platform Device Alexander Graf
2013-07-22 17:50 ` [Qemu-devel] [PATCH 3/9] PlatBus: Add Sysbus/Platform bridge device Alexander Graf
2013-07-22 17:50 ` [Qemu-devel] [PATCH 4/9] PlatBus: Hook up into Makefile system Alexander Graf
2013-07-22 17:50 ` [Qemu-devel] [PATCH 5/9] PPC: Add platform bus to the default compile set Alexander Graf
2013-07-22 17:50 ` [Qemu-devel] [PATCH 6/9] PlatBus: Add serial-platbus device Alexander Graf
2013-07-22 18:26   ` Peter Maydell
2013-07-22 18:56     ` Alexander Graf
2013-07-24 20:16       ` Scott Wood
2013-07-24 20:25         ` Peter Maydell
2013-07-22 17:50 ` [Qemu-devel] [PATCH 7/9] PPC: Add PlatBus Serial to default configs Alexander Graf
2013-07-22 17:50 ` [Qemu-devel] [PATCH 8/9] PPC: E500: Spawn PlatBus bridge for ppce500 machine Alexander Graf
2013-07-22 17:50 ` [Qemu-devel] [PATCH 9/9] PPC: E500: Add PlatBus device tree walker Alexander Graf
2013-07-22 18:21 ` [Qemu-devel] [PATCH 0/9] Add platform bus Peter Maydell
2013-07-22 18:55   ` Alexander Graf
2013-07-23 12:19   ` Paolo Bonzini
2013-07-23 12:22     ` Peter Maydell
2013-07-23 12:34       ` Paolo Bonzini
2013-07-23 12:40         ` Peter Maydell
2013-07-23 13:06           ` Paolo Bonzini
2013-07-23 14:26           ` Anthony Liguori
2013-07-23 14:28             ` Peter Maydell
2013-07-23 12:29     ` François Revol
2013-07-22 19:38 ` Anthony Liguori
2013-07-22 19:44   ` Alexander Graf
2013-07-22 19:52     ` Anthony Liguori
2013-07-22 21:50       ` Peter Maydell
2013-07-22 22:05         ` Anthony Liguori
2013-07-22 22:34           ` Peter Maydell
2013-07-22 23:03             ` Andreas Färber

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1374515411-43818-2-git-send-email-agraf@suse.de \
    --to=agraf@suse.de \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.