Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 24 additions & 12 deletions hw/opentitan/ot_otp_engine.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,12 @@
#define OT_OTP_HW_CLOCK QEMU_CLOCK_VIRTUAL_RT

/* the following delays are arbitrary for now */
#define DAI_DIGEST_DELAY_NS 50000u /* 50us */
#define LCI_PROG_SCHED_NS 1000u /* 1us*/
#define DAI_DIGEST_DELAY_NS 50000 /* 50us */
#define LCI_PROG_SCHED_NS 1000 /* 1us */

/* Use a timer with a small delay instead of a BH for reliability */
#define DIGEST_DECOUPLE_DELAY_NS 100 /* 100 ns */
#define ENTROPY_RESCHEDULE_DELAY_NS 100 /* 100 ns */

/* The size of keys used for OTP scrambling */
#define OTP_SCRAMBLING_KEY_WIDTH 128u
Expand Down Expand Up @@ -203,7 +207,7 @@ struct OtOTPScrmblKeyInit_ {
};

struct OtOTPKeyGen_ {
QEMUBH *entropy_bh;
QEMUTimer *request_entropy;
OtPresentState *present;
OtPrngState *prng;
OtFifo32 entropy_buf;
Expand Down Expand Up @@ -1622,7 +1626,8 @@ static void ot_otp_engine_dai_complete(void *opaque)
break;
case OT_OTP_DAI_DIG_WAIT:
g_assert(s->dai->partition >= 0);
qemu_bh_schedule(s->dai->digest_bh);
int64_t now = qemu_clock_get_ns(OT_VIRTUAL_CLOCK);
timer_mod(s->dai->digest_write, now + DIGEST_DECOUPLE_DELAY_NS);
break;
case OT_OTP_DAI_ERROR:
break;
Expand All @@ -1644,7 +1649,7 @@ static const OtOTPHWCfg *ot_otp_engine_get_hw_cfg(const OtOTPIf *dev)
return (const OtOTPHWCfg *)s->hw_cfg;
}

static void ot_otp_engine_request_entropy_bh(void *opaque)
static void ot_otp_engine_request_entropy(void *opaque)
{
OtOTPEngineState *s = opaque;

Expand Down Expand Up @@ -1679,7 +1684,9 @@ ot_otp_engine_keygen_push_entropy(void *opaque, uint32_t bits, bool fips)
resched);

if (resched && !s->keygen->edn_sched) {
qemu_bh_schedule(s->keygen->entropy_bh);
int64_t now = qemu_clock_get_ns(OT_OTP_HW_CLOCK);
timer_mod(s->keygen->request_entropy,
now + ENTROPY_RESCHEDULE_DELAY_NS);
}
}

Expand Down Expand Up @@ -1813,7 +1820,9 @@ static void ot_otp_engine_generate_scrambling_key(

if (needed_entropy) {
/* some entropy bits have been used, refill the buffer */
qemu_bh_schedule(s->keygen->entropy_bh);
int64_t now = qemu_clock_get_ns(OT_OTP_HW_CLOCK);
timer_mod(s->keygen->request_entropy,
now + ENTROPY_RESCHEDULE_DELAY_NS);
}
}

Expand Down Expand Up @@ -2746,13 +2755,13 @@ static void ot_otp_engine_reset_enter(Object *obj, ResetType type)
c->parent_phases.enter(obj, type);
}

qemu_bh_cancel(s->dai->digest_bh);
qemu_bh_cancel(s->lc_broadcast.bh);
qemu_bh_cancel(s->pwr_otp_bh);

timer_del(s->dai->delay);
timer_del(s->dai->digest_write);
timer_del(s->lci->prog_delay);
qemu_bh_cancel(s->keygen->entropy_bh);
timer_del(s->keygen->request_entropy);
s->keygen->edn_sched = false;

memset(s->hw_cfg, 0, sizeof(*s->hw_cfg));
Expand Down Expand Up @@ -2811,7 +2820,8 @@ static void ot_otp_engine_reset_exit(Object *obj, ResetType type)
ot_edn_connect_endpoint(s->edn, s->edn_ep,
&ot_otp_engine_keygen_push_entropy, s);

qemu_bh_schedule(s->keygen->entropy_bh);
int64_t now = qemu_clock_get_ns(OT_OTP_HW_CLOCK);
timer_mod(s->keygen->request_entropy, now + ENTROPY_RESCHEDULE_DELAY_NS);
}

static void ot_otp_engine_realize(DeviceState *dev, Error **errp)
Expand Down Expand Up @@ -2900,12 +2910,14 @@ static void ot_otp_engine_init(Object *obj)

s->dai->delay =
timer_new_ns(OT_VIRTUAL_CLOCK, &ot_otp_engine_dai_complete, s);
s->dai->digest_bh = qemu_bh_new(&ot_otp_engine_dai_write_digest, s);
s->dai->digest_write =
timer_new_ns(OT_VIRTUAL_CLOCK, &ot_otp_engine_dai_write_digest, s);
s->lci->prog_delay =
timer_new_ns(OT_OTP_HW_CLOCK, &ot_otp_engine_lci_write_word, s);
s->keygen->request_entropy =
timer_new_ns(OT_OTP_HW_CLOCK, &ot_otp_engine_request_entropy, s);
s->pwr_otp_bh = qemu_bh_new(&ot_otp_engine_pwr_otp_bh, s);
s->lc_broadcast.bh = qemu_bh_new(&ot_otp_engine_lc_broadcast_bh, s);
s->keygen->entropy_bh = qemu_bh_new(&ot_otp_engine_request_entropy_bh, s);

for (unsigned part_ix = 0; part_ix < s->part_count; part_ix++) {
if (!s->part_descs[part_ix].buffered) {
Expand Down
2 changes: 1 addition & 1 deletion include/hw/opentitan/ot_otp_engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ typedef struct {

typedef struct OtOTPDAIController {
QEMUTimer *delay; /* simulate delayed access completion */
QEMUBH *digest_bh; /* write computed digest to OTP cell */
QEMUTimer *digest_write; /* write computed digest to OTP cell */
OtOTPDAIState state;
int partition; /* current partition being worked on or -1 */
} OtOTPDAIController;
Expand Down
Loading