diff mbox

[5/9] target-ppc: Add POWER8 SPRs

Message ID 1400653228-31540-6-git-send-email-aik@ozlabs.ru
State New
Headers show

Commit Message

Alexey Kardashevskiy May 21, 2014, 6:20 a.m. UTC
This adds helper which adds TAR/BESCRS/BESCRSU/BESCRR/BESCRRU/
EBBHR/EBBRR/BESCR/TFHAR/TFIAR/TEXASR/TEXASRU SPRs.

This adds MMCR2/FSCR/MMCRS SPRs.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
 target-ppc/cpu.h            |  15 ++++++
 target-ppc/translate_init.c | 123 ++++++++++++++++++++++++++++++++++----------
 2 files changed, 112 insertions(+), 26 deletions(-)

Comments

Alexander Graf May 21, 2014, 10:47 a.m. UTC | #1
On 21.05.14 08:20, Alexey Kardashevskiy wrote:
> This adds helper which adds TAR/BESCRS/BESCRSU/BESCRR/BESCRRU/
> EBBHR/EBBRR/BESCR/TFHAR/TFIAR/TEXASR/TEXASRU SPRs.
>
> This adds MMCR2/FSCR/MMCRS SPRs.
>
> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
> ---
>   target-ppc/cpu.h            |  15 ++++++
>   target-ppc/translate_init.c | 123 ++++++++++++++++++++++++++++++++++----------
>   2 files changed, 112 insertions(+), 26 deletions(-)
>
> diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
> index 262cf0f..72ed763 100644
> --- a/target-ppc/cpu.h
> +++ b/target-ppc/cpu.h
> @@ -1258,6 +1258,10 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>   #define SPR_MPC_EIE           (0x050)
>   #define SPR_MPC_EID           (0x051)
>   #define SPR_MPC_NRI           (0x052)
> +#define SPR_TFHAR             (0x080)
> +#define SPR_TFIAR             (0x081)
> +#define SPR_TEXASR            (0x082)
> +#define SPR_TEXASRU           (0x083)
>   #define SPR_UCTRL             (0x088)
>   #define SPR_MPC_CMPA          (0x090)
>   #define SPR_MPC_CMPB          (0x091)
> @@ -1270,6 +1274,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>   #define SPR_CTRL              (0x098)
>   #define SPR_MPC_CMPE          (0x098)
>   #define SPR_MPC_CMPF          (0x099)
> +#define SPR_FSCR              (0x099)
>   #define SPR_MPC_CMPG          (0x09A)
>   #define SPR_MPC_CMPH          (0x09B)
>   #define SPR_MPC_LCTRL1        (0x09C)
> @@ -1461,6 +1466,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>   #define SPR_MPC_MI_CTR        (0x300)
>   #define SPR_PERF1             (0x301)
>   #define SPR_RCPU_MI_RBA1      (0x301)
> +#define SPR_POWER_UMMCR2      (0x301)
>   #define SPR_PERF2             (0x302)
>   #define SPR_RCPU_MI_RBA2      (0x302)
>   #define SPR_MPC_MI_AP         (0x302)
> @@ -1500,6 +1506,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>   #define SPR_MPC_MD_TW         (0x30F)
>   #define SPR_UPERF0            (0x310)
>   #define SPR_UPERF1            (0x311)
> +#define SPR_POWER_MMCR2       (0x311)
>   #define SPR_UPERF2            (0x312)
>   #define SPR_MMCRA             (0x312)
>   #define SPR_UPERF3            (0x313)
> @@ -1519,11 +1526,18 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>   #define SPR_UPERFF            (0x31F)
>   #define SPR_RCPU_MI_RA0       (0x320)
>   #define SPR_MPC_MI_DBCAM      (0x320)
> +#define SPR_BESCRS            (0x320)
>   #define SPR_RCPU_MI_RA1       (0x321)
>   #define SPR_MPC_MI_DBRAM0     (0x321)
> +#define SPR_BESCRSU           (0x321)
>   #define SPR_RCPU_MI_RA2       (0x322)
>   #define SPR_MPC_MI_DBRAM1     (0x322)
> +#define SPR_BESCRR            (0x322)
>   #define SPR_RCPU_MI_RA3       (0x323)
> +#define SPR_BESCRRU           (0x323)
> +#define SPR_EBBHR             (0x324)
> +#define SPR_EBBRR             (0x325)
> +#define SPR_BESCR             (0x326)
>   #define SPR_RCPU_L2U_RA0      (0x328)
>   #define SPR_MPC_MD_DBCAM      (0x328)
>   #define SPR_RCPU_L2U_RA1      (0x329)
> @@ -1542,6 +1556,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>   #define SPR_440_ITV3          (0x377)
>   #define SPR_440_CCR1          (0x378)
>   #define SPR_DCRIPR            (0x37B)
> +#define SPR_MMCRS             (0x37E)
>   #define SPR_PPR               (0x380)
>   #define SPR_750_GQR0          (0x390)
>   #define SPR_440_DNV0          (0x390)
> diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
> index 3c37e93..d23fcc6 100644
> --- a/target-ppc/translate_init.c
> +++ b/target-ppc/translate_init.c
> @@ -7951,37 +7951,108 @@ POWERPC_FAMILY(POWER7P)(ObjectClass *oc, void *data)
>       pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
>   }
>   
> -static void init_proc_POWER8(CPUPPCState *env)
> +static void get_spr_power8_branch_control(CPUPPCState *env)
>   {
> -    gen_spr_ne_601(env);
> -    gen_spr_7xx(env);
> -    /* Time base */
> -    gen_tbl(env);
> -    gen_spr_book3s_ids(env);
> -    gen_spr_book3s_common(env);
> -    gen_spr_amr(env);
> -    gen_spr_book3s_vr(env);
> -    gen_spr_book3s_lpar(env);
> -    gen_spr_book3s_purr(env);
> -    gen_spr_book3s_debug(env);
> -    gen_spr_book3s_pmu(env);
> -#if !defined(CONFIG_USER_ONLY)
> -    env->slb_nr = 32;
> -#endif /* !CONFIG_USER_ONLY */
> -    init_excp_POWER7(env);
> -    env->dcache_line_size = 128;
> -    env->icache_line_size = 128;
> -
> -    /* Allocate hardware IRQ controller */
> -    ppcPOWER7_irq_init(env);
> -    /* Can't find information on what this should be on reset.  This
> -     * value is the one used by 74xx processors. */
> -    vscr_init(env, 0x00010000);
> -
>       spr_register(env, SPR_TAR, "TAR",
>                    &spr_read_generic, &spr_write_generic,
>                    &spr_read_generic, &spr_write_generic,
>                    0x00000000);
> +
> +    spr_register(env, SPR_BESCRS, "BESCRS",
> +                 SPR_NOACCESS, SPR_NOACCESS,
> +                 &spr_read_generic, &spr_write_generic,

Please introduce a special helper for these that checks whether FSCR.EBB 
== 1 and injects a facility interrupt if not.


Alex
Tom Musta May 21, 2014, 6:08 p.m. UTC | #2
On 5/21/2014 1:20 AM, Alexey Kardashevskiy wrote:
> This adds helper which adds TAR/BESCRS/BESCRSU/BESCRR/BESCRRU/
> EBBHR/EBBRR/BESCR/TFHAR/TFIAR/TEXASR/TEXASRU SPRs.
> 
> This adds MMCR2/FSCR/MMCRS SPRs.
> 
> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
> ---
>  target-ppc/cpu.h            |  15 ++++++
>  target-ppc/translate_init.c | 123 ++++++++++++++++++++++++++++++++++----------
>  2 files changed, 112 insertions(+), 26 deletions(-)
> 
> diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
> index 262cf0f..72ed763 100644
> --- a/target-ppc/cpu.h
> +++ b/target-ppc/cpu.h
> @@ -1258,6 +1258,10 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>  #define SPR_MPC_EIE           (0x050)
>  #define SPR_MPC_EID           (0x051)
>  #define SPR_MPC_NRI           (0x052)
> +#define SPR_TFHAR             (0x080)
> +#define SPR_TFIAR             (0x081)
> +#define SPR_TEXASR            (0x082)
> +#define SPR_TEXASRU           (0x083)
>  #define SPR_UCTRL             (0x088)
>  #define SPR_MPC_CMPA          (0x090)
>  #define SPR_MPC_CMPB          (0x091)
> @@ -1270,6 +1274,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>  #define SPR_CTRL              (0x098)
>  #define SPR_MPC_CMPE          (0x098)
>  #define SPR_MPC_CMPF          (0x099)
> +#define SPR_FSCR              (0x099)
>  #define SPR_MPC_CMPG          (0x09A)
>  #define SPR_MPC_CMPH          (0x09B)
>  #define SPR_MPC_LCTRL1        (0x09C)
> @@ -1461,6 +1466,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>  #define SPR_MPC_MI_CTR        (0x300)
>  #define SPR_PERF1             (0x301)
>  #define SPR_RCPU_MI_RBA1      (0x301)
> +#define SPR_POWER_UMMCR2      (0x301)
>  #define SPR_PERF2             (0x302)
>  #define SPR_RCPU_MI_RBA2      (0x302)
>  #define SPR_MPC_MI_AP         (0x302)
> @@ -1500,6 +1506,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>  #define SPR_MPC_MD_TW         (0x30F)
>  #define SPR_UPERF0            (0x310)
>  #define SPR_UPERF1            (0x311)
> +#define SPR_POWER_MMCR2       (0x311)
>  #define SPR_UPERF2            (0x312)
>  #define SPR_MMCRA             (0x312)
>  #define SPR_UPERF3            (0x313)
> @@ -1519,11 +1526,18 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>  #define SPR_UPERFF            (0x31F)
>  #define SPR_RCPU_MI_RA0       (0x320)
>  #define SPR_MPC_MI_DBCAM      (0x320)
> +#define SPR_BESCRS            (0x320)
>  #define SPR_RCPU_MI_RA1       (0x321)
>  #define SPR_MPC_MI_DBRAM0     (0x321)
> +#define SPR_BESCRSU           (0x321)
>  #define SPR_RCPU_MI_RA2       (0x322)
>  #define SPR_MPC_MI_DBRAM1     (0x322)
> +#define SPR_BESCRR            (0x322)
>  #define SPR_RCPU_MI_RA3       (0x323)
> +#define SPR_BESCRRU           (0x323)
> +#define SPR_EBBHR             (0x324)
> +#define SPR_EBBRR             (0x325)
> +#define SPR_BESCR             (0x326)
>  #define SPR_RCPU_L2U_RA0      (0x328)
>  #define SPR_MPC_MD_DBCAM      (0x328)
>  #define SPR_RCPU_L2U_RA1      (0x329)
> @@ -1542,6 +1556,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>  #define SPR_440_ITV3          (0x377)
>  #define SPR_440_CCR1          (0x378)
>  #define SPR_DCRIPR            (0x37B)
> +#define SPR_MMCRS             (0x37E)
>  #define SPR_PPR               (0x380)
>  #define SPR_750_GQR0          (0x390)
>  #define SPR_440_DNV0          (0x390)
> diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
> index 3c37e93..d23fcc6 100644
> --- a/target-ppc/translate_init.c
> +++ b/target-ppc/translate_init.c
> @@ -7951,37 +7951,108 @@ POWERPC_FAMILY(POWER7P)(ObjectClass *oc, void *data)
>      pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
>  }
>  
> -static void init_proc_POWER8(CPUPPCState *env)
> +static void get_spr_power8_branch_control(CPUPPCState *env)
>  {
> -    gen_spr_ne_601(env);
> -    gen_spr_7xx(env);
> -    /* Time base */
> -    gen_tbl(env);
> -    gen_spr_book3s_ids(env);
> -    gen_spr_book3s_common(env);
> -    gen_spr_amr(env);
> -    gen_spr_book3s_vr(env);
> -    gen_spr_book3s_lpar(env);
> -    gen_spr_book3s_purr(env);
> -    gen_spr_book3s_debug(env);
> -    gen_spr_book3s_pmu(env);
> -#if !defined(CONFIG_USER_ONLY)
> -    env->slb_nr = 32;
> -#endif /* !CONFIG_USER_ONLY */
> -    init_excp_POWER7(env);
> -    env->dcache_line_size = 128;
> -    env->icache_line_size = 128;
> -
> -    /* Allocate hardware IRQ controller */
> -    ppcPOWER7_irq_init(env);
> -    /* Can't find information on what this should be on reset.  This
> -     * value is the one used by 74xx processors. */
> -    vscr_init(env, 0x00010000);
> -
>      spr_register(env, SPR_TAR, "TAR",
>                   &spr_read_generic, &spr_write_generic,
>                   &spr_read_generic, &spr_write_generic,
>                   0x00000000);
> +
> +    spr_register(env, SPR_BESCRS, "BESCRS",
> +                 SPR_NOACCESS, SPR_NOACCESS,
> +                 &spr_read_generic, &spr_write_generic,
> +                 0x00000000);
> +    spr_register(env, SPR_BESCRSU, "BESCRSU",
> +                 SPR_NOACCESS, SPR_NOACCESS,
> +                 &spr_read_generic, &spr_write_generic,
> +                 0x00000000);
> +    spr_register(env, SPR_BESCRR, "BESCRR",
> +                 SPR_NOACCESS, SPR_NOACCESS,
> +                 &spr_read_generic, &spr_write_generic,
> +                 0x00000000);
> +    spr_register(env, SPR_BESCRRU, "BESCRRU",
> +                 SPR_NOACCESS, SPR_NOACCESS,
> +                 &spr_read_generic, &spr_write_generic,
> +                 0x00000000);
> +    spr_register_kvm(env, SPR_EBBHR, "EBBHR",
> +                     SPR_NOACCESS, SPR_NOACCESS,
> +                     &spr_read_generic, &spr_write_generic,
> +                     KVM_REG_PPC_EBBHR, 0x00000000);
> +    spr_register_kvm(env, SPR_EBBRR, "EBBRR",
> +                     SPR_NOACCESS, SPR_NOACCESS,
> +                     &spr_read_generic, &spr_write_generic,
> +                     KVM_REG_PPC_EBBRR, 0x00000000);
> +    spr_register_kvm(env, SPR_BESCR, "BESCR",
> +                     SPR_NOACCESS, SPR_NOACCESS,
> +                     &spr_read_generic, &spr_write_generic,
> +                     KVM_REG_PPC_BESCR, 0x00000000);
> +}

These are all user-mode accessible, no?

> +
> +static void get_spr_power8_tm(CPUPPCState *env)
> +{
> +    spr_register_kvm(env, SPR_TFHAR, "TFHAR",
> +                     SPR_NOACCESS, SPR_NOACCESS,
> +                     &spr_read_generic, &spr_write_generic,
> +                     KVM_REG_PPC_TFHAR, 0x00000000);
> +    spr_register_kvm(env, SPR_TFIAR, "TFIAR",
> +                     SPR_NOACCESS, SPR_NOACCESS,
> +                     &spr_read_generic, &spr_write_generic,
> +                     KVM_REG_PPC_TFIAR, 0x00000000);
> +    spr_register_kvm(env, SPR_TEXASR, "TEXASR",
> +                     SPR_NOACCESS, SPR_NOACCESS,
> +                     &spr_read_generic, &spr_write_generic,
> +                     KVM_REG_PPC_TEXASR, 0x00000000);
> +    spr_register(env, SPR_TEXASRU, "TEXASRU",
> +                 SPR_NOACCESS, SPR_NOACCESS,
> +                 &spr_read_generic, &spr_write_generic,
> +                 0x00000000);
> +}

Same comment.

Also, the xxxU SPRs numbers refer to the upper half of 64-bit SPRs.  These are necessary
to support access on 32-bit implementations.  It seems like some special spr access routines
are required to support this.

> +
> +static void init_proc_POWER8(CPUPPCState *env)
> +{
> +    gen_spr_ne_601(env);
> +    gen_spr_7xx(env);
> +    /* Time base */
> +    gen_tbl(env);
> +    gen_spr_book3s_ids(env);
> +    gen_spr_book3s_common(env);
> +    gen_spr_amr(env);
> +    gen_spr_book3s_vr(env);
> +    gen_spr_book3s_lpar(env);
> +    gen_spr_book3s_purr(env);
> +    gen_spr_book3s_debug(env);
> +    gen_spr_book3s_pmu(env);
> +#if !defined(CONFIG_USER_ONLY)
> +    env->slb_nr = 32;
> +#endif /* !CONFIG_USER_ONLY */
> +    init_excp_POWER7(env);
> +    env->dcache_line_size = 128;
> +    env->icache_line_size = 128;
> +
> +    /* Allocate hardware IRQ controller */
> +    ppcPOWER7_irq_init(env);
> +    /* Can't find information on what this should be on reset.  This
> +     * value is the one used by 74xx processors. */
> +    vscr_init(env, 0x00010000);
> +
> +    get_spr_power8_branch_control(env);
> +    get_spr_power8_tm(env);
> +    spr_register(env, SPR_POWER_MMCR2, "MMCR2",
> +                 &spr_read_generic, &spr_write_generic,
> +                 &spr_read_generic, &spr_write_generic,
> +                 0x00000000);
> +    spr_register_kvm(env, SPR_POWER_UMMCR2, "UMMCR2",
> +                     SPR_NOACCESS, SPR_NOACCESS,
> +                     &spr_read_generic, &spr_write_generic,
> +                     KVM_REG_PPC_MMCR2, 0x00000000);
> +    spr_register_kvm(env, SPR_FSCR, "FSCR",
> +                     SPR_NOACCESS, SPR_NOACCESS,
> +                     &spr_read_generic, &spr_write_generic,
> +                     KVM_REG_PPC_FSCR, 0x00000000);
> +    spr_register_kvm(env, SPR_MMCRS, "MMCRS",
> +                     SPR_NOACCESS, SPR_NOACCESS,
> +                     &spr_read_generic, &spr_write_generic,
> +                     KVM_REG_PPC_MMCRS, 0x00000000);
>  }
>  
>  POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
> 

Fix these also.
Alexey Kardashevskiy May 26, 2014, 3:45 p.m. UTC | #3
On 05/22/2014 04:08 AM, Tom Musta wrote:
> On 5/21/2014 1:20 AM, Alexey Kardashevskiy wrote:
>> This adds helper which adds TAR/BESCRS/BESCRSU/BESCRR/BESCRRU/
>> EBBHR/EBBRR/BESCR/TFHAR/TFIAR/TEXASR/TEXASRU SPRs.
>>
>> This adds MMCR2/FSCR/MMCRS SPRs.
>>
>> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
>> ---
>>  target-ppc/cpu.h            |  15 ++++++
>>  target-ppc/translate_init.c | 123 ++++++++++++++++++++++++++++++++++----------
>>  2 files changed, 112 insertions(+), 26 deletions(-)
>>
>> diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
>> index 262cf0f..72ed763 100644
>> --- a/target-ppc/cpu.h
>> +++ b/target-ppc/cpu.h
>> @@ -1258,6 +1258,10 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>  #define SPR_MPC_EIE           (0x050)
>>  #define SPR_MPC_EID           (0x051)
>>  #define SPR_MPC_NRI           (0x052)
>> +#define SPR_TFHAR             (0x080)
>> +#define SPR_TFIAR             (0x081)
>> +#define SPR_TEXASR            (0x082)
>> +#define SPR_TEXASRU           (0x083)
>>  #define SPR_UCTRL             (0x088)
>>  #define SPR_MPC_CMPA          (0x090)
>>  #define SPR_MPC_CMPB          (0x091)
>> @@ -1270,6 +1274,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>  #define SPR_CTRL              (0x098)
>>  #define SPR_MPC_CMPE          (0x098)
>>  #define SPR_MPC_CMPF          (0x099)
>> +#define SPR_FSCR              (0x099)
>>  #define SPR_MPC_CMPG          (0x09A)
>>  #define SPR_MPC_CMPH          (0x09B)
>>  #define SPR_MPC_LCTRL1        (0x09C)
>> @@ -1461,6 +1466,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>  #define SPR_MPC_MI_CTR        (0x300)
>>  #define SPR_PERF1             (0x301)
>>  #define SPR_RCPU_MI_RBA1      (0x301)
>> +#define SPR_POWER_UMMCR2      (0x301)
>>  #define SPR_PERF2             (0x302)
>>  #define SPR_RCPU_MI_RBA2      (0x302)
>>  #define SPR_MPC_MI_AP         (0x302)
>> @@ -1500,6 +1506,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>  #define SPR_MPC_MD_TW         (0x30F)
>>  #define SPR_UPERF0            (0x310)
>>  #define SPR_UPERF1            (0x311)
>> +#define SPR_POWER_MMCR2       (0x311)
>>  #define SPR_UPERF2            (0x312)
>>  #define SPR_MMCRA             (0x312)
>>  #define SPR_UPERF3            (0x313)
>> @@ -1519,11 +1526,18 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>  #define SPR_UPERFF            (0x31F)
>>  #define SPR_RCPU_MI_RA0       (0x320)
>>  #define SPR_MPC_MI_DBCAM      (0x320)
>> +#define SPR_BESCRS            (0x320)
>>  #define SPR_RCPU_MI_RA1       (0x321)
>>  #define SPR_MPC_MI_DBRAM0     (0x321)
>> +#define SPR_BESCRSU           (0x321)
>>  #define SPR_RCPU_MI_RA2       (0x322)
>>  #define SPR_MPC_MI_DBRAM1     (0x322)
>> +#define SPR_BESCRR            (0x322)
>>  #define SPR_RCPU_MI_RA3       (0x323)
>> +#define SPR_BESCRRU           (0x323)
>> +#define SPR_EBBHR             (0x324)
>> +#define SPR_EBBRR             (0x325)
>> +#define SPR_BESCR             (0x326)
>>  #define SPR_RCPU_L2U_RA0      (0x328)
>>  #define SPR_MPC_MD_DBCAM      (0x328)
>>  #define SPR_RCPU_L2U_RA1      (0x329)
>> @@ -1542,6 +1556,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>  #define SPR_440_ITV3          (0x377)
>>  #define SPR_440_CCR1          (0x378)
>>  #define SPR_DCRIPR            (0x37B)
>> +#define SPR_MMCRS             (0x37E)
>>  #define SPR_PPR               (0x380)
>>  #define SPR_750_GQR0          (0x390)
>>  #define SPR_440_DNV0          (0x390)
>> diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
>> index 3c37e93..d23fcc6 100644
>> --- a/target-ppc/translate_init.c
>> +++ b/target-ppc/translate_init.c
>> @@ -7951,37 +7951,108 @@ POWERPC_FAMILY(POWER7P)(ObjectClass *oc, void *data)
>>      pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
>>  }
>>  
>> -static void init_proc_POWER8(CPUPPCState *env)
>> +static void get_spr_power8_branch_control(CPUPPCState *env)
>>  {
>> -    gen_spr_ne_601(env);
>> -    gen_spr_7xx(env);
>> -    /* Time base */
>> -    gen_tbl(env);
>> -    gen_spr_book3s_ids(env);
>> -    gen_spr_book3s_common(env);
>> -    gen_spr_amr(env);
>> -    gen_spr_book3s_vr(env);
>> -    gen_spr_book3s_lpar(env);
>> -    gen_spr_book3s_purr(env);
>> -    gen_spr_book3s_debug(env);
>> -    gen_spr_book3s_pmu(env);
>> -#if !defined(CONFIG_USER_ONLY)
>> -    env->slb_nr = 32;
>> -#endif /* !CONFIG_USER_ONLY */
>> -    init_excp_POWER7(env);
>> -    env->dcache_line_size = 128;
>> -    env->icache_line_size = 128;
>> -
>> -    /* Allocate hardware IRQ controller */
>> -    ppcPOWER7_irq_init(env);
>> -    /* Can't find information on what this should be on reset.  This
>> -     * value is the one used by 74xx processors. */
>> -    vscr_init(env, 0x00010000);
>> -
>>      spr_register(env, SPR_TAR, "TAR",
>>                   &spr_read_generic, &spr_write_generic,
>>                   &spr_read_generic, &spr_write_generic,
>>                   0x00000000);
>> +
>> +    spr_register(env, SPR_BESCRS, "BESCRS",
>> +                 SPR_NOACCESS, SPR_NOACCESS,
>> +                 &spr_read_generic, &spr_write_generic,
>> +                 0x00000000);
>> +    spr_register(env, SPR_BESCRSU, "BESCRSU",
>> +                 SPR_NOACCESS, SPR_NOACCESS,
>> +                 &spr_read_generic, &spr_write_generic,
>> +                 0x00000000);
>> +    spr_register(env, SPR_BESCRR, "BESCRR",
>> +                 SPR_NOACCESS, SPR_NOACCESS,
>> +                 &spr_read_generic, &spr_write_generic,
>> +                 0x00000000);
>> +    spr_register(env, SPR_BESCRRU, "BESCRRU",
>> +                 SPR_NOACCESS, SPR_NOACCESS,
>> +                 &spr_read_generic, &spr_write_generic,
>> +                 0x00000000);
>> +    spr_register_kvm(env, SPR_EBBHR, "EBBHR",
>> +                     SPR_NOACCESS, SPR_NOACCESS,
>> +                     &spr_read_generic, &spr_write_generic,
>> +                     KVM_REG_PPC_EBBHR, 0x00000000);
>> +    spr_register_kvm(env, SPR_EBBRR, "EBBRR",
>> +                     SPR_NOACCESS, SPR_NOACCESS,
>> +                     &spr_read_generic, &spr_write_generic,
>> +                     KVM_REG_PPC_EBBRR, 0x00000000);
>> +    spr_register_kvm(env, SPR_BESCR, "BESCR",
>> +                     SPR_NOACCESS, SPR_NOACCESS,
>> +                     &spr_read_generic, &spr_write_generic,
>> +                     KVM_REG_PPC_BESCR, 0x00000000);
>> +}
> 
> These are all user-mode accessible, no?
> 
>> +
>> +static void get_spr_power8_tm(CPUPPCState *env)
>> +{
>> +    spr_register_kvm(env, SPR_TFHAR, "TFHAR",
>> +                     SPR_NOACCESS, SPR_NOACCESS,
>> +                     &spr_read_generic, &spr_write_generic,
>> +                     KVM_REG_PPC_TFHAR, 0x00000000);
>> +    spr_register_kvm(env, SPR_TFIAR, "TFIAR",
>> +                     SPR_NOACCESS, SPR_NOACCESS,
>> +                     &spr_read_generic, &spr_write_generic,
>> +                     KVM_REG_PPC_TFIAR, 0x00000000);
>> +    spr_register_kvm(env, SPR_TEXASR, "TEXASR",
>> +                     SPR_NOACCESS, SPR_NOACCESS,
>> +                     &spr_read_generic, &spr_write_generic,
>> +                     KVM_REG_PPC_TEXASR, 0x00000000);
>> +    spr_register(env, SPR_TEXASRU, "TEXASRU",
>> +                 SPR_NOACCESS, SPR_NOACCESS,
>> +                 &spr_read_generic, &spr_write_generic,
>> +                 0x00000000);
>> +}
> 
> Same comment.
> 
> Also, the xxxU SPRs numbers refer to the upper half of 64-bit SPRs.  These are necessary
> to support access on 32-bit implementations.  It seems like some special spr access routines
> are required to support this.


