blob: eb91ace427fca6c9a5020cd61cf0f330a0cd7294 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#include <lib/unittest/unittest.h>
#include <arch/interrupt.h>
#include <arch/ops.h>
static bool interrupt_disable_test() {
BEGIN_TEST;
// make sure ints are disabled and that a simple enable/disable tracks
ASSERT_EQ(false, arch_ints_disabled());
arch_disable_ints();
ASSERT_EQ(true, arch_ints_disabled());
arch_enable_ints();
ASSERT_EQ(false, arch_ints_disabled());
END_TEST;
}
static bool interrupt_save_restore_test() {
BEGIN_TEST;
// validate that a simple save/restore works
{
ASSERT_EQ(false, arch_ints_disabled());
interrupt_saved_state_t state = arch_interrupt_save();
ASSERT_EQ(true, arch_ints_disabled());
arch_interrupt_restore(state);
ASSERT_EQ(false, arch_ints_disabled());
}
// validate that a nested save/restore works
{
ASSERT_EQ(false, arch_ints_disabled());
interrupt_saved_state_t state = arch_interrupt_save();
ASSERT_EQ(true, arch_ints_disabled());
interrupt_saved_state_t state2 = arch_interrupt_save();
ASSERT_EQ(true, arch_ints_disabled());
arch_interrupt_restore(state2);
ASSERT_EQ(true, arch_ints_disabled());
arch_interrupt_restore(state);
ASSERT_EQ(false, arch_ints_disabled());
}
END_TEST;
}
static bool interrupt_save_restore_guard_test() {
BEGIN_TEST;
// validate that a save/restore C++ guard works
ASSERT_EQ(false, arch_ints_disabled());
{
InterruptDisableGuard irqd;
ASSERT_EQ(true, arch_ints_disabled());
}
ASSERT_EQ(false, arch_ints_disabled());
// validate that a nested guard works
{
InterruptDisableGuard irqd;
ASSERT_EQ(true, arch_ints_disabled());
{
InterruptDisableGuard irqd2;
ASSERT_EQ(true, arch_ints_disabled());
}
ASSERT_EQ(true, arch_ints_disabled());
}
ASSERT_EQ(false, arch_ints_disabled());
// validate that reenable works
{
InterruptDisableGuard irqd;
ASSERT_EQ(true, arch_ints_disabled());
irqd.Reenable();
ASSERT_EQ(false, arch_ints_disabled());
irqd.Reenable();
ASSERT_EQ(false, arch_ints_disabled());
}
ASSERT_EQ(false, arch_ints_disabled());
// validate that nested reenable works
{
InterruptDisableGuard irqd;
ASSERT_EQ(true, arch_ints_disabled());
{
InterruptDisableGuard irqd2;
ASSERT_EQ(true, arch_ints_disabled());
irqd2.Reenable();
ASSERT_EQ(true, arch_ints_disabled());
irqd2.Reenable();
ASSERT_EQ(true, arch_ints_disabled());
}
ASSERT_EQ(true, arch_ints_disabled());
}
ASSERT_EQ(false, arch_ints_disabled());
END_TEST;
}
UNITTEST_START_TESTCASE(interrupt_disable_tests)
UNITTEST("interrupt_disable_test", interrupt_disable_test)
UNITTEST("interrupt_save_restore_test", interrupt_save_restore_test)
UNITTEST("interrupt_save_restore_guard_test", interrupt_save_restore_guard_test)
UNITTEST_END_TESTCASE(interrupt_disable_tests, "interrupt_tests", "Test arch enable/disable interrupt routines.")