Revision be147d08

b/target-ppc/cpu.h
287 287

  
288 288
#define PPC_INPUT(env) (env->bus_model)
289 289

  
290
/*****************************************************************************/
290 291
typedef struct ppc_def_t ppc_def_t;
291 292
typedef struct opc_handler_t opc_handler_t;
292 293

  
......
306 307
#if !defined(CONFIG_USER_ONLY)
307 308
    void (*oea_read)(void *opaque, int spr_num);
308 309
    void (*oea_write)(void *opaque, int spr_num);
310
#if defined(TARGET_PPC64H)
311
    void (*hea_read)(void *opaque, int spr_num);
312
    void (*hea_write)(void *opaque, int spr_num);
313
#endif
309 314
#endif
310 315
    const unsigned char *name;
311 316
};
......
607 612
void ppc_store_xer (CPUPPCState *env, target_ulong value);
608 613
target_ulong do_load_msr (CPUPPCState *env);
609 614
void do_store_msr (CPUPPCState *env, target_ulong value);
615
#if defined(TARGET_PPC64)
610 616
void ppc_store_msr_32 (CPUPPCState *env, uint32_t value);
617
#endif
611 618

  
612 619
void do_compute_hflags (CPUPPCState *env);
613 620
void cpu_ppc_reset (void *opaque);
b/target-ppc/op.c
355 355
    RETURN();
356 356
}
357 357

  
358
void OPPROTO op_update_riee (void)
359
{
360
    msr_ri = (T0 >> MSR_RI) & 1;
361
    msr_ee = (T0 >> MSR_EE) & 1;
362
    RETURN();
363
}
364

  
358 365
#if defined (TARGET_PPC64)
359 366
void OPPROTO op_store_msr_32 (void)
360 367
{
......
1913 1920
}
1914 1921
#endif
1915 1922

  
1923
void OPPROTO op_wait (void)
1924
{
1925
    env->halted = 1;
1926
    RETURN();
1927
}
1928

  
1916 1929
/* Return from interrupt */
1917 1930
#if !defined(CONFIG_USER_ONLY)
1918 1931
void OPPROTO op_rfi (void)
......
1928 1941
    RETURN();
1929 1942
}
1930 1943
#endif
1944

  
1945
#if defined(TARGET_PPC64H)
1946
void OPPROTO op_hrfid (void)
1947
{
1948
    do_hrfid();
1949
    RETURN();
1950
}
1951
#endif
1931 1952
#endif
1932 1953

  
1933 1954
/* Trap word */
......
2557 2578
void OPPROTO op_store_40x_dbcr0 (void)
2558 2579
{
2559 2580
    store_40x_dbcr0(env, T0);
2581
    RETURN();
2560 2582
}
2561 2583

  
2562 2584
void OPPROTO op_store_40x_sler (void)
......
2576 2598
    store_booke_tsr(env, T0);
2577 2599
    RETURN();
2578 2600
}
2579

  
2580 2601
#endif /* !defined(CONFIG_USER_ONLY) */
2581 2602

  
2582 2603
#if defined(TARGET_PPCEMB)
b/target-ppc/op_helper.c
1002 1002
    env->interrupt_request |= CPU_INTERRUPT_EXITTB;
1003 1003
}
1004 1004
#endif
1005
#if defined(TARGET_PPC64H)
1006
void do_hrfid (void)
1007
{
1008
    if (env->spr[SPR_HSRR1] & (1ULL << MSR_SF)) {
1009
        env->nip = (uint64_t)(env->spr[SPR_HSRR0] & ~0x00000003);
1010
        do_store_msr(env, (uint64_t)(env->spr[SPR_HSRR1] & ~0xFFFF0000UL));
1011
    } else {
1012
        env->nip = (uint32_t)(env->spr[SPR_HSRR0] & ~0x00000003);
1013
        do_store_msr(env, (uint32_t)(env->spr[SPR_HSRR1] & ~0xFFFF0000UL));
1014
    }
1015
#if defined (DEBUG_OP)
1016
    cpu_dump_rfi(env->nip, do_load_msr(env));
1017
#endif
1018
    env->interrupt_request |= CPU_INTERRUPT_EXITTB;
1019
}
1020
#endif
1005 1021
#endif
1006 1022

  
1007 1023
void do_tw (int flags)
b/target-ppc/op_helper.h
131 131
#if defined(TARGET_PPC64)
132 132
void do_rfid (void);
133 133
#endif
134
#if defined(TARGET_PPC64H)
135
void do_hrfid (void);
136
#endif
134 137
void do_tlbia (void);
135 138
void do_tlbie (void);
136 139
#if defined(TARGET_PPC64)
b/target-ppc/translate.c
480 480
    PPC_FLOAT_EXT     = 0x0000080000000000ULL,
