blob: 8536e1eed6db7c8dd82d2905b590859d93c47418 [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/silicon_creator/lib/drivers/lifecycle.h"
#include <assert.h>
#include <stdint.h>
#include "sw/device/lib/base/bitfield.h"
#include "sw/device/lib/base/hardened.h"
#include "sw/device/lib/base/macros.h"
#include "sw/device/silicon_creator/lib/base/sec_mmio.h"
#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
#include "lc_ctrl_regs.h"
enum {
kBase = TOP_EARLGREY_LC_CTRL_BASE_ADDR,
};
lifecycle_state_t lifecycle_state_get(void) {
uint32_t raw_state = lifecycle_raw_state_get();
switch (launder32(raw_state)) {
case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED0:
HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED0);
return kLcStateTest;
case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED1:
HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED1);
return kLcStateTest;
case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED2:
HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED2);
return kLcStateTest;
case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED3:
HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED3);
return kLcStateTest;
case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED4:
HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED4);
return kLcStateTest;
case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED5:
HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED5);
return kLcStateTest;
case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED6:
HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED6);
return kLcStateTest;
case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED7:
HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED7);
return kLcStateTest;
case LC_CTRL_LC_STATE_STATE_VALUE_DEV:
HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_DEV);
return kLcStateDev;
case LC_CTRL_LC_STATE_STATE_VALUE_PROD:
HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_PROD);
return kLcStateProd;
case LC_CTRL_LC_STATE_STATE_VALUE_PROD_END:
HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_PROD_END);
return kLcStateProdEnd;
case LC_CTRL_LC_STATE_STATE_VALUE_RMA:
HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_RMA);
return kLcStateRma;
default:
HARDENED_UNREACHABLE();
}
}
uint32_t lifecycle_raw_state_get(void) {
uint32_t value = bitfield_field32_read(
sec_mmio_read32(kBase + LC_CTRL_LC_STATE_REG_OFFSET),
LC_CTRL_LC_STATE_STATE_FIELD);
return value;
}
void lifecycle_device_id_get(lifecycle_device_id_t *device_id) {
static_assert(
kLifecycleDeviceIdNumWords == LC_CTRL_PARAM_NUM_DEVICE_ID_WORDS,
"length of the device_id array does not match the length in hardware");
for (size_t i = 0; i < kLifecycleDeviceIdNumWords; ++i) {
device_id->device_id[i] = sec_mmio_read32(
kBase + LC_CTRL_DEVICE_ID_0_REG_OFFSET + i * sizeof(uint32_t));
}
}
void lifecycle_hw_rev_get(lifecycle_hw_rev_t *hw_rev) {
uint32_t reg = sec_mmio_read32(kBase + LC_CTRL_HW_REV_REG_OFFSET);
*hw_rev = (lifecycle_hw_rev_t){
.chip_gen = bitfield_field32_read(reg, LC_CTRL_HW_REV_CHIP_GEN_FIELD),
.chip_rev = bitfield_field32_read(reg, LC_CTRL_HW_REV_CHIP_REV_FIELD),
};
}