Revision 6f27aba6

b/target-sparc/cpu.h
98 98
#define PS_AG    (1<<0)
99 99

  
100 100
#define FPRS_FEF (1<<2)
101

  
102
#define HS_PRIV  (1<<2)
101 103
#endif
102 104

  
103 105
/* Fcc */
......
166 168

  
167 169
typedef struct sparc_def_t sparc_def_t;
168 170

  
171
#if !defined(TARGET_SPARC64)
169 172
#define NB_MMU_MODES 2
173
#else
174
#define NB_MMU_MODES 3
175
#endif
170 176

  
171 177
typedef struct CPUSPARCState {
172 178
    target_ulong gregs[8]; /* general registers */
......
323 329
#define cpu_list sparc_cpu_list
324 330

  
325 331
/* MMU modes definitions */
326
#define MMU_MODE0_SUFFIX _kernel
327
#define MMU_MODE1_SUFFIX _user
328
#define MMU_USER_IDX 1
332
#define MMU_MODE0_SUFFIX _user
333
#define MMU_MODE1_SUFFIX _kernel
334
#ifdef TARGET_SPARC64
335
#define MMU_MODE2_SUFFIX _hypv
336
#endif
337
#define MMU_USER_IDX 0
329 338
static inline int cpu_mmu_index (CPUState *env)
330 339
{
331
    return env->psrs == 0 ? 1 : 0;
340
#if defined(CONFIG_USER_ONLY)
341
    return 0;
342
#elif !defined(TARGET_SPARC64)
343
    return env->psrs;
344
#else
345
    if (!env->psrs)
346
        return 0;
347
    else if ((env->hpstate & HS_PRIV) == 0)
348
        return 1;
349
    else
350
        return 2;
351
#endif
352
}
353

  
354
static inline int cpu_fpu_enabled(CPUState *env)
355
{
356
#if defined(CONFIG_USER_ONLY)
357
    return 1;
358
#elif !defined(TARGET_SPARC64)
359
    return env->psref;
360
#else
361
    return ((env->pstate & PS_PEF) != 0) && ((env->fprs & FPRS_FEF) != 0);
362
#endif
332 363
}
333 364

  
334 365
#include "cpu-all.h"
b/target-sparc/op.c
1023 1023

  
1024 1024
#define MEMSUFFIX _kernel
1025 1025
#include "op_mem.h"
1026

  
1027
#ifdef TARGET_SPARC64
1028
#define MEMSUFFIX _hypv
1029
#include "op_mem.h"
1030
#endif
1026 1031
#endif
1027 1032

  
1028 1033
void OPPROTO op_ldfsr(void)
b/target-sparc/op_helper.c
789 789
{
790 790
    uint64_t ret = 0;
791 791

  
792
    if (asi < 0x80 && (env->pstate & PS_PRIV) == 0)
792
    if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
793
        || (asi >= 0x30 && asi < 0x80) && !(env->hpstate & HS_PRIV))
793 794
        raise_exception(TT_PRIV_ACT);
794 795

  
795 796
    switch (asi) {
......
800 801
    case 0x88: // Primary LE
801 802
    case 0x8a: // Primary no-fault LE
802 803
        if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
803
            switch(size) {
804
            case 1:
805
                ret = ldub_kernel(T0);
806
                break;
807
            case 2:
808
                ret = lduw_kernel(T0 & ~1);
809
                break;
810
            case 4:
811
                ret = ldl_kernel(T0 & ~3);
812
                break;
813
            default:
814
            case 8:
815
                ret = ldq_kernel(T0 & ~7);
816
                break;
804
            if (env->hpstate & HS_PRIV) {
805
                switch(size) {
806
                case 1:
807
                    ret = ldub_hypv(T0);
808
                    break;
809
                case 2:
810
                    ret = lduw_hypv(T0 & ~1);
811
                    break;
812
                case 4:
813
                    ret = ldl_hypv(T0 & ~3);
814
                    break;
815
                default:
816
                case 8:
817
                    ret = ldq_hypv(T0 & ~7);
818
                    break;
819
                }
820
            } else {
821
                switch(size) {
822
                case 1:
823
                    ret = ldub_kernel(T0);
824
                    break;
825
                case 2:
826
                    ret = lduw_kernel(T0 & ~1);
827
                    break;
828
                case 4:
829
                    ret = ldl_kernel(T0 & ~3);
830
                    break;
831
                default:
832
                case 8:
833
                    ret = ldq_kernel(T0 & ~7);
834
                    break;
835
                }
817 836
            }
818 837
        } else {
819 838
            switch(size) {
......
987 1006

  
988 1007
void helper_st_asi(int asi, int size)
989 1008
{
990
    if (asi < 0x80 && (env->pstate & PS_PRIV) == 0)
1009
    if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
1010
        || (asi >= 0x30 && asi < 0x80) && !(env->hpstate & HS_PRIV))
991 1011
        raise_exception(TT_PRIV_ACT);
992 1012

  
993 1013
    /* Convert to little endian */
......
1022 1042
    case 0x80: // Primary
1023 1043
    case 0x88: // Primary LE
1024 1044
        if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
1025
            switch(size) {
1026
            case 1:
1027
                stb_kernel(T0, T1);
1028
                break;
1029
            case 2:
1030
                stw_kernel(T0 & ~1, T1);
1031
                break;
1032
            case 4:
1033
                stl_kernel(T0 & ~3, T1);
1034
                break;
1035
            case 8:
1036
            default:
1037
                stq_kernel(T0 & ~7, T1);
1038
                break;
1045
            if (env->hpstate & HS_PRIV) {
1046
                switch(size) {
1047
                case 1:
1048
                    stb_hypv(T0, T1);
1049
                    break;
1050
                case 2:
1051
                    stw_hypv(T0 & ~1, T1);
1052
                    break;
1053
                case 4:
1054
                    stl_hypv(T0 & ~3, T1);
1055
                    break;
1056
                case 8:
1057
                default:
1058
                    stq_hypv(T0 & ~7, T1);
1059
                    break;
1060
                }
1061
            } else {
1062
                switch(size) {
1063
                case 1:
1064
                    stb_kernel(T0, T1);
1065
                    break;
1066
                case 2:
1067
                    stw_kernel(T0 & ~1, T1);
1068
                    break;
1069
                case 4:
1070
                    stl_kernel(T0 & ~3, T1);
1071
                    break;
1072
                case 8:
1073
                default:
1074
                    stq_kernel(T0 & ~7, T1);
1075
                    break;
1076
                }
1039 1077
            }
1040 1078
        } else {
1041 1079
            switch(size) {
b/target-sparc/translate.c
361 361
#endif
362 362
#define gen_op_ldst(name)        gen_op_##name##_raw()
363 363
#else
364
#define supervisor(dc) (dc->mem_idx == 1)
364
#define supervisor(dc) (dc->mem_idx >= 1)
365 365
#ifdef TARGET_SPARC64
366 366
#define hypervisor(dc) (dc->mem_idx == 2)
367
#endif
368
#define gen_op_ldst(name)        (*gen_op_##name[dc->mem_idx])()
367
#define OP_LD_TABLE(width)                                              \
368
    static GenOpFunc * const gen_op_##width[] = {                       \
369
        &gen_op_##width##_user,                                         \
370
        &gen_op_##width##_kernel,                                       \
371
        &gen_op_##width##_hypv,                                         \
372
    };
373
#else
369 374
#define OP_LD_TABLE(width)                                              \
370 375
    static GenOpFunc * const gen_op_##width[] = {                       \
371 376
        &gen_op_##width##_user,                                         \
372 377
        &gen_op_##width##_kernel,                                       \
373 378
    };
374 379
#endif
380
#define gen_op_ldst(name)        (*gen_op_##name[dc->mem_idx])()
381
#endif
375 382

  
376 383
#ifndef CONFIG_USER_ONLY
377 384
OP_LD_TABLE(ld);
......
3378 3385
    dc->pc = pc_start;
3379 3386
    last_pc = dc->pc;
3380 3387
    dc->npc = (target_ulong) tb->cs_base;
3381
#if defined(CONFIG_USER_ONLY)
3382
    dc->mem_idx = 0;
3383
    dc->fpu_enabled = 1;
3384
#else
3385
    dc->mem_idx = ((env->psrs) != 0);
3386
#ifdef TARGET_SPARC64
3387
    dc->fpu_enabled = (((env->pstate & PS_PEF) != 0) && ((env->fprs & FPRS_FEF) != 0));
3388
#else
3389
    dc->fpu_enabled = ((env->psref) != 0);
3390
#endif
3391
#endif
3388
    dc->mem_idx = cpu_mmu_index(env);
3389
    dc->fpu_enabled = cpu_fpu_enabled(env);
3392 3390
    gen_opc_ptr = gen_opc_buf;
3393 3391
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
3394 3392
    gen_opparam_ptr = gen_opparam_buf;
......
3522 3520
    env->psrps = 1;
3523 3521
#ifdef TARGET_SPARC64
3524 3522
    env->pstate = PS_PRIV;
3523
    env->hpstate = HS_PRIV;
3525 3524
    env->pc = 0x1fff0000000ULL;
3526 3525
#else
3527 3526
    env->pc = 0;

Also available in: Unified diff