Revision 2ace7e55

b/target-alpha/translate.c
85 85
static TCGv cpu_lock_addr;
86 86
static TCGv cpu_lock_st_addr;
87 87
static TCGv cpu_lock_value;
88
#ifdef CONFIG_USER_ONLY
89
static TCGv cpu_uniq;
88
static TCGv cpu_unique;
89
#ifndef CONFIG_USER_ONLY
90
static TCGv cpu_sysval;
91
static TCGv cpu_usp;
90 92
#endif
91 93

  
92 94
/* register names */
......
131 133
					    offsetof(CPUState, lock_value),
132 134
					    "lock_value");
133 135

  
134
#ifdef CONFIG_USER_ONLY
135
    cpu_uniq = tcg_global_mem_new_i64(TCG_AREG0,
136
                                      offsetof(CPUState, unique), "uniq");
136
    cpu_unique = tcg_global_mem_new_i64(TCG_AREG0,
137
                                        offsetof(CPUState, unique), "unique");
138
#ifndef CONFIG_USER_ONLY
139
    cpu_sysval = tcg_global_mem_new_i64(TCG_AREG0,
140
                                        offsetof(CPUState, sysval), "sysval");
141
    cpu_usp = tcg_global_mem_new_i64(TCG_AREG0,
142
                                     offsetof(CPUState, usp), "usp");
137 143
#endif
138 144

  
139 145
    /* register helpers */
......
1464 1470
    tcg_temp_free_i32(tmp);
1465 1471
}
1466 1472

  
1473
static ExitStatus gen_call_pal(DisasContext *ctx, int palcode)
1474
{
1475
    /* We're emulating OSF/1 PALcode.  Many of these are trivial access
1476
       to internal cpu registers.  */
1477

  
1478
    /* Unprivileged PAL call */
1479
    if (palcode >= 0x80 && palcode < 0xC0) {
1480
        switch (palcode) {
1481
        case 0x86:
1482
            /* IMB */
1483
            /* No-op inside QEMU.  */
1484
            break;
1485
        case 0x9E:
1486
            /* RDUNIQUE */
1487
            tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_unique);
1488
            break;
1489
        case 0x9F:
1490
            /* WRUNIQUE */
1491
            tcg_gen_mov_i64(cpu_unique, cpu_ir[IR_A0]);
1492
            break;
1493
        default:
1494
            return gen_excp(ctx, EXCP_CALL_PAL, palcode & 0xbf);
1495
        }
1496
        return NO_EXIT;
1497
    }
1498

  
1499
#ifndef CONFIG_USER_ONLY
1500
    /* Privileged PAL code */
1501
    if (palcode < 0x40 && (ctx->tb->flags & TB_FLAGS_USER_MODE) == 0) {
1502
        switch (palcode) {
1503
        case 0x01:
1504
            /* CFLUSH */
1505
            /* No-op inside QEMU.  */
1506
            break;
1507
        case 0x02:
1508
            /* DRAINA */
1509
            /* No-op inside QEMU.  */
1510
            break;
1511
        case 0x2D:
1512
            /* WRVPTPTR */
1513
            tcg_gen_st_i64(cpu_ir[IR_A0], cpu_env, offsetof(CPUState, vptptr));
1514
            break;
1515
        case 0x31:
1516
            /* WRVAL */
1517
            tcg_gen_mov_i64(cpu_sysval, cpu_ir[IR_A0]);
1518
            break;
1519
        case 0x32:
1520
            /* RDVAL */
1521
            tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_sysval);
1522
            break;
1523

  
1524
        case 0x35: {
1525
            /* SWPIPL */
1526
            TCGv tmp;
1527

  
1528
            /* Note that we already know we're in kernel mode, so we know
1529
               that PS only contains the 3 IPL bits.  */
1530
            tcg_gen_ld8u_i64(cpu_ir[IR_V0], cpu_env, offsetof(CPUState, ps));
1531

  
1532
            /* But make sure and store only the 3 IPL bits from the user.  */
1533
            tmp = tcg_temp_new();
1534
            tcg_gen_andi_i64(tmp, cpu_ir[IR_A0], PS_INT_MASK);
1535
            tcg_gen_st8_i64(tmp, cpu_env, offsetof(CPUState, ps));
1536
            tcg_temp_free(tmp);
1537
            break;
1538
        }
1539

  
1540
        case 0x36:
1541
            /* RDPS */
1542
            tcg_gen_ld8u_i64(cpu_ir[IR_V0], cpu_env, offsetof(CPUState, ps));
1543
            break;
1544
        case 0x38:
1545
            /* WRUSP */
1546
            tcg_gen_mov_i64(cpu_usp, cpu_ir[IR_A0]);
1547
            break;
1548
        case 0x3A:
1549
            /* RDUSP */
1550
            tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_usp);
1551
            break;
1552
        case 0x3C:
1553
            /* WHAMI */
1554
            tcg_gen_ld32s_i64(cpu_ir[IR_V0], cpu_env,
1555
                              offsetof(CPUState, cpu_index));
1556
            break;
1557

  
1558
        default:
1559
            return gen_excp(ctx, EXCP_CALL_PAL, palcode & 0x3f);
1560
        }
1561
        return NO_EXIT;
1562
    }
1563
#endif
1564

  
1565
    return gen_invalid(ctx);
1566
}
1567

  
1467 1568
#ifndef CONFIG_USER_ONLY
1468 1569

  
1469 1570
#define PR_BYTE         0x100000
......
1582 1683
    switch (opc) {
1583 1684
    case 0x00:
1584 1685
        /* CALL_PAL */
1585
#ifdef CONFIG_USER_ONLY
1586
        if (palcode == 0x9E) {
1587
            /* RDUNIQUE */
1588
            tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_uniq);
1589
            break;
1590
        } else if (palcode == 0x9F) {
1591
            /* WRUNIQUE */
1592
            tcg_gen_mov_i64(cpu_uniq, cpu_ir[IR_A0]);
1593
            break;
1594
        }
1595
#endif
1596
        if (palcode >= 0x80 && palcode < 0xC0) {
1597
            /* Unprivileged PAL call */
1598
            ret = gen_excp(ctx, EXCP_CALL_PAL, palcode & 0xBF);
1599
            break;
1600
        }
1601
#ifndef CONFIG_USER_ONLY
1602
        if (palcode < 0x40) {
1603
            /* Privileged PAL code */
1604
            if (ctx->mem_idx != MMU_KERNEL_IDX) {
1605
                goto invalid_opc;
1606
            }
1607
            ret = gen_excp(ctx, EXCP_CALL_PAL, palcode & 0x3F);
1608
        }
1609
#endif
1610
        /* Invalid PAL call */
1611
        goto invalid_opc;
1686
        ret = gen_call_pal(ctx, palcode);
1687
        break;
1612 1688
    case 0x01:
1613 1689
        /* OPC01 */
1614 1690
        goto invalid_opc;

Also available in: Unified diff