]> git.proxmox.com Git - qemu.git/blobdiff - target-ppc/helper_regs.h
Merge remote-tracking branch 'stefanha/net' into staging
[qemu.git] / target-ppc / helper_regs.h
index 03c21c77f66e81ed4a1e3a7f68bcfa8e244a2da2..a6d5e2fe2f1e75cbd436b5661b762af6956bb2d0 100644 (file)
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #if !defined(__HELPER_REGS_H__)
 #define __HELPER_REGS_H__
 
-static always_inline target_ulong hreg_load_xer (CPUPPCState *env)
-{
-    return (xer_so << XER_SO) |
-        (xer_ov << XER_OV) |
-        (xer_ca << XER_CA) |
-        (xer_bc << XER_BC) |
-        (xer_cmp << XER_CMP);
-}
-
-static always_inline void hreg_store_xer (CPUPPCState *env, target_ulong value)
-{
-    xer_so = (value >> XER_SO) & 0x01;
-    xer_ov = (value >> XER_OV) & 0x01;
-    xer_ca = (value >> XER_CA) & 0x01;
-    xer_cmp = (value >> XER_CMP) & 0xFF;
-    xer_bc = (value >> XER_BC) & 0x7F;
-}
-
 /* Swap temporary saved registers with GPRs */
-static always_inline void hreg_swap_gpr_tgpr (CPUPPCState *env)
+static inline void hreg_swap_gpr_tgpr(CPUPPCState *env)
 {
-    ppc_gpr_t tmp;
+    target_ulong tmp;
 
     tmp = env->gpr[0];
     env->gpr[0] = env->tgpr[0];
@@ -58,18 +39,17 @@ static always_inline void hreg_swap_gpr_tgpr (CPUPPCState *env)
     env->tgpr[3] = tmp;
 }
 
-static always_inline void hreg_compute_mem_idx (CPUPPCState *env)
+static inline void hreg_compute_mem_idx(CPUPPCState *env)
 {
-#if defined (TARGET_PPC64)
     /* Precompute MMU index */
-    if (msr_pr == 0 && msr_hv != 0)
+    if (msr_pr == 0 && msr_hv != 0) {
         env->mmu_idx = 2;
-    else
-#endif
+    } else {
         env->mmu_idx = 1 - msr_pr;
+    }
 }
 
-static always_inline void hreg_compute_hflags (CPUPPCState *env)
+static inline void hreg_compute_hflags(CPUPPCState *env)
 {
     target_ulong hflags_mask;
 
@@ -77,28 +57,35 @@ static always_inline void hreg_compute_hflags (CPUPPCState *env)
     hflags_mask = (1 << MSR_VR) | (1 << MSR_AP) | (1 << MSR_SA) |
         (1 << MSR_PR) | (1 << MSR_FP) | (1 << MSR_SE) | (1 << MSR_BE) |
         (1 << MSR_LE);
-#if defined (TARGET_PPC64)
-    hflags_mask |= (1ULL << MSR_CM) | (1ULL << MSR_SF) | (1ULL << MSR_HV);
-#endif
+    hflags_mask |= (1ULL << MSR_CM) | (1ULL << MSR_SF) | MSR_HVB;
     hreg_compute_mem_idx(env);
     env->hflags = env->msr & hflags_mask;
     /* Merge with hflags coming from other registers */
     env->hflags |= env->hflags_nmsr;
 }
 
-static always_inline int hreg_store_msr (CPUPPCState *env, target_ulong value)
+static inline int hreg_store_msr(CPUPPCState *env, target_ulong value,
+                                 int alter_hv)
 {
     int excp;
+#if !defined(CONFIG_USER_ONLY)
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
+#endif
 
     excp = 0;
     value &= env->msr_mask;
-#if !defined (CONFIG_USER_ONLY)
+#if !defined(CONFIG_USER_ONLY)
+    if (!alter_hv) {
+        /* mtmsr cannot alter the hypervisor state */
+        value &= ~MSR_HVB;
+        value |= env->msr & MSR_HVB;
+    }
     if (((value >> MSR_IR) & 1) != msr_ir ||
         ((value >> MSR_DR) & 1) != msr_dr) {
         /* Flush all tlb when changing translation mode */
         tlb_flush(env, 1);
         excp = POWERPC_EXCP_NONE;
-        env->interrupt_request |= CPU_INTERRUPT_EXITTB;
+        cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
     }
     if (unlikely((env->flags & POWERPC_FLAG_TGPR) &&
                  ((value ^ env->msr) & (1 << MSR_TGPR)))) {
@@ -112,10 +99,10 @@ static always_inline int hreg_store_msr (CPUPPCState *env, target_ulong value)
 #endif
     env->msr = value;
     hreg_compute_hflags(env);
-#if !defined (CONFIG_USER_ONLY)
+#if !defined(CONFIG_USER_ONLY)
     if (unlikely(msr_pow == 1)) {
         if ((*env->check_pow)(env)) {
-            env->halted = 1;
+            cs->halted = 1;
             excp = EXCP_HALTED;
         }
     }