]> Git Repo - qemu.git/blob - hw/s390x/s390-virtio-ccw.c
Merge remote-tracking branch 'remotes/kraxel/tags/pull-usb-20140829-1' into staging
[qemu.git] / hw / s390x / s390-virtio-ccw.c
1 /*
2  * virtio ccw machine
3  *
4  * Copyright 2012 IBM Corp.
5  * Author(s): Cornelia Huck <[email protected]>
6  *
7  * This work is licensed under the terms of the GNU GPL, version 2 or (at
8  * your option) any later version. See the COPYING file in the top-level
9  * directory.
10  */
11
12 #include "hw/boards.h"
13 #include "exec/address-spaces.h"
14 #include "s390-virtio.h"
15 #include "hw/s390x/sclp.h"
16 #include "hw/s390x/s390_flic.h"
17 #include "ioinst.h"
18 #include "css.h"
19 #include "virtio-ccw.h"
20
21 #define TYPE_S390_CCW_MACHINE               "s390-ccw-machine"
22
23 void io_subsystem_reset(void)
24 {
25     DeviceState *css, *sclp, *flic;
26
27     css = DEVICE(object_resolve_path_type("", "virtual-css-bridge", NULL));
28     if (css) {
29         qdev_reset_all(css);
30     }
31     sclp = DEVICE(object_resolve_path_type("",
32                   "s390-sclp-event-facility", NULL));
33     if (sclp) {
34         qdev_reset_all(sclp);
35     }
36     flic = DEVICE(object_resolve_path_type("", "s390-flic", NULL));
37     if (flic) {
38         qdev_reset_all(flic);
39     }
40 }
41
42 static int virtio_ccw_hcall_notify(const uint64_t *args)
43 {
44     uint64_t subch_id = args[0];
45     uint64_t queue = args[1];
46     SubchDev *sch;
47     int cssid, ssid, schid, m;
48
49     if (ioinst_disassemble_sch_ident(subch_id, &m, &cssid, &ssid, &schid)) {
50         return -EINVAL;
51     }
52     sch = css_find_subch(m, cssid, ssid, schid);
53     if (!sch || !css_subch_visible(sch)) {
54         return -EINVAL;
55     }
56     if (queue >= VIRTIO_PCI_QUEUE_MAX) {
57         return -EINVAL;
58     }
59     virtio_queue_notify(virtio_ccw_get_vdev(sch), queue);
60     return 0;
61
62 }
63
64 static int virtio_ccw_hcall_early_printk(const uint64_t *args)
65 {
66     uint64_t mem = args[0];
67
68     if (mem < ram_size) {
69         /* Early printk */
70         return 0;
71     }
72     return -EINVAL;
73 }
74
75 static void virtio_ccw_register_hcalls(void)
76 {
77     s390_register_virtio_hypercall(KVM_S390_VIRTIO_CCW_NOTIFY,
78                                    virtio_ccw_hcall_notify);
79     /* Tolerate early printk. */
80     s390_register_virtio_hypercall(KVM_S390_VIRTIO_NOTIFY,
81                                    virtio_ccw_hcall_early_printk);
82 }
83
84 static void ccw_init(MachineState *machine)
85 {
86     ram_addr_t my_ram_size = machine->ram_size;
87     MemoryRegion *sysmem = get_system_memory();
88     MemoryRegion *ram = g_new(MemoryRegion, 1);
89     int shift = 0;
90     uint8_t *storage_keys;
91     int ret;
92     VirtualCssBus *css_bus;
93
94     /* s390x ram size detection needs a 16bit multiplier + an increment. So
95        guests > 64GB can be specified in 2MB steps etc. */
96     while ((my_ram_size >> (20 + shift)) > 65535) {
97         shift++;
98     }
99     my_ram_size = my_ram_size >> (20 + shift) << (20 + shift);
100
101     /* let's propagate the changed ram size into the global variable. */
102     ram_size = my_ram_size;
103
104     /* get a BUS */
105     css_bus = virtual_css_bus_init();
106     s390_sclp_init();
107     s390_init_ipl_dev(machine->kernel_filename, machine->kernel_cmdline,
108                       machine->initrd_filename, "s390-ccw.img");
109     s390_flic_init();
110
111     /* register hypercalls */
112     virtio_ccw_register_hcalls();
113
114     /* allocate RAM */
115     memory_region_init_ram(ram, NULL, "s390.ram", my_ram_size);
116     vmstate_register_ram_global(ram);
117     memory_region_add_subregion(sysmem, 0, ram);
118
119     /* allocate storage keys */
120     storage_keys = g_malloc0(my_ram_size / TARGET_PAGE_SIZE);
121
122     /* init CPUs */
123     s390_init_cpus(machine->cpu_model, storage_keys);
124
125     if (kvm_enabled()) {
126         kvm_s390_enable_css_support(s390_cpu_addr2state(0));
127     }
128     /*
129      * Create virtual css and set it as default so that non mcss-e
130      * enabled guests only see virtio devices.
131      */
132     ret = css_create_css_image(VIRTUAL_CSSID, true);
133     assert(ret == 0);
134
135     /* Create VirtIO network adapters */
136     s390_create_virtio_net(BUS(css_bus), "virtio-net-ccw");
137 }
138
139 static void ccw_machine_class_init(ObjectClass *oc, void *data)
140 {
141     MachineClass *mc = MACHINE_CLASS(oc);
142     NMIClass *nc = NMI_CLASS(oc);
143
144     mc->name = "s390-ccw-virtio";
145     mc->alias = "s390-ccw";
146     mc->desc = "VirtIO-ccw based S390 machine";
147     mc->init = ccw_init;
148     mc->block_default_type = IF_VIRTIO;
149     mc->no_cdrom = 1;
150     mc->no_floppy = 1;
151     mc->no_serial = 1;
152     mc->no_parallel = 1;
153     mc->no_sdcard = 1;
154     mc->use_sclp = 1,
155     mc->max_cpus = 255;
156     nc->nmi_monitor_handler = s390_nmi;
157 }
158
159 static const TypeInfo ccw_machine_info = {
160     .name          = TYPE_S390_CCW_MACHINE,
161     .parent        = TYPE_MACHINE,
162     .class_init    = ccw_machine_class_init,
163     .interfaces = (InterfaceInfo[]) {
164         { TYPE_NMI },
165         { }
166     },
167 };
168
169 static void ccw_machine_register_types(void)
170 {
171     type_register_static(&ccw_machine_info);
172 }
173
174 type_init(ccw_machine_register_types)
This page took 0.035001 seconds and 4 git commands to generate.