excp_helper.c (f003109f710bb39a78c27ce18aa10579340f5a3f) excp_helper.c (7b694df6a6deeac8ede0512f983c70463968021a)
1/*
2 * PowerPC exception emulation helpers for QEMU.
3 *
4 * Copyright (c) 2003-2007 Jocelyn Mayer
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either

--- 9 unchanged lines hidden (view full) ---

18 */
19#include "qemu/osdep.h"
20#include "qemu/main-loop.h"
21#include "qemu/log.h"
22#include "cpu.h"
23#include "exec/exec-all.h"
24#include "internal.h"
25#include "helper_regs.h"
1/*
2 * PowerPC exception emulation helpers for QEMU.
3 *
4 * Copyright (c) 2003-2007 Jocelyn Mayer
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either

--- 9 unchanged lines hidden (view full) ---

18 */
19#include "qemu/osdep.h"
20#include "qemu/main-loop.h"
21#include "qemu/log.h"
22#include "cpu.h"
23#include "exec/exec-all.h"
24#include "internal.h"
25#include "helper_regs.h"
26#include "hw/ppc/ppc.h"
26
27#include "trace.h"
28
29#ifdef CONFIG_TCG
30#include "exec/helper-proto.h"
31#include "exec/cpu_ldst.h"
32#endif
33

--- 2047 unchanged lines hidden (view full) ---

