diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2018-07-09 14:51:34 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2018-07-09 14:51:34 +0100 |
commit | 086ede32afc9c70de3d75c4fb91c63db790cbd5c (patch) | |
tree | 471f251d68728013c8737b5b90022b1628e76521 /tests | |
parent | b78aae9bb65876baa47b73d5cf63372171630bf9 (diff) | |
download | qemu-086ede32afc9c70de3d75c4fb91c63db790cbd5c.zip qemu-086ede32afc9c70de3d75c4fb91c63db790cbd5c.tar.gz qemu-086ede32afc9c70de3d75c4fb91c63db790cbd5c.tar.bz2 |
ptimer: Add TRIGGER_ONLY_ON_DECREMENT policy option
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 <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Guenter Roeck <linux@roeck-us.net>
Message-id: 20180703171044.9503-2-peter.maydell@linaro.org
Diffstat (limited to 'tests')
-rw-r--r-- | tests/ptimer-test.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/tests/ptimer-test.c b/tests/ptimer-test.c index 4148889..b30aad0 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 = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER); bool no_immediate_reload = (*policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD); bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN); + bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT); triggered = false; @@ -311,7 +312,7 @@ static void check_periodic(gconstpointer arg) g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_immediate_reload ? 0 : 10); - 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 = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER); bool no_immediate_reload = (*policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD); bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN); + bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT); triggered = false; @@ -515,7 +517,7 @@ static void check_run_with_delta_0(gconstpointer arg) g_assert_cmpuint(ptimer_get_count(ptimer), ==, no_immediate_reload ? 0 : 99); - 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), ==, no_immediate_reload ? 0 : 99); - 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 arg) ptimer_state *ptimer = ptimer_init(bh, *policy); bool continuous_trigger = (*policy & PTIMER_POLICY_CONTINUOUS_TRIGGER); bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER); + bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT); triggered = false; @@ -617,7 +620,7 @@ static void check_periodic_with_load_0(gconstpointer arg) g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0); - 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 = qemu_bh_new(ptimer_trigger, NULL); ptimer_state *ptimer = ptimer_init(bh, *policy); bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER); + bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT); triggered = false; @@ -675,7 +679,7 @@ static void check_oneshot_with_load_0(gconstpointer arg) g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0); - 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); } + if (policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT) { + g_strlcat(policy_name, "trigger_only_on_decrement,", 256); + } + g_test_add_data_func_full( tmp = g_strdup_printf("/ptimer/set_count policy=%s", policy_name), g_memdup(&policy, 1), check_set_count, g_free); @@ -790,10 +798,15 @@ static void add_ptimer_tests(uint8_t policy) static void add_all_ptimer_policies_comb_tests(void) { - int last_policy = PTIMER_POLICY_NO_COUNTER_ROUND_DOWN; + int last_policy = PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT; int policy = PTIMER_POLICY_DEFAULT; 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); } } |