blob: 02b192ecd1168674498fbaa6fd28b29a2bc489b5 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
#include "sw/device/lib/dif/dif_clkmgr.h"
#include "gtest/gtest.h"
#include "sw/device/lib/base/mmio.h"
#include "sw/device/lib/base/mock_mmio.h"
#include "sw/device/lib/base/multibits.h"
#include "sw/device/lib/dif/dif_test_base.h"
// Generated.
#include "clkmgr_regs.h"
namespace dif_clkmgr_unittest {
namespace {
using mock_mmio::MmioTest;
using mock_mmio::MockDevice;
using testing::Test;
const dif_clkmgr_measure_clock_t kBadMeasClock =
static_cast<dif_clkmgr_measure_clock_t>(27);
class ClkMgrTest : public Test, public MmioTest {
protected:
dif_clkmgr_t clkmgr_ = {.base_addr = dev().region()};
};
class JitterEnableTest : public ClkMgrTest {};
// SetEnabled uses EXPECT_WRITE32 instead of EXPECT_MASK32 because
// dif_clkmgr_jitter_set_enabled doesn't perform a read, just a write.
TEST_F(JitterEnableTest, SetEnabled) {
// Disable jitter.
EXPECT_WRITE32(CLKMGR_JITTER_ENABLE_REG_OFFSET, kMultiBitBool4False);
EXPECT_DIF_OK(dif_clkmgr_jitter_set_enabled(&clkmgr_, kDifToggleDisabled));
// Enable jitter.
EXPECT_WRITE32(CLKMGR_JITTER_ENABLE_REG_OFFSET, kMultiBitBool4True);
EXPECT_DIF_OK(dif_clkmgr_jitter_set_enabled(&clkmgr_, kDifToggleEnabled));
}
TEST_F(JitterEnableTest, SetEnabledError) {
// Null handle.
EXPECT_DIF_BADARG(dif_clkmgr_jitter_set_enabled(nullptr, kDifToggleEnabled));
}
TEST_F(JitterEnableTest, GetEnabled) {
// Get jitter (enabled).
{
dif_toggle_t state = kDifToggleDisabled;
EXPECT_READ32(CLKMGR_JITTER_ENABLE_REG_OFFSET, kMultiBitBool4True);
EXPECT_DIF_OK(dif_clkmgr_jitter_get_enabled(&clkmgr_, &state));
EXPECT_EQ(state, kDifToggleEnabled);
}
// Get jitter (disabled).
{
dif_toggle_t state = kDifToggleEnabled;
EXPECT_READ32(CLKMGR_JITTER_ENABLE_REG_OFFSET, kMultiBitBool4False);
EXPECT_DIF_OK(dif_clkmgr_jitter_get_enabled(&clkmgr_, &state));
EXPECT_EQ(state, kDifToggleDisabled);
}
}
TEST_F(JitterEnableTest, GetEnabledError) {
dif_toggle_t state = kDifToggleDisabled;
EXPECT_DIF_BADARG(dif_clkmgr_jitter_get_enabled(nullptr, &state));
EXPECT_DIF_BADARG(dif_clkmgr_jitter_get_enabled(&clkmgr_, nullptr));
}
class GateableClockTest : public ClkMgrTest {};
TEST_F(GateableClockTest, SetEnabled) {
// Disable gateable clock.
EXPECT_MASK32(CLKMGR_CLK_ENABLES_REG_OFFSET,
{{CLKMGR_CLK_ENABLES_CLK_IO_DIV4_PERI_EN_BIT, 0x1, false}});
EXPECT_DIF_OK(dif_clkmgr_gateable_clock_set_enabled(
&clkmgr_, CLKMGR_CLK_ENABLES_CLK_IO_DIV4_PERI_EN_BIT,
kDifToggleDisabled));
// Enable gateable clock.
EXPECT_MASK32(CLKMGR_CLK_ENABLES_REG_OFFSET,
{{CLKMGR_CLK_ENABLES_CLK_USB_PERI_EN_BIT, 0x1, true}});
EXPECT_DIF_OK(dif_clkmgr_gateable_clock_set_enabled(
&clkmgr_, CLKMGR_CLK_ENABLES_CLK_USB_PERI_EN_BIT, kDifToggleEnabled));
}
TEST_F(GateableClockTest, SetEnabledError) {
// Null handle.
EXPECT_DIF_BADARG(dif_clkmgr_gateable_clock_set_enabled(
nullptr, CLKMGR_CLK_ENABLES_CLK_IO_DIV4_PERI_EN_BIT, kDifToggleEnabled));
// Out-of-bounds index [~0].
EXPECT_DIF_BADARG(dif_clkmgr_gateable_clock_set_enabled(
&clkmgr_, std::numeric_limits<dif_clkmgr_gateable_clock_t>::max(),
kDifToggleEnabled));
// Out-of-bounds index [last+1].
EXPECT_DIF_BADARG(dif_clkmgr_gateable_clock_set_enabled(
&clkmgr_, CLKMGR_PARAM_NUM_SW_GATEABLE_CLOCKS, kDifToggleDisabled));
}
TEST_F(GateableClockTest, GetEnabled) {
// Get gateable clock status (enabled).
{
dif_toggle_t state = kDifToggleDisabled;
EXPECT_READ32(CLKMGR_CLK_ENABLES_REG_OFFSET,
{{CLKMGR_CLK_ENABLES_CLK_IO_DIV4_PERI_EN_BIT, true}});
EXPECT_DIF_OK(dif_clkmgr_gateable_clock_get_enabled(
&clkmgr_, CLKMGR_CLK_ENABLES_CLK_IO_DIV4_PERI_EN_BIT, &state));
EXPECT_EQ(state, kDifToggleEnabled);
}
// Get gateable clock status (disabled).
{
dif_toggle_t state = kDifToggleEnabled;
EXPECT_READ32(CLKMGR_CLK_ENABLES_REG_OFFSET,
{{CLKMGR_CLK_ENABLES_CLK_USB_PERI_EN_BIT, false}});
EXPECT_DIF_OK(dif_clkmgr_gateable_clock_get_enabled(
&clkmgr_, CLKMGR_CLK_ENABLES_CLK_USB_PERI_EN_BIT, &state));
EXPECT_EQ(state, kDifToggleDisabled);
}
}
TEST_F(GateableClockTest, GetEnabledError) {
dif_toggle_t state = kDifToggleDisabled;
EXPECT_DIF_BADARG(dif_clkmgr_gateable_clock_get_enabled(
nullptr, CLKMGR_CLK_ENABLES_CLK_IO_DIV4_PERI_EN_BIT, &state));
EXPECT_DIF_BADARG(dif_clkmgr_gateable_clock_get_enabled(
&clkmgr_, CLKMGR_CLK_ENABLES_CLK_IO_DIV4_PERI_EN_BIT, nullptr));
// Out-of-bounds index [~0].
EXPECT_DIF_BADARG(dif_clkmgr_gateable_clock_get_enabled(
&clkmgr_, std::numeric_limits<dif_clkmgr_gateable_clock_t>::max(),
&state));
// Out-of-bounds index [last+1].
EXPECT_DIF_BADARG(dif_clkmgr_gateable_clock_get_enabled(
&clkmgr_, CLKMGR_PARAM_NUM_SW_GATEABLE_CLOCKS, &state));
}
class HintableClockTest : public ClkMgrTest {};
TEST_F(HintableClockTest, SetHint) {
// Disable hint.
EXPECT_MASK32(CLKMGR_CLK_HINTS_REG_OFFSET,
{{CLKMGR_CLK_HINTS_CLK_MAIN_AES_HINT_BIT, 0x1, false}});
EXPECT_DIF_OK(dif_clkmgr_hintable_clock_set_hint(
&clkmgr_, CLKMGR_CLK_HINTS_CLK_MAIN_AES_HINT_BIT, kDifToggleDisabled));
// Enable hint.
EXPECT_MASK32(CLKMGR_CLK_HINTS_REG_OFFSET,
{{CLKMGR_PARAM_NUM_HINTABLE_CLOCKS - 1, 0x1, true}});
EXPECT_DIF_OK(dif_clkmgr_hintable_clock_set_hint(
&clkmgr_, CLKMGR_PARAM_NUM_HINTABLE_CLOCKS - 1, kDifToggleEnabled));
}
TEST_F(HintableClockTest, SetHintError) {
// Null handle.
EXPECT_DIF_BADARG(dif_clkmgr_hintable_clock_set_hint(
nullptr, CLKMGR_CLK_HINTS_CLK_MAIN_AES_HINT_BIT, kDifToggleEnabled));
// Out-of-bounds index [~0].
EXPECT_DIF_BADARG(dif_clkmgr_hintable_clock_set_hint(
&clkmgr_, std::numeric_limits<dif_clkmgr_hintable_clock_t>::max(),
kDifToggleEnabled));
// Out-of-bounds index [last+1].
EXPECT_DIF_BADARG(dif_clkmgr_hintable_clock_set_hint(
&clkmgr_, CLKMGR_PARAM_NUM_HINTABLE_CLOCKS, kDifToggleDisabled));
}
TEST_F(HintableClockTest, GetHint) {
// Get hint state (enabled).
{
dif_toggle_t state = kDifToggleDisabled;
EXPECT_READ32(CLKMGR_CLK_HINTS_REG_OFFSET,
{{CLKMGR_CLK_HINTS_CLK_MAIN_AES_HINT_BIT, true}});
EXPECT_DIF_OK(dif_clkmgr_hintable_clock_get_hint(
&clkmgr_, CLKMGR_CLK_HINTS_CLK_MAIN_AES_HINT_BIT, &state));
EXPECT_EQ(state, kDifToggleEnabled);
}
// Get hint state (disabled).
{
dif_toggle_t state = kDifToggleEnabled;
EXPECT_READ32(CLKMGR_CLK_HINTS_REG_OFFSET,
{{CLKMGR_CLK_HINTS_CLK_MAIN_OTBN_HINT_BIT, false}});
EXPECT_DIF_OK(dif_clkmgr_hintable_clock_get_hint(
&clkmgr_, CLKMGR_CLK_HINTS_CLK_MAIN_OTBN_HINT_BIT, &state));
EXPECT_EQ(state, kDifToggleDisabled);
}
}
TEST_F(HintableClockTest, GetHintError) {
dif_toggle_t state = kDifToggleDisabled;
EXPECT_DIF_BADARG(dif_clkmgr_hintable_clock_get_hint(
nullptr, CLKMGR_CLK_HINTS_CLK_MAIN_AES_HINT_BIT, &state));
EXPECT_DIF_BADARG(dif_clkmgr_hintable_clock_get_hint(
&clkmgr_, CLKMGR_CLK_HINTS_CLK_MAIN_AES_HINT_BIT, nullptr));
// Out-of-bounds index [~0].
EXPECT_DIF_BADARG(dif_clkmgr_hintable_clock_get_hint(
&clkmgr_, std::numeric_limits<dif_clkmgr_hintable_clock_t>::max(),
&state));
// Out-of-bounds index [last+1].
EXPECT_DIF_BADARG(dif_clkmgr_hintable_clock_get_hint(
&clkmgr_, CLKMGR_PARAM_NUM_HINTABLE_CLOCKS, &state));
}
TEST_F(HintableClockTest, GetEnabled) {
// Get hintable clock status (enabled).
{
dif_toggle_t state = kDifToggleEnabled;
EXPECT_READ32(CLKMGR_CLK_HINTS_STATUS_REG_OFFSET,
{{CLKMGR_CLK_HINTS_STATUS_CLK_MAIN_AES_VAL_BIT, false}});
EXPECT_DIF_OK(dif_clkmgr_hintable_clock_get_enabled(
&clkmgr_, CLKMGR_CLK_HINTS_STATUS_CLK_MAIN_AES_VAL_BIT, &state));
EXPECT_EQ(state, kDifToggleDisabled);
}
// Get hintable clock status (disabled).
{
dif_toggle_t state = kDifToggleDisabled;
EXPECT_READ32(CLKMGR_CLK_HINTS_STATUS_REG_OFFSET,
{{CLKMGR_CLK_HINTS_STATUS_CLK_MAIN_OTBN_VAL_BIT, true}});
EXPECT_DIF_OK(dif_clkmgr_hintable_clock_get_enabled(
&clkmgr_, CLKMGR_CLK_HINTS_STATUS_CLK_MAIN_OTBN_VAL_BIT, &state));
EXPECT_EQ(state, kDifToggleEnabled);
}
}
TEST_F(HintableClockTest, GetEnabledError) {
dif_toggle_t state = kDifToggleDisabled;
EXPECT_DIF_BADARG(dif_clkmgr_hintable_clock_get_enabled(
nullptr, CLKMGR_CLK_HINTS_STATUS_CLK_MAIN_AES_VAL_BIT, &state));
EXPECT_DIF_BADARG(dif_clkmgr_hintable_clock_get_enabled(
&clkmgr_, CLKMGR_CLK_HINTS_STATUS_CLK_MAIN_AES_VAL_BIT, nullptr));
// Out-of-bounds index [~0].
EXPECT_DIF_BADARG(dif_clkmgr_hintable_clock_get_enabled(
&clkmgr_, std::numeric_limits<dif_clkmgr_hintable_clock_t>::max(),
&state));
// Out-of-bounds index [last+1].
EXPECT_DIF_BADARG(dif_clkmgr_hintable_clock_get_enabled(
&clkmgr_, CLKMGR_PARAM_NUM_HINTABLE_CLOCKS, &state));
}
class MeasureCtrlTest : public ClkMgrTest {};
TEST_F(MeasureCtrlTest, Disable) {
EXPECT_WRITE32(CLKMGR_MEASURE_CTRL_REGWEN_REG_OFFSET, 0);
EXPECT_DIF_OK(dif_clkmgr_measure_ctrl_disable(&clkmgr_));
}
TEST_F(MeasureCtrlTest, DisableError) {
EXPECT_DIF_BADARG(dif_clkmgr_measure_ctrl_disable(nullptr));
}
TEST_F(MeasureCtrlTest, GetEnable) {
{ // enabled
dif_toggle_t state = kDifToggleDisabled;
EXPECT_READ32(CLKMGR_MEASURE_CTRL_REGWEN_REG_OFFSET,
{{CLKMGR_MEASURE_CTRL_REGWEN_EN_BIT, true}});
EXPECT_DIF_OK(dif_clkmgr_measure_ctrl_get_enable(&clkmgr_, &state));
EXPECT_EQ(state, kDifToggleEnabled);
}
{ // disabled
dif_toggle_t state = kDifToggleDisabled;
EXPECT_READ32(CLKMGR_MEASURE_CTRL_REGWEN_REG_OFFSET,
{{CLKMGR_MEASURE_CTRL_REGWEN_EN_BIT, false}});
EXPECT_DIF_OK(dif_clkmgr_measure_ctrl_get_enable(&clkmgr_, &state));
EXPECT_EQ(state, kDifToggleDisabled);
}
}
TEST_F(MeasureCtrlTest, GetEnableError) {
EXPECT_DIF_BADARG(dif_clkmgr_measure_ctrl_get_enable(nullptr, nullptr));
EXPECT_DIF_BADARG(dif_clkmgr_measure_ctrl_get_enable(&clkmgr_, nullptr));
dif_toggle_t state;
EXPECT_DIF_BADARG(dif_clkmgr_measure_ctrl_get_enable(nullptr, &state));
}
class MeasureCountTest : public ClkMgrTest {};
TEST_F(MeasureCountTest, EnableBadArgs) {
EXPECT_DIF_BADARG(
dif_clkmgr_enable_measure_counts(nullptr, kBadMeasClock, 2, 3));
// regwen on
EXPECT_READ32(CLKMGR_MEASURE_CTRL_REGWEN_REG_OFFSET, 1);
EXPECT_DIF_BADARG(
dif_clkmgr_enable_measure_counts(&clkmgr_, kBadMeasClock, 2, 3));
EXPECT_DIF_BADARG(dif_clkmgr_enable_measure_counts(
nullptr, kDifClkmgrMeasureClockIoDiv2, 2, 3));
// regwen on
EXPECT_READ32(CLKMGR_MEASURE_CTRL_REGWEN_REG_OFFSET, 1);
EXPECT_DIF_BADARG(
dif_clkmgr_enable_measure_counts(&clkmgr_, kBadMeasClock, 2, 3));
}
TEST_F(MeasureCountTest, EnableLocked) {
// regwen off
EXPECT_READ32(CLKMGR_MEASURE_CTRL_REGWEN_REG_OFFSET, 0);
EXPECT_EQ(dif_clkmgr_enable_measure_counts(
&clkmgr_, kDifClkmgrMeasureClockIoDiv2, 2, 3),
kDifLocked);
}
TEST_F(MeasureCountTest, Enable) {
uint32_t hi_val = 16;
uint32_t lo_val = 8;
uint32_t en_offset;
uint32_t reg_offset;
bitfield_field32_t lo_field;
bitfield_field32_t hi_field;
for (int i = kDifClkmgrMeasureClockIo; i <= kDifClkmgrMeasureClockUsb; ++i) {
dif_clkmgr_measure_clock_t clk = (dif_clkmgr_measure_clock_t)i;
switch (clk) {
#define PICK_COUNT_CTRL_FIELDS(kind_) \
en_offset = CLKMGR_##kind_##_MEAS_CTRL_EN_REG_OFFSET; \
reg_offset = CLKMGR_##kind_##_MEAS_CTRL_SHADOWED_REG_OFFSET; \
lo_field = CLKMGR_##kind_##_MEAS_CTRL_SHADOWED_LO_FIELD; \
hi_field = CLKMGR_##kind_##_MEAS_CTRL_SHADOWED_HI_FIELD; \
break // No semicolon to force semicolon below.
case kDifClkmgrMeasureClockIo:
PICK_COUNT_CTRL_FIELDS(IO);
case kDifClkmgrMeasureClockIoDiv2:
PICK_COUNT_CTRL_FIELDS(IO_DIV2);
case kDifClkmgrMeasureClockIoDiv4:
PICK_COUNT_CTRL_FIELDS(IO_DIV4);
case kDifClkmgrMeasureClockMain:
PICK_COUNT_CTRL_FIELDS(MAIN);
case kDifClkmgrMeasureClockUsb:
PICK_COUNT_CTRL_FIELDS(USB);
default:;
#undef PICK_COUNT_CTRL_FIELDS
}
EXPECT_READ32(CLKMGR_MEASURE_CTRL_REGWEN_REG_OFFSET, 1);
EXPECT_WRITE32(en_offset, kMultiBitBool4True);
std::vector<mock_mmio::BitField> thresholds_val = {
{
.offset = (uintptr_t)lo_field.index,
.value = (uintptr_t)lo_val,
},
{
.offset = hi_field.index,
.value = hi_val,
}};
EXPECT_WRITE32(reg_offset, thresholds_val);
EXPECT_WRITE32(reg_offset, thresholds_val);
EXPECT_DIF_OK(
dif_clkmgr_enable_measure_counts(&clkmgr_, clk, lo_val, hi_val));
}
}
TEST_F(MeasureCountTest, DisableBadArgs) {
EXPECT_DIF_BADARG(dif_clkmgr_disable_measure_counts(nullptr, kBadMeasClock));
// regwen on
EXPECT_READ32(CLKMGR_MEASURE_CTRL_REGWEN_REG_OFFSET, 1);
EXPECT_DIF_BADARG(dif_clkmgr_disable_measure_counts(&clkmgr_, kBadMeasClock));
EXPECT_DIF_BADARG(
dif_clkmgr_disable_measure_counts(nullptr, kDifClkmgrMeasureClockIoDiv2));
// regwen off
EXPECT_READ32(CLKMGR_MEASURE_CTRL_REGWEN_REG_OFFSET, 0);
EXPECT_EQ(
dif_clkmgr_disable_measure_counts(&clkmgr_, kDifClkmgrMeasureClockIoDiv2),
kDifLocked);
}
TEST_F(MeasureCountTest, DisableLocked) {
// regwen off
EXPECT_READ32(CLKMGR_MEASURE_CTRL_REGWEN_REG_OFFSET, 0);
EXPECT_EQ(
dif_clkmgr_disable_measure_counts(&clkmgr_, kDifClkmgrMeasureClockIoDiv2),
kDifLocked);
}
TEST_F(MeasureCountTest, Disable) {
uint32_t en_offset;
for (int i = kDifClkmgrMeasureClockIo; i <= kDifClkmgrMeasureClockUsb; ++i) {
dif_clkmgr_measure_clock_t clk = (dif_clkmgr_measure_clock_t)i;
switch (clk) {
#define PICK_COUNT_CTRL_FIELDS(kind_) \
en_offset = CLKMGR_##kind_##_MEAS_CTRL_EN_REG_OFFSET; \
break // No semicolon to force semicolon below.
case kDifClkmgrMeasureClockIo:
PICK_COUNT_CTRL_FIELDS(IO);
case kDifClkmgrMeasureClockIoDiv2:
PICK_COUNT_CTRL_FIELDS(IO_DIV2);
case kDifClkmgrMeasureClockIoDiv4:
PICK_COUNT_CTRL_FIELDS(IO_DIV4);
case kDifClkmgrMeasureClockMain:
PICK_COUNT_CTRL_FIELDS(MAIN);
case kDifClkmgrMeasureClockUsb:
PICK_COUNT_CTRL_FIELDS(USB);
default:;
#undef PICK_COUNT_CTRL_FIELDS
}
EXPECT_READ32(CLKMGR_MEASURE_CTRL_REGWEN_REG_OFFSET, 1);
EXPECT_WRITE32(en_offset, kMultiBitBool4False);
EXPECT_DIF_OK(dif_clkmgr_disable_measure_counts(&clkmgr_, clk));
}
}
TEST_F(MeasureCountTest, GetEnableBadArgs) {
dif_toggle_t state;
EXPECT_DIF_BADARG(
dif_clkmgr_measure_counts_get_enable(nullptr, kBadMeasClock, nullptr));
EXPECT_DIF_BADARG(
dif_clkmgr_measure_counts_get_enable(&clkmgr_, kBadMeasClock, nullptr));
EXPECT_DIF_BADARG(dif_clkmgr_measure_counts_get_enable(
nullptr, kDifClkmgrMeasureClockIoDiv2, nullptr));
EXPECT_DIF_BADARG(
dif_clkmgr_measure_counts_get_enable(nullptr, kBadMeasClock, &state));
EXPECT_DIF_BADARG(dif_clkmgr_measure_counts_get_enable(
&clkmgr_, kDifClkmgrMeasureClockIoDiv2, nullptr));
EXPECT_DIF_BADARG(dif_clkmgr_measure_counts_get_enable(
nullptr, kDifClkmgrMeasureClockIoDiv2, &state));
EXPECT_DIF_BADARG(
dif_clkmgr_measure_counts_get_enable(&clkmgr_, kBadMeasClock, &state));
}
TEST_F(MeasureCountTest, GetEnable) {
uint32_t en_offset;
for (int i = kDifClkmgrMeasureClockIo; i <= kDifClkmgrMeasureClockUsb; ++i) {
dif_clkmgr_measure_clock_t clk = (dif_clkmgr_measure_clock_t)i;
switch (clk) {
#define PICK_COUNT_CTRL_FIELDS(kind_) \
en_offset = CLKMGR_##kind_##_MEAS_CTRL_EN_REG_OFFSET; \
break // No semicolon to force semicolon below.
case kDifClkmgrMeasureClockIo:
PICK_COUNT_CTRL_FIELDS(IO);
case kDifClkmgrMeasureClockIoDiv2:
PICK_COUNT_CTRL_FIELDS(IO_DIV2);
case kDifClkmgrMeasureClockIoDiv4:
PICK_COUNT_CTRL_FIELDS(IO_DIV4);
case kDifClkmgrMeasureClockMain:
PICK_COUNT_CTRL_FIELDS(MAIN);
case kDifClkmgrMeasureClockUsb:
PICK_COUNT_CTRL_FIELDS(USB);
default:;
#undef PICK_COUNT_CTRL_FIELDS
}
EXPECT_READ32(en_offset, kDifToggleDisabled);
dif_toggle_t state = kDifToggleEnabled;
EXPECT_DIF_OK(dif_clkmgr_measure_counts_get_enable(&clkmgr_, clk, &state));
EXPECT_EQ(state, kDifToggleDisabled);
}
}
TEST_F(MeasureCountTest, GetThresholdsBadArgs) {
uint32_t hi;
uint32_t lo;
EXPECT_DIF_BADARG(dif_clkmgr_measure_counts_get_thresholds(
nullptr, kBadMeasClock, nullptr, nullptr));
EXPECT_DIF_BADARG(dif_clkmgr_measure_counts_get_thresholds(
&clkmgr_, kBadMeasClock, nullptr, nullptr));
EXPECT_DIF_BADARG(dif_clkmgr_measure_counts_get_thresholds(
nullptr, kDifClkmgrMeasureClockIoDiv2, nullptr, nullptr));
EXPECT_DIF_BADARG(dif_clkmgr_measure_counts_get_thresholds(
nullptr, kBadMeasClock, &lo, nullptr));
EXPECT_DIF_BADARG(dif_clkmgr_measure_counts_get_thresholds(
nullptr, kBadMeasClock, nullptr, &hi));
// Two bar args.
EXPECT_DIF_BADARG(dif_clkmgr_measure_counts_get_thresholds(
nullptr, kDifClkmgrMeasureClockIoDiv2, &lo, nullptr));
EXPECT_DIF_BADARG(dif_clkmgr_measure_counts_get_thresholds(
nullptr, kDifClkmgrMeasureClockIoDiv2, nullptr, &hi));
EXPECT_DIF_BADARG(dif_clkmgr_measure_counts_get_thresholds(
nullptr, kBadMeasClock, &lo, &hi));
EXPECT_DIF_BADARG(dif_clkmgr_measure_counts_get_thresholds(
&clkmgr_, kDifClkmgrMeasureClockIoDiv2, nullptr, nullptr));
EXPECT_DIF_BADARG(dif_clkmgr_measure_counts_get_thresholds(
&clkmgr_, kBadMeasClock, nullptr, &hi));
EXPECT_DIF_BADARG(dif_clkmgr_measure_counts_get_thresholds(
&clkmgr_, kBadMeasClock, &lo, nullptr));
// One bad args.
EXPECT_DIF_BADARG(dif_clkmgr_measure_counts_get_thresholds(
&clkmgr_, kDifClkmgrMeasureClockIoDiv2, &lo, nullptr));
EXPECT_DIF_BADARG(dif_clkmgr_measure_counts_get_thresholds(
&clkmgr_, kDifClkmgrMeasureClockIoDiv2, nullptr, &hi));
EXPECT_DIF_BADARG(dif_clkmgr_measure_counts_get_thresholds(
&clkmgr_, kBadMeasClock, &lo, &hi));
EXPECT_DIF_BADARG(dif_clkmgr_measure_counts_get_thresholds(
nullptr, kDifClkmgrMeasureClockIoDiv2, &lo, &hi));
}
TEST_F(MeasureCountTest, GetThresholds) {
uint32_t reg_offset;
bitfield_field32_t lo_field;
bitfield_field32_t hi_field;
for (int i = kDifClkmgrMeasureClockIo; i <= kDifClkmgrMeasureClockUsb; ++i) {
dif_clkmgr_measure_clock_t clk = (dif_clkmgr_measure_clock_t)i;
switch (clk) {
#define PICK_COUNT_CTRL_FIELDS(kind_) \
reg_offset = CLKMGR_##kind_##_MEAS_CTRL_SHADOWED_REG_OFFSET; \
lo_field = CLKMGR_##kind_##_MEAS_CTRL_SHADOWED_LO_FIELD; \
hi_field = CLKMGR_##kind_##_MEAS_CTRL_SHADOWED_HI_FIELD; \
break // No semicolon to force semicolon below.
case kDifClkmgrMeasureClockIo:
PICK_COUNT_CTRL_FIELDS(IO);
case kDifClkmgrMeasureClockIoDiv2:
PICK_COUNT_CTRL_FIELDS(IO_DIV2);
case kDifClkmgrMeasureClockIoDiv4:
PICK_COUNT_CTRL_FIELDS(IO_DIV4);
case kDifClkmgrMeasureClockMain:
PICK_COUNT_CTRL_FIELDS(MAIN);
case kDifClkmgrMeasureClockUsb:
PICK_COUNT_CTRL_FIELDS(USB);
default:;
#undef PICK_COUNT_CTRL_FIELDS
}
EXPECT_READ32(reg_offset, {{
.offset = lo_field.index,
.value = 8,
},
{
.offset = hi_field.index,
.value = 9,
}});
uint32_t min_threshold = 0;
uint32_t max_threshold = 0;
EXPECT_DIF_OK(dif_clkmgr_measure_counts_get_thresholds(
&clkmgr_, clk, &min_threshold, &max_threshold));
EXPECT_EQ(min_threshold, 8);
EXPECT_EQ(max_threshold, 9);
}
}
class RecovErrorTest : public ClkMgrTest {};
TEST_F(RecovErrorTest, GetBadArgs) {
dif_clkmgr_recov_err_codes_t codes;
EXPECT_DIF_BADARG(dif_clkmgr_recov_err_code_get_codes(nullptr, nullptr));
EXPECT_DIF_BADARG(dif_clkmgr_recov_err_code_get_codes(nullptr, &codes));
EXPECT_DIF_BADARG(dif_clkmgr_recov_err_code_get_codes(&clkmgr_, nullptr));
}
TEST_F(RecovErrorTest, GetCodes) {
dif_clkmgr_recov_err_codes_t codes;
EXPECT_READ32(CLKMGR_RECOV_ERR_CODE_REG_OFFSET, 6);
EXPECT_DIF_OK(dif_clkmgr_recov_err_code_get_codes(&clkmgr_, &codes));
EXPECT_EQ(codes, 6);
}
TEST_F(RecovErrorTest, ClearBadArgs) {
EXPECT_DIF_BADARG(dif_clkmgr_recov_err_code_clear_codes(nullptr, 4));
}
TEST_F(RecovErrorTest, ClearCodes) {
EXPECT_WRITE32(CLKMGR_RECOV_ERR_CODE_REG_OFFSET, 6);
EXPECT_DIF_OK(dif_clkmgr_recov_err_code_clear_codes(&clkmgr_, 6));
}
class FatalErrorTest : public ClkMgrTest {};
TEST_F(FatalErrorTest, GetBadArgs) {
dif_clkmgr_fatal_err_codes_t codes;
EXPECT_DIF_BADARG(dif_clkmgr_fatal_err_code_get_codes(nullptr, nullptr));
EXPECT_DIF_BADARG(dif_clkmgr_fatal_err_code_get_codes(nullptr, &codes));
EXPECT_DIF_BADARG(dif_clkmgr_fatal_err_code_get_codes(&clkmgr_, nullptr));
}
TEST_F(FatalErrorTest, GetCodes) {
dif_clkmgr_fatal_err_codes_t codes;
EXPECT_READ32(CLKMGR_FATAL_ERR_CODE_REG_OFFSET, 6);
EXPECT_DIF_OK(dif_clkmgr_fatal_err_code_get_codes(&clkmgr_, &codes));
EXPECT_EQ(codes, 6);
}
} // namespace
} // namespace dif_clkmgr_unittest