2081 * PowerISA v3.1 isn't clear about whether an EBB should be
2082 * postponed or cancelled if the EBB facility is unavailable.
2083 * Our assumption here is that the EBB is cancelled if both
2084 * FSCR and HFSCR EBB facilities aren't available.
2085 */
2086static void do_ebb(CPUPPCState *env, int ebb_excp)
2087{
2088 PowerPCCPU *cpu = env_archcpu(env);
27
28#include "trace.h"
29
30#ifdef CONFIG_TCG
31#include "exec/helper-proto.h"
32#include "exec/cpu_ldst.h"
33#endif
34

--- 2047 unchanged lines hidden (view full) ---

2082 * PowerISA v3.1 isn't clear about whether an EBB should be
2083 * postponed or cancelled if the EBB facility is unavailable.
2084 * Our assumption here is that the EBB is cancelled if both
2085 * FSCR and HFSCR EBB facilities aren't available.
2086 */
2087static void do_ebb(CPUPPCState *env, int ebb_excp)
2088{
2089 PowerPCCPU *cpu = env_archcpu(env);
2089 CPUState *cs = CPU(cpu);
2090
2091 /*
2092 * FSCR_EBB and FSCR_IC_EBB are the same bits used with
2093 * HFSCR.
2094 */
2095 helper_fscr_facility_check(env, FSCR_EBB, 0, FSCR_IC_EBB);
2096 helper_hfscr_facility_check(env, FSCR_EBB, "EBB", FSCR_IC_EBB);
2097
2098 if (ebb_excp == POWERPC_EXCP_PERFM_EBB) {
2099 env->spr[SPR_BESCR] |= BESCR_PMEO;
2100 } else if (ebb_excp == POWERPC_EXCP_EXTERNAL_EBB) {
2101 env->spr[SPR_BESCR] |= BESCR_EEO;
2102 }
2103
2104 if (FIELD_EX64(env->msr, MSR, PR)) {
2105 powerpc_excp(cpu, ebb_excp);
2106 } else {
2090
2091 /*
2092 * FSCR_EBB and FSCR_IC_EBB are the same bits used with
2093 * HFSCR.
2094 */
2095 helper_fscr_facility_check(env, FSCR_EBB, 0, FSCR_IC_EBB);
2096 helper_hfscr_facility_check(env, FSCR_EBB, "EBB", FSCR_IC_EBB);
2097
2098 if (ebb_excp == POWERPC_EXCP_PERFM_EBB) {
2099 env->spr[SPR_BESCR] |= BESCR_PMEO;
2100 } else if (ebb_excp == POWERPC_EXCP_EXTERNAL_EBB) {
2101 env->spr[SPR_BESCR] |= BESCR_EEO;
2102 }
2103
2104 if (FIELD_EX64(env->msr, MSR, PR)) {
2105 powerpc_excp(cpu, ebb_excp);
2106 } else {
2107 env->pending_interrupts |= PPC_INTERRUPT_EBB;
2108 cpu_interrupt(cs, CPU_INTERRUPT_HARD);
2107 ppc_set_irq(cpu, PPC_INTERRUPT_EBB, 1);
2109 }
2110}
2111
2112void raise_ebb_perfm_exception(CPUPPCState *env)
2113{
2114 bool perfm_ebb_enabled = env->spr[SPR_POWER_MMCR0] & MMCR0_EBE &&
2115 env->spr[SPR_BESCR] & BESCR_PME &&
2116 env->spr[SPR_BESCR] & BESCR_GE;

--- 176 unchanged lines hidden (view full) ---

2293void helper_msgclr(CPUPPCState *env, target_ulong rb)
2294{
2295 int irq = dbell2irq(rb);
2296
2297 if (irq < 0) {
2298 return;
2299 }
2300
2108 }
2109}
2110
2111void raise_ebb_perfm_exception(CPUPPCState *env)
2112{
2113 bool perfm_ebb_enabled = env->spr[SPR_POWER_MMCR0] & MMCR0_EBE &&
2114 env->spr[SPR_BESCR] & BESCR_PME &&
2115 env->spr[SPR_BESCR] & BESCR_GE;

--- 176 unchanged lines hidden (view full) ---

2292void helper_msgclr(CPUPPCState *env, target_ulong rb)
2293{
2294 int irq = dbell2irq(rb);
2295
2296 if (irq < 0) {
2297 return;
2298 }
2299
2301 env->pending_interrupts &= ~irq;
2300 ppc_set_irq(env_archcpu(env), irq, 0);
2302}
2303
2304void helper_msgsnd(target_ulong rb)
2305{
2306 int irq = dbell2irq(rb);
2307 int pir = rb & DBELL_PIRTAG_MASK;
2308 CPUState *cs;
2309
2310 if (irq < 0) {
2311 return;
2312 }
2313
2314 qemu_mutex_lock_iothread();
2315 CPU_FOREACH(cs) {
2316 PowerPCCPU *cpu = POWERPC_CPU(cs);
2317 CPUPPCState *cenv = &cpu->env;
2318
2319 if ((rb & DBELL_BRDCAST) || (cenv->spr[SPR_BOOKE_PIR] == pir)) {
2301}
2302
2303void helper_msgsnd(target_ulong rb)
2304{
2305 int irq = dbell2irq(rb);
2306 int pir = rb & DBELL_PIRTAG_MASK;
2307 CPUState *cs;
2308
2309 if (irq < 0) {
2310 return;
2311 }
2312
2313 qemu_mutex_lock_iothread();
2314 CPU_FOREACH(cs) {
2315 PowerPCCPU *cpu = POWERPC_CPU(cs);
2316 CPUPPCState *cenv = &cpu->env;
2317
2318 if ((rb & DBELL_BRDCAST) || (cenv->spr[SPR_BOOKE_PIR] == pir)) {
2320 cenv->pending_interrupts |= irq;
2321 cpu_interrupt(cs, CPU_INTERRUPT_HARD);
2319 ppc_set_irq(cpu, irq, 1);
2322 }
2323 }
2324 qemu_mutex_unlock_iothread();
2325}
2326
2327/* Server Processor Control */
2328
2329static bool dbell_type_server(target_ulong rb)

--- 7 unchanged lines hidden (view full) ---

2337}
2338
2339void helper_book3s_msgclr(CPUPPCState *env, target_ulong rb)
2340{
2341 if (!dbell_type_server(rb)) {
2342 return;
2343 }
2344
2320 }
2321 }
2322 qemu_mutex_unlock_iothread();
2323}
2324
2325/* Server Processor Control */
2326
2327static bool dbell_type_server(target_ulong rb)

--- 7 unchanged lines hidden (view full) ---

2335}
2336
2337void helper_book3s_msgclr(CPUPPCState *env, target_ulong rb)
2338{
2339 if (!dbell_type_server(rb)) {
2340 return;
2341 }
2342
2345 env->pending_interrupts &= ~PPC_INTERRUPT_HDOORBELL;
2343 ppc_set_irq(env_archcpu(env), PPC_INTERRUPT_HDOORBELL, 0);
2346}
2347
2348static void book3s_msgsnd_common(int pir, int irq)
2349{
2350 CPUState *cs;
2351
2352 qemu_mutex_lock_iothread();
2353 CPU_FOREACH(cs) {
2354 PowerPCCPU *cpu = POWERPC_CPU(cs);
2355 CPUPPCState *cenv = &cpu->env;
2356
2357 /* TODO: broadcast message to all threads of the same processor */
2358 if (cenv->spr_cb[SPR_PIR].default_value == pir) {
2344}
2345
2346static void book3s_msgsnd_common(int pir, int irq)
2347{
2348 CPUState *cs;
2349
2350 qemu_mutex_lock_iothread();
2351 CPU_FOREACH(cs) {
2352 PowerPCCPU *cpu = POWERPC_CPU(cs);
2353 CPUPPCState *cenv = &cpu->env;
2354
2355 /* TODO: broadcast message to all threads of the same processor */
2356 if (cenv->spr_cb[SPR_PIR].default_value == pir) {
2359 cenv->pending_interrupts |= irq;
2360 cpu_interrupt(cs, CPU_INTERRUPT_HARD);
2357 ppc_set_irq(cpu, irq, 1);
2361 }
2362 }
2363 qemu_mutex_unlock_iothread();
2364}
2365
2366void helper_book3s_msgsnd(target_ulong rb)
2367{
2368 int pir = rb & DBELL_PROCIDTAG_MASK;

--- 9 unchanged lines hidden (view full) ---

2378void helper_book3s_msgclrp(CPUPPCState *env, target_ulong rb)
2379{
2380 helper_hfscr_facility_check(env, HFSCR_MSGP, "msgclrp", HFSCR_IC_MSGP);
2381
2382 if (!dbell_type_server(rb)) {
2383 return;
2384 }
2385
2358 }
2359 }
2360 qemu_mutex_unlock_iothread();
2361}
2362
2363void helper_book3s_msgsnd(target_ulong rb)
2364{
2365 int pir = rb & DBELL_PROCIDTAG_MASK;

--- 9 unchanged lines hidden (view full) ---

2375void helper_book3s_msgclrp(CPUPPCState *env, target_ulong rb)
2376{
2377 helper_hfscr_facility_check(env, HFSCR_MSGP, "msgclrp", HFSCR_IC_MSGP);
2378
2379 if (!dbell_type_server(rb)) {
2380 return;
2381 }
2382
2386 env->pending_interrupts &= ~PPC_INTERRUPT_DOORBELL;
2383 ppc_set_irq(env_archcpu(env), PPC_INTERRUPT_HDOORBELL, 0);
2387}
2388
2389/*
2390 * sends a message to other threads that are on the same
2391 * multi-threaded processor
2392 */
2393void helper_book3s_msgsndp(CPUPPCState *env, target_ulong rb)
2394{

--- 44 unchanged lines hidden ---
2384}
2385
2386/*
2387 * sends a message to other threads that are on the same
2388 * multi-threaded processor
2389 */
2390void helper_book3s_msgsndp(CPUPPCState *env, target_ulong rb)
2391{

--- 44 unchanged lines hidden ---