I am not familiar with TCG (yet)... Something like below? This uses the
fact that SPRs go consequently.


static void spr_read_upper32(void *opaque, int gprn, int sprn)
{
    TCGv spr64 = tcg_temp_new();

    gen_load_spr(spr64, sprn - 1);
    tcg_gen_shr_i64(spr64, spr64, 32);
    tcg_gen_ext32u_tl(cpu_gpr[gprn], spr64);
    tcg_temp_free(spr64);
    spr_store_dump_spr(sprn);
}

static void spr_write_upper32(void *opaque, int sprn, int gprn)
{
    TCGv t0 = tcg_temp_new(), spr64 = tcg_temp_new();

    tcg_gen_ext32u_tl(t0, cpu_gpr[gprn]);
    gen_load_spr(spr64, sprn - 1);
    tcg_gen_shl_i64(t0, t0, 32);
    tcg_gen_or_i64(spr64, spr64, t0);
    gen_store_spr(sprn - 1, t0);

    tcg_temp_free(t0);
    tcg_temp_free(spr64);
    spr_store_dump_spr(sprn);
}
Alexey Kardashevskiy May 26, 2014, 3:50 p.m. UTC | #4
On 05/21/2014 08:47 PM, Alexander Graf wrote:
> 
> On 21.05.14 08:20, Alexey Kardashevskiy wrote:
>> This adds helper which adds TAR/BESCRS/BESCRSU/BESCRR/BESCRRU/
>> EBBHR/EBBRR/BESCR/TFHAR/TFIAR/TEXASR/TEXASRU SPRs.
>>
>> This adds MMCR2/FSCR/MMCRS SPRs.
>>
>> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
>> ---
>>   target-ppc/cpu.h            |  15 ++++++
>>   target-ppc/translate_init.c | 123
>> ++++++++++++++++++++++++++++++++++----------
>>   2 files changed, 112 insertions(+), 26 deletions(-)
>>
>> diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
>> index 262cf0f..72ed763 100644
>> --- a/target-ppc/cpu.h
>> +++ b/target-ppc/cpu.h
>> @@ -1258,6 +1258,10 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>   #define SPR_MPC_EIE           (0x050)
>>   #define SPR_MPC_EID           (0x051)
>>   #define SPR_MPC_NRI           (0x052)
>> +#define SPR_TFHAR             (0x080)
>> +#define SPR_TFIAR             (0x081)
>> +#define SPR_TEXASR            (0x082)
>> +#define SPR_TEXASRU           (0x083)
>>   #define SPR_UCTRL             (0x088)
>>   #define SPR_MPC_CMPA          (0x090)
>>   #define SPR_MPC_CMPB          (0x091)
>> @@ -1270,6 +1274,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>   #define SPR_CTRL              (0x098)
>>   #define SPR_MPC_CMPE          (0x098)
>>   #define SPR_MPC_CMPF          (0x099)
>> +#define SPR_FSCR              (0x099)
>>   #define SPR_MPC_CMPG          (0x09A)
>>   #define SPR_MPC_CMPH          (0x09B)
>>   #define SPR_MPC_LCTRL1        (0x09C)
>> @@ -1461,6 +1466,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>   #define SPR_MPC_MI_CTR        (0x300)
>>   #define SPR_PERF1             (0x301)
>>   #define SPR_RCPU_MI_RBA1      (0x301)
>> +#define SPR_POWER_UMMCR2      (0x301)
>>   #define SPR_PERF2             (0x302)
>>   #define SPR_RCPU_MI_RBA2      (0x302)
>>   #define SPR_MPC_MI_AP         (0x302)
>> @@ -1500,6 +1506,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>   #define SPR_MPC_MD_TW         (0x30F)
>>   #define SPR_UPERF0            (0x310)
>>   #define SPR_UPERF1            (0x311)
>> +#define SPR_POWER_MMCR2       (0x311)
>>   #define SPR_UPERF2            (0x312)
>>   #define SPR_MMCRA             (0x312)
>>   #define SPR_UPERF3            (0x313)
>> @@ -1519,11 +1526,18 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>   #define SPR_UPERFF            (0x31F)
>>   #define SPR_RCPU_MI_RA0       (0x320)
>>   #define SPR_MPC_MI_DBCAM      (0x320)
>> +#define SPR_BESCRS            (0x320)
>>   #define SPR_RCPU_MI_RA1       (0x321)
>>   #define SPR_MPC_MI_DBRAM0     (0x321)
>> +#define SPR_BESCRSU           (0x321)
>>   #define SPR_RCPU_MI_RA2       (0x322)
>>   #define SPR_MPC_MI_DBRAM1     (0x322)
>> +#define SPR_BESCRR            (0x322)
>>   #define SPR_RCPU_MI_RA3       (0x323)
>> +#define SPR_BESCRRU           (0x323)
>> +#define SPR_EBBHR             (0x324)
>> +#define SPR_EBBRR             (0x325)
>> +#define SPR_BESCR             (0x326)
>>   #define SPR_RCPU_L2U_RA0      (0x328)
>>   #define SPR_MPC_MD_DBCAM      (0x328)
>>   #define SPR_RCPU_L2U_RA1      (0x329)
>> @@ -1542,6 +1556,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>   #define SPR_440_ITV3          (0x377)
>>   #define SPR_440_CCR1          (0x378)
>>   #define SPR_DCRIPR            (0x37B)
>> +#define SPR_MMCRS             (0x37E)
>>   #define SPR_PPR               (0x380)
>>   #define SPR_750_GQR0          (0x390)
>>   #define SPR_440_DNV0          (0x390)
>> diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
>> index 3c37e93..d23fcc6 100644
>> --- a/target-ppc/translate_init.c
>> +++ b/target-ppc/translate_init.c
>> @@ -7951,37 +7951,108 @@ POWERPC_FAMILY(POWER7P)(ObjectClass *oc, void
>> *data)
>>       pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
>>   }
>>   -static void init_proc_POWER8(CPUPPCState *env)
>> +static void get_spr_power8_branch_control(CPUPPCState *env)
>>   {
>> -    gen_spr_ne_601(env);
>> -    gen_spr_7xx(env);
>> -    /* Time base */
>> -    gen_tbl(env);
>> -    gen_spr_book3s_ids(env);
>> -    gen_spr_book3s_common(env);
>> -    gen_spr_amr(env);
>> -    gen_spr_book3s_vr(env);
>> -    gen_spr_book3s_lpar(env);
>> -    gen_spr_book3s_purr(env);
>> -    gen_spr_book3s_debug(env);
>> -    gen_spr_book3s_pmu(env);
>> -#if !defined(CONFIG_USER_ONLY)
>> -    env->slb_nr = 32;
>> -#endif /* !CONFIG_USER_ONLY */
>> -    init_excp_POWER7(env);
>> -    env->dcache_line_size = 128;
>> -    env->icache_line_size = 128;
>> -
>> -    /* Allocate hardware IRQ controller */
>> -    ppcPOWER7_irq_init(env);
>> -    /* Can't find information on what this should be on reset.  This
>> -     * value is the one used by 74xx processors. */
>> -    vscr_init(env, 0x00010000);
>> -
>>       spr_register(env, SPR_TAR, "TAR",
>>                    &spr_read_generic, &spr_write_generic,
>>                    &spr_read_generic, &spr_write_generic,
>>                    0x00000000);
>> +
>> +    spr_register(env, SPR_BESCRS, "BESCRS",
>> +                 SPR_NOACCESS, SPR_NOACCESS,
>> +                 &spr_read_generic, &spr_write_generic,
> 
> Please introduce a special helper for these that checks whether FSCR.EBB ==
> 1 and injects a facility interrupt if not.


Some hints? I have never done anything to TCG yet... Specifically -
1. how to read SPR to uint64_t (to compare that EBB bit)?
2. how to inject that facility interrupt?
Thanks!


ps. getting closer to the end but still not there yet :(

git@github.com:aik/qemu.git power8
Alexander Graf May 26, 2014, 8:09 p.m. UTC | #5
On 26.05.14 17:45, Alexey Kardashevskiy wrote:
> On 05/22/2014 04:08 AM, Tom Musta wrote:
>> On 5/21/2014 1:20 AM, Alexey Kardashevskiy wrote:
>>> This adds helper which adds TAR/BESCRS/BESCRSU/BESCRR/BESCRRU/
>>> EBBHR/EBBRR/BESCR/TFHAR/TFIAR/TEXASR/TEXASRU SPRs.
>>>
>>> This adds MMCR2/FSCR/MMCRS SPRs.
>>>
>>> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
>>> ---
>>>   target-ppc/cpu.h            |  15 ++++++
>>>   target-ppc/translate_init.c | 123 ++++++++++++++++++++++++++++++++++----------
>>>   2 files changed, 112 insertions(+), 26 deletions(-)
>>>
>>> diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
>>> index 262cf0f..72ed763 100644
>>> --- a/target-ppc/cpu.h
>>> +++ b/target-ppc/cpu.h
>>> @@ -1258,6 +1258,10 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>>   #define SPR_MPC_EIE           (0x050)
>>>   #define SPR_MPC_EID           (0x051)
>>>   #define SPR_MPC_NRI           (0x052)
>>> +#define SPR_TFHAR             (0x080)
>>> +#define SPR_TFIAR             (0x081)
>>> +#define SPR_TEXASR            (0x082)
>>> +#define SPR_TEXASRU           (0x083)
>>>   #define SPR_UCTRL             (0x088)
>>>   #define SPR_MPC_CMPA          (0x090)
>>>   #define SPR_MPC_CMPB          (0x091)
>>> @@ -1270,6 +1274,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>>   #define SPR_CTRL              (0x098)
>>>   #define SPR_MPC_CMPE          (0x098)
>>>   #define SPR_MPC_CMPF          (0x099)
>>> +#define SPR_FSCR              (0x099)
>>>   #define SPR_MPC_CMPG          (0x09A)
>>>   #define SPR_MPC_CMPH          (0x09B)
>>>   #define SPR_MPC_LCTRL1        (0x09C)
>>> @@ -1461,6 +1466,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>>   #define SPR_MPC_MI_CTR        (0x300)
>>>   #define SPR_PERF1             (0x301)
>>>   #define SPR_RCPU_MI_RBA1      (0x301)
>>> +#define SPR_POWER_UMMCR2      (0x301)
>>>   #define SPR_PERF2             (0x302)
>>>   #define SPR_RCPU_MI_RBA2      (0x302)
>>>   #define SPR_MPC_MI_AP         (0x302)
>>> @@ -1500,6 +1506,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>>   #define SPR_MPC_MD_TW         (0x30F)
>>>   #define SPR_UPERF0            (0x310)
>>>   #define SPR_UPERF1            (0x311)
>>> +#define SPR_POWER_MMCR2       (0x311)
>>>   #define SPR_UPERF2            (0x312)
>>>   #define SPR_MMCRA             (0x312)
>>>   #define SPR_UPERF3            (0x313)
>>> @@ -1519,11 +1526,18 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>>   #define SPR_UPERFF            (0x31F)
>>>   #define SPR_RCPU_MI_RA0       (0x320)
>>>   #define SPR_MPC_MI_DBCAM      (0x320)
>>> +#define SPR_BESCRS            (0x320)
>>>   #define SPR_RCPU_MI_RA1       (0x321)
>>>   #define SPR_MPC_MI_DBRAM0     (0x321)
>>> +#define SPR_BESCRSU           (0x321)
>>>   #define SPR_RCPU_MI_RA2       (0x322)
>>>   #define SPR_MPC_MI_DBRAM1     (0x322)
>>> +#define SPR_BESCRR            (0x322)
>>>   #define SPR_RCPU_MI_RA3       (0x323)
>>> +#define SPR_BESCRRU           (0x323)
>>> +#define SPR_EBBHR             (0x324)
>>> +#define SPR_EBBRR             (0x325)
>>> +#define SPR_BESCR             (0x326)
>>>   #define SPR_RCPU_L2U_RA0      (0x328)
>>>   #define SPR_MPC_MD_DBCAM      (0x328)
>>>   #define SPR_RCPU_L2U_RA1      (0x329)
>>> @@ -1542,6 +1556,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>>   #define SPR_440_ITV3          (0x377)
>>>   #define SPR_440_CCR1          (0x378)
>>>   #define SPR_DCRIPR            (0x37B)
>>> +#define SPR_MMCRS             (0x37E)
>>>   #define SPR_PPR               (0x380)
>>>   #define SPR_750_GQR0          (0x390)
>>>   #define SPR_440_DNV0          (0x390)
>>> diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
>>> index 3c37e93..d23fcc6 100644
>>> --- a/target-ppc/translate_init.c
>>> +++ b/target-ppc/translate_init.c
>>> @@ -7951,37 +7951,108 @@ POWERPC_FAMILY(POWER7P)(ObjectClass *oc, void *data)
>>>       pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
>>>   }
>>>   
>>> -static void init_proc_POWER8(CPUPPCState *env)
>>> +static void get_spr_power8_branch_control(CPUPPCState *env)
>>>   {
>>> -    gen_spr_ne_601(env);
>>> -    gen_spr_7xx(env);
>>> -    /* Time base */
>>> -    gen_tbl(env);
>>> -    gen_spr_book3s_ids(env);
>>> -    gen_spr_book3s_common(env);
>>> -    gen_spr_amr(env);
>>> -    gen_spr_book3s_vr(env);
>>> -    gen_spr_book3s_lpar(env);
>>> -    gen_spr_book3s_purr(env);
>>> -    gen_spr_book3s_debug(env);
>>> -    gen_spr_book3s_pmu(env);
>>> -#if !defined(CONFIG_USER_ONLY)
>>> -    env->slb_nr = 32;
>>> -#endif /* !CONFIG_USER_ONLY */
>>> -    init_excp_POWER7(env);
>>> -    env->dcache_line_size = 128;
>>> -    env->icache_line_size = 128;
>>> -
>>> -    /* Allocate hardware IRQ controller */
>>> -    ppcPOWER7_irq_init(env);
>>> -    /* Can't find information on what this should be on reset.  This
>>> -     * value is the one used by 74xx processors. */
>>> -    vscr_init(env, 0x00010000);
>>> -
>>>       spr_register(env, SPR_TAR, "TAR",
>>>                    &spr_read_generic, &spr_write_generic,
>>>                    &spr_read_generic, &spr_write_generic,
>>>                    0x00000000);
>>> +
>>> +    spr_register(env, SPR_BESCRS, "BESCRS",
>>> +                 SPR_NOACCESS, SPR_NOACCESS,
>>> +                 &spr_read_generic, &spr_write_generic,
>>> +                 0x00000000);
>>> +    spr_register(env, SPR_BESCRSU, "BESCRSU",
>>> +                 SPR_NOACCESS, SPR_NOACCESS,
>>> +                 &spr_read_generic, &spr_write_generic,
>>> +                 0x00000000);
>>> +    spr_register(env, SPR_BESCRR, "BESCRR",
>>> +                 SPR_NOACCESS, SPR_NOACCESS,
>>> +                 &spr_read_generic, &spr_write_generic,
>>> +                 0x00000000);
>>> +    spr_register(env, SPR_BESCRRU, "BESCRRU",
>>> +                 SPR_NOACCESS, SPR_NOACCESS,
>>> +                 &spr_read_generic, &spr_write_generic,
>>> +                 0x00000000);
>>> +    spr_register_kvm(env, SPR_EBBHR, "EBBHR",
>>> +                     SPR_NOACCESS, SPR_NOACCESS,
>>> +                     &spr_read_generic, &spr_write_generic,
>>> +                     KVM_REG_PPC_EBBHR, 0x00000000);
>>> +    spr_register_kvm(env, SPR_EBBRR, "EBBRR",
>>> +                     SPR_NOACCESS, SPR_NOACCESS,
>>> +                     &spr_read_generic, &spr_write_generic,
>>> +                     KVM_REG_PPC_EBBRR, 0x00000000);
>>> +    spr_register_kvm(env, SPR_BESCR, "BESCR",
>>> +                     SPR_NOACCESS, SPR_NOACCESS,
>>> +                     &spr_read_generic, &spr_write_generic,
>>> +                     KVM_REG_PPC_BESCR, 0x00000000);
>>> +}
>> These are all user-mode accessible, no?
>>
>>> +
>>> +static void get_spr_power8_tm(CPUPPCState *env)
>>> +{
>>> +    spr_register_kvm(env, SPR_TFHAR, "TFHAR",
>>> +                     SPR_NOACCESS, SPR_NOACCESS,
>>> +                     &spr_read_generic, &spr_write_generic,
>>> +                     KVM_REG_PPC_TFHAR, 0x00000000);
>>> +    spr_register_kvm(env, SPR_TFIAR, "TFIAR",
>>> +                     SPR_NOACCESS, SPR_NOACCESS,
>>> +                     &spr_read_generic, &spr_write_generic,
>>> +                     KVM_REG_PPC_TFIAR, 0x00000000);
>>> +    spr_register_kvm(env, SPR_TEXASR, "TEXASR",
>>> +                     SPR_NOACCESS, SPR_NOACCESS,
>>> +                     &spr_read_generic, &spr_write_generic,
>>> +                     KVM_REG_PPC_TEXASR, 0x00000000);
>>> +    spr_register(env, SPR_TEXASRU, "TEXASRU",
>>> +                 SPR_NOACCESS, SPR_NOACCESS,
>>> +                 &spr_read_generic, &spr_write_generic,
>>> +                 0x00000000);
>>> +}
>> Same comment.
>>
>> Also, the xxxU SPRs numbers refer to the upper half of 64-bit SPRs.  These are necessary
>> to support access on 32-bit implementations.  It seems like some special spr access routines
>> are required to support this.
>
> I am not familiar with TCG (yet)... Something like below? This uses the
> fact that SPRs go consequently.
>
>
> static void spr_read_upper32(void *opaque, int gprn, int sprn)
> {
>      TCGv spr64 = tcg_temp_new();
>
>      gen_load_spr(spr64, sprn - 1);

gen_load_spr() takes a GPR as argument, no?

>      tcg_gen_shr_i64(spr64, spr64, 32);
>      tcg_gen_ext32u_tl(cpu_gpr[gprn], spr64);

If you use the deposit op you don't need a temp I think :). Also please 
compile with --enable-tcg-debug and check that you don't break ppc-softmmu.

>      tcg_temp_free(spr64);
>      spr_store_dump_spr(sprn);
> }
>
> static void spr_write_upper32(void *opaque, int sprn, int gprn)
> {
>      TCGv t0 = tcg_temp_new(), spr64 = tcg_temp_new();
>
>      tcg_gen_ext32u_tl(t0, cpu_gpr[gprn]);
>      gen_load_spr(spr64, sprn - 1);
>      tcg_gen_shl_i64(t0, t0, 32);
>      tcg_gen_or_i64(spr64, spr64, t0);

Again, you're easier off with deposit.

>      gen_store_spr(sprn - 1, t0);

Uh, I don't think that works - see above.


Alex

>
>      tcg_temp_free(t0);
>      tcg_temp_free(spr64);
>      spr_store_dump_spr(sprn);
> }
>
>
>
Alexander Graf May 26, 2014, 8:21 p.m. UTC | #6
On 26.05.14 17:50, Alexey Kardashevskiy wrote:
> On 05/21/2014 08:47 PM, Alexander Graf wrote:
>> On 21.05.14 08:20, Alexey Kardashevskiy wrote:
>>> This adds helper which adds TAR/BESCRS/BESCRSU/BESCRR/BESCRRU/
>>> EBBHR/EBBRR/BESCR/TFHAR/TFIAR/TEXASR/TEXASRU SPRs.
>>>
>>> This adds MMCR2/FSCR/MMCRS SPRs.
>>>
>>> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
>>> ---
>>>    target-ppc/cpu.h            |  15 ++++++
>>>    target-ppc/translate_init.c | 123
>>> ++++++++++++++++++++++++++++++++++----------
>>>    2 files changed, 112 insertions(+), 26 deletions(-)
>>>
>>> diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
>>> index 262cf0f..72ed763 100644
>>> --- a/target-ppc/cpu.h
>>> +++ b/target-ppc/cpu.h
>>> @@ -1258,6 +1258,10 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>>    #define SPR_MPC_EIE           (0x050)
>>>    #define SPR_MPC_EID           (0x051)
>>>    #define SPR_MPC_NRI           (0x052)
>>> +#define SPR_TFHAR             (0x080)
>>> +#define SPR_TFIAR             (0x081)
>>> +#define SPR_TEXASR            (0x082)
>>> +#define SPR_TEXASRU           (0x083)
>>>    #define SPR_UCTRL             (0x088)
>>>    #define SPR_MPC_CMPA          (0x090)
>>>    #define SPR_MPC_CMPB          (0x091)
>>> @@ -1270,6 +1274,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>>    #define SPR_CTRL              (0x098)
>>>    #define SPR_MPC_CMPE          (0x098)
>>>    #define SPR_MPC_CMPF          (0x099)
>>> +#define SPR_FSCR              (0x099)
>>>    #define SPR_MPC_CMPG          (0x09A)
>>>    #define SPR_MPC_CMPH          (0x09B)
>>>    #define SPR_MPC_LCTRL1        (0x09C)
>>> @@ -1461,6 +1466,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>>    #define SPR_MPC_MI_CTR        (0x300)
>>>    #define SPR_PERF1             (0x301)
>>>    #define SPR_RCPU_MI_RBA1      (0x301)
>>> +#define SPR_POWER_UMMCR2      (0x301)
>>>    #define SPR_PERF2             (0x302)
>>>    #define SPR_RCPU_MI_RBA2      (0x302)
>>>    #define SPR_MPC_MI_AP         (0x302)
>>> @@ -1500,6 +1506,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>>    #define SPR_MPC_MD_TW         (0x30F)
>>>    #define SPR_UPERF0            (0x310)
>>>    #define SPR_UPERF1            (0x311)
>>> +#define SPR_POWER_MMCR2       (0x311)
>>>    #define SPR_UPERF2            (0x312)
>>>    #define SPR_MMCRA             (0x312)
>>>    #define SPR_UPERF3            (0x313)
>>> @@ -1519,11 +1526,18 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>>    #define SPR_UPERFF            (0x31F)
>>>    #define SPR_RCPU_MI_RA0       (0x320)
>>>    #define SPR_MPC_MI_DBCAM      (0x320)
>>> +#define SPR_BESCRS            (0x320)
>>>    #define SPR_RCPU_MI_RA1       (0x321)
>>>    #define SPR_MPC_MI_DBRAM0     (0x321)
>>> +#define SPR_BESCRSU           (0x321)
>>>    #define SPR_RCPU_MI_RA2       (0x322)
>>>    #define SPR_MPC_MI_DBRAM1     (0x322)
>>> +#define SPR_BESCRR            (0x322)
>>>    #define SPR_RCPU_MI_RA3       (0x323)
>>> +#define SPR_BESCRRU           (0x323)
>>> +#define SPR_EBBHR             (0x324)
>>> +#define SPR_EBBRR             (0x325)
>>> +#define SPR_BESCR             (0x326)
>>>    #define SPR_RCPU_L2U_RA0      (0x328)
>>>    #define SPR_MPC_MD_DBCAM      (0x328)
>>>    #define SPR_RCPU_L2U_RA1      (0x329)
>>> @@ -1542,6 +1556,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>>    #define SPR_440_ITV3          (0x377)
>>>    #define SPR_440_CCR1          (0x378)
>>>    #define SPR_DCRIPR            (0x37B)
>>> +#define SPR_MMCRS             (0x37E)
>>>    #define SPR_PPR               (0x380)
>>>    #define SPR_750_GQR0          (0x390)
>>>    #define SPR_440_DNV0          (0x390)
>>> diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
>>> index 3c37e93..d23fcc6 100644
>>> --- a/target-ppc/translate_init.c
>>> +++ b/target-ppc/translate_init.c
>>> @@ -7951,37 +7951,108 @@ POWERPC_FAMILY(POWER7P)(ObjectClass *oc, void
>>> *data)
>>>        pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
>>>    }
>>>    -static void init_proc_POWER8(CPUPPCState *env)
>>> +static void get_spr_power8_branch_control(CPUPPCState *env)
>>>    {
>>> -    gen_spr_ne_601(env);
>>> -    gen_spr_7xx(env);
>>> -    /* Time base */
>>> -    gen_tbl(env);
>>> -    gen_spr_book3s_ids(env);
>>> -    gen_spr_book3s_common(env);
>>> -    gen_spr_amr(env);
>>> -    gen_spr_book3s_vr(env);
>>> -    gen_spr_book3s_lpar(env);
>>> -    gen_spr_book3s_purr(env);
>>> -    gen_spr_book3s_debug(env);
>>> -    gen_spr_book3s_pmu(env);
>>> -#if !defined(CONFIG_USER_ONLY)
>>> -    env->slb_nr = 32;
>>> -#endif /* !CONFIG_USER_ONLY */
>>> -    init_excp_POWER7(env);
>>> -    env->dcache_line_size = 128;
>>> -    env->icache_line_size = 128;
>>> -
>>> -    /* Allocate hardware IRQ controller */
>>> -    ppcPOWER7_irq_init(env);
>>> -    /* Can't find information on what this should be on reset.  This
>>> -     * value is the one used by 74xx processors. */
>>> -    vscr_init(env, 0x00010000);
>>> -
>>>        spr_register(env, SPR_TAR, "TAR",
>>>                     &spr_read_generic, &spr_write_generic,
>>>                     &spr_read_generic, &spr_write_generic,
>>>                     0x00000000);
>>> +
>>> +    spr_register(env, SPR_BESCRS, "BESCRS",
>>> +                 SPR_NOACCESS, SPR_NOACCESS,
>>> +                 &spr_read_generic, &spr_write_generic,
>> Please introduce a special helper for these that checks whether FSCR.EBB ==
>> 1 and injects a facility interrupt if not.
>
> Some hints? I have never done anything to TCG yet... Specifically -
> 1. how to read SPR to uint64_t (to compare that EBB bit)?

I think the easiest would be to call into a C helper. The call to the C 
helper would be inside the translation phase SPR callback. Check out 
commit fcfda20 for an easy example on this.

> 2. how to inject that facility interrupt?

You'd have to introduce a new POWERPC_EXCP type, handle that in 
powerpc_excp(), create another PPC_INTERRUPT type for it that you handle 
in ppc_hw_interrupt() according to the interrupt priority and trigger 
that via ppc_set_irq() from your C helper :).


Alex


> Thanks!
>
>
> ps. getting closer to the end but still not there yet :(
>
> git@github.com:aik/qemu.git power8
>
>
>
Alexey Kardashevskiy May 27, 2014, 12:23 a.m. UTC | #7
On 05/27/2014 06:09 AM, Alexander Graf wrote:
> 
> On 26.05.14 17:45, Alexey Kardashevskiy wrote:
>> On 05/22/2014 04:08 AM, Tom Musta wrote:
>>> On 5/21/2014 1:20 AM, Alexey Kardashevskiy wrote:
>>>> This adds helper which adds TAR/BESCRS/BESCRSU/BESCRR/BESCRRU/
>>>> EBBHR/EBBRR/BESCR/TFHAR/TFIAR/TEXASR/TEXASRU SPRs.
>>>>
>>>> This adds MMCR2/FSCR/MMCRS SPRs.
>>>>
>>>> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
>>>> ---
>>>>   target-ppc/cpu.h            |  15 ++++++
>>>>   target-ppc/translate_init.c | 123
>>>> ++++++++++++++++++++++++++++++++++----------
>>>>   2 files changed, 112 insertions(+), 26 deletions(-)
>>>>
>>>> diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
>>>> index 262cf0f..72ed763 100644
>>>> --- a/target-ppc/cpu.h
>>>> +++ b/target-ppc/cpu.h
>>>> @@ -1258,6 +1258,10 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>>>   #define SPR_MPC_EIE           (0x050)
>>>>   #define SPR_MPC_EID           (0x051)
>>>>   #define SPR_MPC_NRI           (0x052)
>>>> +#define SPR_TFHAR             (0x080)
>>>> +#define SPR_TFIAR             (0x081)
>>>> +#define SPR_TEXASR            (0x082)
>>>> +#define SPR_TEXASRU           (0x083)
>>>>   #define SPR_UCTRL             (0x088)
>>>>   #define SPR_MPC_CMPA          (0x090)
>>>>   #define SPR_MPC_CMPB          (0x091)
>>>> @@ -1270,6 +1274,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>>>   #define SPR_CTRL              (0x098)
>>>>   #define SPR_MPC_CMPE          (0x098)
>>>>   #define SPR_MPC_CMPF          (0x099)
>>>> +#define SPR_FSCR              (0x099)
>>>>   #define SPR_MPC_CMPG          (0x09A)
>>>>   #define SPR_MPC_CMPH          (0x09B)
>>>>   #define SPR_MPC_LCTRL1        (0x09C)
>>>> @@ -1461,6 +1466,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>>>   #define SPR_MPC_MI_CTR        (0x300)
>>>>   #define SPR_PERF1             (0x301)
>>>>   #define SPR_RCPU_MI_RBA1      (0x301)
>>>> +#define SPR_POWER_UMMCR2      (0x301)
>>>>   #define SPR_PERF2             (0x302)
>>>>   #define SPR_RCPU_MI_RBA2      (0x302)
>>>>   #define SPR_MPC_MI_AP         (0x302)
>>>> @@ -1500,6 +1506,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>>>   #define SPR_MPC_MD_TW         (0x30F)
>>>>   #define SPR_UPERF0            (0x310)
>>>>   #define SPR_UPERF1            (0x311)
>>>> +#define SPR_POWER_MMCR2       (0x311)
>>>>   #define SPR_UPERF2            (0x312)
>>>>   #define SPR_MMCRA             (0x312)
>>>>   #define SPR_UPERF3            (0x313)
>>>> @@ -1519,11 +1526,18 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>>>   #define SPR_UPERFF            (0x31F)
>>>>   #define SPR_RCPU_MI_RA0       (0x320)
>>>>   #define SPR_MPC_MI_DBCAM      (0x320)
>>>> +#define SPR_BESCRS            (0x320)
>>>>   #define SPR_RCPU_MI_RA1       (0x321)
>>>>   #define SPR_MPC_MI_DBRAM0     (0x321)
>>>> +#define SPR_BESCRSU           (0x321)
>>>>   #define SPR_RCPU_MI_RA2       (0x322)
>>>>   #define SPR_MPC_MI_DBRAM1     (0x322)
>>>> +#define SPR_BESCRR            (0x322)
>>>>   #define SPR_RCPU_MI_RA3       (0x323)
>>>> +#define SPR_BESCRRU           (0x323)
>>>> +#define SPR_EBBHR             (0x324)
>>>> +#define SPR_EBBRR             (0x325)
>>>> +#define SPR_BESCR             (0x326)
>>>>   #define SPR_RCPU_L2U_RA0      (0x328)
>>>>   #define SPR_MPC_MD_DBCAM      (0x328)
>>>>   #define SPR_RCPU_L2U_RA1      (0x329)
>>>> @@ -1542,6 +1556,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>>>   #define SPR_440_ITV3          (0x377)
>>>>   #define SPR_440_CCR1          (0x378)
>>>>   #define SPR_DCRIPR            (0x37B)
>>>> +#define SPR_MMCRS             (0x37E)
>>>>   #define SPR_PPR               (0x380)
>>>>   #define SPR_750_GQR0          (0x390)
>>>>   #define SPR_440_DNV0          (0x390)
>>>> diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
>>>> index 3c37e93..d23fcc6 100644
>>>> --- a/target-ppc/translate_init.c
>>>> +++ b/target-ppc/translate_init.c
>>>> @@ -7951,37 +7951,108 @@ POWERPC_FAMILY(POWER7P)(ObjectClass *oc, void
>>>> *data)
>>>>       pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
>>>>   }
>>>>   -static void init_proc_POWER8(CPUPPCState *env)
>>>> +static void get_spr_power8_branch_control(CPUPPCState *env)
>>>>   {
>>>> -    gen_spr_ne_601(env);
>>>> -    gen_spr_7xx(env);
>>>> -    /* Time base */
>>>> -    gen_tbl(env);
>>>> -    gen_spr_book3s_ids(env);
>>>> -    gen_spr_book3s_common(env);
>>>> -    gen_spr_amr(env);
>>>> -    gen_spr_book3s_vr(env);
>>>> -    gen_spr_book3s_lpar(env);
>>>> -    gen_spr_book3s_purr(env);
>>>> -    gen_spr_book3s_debug(env);
>>>> -    gen_spr_book3s_pmu(env);
>>>> -#if !defined(CONFIG_USER_ONLY)
>>>> -    env->slb_nr = 32;
>>>> -#endif /* !CONFIG_USER_ONLY */
>>>> -    init_excp_POWER7(env);
>>>> -    env->dcache_line_size = 128;
>>>> -    env->icache_line_size = 128;
>>>> -
>>>> -    /* Allocate hardware IRQ controller */
>>>> -    ppcPOWER7_irq_init(env);
>>>> -    /* Can't find information on what this should be on reset.  This
>>>> -     * value is the one used by 74xx processors. */
>>>> -    vscr_init(env, 0x00010000);
>>>> -
>>>>       spr_register(env, SPR_TAR, "TAR",
>>>>                    &spr_read_generic, &spr_write_generic,
>>>>                    &spr_read_generic, &spr_write_generic,
>>>>                    0x00000000);
>>>> +
>>>> +    spr_register(env, SPR_BESCRS, "BESCRS",
>>>> +                 SPR_NOACCESS, SPR_NOACCESS,
>>>> +                 &spr_read_generic, &spr_write_generic,
>>>> +                 0x00000000);
>>>> +    spr_register(env, SPR_BESCRSU, "BESCRSU",
>>>> +                 SPR_NOACCESS, SPR_NOACCESS,
>>>> +                 &spr_read_generic, &spr_write_generic,
>>>> +                 0x00000000);
>>>> +    spr_register(env, SPR_BESCRR, "BESCRR",
>>>> +                 SPR_NOACCESS, SPR_NOACCESS,
>>>> +                 &spr_read_generic, &spr_write_generic,
>>>> +                 0x00000000);
>>>> +    spr_register(env, SPR_BESCRRU, "BESCRRU",
>>>> +                 SPR_NOACCESS, SPR_NOACCESS,
>>>> +                 &spr_read_generic, &spr_write_generic,
>>>> +                 0x00000000);
>>>> +    spr_register_kvm(env, SPR_EBBHR, "EBBHR",
>>>> +                     SPR_NOACCESS, SPR_NOACCESS,
>>>> +                     &spr_read_generic, &spr_write_generic,
>>>> +                     KVM_REG_PPC_EBBHR, 0x00000000);
>>>> +    spr_register_kvm(env, SPR_EBBRR, "EBBRR",
>>>> +                     SPR_NOACCESS, SPR_NOACCESS,
>>>> +                     &spr_read_generic, &spr_write_generic,
>>>> +                     KVM_REG_PPC_EBBRR, 0x00000000);
>>>> +    spr_register_kvm(env, SPR_BESCR, "BESCR",
>>>> +                     SPR_NOACCESS, SPR_NOACCESS,
>>>> +                     &spr_read_generic, &spr_write_generic,
>>>> +                     KVM_REG_PPC_BESCR, 0x00000000);
>>>> +}
>>> These are all user-mode accessible, no?
>>>
>>>> +
>>>> +static void get_spr_power8_tm(CPUPPCState *env)
>>>> +{
>>>> +    spr_register_kvm(env, SPR_TFHAR, "TFHAR",
>>>> +                     SPR_NOACCESS, SPR_NOACCESS,
>>>> +                     &spr_read_generic, &spr_write_generic,
>>>> +                     KVM_REG_PPC_TFHAR, 0x00000000);
>>>> +    spr_register_kvm(env, SPR_TFIAR, "TFIAR",
>>>> +                     SPR_NOACCESS, SPR_NOACCESS,
>>>> +                     &spr_read_generic, &spr_write_generic,
>>>> +                     KVM_REG_PPC_TFIAR, 0x00000000);
>>>> +    spr_register_kvm(env, SPR_TEXASR, "TEXASR",
>>>> +                     SPR_NOACCESS, SPR_NOACCESS,
>>>> +                     &spr_read_generic, &spr_write_generic,
>>>> +                     KVM_REG_PPC_TEXASR, 0x00000000);
>>>> +    spr_register(env, SPR_TEXASRU, "TEXASRU",
>>>> +                 SPR_NOACCESS, SPR_NOACCESS,
>>>> +                 &spr_read_generic, &spr_write_generic,
>>>> +                 0x00000000);
>>>> +}
>>> Same comment.
>>>
>>> Also, the xxxU SPRs numbers refer to the upper half of 64-bit SPRs. 
>>> These are necessary
>>> to support access on 32-bit implementations.  It seems like some special
>>> spr access routines
>>> are required to support this.
>>
>> I am not familiar with TCG (yet)... Something like below? This uses the
>> fact that SPRs go consequently.
>>
>>
>> static void spr_read_upper32(void *opaque, int gprn, int sprn)
>> {
>>      TCGv spr64 = tcg_temp_new();
>>
>>      gen_load_spr(spr64, sprn - 1);
> 
> gen_load_spr() takes a GPR as argument, no?

No. Here it is:

static TCGv cpu_gpr[32];
...
static inline void gen_load_spr(TCGv t, int reg)
{
    tcg_gen_ld_tl(t, cpu_env, offsetof(CPUPPCState, spr[reg]));
}
...
static void spr_read_generic (void *opaque, int gprn, int sprn)
{
    gen_load_spr(cpu_gpr[gprn], sprn);
    spr_load_dump_spr(sprn);
}

TCGv is a type of the first parameter of gen_load_spr(), why would it care
if it is GPR or not?

How does this all work? One global static array of GPRs? No SMP whatsoever?
Or there is some trick?

What is opaque for here? This TCG business is behind my understanding yet :)



>>      tcg_gen_shr_i64(spr64, spr64, 32);
>>      tcg_gen_ext32u_tl(cpu_gpr[gprn], spr64);
> 
> If you use the deposit op you don't need a temp I think :). Also please
> compile with --enable-tcg-debug and check that you don't break ppc-softmmu.
> 
>>      tcg_temp_free(spr64);
>>      spr_store_dump_spr(sprn);
>> }
>>
>> static void spr_write_upper32(void *opaque, int sprn, int gprn)
>> {
>>      TCGv t0 = tcg_temp_new(), spr64 = tcg_temp_new();
>>
>>      tcg_gen_ext32u_tl(t0, cpu_gpr[gprn]);
>>      gen_load_spr(spr64, sprn - 1);
>>      tcg_gen_shl_i64(t0, t0, 32);
>>      tcg_gen_or_i64(spr64, spr64, t0);
> 
> Again, you're easier off with deposit.
> 
>>      gen_store_spr(sprn - 1, t0);
> 
> Uh, I don't think that works - see above.
> 
> 
> Alex
> 
>>
>>      tcg_temp_free(t0);
>>      tcg_temp_free(spr64);
>>      spr_store_dump_spr(sprn);
>> }
Alexander Graf May 27, 2014, 12:26 a.m. UTC | #8
On 27.05.14 02:23, Alexey Kardashevskiy wrote:
> On 05/27/2014 06:09 AM, Alexander Graf wrote:
>> On 26.05.14 17:45, Alexey Kardashevskiy wrote:
>>> On 05/22/2014 04:08 AM, Tom Musta wrote:
>>>> On 5/21/2014 1:20 AM, Alexey Kardashevskiy wrote:
>>>>> This adds helper which adds TAR/BESCRS/BESCRSU/BESCRR/BESCRRU/
>>>>> EBBHR/EBBRR/BESCR/TFHAR/TFIAR/TEXASR/TEXASRU SPRs.
>>>>>
>>>>> This adds MMCR2/FSCR/MMCRS SPRs.
>>>>>
>>>>> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
>>>>> ---
>>>>>    target-ppc/cpu.h            |  15 ++++++
>>>>>    target-ppc/translate_init.c | 123
>>>>> ++++++++++++++++++++++++++++++++++----------
>>>>>    2 files changed, 112 insertions(+), 26 deletions(-)
>>>>>
>>>>> diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
>>>>> index 262cf0f..72ed763 100644
>>>>> --- a/target-ppc/cpu.h
>>>>> +++ b/target-ppc/cpu.h
>>>>> @@ -1258,6 +1258,10 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>>>>    #define SPR_MPC_EIE           (0x050)
>>>>>    #define SPR_MPC_EID           (0x051)
>>>>>    #define SPR_MPC_NRI           (0x052)
>>>>> +#define SPR_TFHAR             (0x080)
>>>>> +#define SPR_TFIAR             (0x081)
>>>>> +#define SPR_TEXASR            (0x082)
>>>>> +#define SPR_TEXASRU           (0x083)
>>>>>    #define SPR_UCTRL             (0x088)
>>>>>    #define SPR_MPC_CMPA          (0x090)
>>>>>    #define SPR_MPC_CMPB          (0x091)
>>>>> @@ -1270,6 +1274,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>>>>    #define SPR_CTRL              (0x098)
>>>>>    #define SPR_MPC_CMPE          (0x098)
>>>>>    #define SPR_MPC_CMPF          (0x099)
>>>>> +#define SPR_FSCR              (0x099)
>>>>>    #define SPR_MPC_CMPG          (0x09A)
>>>>>    #define SPR_MPC_CMPH          (0x09B)
>>>>>    #define SPR_MPC_LCTRL1        (0x09C)
>>>>> @@ -1461,6 +1466,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>>>>    #define SPR_MPC_MI_CTR        (0x300)
>>>>>    #define SPR_PERF1             (0x301)
>>>>>    #define SPR_RCPU_MI_RBA1      (0x301)
>>>>> +#define SPR_POWER_UMMCR2      (0x301)
>>>>>    #define SPR_PERF2             (0x302)
>>>>>    #define SPR_RCPU_MI_RBA2      (0x302)
>>>>>    #define SPR_MPC_MI_AP         (0x302)
>>>>> @@ -1500,6 +1506,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>>>>    #define SPR_MPC_MD_TW         (0x30F)
>>>>>    #define SPR_UPERF0            (0x310)
>>>>>    #define SPR_UPERF1            (0x311)
>>>>> +#define SPR_POWER_MMCR2       (0x311)
>>>>>    #define SPR_UPERF2            (0x312)
>>>>>    #define SPR_MMCRA             (0x312)
>>>>>    #define SPR_UPERF3            (0x313)
>>>>> @@ -1519,11 +1526,18 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>>>>    #define SPR_UPERFF            (0x31F)
>>>>>    #define SPR_RCPU_MI_RA0       (0x320)
>>>>>    #define SPR_MPC_MI_DBCAM      (0x320)
>>>>> +#define SPR_BESCRS            (0x320)
>>>>>    #define SPR_RCPU_MI_RA1       (0x321)
>>>>>    #define SPR_MPC_MI_DBRAM0     (0x321)
>>>>> +#define SPR_BESCRSU           (0x321)
>>>>>    #define SPR_RCPU_MI_RA2       (0x322)
>>>>>    #define SPR_MPC_MI_DBRAM1     (0x322)
>>>>> +#define SPR_BESCRR            (0x322)
>>>>>    #define SPR_RCPU_MI_RA3       (0x323)
>>>>> +#define SPR_BESCRRU           (0x323)
>>>>> +#define SPR_EBBHR             (0x324)
>>>>> +#define SPR_EBBRR             (0x325)
>>>>> +#define SPR_BESCR             (0x326)
>>>>>    #define SPR_RCPU_L2U_RA0      (0x328)
>>>>>    #define SPR_MPC_MD_DBCAM      (0x328)
>>>>>    #define SPR_RCPU_L2U_RA1      (0x329)
>>>>> @@ -1542,6 +1556,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>>>>    #define SPR_440_ITV3          (0x377)
>>>>>    #define SPR_440_CCR1          (0x378)
>>>>>    #define SPR_DCRIPR            (0x37B)
>>>>> +#define SPR_MMCRS             (0x37E)
>>>>>    #define SPR_PPR               (0x380)
>>>>>    #define SPR_750_GQR0          (0x390)
>>>>>    #define SPR_440_DNV0          (0x390)
>>>>> diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
>>>>> index 3c37e93..d23fcc6 100644
>>>>> --- a/target-ppc/translate_init.c
>>>>> +++ b/target-ppc/translate_init.c
>>>>> @@ -7951,37 +7951,108 @@ POWERPC_FAMILY(POWER7P)(ObjectClass *oc, void
>>>>> *data)
>>>>>        pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
>>>>>    }
>>>>>    -static void init_proc_POWER8(CPUPPCState *env)
>>>>> +static void get_spr_power8_branch_control(CPUPPCState *env)
>>>>>    {
>>>>> -    gen_spr_ne_601(env);
>>>>> -    gen_spr_7xx(env);
>>>>> -    /* Time base */
>>>>> -    gen_tbl(env);
>>>>> -    gen_spr_book3s_ids(env);
>>>>> -    gen_spr_book3s_common(env);
>>>>> -    gen_spr_amr(env);
>>>>> -    gen_spr_book3s_vr(env);
>>>>> -    gen_spr_book3s_lpar(env);
>>>>> -    gen_spr_book3s_purr(env);
>>>>> -    gen_spr_book3s_debug(env);
>>>>> -    gen_spr_book3s_pmu(env);
>>>>> -#if !defined(CONFIG_USER_ONLY)
>>>>> -    env->slb_nr = 32;
>>>>> -#endif /* !CONFIG_USER_ONLY */
>>>>> -    init_excp_POWER7(env);
>>>>> -    env->dcache_line_size = 128;
>>>>> -    env->icache_line_size = 128;
>>>>> -
>>>>> -    /* Allocate hardware IRQ controller */
>>>>> -    ppcPOWER7_irq_init(env);
>>>>> -    /* Can't find information on what this should be on reset.  This
>>>>> -     * value is the one used by 74xx processors. */
>>>>> -    vscr_init(env, 0x00010000);
>>>>> -
>>>>>        spr_register(env, SPR_TAR, "TAR",
>>>>>                     &spr_read_generic, &spr_write_generic,
>>>>>                     &spr_read_generic, &spr_write_generic,
>>>>>                     0x00000000);
>>>>> +
>>>>> +    spr_register(env, SPR_BESCRS, "BESCRS",
>>>>> +                 SPR_NOACCESS, SPR_NOACCESS,
>>>>> +                 &spr_read_generic, &spr_write_generic,
>>>>> +                 0x00000000);
>>>>> +    spr_register(env, SPR_BESCRSU, "BESCRSU",
>>>>> +                 SPR_NOACCESS, SPR_NOACCESS,
>>>>> +                 &spr_read_generic, &spr_write_generic,
>>>>> +                 0x00000000);
>>>>> +    spr_register(env, SPR_BESCRR, "BESCRR",
>>>>> +                 SPR_NOACCESS, SPR_NOACCESS,
>>>>> +                 &spr_read_generic, &spr_write_generic,
>>>>> +                 0x00000000);
>>>>> +    spr_register(env, SPR_BESCRRU, "BESCRRU",
>>>>> +                 SPR_NOACCESS, SPR_NOACCESS,
>>>>> +                 &spr_read_generic, &spr_write_generic,
>>>>> +                 0x00000000);
>>>>> +    spr_register_kvm(env, SPR_EBBHR, "EBBHR",
>>>>> +                     SPR_NOACCESS, SPR_NOACCESS,
>>>>> +                     &spr_read_generic, &spr_write_generic,
>>>>> +                     KVM_REG_PPC_EBBHR, 0x00000000);
>>>>> +    spr_register_kvm(env, SPR_EBBRR, "EBBRR",
>>>>> +                     SPR_NOACCESS, SPR_NOACCESS,
>>>>> +                     &spr_read_generic, &spr_write_generic,
>>>>> +                     KVM_REG_PPC_EBBRR, 0x00000000);
>>>>> +    spr_register_kvm(env, SPR_BESCR, "BESCR",
>>>>> +                     SPR_NOACCESS, SPR_NOACCESS,
>>>>> +                     &spr_read_generic, &spr_write_generic,
>>>>> +                     KVM_REG_PPC_BESCR, 0x00000000);
>>>>> +}
>>>> These are all user-mode accessible, no?
>>>>
>>>>> +
>>>>> +static void get_spr_power8_tm(CPUPPCState *env)
>>>>> +{
>>>>> +    spr_register_kvm(env, SPR_TFHAR, "TFHAR",
>>>>> +                     SPR_NOACCESS, SPR_NOACCESS,
>>>>> +                     &spr_read_generic, &spr_write_generic,
>>>>> +                     KVM_REG_PPC_TFHAR, 0x00000000);
>>>>> +    spr_register_kvm(env, SPR_TFIAR, "TFIAR",
>>>>> +                     SPR_NOACCESS, SPR_NOACCESS,
>>>>> +                     &spr_read_generic, &spr_write_generic,
>>>>> +                     KVM_REG_PPC_TFIAR, 0x00000000);
>>>>> +    spr_register_kvm(env, SPR_TEXASR, "TEXASR",
>>>>> +                     SPR_NOACCESS, SPR_NOACCESS,
>>>>> +                     &spr_read_generic, &spr_write_generic,
>>>>> +                     KVM_REG_PPC_TEXASR, 0x00000000);
>>>>> +    spr_register(env, SPR_TEXASRU, "TEXASRU",
>>>>> +                 SPR_NOACCESS, SPR_NOACCESS,
>>>>> +                 &spr_read_generic, &spr_write_generic,
>>>>> +                 0x00000000);
>>>>> +}
>>>> Same comment.
>>>>
>>>> Also, the xxxU SPRs numbers refer to the upper half of 64-bit SPRs.
>>>> These are necessary
>>>> to support access on 32-bit implementations.  It seems like some special
>>>> spr access routines
>>>> are required to support this.
>>> I am not familiar with TCG (yet)... Something like below? This uses the
>>> fact that SPRs go consequently.
>>>
>>>
>>> static void spr_read_upper32(void *opaque, int gprn, int sprn)
>>> {
>>>       TCGv spr64 = tcg_temp_new();
>>>
>>>       gen_load_spr(spr64, sprn - 1);
>> gen_load_spr() takes a GPR as argument, no?
> No. Here it is:
>
> static TCGv cpu_gpr[32];
> ...
> static inline void gen_load_spr(TCGv t, int reg)
> {
>      tcg_gen_ld_tl(t, cpu_env, offsetof(CPUPPCState, spr[reg]));
> }
> ...
> static void spr_read_generic (void *opaque, int gprn, int sprn)
> {
>      gen_load_spr(cpu_gpr[gprn], sprn);
>      spr_load_dump_spr(sprn);
> }

Ah, I must've looked at the wrong function then.

>
> TCGv is a type of the first parameter of gen_load_spr(), why would it care
> if it is GPR or not?
>
> How does this all work? One global static array of GPRs? No SMP whatsoever?
> Or there is some trick?

It's a global static array of TCG variables that reference env + static 
offset :). Env stays dynamic, the only thing that's global is the offset.

