Diff for /qemu/target-ppc/translate_init.c between versions 1.1.1.10 and 1.1.1.11

version 1.1.1.10, 2018/04/24 19:02:38 version 1.1.1.11, 2018/04/24 19:30:53
Line 24 Line 24
   
 #include "dis-asm.h"  #include "dis-asm.h"
 #include "gdbstub.h"  #include "gdbstub.h"
   #include <kvm.h>
   #include "kvm_ppc.h"
   
 //#define PPC_DUMP_CPU  //#define PPC_DUMP_CPU
 //#define PPC_DEBUG_SPR  //#define PPC_DEBUG_SPR
Line 32 Line 34
 #define TODO_USER_ONLY 1  #define TODO_USER_ONLY 1
 #endif  #endif
   
 struct ppc_def_t {  
     const char *name;  
     uint32_t pvr;  
     uint32_t svr;  
     uint64_t insns_flags;  
     uint64_t insns_flags2;  
     uint64_t msr_mask;  
     powerpc_mmu_t   mmu_model;  
     powerpc_excp_t  excp_model;  
     powerpc_input_t bus_model;  
     uint32_t flags;  
     int bfd_mach;  
     void (*init_proc)(CPUPPCState *env);  
     int  (*check_pow)(CPUPPCState *env);  
 };  
   
 /* For user-mode emulation, we don't emulate any IRQ controller */  /* For user-mode emulation, we don't emulate any IRQ controller */
 #if defined(CONFIG_USER_ONLY)  #if defined(CONFIG_USER_ONLY)
 #define PPC_IRQ_INIT_FN(name)                                                 \  #define PPC_IRQ_INIT_FN(name)                                                 \
