Revision b172c56a
b/darwin-user/main.c | ||
---|---|---|
386 | 386 |
cpu_abort(env, "Reset interrupt while in user mode. " |
387 | 387 |
"Aborting\n"); |
388 | 388 |
break; |
389 |
#if defined(TARGET_PPC64) /* PowerPC 64 */ |
|
390 | 389 |
case POWERPC_EXCP_DSEG: /* Data segment exception */ |
391 | 390 |
cpu_abort(env, "Data segment exception while in user mode. " |
392 | 391 |
"Aborting\n"); |
... | ... | |
395 | 394 |
cpu_abort(env, "Instruction segment exception " |
396 | 395 |
"while in user mode. Aborting\n"); |
397 | 396 |
break; |
398 |
#endif /* defined(TARGET_PPC64) */ |
|
399 |
#if defined(TARGET_PPC64H) /* PowerPC 64 with hypervisor mode support */ |
|
400 | 397 |
case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */ |
401 | 398 |
cpu_abort(env, "Hypervisor decrementer interrupt " |
402 | 399 |
"while in user mode. Aborting\n"); |
403 | 400 |
break; |
404 |
#endif /* defined(TARGET_PPC64H) */ |
|
405 | 401 |
case POWERPC_EXCP_TRACE: /* Trace exception */ |
406 | 402 |
/* Nothing to do: |
407 | 403 |
* we use this exception to emulate step-by-step execution mode. |
408 | 404 |
*/ |
409 | 405 |
break; |
410 |
#if defined(TARGET_PPC64H) /* PowerPC 64 with hypervisor mode support */ |
|
411 | 406 |
case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */ |
412 | 407 |
cpu_abort(env, "Hypervisor data storage exception " |
413 | 408 |
"while in user mode. Aborting\n"); |
... | ... | |
424 | 419 |
cpu_abort(env, "Hypervisor instruction segment exception " |
425 | 420 |
"while in user mode. Aborting\n"); |
426 | 421 |
break; |
427 |
#endif /* defined(TARGET_PPC64H) */ |
|
428 | 422 |
case POWERPC_EXCP_VPU: /* Vector unavailable exception */ |
429 | 423 |
EXCP_DUMP(env, "No Altivec instructions allowed\n"); |
430 | 424 |
info.si_signo = SIGILL; |
b/hw/ppc.c | ||
---|---|---|
428 | 428 |
uint64_t decr_next; /* Tick for next decr interrupt */ |
429 | 429 |
uint32_t decr_freq; /* decrementer frequency */ |
430 | 430 |
struct QEMUTimer *decr_timer; |
431 |
#if defined(TARGET_PPC64H) |
|
432 | 431 |
/* Hypervisor decrementer management */ |
433 | 432 |
uint64_t hdecr_next; /* Tick for next hdecr interrupt */ |
434 | 433 |
struct QEMUTimer *hdecr_timer; |
435 | 434 |
uint64_t purr_load; |
436 | 435 |
uint64_t purr_start; |
437 |
#endif |
|
438 | 436 |
void *opaque; |
439 | 437 |
}; |
440 | 438 |
|
... | ... | |
643 | 641 |
return _cpu_ppc_load_decr(env, &tb_env->decr_next); |
644 | 642 |
} |
645 | 643 |
|
646 |
#if defined(TARGET_PPC64H) |
|
647 | 644 |
uint32_t cpu_ppc_load_hdecr (CPUState *env) |
648 | 645 |
{ |
649 | 646 |
ppc_tb_t *tb_env = env->tb_env; |
... | ... | |
660 | 657 |
|
661 | 658 |
return tb_env->purr_load + muldiv64(diff, tb_env->tb_freq, ticks_per_sec); |
662 | 659 |
} |
663 |
#endif /* defined(TARGET_PPC64H) */ |
|
664 | 660 |
|
665 | 661 |
/* When decrementer expires, |
666 | 662 |
* all we need to do is generate or queue a CPU exception |
... | ... | |
736 | 732 |
_cpu_ppc_store_decr(opaque, 0x00000000, 0xFFFFFFFF, 1); |
737 | 733 |
} |
738 | 734 |
|
739 |
#if defined(TARGET_PPC64H) |
|
740 | 735 |
static always_inline void _cpu_ppc_store_hdecr (CPUState *env, uint32_t hdecr, |
741 | 736 |
uint32_t value, int is_excp) |
742 | 737 |
{ |
743 | 738 |
ppc_tb_t *tb_env = env->tb_env; |
744 | 739 |
|
745 |
__cpu_ppc_store_decr(env, &tb_env->hdecr_next, tb_env->hdecr_timer, |
|
746 |
&cpu_ppc_hdecr_excp, hdecr, value, is_excp); |
|
740 |
if (tb_env->hdecr_timer != NULL) { |
|
741 |
__cpu_ppc_store_decr(env, &tb_env->hdecr_next, tb_env->hdecr_timer, |
|
742 |
&cpu_ppc_hdecr_excp, hdecr, value, is_excp); |
|
743 |
} |
|
747 | 744 |
} |
748 | 745 |
|
749 | 746 |
void cpu_ppc_store_hdecr (CPUState *env, uint32_t value) |
... | ... | |
763 | 760 |
tb_env->purr_load = value; |
764 | 761 |
tb_env->purr_start = qemu_get_clock(vm_clock); |
765 | 762 |
} |
766 |
#endif /* defined(TARGET_PPC64H) */ |
|
767 | 763 |
|
768 | 764 |
static void cpu_ppc_set_tb_clk (void *opaque, uint32_t freq) |
769 | 765 |
{ |
... | ... | |
777 | 773 |
* it's not ready to handle it... |
778 | 774 |
*/ |
779 | 775 |
_cpu_ppc_store_decr(env, 0xFFFFFFFF, 0xFFFFFFFF, 0); |
780 |
#if defined(TARGET_PPC64H) |
|
781 | 776 |
_cpu_ppc_store_hdecr(env, 0xFFFFFFFF, 0xFFFFFFFF, 0); |
782 | 777 |
cpu_ppc_store_purr(env, 0x0000000000000000ULL); |
783 |
#endif /* defined(TARGET_PPC64H) */ |
|
784 | 778 |
} |
785 | 779 |
|
786 | 780 |
/* Set up (once) timebase frequency (in Hz) */ |
... | ... | |
794 | 788 |
env->tb_env = tb_env; |
795 | 789 |
/* Create new timer */ |
796 | 790 |
tb_env->decr_timer = qemu_new_timer(vm_clock, &cpu_ppc_decr_cb, env); |
797 |
#if defined(TARGET_PPC64H) |
|
798 |
tb_env->hdecr_timer = qemu_new_timer(vm_clock, &cpu_ppc_hdecr_cb, env); |
|
799 |
#endif /* defined(TARGET_PPC64H) */ |
|
791 |
if (0) { |
|
792 |
/* XXX: find a suitable condition to enable the hypervisor decrementer |
|
793 |
*/ |
|
794 |
tb_env->hdecr_timer = qemu_new_timer(vm_clock, &cpu_ppc_hdecr_cb, env); |
|
795 |
} else { |
|
796 |
tb_env->hdecr_timer = NULL; |
|
797 |
} |
|
800 | 798 |
cpu_ppc_set_tb_clk(env, freq); |
801 | 799 |
|
802 | 800 |
return &cpu_ppc_set_tb_clk; |
b/linux-user/main.c | ||
---|---|---|
1047 | 1047 |
cpu_abort(env, "Reset interrupt while in user mode. " |
1048 | 1048 |
"Aborting\n"); |
1049 | 1049 |
break; |
1050 |
#if defined(TARGET_PPC64) && !defined(TARGET_ABI32) /* PowerPC 64 */ |
|
1051 | 1050 |
case POWERPC_EXCP_DSEG: /* Data segment exception */ |
1052 | 1051 |
cpu_abort(env, "Data segment exception while in user mode. " |
1053 | 1052 |
"Aborting\n"); |
... | ... | |
1056 | 1055 |
cpu_abort(env, "Instruction segment exception " |
1057 | 1056 |
"while in user mode. Aborting\n"); |
1058 | 1057 |
break; |
1059 |
#endif /* defined(TARGET_PPC64) && !defined(TARGET_ABI32) */ |
|
1060 |
#if defined(TARGET_PPC64H) && !defined(TARGET_ABI32) |
|
1061 | 1058 |
/* PowerPC 64 with hypervisor mode support */ |
1062 | 1059 |
case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */ |
1063 | 1060 |
cpu_abort(env, "Hypervisor decrementer interrupt " |
1064 | 1061 |
"while in user mode. Aborting\n"); |
1065 | 1062 |
break; |
1066 |
#endif /* defined(TARGET_PPC64H) && !defined(TARGET_ABI32) */ |
|
1067 | 1063 |
case POWERPC_EXCP_TRACE: /* Trace exception */ |
1068 | 1064 |
/* Nothing to do: |
1069 | 1065 |
* we use this exception to emulate step-by-step execution mode. |
1070 | 1066 |
*/ |
1071 | 1067 |
break; |
1072 |
#if defined(TARGET_PPC64H) && !defined(TARGET_ABI32) |
|
1073 | 1068 |
/* PowerPC 64 with hypervisor mode support */ |
1074 | 1069 |
case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */ |
1075 | 1070 |
cpu_abort(env, "Hypervisor data storage exception " |
... | ... | |
1087 | 1082 |
cpu_abort(env, "Hypervisor instruction segment exception " |
1088 | 1083 |
"while in user mode. Aborting\n"); |
1089 | 1084 |
break; |
1090 |
#endif /* defined(TARGET_PPC64H) && !defined(TARGET_ABI32) */ |
|
1091 | 1085 |
case POWERPC_EXCP_VPU: /* Vector unavailable exception */ |
1092 | 1086 |
EXCP_DUMP(env, "No Altivec instructions allowed\n"); |
1093 | 1087 |
info.si_signo = TARGET_SIGILL; |
b/target-ppc/cpu.h | ||
---|---|---|
180 | 180 |
/* Vectors 38 to 63 are reserved */ |
181 | 181 |
/* Exceptions defined in the PowerPC server specification */ |
182 | 182 |
POWERPC_EXCP_RESET = 64, /* System reset exception */ |
183 |
#if defined(TARGET_PPC64) /* PowerPC 64 */ |
|
184 | 183 |
POWERPC_EXCP_DSEG = 65, /* Data segment exception */ |
185 | 184 |
POWERPC_EXCP_ISEG = 66, /* Instruction segment exception */ |
186 |
#endif /* defined(TARGET_PPC64) */ |
|
187 |
#if defined(TARGET_PPC64H) /* PowerPC 64 with hypervisor mode support */ |
|
188 | 185 |
POWERPC_EXCP_HDECR = 67, /* Hypervisor decrementer exception */ |
189 |
#endif /* defined(TARGET_PPC64H) */ |
|
190 | 186 |
POWERPC_EXCP_TRACE = 68, /* Trace exception */ |
191 |
#if defined(TARGET_PPC64H) /* PowerPC 64 with hypervisor mode support */ |
|
192 | 187 |
POWERPC_EXCP_HDSI = 69, /* Hypervisor data storage exception */ |
193 | 188 |
POWERPC_EXCP_HISI = 70, /* Hypervisor instruction storage exception */ |
194 | 189 |
POWERPC_EXCP_HDSEG = 71, /* Hypervisor data segment exception */ |
195 | 190 |
POWERPC_EXCP_HISEG = 72, /* Hypervisor instruction segment exception */ |
196 |
#endif /* defined(TARGET_PPC64H) */ |
|
197 | 191 |
POWERPC_EXCP_VPU = 73, /* Vector unavailable exception */ |
198 | 192 |
/* 40x specific exceptions */ |
199 | 193 |
POWERPC_EXCP_PIT = 74, /* Programmable interval timer interrupt */ |
... | ... | |
736 | 730 |
void cpu_ppc_store_atbu (CPUPPCState *env, uint32_t value); |
737 | 731 |
uint32_t cpu_ppc_load_decr (CPUPPCState *env); |
738 | 732 |
void cpu_ppc_store_decr (CPUPPCState *env, uint32_t value); |
739 |
#if defined(TARGET_PPC64H) |
|
740 | 733 |
uint32_t cpu_ppc_load_hdecr (CPUPPCState *env); |
741 | 734 |
void cpu_ppc_store_hdecr (CPUPPCState *env, uint32_t value); |
742 | 735 |
uint64_t cpu_ppc_load_purr (CPUPPCState *env); |
743 | 736 |
void cpu_ppc_store_purr (CPUPPCState *env, uint64_t value); |
744 |
#endif |
|
745 | 737 |
uint32_t cpu_ppc601_load_rtcl (CPUPPCState *env); |
746 | 738 |
uint32_t cpu_ppc601_load_rtcu (CPUPPCState *env); |
747 | 739 |
#if !defined(CONFIG_USER_ONLY) |
b/target-ppc/helper.c | ||
---|---|---|
2134 | 2134 |
{ |
2135 | 2135 |
target_ulong msr, new_msr, vector; |
2136 | 2136 |
int srr0, srr1, asrr0, asrr1; |
2137 |
#if defined(TARGET_PPC64H) |
|
2138 |
int lpes0, lpes1, lev; |
|
2139 |
|
|
2140 |
lpes0 = (env->spr[SPR_LPCR] >> 1) & 1; |
|
2141 |
lpes1 = (env->spr[SPR_LPCR] >> 2) & 1; |
|
2137 |
int lpes0, lpes1; |
|
2138 |
#if defined(TARGET_PPC64) |
|
2139 |
int lev; |
|
2142 | 2140 |
#endif |
2143 | 2141 |
|
2142 |
if (0) { |
|
2143 |
/* XXX: find a suitable condition to enable the hypervisor mode */ |
|
2144 |
lpes0 = (env->spr[SPR_LPCR] >> 1) & 1; |
|
2145 |
lpes1 = (env->spr[SPR_LPCR] >> 2) & 1; |
|
2146 |
} else { |
|
2147 |
/* Those values ensure we won't enter the hypervisor mode */ |
|
2148 |
lpes0 = 0; |
|
2149 |
lpes1 = 1; |
|
2150 |
} |
|
2151 |
|
|
2144 | 2152 |
if (loglevel & CPU_LOG_INT) { |
2145 | 2153 |
fprintf(logfile, "Raise exception at 0x" ADDRX " => 0x%08x (%02x)\n", |
2146 | 2154 |
env->nip, excp, env->error_code); |
... | ... | |
2190 | 2198 |
} |
2191 | 2199 |
new_msr &= ~((target_ulong)1 << MSR_RI); |
2192 | 2200 |
new_msr &= ~((target_ulong)1 << MSR_ME); |
2193 |
#if defined(TARGET_PPC64H) |
|
2194 |
new_msr |= (target_ulong)1 << MSR_HV; |
|
2201 |
#if defined(TARGET_PPC64) |
|
2202 |
if (0) { |
|
2203 |
/* XXX: find a suitable condition to enable the hypervisor mode */ |
|
2204 |
new_msr |= (target_ulong)1 << MSR_HV; |
|
2205 |
} |
|
2195 | 2206 |
#endif |
2196 | 2207 |
/* XXX: should also have something loaded in DAR / DSISR */ |
2197 | 2208 |
switch (excp_model) { |
... | ... | |
2217 | 2228 |
} |
2218 | 2229 |
#endif |
2219 | 2230 |
new_msr &= ~((target_ulong)1 << MSR_RI); |
2220 |
#if defined(TARGET_PPC64H)
|
|
2231 |
#if defined(TARGET_PPC64) |
|
2221 | 2232 |
if (lpes1 == 0) |
2222 | 2233 |
new_msr |= (target_ulong)1 << MSR_HV; |
2223 | 2234 |
#endif |
... | ... | |
2230 | 2241 |
} |
2231 | 2242 |
#endif |
2232 | 2243 |
new_msr &= ~((target_ulong)1 << MSR_RI); |
2233 |
#if defined(TARGET_PPC64H)
|
|
2244 |
#if defined(TARGET_PPC64) |
|
2234 | 2245 |
if (lpes1 == 0) |
2235 | 2246 |
new_msr |= (target_ulong)1 << MSR_HV; |
2236 | 2247 |
#endif |
... | ... | |
2238 | 2249 |
goto store_next; |
2239 | 2250 |
case POWERPC_EXCP_EXTERNAL: /* External input */ |
2240 | 2251 |
new_msr &= ~((target_ulong)1 << MSR_RI); |
2241 |
#if defined(TARGET_PPC64H)
|
|
2252 |
#if defined(TARGET_PPC64) |
|
2242 | 2253 |
if (lpes0 == 1) |
2243 | 2254 |
new_msr |= (target_ulong)1 << MSR_HV; |
2244 | 2255 |
#endif |
2245 | 2256 |
goto store_next; |
2246 | 2257 |
case POWERPC_EXCP_ALIGN: /* Alignment exception */ |
2247 | 2258 |
new_msr &= ~((target_ulong)1 << MSR_RI); |
2248 |
#if defined(TARGET_PPC64H)
|
|
2259 |
#if defined(TARGET_PPC64) |
|
2249 | 2260 |
if (lpes1 == 0) |
2250 | 2261 |
new_msr |= (target_ulong)1 << MSR_HV; |
2251 | 2262 |
#endif |
... | ... | |
2267 | 2278 |
return; |
2268 | 2279 |
} |
2269 | 2280 |
new_msr &= ~((target_ulong)1 << MSR_RI); |
2270 |
#if defined(TARGET_PPC64H)
|
|
2281 |
#if defined(TARGET_PPC64) |
|
2271 | 2282 |
if (lpes1 == 0) |
2272 | 2283 |
new_msr |= (target_ulong)1 << MSR_HV; |
2273 | 2284 |
#endif |
... | ... | |
2284 | 2295 |
} |
2285 | 2296 |
#endif |
2286 | 2297 |
new_msr &= ~((target_ulong)1 << MSR_RI); |
2287 |
#if defined(TARGET_PPC64H)
|
|
2298 |
#if defined(TARGET_PPC64) |
|
2288 | 2299 |
if (lpes1 == 0) |
2289 | 2300 |
new_msr |= (target_ulong)1 << MSR_HV; |
2290 | 2301 |
#endif |
... | ... | |
2292 | 2303 |
break; |
2293 | 2304 |
case POWERPC_EXCP_PRIV: |
2294 | 2305 |
new_msr &= ~((target_ulong)1 << MSR_RI); |
2295 |
#if defined(TARGET_PPC64H)
|
|
2306 |
#if defined(TARGET_PPC64) |
|
2296 | 2307 |
if (lpes1 == 0) |
2297 | 2308 |
new_msr |= (target_ulong)1 << MSR_HV; |
2298 | 2309 |
#endif |
... | ... | |
2300 | 2311 |
break; |
2301 | 2312 |
case POWERPC_EXCP_TRAP: |
2302 | 2313 |
new_msr &= ~((target_ulong)1 << MSR_RI); |
2303 |
#if defined(TARGET_PPC64H)
|
|
2314 |
#if defined(TARGET_PPC64) |
|
2304 | 2315 |
if (lpes1 == 0) |
2305 | 2316 |
new_msr |= (target_ulong)1 << MSR_HV; |
2306 | 2317 |
#endif |
... | ... | |
2315 | 2326 |
goto store_current; |
2316 | 2327 |
case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ |
2317 | 2328 |
new_msr &= ~((target_ulong)1 << MSR_RI); |
2318 |
#if defined(TARGET_PPC64H)
|
|
2329 |
#if defined(TARGET_PPC64) |
|
2319 | 2330 |
if (lpes1 == 0) |
2320 | 2331 |
new_msr |= (target_ulong)1 << MSR_HV; |
2321 | 2332 |
#endif |
... | ... | |
2336 | 2347 |
dump_syscall(env); |
2337 | 2348 |
} |
2338 | 2349 |
new_msr &= ~((target_ulong)1 << MSR_RI); |
2339 |
#if defined(TARGET_PPC64H)
|
|
2350 |
#if defined(TARGET_PPC64) |
|
2340 | 2351 |
lev = env->error_code; |
2341 | 2352 |
if (lev == 1 || (lpes0 == 0 && lpes1 == 0)) |
2342 | 2353 |
new_msr |= (target_ulong)1 << MSR_HV; |
... | ... | |
2347 | 2358 |
goto store_current; |
2348 | 2359 |
case POWERPC_EXCP_DECR: /* Decrementer exception */ |
2349 | 2360 |
new_msr &= ~((target_ulong)1 << MSR_RI); |
2350 |
#if defined(TARGET_PPC64H)
|
|
2361 |
#if defined(TARGET_PPC64) |
|
2351 | 2362 |
if (lpes1 == 0) |
2352 | 2363 |
new_msr |= (target_ulong)1 << MSR_HV; |
2353 | 2364 |
#endif |
... | ... | |
2434 | 2445 |
goto store_next; |
2435 | 2446 |
case POWERPC_EXCP_RESET: /* System reset exception */ |
2436 | 2447 |
new_msr &= ~((target_ulong)1 << MSR_RI); |
2437 |
#if defined(TARGET_PPC64H)
|
|
2448 |
#if defined(TARGET_PPC64) |
|
2438 | 2449 |
new_msr |= (target_ulong)1 << MSR_HV; |
2439 | 2450 |
#endif |
2440 | 2451 |
goto store_next; |
2441 |
#if defined(TARGET_PPC64) |
|
2442 | 2452 |
case POWERPC_EXCP_DSEG: /* Data segment exception */ |
2443 | 2453 |
new_msr &= ~((target_ulong)1 << MSR_RI); |
2444 |
#if defined(TARGET_PPC64H)
|
|
2454 |
#if defined(TARGET_PPC64) |
|
2445 | 2455 |
if (lpes1 == 0) |
2446 | 2456 |
new_msr |= (target_ulong)1 << MSR_HV; |
2447 | 2457 |
#endif |
2448 | 2458 |
goto store_next; |
2449 | 2459 |
case POWERPC_EXCP_ISEG: /* Instruction segment exception */ |
2450 | 2460 |
new_msr &= ~((target_ulong)1 << MSR_RI); |
2451 |
#if defined(TARGET_PPC64H)
|
|
2461 |
#if defined(TARGET_PPC64) |
|
2452 | 2462 |
if (lpes1 == 0) |
2453 | 2463 |
new_msr |= (target_ulong)1 << MSR_HV; |
2454 | 2464 |
#endif |
2455 | 2465 |
goto store_next; |
2456 |
#endif /* defined(TARGET_PPC64) */ |
|
2457 |
#if defined(TARGET_PPC64H) |
|
2458 | 2466 |
case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */ |
2459 | 2467 |
srr0 = SPR_HSRR0; |
2460 | 2468 |
srr1 = SPR_HSRR1; |
2469 |
#if defined(TARGET_PPC64) |
|
2461 | 2470 |
new_msr |= (target_ulong)1 << MSR_HV; |
2462 |
goto store_next; |
|
2463 | 2471 |
#endif |
2472 |
goto store_next; |
|
2464 | 2473 |
case POWERPC_EXCP_TRACE: /* Trace exception */ |
2465 | 2474 |
new_msr &= ~((target_ulong)1 << MSR_RI); |
2466 |
#if defined(TARGET_PPC64H)
|
|
2475 |
#if defined(TARGET_PPC64) |
|
2467 | 2476 |
if (lpes1 == 0) |
2468 | 2477 |
new_msr |= (target_ulong)1 << MSR_HV; |
2469 | 2478 |
#endif |
2470 | 2479 |
goto store_next; |
2471 |
#if defined(TARGET_PPC64H) |
|
2472 | 2480 |
case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */ |
2473 | 2481 |
srr0 = SPR_HSRR0; |
2474 | 2482 |
srr1 = SPR_HSRR1; |
2483 |
#if defined(TARGET_PPC64) |
|
2475 | 2484 |
new_msr |= (target_ulong)1 << MSR_HV; |
2485 |
#endif |
|
2476 | 2486 |
goto store_next; |
2477 | 2487 |
case POWERPC_EXCP_HISI: /* Hypervisor instruction storage exception */ |
2478 | 2488 |
srr0 = SPR_HSRR0; |
2479 | 2489 |
srr1 = SPR_HSRR1; |
2490 |
#if defined(TARGET_PPC64) |
|
2480 | 2491 |
new_msr |= (target_ulong)1 << MSR_HV; |
2492 |
#endif |
|
2481 | 2493 |
goto store_next; |
2482 | 2494 |
case POWERPC_EXCP_HDSEG: /* Hypervisor data segment exception */ |
2483 | 2495 |
srr0 = SPR_HSRR0; |
2484 | 2496 |
srr1 = SPR_HSRR1; |
2497 |
#if defined(TARGET_PPC64) |
|
2485 | 2498 |
new_msr |= (target_ulong)1 << MSR_HV; |
2499 |
#endif |
|
2486 | 2500 |
goto store_next; |
2487 | 2501 |
case POWERPC_EXCP_HISEG: /* Hypervisor instruction segment exception */ |
2488 | 2502 |
srr0 = SPR_HSRR0; |
2489 | 2503 |
srr1 = SPR_HSRR1; |
2504 |
#if defined(TARGET_PPC64) |
|
2490 | 2505 |
new_msr |= (target_ulong)1 << MSR_HV; |
2506 |
#endif |
|
2491 | 2507 |
goto store_next; |
2492 |
#endif /* defined(TARGET_PPC64H) */ |
|
2493 | 2508 |
case POWERPC_EXCP_VPU: /* Vector unavailable exception */ |
2494 | 2509 |
new_msr &= ~((target_ulong)1 << MSR_RI); |
2495 |
#if defined(TARGET_PPC64H)
|
|
2510 |
#if defined(TARGET_PPC64) |
|
2496 | 2511 |
if (lpes1 == 0) |
2497 | 2512 |
new_msr |= (target_ulong)1 << MSR_HV; |
2498 | 2513 |
#endif |
... | ... | |
2519 | 2534 |
goto store_next; |
2520 | 2535 |
case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */ |
2521 | 2536 |
new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */ |
2522 |
#if defined(TARGET_PPC64H) /* XXX: check this */
|
|
2537 |
#if defined(TARGET_PPC64) /* XXX: check this */ |
|
2523 | 2538 |
if (lpes1 == 0) |
2524 | 2539 |
new_msr |= (target_ulong)1 << MSR_HV; |
2525 | 2540 |
#endif |
... | ... | |
2540 | 2555 |
break; |
2541 | 2556 |
case POWERPC_EXCP_DLTLB: /* Data load TLB miss */ |
2542 | 2557 |
new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */ |
2543 |
#if defined(TARGET_PPC64H) /* XXX: check this */
|
|
2558 |
#if defined(TARGET_PPC64) /* XXX: check this */ |
|
2544 | 2559 |
if (lpes1 == 0) |
2545 | 2560 |
new_msr |= (target_ulong)1 << MSR_HV; |
2546 | 2561 |
#endif |
... | ... | |
2561 | 2576 |
break; |
2562 | 2577 |
case POWERPC_EXCP_DSTLB: /* Data store TLB miss */ |
2563 | 2578 |
new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */ |
2564 |
#if defined(TARGET_PPC64H) /* XXX: check this */
|
|
2579 |
#if defined(TARGET_PPC64) /* XXX: check this */ |
|
2565 | 2580 |
if (lpes1 == 0) |
2566 | 2581 |
new_msr |= (target_ulong)1 << MSR_HV; |
2567 | 2582 |
#endif |
... | ... | |
2663 | 2678 |
goto store_next; |
2664 | 2679 |
case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */ |
2665 | 2680 |
new_msr &= ~((target_ulong)1 << MSR_RI); |
2666 |
#if defined(TARGET_PPC64H)
|
|
2681 |
#if defined(TARGET_PPC64) |
|
2667 | 2682 |
if (lpes1 == 0) |
2668 | 2683 |
new_msr |= (target_ulong)1 << MSR_HV; |
2669 | 2684 |
#endif |
... | ... | |
2769 | 2784 |
|
2770 | 2785 |
void ppc_hw_interrupt (CPUPPCState *env) |
2771 | 2786 |
{ |
2772 |
#if defined(TARGET_PPC64H)
|
|
2787 |
#if defined(TARGET_PPC64) |
|
2773 | 2788 |
int hdice; |
2774 | 2789 |
#endif |
2775 | 2790 |
|
... | ... | |
2800 | 2815 |
return; |
2801 | 2816 |
} |
2802 | 2817 |
#endif |
2803 |
#if defined(TARGET_PPC64H) |
|
2804 |
hdice = env->spr[SPR_LPCR] & 1; |
|
2818 |
#if defined(TARGET_PPC64) |
|
2819 |
if (0) { |
|
2820 |
/* XXX: find a suitable condition to enable the hypervisor mode */ |
|
2821 |
hdice = env->spr[SPR_LPCR] & 1; |
|
2822 |
} else { |
|
2823 |
hdice = 0; |
|
2824 |
} |
|
2805 | 2825 |
if ((msr_ee != 0 || msr_hv == 0 || msr_pr != 0) && hdice != 0) { |
2806 | 2826 |
/* Hypervisor decrementer exception */ |
2807 | 2827 |
if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) { |
b/target-ppc/helper_regs.h | ||
---|---|---|
60 | 60 |
|
61 | 61 |
static always_inline void hreg_compute_mem_idx (CPUPPCState *env) |
62 | 62 |
{ |
63 |
#if defined (TARGET_PPC64H)
|
|
63 |
#if defined (TARGET_PPC64) |
|
64 | 64 |
/* Precompute MMU index */ |
65 | 65 |
if (msr_pr == 0 && msr_hv != 0) |
66 | 66 |
env->mmu_idx = 2; |
... | ... | |
78 | 78 |
(1 << MSR_PR) | (1 << MSR_FP) | (1 << MSR_SE) | (1 << MSR_BE) | |
79 | 79 |
(1 << MSR_LE); |
80 | 80 |
#if defined (TARGET_PPC64) |
81 |
hflags_mask |= (1ULL << MSR_CM) | (1ULL << MSR_SF); |
|
82 |
#if defined (TARGET_PPC64H) |
|
83 |
hflags_mask |= 1ULL << MSR_HV; |
|
84 |
#endif |
|
81 |
hflags_mask |= (1ULL << MSR_CM) | (1ULL << MSR_SF) | (1ULL << MSR_HV); |
|
85 | 82 |
#endif |
86 | 83 |
hreg_compute_mem_idx(env); |
87 | 84 |
env->hflags = env->msr & hflags_mask; |
b/target-ppc/translate_init.c | ||
---|---|---|
2609 | 2609 |
env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700; |
2610 | 2610 |
env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800; |
2611 | 2611 |
env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900; |
2612 |
#if defined(TARGET_PPC64H) /* PowerPC 64 with hypervisor mode support */ |
|
2613 | 2612 |
env->excp_vectors[POWERPC_EXCP_HDECR] = 0x00000980; |
2614 |
#endif |
|
2615 | 2613 |
env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00; |
2616 | 2614 |
env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00; |
2617 | 2615 |
env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00; |
Also available in: Unified diff