Change requested in launchpad bug #1288352
[packages/centos6/qemu.git] / 0010-target-s390x-rename-op_helper.c-to-misc_helper.c.patch
1 From 56018228deac6e704a7ec8befd9e9dc69f2fe73f Mon Sep 17 00:00:00 2001
2 From: Blue Swirl <blauwirbel@gmail.com>
3 Date: Sun, 2 Sep 2012 07:33:35 +0000
4 Subject: [PATCH] target-s390x: rename op_helper.c to misc_helper.c
5
6 Now op_helper.c contains miscellaneous helpers, rename
7 it to misc_helper.c.
8
9 Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
10 [agraf: fix conflict]
11 Signed-off-by: Alexander Graf <agraf@suse.de>
12
13 Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
14 ---
15  target-s390x/Makefile.objs |   6 +-
16  target-s390x/cpu.h         |   2 +-
17  target-s390x/misc_helper.c | 428 +++++++++++++++++++++++++++++++++++++++++++++
18  target-s390x/op_helper.c   | 428 ---------------------------------------------
19  4 files changed, 432 insertions(+), 432 deletions(-)
20  create mode 100644 target-s390x/misc_helper.c
21  delete mode 100644 target-s390x/op_helper.c
22
23 diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
24 index b9b3061..a87d26f 100644
25 --- a/target-s390x/Makefile.objs
26 +++ b/target-s390x/Makefile.objs
27 @@ -1,10 +1,10 @@
28 -obj-y += translate.o op_helper.o helper.o cpu.o interrupt.o
29 -obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o
30 +obj-y += translate.o helper.o cpu.o interrupt.o
31 +obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o misc_helper.o
32  obj-$(CONFIG_SOFTMMU) += machine.o
33  obj-$(CONFIG_KVM) += kvm.o
34  
35 -$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
36  $(obj)/int_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
37  $(obj)/fpu_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
38  $(obj)/cc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
39  $(obj)/mem_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
40 +$(obj)/misc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
41 diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
42 index 97fde5e..0ccb551 100644
43 --- a/target-s390x/cpu.h
44 +++ b/target-s390x/cpu.h
45 @@ -1005,7 +1005,7 @@ uint32_t set_cc_f64(float64 v1, float64 v2);
46  uint32_t set_cc_nz_f32(float32 v);
47  uint32_t set_cc_nz_f64(float64 v);
48  
49 -/* op_helper.c */
50 +/* misc_helper.c */
51  void program_interrupt(CPUS390XState *env, uint32_t code, int ilc);
52  
53  #endif
54 diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c
55 new file mode 100644
56 index 0000000..1d5137f
57 --- /dev/null
58 +++ b/target-s390x/misc_helper.c
59 @@ -0,0 +1,428 @@
60 +/*
61 + *  S/390 misc helper routines
62 + *
63 + *  Copyright (c) 2009 Ulrich Hecht
64 + *  Copyright (c) 2009 Alexander Graf
65 + *
66 + * This library is free software; you can redistribute it and/or
67 + * modify it under the terms of the GNU Lesser General Public
68 + * License as published by the Free Software Foundation; either
69 + * version 2 of the License, or (at your option) any later version.
70 + *
71 + * This library is distributed in the hope that it will be useful,
72 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
73 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
74 + * Lesser General Public License for more details.
75 + *
76 + * You should have received a copy of the GNU Lesser General Public
77 + * License along with this library; if not, see <http://www.gnu.org/licenses/>.
78 + */
79 +
80 +#include "cpu.h"
81 +#include "memory.h"
82 +#include "cputlb.h"
83 +#include "dyngen-exec.h"
84 +#include "host-utils.h"
85 +#include "helper.h"
86 +#include <string.h>
87 +#include "kvm.h"
88 +#include "qemu-timer.h"
89 +#ifdef CONFIG_KVM
90 +#include <linux/kvm.h>
91 +#endif
92 +
93 +#if !defined(CONFIG_USER_ONLY)
94 +#include "softmmu_exec.h"
95 +#include "sysemu.h"
96 +#endif
97 +
98 +/* #define DEBUG_HELPER */
99 +#ifdef DEBUG_HELPER
100 +#define HELPER_LOG(x...) qemu_log(x)
101 +#else
102 +#define HELPER_LOG(x...)
103 +#endif
104 +
105 +/* raise an exception */
106 +void HELPER(exception)(uint32_t excp)
107 +{
108 +    HELPER_LOG("%s: exception %d\n", __func__, excp);
109 +    env->exception_index = excp;
110 +    cpu_loop_exit(env);
111 +}
112 +
113 +#ifndef CONFIG_USER_ONLY
114 +void program_interrupt(CPUS390XState *env, uint32_t code, int ilc)
115 +{
116 +    qemu_log("program interrupt at %#" PRIx64 "\n", env->psw.addr);
117 +
118 +    if (kvm_enabled()) {
119 +#ifdef CONFIG_KVM
120 +        kvm_s390_interrupt(env, KVM_S390_PROGRAM_INT, code);
121 +#endif
122 +    } else {
123 +        env->int_pgm_code = code;
124 +        env->int_pgm_ilc = ilc;
125 +        env->exception_index = EXCP_PGM;
126 +        cpu_loop_exit(env);
127 +    }
128 +}
129 +
130 +/*
131 + * ret < 0 indicates program check, ret = 0, 1, 2, 3 -> cc
132 + */
133 +int sclp_service_call(CPUS390XState *env, uint32_t sccb, uint64_t code)
134 +{
135 +    int r = 0;
136 +    int shift = 0;
137 +
138 +#ifdef DEBUG_HELPER
139 +    printf("sclp(0x%x, 0x%" PRIx64 ")\n", sccb, code);
140 +#endif
141 +
142 +    /* basic checks */
143 +    if (!memory_region_is_ram(phys_page_find(sccb >> TARGET_PAGE_BITS)->mr)) {
144 +        return -PGM_ADDRESSING;
145 +    }
146 +    if (sccb & ~0x7ffffff8ul) {
147 +        return -PGM_SPECIFICATION;
148 +    }
149 +
150 +    switch (code) {
151 +    case SCLP_CMDW_READ_SCP_INFO:
152 +    case SCLP_CMDW_READ_SCP_INFO_FORCED:
153 +        while ((ram_size >> (20 + shift)) > 65535) {
154 +            shift++;
155 +        }
156 +        stw_phys(sccb + SCP_MEM_CODE, ram_size >> (20 + shift));
157 +        stb_phys(sccb + SCP_INCREMENT, 1 << shift);
158 +        stw_phys(sccb + SCP_RESPONSE_CODE, 0x10);
159 +
160 +        s390_sclp_extint(sccb & ~3);
161 +        break;
162 +    default:
163 +#ifdef DEBUG_HELPER
164 +        printf("KVM: invalid sclp call 0x%x / 0x%" PRIx64 "x\n", sccb, code);
165 +#endif
166 +        r = 3;
167 +        break;
168 +    }
169 +
170 +    return r;
171 +}
172 +
173 +/* SCLP service call */
174 +uint32_t HELPER(servc)(uint32_t r1, uint64_t r2)
175 +{
176 +    int r;
177 +
178 +    r = sclp_service_call(env, r1, r2);
179 +    if (r < 0) {
180 +        program_interrupt(env, -r, 4);
181 +        return 0;
182 +    }
183 +    return r;
184 +}
185 +
186 +/* DIAG */
187 +uint64_t HELPER(diag)(uint32_t num, uint64_t mem, uint64_t code)
188 +{
189 +    uint64_t r;
190 +
191 +    switch (num) {
192 +    case 0x500:
193 +        /* KVM hypercall */
194 +        r = s390_virtio_hypercall(env, mem, code);
195 +        break;
196 +    case 0x44:
197 +        /* yield */
198 +        r = 0;
199 +        break;
200 +    case 0x308:
201 +        /* ipl */
202 +        r = 0;
203 +        break;
204 +    default:
205 +        r = -1;
206 +        break;
207 +    }
208 +
209 +    if (r) {
210 +        program_interrupt(env, PGM_OPERATION, ILC_LATER_INC);
211 +    }
212 +
213 +    return r;
214 +}
215 +
216 +/* Store CPU ID */
217 +void HELPER(stidp)(uint64_t a1)
218 +{
219 +    stq(a1, env->cpu_num);
220 +}
221 +
222 +/* Set Prefix */
223 +void HELPER(spx)(uint64_t a1)
224 +{
225 +    uint32_t prefix;
226 +
227 +    prefix = ldl(a1);
228 +    env->psa = prefix & 0xfffff000;
229 +    qemu_log("prefix: %#x\n", prefix);
230 +    tlb_flush_page(env, 0);
231 +    tlb_flush_page(env, TARGET_PAGE_SIZE);
232 +}
233 +
234 +/* Set Clock */
235 +uint32_t HELPER(sck)(uint64_t a1)
236 +{
237 +    /* XXX not implemented - is it necessary? */
238 +
239 +    return 0;
240 +}
241 +
242 +static inline uint64_t clock_value(CPUS390XState *env)
243 +{
244 +    uint64_t time;
245 +
246 +    time = env->tod_offset +
247 +        time2tod(qemu_get_clock_ns(vm_clock) - env->tod_basetime);
248 +
249 +    return time;
250 +}
251 +
252 +/* Store Clock */
253 +uint32_t HELPER(stck)(uint64_t a1)
254 +{
255 +    stq(a1, clock_value(env));
256 +
257 +    return 0;
258 +}
259 +
260 +/* Store Clock Extended */
261 +uint32_t HELPER(stcke)(uint64_t a1)
262 +{
263 +    stb(a1, 0);
264 +    /* basically the same value as stck */
265 +    stq(a1 + 1, clock_value(env) | env->cpu_num);
266 +    /* more fine grained than stck */
267 +    stq(a1 + 9, 0);
268 +    /* XXX programmable fields */
269 +    stw(a1 + 17, 0);
270 +
271 +    return 0;
272 +}
273 +
274 +/* Set Clock Comparator */
275 +void HELPER(sckc)(uint64_t a1)
276 +{
277 +    uint64_t time = ldq(a1);
278 +
279 +    if (time == -1ULL) {
280 +        return;
281 +    }
282 +
283 +    /* difference between now and then */
284 +    time -= clock_value(env);
285 +    /* nanoseconds */
286 +    time = (time * 125) >> 9;
287 +
288 +    qemu_mod_timer(env->tod_timer, qemu_get_clock_ns(vm_clock) + time);
289 +}
290 +
291 +/* Store Clock Comparator */
292 +void HELPER(stckc)(uint64_t a1)
293 +{
294 +    /* XXX implement */
295 +    stq(a1, 0);
296 +}
297 +
298 +/* Set CPU Timer */
299 +void HELPER(spt)(uint64_t a1)
300 +{
301 +    uint64_t time = ldq(a1);
302 +
303 +    if (time == -1ULL) {
304 +        return;
305 +    }
306 +
307 +    /* nanoseconds */
308 +    time = (time * 125) >> 9;
309 +
310 +    qemu_mod_timer(env->cpu_timer, qemu_get_clock_ns(vm_clock) + time);
311 +}
312 +
313 +/* Store CPU Timer */
314 +void HELPER(stpt)(uint64_t a1)
315 +{
316 +    /* XXX implement */
317 +    stq(a1, 0);
318 +}
319 +
320 +/* Store System Information */
321 +uint32_t HELPER(stsi)(uint64_t a0, uint32_t r0, uint32_t r1)
322 +{
323 +    int cc = 0;
324 +    int sel1, sel2;
325 +
326 +    if ((r0 & STSI_LEVEL_MASK) <= STSI_LEVEL_3 &&
327 +        ((r0 & STSI_R0_RESERVED_MASK) || (r1 & STSI_R1_RESERVED_MASK))) {
328 +        /* valid function code, invalid reserved bits */
329 +        program_interrupt(env, PGM_SPECIFICATION, 2);
330 +    }
331 +
332 +    sel1 = r0 & STSI_R0_SEL1_MASK;
333 +    sel2 = r1 & STSI_R1_SEL2_MASK;
334 +
335 +    /* XXX: spec exception if sysib is not 4k-aligned */
336 +
337 +    switch (r0 & STSI_LEVEL_MASK) {
338 +    case STSI_LEVEL_1:
339 +        if ((sel1 == 1) && (sel2 == 1)) {
340 +            /* Basic Machine Configuration */
341 +            struct sysib_111 sysib;
342 +
343 +            memset(&sysib, 0, sizeof(sysib));
344 +            ebcdic_put(sysib.manuf, "QEMU            ", 16);
345 +            /* same as machine type number in STORE CPU ID */
346 +            ebcdic_put(sysib.type, "QEMU", 4);
347 +            /* same as model number in STORE CPU ID */
348 +            ebcdic_put(sysib.model, "QEMU            ", 16);
349 +            ebcdic_put(sysib.sequence, "QEMU            ", 16);
350 +            ebcdic_put(sysib.plant, "QEMU", 4);
351 +            cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
352 +        } else if ((sel1 == 2) && (sel2 == 1)) {
353 +            /* Basic Machine CPU */
354 +            struct sysib_121 sysib;
355 +
356 +            memset(&sysib, 0, sizeof(sysib));
357 +            /* XXX make different for different CPUs? */
358 +            ebcdic_put(sysib.sequence, "QEMUQEMUQEMUQEMU", 16);
359 +            ebcdic_put(sysib.plant, "QEMU", 4);
360 +            stw_p(&sysib.cpu_addr, env->cpu_num);
361 +            cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
362 +        } else if ((sel1 == 2) && (sel2 == 2)) {
363 +            /* Basic Machine CPUs */
364 +            struct sysib_122 sysib;
365 +
366 +            memset(&sysib, 0, sizeof(sysib));
367 +            stl_p(&sysib.capability, 0x443afc29);
368 +            /* XXX change when SMP comes */
369 +            stw_p(&sysib.total_cpus, 1);
370 +            stw_p(&sysib.active_cpus, 1);
371 +            stw_p(&sysib.standby_cpus, 0);
372 +            stw_p(&sysib.reserved_cpus, 0);
373 +            cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
374 +        } else {
375 +            cc = 3;
376 +        }
377 +        break;
378 +    case STSI_LEVEL_2:
379 +        {
380 +            if ((sel1 == 2) && (sel2 == 1)) {
381 +                /* LPAR CPU */
382 +                struct sysib_221 sysib;
383 +
384 +                memset(&sysib, 0, sizeof(sysib));
385 +                /* XXX make different for different CPUs? */
386 +                ebcdic_put(sysib.sequence, "QEMUQEMUQEMUQEMU", 16);
387 +                ebcdic_put(sysib.plant, "QEMU", 4);
388 +                stw_p(&sysib.cpu_addr, env->cpu_num);
389 +                stw_p(&sysib.cpu_id, 0);
390 +                cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
391 +            } else if ((sel1 == 2) && (sel2 == 2)) {
392 +                /* LPAR CPUs */
393 +                struct sysib_222 sysib;
394 +
395 +                memset(&sysib, 0, sizeof(sysib));
396 +                stw_p(&sysib.lpar_num, 0);
397 +                sysib.lcpuc = 0;
398 +                /* XXX change when SMP comes */
399 +                stw_p(&sysib.total_cpus, 1);
400 +                stw_p(&sysib.conf_cpus, 1);
401 +                stw_p(&sysib.standby_cpus, 0);
402 +                stw_p(&sysib.reserved_cpus, 0);
403 +                ebcdic_put(sysib.name, "QEMU    ", 8);
404 +                stl_p(&sysib.caf, 1000);
405 +                stw_p(&sysib.dedicated_cpus, 0);
406 +                stw_p(&sysib.shared_cpus, 0);
407 +                cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
408 +            } else {
409 +                cc = 3;
410 +            }
411 +            break;
412 +        }
413 +    case STSI_LEVEL_3:
414 +        {
415 +            if ((sel1 == 2) && (sel2 == 2)) {
416 +                /* VM CPUs */
417 +                struct sysib_322 sysib;
418 +
419 +                memset(&sysib, 0, sizeof(sysib));
420 +                sysib.count = 1;
421 +                /* XXX change when SMP comes */
422 +                stw_p(&sysib.vm[0].total_cpus, 1);
423 +                stw_p(&sysib.vm[0].conf_cpus, 1);
424 +                stw_p(&sysib.vm[0].standby_cpus, 0);
425 +                stw_p(&sysib.vm[0].reserved_cpus, 0);
426 +                ebcdic_put(sysib.vm[0].name, "KVMguest", 8);
427 +                stl_p(&sysib.vm[0].caf, 1000);
428 +                ebcdic_put(sysib.vm[0].cpi, "KVM/Linux       ", 16);
429 +                cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
430 +            } else {
431 +                cc = 3;
432 +            }
433 +            break;
434 +        }
435 +    case STSI_LEVEL_CURRENT:
436 +        env->regs[0] = STSI_LEVEL_3;
437 +        break;
438 +    default:
439 +        cc = 3;
440 +        break;
441 +    }
442 +
443 +    return cc;
444 +}
445 +
446 +uint32_t HELPER(sigp)(uint64_t order_code, uint32_t r1, uint64_t cpu_addr)
447 +{
448 +    int cc = 0;
449 +
450 +    HELPER_LOG("%s: %016" PRIx64 " %08x %016" PRIx64 "\n",
451 +               __func__, order_code, r1, cpu_addr);
452 +
453 +    /* Remember: Use "R1 or R1 + 1, whichever is the odd-numbered register"
454 +       as parameter (input). Status (output) is always R1. */
455 +
456 +    switch (order_code) {
457 +    case SIGP_SET_ARCH:
458 +        /* switch arch */
459 +        break;
460 +    case SIGP_SENSE:
461 +        /* enumerate CPU status */
462 +        if (cpu_addr) {
463 +            /* XXX implement when SMP comes */
464 +            return 3;
465 +        }
466 +        env->regs[r1] &= 0xffffffff00000000ULL;
467 +        cc = 1;
468 +        break;
469 +#if !defined(CONFIG_USER_ONLY)
470 +    case SIGP_RESTART:
471 +        qemu_system_reset_request();
472 +        cpu_loop_exit(env);
473 +        break;
474 +    case SIGP_STOP:
475 +        qemu_system_shutdown_request();
476 +        cpu_loop_exit(env);
477 +        break;
478 +#endif
479 +    default:
480 +        /* unknown sigp */
481 +        fprintf(stderr, "XXX unknown sigp: 0x%" PRIx64 "\n", order_code);
482 +        cc = 3;
483 +    }
484 +
485 +    return cc;
486 +}
487 +#endif
488 diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c
489 deleted file mode 100644
490 index bb8dbf5..0000000
491 --- a/target-s390x/op_helper.c
492 +++ /dev/null
493 @@ -1,428 +0,0 @@
494 -/*
495 - *  S/390 helper routines
496 - *
497 - *  Copyright (c) 2009 Ulrich Hecht
498 - *  Copyright (c) 2009 Alexander Graf
499 - *
500 - * This library is free software; you can redistribute it and/or
501 - * modify it under the terms of the GNU Lesser General Public
502 - * License as published by the Free Software Foundation; either
503 - * version 2 of the License, or (at your option) any later version.
504 - *
505 - * This library is distributed in the hope that it will be useful,
506 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
507 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
508 - * Lesser General Public License for more details.
509 - *
510 - * You should have received a copy of the GNU Lesser General Public
511 - * License along with this library; if not, see <http://www.gnu.org/licenses/>.
512 - */
513 -
514 -#include "cpu.h"
515 -#include "memory.h"
516 -#include "cputlb.h"
517 -#include "dyngen-exec.h"
518 -#include "host-utils.h"
519 -#include "helper.h"
520 -#include <string.h>
521 -#include "kvm.h"
522 -#include "qemu-timer.h"
523 -#ifdef CONFIG_KVM
524 -#include <linux/kvm.h>
525 -#endif
526 -
527 -#if !defined(CONFIG_USER_ONLY)
528 -#include "softmmu_exec.h"
529 -#include "sysemu.h"
530 -#endif
531 -
532 -/* #define DEBUG_HELPER */
533 -#ifdef DEBUG_HELPER
534 -#define HELPER_LOG(x...) qemu_log(x)
535 -#else
536 -#define HELPER_LOG(x...)
537 -#endif
538 -
539 -/* raise an exception */
540 -void HELPER(exception)(uint32_t excp)
541 -{
542 -    HELPER_LOG("%s: exception %d\n", __func__, excp);
543 -    env->exception_index = excp;
544 -    cpu_loop_exit(env);
545 -}
546 -
547 -#ifndef CONFIG_USER_ONLY
548 -void program_interrupt(CPUS390XState *env, uint32_t code, int ilc)
549 -{
550 -    qemu_log("program interrupt at %#" PRIx64 "\n", env->psw.addr);
551 -
552 -    if (kvm_enabled()) {
553 -#ifdef CONFIG_KVM
554 -        kvm_s390_interrupt(env, KVM_S390_PROGRAM_INT, code);
555 -#endif
556 -    } else {
557 -        env->int_pgm_code = code;
558 -        env->int_pgm_ilc = ilc;
559 -        env->exception_index = EXCP_PGM;
560 -        cpu_loop_exit(env);
561 -    }
562 -}
563 -
564 -/*
565 - * ret < 0 indicates program check, ret = 0, 1, 2, 3 -> cc
566 - */
567 -int sclp_service_call(CPUS390XState *env, uint32_t sccb, uint64_t code)
568 -{
569 -    int r = 0;
570 -    int shift = 0;
571 -
572 -#ifdef DEBUG_HELPER
573 -    printf("sclp(0x%x, 0x%" PRIx64 ")\n", sccb, code);
574 -#endif
575 -
576 -    /* basic checks */
577 -    if (!memory_region_is_ram(phys_page_find(sccb >> TARGET_PAGE_BITS)->mr)) {
578 -        return -PGM_ADDRESSING;
579 -    }
580 -    if (sccb & ~0x7ffffff8ul) {
581 -        return -PGM_SPECIFICATION;
582 -    }
583 -
584 -    switch (code) {
585 -    case SCLP_CMDW_READ_SCP_INFO:
586 -    case SCLP_CMDW_READ_SCP_INFO_FORCED:
587 -        while ((ram_size >> (20 + shift)) > 65535) {
588 -            shift++;
589 -        }
590 -        stw_phys(sccb + SCP_MEM_CODE, ram_size >> (20 + shift));
591 -        stb_phys(sccb + SCP_INCREMENT, 1 << shift);
592 -        stw_phys(sccb + SCP_RESPONSE_CODE, 0x10);
593 -
594 -        s390_sclp_extint(sccb & ~3);
595 -        break;
596 -    default:
597 -#ifdef DEBUG_HELPER
598 -        printf("KVM: invalid sclp call 0x%x / 0x%" PRIx64 "x\n", sccb, code);
599 -#endif
600 -        r = 3;
601 -        break;
602 -    }
603 -
604 -    return r;
605 -}
606 -
607 -/* SCLP service call */
608 -uint32_t HELPER(servc)(uint32_t r1, uint64_t r2)
609 -{
610 -    int r;
611 -
612 -    r = sclp_service_call(env, r1, r2);
613 -    if (r < 0) {
614 -        program_interrupt(env, -r, 4);
615 -        return 0;
616 -    }
617 -    return r;
618 -}
619 -
620 -/* DIAG */
621 -uint64_t HELPER(diag)(uint32_t num, uint64_t mem, uint64_t code)
622 -{
623 -    uint64_t r;
624 -
625 -    switch (num) {
626 -    case 0x500:
627 -        /* KVM hypercall */
628 -        r = s390_virtio_hypercall(env, mem, code);
629 -        break;
630 -    case 0x44:
631 -        /* yield */
632 -        r = 0;
633 -        break;
634 -    case 0x308:
635 -        /* ipl */
636 -        r = 0;
637 -        break;
638 -    default:
639 -        r = -1;
640 -        break;
641 -    }
642 -
643 -    if (r) {
644 -        program_interrupt(env, PGM_OPERATION, ILC_LATER_INC);
645 -    }
646 -
647 -    return r;
648 -}
649 -
650 -/* Store CPU ID */
651 -void HELPER(stidp)(uint64_t a1)
652 -{
653 -    stq(a1, env->cpu_num);
654 -}
655 -
656 -/* Set Prefix */
657 -void HELPER(spx)(uint64_t a1)
658 -{
659 -    uint32_t prefix;
660 -
661 -    prefix = ldl(a1);
662 -    env->psa = prefix & 0xfffff000;
663 -    qemu_log("prefix: %#x\n", prefix);
664 -    tlb_flush_page(env, 0);
665 -    tlb_flush_page(env, TARGET_PAGE_SIZE);
666 -}
667 -
668 -/* Set Clock */
669 -uint32_t HELPER(sck)(uint64_t a1)
670 -{
671 -    /* XXX not implemented - is it necessary? */
672 -
673 -    return 0;
674 -}
675 -
676 -static inline uint64_t clock_value(CPUS390XState *env)
677 -{
678 -    uint64_t time;
679 -
680 -    time = env->tod_offset +
681 -        time2tod(qemu_get_clock_ns(vm_clock) - env->tod_basetime);
682 -
683 -    return time;
684 -}
685 -
686 -/* Store Clock */
687 -uint32_t HELPER(stck)(uint64_t a1)
688 -{
689 -    stq(a1, clock_value(env));
690 -
691 -    return 0;
692 -}
693 -
694 -/* Store Clock Extended */
695 -uint32_t HELPER(stcke)(uint64_t a1)
696 -{
697 -    stb(a1, 0);
698 -    /* basically the same value as stck */
699 -    stq(a1 + 1, clock_value(env) | env->cpu_num);
700 -    /* more fine grained than stck */
701 -    stq(a1 + 9, 0);
702 -    /* XXX programmable fields */
703 -    stw(a1 + 17, 0);
704 -
705 -    return 0;
706 -}
707 -
708 -/* Set Clock Comparator */
709 -void HELPER(sckc)(uint64_t a1)
710 -{
711 -    uint64_t time = ldq(a1);
712 -
713 -    if (time == -1ULL) {
714 -        return;
715 -    }
716 -
717 -    /* difference between now and then */
718 -    time -= clock_value(env);
719 -    /* nanoseconds */
720 -    time = (time * 125) >> 9;
721 -
722 -    qemu_mod_timer(env->tod_timer, qemu_get_clock_ns(vm_clock) + time);
723 -}
724 -
725 -/* Store Clock Comparator */
726 -void HELPER(stckc)(uint64_t a1)
727 -{
728 -    /* XXX implement */
729 -    stq(a1, 0);
730 -}
731 -
732 -/* Set CPU Timer */
733 -void HELPER(spt)(uint64_t a1)
734 -{
735 -    uint64_t time = ldq(a1);
736 -
737 -    if (time == -1ULL) {
738 -        return;
739 -    }
740 -
741 -    /* nanoseconds */
742 -    time = (time * 125) >> 9;
743 -
744 -    qemu_mod_timer(env->cpu_timer, qemu_get_clock_ns(vm_clock) + time);
745 -}
746 -
747 -/* Store CPU Timer */
748 -void HELPER(stpt)(uint64_t a1)
749 -{
750 -    /* XXX implement */
751 -    stq(a1, 0);
752 -}
753 -
754 -/* Store System Information */
755 -uint32_t HELPER(stsi)(uint64_t a0, uint32_t r0, uint32_t r1)
756 -{
757 -    int cc = 0;
758 -    int sel1, sel2;
759 -
760 -    if ((r0 & STSI_LEVEL_MASK) <= STSI_LEVEL_3 &&
761 -        ((r0 & STSI_R0_RESERVED_MASK) || (r1 & STSI_R1_RESERVED_MASK))) {
762 -        /* valid function code, invalid reserved bits */
763 -        program_interrupt(env, PGM_SPECIFICATION, 2);
764 -    }
765 -
766 -    sel1 = r0 & STSI_R0_SEL1_MASK;
767 -    sel2 = r1 & STSI_R1_SEL2_MASK;
768 -
769 -    /* XXX: spec exception if sysib is not 4k-aligned */
770 -
771 -    switch (r0 & STSI_LEVEL_MASK) {
772 -    case STSI_LEVEL_1:
773 -        if ((sel1 == 1) && (sel2 == 1)) {
774 -            /* Basic Machine Configuration */
775 -            struct sysib_111 sysib;
776 -
777 -            memset(&sysib, 0, sizeof(sysib));
778 -            ebcdic_put(sysib.manuf, "QEMU            ", 16);
779 -            /* same as machine type number in STORE CPU ID */
780 -            ebcdic_put(sysib.type, "QEMU", 4);
781 -            /* same as model number in STORE CPU ID */
782 -            ebcdic_put(sysib.model, "QEMU            ", 16);
783 -            ebcdic_put(sysib.sequence, "QEMU            ", 16);
784 -            ebcdic_put(sysib.plant, "QEMU", 4);
785 -            cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
786 -        } else if ((sel1 == 2) && (sel2 == 1)) {
787 -            /* Basic Machine CPU */
788 -            struct sysib_121 sysib;
789 -
790 -            memset(&sysib, 0, sizeof(sysib));
791 -            /* XXX make different for different CPUs? */
792 -            ebcdic_put(sysib.sequence, "QEMUQEMUQEMUQEMU", 16);
793 -            ebcdic_put(sysib.plant, "QEMU", 4);
794 -            stw_p(&sysib.cpu_addr, env->cpu_num);
795 -            cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
796 -        } else if ((sel1 == 2) && (sel2 == 2)) {
797 -            /* Basic Machine CPUs */
798 -            struct sysib_122 sysib;
799 -
800 -            memset(&sysib, 0, sizeof(sysib));
801 -            stl_p(&sysib.capability, 0x443afc29);
802 -            /* XXX change when SMP comes */
803 -            stw_p(&sysib.total_cpus, 1);
804 -            stw_p(&sysib.active_cpus, 1);
805 -            stw_p(&sysib.standby_cpus, 0);
806 -            stw_p(&sysib.reserved_cpus, 0);
807 -            cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
808 -        } else {
809 -            cc = 3;
810 -        }
811 -        break;
812 -    case STSI_LEVEL_2:
813 -        {
814 -            if ((sel1 == 2) && (sel2 == 1)) {
815 -                /* LPAR CPU */
816 -                struct sysib_221 sysib;
817 -
818 -                memset(&sysib, 0, sizeof(sysib));
819 -                /* XXX make different for different CPUs? */
820 -                ebcdic_put(sysib.sequence, "QEMUQEMUQEMUQEMU", 16);
821 -                ebcdic_put(sysib.plant, "QEMU", 4);
822 -                stw_p(&sysib.cpu_addr, env->cpu_num);
823 -                stw_p(&sysib.cpu_id, 0);
824 -                cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
825 -            } else if ((sel1 == 2) && (sel2 == 2)) {
826 -                /* LPAR CPUs */
827 -                struct sysib_222 sysib;
828 -
829 -                memset(&sysib, 0, sizeof(sysib));
830 -                stw_p(&sysib.lpar_num, 0);
831 -                sysib.lcpuc = 0;
832 -                /* XXX change when SMP comes */
833 -                stw_p(&sysib.total_cpus, 1);
834 -                stw_p(&sysib.conf_cpus, 1);
835 -                stw_p(&sysib.standby_cpus, 0);
836 -                stw_p(&sysib.reserved_cpus, 0);
837 -                ebcdic_put(sysib.name, "QEMU    ", 8);
838 -                stl_p(&sysib.caf, 1000);
839 -                stw_p(&sysib.dedicated_cpus, 0);
840 -                stw_p(&sysib.shared_cpus, 0);
841 -                cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
842 -            } else {
843 -                cc = 3;
844 -            }
845 -            break;
846 -        }
847 -    case STSI_LEVEL_3:
848 -        {
849 -            if ((sel1 == 2) && (sel2 == 2)) {
850 -                /* VM CPUs */
851 -                struct sysib_322 sysib;
852 -
853 -                memset(&sysib, 0, sizeof(sysib));
854 -                sysib.count = 1;
855 -                /* XXX change when SMP comes */
856 -                stw_p(&sysib.vm[0].total_cpus, 1);
857 -                stw_p(&sysib.vm[0].conf_cpus, 1);
858 -                stw_p(&sysib.vm[0].standby_cpus, 0);
859 -                stw_p(&sysib.vm[0].reserved_cpus, 0);
860 -                ebcdic_put(sysib.vm[0].name, "KVMguest", 8);
861 -                stl_p(&sysib.vm[0].caf, 1000);
862 -                ebcdic_put(sysib.vm[0].cpi, "KVM/Linux       ", 16);
863 -                cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
864 -            } else {
865 -                cc = 3;
866 -            }
867 -            break;
868 -        }
869 -    case STSI_LEVEL_CURRENT:
870 -        env->regs[0] = STSI_LEVEL_3;
871 -        break;
872 -    default:
873 -        cc = 3;
874 -        break;
875 -    }
876 -
877 -    return cc;
878 -}
879 -
880 -uint32_t HELPER(sigp)(uint64_t order_code, uint32_t r1, uint64_t cpu_addr)
881 -{
882 -    int cc = 0;
883 -
884 -    HELPER_LOG("%s: %016" PRIx64 " %08x %016" PRIx64 "\n",
885 -               __func__, order_code, r1, cpu_addr);
886 -
887 -    /* Remember: Use "R1 or R1 + 1, whichever is the odd-numbered register"
888 -       as parameter (input). Status (output) is always R1. */
889 -
890 -    switch (order_code) {
891 -    case SIGP_SET_ARCH:
892 -        /* switch arch */
893 -        break;
894 -    case SIGP_SENSE:
895 -        /* enumerate CPU status */
896 -        if (cpu_addr) {
897 -            /* XXX implement when SMP comes */
898 -            return 3;
899 -        }
900 -        env->regs[r1] &= 0xffffffff00000000ULL;
901 -        cc = 1;
902 -        break;
903 -#if !defined(CONFIG_USER_ONLY)
904 -    case SIGP_RESTART:
905 -        qemu_system_reset_request();
906 -        cpu_loop_exit(env);
907 -        break;
908 -    case SIGP_STOP:
909 -        qemu_system_shutdown_request();
910 -        cpu_loop_exit(env);
911 -        break;
912 -#endif
913 -    default:
914 -        /* unknown sigp */
915 -        fprintf(stderr, "XXX unknown sigp: 0x%" PRIx64 "\n", order_code);
916 -        cc = 3;
917 -    }
918 -
919 -    return cc;
920 -}
921 -#endif
922 -- 
923 1.7.12.1
924