From patchwork Mon Nov 1 23:56:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Henrique Barboza X-Patchwork-Id: 1549443 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20210112 header.b=kXLDbKhm; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-ppc-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HjrVW6rLwz9sXM for ; Tue, 2 Nov 2021 11:33:38 +1100 (AEDT) Received: from localhost ([::1]:51006 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mhhk4-0007sp-Pv for incoming@patchwork.ozlabs.org; Mon, 01 Nov 2021 20:33:34 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48706) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mhhB9-0004J2-VU; Mon, 01 Nov 2021 19:57:28 -0400 Received: from mail-qv1-xf29.google.com ([2607:f8b0:4864:20::f29]:39877) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1mhhB7-0006Kx-Rz; Mon, 01 Nov 2021 19:57:27 -0400 Received: by mail-qv1-xf29.google.com with SMTP id k29so12283930qve.6; Mon, 01 Nov 2021 16:57:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=RSjNAoRTLlpuzK4b66Fsx9WSOY2wevSbv/PVBVestSk=; b=kXLDbKhmtTOTNaY8I+w9Dm4u4dDzhbLv5cvOyqJnrlb3oaHD6AG6tqc28RJsOr2A7p HCpFmO3Teacyn7UFk+6aA2S5LAIVTYj1zr4GTiauuGJNPrRj/mg7ZRjU89rTMdIP5GmM 8TGVYtZzNnudWhv7+0IUKoXlQg9RzLoWoCPL6u84oEsaANNYXMQ6TrNICB+ZDArS2FLD m9MCtb9Kc2iohH92bOMtgziL2vsRhBAgWdeRMyEPzAAFuMb5/EBYNjUYabtfmtL7tO/d myrXVuuNk6IR8G8fK3LsrTItDdgddUDAcUnfHScm72r0c+wo8oryjg3Z/0KF+vYs0mKJ e3uQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=RSjNAoRTLlpuzK4b66Fsx9WSOY2wevSbv/PVBVestSk=; b=In9VCdK4XDOqBUe3HiVF1BMLapj/p168Pc/D3rV6/2xM8wfp0TOg1mAk3g5f3BAfNz +4JZwn2LoKpPn2LP+3OWKzluGJxiJ8Qm9Csj7skxUW5W89CDUXvurgGquPDmcr5kA7/r EVjVqiZAE9wQPKCdLxNKt9q9QOTZ2k6xlrLtva5eCMt2DIHo0OunH8JIUfurIg22vOB/ pNZCpY6uUYSkZLeywfDbtCBwrsTQKYAdd/j3m/IruLlpZ6cowfDioTD1IzYLbxEa0gfg 6VdMe40DlZYEEqr+0lFBQ3OFEn1AU825Hj4AafLxssUqkZ3i0tYJYfWS3BSYAxrCmHV7 vcvg== X-Gm-Message-State: AOAM532dfP/F5vCJ7zGgtJV8+LNf3wjThSiOV7EKPX1MnHTmXdZbl40/ f/joqPzuEztrapWDLyNzHWP7tp8Og0w= X-Google-Smtp-Source: ABdhPJxQn2PlabLpz3EvQ6jDMs++ifhf+Zi6f4q+W+lpXNHVb0BzXjOJ061T6BRtE6iorjvzB9U0uA== X-Received: by 2002:a05:6214:1d0d:: with SMTP id e13mr31689557qvd.0.1635811043885; Mon, 01 Nov 2021 16:57:23 -0700 (PDT) Received: from rekt.ibmuc.com ([191.19.172.174]) by smtp.gmail.com with ESMTPSA id p187sm10927212qkd.101.2021.11.01.16.57.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Nov 2021 16:57:23 -0700 (PDT) From: Daniel Henrique Barboza To: qemu-devel@nongnu.org Subject: [PATCH v5 09/10] target/ppc: PMU Event-Based exception support Date: Mon, 1 Nov 2021 20:56:41 -0300 Message-Id: <20211101235642.926773-10-danielhb413@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211101235642.926773-1-danielhb413@gmail.com> References: <20211101235642.926773-1-danielhb413@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::f29; envelope-from=danielhb413@gmail.com; helo=mail-qv1-xf29.google.com X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-ppc@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gustavo Romero , Gustavo Romero , Daniel Henrique Barboza , richard.henderson@linaro.org, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, matheus.ferst@eldorado.org.br, david@gibson.dropbear.id.au Errors-To: qemu-ppc-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-ppc" From: Gustavo Romero Following up the rfebb implementation, this patch adds the EBB exception support that are triggered by Performance Monitor alerts. This exception occurs when an enabled PMU condition or event happens and both MMCR0_EBE and BESCR_PME are set. The supported PM alerts will consist of counter negative conditions of the PMU counters. This will be achieved by a timer mechanism that will predict when a counter becomes negative. The PMU timer callback will set the appropriate bits in MMCR0 and fire a PMC interrupt. The EBB exception code will then set the appropriate BESCR bits, set the next instruction pointer to the address pointed by the return register (SPR_EBBRR), and redirect execution to the handler (pointed by SPR_EBBHR). CC: Gustavo Romero Signed-off-by: Gustavo Romero Signed-off-by: Daniel Henrique Barboza --- target/ppc/cpu.h | 5 ++++- target/ppc/excp_helper.c | 28 ++++++++++++++++++++++++++++ target/ppc/power8-pmu.c | 26 ++++++++++++++++++++++++-- 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 8f545ff482..592031ce54 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -129,8 +129,10 @@ enum { /* ISA 3.00 additions */ POWERPC_EXCP_HVIRT = 101, POWERPC_EXCP_SYSCALL_VECTORED = 102, /* scv exception */ + POWERPC_EXCP_EBB = 103, /* Event-based branch exception */ + /* EOL */ - POWERPC_EXCP_NB = 103, + POWERPC_EXCP_NB = 104, /* QEMU exceptions: special cases we want to stop translation */ POWERPC_EXCP_SYSCALL_USER = 0x203, /* System call in user mode only */ }; @@ -2455,6 +2457,7 @@ enum { PPC_INTERRUPT_HMI, /* Hypervisor Maintenance interrupt */ PPC_INTERRUPT_HDOORBELL, /* Hypervisor Doorbell interrupt */ PPC_INTERRUPT_HVIRT, /* Hypervisor virtualization interrupt */ + PPC_INTERRUPT_PMC, /* Hypervisor virtualization interrupt */ }; /* Processor Compatibility mask (PCR) */ diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 7be334e007..88aa0a84f8 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -797,6 +797,22 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) cpu_abort(cs, "Non maskable external exception " "is not implemented yet !\n"); break; + case POWERPC_EXCP_EBB: /* Event-based branch exception */ + if ((env->spr[SPR_BESCR] & BESCR_GE) && + (env->spr[SPR_BESCR] & BESCR_PME)) { + target_ulong nip; + + env->spr[SPR_BESCR] &= ~BESCR_GE; /* Clear GE */ + env->spr[SPR_BESCR] |= BESCR_PMEO; /* Set PMEO */ + env->spr[SPR_EBBRR] = env->nip; /* Save NIP for rfebb insn */ + nip = env->spr[SPR_EBBHR]; /* EBB handler */ + powerpc_set_excp_state(cpu, nip, env->msr); + } + /* + * This interrupt is handled by userspace. No need + * to proceed. + */ + return; default: excp_invalid: cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); @@ -1044,6 +1060,18 @@ static void ppc_hw_interrupt(CPUPPCState *env) powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_THERM); return; } + /* PMC -> Event-based branch exception */ + if (env->pending_interrupts & (1 << PPC_INTERRUPT_PMC)) { + /* + * Performance Monitor event-based exception can only + * occur in problem state. + */ + if (msr_pr == 1) { + env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PMC); + powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_EBB); + return; + } + } } if (env->resume_as_sreset) { diff --git a/target/ppc/power8-pmu.c b/target/ppc/power8-pmu.c index aa10233b29..ca3954ff0e 100644 --- a/target/ppc/power8-pmu.c +++ b/target/ppc/power8-pmu.c @@ -323,8 +323,30 @@ static void fire_PMC_interrupt(PowerPCCPU *cpu) return; } - /* PMC interrupt not implemented yet */ - return; + if (env->spr[SPR_POWER_MMCR0] & MMCR0_FCECE) { + env->spr[SPR_POWER_MMCR0] &= ~MMCR0_FCECE; + env->spr[SPR_POWER_MMCR0] |= MMCR0_FC; + + /* Changing MMCR0_FC demands a new hflags compute */ + hreg_compute_hflags(env); + + /* + * Delete all pending timers if we need to freeze + * the PMC. We'll restart them when the PMC starts + * running again. + */ + pmu_delete_timers(env); + } + + pmu_update_cycles(env); + + if (env->spr[SPR_POWER_MMCR0] & MMCR0_PMAE) { + env->spr[SPR_POWER_MMCR0] &= ~MMCR0_PMAE; + env->spr[SPR_POWER_MMCR0] |= MMCR0_PMAO; + } + + /* Fire the PMC hardware exception */ + ppc_set_irq(cpu, PPC_INTERRUPT_PMC, 1); } /* This helper assumes that the PMC is running. */