> What is opaque for here? This TCG business is behind my understanding yet :)

Apparently unused in this case :)


Alex
Alexey Kardashevskiy May 27, 2014, 7:41 a.m. UTC | #9
On 05/27/2014 06:09 AM, Alexander Graf wrote:
> 
> On 26.05.14 17:45, Alexey Kardashevskiy wrote:
>> On 05/22/2014 04:08 AM, Tom Musta wrote:
>>> On 5/21/2014 1:20 AM, Alexey Kardashevskiy wrote:
>>>> This adds helper which adds TAR/BESCRS/BESCRSU/BESCRR/BESCRRU/
>>>> EBBHR/EBBRR/BESCR/TFHAR/TFIAR/TEXASR/TEXASRU SPRs.
>>>>
>>>> This adds MMCR2/FSCR/MMCRS SPRs.
>>>>
>>>> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
>>>> ---
>>>>   target-ppc/cpu.h            |  15 ++++++
>>>>   target-ppc/translate_init.c | 123
>>>> ++++++++++++++++++++++++++++++++++----------
>>>>   2 files changed, 112 insertions(+), 26 deletions(-)
>>>>
>>>> diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
>>>> index 262cf0f..72ed763 100644
>>>> --- a/target-ppc/cpu.h
>>>> +++ b/target-ppc/cpu.h
>>>> @@ -1258,6 +1258,10 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>>>   #define SPR_MPC_EIE           (0x050)
>>>>   #define SPR_MPC_EID           (0x051)
>>>>   #define SPR_MPC_NRI           (0x052)
>>>> +#define SPR_TFHAR             (0x080)
>>>> +#define SPR_TFIAR             (0x081)
>>>> +#define SPR_TEXASR            (0x082)
>>>> +#define SPR_TEXASRU           (0x083)
>>>>   #define SPR_UCTRL             (0x088)
>>>>   #define SPR_MPC_CMPA          (0x090)
>>>>   #define SPR_MPC_CMPB          (0x091)
>>>> @@ -1270,6 +1274,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>>>   #define SPR_CTRL              (0x098)
>>>>   #define SPR_MPC_CMPE          (0x098)
>>>>   #define SPR_MPC_CMPF          (0x099)
>>>> +#define SPR_FSCR              (0x099)
>>>>   #define SPR_MPC_CMPG          (0x09A)
>>>>   #define SPR_MPC_CMPH          (0x09B)
>>>>   #define SPR_MPC_LCTRL1        (0x09C)
>>>> @@ -1461,6 +1466,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>>>   #define SPR_MPC_MI_CTR        (0x300)
>>>>   #define SPR_PERF1             (0x301)
>>>>   #define SPR_RCPU_MI_RBA1      (0x301)
>>>> +#define SPR_POWER_UMMCR2      (0x301)
>>>>   #define SPR_PERF2             (0x302)
>>>>   #define SPR_RCPU_MI_RBA2      (0x302)
>>>>   #define SPR_MPC_MI_AP         (0x302)
>>>> @@ -1500,6 +1506,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>>>   #define SPR_MPC_MD_TW         (0x30F)
>>>>   #define SPR_UPERF0            (0x310)
>>>>   #define SPR_UPERF1            (0x311)
>>>> +#define SPR_POWER_MMCR2       (0x311)
>>>>   #define SPR_UPERF2            (0x312)
>>>>   #define SPR_MMCRA             (0x312)
>>>>   #define SPR_UPERF3            (0x313)
>>>> @@ -1519,11 +1526,18 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>>>   #define SPR_UPERFF            (0x31F)
>>>>   #define SPR_RCPU_MI_RA0       (0x320)
>>>>   #define SPR_MPC_MI_DBCAM      (0x320)
>>>> +#define SPR_BESCRS            (0x320)
>>>>   #define SPR_RCPU_MI_RA1       (0x321)
>>>>   #define SPR_MPC_MI_DBRAM0     (0x321)
>>>> +#define SPR_BESCRSU           (0x321)
>>>>   #define SPR_RCPU_MI_RA2       (0x322)
>>>>   #define SPR_MPC_MI_DBRAM1     (0x322)
>>>> +#define SPR_BESCRR            (0x322)
>>>>   #define SPR_RCPU_MI_RA3       (0x323)
>>>> +#define SPR_BESCRRU           (0x323)
>>>> +#define SPR_EBBHR             (0x324)
>>>> +#define SPR_EBBRR             (0x325)
>>>> +#define SPR_BESCR             (0x326)
>>>>   #define SPR_RCPU_L2U_RA0      (0x328)
>>>>   #define SPR_MPC_MD_DBCAM      (0x328)
>>>>   #define SPR_RCPU_L2U_RA1      (0x329)
>>>> @@ -1542,6 +1556,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
>>>>   #define SPR_440_ITV3          (0x377)
>>>>   #define SPR_440_CCR1          (0x378)
>>>>   #define SPR_DCRIPR            (0x37B)
>>>> +#define SPR_MMCRS             (0x37E)
>>>>   #define SPR_PPR               (0x380)
>>>>   #define SPR_750_GQR0          (0x390)
>>>>   #define SPR_440_DNV0          (0x390)
>>>> diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
>>>> index 3c37e93..d23fcc6 100644
>>>> --- a/target-ppc/translate_init.c
>>>> +++ b/target-ppc/translate_init.c
>>>> @@ -7951,37 +7951,108 @@ POWERPC_FAMILY(POWER7P)(ObjectClass *oc, void
>>>> *data)
>>>>       pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
>>>>   }
>>>>   -static void init_proc_POWER8(CPUPPCState *env)
>>>> +static void get_spr_power8_branch_control(CPUPPCState *env)
>>>>   {
>>>> -    gen_spr_ne_601(env);
>>>> -    gen_spr_7xx(env);
>>>> -    /* Time base */
>>>> -    gen_tbl(env);
>>>> -    gen_spr_book3s_ids(env);
>>>> -    gen_spr_book3s_common(env);
>>>> -    gen_spr_amr(env);
>>>> -    gen_spr_book3s_vr(env);
>>>> -    gen_spr_book3s_lpar(env);
>>>> -    gen_spr_book3s_purr(env);
>>>> -    gen_spr_book3s_debug(env);
>>>> -    gen_spr_book3s_pmu(env);
>>>> -#if !defined(CONFIG_USER_ONLY)
>>>> -    env->slb_nr = 32;
>>>> -#endif /* !CONFIG_USER_ONLY */
>>>> -    init_excp_POWER7(env);
>>>> -    env->dcache_line_size = 128;
>>>> -    env->icache_line_size = 128;
>>>> -
>>>> -    /* Allocate hardware IRQ controller */
>>>> -    ppcPOWER7_irq_init(env);
>>>> -    /* Can't find information on what this should be on reset.  This
>>>> -     * value is the one used by 74xx processors. */
>>>> -    vscr_init(env, 0x00010000);
>>>> -
>>>>       spr_register(env, SPR_TAR, "TAR",
>>>>                    &spr_read_generic, &spr_write_generic,
>>>>                    &spr_read_generic, &spr_write_generic,
>>>>                    0x00000000);
>>>> +
>>>> +    spr_register(env, SPR_BESCRS, "BESCRS",
>>>> +                 SPR_NOACCESS, SPR_NOACCESS,
>>>> +                 &spr_read_generic, &spr_write_generic,
>>>> +                 0x00000000);
>>>> +    spr_register(env, SPR_BESCRSU, "BESCRSU",
>>>> +                 SPR_NOACCESS, SPR_NOACCESS,
>>>> +                 &spr_read_generic, &spr_write_generic,
>>>> +                 0x00000000);
>>>> +    spr_register(env, SPR_BESCRR, "BESCRR",
>>>> +                 SPR_NOACCESS, SPR_NOACCESS,
>>>> +                 &spr_read_generic, &spr_write_generic,
>>>> +                 0x00000000);
>>>> +    spr_register(env, SPR_BESCRRU, "BESCRRU",
>>>> +                 SPR_NOACCESS, SPR_NOACCESS,
>>>> +                 &spr_read_generic, &spr_write_generic,
>>>> +                 0x00000000);
>>>> +    spr_register_kvm(env, SPR_EBBHR, "EBBHR",
>>>> +                     SPR_NOACCESS, SPR_NOACCESS,
>>>> +                     &spr_read_generic, &spr_write_generic,
>>>> +                     KVM_REG_PPC_EBBHR, 0x00000000);
>>>> +    spr_register_kvm(env, SPR_EBBRR, "EBBRR",
>>>> +                     SPR_NOACCESS, SPR_NOACCESS,
>>>> +                     &spr_read_generic, &spr_write_generic,
>>>> +                     KVM_REG_PPC_EBBRR, 0x00000000);
>>>> +    spr_register_kvm(env, SPR_BESCR, "BESCR",
>>>> +                     SPR_NOACCESS, SPR_NOACCESS,
>>>> +                     &spr_read_generic, &spr_write_generic,
>>>> +                     KVM_REG_PPC_BESCR, 0x00000000);
>>>> +}
>>> These are all user-mode accessible, no?
>>>
>>>> +
>>>> +static void get_spr_power8_tm(CPUPPCState *env)
>>>> +{
>>>> +    spr_register_kvm(env, SPR_TFHAR, "TFHAR",
>>>> +                     SPR_NOACCESS, SPR_NOACCESS,
>>>> +                     &spr_read_generic, &spr_write_generic,
>>>> +                     KVM_REG_PPC_TFHAR, 0x00000000);
>>>> +    spr_register_kvm(env, SPR_TFIAR, "TFIAR",
>>>> +                     SPR_NOACCESS, SPR_NOACCESS,
>>>> +                     &spr_read_generic, &spr_write_generic,
>>>> +                     KVM_REG_PPC_TFIAR, 0x00000000);
>>>> +    spr_register_kvm(env, SPR_TEXASR, "TEXASR",
>>>> +                     SPR_NOACCESS, SPR_NOACCESS,
>>>> +                     &spr_read_generic, &spr_write_generic,
>>>> +                     KVM_REG_PPC_TEXASR, 0x00000000);
>>>> +    spr_register(env, SPR_TEXASRU, "TEXASRU",
>>>> +                 SPR_NOACCESS, SPR_NOACCESS,
>>>> +                 &spr_read_generic, &spr_write_generic,
>>>> +                 0x00000000);
>>>> +}
>>> Same comment.
>>>
>>> Also, the xxxU SPRs numbers refer to the upper half of 64-bit SPRs. 
>>> These are necessary
>>> to support access on 32-bit implementations.  It seems like some special
>>> spr access routines
>>> are required to support this.
>>
>> I am not familiar with TCG (yet)... Something like below? This uses the
>> fact that SPRs go consequently.
>>
>>
>> static void spr_read_upper32(void *opaque, int gprn, int sprn)
>> {
>>      TCGv spr64 = tcg_temp_new();
>>
>>      gen_load_spr(spr64, sprn - 1);
> 
> gen_load_spr() takes a GPR as argument, no?
> 
>>      tcg_gen_shr_i64(spr64, spr64, 32);
>>      tcg_gen_ext32u_tl(cpu_gpr[gprn], spr64);
> 
> If you use the deposit op you don't need a temp I think :). Also please
> compile with --enable-tcg-debug and check that you don't break ppc-softmmu.


trunc_shr_i32 should do it but I fail to see how would "deposit" (this one
- tcg_gen_deposit_i64?) help here.


> 
>>      tcg_temp_free(spr64);
>>      spr_store_dump_spr(sprn);
>> }
>>
>> static void spr_write_upper32(void *opaque, int sprn, int gprn)
>> {
>>      TCGv t0 = tcg_temp_new(), spr64 = tcg_temp_new();
>>
>>      tcg_gen_ext32u_tl(t0, cpu_gpr[gprn]);
>>      gen_load_spr(spr64, sprn - 1);
>>      tcg_gen_shl_i64(t0, t0, 32);
>>      tcg_gen_or_i64(spr64, spr64, t0);
> 
> Again, you're easier off with deposit.


Yes, here I can understand use of deposit.


> 
>>      gen_store_spr(sprn - 1, t0);
> 
> Uh, I don't think that works - see above.
> 
> 
> Alex
> 
>>
>>      tcg_temp_free(t0);
>>      tcg_temp_free(spr64);
>>      spr_store_dump_spr(sprn);
>> }
>>
>>
>>
>
diff mbox

