xref: /qemu/target/alpha/sys_helper.c (revision 31b030d4abc5bea89c2b33b39d3b302836f6b6ee)
169163fbbSRichard Henderson /*
269163fbbSRichard Henderson  *  Helpers for system instructions.
369163fbbSRichard Henderson  *
469163fbbSRichard Henderson  *  Copyright (c) 2007 Jocelyn Mayer
569163fbbSRichard Henderson  *
669163fbbSRichard Henderson  * This library is free software; you can redistribute it and/or
769163fbbSRichard Henderson  * modify it under the terms of the GNU Lesser General Public
869163fbbSRichard Henderson  * License as published by the Free Software Foundation; either
969163fbbSRichard Henderson  * version 2 of the License, or (at your option) any later version.
1069163fbbSRichard Henderson  *
1169163fbbSRichard Henderson  * This library is distributed in the hope that it will be useful,
1269163fbbSRichard Henderson  * but WITHOUT ANY WARRANTY; without even the implied warranty of
1369163fbbSRichard Henderson  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1469163fbbSRichard Henderson  * Lesser General Public License for more details.
1569163fbbSRichard Henderson  *
1669163fbbSRichard Henderson  * You should have received a copy of the GNU Lesser General Public
1769163fbbSRichard Henderson  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
1869163fbbSRichard Henderson  */
1969163fbbSRichard Henderson 
2069163fbbSRichard Henderson #include "cpu.h"
2169163fbbSRichard Henderson #include "helper.h"
229c17d615SPaolo Bonzini #include "sysemu/sysemu.h"
231de7afc9SPaolo Bonzini #include "qemu/timer.h"
2469163fbbSRichard Henderson 
2569163fbbSRichard Henderson 
2669163fbbSRichard Henderson uint64_t helper_load_pcc(CPUAlphaState *env)
2769163fbbSRichard Henderson {
2869163fbbSRichard Henderson #ifndef CONFIG_USER_ONLY
2969163fbbSRichard Henderson     /* In system mode we have access to a decent high-resolution clock.
3069163fbbSRichard Henderson        In order to make OS-level time accounting work with the RPCC,
3169163fbbSRichard Henderson        present it with a well-timed clock fixed at 250MHz.  */
3269163fbbSRichard Henderson     return (((uint64_t)env->pcc_ofs << 32)
33bc72ad67SAlex Bligh             | (uint32_t)(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >> 2));
3469163fbbSRichard Henderson #else
35bc72ad67SAlex Bligh     /* In user-mode, QEMU_CLOCK_VIRTUAL doesn't exist.  Just pass through the host cpu
3669163fbbSRichard Henderson        clock ticks.  Also, don't bother taking PCC_OFS into account.  */
3769163fbbSRichard Henderson     return (uint32_t)cpu_get_real_ticks();
3869163fbbSRichard Henderson #endif
3969163fbbSRichard Henderson }
4069163fbbSRichard Henderson 
4169163fbbSRichard Henderson /* PALcode support special instructions */
4269163fbbSRichard Henderson #ifndef CONFIG_USER_ONLY
4369163fbbSRichard Henderson void helper_hw_ret(CPUAlphaState *env, uint64_t a)
4469163fbbSRichard Henderson {
4569163fbbSRichard Henderson     env->pc = a & ~3;
4669163fbbSRichard Henderson     env->intr_flag = 0;
4769163fbbSRichard Henderson     env->lock_addr = -1;
4869163fbbSRichard Henderson     if ((a & 1) == 0) {
4969163fbbSRichard Henderson         env->pal_mode = 0;
5069163fbbSRichard Henderson         swap_shadow_regs(env);
5169163fbbSRichard Henderson     }
5269163fbbSRichard Henderson }
5369163fbbSRichard Henderson 
54ba96394eSRichard Henderson void helper_call_pal(CPUAlphaState *env, uint64_t pc, uint64_t entry_ofs)
55ba96394eSRichard Henderson {
56ba96394eSRichard Henderson     int pal_mode = env->pal_mode;
57ba96394eSRichard Henderson     env->exc_addr = pc | pal_mode;
58ba96394eSRichard Henderson     env->pc = env->palbr + entry_ofs;
59ba96394eSRichard Henderson     if (!pal_mode) {
60ba96394eSRichard Henderson         env->pal_mode = 1;
61ba96394eSRichard Henderson         swap_shadow_regs(env);
62ba96394eSRichard Henderson     }
63ba96394eSRichard Henderson }
64ba96394eSRichard Henderson 
6569163fbbSRichard Henderson void helper_tbia(CPUAlphaState *env)
6669163fbbSRichard Henderson {
6769163fbbSRichard Henderson     tlb_flush(env, 1);
6869163fbbSRichard Henderson }
6969163fbbSRichard Henderson 
7069163fbbSRichard Henderson void helper_tbis(CPUAlphaState *env, uint64_t p)
7169163fbbSRichard Henderson {
7231b030d4SAndreas Färber     tlb_flush_page(CPU(alpha_env_get_cpu(env)), p);
7369163fbbSRichard Henderson }
7469163fbbSRichard Henderson 
75a9ead832SRichard Henderson void helper_tb_flush(CPUAlphaState *env)
76a9ead832SRichard Henderson {
77a9ead832SRichard Henderson     tb_flush(env);
78a9ead832SRichard Henderson }
79a9ead832SRichard Henderson 
8069163fbbSRichard Henderson void helper_halt(uint64_t restart)
8169163fbbSRichard Henderson {
8269163fbbSRichard Henderson     if (restart) {
8369163fbbSRichard Henderson         qemu_system_reset_request();
8469163fbbSRichard Henderson     } else {
8569163fbbSRichard Henderson         qemu_system_shutdown_request();
8669163fbbSRichard Henderson     }
8769163fbbSRichard Henderson }
8869163fbbSRichard Henderson 
8919e0cbb8SRichard Henderson uint64_t helper_get_vmtime(void)
9019e0cbb8SRichard Henderson {
91bc72ad67SAlex Bligh     return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
9219e0cbb8SRichard Henderson }
9319e0cbb8SRichard Henderson 
9419e0cbb8SRichard Henderson uint64_t helper_get_walltime(void)
9569163fbbSRichard Henderson {
96884f17c2SAlex Bligh     return qemu_clock_get_ns(rtc_clock);
9769163fbbSRichard Henderson }
9869163fbbSRichard Henderson 
9969163fbbSRichard Henderson void helper_set_alarm(CPUAlphaState *env, uint64_t expire)
10069163fbbSRichard Henderson {
101c9245853SAndreas Färber     AlphaCPU *cpu = alpha_env_get_cpu(env);
102c9245853SAndreas Färber 
10369163fbbSRichard Henderson     if (expire) {
10469163fbbSRichard Henderson         env->alarm_expire = expire;
105bc72ad67SAlex Bligh         timer_mod(cpu->alarm_timer, expire);
10669163fbbSRichard Henderson     } else {
107bc72ad67SAlex Bligh         timer_del(cpu->alarm_timer);
10869163fbbSRichard Henderson     }
10969163fbbSRichard Henderson }
110ba96394eSRichard Henderson 
11169163fbbSRichard Henderson #endif /* CONFIG_USER_ONLY */
112