From patchwork Thu Jan 17 14:23:56 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cornelia Huck X-Patchwork-Id: 1996671 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 3024CDF2F2 for ; Thu, 17 Jan 2013 14:24:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756066Ab3AQOY3 (ORCPT ); Thu, 17 Jan 2013 09:24:29 -0500 Received: from e06smtp17.uk.ibm.com ([195.75.94.113]:46960 "EHLO e06smtp17.uk.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755959Ab3AQOYI (ORCPT ); Thu, 17 Jan 2013 09:24:08 -0500 Received: from /spool/local by e06smtp17.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 17 Jan 2013 14:23:13 -0000 Received: from b06cxnps4074.portsmouth.uk.ibm.com (9.149.109.196) by e06smtp17.uk.ibm.com (192.168.101.147) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Thu, 17 Jan 2013 14:23:12 -0000 Received: from d06av01.portsmouth.uk.ibm.com (d06av01.portsmouth.uk.ibm.com [9.149.37.212]) by b06cxnps4074.portsmouth.uk.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id r0HENuhK655856; Thu, 17 Jan 2013 14:23:56 GMT Received: from d06av01.portsmouth.uk.ibm.com (loopback [127.0.0.1]) by d06av01.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id r0HEO35S018153; Thu, 17 Jan 2013 07:24:04 -0700 Received: from tuxmaker.boeblingen.de.ibm.com (tuxmaker.boeblingen.de.ibm.com [9.152.85.9]) by d06av01.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id r0HENwSQ017784; Thu, 17 Jan 2013 07:24:03 -0700 From: Cornelia Huck To: qemu-devel , KVM , linux-s390 Cc: Marcelo Tosatti , Gleb Natapov , Anthony Liguori , Christian Borntraeger , Carsten Otte , Alexander Graf , Heiko Carstens , Martin Schwidefsky , Sebastian Ott Subject: [PATCH 11/12] s390-virtio: Factor out some initialization code. Date: Thu, 17 Jan 2013 15:23:56 +0100 Message-Id: <1358432637-42512-12-git-send-email-cornelia.huck@de.ibm.com> X-Mailer: git-send-email 1.7.12.4 In-Reply-To: <1358432637-42512-1-git-send-email-cornelia.huck@de.ibm.com> References: <1358432637-42512-1-git-send-email-cornelia.huck@de.ibm.com> x-cbid: 13011714-0542-0000-0000-00000428A67D Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Some of the machine initialization for s390-virtio will be reused by virtio-ccw. Signed-off-by: Cornelia Huck --- hw/s390-virtio.c | 155 ++++++++++++++++++++++++++++++------------------------- hw/s390-virtio.h | 5 ++ 2 files changed, 91 insertions(+), 69 deletions(-) diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c index bded30b..603f6b0 100644 --- a/hw/s390-virtio.c +++ b/hw/s390-virtio.c @@ -155,62 +155,10 @@ unsigned s390_del_running_cpu(CPUS390XState *env) return s390_running_cpus; } -/* PC hardware initialisation */ -static void s390_init(QEMUMachineInitArgs *args) +void s390_init_cpus(const char *cpu_model, uint8_t *storage_keys) { - ram_addr_t my_ram_size = args->ram_size; - const char *cpu_model = args->cpu_model; - const char *kernel_filename = args->kernel_filename; - const char *kernel_cmdline = args->kernel_cmdline; - const char *initrd_filename = args->initrd_filename; - CPUS390XState *env = NULL; - MemoryRegion *sysmem = get_system_memory(); - MemoryRegion *ram = g_new(MemoryRegion, 1); - ram_addr_t kernel_size = 0; - ram_addr_t initrd_offset; - ram_addr_t initrd_size = 0; - int shift = 0; - uint8_t *storage_keys; - void *virtio_region; - hwaddr virtio_region_len; - hwaddr virtio_region_start; int i; - /* s390x ram size detection needs a 16bit multiplier + an increment. So - guests > 64GB can be specified in 2MB steps etc. */ - while ((my_ram_size >> (20 + shift)) > 65535) { - shift++; - } - my_ram_size = my_ram_size >> (20 + shift) << (20 + shift); - - /* lets propagate the changed ram size into the global variable. */ - ram_size = my_ram_size; - - /* get a BUS */ - s390_bus = s390_virtio_bus_init(&my_ram_size); - s390_sclp_init(); - - /* register hypercalls */ - s390_virtio_register_hcalls(); - - /* allocate RAM */ - memory_region_init_ram(ram, "s390.ram", my_ram_size); - vmstate_register_ram_global(ram); - memory_region_add_subregion(sysmem, 0, ram); - - /* clear virtio region */ - virtio_region_len = my_ram_size - ram_size; - virtio_region_start = ram_size; - virtio_region = cpu_physical_memory_map(virtio_region_start, - &virtio_region_len, true); - memset(virtio_region, 0, virtio_region_len); - cpu_physical_memory_unmap(virtio_region, virtio_region_len, 1, - virtio_region_len); - - /* allocate storage keys */ - storage_keys = g_malloc0(my_ram_size / TARGET_PAGE_SIZE); - - /* init CPUs */ if (cpu_model == NULL) { cpu_model = "host"; } @@ -219,21 +167,27 @@ static void s390_init(QEMUMachineInitArgs *args) for (i = 0; i < smp_cpus; i++) { S390CPU *cpu; - CPUS390XState *tmp_env; cpu = cpu_s390x_init(cpu_model); - tmp_env = &cpu->env; - if (!env) { - env = tmp_env; - } + ipi_states[i] = cpu; - tmp_env->halted = 1; - tmp_env->exception_index = EXCP_HLT; - tmp_env->storage_keys = storage_keys; + cpu->env.halted = 1; + cpu->env.exception_index = EXCP_HLT; + cpu->env.storage_keys = storage_keys; } +} + +void s390_set_up_kernel(const char *kernel_filename, + const char *kernel_cmdline, + const char *initrd_filename) +{ + ram_addr_t kernel_size = 0; + ram_addr_t initrd_offset; + ram_addr_t initrd_size = 0; + S390CPU *cpu = s390_cpu_addr2state(0); /* One CPU has to run */ - s390_add_running_cpu(env); + s390_add_running_cpu(&cpu->env); if (kernel_filename) { @@ -252,8 +206,8 @@ static void s390_init(QEMUMachineInitArgs *args) * value was 0x800 (the SALIPL loader) and it wont work. For * all (Linux) cases 0x10000 (KERN_IMAGE_START) should be fine. */ - env->psw.addr = KERN_IMAGE_START; - env->psw.mask = 0x0000000180000000ULL; + cpu->env.psw.addr = KERN_IMAGE_START; + cpu->env.psw.mask = 0x0000000180000000ULL; } else { ram_addr_t bios_size = 0; char *bios_filename; @@ -275,8 +229,8 @@ static void s390_init(QEMUMachineInitArgs *args) hw_error("stage1 bootloader is > 4k\n"); } - env->psw.addr = ZIPL_START; - env->psw.mask = 0x0000000180000000ULL; + cpu->env.psw.addr = ZIPL_START; + cpu->env.psw.mask = 0x0000000180000000ULL; } if (initrd_filename) { @@ -302,9 +256,13 @@ static void s390_init(QEMUMachineInitArgs *args) memcpy(rom_ptr(KERN_PARM_AREA), kernel_cmdline, strlen(kernel_cmdline) + 1); } +} - /* Create VirtIO network adapters */ - for(i = 0; i < nb_nics; i++) { +void s390_create_virtio_net(BusState *bus, const char *name) +{ + int i; + + for (i = 0; i < nb_nics; i++) { NICInfo *nd = &nd_table[i]; DeviceState *dev; @@ -317,12 +275,71 @@ static void s390_init(QEMUMachineInitArgs *args) exit(1); } - dev = qdev_create((BusState *)s390_bus, "virtio-net-s390"); + dev = qdev_create(bus, name); qdev_set_nic_properties(dev, nd); qdev_init_nofail(dev); } } +/* PC hardware initialisation */ +static void s390_init(QEMUMachineInitArgs *args) +{ + ram_addr_t my_ram_size = args->ram_size; + const char *cpu_model = args->cpu_model; + const char *kernel_filename = args->kernel_filename; + const char *kernel_cmdline = args->kernel_cmdline; + const char *initrd_filename = args->initrd_filename; + MemoryRegion *sysmem = get_system_memory(); + MemoryRegion *ram = g_new(MemoryRegion, 1); + int shift = 0; + uint8_t *storage_keys; + void *virtio_region; + hwaddr virtio_region_len; + hwaddr virtio_region_start; + + /* s390x ram size detection needs a 16bit multiplier + an increment. So + guests > 64GB can be specified in 2MB steps etc. */ + while ((my_ram_size >> (20 + shift)) > 65535) { + shift++; + } + my_ram_size = my_ram_size >> (20 + shift) << (20 + shift); + + /* lets propagate the changed ram size into the global variable. */ + ram_size = my_ram_size; + + /* get a BUS */ + s390_bus = s390_virtio_bus_init(&my_ram_size); + s390_sclp_init(); + + /* register hypercalls */ + s390_virtio_register_hcalls(); + + /* allocate RAM */ + memory_region_init_ram(ram, "s390.ram", my_ram_size); + vmstate_register_ram_global(ram); + memory_region_add_subregion(sysmem, 0, ram); + + /* clear virtio region */ + virtio_region_len = my_ram_size - ram_size; + virtio_region_start = ram_size; + virtio_region = cpu_physical_memory_map(virtio_region_start, + &virtio_region_len, true); + memset(virtio_region, 0, virtio_region_len); + cpu_physical_memory_unmap(virtio_region, virtio_region_len, 1, + virtio_region_len); + + /* allocate storage keys */ + storage_keys = g_malloc0(my_ram_size / TARGET_PAGE_SIZE); + + /* init CPUs */ + s390_init_cpus(cpu_model, storage_keys); + + s390_set_up_kernel(kernel_filename, kernel_cmdline, initrd_filename); + + /* Create VirtIO network adapters */ + s390_create_virtio_net((BusState *)s390_bus, "virtio-net-s390"); +} + static QEMUMachine s390_machine = { .name = "s390-virtio", .alias = "s390", diff --git a/hw/s390-virtio.h b/hw/s390-virtio.h index 25bb610..aefc99d 100644 --- a/hw/s390-virtio.h +++ b/hw/s390-virtio.h @@ -19,4 +19,9 @@ typedef int (*s390_virtio_fn)(const uint64_t *args); void s390_register_virtio_hypercall(uint64_t code, s390_virtio_fn fn); +void s390_init_cpus(const char *cpu_model, uint8_t *storage_keys); +void s390_set_up_kernel(const char *kernel_filename, + const char *kernel_cmdline, + const char *initrd_filename); +void s390_create_virtio_net(BusState *bus, const char *name); #endif