s390/kexec: Implement diag308 subcode 0
[sdk/emulator/qemu.git] / target-s390x / misc_helper.c
1 /*
2  *  S/390 misc helper routines
3  *
4  *  Copyright (c) 2009 Ulrich Hecht
5  *  Copyright (c) 2009 Alexander Graf
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include "cpu.h"
22 #include "exec/memory.h"
23 #include "qemu/host-utils.h"
24 #include "helper.h"
25 #include <string.h>
26 #include "sysemu/kvm.h"
27 #include "qemu/timer.h"
28 #ifdef CONFIG_KVM
29 #include <linux/kvm.h>
30 #endif
31
32 #if !defined(CONFIG_USER_ONLY)
33 #include "exec/softmmu_exec.h"
34 #include "sysemu/cpus.h"
35 #include "sysemu/sysemu.h"
36 #endif
37
38 /* #define DEBUG_HELPER */
39 #ifdef DEBUG_HELPER
40 #define HELPER_LOG(x...) qemu_log(x)
41 #else
42 #define HELPER_LOG(x...)
43 #endif
44
45 /* Raise an exception dynamically from a helper function.  */
46 void QEMU_NORETURN runtime_exception(CPUS390XState *env, int excp,
47                                      uintptr_t retaddr)
48 {
49     int t;
50
51     env->exception_index = EXCP_PGM;
52     env->int_pgm_code = excp;
53
54     /* Use the (ultimate) callers address to find the insn that trapped.  */
55     cpu_restore_state(env, retaddr);
56
57     /* Advance past the insn.  */
58     t = cpu_ldub_code(env, env->psw.addr);
59     env->int_pgm_ilen = t = get_ilen(t);
60     env->psw.addr += 2 * t;
61
62     cpu_loop_exit(env);
63 }
64
65 /* Raise an exception statically from a TB.  */
66 void HELPER(exception)(CPUS390XState *env, uint32_t excp)
67 {
68     HELPER_LOG("%s: exception %d\n", __func__, excp);
69     env->exception_index = excp;
70     cpu_loop_exit(env);
71 }
72
73 #ifndef CONFIG_USER_ONLY
74
75 /* EBCDIC handling */
76 static const uint8_t ebcdic2ascii[] = {
77     0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F,
78     0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
79     0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07,
80     0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
81     0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B,
82     0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07,
83     0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04,
84     0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A,
85     0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86,
86     0x87, 0xA4, 0x5B, 0x2E, 0x3C, 0x28, 0x2B, 0x21,
87     0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07,
88     0x8D, 0xE1, 0x5D, 0x24, 0x2A, 0x29, 0x3B, 0x5E,
89     0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F,
90     0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
91     0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
92     0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
93     0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
94     0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1,
95     0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
96     0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07,
97     0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
98     0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07,
99     0x9B, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC,
100     0xAB, 0x07, 0xAA, 0x7C, 0x07, 0x07, 0x07, 0x07,
101     0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
102     0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07,
103     0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
104     0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98,
105     0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
106     0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07,
107     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
108     0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07,
109 };
110
111 static const uint8_t ascii2ebcdic[] = {
112     0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F,
113     0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
114     0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26,
115     0x18, 0x19, 0x3F, 0x27, 0x22, 0x1D, 0x1E, 0x1F,
116     0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D,
117     0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
118     0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
119     0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
120     0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
121     0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
122     0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
123     0xE7, 0xE8, 0xE9, 0xBA, 0xE0, 0xBB, 0xB0, 0x6D,
124     0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
125     0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
126     0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
127     0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07,
128     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
129     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
130     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
131     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
132     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
133     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
134     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
135     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
136     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
137     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
138     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
139     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
140     0x3F, 0x59, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
141     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
142     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
143     0x90, 0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x3F, 0xFF
144 };
145
146 static inline void ebcdic_put(uint8_t *p, const char *ascii, int len)
147 {
148     int i;
149
150     for (i = 0; i < len; i++) {
151         p[i] = ascii2ebcdic[(uint8_t)ascii[i]];
152     }
153 }
154
155 void program_interrupt(CPUS390XState *env, uint32_t code, int ilen)
156 {
157     qemu_log_mask(CPU_LOG_INT, "program interrupt at %#" PRIx64 "\n",
158                   env->psw.addr);
159
160     if (kvm_enabled()) {
161 #ifdef CONFIG_KVM
162         kvm_s390_interrupt(s390_env_get_cpu(env), KVM_S390_PROGRAM_INT, code);
163 #endif
164     } else {
165         env->int_pgm_code = code;
166         env->int_pgm_ilen = ilen;
167         env->exception_index = EXCP_PGM;
168         cpu_loop_exit(env);
169     }
170 }
171
172 /* SCLP service call */
173 uint32_t HELPER(servc)(CPUS390XState *env, uint64_t r1, uint64_t r2)
174 {
175     int r = sclp_service_call(r1, r2);
176     if (r < 0) {
177         program_interrupt(env, -r, 4);
178         return 0;
179     }
180     return r;
181 }
182
183 #ifndef CONFIG_USER_ONLY
184 static void cpu_reset_all(void)
185 {
186     CPUState *cs;
187     S390CPUClass *scc;
188
189     CPU_FOREACH(cs) {
190         scc = S390_CPU_GET_CLASS(cs);
191         scc->cpu_reset(cs);
192     }
193 }
194
195 static void cpu_full_reset_all(void)
196 {
197     CPUState *cpu;
198
199     CPU_FOREACH(cpu) {
200         cpu_reset(cpu);
201     }
202 }
203
204 static int modified_clear_reset(S390CPU *cpu)
205 {
206     S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
207
208     pause_all_vcpus();
209     cpu_synchronize_all_states();
210     cpu_full_reset_all();
211     io_subsystem_reset();
212     scc->load_normal(CPU(cpu));
213     cpu_synchronize_all_post_reset();
214     resume_all_vcpus();
215     return 0;
216 }
217
218 static int load_normal_reset(S390CPU *cpu)
219 {
220     S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
221
222     pause_all_vcpus();
223     cpu_synchronize_all_states();
224     cpu_reset_all();
225     io_subsystem_reset();
226     scc->initial_cpu_reset(CPU(cpu));
227     scc->load_normal(CPU(cpu));
228     cpu_synchronize_all_post_reset();
229     resume_all_vcpus();
230     return 0;
231 }
232
233 #define DIAG_308_RC_NO_CONF         0x0102
234 #define DIAG_308_RC_INVALID         0x0402
235 void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3)
236 {
237     uint64_t addr =  env->regs[r1];
238     uint64_t subcode = env->regs[r3];
239
240     if (env->psw.mask & PSW_MASK_PSTATE) {
241         program_interrupt(env, PGM_PRIVILEGED, ILEN_LATER_INC);
242         return;
243     }
244
245     if ((subcode & ~0x0ffffULL) || (subcode > 6)) {
246         program_interrupt(env, PGM_SPECIFICATION, ILEN_LATER_INC);
247         return;
248     }
249
250     switch (subcode) {
251     case 0:
252         modified_clear_reset(s390_env_get_cpu(env));
253         break;
254     case 1:
255         load_normal_reset(s390_env_get_cpu(env));
256         break;
257     case 5:
258         if ((r1 & 1) || (addr & 0x0fffULL)) {
259             program_interrupt(env, PGM_SPECIFICATION, ILEN_LATER_INC);
260             return;
261         }
262         env->regs[r1+1] = DIAG_308_RC_INVALID;
263         return;
264     case 6:
265         if ((r1 & 1) || (addr & 0x0fffULL)) {
266             program_interrupt(env, PGM_SPECIFICATION, ILEN_LATER_INC);
267             return;
268         }
269         env->regs[r1+1] = DIAG_308_RC_NO_CONF;
270         return;
271     default:
272         hw_error("Unhandled diag308 subcode %" PRIx64, subcode);
273         break;
274     }
275 }
276 #endif
277
278 /* DIAG */
279 uint64_t HELPER(diag)(CPUS390XState *env, uint32_t num, uint64_t mem,
280                       uint64_t code)
281 {
282     uint64_t r;
283
284     switch (num) {
285     case 0x500:
286         /* KVM hypercall */
287         r = s390_virtio_hypercall(env);
288         break;
289     case 0x44:
290         /* yield */
291         r = 0;
292         break;
293     case 0x308:
294         /* ipl */
295         r = 0;
296         break;
297     default:
298         r = -1;
299         break;
300     }
301
302     if (r) {
303         program_interrupt(env, PGM_OPERATION, ILEN_LATER_INC);
304     }
305
306     return r;
307 }
308
309 /* Set Prefix */
310 void HELPER(spx)(CPUS390XState *env, uint64_t a1)
311 {
312     uint32_t prefix = a1 & 0x7fffe000;
313     env->psa = prefix;
314     qemu_log("prefix: %#x\n", prefix);
315     tlb_flush_page(env, 0);
316     tlb_flush_page(env, TARGET_PAGE_SIZE);
317 }
318
319 static inline uint64_t clock_value(CPUS390XState *env)
320 {
321     uint64_t time;
322
323     time = env->tod_offset +
324         time2tod(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - env->tod_basetime);
325
326     return time;
327 }
328
329 /* Store Clock */
330 uint64_t HELPER(stck)(CPUS390XState *env)
331 {
332     return clock_value(env);
333 }
334
335 /* Set Clock Comparator */
336 void HELPER(sckc)(CPUS390XState *env, uint64_t time)
337 {
338     if (time == -1ULL) {
339         return;
340     }
341
342     /* difference between now and then */
343     time -= clock_value(env);
344     /* nanoseconds */
345     time = (time * 125) >> 9;
346
347     timer_mod(env->tod_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + time);
348 }
349
350 /* Store Clock Comparator */
351 uint64_t HELPER(stckc)(CPUS390XState *env)
352 {
353     /* XXX implement */
354     return 0;
355 }
356
357 /* Set CPU Timer */
358 void HELPER(spt)(CPUS390XState *env, uint64_t time)
359 {
360     if (time == -1ULL) {
361         return;
362     }
363
364     /* nanoseconds */
365     time = (time * 125) >> 9;
366
367     timer_mod(env->cpu_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + time);
368 }
369
370 /* Store CPU Timer */
371 uint64_t HELPER(stpt)(CPUS390XState *env)
372 {
373     /* XXX implement */
374     return 0;
375 }
376
377 /* Store System Information */
378 uint32_t HELPER(stsi)(CPUS390XState *env, uint64_t a0,
379                       uint64_t r0, uint64_t r1)
380 {
381     int cc = 0;
382     int sel1, sel2;
383
384     if ((r0 & STSI_LEVEL_MASK) <= STSI_LEVEL_3 &&
385         ((r0 & STSI_R0_RESERVED_MASK) || (r1 & STSI_R1_RESERVED_MASK))) {
386         /* valid function code, invalid reserved bits */
387         program_interrupt(env, PGM_SPECIFICATION, 2);
388     }
389
390     sel1 = r0 & STSI_R0_SEL1_MASK;
391     sel2 = r1 & STSI_R1_SEL2_MASK;
392
393     /* XXX: spec exception if sysib is not 4k-aligned */
394
395     switch (r0 & STSI_LEVEL_MASK) {
396     case STSI_LEVEL_1:
397         if ((sel1 == 1) && (sel2 == 1)) {
398             /* Basic Machine Configuration */
399             struct sysib_111 sysib;
400
401             memset(&sysib, 0, sizeof(sysib));
402             ebcdic_put(sysib.manuf, "QEMU            ", 16);
403             /* same as machine type number in STORE CPU ID */
404             ebcdic_put(sysib.type, "QEMU", 4);
405             /* same as model number in STORE CPU ID */
406             ebcdic_put(sysib.model, "QEMU            ", 16);
407             ebcdic_put(sysib.sequence, "QEMU            ", 16);
408             ebcdic_put(sysib.plant, "QEMU", 4);
409             cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
410         } else if ((sel1 == 2) && (sel2 == 1)) {
411             /* Basic Machine CPU */
412             struct sysib_121 sysib;
413
414             memset(&sysib, 0, sizeof(sysib));
415             /* XXX make different for different CPUs? */
416             ebcdic_put(sysib.sequence, "QEMUQEMUQEMUQEMU", 16);
417             ebcdic_put(sysib.plant, "QEMU", 4);
418             stw_p(&sysib.cpu_addr, env->cpu_num);
419             cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
420         } else if ((sel1 == 2) && (sel2 == 2)) {
421             /* Basic Machine CPUs */
422             struct sysib_122 sysib;
423
424             memset(&sysib, 0, sizeof(sysib));
425             stl_p(&sysib.capability, 0x443afc29);
426             /* XXX change when SMP comes */
427             stw_p(&sysib.total_cpus, 1);
428             stw_p(&sysib.active_cpus, 1);
429             stw_p(&sysib.standby_cpus, 0);
430             stw_p(&sysib.reserved_cpus, 0);
431             cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
432         } else {
433             cc = 3;
434         }
435         break;
436     case STSI_LEVEL_2:
437         {
438             if ((sel1 == 2) && (sel2 == 1)) {
439                 /* LPAR CPU */
440                 struct sysib_221 sysib;
441
442                 memset(&sysib, 0, sizeof(sysib));
443                 /* XXX make different for different CPUs? */
444                 ebcdic_put(sysib.sequence, "QEMUQEMUQEMUQEMU", 16);
445                 ebcdic_put(sysib.plant, "QEMU", 4);
446                 stw_p(&sysib.cpu_addr, env->cpu_num);
447                 stw_p(&sysib.cpu_id, 0);
448                 cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
449             } else if ((sel1 == 2) && (sel2 == 2)) {
450                 /* LPAR CPUs */
451                 struct sysib_222 sysib;
452
453                 memset(&sysib, 0, sizeof(sysib));
454                 stw_p(&sysib.lpar_num, 0);
455                 sysib.lcpuc = 0;
456                 /* XXX change when SMP comes */
457                 stw_p(&sysib.total_cpus, 1);
458                 stw_p(&sysib.conf_cpus, 1);
459                 stw_p(&sysib.standby_cpus, 0);
460                 stw_p(&sysib.reserved_cpus, 0);
461                 ebcdic_put(sysib.name, "QEMU    ", 8);
462                 stl_p(&sysib.caf, 1000);
463                 stw_p(&sysib.dedicated_cpus, 0);
464                 stw_p(&sysib.shared_cpus, 0);
465                 cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
466             } else {
467                 cc = 3;
468             }
469             break;
470         }
471     case STSI_LEVEL_3:
472         {
473             if ((sel1 == 2) && (sel2 == 2)) {
474                 /* VM CPUs */
475                 struct sysib_322 sysib;
476
477                 memset(&sysib, 0, sizeof(sysib));
478                 sysib.count = 1;
479                 /* XXX change when SMP comes */
480                 stw_p(&sysib.vm[0].total_cpus, 1);
481                 stw_p(&sysib.vm[0].conf_cpus, 1);
482                 stw_p(&sysib.vm[0].standby_cpus, 0);
483                 stw_p(&sysib.vm[0].reserved_cpus, 0);
484                 ebcdic_put(sysib.vm[0].name, "KVMguest", 8);
485                 stl_p(&sysib.vm[0].caf, 1000);
486                 ebcdic_put(sysib.vm[0].cpi, "KVM/Linux       ", 16);
487                 cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
488             } else {
489                 cc = 3;
490             }
491             break;
492         }
493     case STSI_LEVEL_CURRENT:
494         env->regs[0] = STSI_LEVEL_3;
495         break;
496     default:
497         cc = 3;
498         break;
499     }
500
501     return cc;
502 }
503
504 uint32_t HELPER(sigp)(CPUS390XState *env, uint64_t order_code, uint32_t r1,
505                       uint64_t cpu_addr)
506 {
507     int cc = 0;
508
509     HELPER_LOG("%s: %016" PRIx64 " %08x %016" PRIx64 "\n",
510                __func__, order_code, r1, cpu_addr);
511
512     /* Remember: Use "R1 or R1 + 1, whichever is the odd-numbered register"
513        as parameter (input). Status (output) is always R1. */
514
515     switch (order_code) {
516     case SIGP_SET_ARCH:
517         /* switch arch */
518         break;
519     case SIGP_SENSE:
520         /* enumerate CPU status */
521         if (cpu_addr) {
522             /* XXX implement when SMP comes */
523             return 3;
524         }
525         env->regs[r1] &= 0xffffffff00000000ULL;
526         cc = 1;
527         break;
528 #if !defined(CONFIG_USER_ONLY)
529     case SIGP_RESTART:
530         qemu_system_reset_request();
531         cpu_loop_exit(env);
532         break;
533     case SIGP_STOP:
534         qemu_system_shutdown_request();
535         cpu_loop_exit(env);
536         break;
537 #endif
538     default:
539         /* unknown sigp */
540         fprintf(stderr, "XXX unknown sigp: 0x%" PRIx64 "\n", order_code);
541         cc = 3;
542     }
543
544     return cc;
545 }
546 #endif