1b6a71ef7SJia Liu /* 2b6a71ef7SJia Liu * OpenRISC interrupt helper routines 3b6a71ef7SJia Liu * 4b6a71ef7SJia Liu * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> 5b6a71ef7SJia Liu * Feng Gao <gf91597@gmail.com> 6b6a71ef7SJia Liu * 7b6a71ef7SJia Liu * This library is free software; you can redistribute it and/or 8b6a71ef7SJia Liu * modify it under the terms of the GNU Lesser General Public 9b6a71ef7SJia Liu * License as published by the Free Software Foundation; either 10b6a71ef7SJia Liu * version 2 of the License, or (at your option) any later version. 11b6a71ef7SJia Liu * 12b6a71ef7SJia Liu * This library is distributed in the hope that it will be useful, 13b6a71ef7SJia Liu * but WITHOUT ANY WARRANTY; without even the implied warranty of 14b6a71ef7SJia Liu * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15b6a71ef7SJia Liu * Lesser General Public License for more details. 16b6a71ef7SJia Liu * 17b6a71ef7SJia Liu * You should have received a copy of the GNU Lesser General Public 18b6a71ef7SJia Liu * License along with this library; if not, see <http://www.gnu.org/licenses/>. 19b6a71ef7SJia Liu */ 20b6a71ef7SJia Liu 21ed2decc6SPeter Maydell #include "qemu/osdep.h" 22b6a71ef7SJia Liu #include "cpu.h" 232ef6175aSRichard Henderson #include "exec/helper-proto.h" 24b6a71ef7SJia Liu 25b6a71ef7SJia Liu void HELPER(rfe)(CPUOpenRISCState *env) 26b6a71ef7SJia Liu { 27dd51dc52SAndreas Färber OpenRISCCPU *cpu = openrisc_env_get_cpu(env); 28259186a7SAndreas Färber CPUState *cs = CPU(cpu); 29b6a71ef7SJia Liu #ifndef CONFIG_USER_ONLY 30b6a71ef7SJia Liu int need_flush_tlb = (cpu->env.sr & (SR_SM | SR_IME | SR_DME)) ^ 31b6a71ef7SJia Liu (cpu->env.esr & (SR_SM | SR_IME | SR_DME)); 32b6a71ef7SJia Liu #endif 33b6a71ef7SJia Liu cpu->env.pc = cpu->env.epcr; 34b6a71ef7SJia Liu cpu->env.npc = cpu->env.epcr; 35b6a71ef7SJia Liu cpu->env.sr = cpu->env.esr; 36b6a71ef7SJia Liu 37b6a71ef7SJia Liu #ifndef CONFIG_USER_ONLY 38b6a71ef7SJia Liu if (cpu->env.sr & SR_DME) { 39b6a71ef7SJia Liu cpu->env.tlb->cpu_openrisc_map_address_data = 40b6a71ef7SJia Liu &cpu_openrisc_get_phys_data; 41b6a71ef7SJia Liu } else { 42b6a71ef7SJia Liu cpu->env.tlb->cpu_openrisc_map_address_data = 43b6a71ef7SJia Liu &cpu_openrisc_get_phys_nommu; 44b6a71ef7SJia Liu } 45b6a71ef7SJia Liu 46b6a71ef7SJia Liu if (cpu->env.sr & SR_IME) { 47b6a71ef7SJia Liu cpu->env.tlb->cpu_openrisc_map_address_code = 48b6a71ef7SJia Liu &cpu_openrisc_get_phys_code; 49b6a71ef7SJia Liu } else { 50b6a71ef7SJia Liu cpu->env.tlb->cpu_openrisc_map_address_code = 51b6a71ef7SJia Liu &cpu_openrisc_get_phys_nommu; 52b6a71ef7SJia Liu } 53b6a71ef7SJia Liu 54b6a71ef7SJia Liu if (need_flush_tlb) { 5500c8cb0aSAndreas Färber tlb_flush(cs, 1); 56b6a71ef7SJia Liu } 57b6a71ef7SJia Liu #endif 58259186a7SAndreas Färber cs->interrupt_request |= CPU_INTERRUPT_EXITTB; 59b6a71ef7SJia Liu } 60