xref: /openbmc/qemu/hw/s390x/sclp.c (revision 19f70347)
1 /*
2  * SCLP Support
3  *
4  * Copyright IBM, Corp. 2012
5  *
6  * Authors:
7  *  Christian Borntraeger <borntraeger@de.ibm.com>
8  *  Heinz Graalfs <graalfs@linux.vnet.ibm.com>
9  *
10  * This work is licensed under the terms of the GNU GPL, version 2 or (at your
11  * option) any later version.  See the COPYING file in the top-level directory.
12  *
13  */
14 
15 #include "qemu/osdep.h"
16 #include "qemu/units.h"
17 #include "qapi/error.h"
18 #include "cpu.h"
19 #include "sysemu/sysemu.h"
20 #include "hw/boards.h"
21 #include "hw/s390x/sclp.h"
22 #include "hw/s390x/event-facility.h"
23 #include "hw/s390x/s390-pci-bus.h"
24 #include "hw/s390x/ipl.h"
25 
26 static inline SCLPDevice *get_sclp_device(void)
27 {
28     static SCLPDevice *sclp;
29 
30     if (!sclp) {
31         sclp = SCLP(object_resolve_path_type("", TYPE_SCLP, NULL));
32     }
33     return sclp;
34 }
35 
36 static void prepare_cpu_entries(SCLPDevice *sclp, CPUEntry *entry, int *count)
37 {
38     MachineState *ms = MACHINE(qdev_get_machine());
39     uint8_t features[SCCB_CPU_FEATURE_LEN] = { 0 };
40     int i;
41 
42     s390_get_feat_block(S390_FEAT_TYPE_SCLP_CPU, features);
43     for (i = 0, *count = 0; i < ms->possible_cpus->len; i++) {
44         if (!ms->possible_cpus->cpus[i].cpu) {
45             continue;
46         }
47         entry[*count].address = ms->possible_cpus->cpus[i].arch_id;
48         entry[*count].type = 0;
49         memcpy(entry[*count].features, features, sizeof(features));
50         (*count)++;
51     }
52 }
53 
54 /* Provide information about the configuration, CPUs and storage */
55 static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
56 {
57     ReadInfo *read_info = (ReadInfo *) sccb;
58     MachineState *machine = MACHINE(qdev_get_machine());
59     int cpu_count;
60     int rnsize, rnmax;
61     IplParameterBlock *ipib = s390_ipl_get_iplb();
62 
63     /* CPU information */
64     prepare_cpu_entries(sclp, read_info->entries, &cpu_count);
65     read_info->entries_cpu = cpu_to_be16(cpu_count);
66     read_info->offset_cpu = cpu_to_be16(offsetof(ReadInfo, entries));
67     read_info->highest_cpu = cpu_to_be16(machine->smp.max_cpus - 1);
68 
69     read_info->ibc_val = cpu_to_be32(s390_get_ibc_val());
70 
71     if (be16_to_cpu(sccb->h.length) <
72             (sizeof(ReadInfo) + cpu_count * sizeof(CPUEntry))) {
73         sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
74         return;
75     }
76 
77     /* Configuration Characteristic (Extension) */
78     s390_get_feat_block(S390_FEAT_TYPE_SCLP_CONF_CHAR,
79                          read_info->conf_char);
80     s390_get_feat_block(S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT,
81                          read_info->conf_char_ext);
82 
83     read_info->facilities = cpu_to_be64(SCLP_HAS_CPU_INFO |
84                                         SCLP_HAS_IOA_RECONFIG);
85 
86     read_info->mha_pow = s390_get_mha_pow();
87     read_info->hmfai = cpu_to_be32(s390_get_hmfai());
88 
89     rnsize = 1 << (sclp->increment_size - 20);
90     if (rnsize <= 128) {
91         read_info->rnsize = rnsize;
92     } else {
93         read_info->rnsize = 0;
94         read_info->rnsize2 = cpu_to_be32(rnsize);
95     }
96 
97     /* we don't support standby memory, maxram_size is never exposed */
98     rnmax = machine->ram_size >> sclp->increment_size;
99     if (rnmax < 0x10000) {
100         read_info->rnmax = cpu_to_be16(rnmax);
101     } else {
102         read_info->rnmax = cpu_to_be16(0);
103         read_info->rnmax2 = cpu_to_be64(rnmax);
104     }
105 
106     if (ipib && ipib->flags & DIAG308_FLAGS_LP_VALID) {
107         memcpy(&read_info->loadparm, &ipib->loadparm,
108                sizeof(read_info->loadparm));
109     } else {
110         s390_ipl_set_loadparm(read_info->loadparm);
111     }
112 
113     sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_READ_COMPLETION);
114 }
115 
116 /* Provide information about the CPU */
117 static void sclp_read_cpu_info(SCLPDevice *sclp, SCCB *sccb)
118 {
119     ReadCpuInfo *cpu_info = (ReadCpuInfo *) sccb;
120     int cpu_count;
121 
122     prepare_cpu_entries(sclp, cpu_info->entries, &cpu_count);
123     cpu_info->nr_configured = cpu_to_be16(cpu_count);
124     cpu_info->offset_configured = cpu_to_be16(offsetof(ReadCpuInfo, entries));
125     cpu_info->nr_standby = cpu_to_be16(0);
126 
127     if (be16_to_cpu(sccb->h.length) <
128             (sizeof(ReadCpuInfo) + cpu_count * sizeof(CPUEntry))) {
129         sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
130         return;
131     }
132 
133     /* The standby offset is 16-byte for each CPU */
134     cpu_info->offset_standby = cpu_to_be16(cpu_info->offset_configured
135         + cpu_info->nr_configured*sizeof(CPUEntry));
136 
137 
138     sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_READ_COMPLETION);
139 }
140 
141 static void sclp_configure_io_adapter(SCLPDevice *sclp, SCCB *sccb,
142                                       bool configure)
143 {
144     int rc;
145 
146     if (be16_to_cpu(sccb->h.length) < 16) {
147         rc = SCLP_RC_INSUFFICIENT_SCCB_LENGTH;
148         goto out_err;
149     }
150 
151     switch (((IoaCfgSccb *)sccb)->atype) {
152     case SCLP_RECONFIG_PCI_ATYPE:
153         if (s390_has_feat(S390_FEAT_ZPCI)) {
154             if (configure) {
155                 s390_pci_sclp_configure(sccb);
156             } else {
157                 s390_pci_sclp_deconfigure(sccb);
158             }
159             return;
160         }
161         /* fallthrough */
162     default:
163         rc = SCLP_RC_ADAPTER_TYPE_NOT_RECOGNIZED;
164     }
165 
166  out_err:
167     sccb->h.response_code = cpu_to_be16(rc);
168 }
169 
170 static void sclp_execute(SCLPDevice *sclp, SCCB *sccb, uint32_t code)
171 {
172     SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp);
173     SCLPEventFacility *ef = sclp->event_facility;
174     SCLPEventFacilityClass *efc = EVENT_FACILITY_GET_CLASS(ef);
175 
176     switch (code & SCLP_CMD_CODE_MASK) {
177     case SCLP_CMDW_READ_SCP_INFO:
178     case SCLP_CMDW_READ_SCP_INFO_FORCED:
179         sclp_c->read_SCP_info(sclp, sccb);
180         break;
181     case SCLP_CMDW_READ_CPU_INFO:
182         sclp_c->read_cpu_info(sclp, sccb);
183         break;
184     case SCLP_CMDW_CONFIGURE_IOA:
185         sclp_configure_io_adapter(sclp, sccb, true);
186         break;
187     case SCLP_CMDW_DECONFIGURE_IOA:
188         sclp_configure_io_adapter(sclp, sccb, false);
189         break;
190     default:
191         efc->command_handler(ef, sccb, code);
192         break;
193     }
194 }
195 
196 int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t code)
197 {
198     SCLPDevice *sclp = get_sclp_device();
199     SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp);
200     SCCB work_sccb;
201 
202     hwaddr sccb_len = sizeof(SCCB);
203 
204     /* first some basic checks on program checks */
205     if (env->psw.mask & PSW_MASK_PSTATE) {
206         return -PGM_PRIVILEGED;
207     }
208     if (cpu_physical_memory_is_io(sccb)) {
209         return -PGM_ADDRESSING;
210     }
211     if ((sccb & ~0x1fffUL) == 0 || (sccb & ~0x1fffUL) == env->psa
212         || (sccb & ~0x7ffffff8UL) != 0) {
213         return -PGM_SPECIFICATION;
214     }
215 
216     /*
217      * we want to work on a private copy of the sccb, to prevent guests
218      * from playing dirty tricks by modifying the memory content after
219      * the host has checked the values
220      */
221     cpu_physical_memory_read(sccb, &work_sccb, sccb_len);
222 
223     /* Valid sccb sizes */
224     if (be16_to_cpu(work_sccb.h.length) < sizeof(SCCBHeader)) {
225         return -PGM_SPECIFICATION;
226     }
227 
228     switch (code & SCLP_CMD_CODE_MASK) {
229     case SCLP_CMDW_READ_SCP_INFO:
230     case SCLP_CMDW_READ_SCP_INFO_FORCED:
231     case SCLP_CMDW_READ_CPU_INFO:
232     case SCLP_CMDW_CONFIGURE_IOA:
233     case SCLP_CMDW_DECONFIGURE_IOA:
234     case SCLP_CMD_READ_EVENT_DATA:
235     case SCLP_CMD_WRITE_EVENT_DATA:
236     case SCLP_CMD_WRITE_EVENT_MASK:
237         break;
238     default:
239         work_sccb.h.response_code = cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND);
240         goto out_write;
241     }
242 
243     if ((sccb + be16_to_cpu(work_sccb.h.length)) > ((sccb & PAGE_MASK) + PAGE_SIZE)) {
244         work_sccb.h.response_code = cpu_to_be16(SCLP_RC_SCCB_BOUNDARY_VIOLATION);
245         goto out_write;
246     }
247 
248     sclp_c->execute(sclp, &work_sccb, code);
249 out_write:
250     cpu_physical_memory_write(sccb, &work_sccb,
251                               be16_to_cpu(work_sccb.h.length));
252 
253     sclp_c->service_interrupt(sclp, sccb);
254 
255     return 0;
256 }
257 
258 static void service_interrupt(SCLPDevice *sclp, uint32_t sccb)
259 {
260     SCLPEventFacility *ef = sclp->event_facility;
261     SCLPEventFacilityClass *efc = EVENT_FACILITY_GET_CLASS(ef);
262 
263     uint32_t param = sccb & ~3;
264 
265     /* Indicate whether an event is still pending */
266     param |= efc->event_pending(ef) ? 1 : 0;
267 
268     if (!param) {
269         /* No need to send an interrupt, there's nothing to be notified about */
270         return;
271     }
272     s390_sclp_extint(param);
273 }
274 
275 void sclp_service_interrupt(uint32_t sccb)
276 {
277     SCLPDevice *sclp = get_sclp_device();
278     SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp);
279 
280     sclp_c->service_interrupt(sclp, sccb);
281 }
282 
283 /* qemu object creation and initialization functions */
284 
285 void s390_sclp_init(void)
286 {
287     Object *new = object_new(TYPE_SCLP);
288 
289     object_property_add_child(qdev_get_machine(), TYPE_SCLP, new,
290                               NULL);
291     object_unref(OBJECT(new));
292     qdev_init_nofail(DEVICE(new));
293 }
294 
295 static void sclp_realize(DeviceState *dev, Error **errp)
296 {
297     MachineState *machine = MACHINE(qdev_get_machine());
298     SCLPDevice *sclp = SCLP(dev);
299     Error *err = NULL;
300     uint64_t hw_limit;
301     int ret;
302 
303     object_property_set_bool(OBJECT(sclp->event_facility), true, "realized",
304                              &err);
305     if (err) {
306         goto out;
307     }
308     /*
309      * qdev_device_add searches the sysbus for TYPE_SCLP_EVENTS_BUS. As long
310      * as we can't find a fitting bus via the qom tree, we have to add the
311      * event facility to the sysbus, so e.g. a sclp console can be created.
312      */
313     qdev_set_parent_bus(DEVICE(sclp->event_facility), sysbus_get_default());
314 
315     ret = s390_set_memory_limit(machine->maxram_size, &hw_limit);
316     if (ret == -E2BIG) {
317         error_setg(&err, "host supports a maximum of %" PRIu64 " GB",
318                    hw_limit / GiB);
319     } else if (ret) {
320         error_setg(&err, "setting the guest size failed");
321     }
322 
323 out:
324     error_propagate(errp, err);
325 }
326 
327 static void sclp_memory_init(SCLPDevice *sclp)
328 {
329     MachineState *machine = MACHINE(qdev_get_machine());
330     ram_addr_t initial_mem = machine->ram_size;
331     int increment_size = 20;
332 
333     /* The storage increment size is a multiple of 1M and is a power of 2.
334      * The number of storage increments must be MAX_STORAGE_INCREMENTS or fewer.
335      * The variable 'increment_size' is an exponent of 2 that can be
336      * used to calculate the size (in bytes) of an increment. */
337     while ((initial_mem >> increment_size) > MAX_STORAGE_INCREMENTS) {
338         increment_size++;
339     }
340     sclp->increment_size = increment_size;
341 
342     /* The core memory area needs to be aligned with the increment size.
343      * In effect, this can cause the user-specified memory size to be rounded
344      * down to align with the nearest increment boundary. */
345     initial_mem = initial_mem >> increment_size << increment_size;
346 
347     machine->ram_size = initial_mem;
348     machine->maxram_size = initial_mem;
349     /* let's propagate the changed ram size into the global variable. */
350     ram_size = initial_mem;
351 }
352 
353 static void sclp_init(Object *obj)
354 {
355     SCLPDevice *sclp = SCLP(obj);
356     Object *new;
357 
358     new = object_new(TYPE_SCLP_EVENT_FACILITY);
359     object_property_add_child(obj, TYPE_SCLP_EVENT_FACILITY, new, NULL);
360     object_unref(new);
361     sclp->event_facility = EVENT_FACILITY(new);
362 
363     sclp_memory_init(sclp);
364 }
365 
366 static void sclp_class_init(ObjectClass *oc, void *data)
367 {
368     SCLPDeviceClass *sc = SCLP_CLASS(oc);
369     DeviceClass *dc = DEVICE_CLASS(oc);
370 
371     dc->desc = "SCLP (Service-Call Logical Processor)";
372     dc->realize = sclp_realize;
373     dc->hotpluggable = false;
374     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
375     /*
376      * Reason: Creates TYPE_SCLP_EVENT_FACILITY in sclp_init
377      * which is a non-pluggable sysbus device
378      */
379     dc->user_creatable = false;
380 
381     sc->read_SCP_info = read_SCP_info;
382     sc->read_cpu_info = sclp_read_cpu_info;
383     sc->execute = sclp_execute;
384     sc->service_interrupt = service_interrupt;
385 }
386 
387 static TypeInfo sclp_info = {
388     .name = TYPE_SCLP,
389     .parent = TYPE_DEVICE,
390     .instance_init = sclp_init,
391     .instance_size = sizeof(SCLPDevice),
392     .class_init = sclp_class_init,
393     .class_size = sizeof(SCLPDeviceClass),
394 };
395 
396 static void register_types(void)
397 {
398     type_register_static(&sclp_info);
399 }
400 type_init(register_types);
401