From patchwork Wed Oct 21 09:25:02 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 36507 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 892B3B7B9D for ; Wed, 21 Oct 2009 20:26:11 +1100 (EST) Received: from localhost ([127.0.0.1]:45356 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1N0XSJ-0003U1-Hz for incoming@patchwork.ozlabs.org; Wed, 21 Oct 2009 05:26:07 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1N0XRT-0003SH-0Y for qemu-devel@nongnu.org; Wed, 21 Oct 2009 05:25:15 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1N0XRN-0003Q1-NE for qemu-devel@nongnu.org; Wed, 21 Oct 2009 05:25:13 -0400 Received: from [199.232.76.173] (port=55463 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1N0XRN-0003Pr-DH for qemu-devel@nongnu.org; Wed, 21 Oct 2009 05:25:09 -0400 Received: from cantor2.suse.de ([195.135.220.15]:39774 helo=mx2.suse.de) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1N0XRM-0000vZ-I0 for qemu-devel@nongnu.org; Wed, 21 Oct 2009 05:25:09 -0400 Received: from relay1.suse.de (relay-ext.suse.de [195.135.221.8]) by mx2.suse.de (Postfix) with ESMTP id 0613D8672B; Wed, 21 Oct 2009 11:25:07 +0200 (CEST) From: Alexander Graf To: qemu-devel Date: Wed, 21 Oct 2009 11:25:02 +0200 Message-Id: <1256117106-9475-6-git-send-email-agraf@suse.de> X-Mailer: git-send-email 1.6.0.2 In-Reply-To: <1256117106-9475-5-git-send-email-agraf@suse.de> References: <1256117106-9475-1-git-send-email-agraf@suse.de> <1256117106-9475-2-git-send-email-agraf@suse.de> <1256117106-9475-3-git-send-email-agraf@suse.de> <1256117106-9475-4-git-send-email-agraf@suse.de> <1256117106-9475-5-git-send-email-agraf@suse.de> X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.4-2.6 Cc: Carsten Otte Subject: [Qemu-devel] [PATCH 5/9] Add S390x virtio machine description X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org In order to use the new S390x virtio bus we just introduced, we also need a machine description that sets up the machine according to our PV specification. Let's add that machine description and be happy! Signed-off-by: Alexander Graf --- Makefile.target | 2 +- hw/s390-virtio.c | 244 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 245 insertions(+), 1 deletions(-) create mode 100644 hw/s390-virtio.c diff --git a/Makefile.target b/Makefile.target index ef72867..524be43 100644 --- a/Makefile.target +++ b/Makefile.target @@ -294,7 +294,7 @@ obj-sh4-y += ide/core.o ide/mmio.o obj-m68k-y = an5206.o mcf5206.o mcf_uart.o mcf_intc.o mcf5208.o mcf_fec.o obj-m68k-y += m68k-semi.o dummy_m68k.o -obj-s390x-y = s390-virtio-bus.o +obj-s390x-y = s390-virtio-bus.o s390-virtio.o main.o vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c new file mode 100644 index 0000000..cd62e54 --- /dev/null +++ b/hw/s390-virtio.c @@ -0,0 +1,244 @@ +/* + * QEMU S390 virtio target + * + * Copyright (c) 2009 Alexander Graf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "hw.h" +#include "block.h" +#include "sysemu.h" +#include "net.h" +#include "boards.h" +#include "monitor.h" +#include "loader.h" +#include "elf.h" +#include "hw/virtio.h" +#include "hw/virtio-console.h" +#include "hw/sysbus.h" +#include "kvm.h" + +#include "hw/s390-virtio-bus.h" + +//#define DEBUG_S390 + +#ifdef DEBUG_S390 +#define dprintf(fmt, ...) \ + do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0) +#else +#define dprintf(fmt, ...) \ + do { } while (0) +#endif + +#define KVM_S390_VIRTIO_NOTIFY 0 +#define KVM_S390_VIRTIO_RESET 1 +#define KVM_S390_VIRTIO_SET_STATUS 2 + +#define KERN_IMAGE_START 0x010000UL +#define KERN_PARM_AREA 0x010480UL +#define INITRD_START 0x800000UL +#define INITRD_PARM_START 0x010408UL +#define INITRD_PARM_SIZE 0x010410UL +#define PARMFILE_START 0x001000UL + +#define MAX_BLK_DEVS 10 + +static VirtIOS390Bus *s390_bus; +static CPUState **ipi_states; + +void irq_info(Monitor *mon); +void pic_info(Monitor *mon); + +void irq_info(Monitor *mon) +{ +} + +void pic_info(Monitor *mon) +{ +} + +CPUState *s390_cpu_addr2state(uint16_t cpu_addr) +{ + if (cpu_addr >= smp_cpus) + return NULL; + + return ipi_states[cpu_addr]; +} + +int s390_virtio_hypercall(CPUState *env) +{ + int r = 0, i; + target_ulong mem = env->regs[2]; + + dprintf("KVM hypercall: %ld\n", env->regs[1]); + switch (env->regs[1]) { + case KVM_S390_VIRTIO_NOTIFY: + if (mem > ram_size) { + VirtIOS390Device *dev = s390_virtio_bus_find_vring(s390_bus, + mem, &i); + if (dev) { + virtio_queue_notify(dev->vdev, i); + } else { + r = -EINVAL; + } + } else { + /* Early printk */ + uint8_t *p = (uint8_t *)qemu_get_ram_ptr(mem); + VirtIOS390Device *dev = s390_virtio_bus_console(s390_bus); + virtio_console_print_early(dev->vdev, p); + } + break; + case KVM_S390_VIRTIO_RESET: + { + /* Virtio_reset resets the internal addresses, so we'd have to sync + them up again. We don't want to reallicate a vring though, so let's + just not reset. */ + /* virtio_reset(dev->vdev); */ + break; + } + case KVM_S390_VIRTIO_SET_STATUS: + { + VirtIOS390Device *dev; + + dev = s390_virtio_bus_find_mem(s390_bus, mem); + if (dev) + s390_virtio_device_update_status(dev); + else + r = -EINVAL; + break; + } + default: + r = -EINVAL; + break; + } + + env->regs[2] = r; + return 0; +} + +/* PC hardware initialisation */ +static void s390_init(ram_addr_t _ram_size, + const char *boot_device, + const char *kernel_filename, + const char *kernel_cmdline, + const char *initrd_filename, + const char *cpu_model) +{ + CPUState *env = NULL; + ram_addr_t ram_addr, ram_size = _ram_size; + ram_addr_t kernel_size = 0; + ram_addr_t initrd_offset; + ram_addr_t initrd_size = 0; + int i; + + /* get a BUS */ + s390_bus = s390_virtio_bus_init(&ram_size); + + /* allocate RAM */ + /* S390 requires the topmost virtual address of the RAM to be < 256GB */ + ram_addr = _qemu_ram_alloc(ram_size, (void*)0x1000000); + cpu_register_physical_memory(0, ram_size, ram_addr); + + /* init CPUs */ + if (cpu_model == NULL) { + cpu_model = "host"; + } + + ipi_states = qemu_malloc(sizeof(CPUState *) * smp_cpus); + + for (i = 0; i < smp_cpus; i++) { + env = cpu_init(cpu_model); + ipi_states[smp_cpus - (i + 1)] = env; + env->halted = 1; + env->exception_index = EXCP_HLT; + } + + env->halted = 0; + env->exception_index = 0; + + if (kernel_filename) { + kernel_size = load_image(kernel_filename, qemu_get_ram_ptr(0)); + + if (lduw_phys(KERN_IMAGE_START) != 0x0dd0) { + fprintf(stderr, "Specified image is not an s390 boot image\n"); + exit(1); + } + + cpu_synchronize_state(env); + env->psw.addr = KERN_IMAGE_START; + env->psw.mask = 0x0000000180000000UL; + } + + if (initrd_filename) { + initrd_offset = INITRD_START; + while (kernel_size + 0x100000 > initrd_offset) + initrd_offset += 0x100000; + initrd_size = load_image(initrd_filename, qemu_get_ram_ptr(initrd_offset)); + + stq_phys(INITRD_PARM_START, initrd_offset); + stq_phys(INITRD_PARM_SIZE, initrd_size); + } + + if (kernel_cmdline) { + cpu_physical_memory_rw(KERN_PARM_AREA, (uint8_t *)kernel_cmdline, + strlen(kernel_cmdline), 1); + } + + /* Create VirtIO console */ + qdev_init_nofail(qdev_create((BusState *)s390_bus, "virtio-console-s390")); + + /* Create VirtIO network adapters */ + for(i = 0; i < nb_nics; i++) { + NICInfo *nd = &nd_table[i]; + DeviceState *dev; + + if (!nd->model) + nd->model = (char*)"virtio"; + + dev = qdev_create((BusState *)s390_bus, "virtio-net-s390"); + dev->nd = nd; + qdev_init_nofail(dev); + } + + /* Create VirtIO disk drives */ + for(i = 0; i < MAX_BLK_DEVS; i++) { + DriveInfo *dinfo; + DeviceState *dev; + + dinfo = drive_get(IF_IDE, 0, i); + if (!dinfo) + continue; + + dev = qdev_create((BusState *)s390_bus, "virtio-blk-s390"); + qdev_prop_set_drive(dev, "drive", dinfo); + qdev_init_nofail(dev); + } +} + +static QEMUMachine s390_machine = { + .name = "s390-virtio", + .alias = "s390", + .desc = "VirtIO based S390 machine", + .init = s390_init, + .max_cpus = 255, + .is_default = 1, +}; + +static void s390_machine_init(void) +{ + qemu_register_machine(&s390_machine); +} + +machine_init(s390_machine_init);