Patch

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 262cf0f..72ed763 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1258,6 +1258,10 @@  static inline int cpu_mmu_index (CPUPPCState *env)
 #define SPR_MPC_EIE           (0x050)
 #define SPR_MPC_EID           (0x051)
 #define SPR_MPC_NRI           (0x052)
+#define SPR_TFHAR             (0x080)
+#define SPR_TFIAR             (0x081)
+#define SPR_TEXASR            (0x082)
+#define SPR_TEXASRU           (0x083)
 #define SPR_UCTRL             (0x088)
 #define SPR_MPC_CMPA          (0x090)
 #define SPR_MPC_CMPB          (0x091)
@@ -1270,6 +1274,7 @@  static inline int cpu_mmu_index (CPUPPCState *env)
 #define SPR_CTRL              (0x098)
 #define SPR_MPC_CMPE          (0x098)
 #define SPR_MPC_CMPF          (0x099)
+#define SPR_FSCR              (0x099)
 #define SPR_MPC_CMPG          (0x09A)
 #define SPR_MPC_CMPH          (0x09B)
 #define SPR_MPC_LCTRL1        (0x09C)
@@ -1461,6 +1466,7 @@  static inline int cpu_mmu_index (CPUPPCState *env)
 #define SPR_MPC_MI_CTR        (0x300)
 #define SPR_PERF1             (0x301)
 #define SPR_RCPU_MI_RBA1      (0x301)
