Revision 2ace7e55 target-alpha/translate.c
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