Skip to content

Commit 515d513

Browse files
committed
feat!: update PPC to 5.1.0
1 parent b6306df commit 515d513

File tree

10 files changed

+579
-473
lines changed

10 files changed

+579
-473
lines changed

qemu/target/ppc/cpu.h

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,9 @@ enum {
129129
POWERPC_EXCP_SDOOR_HV = 100,
130130
/* ISA 3.00 additions */
131131
POWERPC_EXCP_HVIRT = 101,
132+
POWERPC_EXCP_SYSCALL_VECTORED = 102, /* scv exception */
132133
/* EOL */
133-
POWERPC_EXCP_NB = 102,
134+
POWERPC_EXCP_NB = 103,
134135
/* QEMU exceptions: used internally during code translation */
135136
POWERPC_EXCP_STOP = 0x200, /* stop translation */
136137
POWERPC_EXCP_BRANCH = 0x201, /* branch instruction */
@@ -460,6 +461,9 @@ typedef struct ppc_v3_pate_t {
460461
#define DSISR_AMR 0x00200000
461462
/* Unsupported Radix Tree Configuration */
462463
#define DSISR_R_BADCONFIG 0x00080000
464+
#define DSISR_ATOMIC_RC 0x00040000
465+
/* Unable to translate address of (guest) pde or process/page table entry */
466+
#define DSISR_PRTABLE_FAULT 0x00020000
463467

464468
/* SRR1 error code fields */
465469

@@ -469,9 +473,31 @@ typedef struct ppc_v3_pate_t {
469473
#define SRR1_PROTFAULT DSISR_PROTFAULT
470474
#define SRR1_IAMR DSISR_AMR
471475

476+
/* SRR1[42:45] wakeup fields for System Reset Interrupt */
477+
478+
#define SRR1_WAKEMASK 0x003c0000 /* reason for wakeup */
479+
480+
#define SRR1_WAKEHMI 0x00280000 /* Hypervisor maintenance */
481+
#define SRR1_WAKEHVI 0x00240000 /* Hypervisor Virt. Interrupt (P9) */
482+
#define SRR1_WAKEEE 0x00200000 /* External interrupt */
483+
#define SRR1_WAKEDEC 0x00180000 /* Decrementer interrupt */
484+
#define SRR1_WAKEDBELL 0x00140000 /* Privileged doorbell */
485+
#define SRR1_WAKERESET 0x00100000 /* System reset */
486+
#define SRR1_WAKEHDBELL 0x000c0000 /* Hypervisor doorbell */
487+
#define SRR1_WAKESCOM 0x00080000 /* SCOM not in power-saving mode */
488+
489+
/* SRR1[46:47] power-saving exit mode */
490+
491+
#define SRR1_WAKESTATE 0x00030000 /* Powersave exit mask */
492+
493+
#define SRR1_WS_HVLOSS 0x00030000 /* HV resources not maintained */
494+
#define SRR1_WS_GPRLOSS 0x00020000 /* GPRs not maintained */
495+
#define SRR1_WS_NOLOSS 0x00010000 /* All resources maintained */
496+
472497
/* Facility Status and Control (FSCR) bits */
473498
#define FSCR_EBB (63 - 56) /* Event-Based Branch Facility */
474499
#define FSCR_TAR (63 - 55) /* Target Address Register */
500+
#define FSCR_SCV (63 - 51) /* System call vectored */
475501
/* Interrupt cause mask and position in FSCR. HFSCR has the same format */
476502
#define FSCR_IC_MASK (0xFFULL)
477503
#define FSCR_IC_POS (63 - 7)
@@ -481,6 +507,7 @@ typedef struct ppc_v3_pate_t {
481507
#define FSCR_IC_TM 5
482508
#define FSCR_IC_EBB 7
483509
#define FSCR_IC_TAR 8
510+
#define FSCR_IC_SCV 12
484511

485512
/* Exception state register bits definition */
486513
#define ESR_PIL PPC_BIT(36) /* Illegal Instruction */
@@ -548,6 +575,8 @@ enum {
548575
POWERPC_FLAG_VSX = 0x00080000,
549576
/* Has Transaction Memory (ISA 2.07) */
550577
POWERPC_FLAG_TM = 0x00100000,
578+
/* Has SCV (ISA 3.00) */
579+
POWERPC_FLAG_SCV = 0x00200000,
551580
};
552581

553582
/*****************************************************************************/
@@ -1206,7 +1235,7 @@ void ppc_cpu_do_interrupt(CPUState *cpu);
12061235
bool ppc_cpu_exec_interrupt(CPUState *cpu, int int_req);
12071236
hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
12081237

1209-
void ppc_cpu_do_system_reset(CPUState *cs, target_ulong vector);
1238+
void ppc_cpu_do_system_reset(CPUState *cs);
12101239
void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector);
12111240
#if 0
12121241
extern const VMStateDescription vmstate_ppc_cpu;

qemu/target/ppc/dfp_helper.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ static void dfp_set_round_mode_from_immediate(uint8_t r, uint8_t rmc,
113113
case 3: /* use FPSCR rounding mode */
114114
return;
115115
default:
116-
assert(0); /* cannot get here */
116+
g_assert_not_reached(); /* cannot get here */
117117
}
118118
} else { /* r == 1 */
119119
switch (rmc & 3) {
@@ -130,7 +130,7 @@ static void dfp_set_round_mode_from_immediate(uint8_t r, uint8_t rmc,
130130
rnd = DEC_ROUND_HALF_DOWN;
131131
break;
132132
default:
133-
assert(0); /* cannot get here */
133+
g_assert_not_reached(); /* cannot get here */
134134
}
135135
}
136136
decContextSetRounding(&dfp->context, rnd);

qemu/target/ppc/excp_helper.c

Lines changed: 86 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,27 @@
3838
/* Exception processing */
3939
static inline void dump_syscall(CPUPPCState *env)
4040
{
41-
qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64 " r3=%016" PRIx64
41+
qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64
42+
" r3=%016" PRIx64 " r4=%016" PRIx64 " r5=%016" PRIx64
43+
" r6=%016" PRIx64 " r7=%016" PRIx64 " r8=%016" PRIx64
4244
" r4=%016" PRIx64 " r5=%016" PRIx64 " r6=%016" PRIx64
4345
" nip=" TARGET_FMT_lx "\n",
4446
ppc_dump_gpr(env, 0), ppc_dump_gpr(env, 3),
4547
ppc_dump_gpr(env, 4), ppc_dump_gpr(env, 5),
46-
ppc_dump_gpr(env, 6), env->nip);
48+
ppc_dump_gpr(env, 6), ppc_dump_gpr(env, 7),
49+
ppc_dump_gpr(env, 8), env->nip);
50+
}
51+
52+
static inline void dump_syscall_vectored(CPUPPCState *env)
53+
{
54+
qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64
55+
" r3=%016" PRIx64 " r4=%016" PRIx64 " r5=%016" PRIx64
56+
" r6=%016" PRIx64 " r7=%016" PRIx64 " r8=%016" PRIx64
57+
" nip=" TARGET_FMT_lx "\n",
58+
ppc_dump_gpr(env, 0), ppc_dump_gpr(env, 3),
59+
ppc_dump_gpr(env, 4), ppc_dump_gpr(env, 5),
60+
ppc_dump_gpr(env, 6), ppc_dump_gpr(env, 7),
61+
ppc_dump_gpr(env, 8), env->nip);
4762
}
4863

