From nobody Tue Nov 4 15:27:56 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1530638759067751.0969538505018; Tue, 3 Jul 2018 10:25:59 -0700 (PDT) Received: from localhost ([::1]:41909 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1faP3k-0000CT-V2 for importer@patchew.org; Tue, 03 Jul 2018 13:25:48 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33510) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1faP2k-0008Ax-77 for qemu-devel@nongnu.org; Tue, 03 Jul 2018 13:24:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1faP2i-0005Xz-SA for qemu-devel@nongnu.org; Tue, 03 Jul 2018 13:24:46 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:43246) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1faP2f-0005Vo-JL; Tue, 03 Jul 2018 13:24:41 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1faOpC-00033H-Io; Tue, 03 Jul 2018 18:10:46 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Tue, 3 Jul 2018 18:10:41 +0100 Message-Id: <20180703171044.9503-2-peter.maydell@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180703171044.9503-1-peter.maydell@linaro.org> References: <20180703171044.9503-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PATCH for-3.0 1/4] ptimer: Add TRIGGER_ONLY_ON_DECREMENT policy option X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Guenter Roeck , patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The CMSDK timer behaviour is that an interrupt is triggered when the counter counts down from 1 to 0; however one is not triggered if the counter is manually set to 0 by a guest write to the counter register. Currently ptimer can't handle this; add a policy option to allow a ptimer user to request this behaviour. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Tested-by: Guenter Roeck --- include/hw/ptimer.h | 9 +++++++++ hw/core/ptimer.c | 22 +++++++++++++++++++++- tests/ptimer-test.c | 25 +++++++++++++++++++------ 3 files changed, 49 insertions(+), 7 deletions(-) diff --git a/include/hw/ptimer.h b/include/hw/ptimer.h index fc4ef5cc1d2..0731d9aef19 100644 --- a/include/hw/ptimer.h +++ b/include/hw/ptimer.h @@ -69,6 +69,15 @@ * not the one less. */ #define PTIMER_POLICY_NO_COUNTER_ROUND_DOWN (1 << 4) =20 +/* + * Starting to run with a zero counter, or setting the counter to "0" via + * ptimer_set_count() or ptimer_set_limit() will not trigger the timer + * (though it will cause a reload). Only a counter decrement to "0" + * will cause a trigger. Not compatible with NO_IMMEDIATE_TRIGGER; + * ptimer_init() will assert() that you don't set both. + */ +#define PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT (1 << 5) + /* ptimer.c */ typedef struct ptimer_state ptimer_state; typedef void (*ptimer_cb)(void *opaque); diff --git a/hw/core/ptimer.c b/hw/core/ptimer.c index 7221c68a984..170fd34d8b5 100644 --- a/hw/core/ptimer.c +++ b/hw/core/ptimer.c @@ -45,8 +45,20 @@ static void ptimer_reload(ptimer_state *s, int delta_adj= ust) uint32_t period_frac =3D s->period_frac; uint64_t period =3D s->period; uint64_t delta =3D s->delta; + bool suppress_trigger =3D false; =20 - if (delta =3D=3D 0 && !(s->policy_mask & PTIMER_POLICY_NO_IMMEDIATE_TR= IGGER)) { + /* + * Note that if delta_adjust is 0 then we must be here because of + * a count register write or timer start, not because of timer expiry. + * In that case the policy might require us to suppress the timer trig= ger + * that we would otherwise generate for a zero delta. + */ + if (delta_adjust =3D=3D 0 && + (s->policy_mask & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT)) { + suppress_trigger =3D true; + } + if (delta =3D=3D 0 && !(s->policy_mask & PTIMER_POLICY_NO_IMMEDIATE_TR= IGGER) + && !suppress_trigger) { ptimer_trigger(s); } =20 @@ -353,6 +365,14 @@ ptimer_state *ptimer_init(QEMUBH *bh, uint8_t policy_m= ask) s->bh =3D bh; s->timer =3D timer_new_ns(QEMU_CLOCK_VIRTUAL, ptimer_tick, s); s->policy_mask =3D policy_mask; + + /* + * These two policies are incompatible -- trigger-on-decrement implies + * a timer trigger when the count becomes 0, but no-immediate-trigger + * implies a trigger when the count stops being 0. + */ + assert(!((policy_mask & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT) && + (policy_mask & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER))); return s; } =20 diff --git a/tests/ptimer-test.c b/tests/ptimer-test.c index 41488896f76..b30aad07372 100644 --- a/tests/ptimer-test.c +++ b/tests/ptimer-test.c @@ -208,6 +208,7 @@ static void check_periodic(gconstpointer arg) bool no_immediate_trigger =3D (*policy & PTIMER_POLICY_NO_IMMEDIATE_TR= IGGER); bool no_immediate_reload =3D (*policy & PTIMER_POLICY_NO_IMMEDIATE_REL= OAD); bool no_round_down =3D (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN); + bool trig_only_on_dec =3D (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DEC= REMENT); =20 triggered =3D false; =20 @@ -311,7 +312,7 @@ static void check_periodic(gconstpointer arg) g_assert_cmpuint(ptimer_get_count(ptimer), =3D=3D, no_immediate_reload ? 0 : 10); =20 - if (no_immediate_trigger) { + if (no_immediate_trigger || trig_only_on_dec) { g_assert_false(triggered); } else { g_assert_true(triggered); @@ -506,6 +507,7 @@ static void check_run_with_delta_0(gconstpointer arg) bool no_immediate_trigger =3D (*policy & PTIMER_POLICY_NO_IMMEDIATE_TR= IGGER); bool no_immediate_reload =3D (*policy & PTIMER_POLICY_NO_IMMEDIATE_REL= OAD); bool no_round_down =3D (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN); + bool trig_only_on_dec =3D (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DEC= REMENT); =20 triggered =3D false; =20 @@ -515,7 +517,7 @@ static void check_run_with_delta_0(gconstpointer arg) g_assert_cmpuint(ptimer_get_count(ptimer), =3D=3D, no_immediate_reload ? 0 : 99); =20 - if (no_immediate_trigger) { + if (no_immediate_trigger || trig_only_on_dec) { g_assert_false(triggered); } else { g_assert_true(triggered); @@ -563,7 +565,7 @@ static void check_run_with_delta_0(gconstpointer arg) g_assert_cmpuint(ptimer_get_count(ptimer), =3D=3D, no_immediate_reload ? 0 : 99); =20 - if (no_immediate_trigger) { + if (no_immediate_trigger || trig_only_on_dec) { g_assert_false(triggered); } else { g_assert_true(triggered); @@ -609,6 +611,7 @@ static void check_periodic_with_load_0(gconstpointer ar= g) ptimer_state *ptimer =3D ptimer_init(bh, *policy); bool continuous_trigger =3D (*policy & PTIMER_POLICY_CONTINUOUS_TRIGGE= R); bool no_immediate_trigger =3D (*policy & PTIMER_POLICY_NO_IMMEDIATE_TR= IGGER); + bool trig_only_on_dec =3D (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DEC= REMENT); =20 triggered =3D false; =20 @@ -617,7 +620,7 @@ static void check_periodic_with_load_0(gconstpointer ar= g) =20 g_assert_cmpuint(ptimer_get_count(ptimer), =3D=3D, 0); =20 - if (no_immediate_trigger) { + if (no_immediate_trigger || trig_only_on_dec) { g_assert_false(triggered); } else { g_assert_true(triggered); @@ -667,6 +670,7 @@ static void check_oneshot_with_load_0(gconstpointer arg) QEMUBH *bh =3D qemu_bh_new(ptimer_trigger, NULL); ptimer_state *ptimer =3D ptimer_init(bh, *policy); bool no_immediate_trigger =3D (*policy & PTIMER_POLICY_NO_IMMEDIATE_TR= IGGER); + bool trig_only_on_dec =3D (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DEC= REMENT); =20 triggered =3D false; =20 @@ -675,7 +679,7 @@ static void check_oneshot_with_load_0(gconstpointer arg) =20 g_assert_cmpuint(ptimer_get_count(ptimer), =3D=3D, 0); =20 - if (no_immediate_trigger) { + if (no_immediate_trigger || trig_only_on_dec) { g_assert_false(triggered); } else { g_assert_true(triggered); @@ -725,6 +729,10 @@ static void add_ptimer_tests(uint8_t policy) g_strlcat(policy_name, "no_counter_rounddown,", 256); } =20 + if (policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT) { + g_strlcat(policy_name, "trigger_only_on_decrement,", 256); + } + g_test_add_data_func_full( tmp =3D g_strdup_printf("/ptimer/set_count policy=3D%s", policy_na= me), g_memdup(&policy, 1), check_set_count, g_free); @@ -790,10 +798,15 @@ static void add_ptimer_tests(uint8_t policy) =20 static void add_all_ptimer_policies_comb_tests(void) { - int last_policy =3D PTIMER_POLICY_NO_COUNTER_ROUND_DOWN; + int last_policy =3D PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT; int policy =3D PTIMER_POLICY_DEFAULT; =20 for (; policy < (last_policy << 1); policy++) { + if ((policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT) && + (policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER)) { + /* Incompatible policy flag settings -- don't try to test them= */ + continue; + } add_ptimer_tests(policy); } } --=20 2.17.1 From nobody Tue Nov 4 15:27:56 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1530638164115676.6456489915513; Tue, 3 Jul 2018 10:16:04 -0700 (PDT) Received: from localhost ([::1]:41878 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1faOuJ-00073g-Fj for importer@patchew.org; Tue, 03 Jul 2018 13:16:03 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59351) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1faOpQ-0003WS-V5 for qemu-devel@nongnu.org; Tue, 03 Jul 2018 13:11:01 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1faOpP-0005H8-Qw for qemu-devel@nongnu.org; Tue, 03 Jul 2018 13:11:00 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:43234) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1faOpN-00058l-68; Tue, 03 Jul 2018 13:10:57 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1faOpD-00033Z-80; Tue, 03 Jul 2018 18:10:47 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Tue, 3 Jul 2018 18:10:42 +0100 Message-Id: <20180703171044.9503-3-peter.maydell@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180703171044.9503-1-peter.maydell@linaro.org> References: <20180703171044.9503-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PATCH for-3.0 2/4] hw/timer/cmsdk-apb-timer: Correct ptimer policy settings X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Guenter Roeck , patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The CMSDK timer interrupt triggers when the counter goes from 1 to 0, so we want to trigger immediately, rather than waiting for a clock cycle. Drop the incorrect NO_IMMEDIATE_TRIGGER setting. We also do not want to get an interrupt if the guest sets the counter directly to zero, so use the new TRIGGER_ONLY_ON_DECREMENT policy. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Tested-by: Guenter Roeck --- hw/timer/cmsdk-apb-timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/timer/cmsdk-apb-timer.c b/hw/timer/cmsdk-apb-timer.c index 9878746609a..1f99081db1a 100644 --- a/hw/timer/cmsdk-apb-timer.c +++ b/hw/timer/cmsdk-apb-timer.c @@ -201,7 +201,7 @@ static void cmsdk_apb_timer_realize(DeviceState *dev, E= rror **errp) bh =3D qemu_bh_new(cmsdk_apb_timer_tick, s); s->timer =3D ptimer_init(bh, PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD | - PTIMER_POLICY_NO_IMMEDIATE_TRIGGER | + PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT | PTIMER_POLICY_NO_IMMEDIATE_RELOAD | PTIMER_POLICY_NO_COUNTER_ROUND_DOWN); =20 --=20 2.17.1 From nobody Tue Nov 4 15:27:56 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1530637963581381.1514260179407; Tue, 3 Jul 2018 10:12:43 -0700 (PDT) Received: from localhost ([::1]:41854 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1faOqw-0004QA-36 for importer@patchew.org; Tue, 03 Jul 2018 13:12:34 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59332) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1faOpP-0003Uf-Aw for qemu-devel@nongnu.org; Tue, 03 Jul 2018 13:11:00 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1faOpO-0005G2-BD for qemu-devel@nongnu.org; Tue, 03 Jul 2018 13:10:59 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:43234) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1faOpM-00058l-7S; Tue, 03 Jul 2018 13:10:56 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1faOpE-00034F-0z; Tue, 03 Jul 2018 18:10:48 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Tue, 3 Jul 2018 18:10:43 +0100 Message-Id: <20180703171044.9503-4-peter.maydell@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180703171044.9503-1-peter.maydell@linaro.org> References: <20180703171044.9503-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PATCH for-3.0 3/4] hw/timer/cmsdk-apb-timer: Correctly identify and set one-shot mode X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Guenter Roeck , patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Guenter Roeck The CMSDK APB timer is currently always configured as periodic timer. This results in the following messages when trying to boot Linux. Timer with delta zero, disabling If the timer limit set with the RELOAD command is 0, the timer needs to be enabled as one-shot timer. Signed-off-by: Guenter Roeck Message-id: 1529374119-27015-1-git-send-email-linux@roeck-us.net Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Tested-by: Guenter Roeck --- hw/timer/cmsdk-apb-timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/timer/cmsdk-apb-timer.c b/hw/timer/cmsdk-apb-timer.c index 1f99081db1a..3ebdc7be408 100644 --- a/hw/timer/cmsdk-apb-timer.c +++ b/hw/timer/cmsdk-apb-timer.c @@ -119,7 +119,7 @@ static void cmsdk_apb_timer_write(void *opaque, hwaddr = offset, uint64_t value, } s->ctrl =3D value & 0xf; if (s->ctrl & R_CTRL_EN_MASK) { - ptimer_run(s->timer, 0); + ptimer_run(s->timer, ptimer_get_limit(s->timer) =3D=3D 0); } else { ptimer_stop(s->timer); } --=20 2.17.1 From nobody Tue Nov 4 15:27:56 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1530638089083600.4385848896128; Tue, 3 Jul 2018 10:14:49 -0700 (PDT) Received: from localhost ([::1]:41867 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1faOt2-00069J-L1 for importer@patchew.org; Tue, 03 Jul 2018 13:14:44 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59308) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1faOpO-0003UP-I7 for qemu-devel@nongnu.org; Tue, 03 Jul 2018 13:10:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1faOpN-0005Ff-KR for qemu-devel@nongnu.org; Tue, 03 Jul 2018 13:10:58 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:43234) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1faOpL-00058l-8U; Tue, 03 Jul 2018 13:10:55 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1faOpE-00034V-O8; Tue, 03 Jul 2018 18:10:48 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Tue, 3 Jul 2018 18:10:44 +0100 Message-Id: <20180703171044.9503-5-peter.maydell@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180703171044.9503-1-peter.maydell@linaro.org> References: <20180703171044.9503-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PATCH for-3.0 4/4] hw/timer/cmsdk-apb-timer: run or stop timer on writes to RELOAD and VALUE X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Guenter Roeck , patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" If the CMSDK APB timer is set up with a zero RELOAD value then it will count down to zero, fire once and then stay at zero. From the point of view of the ptimer system, the timer is disabled; but the enable bit in the CTRL register is still set and if the guest subsequently writes to the RELOAD or VALUE registers this should cause the timer to start counting down again. Add code to the write paths for RELOAD and VALUE so that we correctly restart the timer in this situation. Conversely, if the new RELOAD and VALUE are both zero, we should stop the ptimer. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Tested-by: Guenter Roeck --- hw/timer/cmsdk-apb-timer.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/hw/timer/cmsdk-apb-timer.c b/hw/timer/cmsdk-apb-timer.c index 3ebdc7be408..801d1dba741 100644 --- a/hw/timer/cmsdk-apb-timer.c +++ b/hw/timer/cmsdk-apb-timer.c @@ -126,10 +126,26 @@ static void cmsdk_apb_timer_write(void *opaque, hwadd= r offset, uint64_t value, break; case A_RELOAD: /* Writing to reload also sets the current timer value */ + if (!value) { + ptimer_stop(s->timer); + } ptimer_set_limit(s->timer, value, 1); + if (value && (s->ctrl & R_CTRL_EN_MASK)) { + /* + * Make sure timer is running (it might have stopped if this + * was an expired one-shot timer) + */ + ptimer_run(s->timer, 0); + } break; case A_VALUE: + if (!value && !ptimer_get_limit(s->timer)) { + ptimer_stop(s->timer); + } ptimer_set_count(s->timer, value); + if (value && (s->ctrl & R_CTRL_EN_MASK)) { + ptimer_run(s->timer, ptimer_get_limit(s->timer) =3D=3D 0); + } break; case A_INTSTATUS: /* Just one bit, which is W1C. */ --=20 2.17.1