481 481
    /* New wait instruction (PowerPC 2.0x)              */
482 482
    PPC_WAIT          = 0x0000100000000000ULL,
483
    /* New 64 bits extensions (PowerPC 2.0x)            */
484
    PPC_64BX          = 0x0000200000000000ULL,
483 485
};
484 486

  
485 487
/*****************************************************************************/
......
1141 1143
            /* Set process priority to normal */
1142 1144
            gen_op_store_pri(4);
1143 1145
            break;
1146
#if !defined(CONFIG_USER_ONLY)
1147
        case 31:
1148
            if (ctx->supervisor > 0) {
1149
                /* Set process priority to very low */
1150
                gen_op_store_pri(1);
1151
            }
1152
            break;
1153
        case 5:
1154
            if (ctx->supervisor > 0) {
1155
                /* Set process priority to medium-hight */
1156
                gen_op_store_pri(5);
1157
            }
1158
            break;
1159
        case 3:
1160
            if (ctx->supervisor > 0) {
1161
                /* Set process priority to high */
1162
                gen_op_store_pri(6);
1163
            }
1164
            break;
1165
#if defined(TARGET_PPC64H)
1166
        case 7:
1167
            if (ctx->supervisor > 1) {
1168
                /* Set process priority to very high */
1169
                gen_op_store_pri(7);
1170
            }
1171
            break;
1172
#endif
1173
#endif
1144 1174
        default:
1145 1175
            /* nop */
1146 1176
            break;
......
1902 1932

  
1903 1933
/***                           Addressing modes                            ***/
1904 1934
/* Register indirect with immediate index : EA = (rA|0) + SIMM */
1905
static inline void gen_addr_imm_index (DisasContext *ctx, int maskl)
1935
static inline void gen_addr_imm_index (DisasContext *ctx, target_long maskl)
1906 1936
{
1907 1937
    target_long simm = SIMM(ctx->opcode);
1908 1938

  
1909
    if (maskl)
1910
        simm &= ~0x03;
1939
    simm &= ~maskl;
1911 1940
    if (rA(ctx->opcode) == 0) {
1912 1941
        gen_set_T0(simm);
1913 1942
    } else {
......
2051 2080
        return;                                                               \
2052 2081
    }                                                                         \
2053 2082
    if (type == PPC_64B)                                                      \
2054
        gen_addr_imm_index(ctx, 1);                                           \
2083
        gen_addr_imm_index(ctx, 0x03);                                        \
2055 2084
    else                                                                      \
2056 2085
        gen_addr_imm_index(ctx, 0);                                           \
2057 2086
    op_ldst(l##width);                                                        \
......
2116 2145
            return;
2117 2146
        }
2118 2147
    }
2119
    gen_addr_imm_index(ctx, 1);
2148
    gen_addr_imm_index(ctx, 0x03);
2120 2149
    if (ctx->opcode & 0x02) {
2121 2150
        /* lwa (lwau is undefined) */
2122 2151
        op_ldst(lwa);
......
2128 2157
    if (Rc(ctx->opcode))
2129 2158
        gen_op_store_T0_gpr(rA(ctx->opcode));
2130 2159
}
2160
/* lq */
2161
GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX)
2162
{
2163
#if defined(CONFIG_USER_ONLY)
2164
    GEN_EXCP_PRIVOPC(ctx);
2165
#else
2166
    int ra, rd;
2167

  
2168
    /* Restore CPU state */
2169
    if (unlikely(ctx->supervisor == 0)) {
2170
        GEN_EXCP_PRIVOPC(ctx);
2171
        return;
2172
    }
2173
    ra = rA(ctx->opcode);
2174
    rd = rD(ctx->opcode);
2175
    if (unlikely((rd & 1) || rd == ra)) {
2176
        GEN_EXCP_INVAL(ctx);
2177
        return;
2178
    }
2179
    if (unlikely(ctx->mem_idx & 1)) {
2180
        /* Little-endian mode is not handled */
2181
        GEN_EXCP(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
2182
        return;
2183
    }
2184
    gen_addr_imm_index(ctx, 0x0F);
2185
    op_ldst(ld);
2186
    gen_op_store_T1_gpr(rd);
2187
    gen_op_addi(8);
2188
    op_ldst(ld);
2189
    gen_op_store_T1_gpr(rd + 1);
2190
#endif
2191
}
2131 2192
#endif
2132 2193

  
2133 2194
/***                              Integer store                            ***/
......
2147 2208
        return;                                                               \
2148 2209
    }                                                                         \
