Software APIs
sensor_ctrl.c
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #include "sw/device/silicon_creator/lib/drivers/sensor_ctrl.h"
6 
10 #include "sw/device/silicon_creator/lib/drivers/otp.h"
11 
13 #include "otp_ctrl_regs.h"
14 #include "sensor_ctrl_regs.h"
15 
16 enum {
18  kSensorCtrlAlertConfig =
19  OTP_CTRL_PARAM_OWNER_SW_CFG_ROM_SENSOR_CTRL_ALERT_CFG_OFFSET,
20  kSensorCtrlAlertSize = SENSOR_CTRL_ALERT_EN_MULTIREG_COUNT,
21 };
22 
23 static_assert(kSensorCtrlAlertSize <=
24  OTP_CTRL_PARAM_OWNER_SW_CFG_ROM_SENSOR_CTRL_ALERT_CFG_SIZE,
25  "sensor_ctrl has more registers than OTP configuraiton bytes");
26 
27 rom_error_t sensor_ctrl_configure(lifecycle_state_t lc_state) {
28  switch (launder32(lc_state)) {
29  case kLcStateProd:
30  case kLcStateProdEnd:
31  case kLcStateDev:
32  // We don't need hardened checks for mission mode states because we intend
33  // to program the sensor control block.
34  //
35  // We have hardened checks on the test and rma states because those states
36  // skip programming.
37  SEC_MMIO_WRITE_INCREMENT(kSensorCtrlSecMmioConfigure);
38  break;
39  case kLcStateTest:
40  HARDENED_CHECK_EQ(lc_state, kLcStateTest);
41  return kErrorOk;
42  case kLcStateRma:
43  HARDENED_CHECK_EQ(lc_state, kLcStateRma);
44  return kErrorOk;
45  default:
46  HARDENED_TRAP();
47  }
48 
49  uint32_t val = 0;
50  uint32_t fatal = 0;
51  for (size_t i = 0; i < kSensorCtrlAlertSize; ++i) {
52  // The OTP configuration words should be thought of as a single byte field
53  // for each of the sensor_ctrl alert enables. In each byte, the lower
54  // nybble is a Mubi4 specifying whether to enable the alert and the upper
55  // nybble is a Mubi4 specifying whether the alert is recoverable.
56  val = otp_read32(kSensorCtrlAlertConfig + (i & ~3ul));
57  uint32_t shift = 8 * (i % sizeof(uint32_t));
59  kBase + SENSOR_CTRL_ALERT_EN_0_REG_OFFSET + i * sizeof(uint32_t),
61  val, ((bitfield_field32_t){.mask = 0xF, .index = shift})));
62 
63  shift += 4;
64  // The upper nybble will be Mubi4True (0x6) if the alert is recoverable and
65  // Mubi4False (0x9) if fatal. We XOR the lower three bits of the nybble
66  // into the fatal-enable bit position for this alert.
67  // When recoverable, the value will be zero (0 ^ 1 ^ 1).
68  // When fatal, the value will be one: (1 ^ 0 ^ 0).
69  fatal ^= (uint32_t)bitfield_bit32_read(val, shift++) << i;
70  fatal ^= (uint32_t)bitfield_bit32_read(val, shift++) << i;
71  fatal ^= (uint32_t)bitfield_bit32_read(val, shift++) << i;
72  }
73  sec_mmio_write32(kBase + SENSOR_CTRL_FATAL_ALERT_EN_REG_OFFSET, fatal);
74  return kErrorOk;
75 }