+#define SPR_POWER_UMMCR2      (0x301)
 #define SPR_PERF2             (0x302)
 #define SPR_RCPU_MI_RBA2      (0x302)
 #define SPR_MPC_MI_AP         (0x302)
@@ -1500,6 +1506,7 @@  static inline int cpu_mmu_index (CPUPPCState *env)
 #define SPR_MPC_MD_TW         (0x30F)
 #define SPR_UPERF0            (0x310)
 #define SPR_UPERF1            (0x311)
+#define SPR_POWER_MMCR2       (0x311)
 #define SPR_UPERF2            (0x312)
 #define SPR_MMCRA             (0x312)
 #define SPR_UPERF3            (0x313)
@@ -1519,11 +1526,18 @@  static inline int cpu_mmu_index (CPUPPCState *env)
 #define SPR_UPERFF            (0x31F)
 #define SPR_RCPU_MI_RA0       (0x320)
 #define SPR_MPC_MI_DBCAM      (0x320)
+#define SPR_BESCRS            (0x320)
 #define SPR_RCPU_MI_RA1       (0x321)
 #define SPR_MPC_MI_DBRAM0     (0x321)
+#define SPR_BESCRSU           (0x321)
 #define SPR_RCPU_MI_RA2       (0x322)
 #define SPR_MPC_MI_DBRAM1     (0x322)
