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 <ag...@suse.de> --- hw/xenner_pv.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 135 insertions(+), 0 deletions(-) create mode 100644 hw/xenner_pv.c 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 <kra...@redhat.com> + * Alexander Graf <ag...@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; +} -- 1.6.0.2