]>
Commit | Line | Data |
---|---|---|
c70647ee PMD |
1 | /* |
2 | * Helpers for HPPA system instructions. | |
3 | * | |
4 | * Copyright (c) 2016 Richard Henderson <rth@twiddle.net> | |
5 | * | |
6 | * This library is free software; you can redistribute it and/or | |
7 | * modify it under the terms of the GNU Lesser General Public | |
8 | * License as published by the Free Software Foundation; either | |
9 | * version 2.1 of the License, or (at your option) any later version. | |
10 | * | |
11 | * This library is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | * Lesser General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU Lesser General Public | |
17 | * License along with this library; if not, see <http://www.gnu.org/licenses/>. | |
18 | */ | |
19 | ||
20 | #include "qemu/osdep.h" | |
21 | #include "cpu.h" | |
22 | #include "exec/exec-all.h" | |
23 | #include "exec/helper-proto.h" | |
24 | #include "qemu/timer.h" | |
25 | #include "sysemu/runstate.h" | |
26 | ||
c53e401e | 27 | void HELPER(write_interval_timer)(CPUHPPAState *env, target_ulong val) |
c70647ee PMD |
28 | { |
29 | HPPACPU *cpu = env_archcpu(env); | |
30 | uint64_t current = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); | |
31 | uint64_t timeout; | |
32 | ||
33 | /* | |
34 | * Even in 64-bit mode, the comparator is always 32-bit. But the | |
35 | * value we expose to the guest is 1/4 of the speed of the clock, | |
36 | * so moosh in 34 bits. | |
37 | */ | |
38 | timeout = deposit64(current, 0, 34, (uint64_t)val << 2); | |
39 | ||
40 | /* If the mooshing puts the clock in the past, advance to next round. */ | |
41 | if (timeout < current + 1000) { | |
42 | timeout += 1ULL << 34; | |
43 | } | |
44 | ||
45 | cpu->env.cr[CR_IT] = timeout; | |
46 | timer_mod(cpu->alarm_timer, timeout); | |
47 | } | |
48 | ||
49 | void HELPER(halt)(CPUHPPAState *env) | |
50 | { | |
51 | qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); | |
52 | helper_excp(env, EXCP_HLT); | |
53 | } | |
54 | ||
55 | void HELPER(reset)(CPUHPPAState *env) | |
56 | { | |
57 | qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); | |
58 | helper_excp(env, EXCP_HLT); | |
59 | } | |
60 | ||
c53e401e | 61 | target_ulong HELPER(swap_system_mask)(CPUHPPAState *env, target_ulong nsm) |
c70647ee PMD |
62 | { |
63 | target_ulong psw = env->psw; | |
64 | /* | |
65 | * Setting the PSW Q bit to 1, if it was not already 1, is an | |
66 | * undefined operation. | |
67 | * | |
68 | * However, HP-UX 10.20 does this with the SSM instruction. | |
69 | * Tested this on HP9000/712 and HP9000/785/C3750 and both | |
70 | * machines set the Q bit from 0 to 1 without an exception, | |
71 | * so let this go without comment. | |
72 | */ | |
73 | env->psw = (psw & ~PSW_SM) | (nsm & PSW_SM); | |
74 | return psw & PSW_SM; | |
75 | } | |
76 | ||
77 | void HELPER(rfi)(CPUHPPAState *env) | |
78 | { | |
79 | env->iasq_f = (uint64_t)env->cr[CR_IIASQ] << 32; | |
80 | env->iasq_b = (uint64_t)env->cr_back[0] << 32; | |
81 | env->iaoq_f = env->cr[CR_IIAOQ]; | |
82 | env->iaoq_b = env->cr_back[1]; | |
b10700d8 RH |
83 | |
84 | /* | |
85 | * For pa2.0, IIASQ is the top bits of the virtual address. | |
86 | * To recreate the space identifier, remove the offset bits. | |
87 | */ | |
88 | if (hppa_is_pa20(env)) { | |
89 | env->iasq_f &= ~env->iaoq_f; | |
90 | env->iasq_b &= ~env->iaoq_b; | |
91 | } | |
92 | ||
c70647ee PMD |
93 | cpu_hppa_put_psw(env, env->cr[CR_IPSW]); |
94 | } | |
95 | ||
96 | void HELPER(getshadowregs)(CPUHPPAState *env) | |
97 | { | |
98 | env->gr[1] = env->shadow[0]; | |
99 | env->gr[8] = env->shadow[1]; | |
100 | env->gr[9] = env->shadow[2]; | |
101 | env->gr[16] = env->shadow[3]; | |
102 | env->gr[17] = env->shadow[4]; | |
103 | env->gr[24] = env->shadow[5]; | |
104 | env->gr[25] = env->shadow[6]; | |
105 | } | |
106 | ||
107 | void HELPER(rfi_r)(CPUHPPAState *env) | |
108 | { | |
109 | helper_getshadowregs(env); | |
110 | helper_rfi(env); | |
111 | } |