+#define SPR_BESCRR            (0x322)
 #define SPR_RCPU_MI_RA3       (0x323)
+#define SPR_BESCRRU           (0x323)
+#define SPR_EBBHR             (0x324)
+#define SPR_EBBRR             (0x325)
+#define SPR_BESCR             (0x326)
 #define SPR_RCPU_L2U_RA0      (0x328)
 #define SPR_MPC_MD_DBCAM      (0x328)
 #define SPR_RCPU_L2U_RA1      (0x329)
@@ -1542,6 +1556,7 @@  static inline int cpu_mmu_index (CPUPPCState *env)
 #define SPR_440_ITV3          (0x377)
 #define SPR_440_CCR1          (0x378)
 #define SPR_DCRIPR            (0x37B)
+#define SPR_MMCRS             (0x37E)
 #define SPR_PPR               (0x380)
 #define SPR_750_GQR0          (0x390)
 #define SPR_440_DNV0          (0x390)
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 3c37e93..d23fcc6 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -7951,37 +7951,108 @@  POWERPC_FAMILY(POWER7P)(ObjectClass *oc, void *data)
     pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
 }
 
-static void init_proc_POWER8(CPUPPCState *env)
+static void get_spr_power8_branch_control(CPUPPCState *env)
 {
-    gen_spr_ne_601(env);
-    gen_spr_7xx(env);
-    /* Time base */
-    gen_tbl(env);
-    gen_spr_book3s_ids(env);
-    gen_spr_book3s_common(env);
-    gen_spr_amr(env);
-    gen_spr_book3s_vr(env);
-    gen_spr_book3s_lpar(env);
-    gen_spr_book3s_purr(env);
-    gen_spr_book3s_debug(env);
-    gen_spr_book3s_pmu(env);
-#if !defined(CONFIG_USER_ONLY)
-    env->slb_nr = 32;
-#endif /* !CONFIG_USER_ONLY */
-    init_excp_POWER7(env);
-    env->dcache_line_size = 128;
-    env->icache_line_size = 128;
-
-    /* Allocate hardware IRQ controller */
-    ppcPOWER7_irq_init(env);
-    /* Can't find information on what this should be on reset.  This
-     * value is the one used by 74xx processors. */
-    vscr_init(env, 0x00010000);
-
     spr_register(env, SPR_TAR, "TAR",
                  &spr_read_generic, &spr_write_generic,
                  &spr_read_generic, &spr_write_generic,
                  0x00000000);
+
+    spr_register(env, SPR_BESCRS, "BESCRS",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_BESCRSU, "BESCRSU",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_BESCRR, "BESCRR",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_BESCRRU, "BESCRRU",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register_kvm(env, SPR_EBBHR, "EBBHR",
+                     SPR_NOACCESS, SPR_NOACCESS,
+                     &spr_read_generic, &spr_write_generic,
+                     KVM_REG_PPC_EBBHR, 0x00000000);
+    spr_register_kvm(env, SPR_EBBRR, "EBBRR",
+                     SPR_NOACCESS, SPR_NOACCESS,
+                     &spr_read_generic, &spr_write_generic,
+                     KVM_REG_PPC_EBBRR, 0x00000000);
+    spr_register_kvm(env, SPR_BESCR, "BESCR",
+                     SPR_NOACCESS, SPR_NOACCESS,
+                     &spr_read_generic, &spr_write_generic,
+                     KVM_REG_PPC_BESCR, 0x00000000);
+}
+
+static void get_spr_power8_tm(CPUPPCState *env)
+{
+    spr_register_kvm(env, SPR_TFHAR, "TFHAR",
+                     SPR_NOACCESS, SPR_NOACCESS,
+                     &spr_read_generic, &spr_write_generic,
+                     KVM_REG_PPC_TFHAR, 0x00000000);
+    spr_register_kvm(env, SPR_TFIAR, "TFIAR",
+                     SPR_NOACCESS, SPR_NOACCESS,
+                     &spr_read_generic, &spr_write_generic,
+                     KVM_REG_PPC_TFIAR, 0x00000000);
+    spr_register_kvm(env, SPR_TEXASR, "TEXASR",
+                     SPR_NOACCESS, SPR_NOACCESS,
+                     &spr_read_generic, &spr_write_generic,
+                     KVM_REG_PPC_TEXASR, 0x00000000);
+    spr_register(env, SPR_TEXASRU, "TEXASRU",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+}
+
+static void init_proc_POWER8(CPUPPCState *env)
+{
+    gen_spr_ne_601(env);
+    gen_spr_7xx(env);
+    /* Time base */
+    gen_tbl(env);
+    gen_spr_book3s_ids(env);
+    gen_spr_book3s_common(env);
+    gen_spr_amr(env);
+    gen_spr_book3s_vr(env);
+    gen_spr_book3s_lpar(env);
+    gen_spr_book3s_purr(env);
+    gen_spr_book3s_debug(env);
+    gen_spr_book3s_pmu(env);
+#if !defined(CONFIG_USER_ONLY)
+    env->slb_nr = 32;
+#endif /* !CONFIG_USER_ONLY */
+    init_excp_POWER7(env);
+    env->dcache_line_size = 128;
+    env->icache_line_size = 128;
+
+    /* Allocate hardware IRQ controller */
+    ppcPOWER7_irq_init(env);
+    /* Can't find information on what this should be on reset.  This
+     * value is the one used by 74xx processors. */
+    vscr_init(env, 0x00010000);
+
+    get_spr_power8_branch_control(env);
+    get_spr_power8_tm(env);
+    spr_register(env, SPR_POWER_MMCR2, "MMCR2",
+                 &spr_read_generic, &spr_write_generic,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register_kvm(env, SPR_POWER_UMMCR2, "UMMCR2",
+                     SPR_NOACCESS, SPR_NOACCESS,
+                     &spr_read_generic, &spr_write_generic,
+                     KVM_REG_PPC_MMCR2, 0x00000000);
+    spr_register_kvm(env, SPR_FSCR, "FSCR",
+                     SPR_NOACCESS, SPR_NOACCESS,
+                     &spr_read_generic, &spr_write_generic,
+                     KVM_REG_PPC_FSCR, 0x00000000);
+    spr_register_kvm(env, SPR_MMCRS, "MMCRS",
+                     SPR_NOACCESS, SPR_NOACCESS,
+                     &spr_read_generic, &spr_write_generic,
+                     KVM_REG_PPC_MMCRS, 0x00000000);
 }
 
 POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)