4964
static int powerpc_reset_wakeup(CPUState *cs, CPUPPCState *env, int excp,
@@ -53,33 +68,33 @@ static int powerpc_reset_wakeup(CPUState *cs, CPUPPCState *env, int excp,
5368
env->resume_as_sreset = false;
5469

5570
/* Pretend to be returning from doze always as we don't lose state */
56-
*msr |= (0x1ull << (63 - 47));
71+
*msr |= SRR1_WS_NOLOSS;
5772

5873
/* Machine checks are sent normally */
5974
if (excp == POWERPC_EXCP_MCHECK) {
6075
return excp;
6176
}
6277
switch (excp) {
6378
case POWERPC_EXCP_RESET:
64-
*msr |= 0x4ull << (63 - 45);
79+
*msr |= SRR1_WAKERESET;
6580
break;
6681
case POWERPC_EXCP_EXTERNAL:
67-
*msr |= 0x8ull << (63 - 45);
82+
*msr |= SRR1_WAKEEE;
6883
break;
6984
case POWERPC_EXCP_DECR:
70-
*msr |= 0x6ull << (63 - 45);
85+
*msr |= SRR1_WAKEDEC;
7186
break;
7287
case POWERPC_EXCP_SDOOR:
73-
*msr |= 0x5ull << (63 - 45);
88+
*msr |= SRR1_WAKEDBELL;
7489
break;
7590
case POWERPC_EXCP_SDOOR_HV:
76-
*msr |= 0x3ull << (63 - 45);
91+
*msr |= SRR1_WAKEHDBELL;
7792
break;
7893
case POWERPC_EXCP_HV_MAINT:
79-
*msr |= 0xaull << (63 - 45);
94+
*msr |= SRR1_WAKEHMI;
8095
break;
8196
case POWERPC_EXCP_HVIRT:
82-
*msr |= 0x9ull << (63 - 45);
97+
*msr |= SRR1_WAKEHVI;
8398
break;
8499
default:
85100
cpu_abort(cs, "Unsupported exception %d in Power Save mode\n",
@@ -149,7 +164,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
149164
CPUState *cs = CPU(cpu);
150165
CPUPPCState *env = &cpu->env;
151166
target_ulong msr, new_msr, vector;
152-
int srr0, srr1, asrr0, asrr1, lev, ail;
167+
int srr0, srr1, asrr0, asrr1, lev = -1, ail;
153168
bool lpes0;
154169

155170
qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
@@ -388,6 +403,13 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
388403
new_msr |= (target_ulong)MSR_HVB;
389404
}
390405
break;
406+
case POWERPC_EXCP_SYSCALL_VECTORED: /* scv exception */
407+
lev = env->error_code;
408+
dump_syscall_vectored(env);
409+
env->nip += 4;
410+
new_msr |= env->msr & ((target_ulong)1 << MSR_EE);
411+
new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
412+
break;
391413
case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
392414
case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */
393415
case POWERPC_EXCP_DECR: /* Decrementer exception */
@@ -476,6 +498,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
476498
case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */
477499
case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */
478500
case POWERPC_EXCP_HISI: /* Hypervisor instruction storage exception */
501+
msr |= env->error_code;
479502
case POWERPC_EXCP_HDSEG: /* Hypervisor data segment exception */
480503
case POWERPC_EXCP_HISEG: /* Hypervisor instruction segment exception */
481504
case POWERPC_EXCP_SDOOR_HV: /* Hypervisor Doorbell interrupt */
@@ -690,12 +713,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
690713
break;
691714
}
692715

693-
/* Save PC */
694-
env->spr[srr0] = env->nip;
695-
696-
/* Save MSR */
697-
env->spr[srr1] = msr;
698-
699716
/* Sanity check */
700717
if (!(env->msr_mask & MSR_HVB)) {
701718
if (new_msr & MSR_HVB) {
@@ -708,14 +725,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
708725
}
709726
}
710727

711-
/* If any alternate SRR register are defined, duplicate saved values */
712-
if (asrr0 != -1) {
713-
env->spr[asrr0] = env->spr[srr0];
714-
}
715-
if (asrr1 != -1) {
716-
env->spr[asrr1] = env->spr[srr1];
717-
}
718-
719728
/*
720729
* Sort out endianness of interrupt, this differs depending on the
721730
* CPU, the HV mode, etc...
@@ -750,18 +759,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
750759
}
751760
#endif
752761

753-
/* Jump to handler */
754-
vector = env->excp_vectors[excp];
755-
#ifdef _MSC_VER
756-
if (vector == (target_ulong)(0ULL - 1ULL)) {
757-
#else
758-
if (vector == (target_ulong)-1ULL) {
759-
#endif
760-
cpu_abort(cs, "Raised an exception without defined vector %d\n",
761-
excp);
762-
}
763-
vector |= env->excp_prefix;
764-
765762
/*
766763
* AIL only works if there is no HV transition and we are running
767764
* with translations enabled
@@ -770,10 +767,21 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
770767
((new_msr & MSR_HVB) && !(msr & MSR_HVB))) {
771768
ail = 0;
772769
}
773-
/* Handle AIL */
774-
if (ail) {
775-
new_msr |= (1 << MSR_IR) | (1 << MSR_DR);
776-
vector |= ppc_excp_vector_offset(cs, ail);
770+
771+
vector = env->excp_vectors[excp];
772+
if (vector == (target_ulong)-1ULL) {
773+
cpu_abort(cs, "Raised an exception without defined vector %d\n",
774+
excp);
775+
}
776+
777+
vector |= env->excp_prefix;
778+
779+
/* If any alternate SRR register are defined, duplicate saved values */
780+
if (asrr0 != -1) {
781+
env->spr[asrr0] = env->nip;
782+
}
783+
if (asrr1 != -1) {
784+
env->spr[asrr1] = msr;
777785
}
778786

779787
#if defined(TARGET_PPC64)
@@ -793,6 +801,37 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
793801
}
794802
#endif
795803

804+
if (excp != POWERPC_EXCP_SYSCALL_VECTORED) {
805+
/* Save PC */
806+
env->spr[srr0] = env->nip;
807+
808+
/* Save MSR */
809+
env->spr[srr1] = msr;
810+
811+
/* Handle AIL */
812+
if (ail) {
813+
new_msr |= (1 << MSR_IR) | (1 << MSR_DR);
814+
vector |= ppc_excp_vector_offset(cs, ail);
815+
}
816+
817+
#if defined(TARGET_PPC64)
818+
} else {
819+
/* scv AIL is a little different */
820+
if (ail) {
821+
new_msr |= (1 << MSR_IR) | (1 << MSR_DR);
822+
}
823+
if (ail == AIL_C000_0000_0000_4000) {
824+
vector |= 0xc000000000003000ull;
825+
} else {
826+
vector |= 0x0000000000017000ull;
827+
}
828+
vector += lev * 0x20;
829+
830+
env->lr = env->nip;
831+
env->ctr = msr;
832+
#endif
833+
}
834+
796835
powerpc_set_excp_state(cpu, vector, new_msr);
797836
}
798837

@@ -954,15 +993,12 @@ static void ppc_hw_interrupt(CPUPPCState *env)
954993
}
955994
}
956995

