Patchwork [34/40] xenner: PV machine

login
register
mail settings
Submitter Alexander Graf
Date Nov. 1, 2010, 3:01 p.m.
Message ID <1288623713-28062-35-git-send-email-agraf@suse.de>
Download mbox | patch
Permalink /patch/69797/
State New
Headers show

Comments

Alexander Graf - Nov. 1, 2010, 3:01 p.m.
The same as Xen has a PV machine to do all the initialization of devices, we
have one for xenner. This patch implements said machine description.

Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/xenner_pv.c |  135 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 135 insertions(+), 0 deletions(-)
 create mode 100644 hw/xenner_pv.c

Patch

diff --git a/hw/xenner_pv.c b/hw/xenner_pv.c
new file mode 100644
index 0000000..6350075
--- /dev/null
+++ b/hw/xenner_pv.c
@@ -0,0 +1,135 @@ 
+/*
+ *  Copyright (C) Red Hat 2007
+ *  Copyright (C) Novell Inc. 2010
+ *
+ *  Author(s): Gerd Hoffmann <kraxel@redhat.com>
+ *             Alexander Graf <agraf@suse.de>
+ *
+ *  Xenner PV machine
+ *
+ *  This program 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; under version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/mman.h>
+
+#include <xen/io/protocols.h>
+
+#include "hw.h"
+#include "pc.h"
+#include "kvm.h"
+#include "sysemu.h"
+#include "qemu-char.h"
+#include "xen_backend.h"
+#include "xen_interfaces.h"
+#include "xen_domainbuild.h"
+#include "xenner.h"
+#include "xenner_emudev.h"
+#include "loader.h"
+#include "elf.h"
+#include "apic.h"
+#include "sysbus.h"
+
+/* ------------------------------------------------------------- */
+
+/* convert megabytes to pages and back */
+#define MB_TO_PG(x) (x << 8)
+#define PG_TO_MB(x) (x >> 8)
+
+#define addr_to_frame(addr)    ((addr) >> PAGE_SHIFT)
+#define frame_to_addr(frame)   ((frame) << PAGE_SHIFT)
+#define addr_offset(addr)      ((addr) & ~PAGE_MASK)
+
+static int       guest_evtchndev;
+
+/* ------------------------------------------------------------- */
+
+static IsaIrqState *isa_irq_state;
+
+static void ioapic_init(IsaIrqState *isa_irq_state)
+{
+    DeviceState *dev;
+    SysBusDevice *d;
+    unsigned int i;
+
+    dev = qdev_create(NULL, "ioapic");
+    qdev_init_nofail(dev);
+    d = sysbus_from_qdev(dev);
+    sysbus_mmio_map(d, 0, 0xfec00000);
+
+    for (i = 0; i < IOAPIC_NUM_PINS; i++) {
+        isa_irq_state->ioapic[i] = qdev_get_gpio_in(dev, i);
+    }
+}
+
+static void xenner_request_irq(void *opaque, int irq, int level)
+{
+}
+
+static int xenner_setup_irqs(void)
+{
+    qemu_irq *isa_irq;
+    qemu_irq *cpu_irq;
+
+    cpu_irq = qemu_allocate_irqs(xenner_request_irq, NULL, 1);
+    isa_irq_state = qemu_mallocz(sizeof(*isa_irq_state));
+    isa_irq_state->i8259 = i8259_init(cpu_irq[0]);
+    ioapic_init(isa_irq_state);
+    isa_irq = qemu_allocate_irqs(isa_irq_handler, isa_irq_state, 24);
+
+    isa_bus_new(NULL);
+    isa_bus_irqs(isa_irq);
+
+    return 0;
+}
+
+static void guest_evtchn_event(void *opaque)
+{
+    evtchn_port_t port;
+    int pin;
+
+    port = xc_evtchn.pending(guest_evtchndev);
+    if ((int)port < 0 || port > EMUDEV_CONF_EVTCHN_TO_PIN_COUNT) {
+        return;
+    }
+    xc_evtchn.unmask(guest_evtchndev, port);
+    pin = xenner_get_evtchn_pin(port);
+    qemu_set_irq(isa_irq_state->ioapic[pin], 1);
+}
+
+int xenner_init_pv(const char *kernel_filename,
+                   const char *kernel_cmdline,
+                   const char *initrd_filename)
+{
+    ram_addr_t ram_addr;
+    ram_addr_t boot_addr;
+
+    pc_cpus_init(NULL);
+
+    ram_addr = qemu_ram_alloc(NULL, "pc.ram", ram_size);
+    cpu_register_physical_memory(0, ram_size, ram_addr);
+
+    boot_addr = qemu_ram_alloc(NULL, "xenner.trampoline", 0x1000);
+    cpu_register_physical_memory(0xfffff000, 0x1000, boot_addr);
+
+    guest_evtchndev = xc_evtchn.open();
+    xenner_core_init(guest_evtchndev);
+    qemu_set_fd_handler(xc_evtchn.fd(guest_evtchndev),
+                        guest_evtchn_event, NULL, NULL);
+
+    xenner_setup_irqs();
+
+    xenner_domain_build_pv(kernel_filename, initrd_filename,
+                           kernel_cmdline);
+
+    return 0;
+}