Line 129  static void spr_write_lr (void *opaque,  Line 115  static void spr_write_lr (void *opaque, 
     tcg_gen_mov_tl(cpu_lr, cpu_gpr[gprn]);      tcg_gen_mov_tl(cpu_lr, cpu_gpr[gprn]);
 }  }
   
   /* CFAR */
   #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
   static void spr_read_cfar (void *opaque, int gprn, int sprn)
   {
       tcg_gen_mov_tl(cpu_gpr[gprn], cpu_cfar);
   }
   
   static void spr_write_cfar (void *opaque, int sprn, int gprn)
   {
       tcg_gen_mov_tl(cpu_cfar, cpu_gpr[gprn]);
   }
   #endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */
   
 /* CTR */  /* CTR */
 static void spr_read_ctr (void *opaque, int gprn, int sprn)  static void spr_read_ctr (void *opaque, int gprn, int sprn)
 {  {
Line 3253  static void init_proc_401 (CPUPPCState * Line 3252  static void init_proc_401 (CPUPPCState *
     env->icache_line_size = 32;      env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */      /* Allocate hardware IRQ controller */
     ppc40x_irq_init(env);      ppc40x_irq_init(env);
   
       SET_FIT_PERIOD(12, 16, 20, 24);
       SET_WDT_PERIOD(16, 20, 24, 28);
 }  }
   
 /* PowerPC 401x2                                                             */  /* PowerPC 401x2                                                             */
Line 3291  static void init_proc_401x2 (CPUPPCState Line 3293  static void init_proc_401x2 (CPUPPCState
     env->icache_line_size = 32;      env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */      /* Allocate hardware IRQ controller */
     ppc40x_irq_init(env);      ppc40x_irq_init(env);
   
       SET_FIT_PERIOD(12, 16, 20, 24);
       SET_WDT_PERIOD(16, 20, 24, 28);
 }  }
   
 /* PowerPC 401x3                                                             */  /* PowerPC 401x3                                                             */
Line 3324  static void init_proc_401x3 (CPUPPCState Line 3329  static void init_proc_401x3 (CPUPPCState
     env->icache_line_size = 32;      env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */      /* Allocate hardware IRQ controller */
     ppc40x_irq_init(env);      ppc40x_irq_init(env);
   
       SET_FIT_PERIOD(12, 16, 20, 24);
       SET_WDT_PERIOD(16, 20, 24, 28);
 }  }
   
 /* IOP480                                                                    */  /* IOP480                                                                    */
Line 3362  static void init_proc_IOP480 (CPUPPCStat Line 3370  static void init_proc_IOP480 (CPUPPCStat
     env->icache_line_size = 32;      env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */      /* Allocate hardware IRQ controller */
     ppc40x_irq_init(env);      ppc40x_irq_init(env);
   
       SET_FIT_PERIOD(8, 12, 16, 20);
       SET_WDT_PERIOD(16, 20, 24, 28);
 }  }
   
 /* PowerPC 403                                                               */  /* PowerPC 403                                                               */
Line 3392  static void init_proc_403 (CPUPPCState * Line 3403  static void init_proc_403 (CPUPPCState *
     env->icache_line_size = 32;      env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */      /* Allocate hardware IRQ controller */
     ppc40x_irq_init(env);      ppc40x_irq_init(env);
   
       SET_FIT_PERIOD(8, 12, 16, 20);
       SET_WDT_PERIOD(16, 20, 24, 28);
 }  }
   
 /* PowerPC 403 GCX                                                           */  /* PowerPC 403 GCX                                                           */
Line 3442  static void init_proc_403GCX (CPUPPCStat Line 3456  static void init_proc_403GCX (CPUPPCStat
     env->icache_line_size = 32;      env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */      /* Allocate hardware IRQ controller */
     ppc40x_irq_init(env);      ppc40x_irq_init(env);
   
       SET_FIT_PERIOD(8, 12, 16, 20);
       SET_WDT_PERIOD(16, 20, 24, 28);
 }  }
   
 /* PowerPC 405                                                               */  /* PowerPC 405                                                               */
Line 3491  static void init_proc_405 (CPUPPCState * Line 3508  static void init_proc_405 (CPUPPCState *
     env->icache_line_size = 32;      env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */      /* Allocate hardware IRQ controller */
     ppc40x_irq_init(env);      ppc40x_irq_init(env);
   
       SET_FIT_PERIOD(8, 12, 16, 20);
       SET_WDT_PERIOD(16, 20, 24, 28);
 }  }
   
 /* PowerPC 440 EP                                                            */  /* PowerPC 440 EP                                                            */
Line 3573  static void init_proc_440EP (CPUPPCState Line 3593  static void init_proc_440EP (CPUPPCState
     env->dcache_line_size = 32;      env->dcache_line_size = 32;
     env->icache_line_size = 32;      env->icache_line_size = 32;
     /* XXX: TODO: allocate internal IRQ controller */      /* XXX: TODO: allocate internal IRQ controller */
   
       SET_FIT_PERIOD(12, 16, 20, 24);
       SET_WDT_PERIOD(20, 24, 28, 32);
 }  }
   
 /* PowerPC 440 GP                                                            */  /* PowerPC 440 GP                                                            */
Line 3637  static void init_proc_440GP (CPUPPCState Line 3660  static void init_proc_440GP (CPUPPCState
     env->dcache_line_size = 32;      env->dcache_line_size = 32;
     env->icache_line_size = 32;      env->icache_line_size = 32;
     /* XXX: TODO: allocate internal IRQ controller */      /* XXX: TODO: allocate internal IRQ controller */
   
       SET_FIT_PERIOD(12, 16, 20, 24);
       SET_WDT_PERIOD(20, 24, 28, 32);
 }  }
   
 /* PowerPC 440x4                                                             */  /* PowerPC 440x4                                                             */
Line 3701  static void init_proc_440x4 (CPUPPCState Line 3727  static void init_proc_440x4 (CPUPPCState
     env->dcache_line_size = 32;      env->dcache_line_size = 32;
     env->icache_line_size = 32;      env->icache_line_size = 32;
     /* XXX: TODO: allocate internal IRQ controller */      /* XXX: TODO: allocate internal IRQ controller */
   
       SET_FIT_PERIOD(12, 16, 20, 24);
       SET_WDT_PERIOD(20, 24, 28, 32);
 }  }
   
 /* PowerPC 440x5                                                             */  /* PowerPC 440x5                                                             */
Line 3782  static void init_proc_440x5 (CPUPPCState Line 3811  static void init_proc_440x5 (CPUPPCState
     env->dcache_line_size = 32;      env->dcache_line_size = 32;
     env->icache_line_size = 32;      env->icache_line_size = 32;
     ppc40x_irq_init(env);      ppc40x_irq_init(env);
   
       SET_FIT_PERIOD(12, 16, 20, 24);
       SET_WDT_PERIOD(20, 24, 28, 32);
 }  }
   
 /* PowerPC 460 (guessed)                                                     */  /* PowerPC 460 (guessed)                                                     */
Line 3870  static void init_proc_460 (CPUPPCState * Line 3902  static void init_proc_460 (CPUPPCState *
     env->dcache_line_size = 32;      env->dcache_line_size = 32;
     env->icache_line_size = 32;      env->icache_line_size = 32;
     /* XXX: TODO: allocate internal IRQ controller */      /* XXX: TODO: allocate internal IRQ controller */
   
       SET_FIT_PERIOD(12, 16, 20, 24);
       SET_WDT_PERIOD(20, 24, 28, 32);
 }  }
   
 /* PowerPC 460F (guessed)                                                    */  /* PowerPC 460F (guessed)                                                    */
Line 3961  static void init_proc_460F (CPUPPCState  Line 3996  static void init_proc_460F (CPUPPCState 
     env->dcache_line_size = 32;      env->dcache_line_size = 32;
     env->icache_line_size = 32;      env->icache_line_size = 32;
     /* XXX: TODO: allocate internal IRQ controller */      /* XXX: TODO: allocate internal IRQ controller */
   
       SET_FIT_PERIOD(12, 16, 20, 24);
       SET_WDT_PERIOD(20, 24, 28, 32);
 }  }
   
 /* Freescale 5xx cores (aka RCPU) */  /* Freescale 5xx cores (aka RCPU) */
Line 6481  static void init_proc_970MP (CPUPPCState Line 6519  static void init_proc_970MP (CPUPPCState
                               PPC_64B | PPC_ALTIVEC |                         \                                PPC_64B | PPC_ALTIVEC |                         \
                               PPC_SEGMENT_64B | PPC_SLBI |                    \                                PPC_SEGMENT_64B | PPC_SLBI |                    \
                               PPC_POPCNTB | PPC_POPCNTWD)                                PPC_POPCNTB | PPC_POPCNTWD)
 #define POWERPC_INSNS2_POWER7 (PPC_NONE)  #define POWERPC_INSNS2_POWER7 (PPC2_VSX | PPC2_DFP)
 #define POWERPC_MSRM_POWER7   (0x800000000204FF36ULL)  #define POWERPC_MSRM_POWER7   (0x800000000204FF36ULL)
 #define POWERPC_MMU_POWER7    (POWERPC_MMU_2_06)  #define POWERPC_MMU_POWER7    (POWERPC_MMU_2_06)
 #define POWERPC_EXCP_POWER7   (POWERPC_EXCP_POWER7)  #define POWERPC_EXCP_POWER7   (POWERPC_EXCP_POWER7)
Line 6489  static void init_proc_970MP (CPUPPCState Line 6527  static void init_proc_970MP (CPUPPCState
 #define POWERPC_BFDM_POWER7   (bfd_mach_ppc64)  #define POWERPC_BFDM_POWER7   (bfd_mach_ppc64)
 #define POWERPC_FLAG_POWER7   (POWERPC_FLAG_VRE | POWERPC_FLAG_SE |            \  #define POWERPC_FLAG_POWER7   (POWERPC_FLAG_VRE | POWERPC_FLAG_SE |            \
                               POWERPC_FLAG_BE | POWERPC_FLAG_PMM |            \                                POWERPC_FLAG_BE | POWERPC_FLAG_PMM |            \
                               POWERPC_FLAG_BUS_CLK)                                POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR)
 #define check_pow_POWER7    check_pow_nocheck  #define check_pow_POWER7    check_pow_nocheck
   
 static void init_proc_POWER7 (CPUPPCState *env)  static void init_proc_POWER7 (CPUPPCState *env)
Line 6508  static void init_proc_POWER7 (CPUPPCStat Line 6546  static void init_proc_POWER7 (CPUPPCStat
                  &spr_read_purr, SPR_NOACCESS,                   &spr_read_purr, SPR_NOACCESS,
                  &spr_read_purr, SPR_NOACCESS,                   &spr_read_purr, SPR_NOACCESS,
                  0x00000000);                   0x00000000);
       spr_register(env, SPR_CFAR, "SPR_CFAR",
                    SPR_NOACCESS, SPR_NOACCESS,
                    &spr_read_cfar, &spr_write_cfar,
                    0x00000000);
       spr_register(env, SPR_DSCR, "SPR_DSCR",
                    SPR_NOACCESS, SPR_NOACCESS,
                    &spr_read_generic, &spr_write_generic,
                    0x00000000);
 #endif /* !CONFIG_USER_ONLY */  #endif /* !CONFIG_USER_ONLY */
     /* Memory management */      /* Memory management */
     /* XXX : not implemented */      /* XXX : not implemented */
Line 7271  enum { Line 7317  enum {
     CPU_POWERPC_POWER6A            = 0x0F000002,      CPU_POWERPC_POWER6A            = 0x0F000002,
 #define CPU_POWERPC_POWER7           CPU_POWERPC_POWER7_v20  #define CPU_POWERPC_POWER7           CPU_POWERPC_POWER7_v20
     CPU_POWERPC_POWER7_v20         = 0x003F0200,      CPU_POWERPC_POWER7_v20         = 0x003F0200,
       CPU_POWERPC_POWER7_v21         = 0x003F0201,
       CPU_POWERPC_POWER7_v23         = 0x003F0203,
     CPU_POWERPC_970                = 0x00390202,      CPU_POWERPC_970                = 0x00390202,
 #define CPU_POWERPC_970FX            CPU_POWERPC_970FX_v31  #define CPU_POWERPC_970FX            CPU_POWERPC_970FX_v31
     CPU_POWERPC_970FX_v10          = 0x00391100,      CPU_POWERPC_970FX_v10          = 0x00391100,
Line 9077  static const ppc_def_t ppc_defs[] = { Line 9125  static const ppc_def_t ppc_defs[] = {
     /* POWER7                                                                */      /* POWER7                                                                */
     POWERPC_DEF("POWER7",        CPU_POWERPC_POWER7,                 POWER7),      POWERPC_DEF("POWER7",        CPU_POWERPC_POWER7,                 POWER7),
     POWERPC_DEF("POWER7_v2.0",   CPU_POWERPC_POWER7_v20,             POWER7),      POWERPC_DEF("POWER7_v2.0",   CPU_POWERPC_POWER7_v20,             POWER7),
       POWERPC_DEF("POWER7_v2.1",   CPU_POWERPC_POWER7_v21,             POWER7),
       POWERPC_DEF("POWER7_v2.3",   CPU_POWERPC_POWER7_v23,             POWER7),
     /* PowerPC 970                                                           */      /* PowerPC 970                                                           */
     POWERPC_DEF("970",           CPU_POWERPC_970,                    970),      POWERPC_DEF("970",           CPU_POWERPC_970,                    970),
     /* PowerPC 970FX (G5)                                                    */      /* PowerPC 970FX (G5)                                                    */
Line 9327  static void init_ppc_proc (CPUPPCState * Line 9377  static void init_ppc_proc (CPUPPCState *
             nb_tlb *= 2;              nb_tlb *= 2;
         switch (env->tlb_type) {          switch (env->tlb_type) {
         case TLB_6XX:          case TLB_6XX:
             env->tlb.tlb6 = qemu_mallocz(nb_tlb * sizeof(ppc6xx_tlb_t));              env->tlb.tlb6 = g_malloc0(nb_tlb * sizeof(ppc6xx_tlb_t));
             break;              break;
         case TLB_EMB:          case TLB_EMB:
             env->tlb.tlbe = qemu_mallocz(nb_tlb * sizeof(ppcemb_tlb_t));              env->tlb.tlbe = g_malloc0(nb_tlb * sizeof(ppcemb_tlb_t));
             break;              break;
         case TLB_MAS:          case TLB_MAS:
             env->tlb.tlbm = qemu_mallocz(nb_tlb * sizeof(ppcmas_tlb_t));              env->tlb.tlbm = g_malloc0(nb_tlb * sizeof(ppcmas_tlb_t));
             break;              break;
         }          }
         /* Pre-compute some useful values */          /* Pre-compute some useful values */
Line 9679  static int gdb_get_float_reg(CPUState *e Line 9729  static int gdb_get_float_reg(CPUState *e
         return 8;          return 8;
     }      }
     if (n == 32) {      if (n == 32) {
         /* FPSCR not implemented  */          stl_p(mem_buf, env->fpscr);
         memset(mem_buf, 0, 4);  
         return 4;          return 4;
     }      }
     return 0;      return 0;
Line 9797  int cpu_ppc_register_internal (CPUPPCSta Line 9846  int cpu_ppc_register_internal (CPUPPCSta
     env->bus_model = def->bus_model;      env->bus_model = def->bus_model;
     env->insns_flags = def->insns_flags;      env->insns_flags = def->insns_flags;
     env->insns_flags2 = def->insns_flags2;      env->insns_flags2 = def->insns_flags2;
       if (!kvm_enabled()) {
           /* TCG doesn't (yet) emulate some groups of instructions that
            * are implemented on some otherwise supported CPUs (e.g. VSX
            * and decimal floating point instructions on POWER7).  We
            * remove unsupported instruction groups from the cpu state's
            * instruction masks and hope the guest can cope.  For at
            * least the pseries machine, the unavailability of these
            * instructions can be advertise to the guest via the device
            * tree.
            *
            * FIXME: we should have a similar masking for CPU features
            * not accessible under KVM, but so far, there aren't any of
            * those. */
           env->insns_flags &= PPC_TCG_INSNS;
           env->insns_flags2 &= PPC_TCG_INSNS2;
       }
     env->flags = def->flags;      env->flags = def->flags;
     env->bfd_mach = def->bfd_mach;      env->bfd_mach = def->bfd_mach;
     env->check_pow = def->check_pow;      env->check_pow = def->check_pow;
Line 9982  int cpu_ppc_register_internal (CPUPPCSta Line 10047  int cpu_ppc_register_internal (CPUPPCSta
     return 0;      return 0;
 }  }
   
 static const ppc_def_t *ppc_find_by_pvr (uint32_t pvr)  static bool ppc_cpu_usable(const ppc_def_t *def)
 {  {
     const ppc_def_t *ret;  #if defined(TARGET_PPCEMB)
     uint32_t pvr_rev;      /* When using the ppcemb target, we only support 440 style cores */
     int i, best, match, best_match, max;      if (def->mmu_model != POWERPC_MMU_BOOKE) {
           return false;
       }
   #endif
   
     ret = NULL;      return true;
     max = ARRAY_SIZE(ppc_defs);  }
     best = -1;  
     pvr_rev = pvr & 0xFFFF;  const ppc_def_t *ppc_find_by_pvr(uint32_t pvr)
     /* We want all specified bits to match */  {
     best_match = 32 - ctz32(pvr_rev);      int i;
     for (i = 0; i < max; i++) {  
         /* We check that the 16 higher bits are the same to ensure the CPU      for (i = 0; i < ARRAY_SIZE(ppc_defs); i++) {
          * model will be the choosen one.          if (!ppc_cpu_usable(&ppc_defs[i])) {
          */              continue;
         if (((pvr ^ ppc_defs[i].pvr) >> 16) == 0) {          }
             /* We want as much as possible of the low-level 16 bits  
              * to be the same but we allow inexact matches.          /* If we have an exact match, we're done */
              */          if (pvr == ppc_defs[i].pvr) {
             match = clz32(pvr_rev ^ (ppc_defs[i].pvr & 0xFFFF));              return &ppc_defs[i];
             /* We check '>=' instead of '>' because the PPC_defs table  
              * is ordered by increasing revision.  
              * Then, we will match the higher revision compatible  
              * with the requested PVR  
              */  
             if (match >= best_match) {  
                 best = i;  
                 best_match = match;  
             }  
         }          }
     }      }
     if (best != -1)  
         ret = &ppc_defs[best];  
   
     return ret;      return NULL;
 }  }
   
 #include <ctype.h>  #include <ctype.h>
Line 10028  const ppc_def_t *cpu_ppc_find_by_name (c Line 10085  const ppc_def_t *cpu_ppc_find_by_name (c
     const char *p;      const char *p;
     int i, max, len;      int i, max, len;
   
       if (kvm_enabled() && (strcasecmp(name, "host") == 0)) {
           return kvmppc_host_cpu_def();
       }
   
     /* Check if the given name is a PVR */      /* Check if the given name is a PVR */
     len = strlen(name);      len = strlen(name);
     if (len == 10 && name[0] == '0' && name[1] == 'x') {      if (len == 10 && name[0] == '0' && name[1] == 'x') {
Line 10046  const ppc_def_t *cpu_ppc_find_by_name (c Line 10107  const ppc_def_t *cpu_ppc_find_by_name (c
     ret = NULL;      ret = NULL;
     max = ARRAY_SIZE(ppc_defs);      max = ARRAY_SIZE(ppc_defs);
     for (i = 0; i < max; i++) {      for (i = 0; i < max; i++) {
           if (!ppc_cpu_usable(&ppc_defs[i])) {
               continue;
           }
   
         if (strcasecmp(name, ppc_defs[i].name) == 0) {          if (strcasecmp(name, ppc_defs[i].name) == 0) {
             ret = &ppc_defs[i];              ret = &ppc_defs[i];
             break;              break;
Line 10061  void ppc_cpu_list (FILE *f, fprintf_func Line 10126  void ppc_cpu_list (FILE *f, fprintf_func
   
     max = ARRAY_SIZE(ppc_defs);      max = ARRAY_SIZE(ppc_defs);
     for (i = 0; i < max; i++) {      for (i = 0; i < max; i++) {
           if (!ppc_cpu_usable(&ppc_defs[i])) {
               continue;
           }
   
         (*cpu_fprintf)(f, "PowerPC %-16s PVR %08x\n",          (*cpu_fprintf)(f, "PowerPC %-16s PVR %08x\n",
                        ppc_defs[i].name, ppc_defs[i].pvr);                         ppc_defs[i].name, ppc_defs[i].pvr);
     }      }

Removed from v.1.1.1.10  
changed lines
  Added in v.1.1.1.11


unix.superglobalmegacorp.com