957-
void ppc_cpu_do_system_reset(CPUState *cs, target_ulong vector)
996+
void ppc_cpu_do_system_reset(CPUState *cs)
958997
{
959998
PowerPCCPU *cpu = POWERPC_CPU(cs);
960999
CPUPPCState *env = &cpu->env;
9611000

9621001
powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_RESET);
963-
if (vector != -1) {
964-
env->nip = vector;
965-
}
9661002
}
9671003

9681004
void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector)
@@ -1135,6 +1171,11 @@ void helper_rfid(CPUPPCState *env)
11351171
do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1]);
11361172
}
11371173

1174+
void helper_rfscv(CPUPPCState *env)
1175+
{
1176+
do_rfi(env, env->lr, env->ctr);
1177+
}
1178+
11381179
void helper_hrfid(CPUPPCState *env)
11391180
{
11401181
do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]);

qemu/target/ppc/helper.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ DEF_HELPER_1(rfmci, void, env)
1818
#if defined(TARGET_PPC64)
1919
DEF_HELPER_2(pminsn, void, env, i32)
2020
DEF_HELPER_1(rfid, void, env)
21+
DEF_HELPER_1(rfscv, void, env)
2122
DEF_HELPER_1(hrfid, void, env)
2223
DEF_HELPER_2(store_lpcr, void, env, tl)
2324
DEF_HELPER_2(store_pcr, void, env, tl)
@@ -215,10 +216,6 @@ DEF_HELPER_3(vsubuqm, void, avr, avr, avr)
215216
DEF_HELPER_4(vsubecuq, void, avr, avr, avr, avr)
216217
DEF_HELPER_4(vsubeuqm, void, avr, avr, avr, avr)
217218
DEF_HELPER_3(vsubcuq, void, avr, avr, avr)
218-
DEF_HELPER_3(vrlb, void, avr, avr, avr)
219-
DEF_HELPER_3(vrlh, void, avr, avr, avr)
220-
DEF_HELPER_3(vrlw, void, avr, avr, avr)
221-
DEF_HELPER_3(vrld, void, avr, avr, avr)
222219
DEF_HELPER_4(vsldoi, void, avr, avr, avr, i32)
223220
DEF_HELPER_3(vextractub, void, avr, avr, i32)
224221
DEF_HELPER_3(vextractuh, void, avr, avr, i32)

0 commit comments

Comments
 (0)