2149 2210
    if (type == PPC_64B)                                                      \
2150
        gen_addr_imm_index(ctx, 1);                                           \
2211
        gen_addr_imm_index(ctx, 0x03);                                        \
2151 2212
    else                                                                      \
2152 2213
        gen_addr_imm_index(ctx, 0);                                           \
2153 2214
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
......
2193 2254
OP_ST_TABLE(d);
2194 2255
GEN_STUX(d, 0x15, 0x05, PPC_64B);
2195 2256
GEN_STX(d, 0x15, 0x04, PPC_64B);
2196
GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000002, PPC_64B)
2257
GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B)
2197 2258
{
2198
    if (Rc(ctx->opcode)) {
2199
        if (unlikely(rA(ctx->opcode) == 0)) {
2259
    int rs;
2260

  
2261
    rs = rS(ctx->opcode);
2262
    if ((ctx->opcode & 0x3) == 0x2) {
2263
#if defined(CONFIG_USER_ONLY)
2264
        GEN_EXCP_PRIVOPC(ctx);
2265
#else
2266
        /* stq */
2267
        if (unlikely(ctx->supervisor == 0)) {
2268
            GEN_EXCP_PRIVOPC(ctx);
2269
            return;
2270
        }
2271
        if (unlikely(rs & 1)) {
2200 2272
            GEN_EXCP_INVAL(ctx);
2201 2273
            return;
2202 2274
        }
2275
        if (unlikely(ctx->mem_idx & 1)) {
2276
            /* Little-endian mode is not handled */
2277
            GEN_EXCP(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
2278
            return;
2279
        }
2280
        gen_addr_imm_index(ctx, 0x03);
2281
        gen_op_load_gpr_T1(rs);
2282
        op_ldst(std);
2283
        gen_op_addi(8);
2284
        gen_op_load_gpr_T1(rs + 1);
2285
        op_ldst(std);
2286
#endif
2287
    } else {
2288
        /* std / stdu */
2289
        if (Rc(ctx->opcode)) {
2290
            if (unlikely(rA(ctx->opcode) == 0)) {
2291
                GEN_EXCP_INVAL(ctx);
2292
                return;
2293
            }
2294
        }
2295
        gen_addr_imm_index(ctx, 0x03);
2296
        gen_op_load_gpr_T1(rs);
2297
        op_ldst(std);
2298
        if (Rc(ctx->opcode))
2299
            gen_op_store_T0_gpr(rA(ctx->opcode));
2203 2300
    }
2204
    gen_addr_imm_index(ctx, 1);
2205
    gen_op_load_gpr_T1(rS(ctx->opcode));
2206
    op_ldst(std);
2207
    if (Rc(ctx->opcode))
2208
        gen_op_store_T0_gpr(rA(ctx->opcode));
2209 2301
}
2210 2302
#endif
2211 2303
/***                Integer load and store with byte reverse               ***/
......
2620 2712
GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x03FFF801, PPC_WAIT)
2621 2713
{
2622 2714
    /* Stop translation, as the CPU is supposed to sleep from now */
2623
    /* XXX: TODO: handle this idle CPU case */
2624
    GEN_STOP(ctx);
2715
    gen_op_wait();
2716
    GEN_EXCP(ctx, EXCP_HLT, 1);
2625 2717
}
2626 2718

  
2627 2719
/***                         Floating-point load                           ***/
......
3077 3169
}
3078 3170
#endif
3079 3171

  
3172
#if defined(TARGET_PPC64H)
3173
GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64B)
3174
{
3175
#if defined(CONFIG_USER_ONLY)
3176
    GEN_EXCP_PRIVOPC(ctx);
3177
#else
3178
    /* Restore CPU state */
3179
    if (unlikely(ctx->supervisor <= 1)) {
3180
        GEN_EXCP_PRIVOPC(ctx);
3181
        return;
3182
    }
3183
    gen_op_hrfid();
3184
    GEN_SYNC(ctx);
3185
#endif
3186
}
3187
#endif
3188

  
3080 3189
/* sc */
3081 3190
GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW)
3082 3191
{
......
3193 3302
    uint32_t sprn = SPR(ctx->opcode);
3194 3303

  
3195 3304
#if !defined(CONFIG_USER_ONLY)
3305
#if defined(TARGET_PPC64H)
3306
    if (ctx->supervisor == 2)
3307
        read_cb = ctx->spr_cb[sprn].hea_read;
3308
    else
3309
#endif
3196 3310
    if (ctx->supervisor)
3197 3311
        read_cb = ctx->spr_cb[sprn].oea_read;
3198 3312
    else
......
3253 3367

  
3254 3368
/* mtmsr */
3255 3369
#if defined(TARGET_PPC64)
3256
GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001FF801, PPC_64B)
3370
GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B)
3257 3371
{
3258 3372
#if defined(CONFIG_USER_ONLY)
3259 3373
    GEN_EXCP_PRIVREG(ctx);
......
3262 3376
        GEN_EXCP_PRIVREG(ctx);
3263 3377
        return;
3264 3378
    }
