-
Notifications
You must be signed in to change notification settings - Fork 13
ot_otp: unify implementations
#272
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: ot-9.2.0
Are you sure you want to change the base?
Conversation
32de450 to
a5cad1d
Compare
e6edb49 to
4eb19dc
Compare
| (void)OBJECT_CHECK(OtOTPIf, s->otp_ctrl, TYPE_OT_OTP_IF); | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this check required? Doesn't DEFINE_PROP_LINK already add a type check?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Interfaces" property are assigned to generic device, the top-most level kind, DeviceState *. QEMU checks on property assignment that the object is a DeviceState, but not the interfaces the device supports. This is very specific to interfaces
| void (*update_status_error)(OtOTPImplIf *dev, OtOTPStatus error, bool set); | ||
|
|
||
| /* | ||
| * Signal the power management as triggered the OTP initialization sequence. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Signal that power management has triggered"
hw/opentitan/ot_otp_dj.c
Outdated
|
|
||
| // @otod add _ADDR or _OFFSET |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo (@todo)
hw/opentitan/ot_otp_engine.c
Outdated
| * "Note that if errors occur, we aggregate the error code but still | ||
| * attempt to program all remaining words. This is done to ensure that | ||
| * a life cycle state with ECC correctable errors in some words can | ||
| * still be scrapped." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing a space before still
hw/opentitan/ot_otp_engine.c
Outdated
| * IP reset, which are exercised automatically from the SoC, since all the | ||
| * OT SysBysDevice IPs are connected to the private system bus of the Ibex. | ||
| * This is by-design in QEMU. The reset management is already far too | ||
| * complex to create a special case for the OTP. Kind in mind that the OTP |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kind in mind -> Keep in mind
hw/opentitan/ot_otp_engine.c
Outdated
| ERR_CODE_NAMES[(_err_)] : \ | ||
| "?") | ||
|
|
||
| /* todo: add assertion to validate those */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@todo
hw/opentitan/ot_otp_engine.c
Outdated
| if (level) { | ||
| DAI_CHANGE_STATE(s, OTP_DAI_ERROR); | ||
| LCI_CHANGE_STATE(s, OTP_LCI_ERROR); | ||
| /* TODO: manage other FSMs */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@todo
hw/opentitan/ot_otp_engine.c
Outdated
| pctrl->failed = true; | ||
| /* this is a fatal error */ | ||
| ot_otp_engine_set_error(s, part_ix, OTP_CHECK_FAIL_ERROR); | ||
| /* TODO: revert buffered part to default */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@todo
hw/opentitan/ot_otp_engine.c
Outdated
| ibex_irq_set(&s->pwc_otp_rsp, 0); | ||
|
|
||
| for (unsigned part_ix = 0; part_ix < s->part_count; part_ix++) { | ||
| /* TODO: initialize with actual default partition data once known */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@todo
8494dad to
56b1a5e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Partial review (reviewed up to the "merge OTP implementation" commit, and I only looked at the ot_otp_engine.h and ot_otp_{dj,eg}_parts.c files in that commit so far).
hw/opentitan/ot_otp_dj.c
Outdated
| secret_addr = (unsigned)A_SECRET0_TEST_EXIT_TOKEN; | ||
| break; | ||
| case OTP_TOKEN_RMA: | ||
| partition = OTP_PART_SECRET2; | ||
| secret_addr = A_SECRET2_RMA_TOKEN; | ||
| secret_addr = (unsigned)A_SECRET2_RMA_TOKEN; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Casts should be on the partition, not the secret_addr.
hw/opentitan/ot_entropy_src.c
Outdated
| @@ -1,5 +1,5 @@ | |||
| /* | |||
| * QEMU OpenTitan Earlgrey 1.0.0 Entropy Source device | |||
| * QEMU OpenTitan Earlgrey Entropy Source device | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't even be "Earlgrey" anymore now these are unified, right?
The header file is correct ("QEMU OpenTitan Entropy Source device").
hw/opentitan/ot_otp_dj.c
Outdated
| } | ||
|
|
||
| static inline unsigned ot_otp_dj_part_data_offset(const OtOTPDjState *s, unsigned part_ix) | ||
| static inline unsigned |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small nit: it's not very important (especially if it ends up being a lot of conflicts to fix), but really this formatter run should be on the earlier commit preparing the OTP for unification, not on the commit adding the interface. It makes it harder to follow the history by blaming (and harder to review!)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have reformatted all the commits on this branch. Is that ok?
python/qemu/ot/otp/descriptor.py
Outdated
| print('#define OTP_PART_COUNT ARRAY_SIZE(OtOTPPartDescs)', file=cfp) | ||
| print('#define OTP_PART_COUNT ARRAY_SIZE(OT_OTP_PART_DESCS)', file=cfp) | ||
| print(file=cfp) | ||
| key_seeds: list[str, str, int, int] = [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typing nit - should be:
| key_seeds: list[str, str, int, int] = [] | |
| key_seeds: list[tuple[str, str, int, int]] = [] |
?
hw/opentitan/ot_otp_dj.c
Outdated
|
|
||
| // @todo add _ADDR or _OFFSET |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: QEMU comment style
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added this special comment not to forget to do it before pushing the PR. It seems it did not work as expected :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even if it doesn't stop you pushing it, it gets pointed out in review at least :)
include/hw/opentitan/ot_otp_engine.h
Outdated
| @@ -0,0 +1,423 @@ | |||
| /* | |||
| * QEMU OpenTitan EarlGrey One Time Programmable (OTP) memory controller | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| * QEMU OpenTitan EarlGrey One Time Programmable (OTP) memory controller | |
| * QEMU OpenTitan One Time Programmable (OTP) memory controller |
|
|
||
| if (s->part_descs[part_ix].hw_digest || s->part_descs[part_ix].sw_digest) { | ||
| size -= sizeof(uint32_t) * NUM_DIGEST_WORDS; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should also account for zeroizable words in zeroizable partitions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch.
I originally selected the DJ model to do the port, then I moved to EG as DJ does not have flash ... and I forgot about the zeroification altogether.
hw/opentitan/ot_otp_engine.h
Outdated
| FIELD(DIRECT_ACCESS_CMD, RD, 0u, 1u) | ||
| FIELD(DIRECT_ACCESS_CMD, WR, 1u, 1u) | ||
| FIELD(DIRECT_ACCESS_CMD, DIGEST, 2u, 1u) | ||
| FIELD(DIRECT_ACCESS_CMD, ZEROIZE, 3u, 1u) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: the ZEROIZE field is not "common" in the Earlgrey 1.0.0 version (have not looked where this is used yet, maybe it does not end up being a problem).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've updated the command, and added a flag in OtOTPImplIfClass that tracks support for this feature.
Note that this feature is not yet implemented (I mean in Darjeeling), only what's needed to use the partitions when such feature is defined. I've added a @todo.
hw/opentitan/ot_otp_dj_parts.c
Outdated
| #define OTP_PART_COUNT ARRAY_SIZE(OT_OTP_PART_DESCS) | ||
|
|
||
| static const OtOTPKeySeed OT_OTP_KEY_SEEDS[OTP_KEY_COUNT] = { | ||
| [OTP_KEY_OTBN] = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(same for EG) Maybe put a comment here similar to the previous comment explaining the overlap with the SRAM key:
/* The OTBN scrambling key is derived from the SRAM scrambling key */
(could even mention a reference to OpenTitan's rtl/otp_ctrl_kdi.sv?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is commented where those values are used. Is it required to add this here as well (more to fix if it evolves, as it needs to be in Python and in C)?
(@ line 1822, in ot_otp_engine_get_otp_key function)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's probably ok, this is just the type of code that I would find when debugging and think "surely this must be a copy/paste error, why are the SRAM and OTBN key set to the same offset/size?" and then only find out after an hour of reading through the RTL that they are intentionally the same. I went through a similar experience to this going through the original RTL to implement these scrambling keys...
But the other comment is probably sufficient (I just hadn't got to reviewing that file yet - the downsides of doing partial reviews).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leaving it open for now, if you think it is better to have it in Python, I'll add it.
b588e1b to
5e0c13a
Compare
Disable all LLVM rules as they hard-code paths from LLVM project. llvm-header-guard therefore suggests to replace header guard path with the full absolute path of the current local check out directory path! It appears that llvm-* rules are only to be used for the LLVM project itself, but they are nevertheless automatically added with the default `*` wildcard... Signed-off-by: Emmanuel Blot <eblot@rivosinc.com>
…erator Signed-off-by: Emmanuel Blot <eblot@rivosinc.com>
- move partition names to the OtOTPPartDesc array - allocate arrays of string properties and their matching byte values at runtime, - rename partition-related variables, as several new variables are added - replace statically defined constants with dynamic variables - clean up Signed-off-by: Emmanuel Blot <eblot@rivosinc.com>
- move partition names to the OtOTPPartDesc array - allocate arrays of string properties and their matching byte values at runtime, - rename partition-related variables, as several new variables are added - replace statically defined constants with dynamic variables - clean up Signed-off-by: Emmanuel Blot <eblot@rivosinc.com>
…erface. This is the second step towards unification of OtOTP* implementations. It is better to expose the OtOTPState feature as an interface, so that OtOTPState can later implement the common feature for all OtOTP Top-specialized implementation. Signed-off-by: Emmanuel Blot <eblot@rivosinc.com>
…TP devices Signed-off-by: Emmanuel Blot <eblot@rivosinc.com>
… file Signed-off-by: Emmanuel Blot <eblot@rivosinc.com>
… Darjeeling - merge and adapt common code into OtOTPEngine - keep only OTP top-specific implementation in ot_otp_eg.c and ot_otp_dj.c, which implement the OtOTPImplIf interface (specialization for Tops) - regenerate OTP partition descriptions and key seed definition with otptool.py Signed-off-by: Emmanuel Blot <eblot@rivosinc.com>
- use Top defined constants - simplify stack of macro calls - remove definitions from ot_otp_engine.h Signed-off-by: Emmanuel Blot <eblot@rivosinc.com>
…ctory This is needed to implement other OTP top-specific implementations. Signed-off-by: Emmanuel Blot <eblot@rivosinc.com>
…rties - secret_scrambling_keys: the exact number of such properties is created. this avoid allocated useless memory, and ensure QEMU property subsystem may report any attempt to define values for keys that do not exist - secret_scrambling_key and inv_default_data values are now tied to the partition controller, rather than to be allocated as separate arrays Signed-off-by: Emmanuel Blot <eblot@rivosinc.com>
Should start with OT_OTP, OtOtp, ot_otp to prevent from unexpected conflicts Signed-off-by: Emmanuel Blot <eblot@rivosinc.com>
5e0c13a to
fbe0c39
Compare
fbe0c39 to
1aadd5c
Compare
…d data Signed-off-by: Emmanuel Blot <eblot@rivosinc.com>
1aadd5c to
d7b4ee4
Compare
This PR generalizes OTP implementation, so that code is no longer duplicated for each top.
Most of the code is now implemented in a new component
OtOTPEngineState(ot_otp_engine.c) which contains over 4/5 of the duplicated code that used to exist inot_otp_eg.candot_otp_dj.cfiles.Those two latter files now only contain what is specific to each Top:
Some note about the interfaces/classes:
OtOTPIf(Class)interface exposes the public interface of the OTP, i.e. the API that other OpenTitan "HW" devices can use to communicate with the OTPOtOTPImplIf(Class)interface exposes the semi- private interface that a top-specific OTP implementation exposes to theOtOTPEngineStateOtOtpBeIf(Class)interface exposes the public interface of an OTP backend, which describes the characteristics of a specific backend. Note that ideally, this component should manage the QEMU OTP image file, which is not (yet) the case.OtOTPEngineState/Classimplements the whole OTP emulation. It is an abstract class whose concrete implementation is Top-specific.OtOTPEgState/ClassandOtOTPDjState/Classare two concrete implementations ofOtOTPEngineState/Class. Each implements the implements theOtOTPIfinterface which is exposed to the OTP clients, and implement theOtOTPImplIfto provide the features required by their abstract classOtOTPEngineState/Class.