Software APIs
retention_sram.h
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#ifndef OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_DRIVERS_RETENTION_SRAM_H_
6#define OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_DRIVERS_RETENTION_SRAM_H_
7
8#include <stdint.h>
9
10#include "dt/dt_sram_ctrl.h"
12#include "sw/device/silicon_creator/lib/boot_log.h"
13#include "sw/device/silicon_creator/lib/boot_svc/boot_svc_msg.h"
14#include "sw/device/silicon_creator/lib/error.h"
15
16#ifdef __cplusplus
17extern "C" {
18#endif
19
20/**
21 * Retention SRAM silicon creator area.
22 */
23typedef struct retention_sram_creator {
24 /**
25 * Reset reasons reported by the reset manager before they were reset in mask
26 * ROM.
27 */
28 uint32_t reset_reasons;
29 /**
30 * Boot services message area.
31 *
32 * This is the shared buffer through which ROM_EXT and silicon owner code
33 * communicate with each other.
34 */
35 boot_svc_msg_t boot_svc_msg;
36
37 /**
38 * Space reserved for future allocation by the silicon creator.
39 *
40 * The first half of the retention SRAM is reserved for the silicon creator
41 * except for the first word that stores the format version. Hence the total
42 * size of this struct must be 2044 bytes.
43 *
44 * The remaining space is reserved for future use.
45 *
46 * We are locating the boot_svc at the beginning and the rest of the members
47 * at the end so that:
48 * - We can grow boot_svc down into the reserved space if needed.
49 * - We can add additional members at the end (growing up into reserved
50 * space) without affecting the layout of other structures.
51 */
52 uint32_t reserved[(2044 - (sizeof(uint32_t) // reset_reason
53 + sizeof(boot_svc_msg_t) // boot services message
54 + sizeof(boot_log_t) // boot_log
55 + sizeof(rom_error_t) // last_shutdown_reason
56 )) /
57 sizeof(uint32_t)];
58 /**
59 * Boot log area.
60 *
61 * This buffer tracks information about the boot process.
62 */
63 boot_log_t boot_log;
64 /**
65 * Shutdown reason.
66 *
67 * Reason of the last shutdown, redacted according to the redaction policy.
68 * This field is initialized to `kErrorOk` on PoR and a value of `kErrorOk`
69 * indicates that no shutdowns since the last PoR.
70 */
72} retention_sram_creator_t;
73OT_ASSERT_MEMBER_OFFSET(retention_sram_creator_t, reset_reasons, 0);
74OT_ASSERT_MEMBER_OFFSET(retention_sram_creator_t, boot_svc_msg, 4);
75OT_ASSERT_MEMBER_OFFSET(retention_sram_creator_t, reserved, 260);
76OT_ASSERT_MEMBER_OFFSET(retention_sram_creator_t, boot_log, 1912);
77OT_ASSERT_MEMBER_OFFSET(retention_sram_creator_t, last_shutdown_reason, 2040);
78OT_ASSERT_SIZE(boot_svc_msg_t, 256);
79OT_ASSERT_SIZE(retention_sram_creator_t, 2044);
80
81/**
82 * Retention SRAM silicon owner area.
83 */
84typedef struct retention_sram_owner {
85 /**
86 * Space reserved for allocation by the silicon owner.
87 *
88 * The silcon creator boot stages will not modify this field except for
89 * clearing it at initial power on.
90 *
91 * Tests that need to trigger (or detect) a device reset may use this field to
92 * preserve state information across resets.
93 */
94 uint32_t reserved[2048 / sizeof(uint32_t)];
95} retention_sram_owner_t;
96OT_ASSERT_SIZE(retention_sram_owner_t, 2048);
97
98/**
99 * The retention SRAM is memory that is used to retain information, such as a
100 * boot service request, across a device reset. If the reset reason is 'power
101 * on' (POR) all fields will be initialized using the LFSR by the ROM.
102 */
103typedef struct retention_sram {
104 /**
105 * Retention SRAM format version.
106 *
107 * ROM sets this field to `kRetentionSramVersion2` only after PoR and
108 * does not modify it otherwise. ROM_EXT can use this information for backward
109 * compatibility and set this field to a different value after migrating to a
110 * different layout if needed.
111 */
112 uint32_t version;
113 /**
114 * Silicon creator area.
115 */
116 retention_sram_creator_t creator;
117 /**
118 * Silicon owner area.
119 */
120 retention_sram_owner_t owner;
121} retention_sram_t;
122
123OT_ASSERT_MEMBER_OFFSET(retention_sram_t, creator, 4);
124OT_ASSERT_MEMBER_OFFSET(retention_sram_t, owner, 2048);
125OT_ASSERT_SIZE(retention_sram_t, 4096);
126
127enum {
128 /**
129 * Engineering sample version.
130 */
131 kRetentionSramVersion1 = 0x72f4eb2e,
132 /**
133 * Includes the `boot_svc_msg`, `boot_log`, and `last_shutdown_reason` fields
134 * in the silicon creator area.
135 */
136 kRetentionSramVersion2 = 0x5b89bd6d,
137 /**
138 * Version 3 is a more stable and expandable layout than prior version.
139 * and the a recognizable ASCII tag of `RR03`.
140 */
141 kRetentionSramVersion3 = 0x33305252,
142 /**
143 * Version 4 is the same layout as 3, but all identifiers and commands have
144 * been changed to use "FourCC" style values. Version 4 is identified by
145 * the ASCII tag `RR04`.
146 */
147 kRetentionSramVersion4 = 0x34305252,
148};
149
150/**
151 * Returns a typed pointer to the retention SRAM.
152 *
153 * @return A pointer to the retention SRAM.
154 */
156inline retention_sram_t *retention_sram_get(void) {
157 // NOTE: this assumes that the retention SRAM is always using the name
158 // "ret_aon"
159 return (retention_sram_t *)dt_sram_ctrl_reg_block(kDtSramCtrlRetAon,
160 kDtSramCtrlRegBlockRam);
161}
162
163/**
164 * Clear the retention SRAM by setting every word to 0.
165 */
166void retention_sram_clear(void);
167
168/**
169 * Initialize the retention SRAM with pseudo-random data from the LFSR.
170 *
171 * This function does not request a new scrambling key. See
172 * `retention_sram_scramble()`.
173 *
174 * @return Result of the operation.
175 */
176void retention_sram_init(void);
177
178/**
179 * Enable or disable the readback feature of the retention SRAM.
180 *
181 * @param en A Mubi4True to enable the feature.
182 */
183void retention_sram_readback_enable(uint32_t en);
184
185/**
186 * Start scrambling the retention SRAM.
187 *
188 * Requests a new scrambling key for the retention SRAM. This operation
189 * will wipe all of the data in the retention SRAM. The retention SRAM
190 * will then be initialized to undefined values.
191 *
192 * The scrambling operation takes time and accesses to retention SRAM
193 * will stall until it completes.
194 *
195 * @return An error if a new key cannot be requested.
196 */
197void retention_sram_scramble(void);
198
199/**
200 * Check that the retention SRAM is a known version.
201 *
202 * @return An error if the retention SRAM version is unknown.
203 */
204rom_error_t retention_sram_check_version(void);
205
206#ifdef __cplusplus
207}
208#endif
209
210#endif // OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_DRIVERS_RETENTION_SRAM_H_