3265
    gen_update_nip(ctx, ctx->nip);
3266 3379
    gen_op_load_gpr_T0(rS(ctx->opcode));
3267
    gen_op_store_msr();
3268
    /* Must stop the translation as machine state (may have) changed */
3269
    /* Note that mtmsr is not always defined as context-synchronizing */
3270
    GEN_STOP(ctx);
3380
    if (ctx->opcode & 0x00010000) {
3381
        /* Special form that does not need any synchronisation */
3382
        gen_op_update_riee();
3383
    } else {
3384
        gen_update_nip(ctx, ctx->nip);
3385
        gen_op_store_msr();
3386
        /* Must stop the translation as machine state (may have) changed */
3387
        /* Note that mtmsr is not always defined as context-synchronizing */
3388
        GEN_STOP(ctx);
3389
    }
3271 3390
#endif
3272 3391
}
3273 3392
#endif
......
3281 3400
        GEN_EXCP_PRIVREG(ctx);
3282 3401
        return;
3283 3402
    }
3284
    gen_update_nip(ctx, ctx->nip);
3285 3403
    gen_op_load_gpr_T0(rS(ctx->opcode));
3404
    if (ctx->opcode & 0x00010000) {
3405
        /* Special form that does not need any synchronisation */
3406
        gen_op_update_riee();
3407
    } else {
3408
        gen_update_nip(ctx, ctx->nip);
3286 3409
#if defined(TARGET_PPC64)
3287
    if (!ctx->sf_mode)
3288
        gen_op_store_msr_32();
3289
    else
3410
        if (!ctx->sf_mode)
3411
            gen_op_store_msr_32();
3412
        else
3290 3413
#endif
3291
        gen_op_store_msr();
3292
    /* Must stop the translation as machine state (may have) changed */
3293
    /* Note that mtmsrd is not always defined as context-synchronizing */
3294
    GEN_STOP(ctx);
3414
            gen_op_store_msr();
3415
        /* Must stop the translation as machine state (may have) changed */
3416
        /* Note that mtmsrd is not always defined as context-synchronizing */
3417
        GEN_STOP(ctx);
3418
    }
3295 3419
#endif
3296 3420
}
3297 3421

  
......
3302 3426
    uint32_t sprn = SPR(ctx->opcode);
3303 3427

  
3304 3428
#if !defined(CONFIG_USER_ONLY)
3429
#if defined(TARGET_PPC64H)
3430
    if (ctx->supervisor == 2)
3431
        write_cb = ctx->spr_cb[sprn].hea_write;
3432
    else
3433
#endif
3305 3434
    if (ctx->supervisor)
3306 3435
        write_cb = ctx->spr_cb[sprn].oea_write;
3307 3436
    else
......
6011 6140
    ctx.mem_idx |= msr_sf << 1;
6012 6141
#endif
6013 6142
#else
6014
    ctx.supervisor = 1 - msr_pr;
6143
#if defined(TARGET_PPC64H)
6144
    if (msr_pr == 0 && msr_hv == 1)
6145
        ctx.supervisor = 2;
6146
    else
6147
#endif
6148
        ctx.supervisor = 1 - msr_pr;
6015 6149
    ctx.mem_idx = ((1 - msr_pr) << 1) | msr_le;
6016 6150
#if defined(TARGET_PPC64)
6017 6151
    ctx.mem_idx |= msr_sf << 2;

Also available in: Unified diff