]> git.proxmox.com Git - qemu.git/blobdiff - target-mips/helper.c
qdev-properties-system.c: Allow vlan or netdev for -device, not both
[qemu.git] / target-mips / helper.c
index bdc1e53669e83743ef5761473fd6b18b2b15f46b..33e0e8863772f0eec7c8a4e108b2bedc8430c895 100644 (file)
@@ -24,7 +24,6 @@
 #include <signal.h>
 
 #include "cpu.h"
-#include "exec-all.h"
 
 enum {
     TLBRET_DIRTY = -4,
@@ -37,7 +36,7 @@ enum {
 #if !defined(CONFIG_USER_ONLY)
 
 /* no MMU emulation */
-int no_mmu_map_address (CPUState *env, target_phys_addr_t *physical, int *prot,
+int no_mmu_map_address (CPUMIPSState *env, hwaddr *physical, int *prot,
                         target_ulong address, int rw, int access_type)
 {
     *physical = address;
@@ -46,7 +45,7 @@ int no_mmu_map_address (CPUState *env, target_phys_addr_t *physical, int *prot,
 }
 
 /* fixed mapping MMU emulation */
-int fixed_mmu_map_address (CPUState *env, target_phys_addr_t *physical, int *prot,
+int fixed_mmu_map_address (CPUMIPSState *env, hwaddr *physical, int *prot,
                            target_ulong address, int rw, int access_type)
 {
     if (address <= (int32_t)0x7FFFFFFFUL) {
@@ -64,7 +63,7 @@ int fixed_mmu_map_address (CPUState *env, target_phys_addr_t *physical, int *pro
 }
 
 /* MIPS32/MIPS64 R4000-style MMU emulation */
-int r4k_map_address (CPUState *env, target_phys_addr_t *physical, int *prot,
+int r4k_map_address (CPUMIPSState *env, hwaddr *physical, int *prot,
                      target_ulong address, int rw, int access_type)
 {
     uint8_t ASID = env->CP0_EntryHi & 0xFF;
@@ -100,7 +99,7 @@ int r4k_map_address (CPUState *env, target_phys_addr_t *physical, int *prot,
     return TLBRET_NOMATCH;
 }
 
-static int get_physical_address (CPUState *env, target_phys_addr_t *physical,
+static int get_physical_address (CPUMIPSState *env, hwaddr *physical,
                                 int *prot, target_ulong address,
                                 int rw, int access_type)
 {
@@ -194,7 +193,7 @@ static int get_physical_address (CPUState *env, target_phys_addr_t *physical,
         }
     }
 #if 0
-    qemu_log(TARGET_FMT_lx " %d %d => " TARGET_FMT_lx " %d (%d)\n",
+    qemu_log(TARGET_FMT_lx " %d %d => %" HWADDR_PRIx " %d (%d)\n",
             address, rw, access_type, *physical, *prot, ret);
 #endif
 
@@ -202,7 +201,7 @@ static int get_physical_address (CPUState *env, target_phys_addr_t *physical,
 }
 #endif
 
-static void raise_mmu_exception(CPUState *env, target_ulong address,
+static void raise_mmu_exception(CPUMIPSState *env, target_ulong address,
                                 int rw, int tlb_error)
 {
     int exception = 0, error_code = 0;
@@ -255,51 +254,52 @@ static void raise_mmu_exception(CPUState *env, target_ulong address,
 }
 
 #if !defined(CONFIG_USER_ONLY)
-target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
+hwaddr mips_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 {
-    target_phys_addr_t phys_addr;
+    MIPSCPU *cpu = MIPS_CPU(cs);
+    hwaddr phys_addr;
     int prot;
 
-    if (get_physical_address(env, &phys_addr, &prot, addr, 0, ACCESS_INT) != 0)
+    if (get_physical_address(&cpu->env, &phys_addr, &prot, addr, 0,
+                             ACCESS_INT) != 0) {
         return -1;
+    }
     return phys_addr;
 }
 #endif
 
-int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                               int mmu_idx, int is_softmmu)
+int cpu_mips_handle_mmu_fault (CPUMIPSState *env, target_ulong address, int rw,
+                               int mmu_idx)
 {
 #if !defined(CONFIG_USER_ONLY)
-    target_phys_addr_t physical;
+    hwaddr physical;
     int prot;
-#endif
     int access_type;
+#endif
     int ret = 0;
 
 #if 0
-    log_cpu_state(env, 0);
+    log_cpu_state(CPU(mips_env_get_cpu(env)), 0);
 #endif
-    qemu_log("%s pc " TARGET_FMT_lx " ad " TARGET_FMT_lx " rw %d mmu_idx %d smmu %d\n",
-              __func__, env->active_tc.PC, address, rw, mmu_idx, is_softmmu);
+    qemu_log("%s pc " TARGET_FMT_lx " ad " TARGET_FMT_lx " rw %d mmu_idx %d\n",
+              __func__, env->active_tc.PC, address, rw, mmu_idx);
 
     rw &= 1;
 
     /* data access */
+#if !defined(CONFIG_USER_ONLY)
     /* XXX: put correct access by using cpu_restore_state()
        correctly */
     access_type = ACCESS_INT;
-#if defined(CONFIG_USER_ONLY)
-    ret = TLBRET_NOMATCH;
-#else
     ret = get_physical_address(env, &physical, &prot,
                                address, rw, access_type);
     qemu_log("%s address=" TARGET_FMT_lx " ret %d physical " TARGET_FMT_plx " prot %d\n",
               __func__, address, ret, physical, prot);
     if (ret == TLBRET_MATCH) {
-       tlb_set_page(env, address & TARGET_PAGE_MASK,
-                    physical & TARGET_PAGE_MASK, prot | PAGE_EXEC,
-                    mmu_idx, TARGET_PAGE_SIZE);
-       ret = 0;
+        tlb_set_page(env, address & TARGET_PAGE_MASK,
+                     physical & TARGET_PAGE_MASK, prot | PAGE_EXEC,
+                     mmu_idx, TARGET_PAGE_SIZE);
+        ret = 0;
     } else if (ret < 0)
 #endif
     {
@@ -311,9 +311,9 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
 }
 
 #if !defined(CONFIG_USER_ONLY)
-target_phys_addr_t cpu_mips_translate_address(CPUState *env, target_ulong address, int rw)
+hwaddr cpu_mips_translate_address(CPUMIPSState *env, target_ulong address, int rw)
 {
-    target_phys_addr_t physical;
+    hwaddr physical;
     int prot;
     int access_type;
     int ret = 0;
@@ -369,8 +369,7 @@ static const char * const excp_names[EXCP_LAST + 1] = {
     [EXCP_CACHE] = "cache error",
 };
 
-#if !defined(CONFIG_USER_ONLY)
-static target_ulong exception_resume_pc (CPUState *env)
+target_ulong exception_resume_pc (CPUMIPSState *env)
 {
     target_ulong bad_pc;
     target_ulong isa_mode;
@@ -386,7 +385,8 @@ static target_ulong exception_resume_pc (CPUState *env)
     return bad_pc;
 }
 
-static void set_hflags_for_handler (CPUState *env)
+#if !defined(CONFIG_USER_ONLY)
+static void set_hflags_for_handler (CPUMIPSState *env)
 {
     /* Exception handlers are entered in 32-bit mode.  */
     env->hflags &= ~(MIPS_HFLAG_M16);
@@ -399,8 +399,10 @@ static void set_hflags_for_handler (CPUState *env)
 }
 #endif
 
-void do_interrupt (CPUState *env)
+void mips_cpu_do_interrupt(CPUState *cs)
 {
+    MIPSCPU *cpu = MIPS_CPU(cs);
+    CPUMIPSState *env = &cpu->env;
 #if !defined(CONFIG_USER_ONLY)
     target_ulong offset;
     int cause = -1;
@@ -455,7 +457,7 @@ void do_interrupt (CPUState *env)
         set_hflags_for_handler(env);
         break;
     case EXCP_RESET:
-        cpu_reset(env);
+        cpu_reset(CPU(cpu));
         break;
     case EXCP_SRESET:
         env->CP0_Status |= (1 << CP0St_SR);
@@ -485,22 +487,22 @@ void do_interrupt (CPUState *env)
             unsigned int vector;
             unsigned int pending = (env->CP0_Cause & CP0Ca_IP_mask) >> 8;
 
+            pending &= env->CP0_Status >> 8;
             /* Compute the Vector Spacing.  */
             spacing = (env->CP0_IntCtl >> CP0IntCtl_VS) & ((1 << 6) - 1);
             spacing <<= 5;
 
             if (env->CP0_Config3 & (1 << CP0C3_VInt)) {
                 /* For VInt mode, the MIPS computes the vector internally.  */
-                for (vector = 0; vector < 8; vector++) {
-                    if (pending & 1) {
+                for (vector = 7; vector > 0; vector--) {
+                    if (pending & (1 << vector)) {
                         /* Found it.  */
                         break;
                     }
-                    pending >>= 1;
                 }
             } else {
                 /* For VEIC mode, the external interrupt controller feeds the
-                   vector throught the CP0Cause IP lines.  */
+                   vector through the CP0Cause IP lines.  */
                 vector = pending;
             }
             offset = 0x200 + vector * spacing;
@@ -594,6 +596,9 @@ void do_interrupt (CPUState *env)
     case EXCP_THREAD:
         cause = 25;
         goto set_EPC;
+    case EXCP_DSPDIS:
+        cause = 26;
+        goto set_EPC;
     case EXCP_CACHE:
         cause = 30;
         if (env->CP0_Status & (1 << CP0St_BEV)) {
@@ -640,7 +645,7 @@ void do_interrupt (CPUState *env)
 }
 
 #if !defined(CONFIG_USER_ONLY)
-void r4k_invalidate_tlb (CPUState *env, int idx, int use_extra)
+void r4k_invalidate_tlb (CPUMIPSState *env, int idx, int use_extra)
 {
     r4k_tlb_t *tlb;
     target_ulong addr;