Merge remote-tracking branch 'afaerber/tags/qom-cpu-for-anthony' into staging
[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 int load_normal_reset(S390CPU *cpu)
196 {
197     S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
198
199     pause_all_vcpus();
200     cpu_synchronize_all_states();
201     cpu_reset_all();
202     io_subsystem_reset();
203     scc->initial_cpu_reset(CPU(cpu));
204     scc->load_normal(CPU(cpu));
205     cpu_synchronize_all_post_reset();
206     resume_all_vcpus();
207     return 0;
208 }
209
210 #define DIAG_308_RC_NO_CONF         0x0102
211 #define DIAG_308_RC_INVALID         0x0402
212 void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3)
213 {
214     uint64_t addr =  env->regs[r1];
215     uint64_t subcode = env->regs[r3];
216
217     if (env->psw.mask & PSW_MASK_PSTATE) {
218         program_interrupt(env, PGM_PRIVILEGED, ILEN_LATER_INC);
219         return;
220     }
221
222     if ((subcode & ~0x0ffffULL) || (subcode > 6)) {
223         program_interrupt(env, PGM_SPECIFICATION, ILEN_LATER_INC);
224         return;
225     }
226
227     switch (subcode) {
228     case 1:
229         load_normal_reset(s390_env_get_cpu(env));
230         break;
231     case 5:
232         if ((r1 & 1) || (addr & 0x0fffULL)) {
233             program_interrupt(env, PGM_SPECIFICATION, ILEN_LATER_INC);
234             return;
235         }
236         env->regs[r1+1] = DIAG_308_RC_INVALID;
237         return;
238     case 6:
239         if ((r1 & 1) || (addr & 0x0fffULL)) {
240             program_interrupt(env, PGM_SPECIFICATION, ILEN_LATER_INC);
241             return;
242         }
243         env->regs[r1+1] = DIAG_308_RC_NO_CONF;
244         return;
245     default:
246         hw_error("Unhandled diag308 subcode %" PRIx64, subcode);
247         break;
248     }
249 }
250 #endif
251
252 /* DIAG */
253 uint64_t HELPER(diag)(CPUS390XState *env, uint32_t num, uint64_t mem,
254                       uint64_t code)
255 {
256     uint64_t r;
257
258     switch (num) {
259     case 0x500:
260         /* KVM hypercall */
261         r = s390_virtio_hypercall(env);
262         break;
263     case 0x44:
264         /* yield */
265         r = 0;
266         break;
267     case 0x308:
268         /* ipl */
269         r = 0;
270         break;
271     default:
272         r = -1;
273         break;
274     }
275
276     if (r) {
277         program_interrupt(env, PGM_OPERATION, ILEN_LATER_INC);
278     }
279
280     return r;
281 }
282
283 /* Set Prefix */
284 void HELPER(spx)(CPUS390XState *env, uint64_t a1)
285 {
286     uint32_t prefix = a1 & 0x7fffe000;
287     env->psa = prefix;
288     qemu_log("prefix: %#x\n", prefix);
289     tlb_flush_page(env, 0);
290     tlb_flush_page(env, TARGET_PAGE_SIZE);
291 }
292
293 static inline uint64_t clock_value(CPUS390XState *env)
294 {
295     uint64_t time;
296
297     time = env->tod_offset +
298         time2tod(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - env->tod_basetime);
299
300     return time;
301 }
302
303 /* Store Clock */
304 uint64_t HELPER(stck)(CPUS390XState *env)
305 {
306     return clock_value(env);
307 }
308
309 /* Set Clock Comparator */
310 void HELPER(sckc)(CPUS390XState *env, uint64_t time)
311 {
312     if (time == -1ULL) {
313         return;
314     }
315
316     /* difference between now and then */
317     time -= clock_value(env);
318     /* nanoseconds */
319     time = (time * 125) >> 9;
320
321     timer_mod(env->tod_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + time);
322 }
323
324 /* Store Clock Comparator */
325 uint64_t HELPER(stckc)(CPUS390XState *env)
326 {
327     /* XXX implement */
328     return 0;
329 }
330
331 /* Set CPU Timer */
332 void HELPER(spt)(CPUS390XState *env, uint64_t time)
333 {
334     if (time == -1ULL) {
335         return;
336     }
337
338     /* nanoseconds */
339     time = (time * 125) >> 9;
340
341     timer_mod(env->cpu_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + time);
342 }
343
344 /* Store CPU Timer */
345 uint64_t HELPER(stpt)(CPUS390XState *env)
346 {
347     /* XXX implement */
348     return 0;
349 }
350
351 /* Store System Information */
352 uint32_t HELPER(stsi)(CPUS390XState *env, uint64_t a0,
353                       uint64_t r0, uint64_t r1)
354 {
355     int cc = 0;
356     int sel1, sel2;
357
358     if ((r0 & STSI_LEVEL_MASK) <= STSI_LEVEL_3 &&
359         ((r0 & STSI_R0_RESERVED_MASK) || (r1 & STSI_R1_RESERVED_MASK))) {
360         /* valid function code, invalid reserved bits */
361         program_interrupt(env, PGM_SPECIFICATION, 2);
362     }
363
364     sel1 = r0 & STSI_R0_SEL1_MASK;
365     sel2 = r1 & STSI_R1_SEL2_MASK;
366
367     /* XXX: spec exception if sysib is not 4k-aligned */
368
369     switch (r0 & STSI_LEVEL_MASK) {
370     case STSI_LEVEL_1:
371         if ((sel1 == 1) && (sel2 == 1)) {
372             /* Basic Machine Configuration */
373             struct sysib_111 sysib;
374
375             memset(&sysib, 0, sizeof(sysib));
376             ebcdic_put(sysib.manuf, "QEMU            ", 16);
377             /* same as machine type number in STORE CPU ID */
378             ebcdic_put(sysib.type, "QEMU", 4);
379             /* same as model number in STORE CPU ID */
380             ebcdic_put(sysib.model, "QEMU            ", 16);
381             ebcdic_put(sysib.sequence, "QEMU            ", 16);
382             ebcdic_put(sysib.plant, "QEMU", 4);
383             cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
384         } else if ((sel1 == 2) && (sel2 == 1)) {
385             /* Basic Machine CPU */
386             struct sysib_121 sysib;
387
388             memset(&sysib, 0, sizeof(sysib));
389             /* XXX make different for different CPUs? */
390             ebcdic_put(sysib.sequence, "QEMUQEMUQEMUQEMU", 16);
391             ebcdic_put(sysib.plant, "QEMU", 4);
392             stw_p(&sysib.cpu_addr, env->cpu_num);
393             cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
394         } else if ((sel1 == 2) && (sel2 == 2)) {
395             /* Basic Machine CPUs */
396             struct sysib_122 sysib;
397
398             memset(&sysib, 0, sizeof(sysib));
399             stl_p(&sysib.capability, 0x443afc29);
400             /* XXX change when SMP comes */
401             stw_p(&sysib.total_cpus, 1);
402             stw_p(&sysib.active_cpus, 1);
403             stw_p(&sysib.standby_cpus, 0);
404             stw_p(&sysib.reserved_cpus, 0);
405             cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
406         } else {
407             cc = 3;
408         }
409         break;
410     case STSI_LEVEL_2:
411         {
412             if ((sel1 == 2) && (sel2 == 1)) {
413                 /* LPAR CPU */
414                 struct sysib_221 sysib;
415
416                 memset(&sysib, 0, sizeof(sysib));
417                 /* XXX make different for different CPUs? */
418                 ebcdic_put(sysib.sequence, "QEMUQEMUQEMUQEMU", 16);
419                 ebcdic_put(sysib.plant, "QEMU", 4);
420                 stw_p(&sysib.cpu_addr, env->cpu_num);
421                 stw_p(&sysib.cpu_id, 0);
422                 cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
423             } else if ((sel1 == 2) && (sel2 == 2)) {
424                 /* LPAR CPUs */
425                 struct sysib_222 sysib;
426
427                 memset(&sysib, 0, sizeof(sysib));
428                 stw_p(&sysib.lpar_num, 0);
429                 sysib.lcpuc = 0;
430                 /* XXX change when SMP comes */
431                 stw_p(&sysib.total_cpus, 1);
432                 stw_p(&sysib.conf_cpus, 1);
433                 stw_p(&sysib.standby_cpus, 0);
434                 stw_p(&sysib.reserved_cpus, 0);
435                 ebcdic_put(sysib.name, "QEMU    ", 8);
436                 stl_p(&sysib.caf, 1000);
437                 stw_p(&sysib.dedicated_cpus, 0);
438                 stw_p(&sysib.shared_cpus, 0);
439                 cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
440             } else {
441                 cc = 3;
442             }
443             break;
444         }
445     case STSI_LEVEL_3:
446         {
447             if ((sel1 == 2) && (sel2 == 2)) {
448                 /* VM CPUs */
449                 struct sysib_322 sysib;
450
451                 memset(&sysib, 0, sizeof(sysib));
452                 sysib.count = 1;
453                 /* XXX change when SMP comes */
454                 stw_p(&sysib.vm[0].total_cpus, 1);
455                 stw_p(&sysib.vm[0].conf_cpus, 1);
456                 stw_p(&sysib.vm[0].standby_cpus, 0);
457                 stw_p(&sysib.vm[0].reserved_cpus, 0);
458                 ebcdic_put(sysib.vm[0].name, "KVMguest", 8);
459                 stl_p(&sysib.vm[0].caf, 1000);
460                 ebcdic_put(sysib.vm[0].cpi, "KVM/Linux       ", 16);
461                 cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
462             } else {
463                 cc = 3;
464             }
465             break;
466         }
467     case STSI_LEVEL_CURRENT:
468         env->regs[0] = STSI_LEVEL_3;
469         break;
470     default:
471         cc = 3;
472         break;
473     }
474
475     return cc;
476 }
477
478 uint32_t HELPER(sigp)(CPUS390XState *env, uint64_t order_code, uint32_t r1,
479                       uint64_t cpu_addr)
480 {
481     int cc = 0;
482
483     HELPER_LOG("%s: %016" PRIx64 " %08x %016" PRIx64 "\n",
484                __func__, order_code, r1, cpu_addr);
485
486     /* Remember: Use "R1 or R1 + 1, whichever is the odd-numbered register"
487        as parameter (input). Status (output) is always R1. */
488
489     switch (order_code) {
490     case SIGP_SET_ARCH:
491         /* switch arch */
492         break;
493     case SIGP_SENSE:
494         /* enumerate CPU status */
495         if (cpu_addr) {
496             /* XXX implement when SMP comes */
497             return 3;
498         }
499         env->regs[r1] &= 0xffffffff00000000ULL;
500         cc = 1;
501         break;
502 #if !defined(CONFIG_USER_ONLY)
503     case SIGP_RESTART:
504         qemu_system_reset_request();
505         cpu_loop_exit(env);
506         break;
507     case SIGP_STOP:
508         qemu_system_shutdown_request();
509         cpu_loop_exit(env);
510         break;
511 #endif
512     default:
513         /* unknown sigp */
514         fprintf(stderr, "XXX unknown sigp: 0x%" PRIx64 "\n", order_code);
515         cc = 3;
516     }
517
518     return cc;
519 }
520 #endif