From: Sascha Hauer <s.hauer@pengutronix.de>
To: Barebox List <barebox@lists.infradead.org>
Subject: [PATCH] k3: add keywriter lite support
Date: Mon, 10 Nov 2025 14:39:20 +0100 [thread overview]
Message-ID: <20251110133920.3900948-1-s.hauer@pengutronix.de> (raw)
This adds a command for turning a AM62L SoC from HS-FS (High Security -
Field Securable) to HS-SE (High Security - Security Enforced) mode.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
commands/Kconfig | 8 +
commands/Makefile | 1 +
commands/k3-keywriter.c | 172 +++++++++++++++++++
common/Kconfig | 6 +
common/Makefile | 1 +
common/k3-keywriter-lite.c | 293 ++++++++++++++++++++++++++++++++
include/soc/k3/keywriter-lite.h | 177 +++++++++++++++++++
7 files changed, 658 insertions(+)
create mode 100644 commands/k3-keywriter.c
create mode 100644 common/k3-keywriter-lite.c
create mode 100644 include/soc/k3/keywriter-lite.h
diff --git a/commands/Kconfig b/commands/Kconfig
index 78b1e69dd3..4188405e3b 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -2307,6 +2307,14 @@ config CMD_HAB
depends on HAB
prompt "High Assurance boot (hab)"
+config CMD_K3_KEYWRITER
+ bool
+ depends on MACH_AM62LX
+ select K3_KEYWRITER_LITE
+ prompt "K3 keywriter support"
+ help
+ The K3 keywriter command provides support for fusing TI AM62Lx SoCs
+
# end Hardware manipulation commands
endmenu
diff --git a/commands/Makefile b/commands/Makefile
index 858e0c257e..85ba357708 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -110,6 +110,7 @@ obj-$(CONFIG_CMD_DMESG) += dmesg.o
obj-$(CONFIG_CMD_BLOBGEN) += blobgen.o
obj-$(CONFIG_CMD_BASENAME) += basename.o
obj-$(CONFIG_CMD_HAB) += hab.o
+obj-$(CONFIG_CMD_K3_KEYWRITER) += k3-keywriter.o
obj-$(CONFIG_CMD_DIRNAME) += dirname.o
obj-$(CONFIG_CMD_READLINK) += readlink.o
obj-$(CONFIG_CMD_LET) += let.o
diff --git a/commands/k3-keywriter.c b/commands/k3-keywriter.c
new file mode 100644
index 0000000000..5243d8a11e
--- /dev/null
+++ b/commands/k3-keywriter.c
@@ -0,0 +1,172 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <stdio.h>
+#include <malloc.h>
+#include <command.h>
+#include <getopt.h>
+#include <libfile.h>
+#include <linux/kstrtox.h>
+#include <soc/k3/keywriter-lite.h>
+
+static void *read_sha512(const char *filename)
+{
+ size_t size;
+ int ret;
+ void *hash;
+
+ ret = read_file_2(filename, &size, &hash, SHA512_DIGEST_SIZE + 1);
+ if (ret) {
+ printf("Cannot read %s: %pe\n", filename, ERR_PTR(ret));
+ return NULL;
+ }
+
+ if (size != SHA512_DIGEST_SIZE) {
+ printf("unexpected file size in hash file. Should be %u\n",
+ SHA512_DIGEST_SIZE);
+ free(hash);
+ return NULL;
+ }
+
+ return hash;
+}
+
+static int do_k3_keywriter(int argc, char *argv[])
+{
+ struct keywriter_lite_packet p;
+ struct keywriter_lite_blob *blob;
+ int opt, ret;
+ const char *smpkh_file = NULL;
+ const char *bmpkh_file = NULL;
+ const char *outfile = NULL;
+ int key_count = -1;
+ int key_rev = -1;
+ bool doit = false;
+
+ blob = &p.blob;
+
+ while ((opt = getopt(argc, argv, "s:b:o:c:r:x")) > 0) {
+ switch (opt) {
+ case 's':
+ smpkh_file = optarg;
+ break;
+ case 'b':
+ bmpkh_file = optarg;
+ break;
+ case 'o':
+ outfile = optarg;
+ break;
+ case 'c':
+ ret = kstrtouint(optarg, 0, &key_count);
+ if (ret)
+ goto err;
+ break;
+ case 'r':
+ ret = kstrtouint(optarg, 0, &key_rev);
+ if (ret)
+ goto err;
+ break;
+ case 'x':
+ doit = true;
+ break;
+ }
+ }
+
+ k3_kwl_prepare(&p);
+
+ if (smpkh_file) {
+ unsigned char *hash = read_sha512(smpkh_file);
+
+ if (!hash) {
+ ret = COMMAND_ERROR;
+ goto err;
+ }
+
+ k3_kwl_set_smpkh(&blob->payload.smpkh, hash, FLAG_ACTIVE);
+ free(hash);
+ }
+
+ if (bmpkh_file) {
+ unsigned char *hash = read_sha512(bmpkh_file);
+
+ if (!hash) {
+ ret = COMMAND_ERROR;
+ goto err;
+ }
+
+ k3_kwl_set_bmpkh(&blob->payload.bmpkh, hash, FLAG_ACTIVE);
+ free(hash);
+ }
+
+ if (key_count >= 0) {
+ ret = k3_kwl_set_keycnt(&blob->payload.key_count, key_count,
+ FLAG_ACTIVE);
+ if (ret)
+ goto err;
+ }
+
+ if (key_rev >= 0) {
+ ret = k3_kwl_set_key_revision(&blob->payload.key_revision, key_rev,
+ FLAG_ACTIVE);
+ if (ret)
+ goto err;
+ }
+
+ ret = k3_kwl_finalize(&p);
+ if (ret) {
+ ret = COMMAND_ERROR;
+ printf("Cannot finalize keywriter lite structure: %pe\n", ERR_PTR(ret));
+ goto err;
+ }
+
+ if (outfile) {
+ ret = write_file(outfile, &p, sizeof(p));
+ if (ret) {
+ ret = COMMAND_ERROR;
+ printf("Failed to write %s: %pe\n", outfile, ERR_PTR(ret));
+ goto err;
+ }
+ }
+
+ if (!smpkh_file && !bmpkh_file && key_count < 0 && key_rev < 0) {
+ printf("Nothing to do\n");
+ ret = COMMAND_ERROR_USAGE;
+ }
+
+ if (doit) {
+ printf("Writing fuses...\n");
+ ret = k3_kwl_fuse_writebuff(&p);
+ if (ret) {
+ printf("Failed to write fuses: %pe\n", ERR_PTR(ret));
+ goto err;
+ } else {
+ printf("Fuses written successfully\n");
+ }
+ } else {
+ printf("Not writing fuses as requested. "
+ "Pass -x to actually write fuses\n");
+ ret = 0;
+ }
+
+err:
+ return ret;
+}
+
+BAREBOX_CMD_HELP_START(k3_keywriter)
+BAREBOX_CMD_HELP_TEXT("K3 keywriter support")
+BAREBOX_CMD_HELP_TEXT("")
+BAREBOX_CMD_HELP_TEXT("Options:")
+BAREBOX_CMD_HELP_OPT ("-s <FILE>", "Read SMPK hash from <FILE>")
+BAREBOX_CMD_HELP_OPT ("-b <FILE>", "Read BMPK hash from <FILE>")
+BAREBOX_CMD_HELP_OPT ("-o <FILE>", "write data structure for ROM to <FILE> (for debug)")
+BAREBOX_CMD_HELP_OPT ("-c <NKEYS>","set key count to <NKEYS>")
+BAREBOX_CMD_HELP_OPT ("-r <REV>", "set key revision to <REV>")
+BAREBOX_CMD_HELP_OPT ("-x", "Do it! actually write fuses")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(k3_keywriter)
+ .cmd = do_k3_keywriter,
+ BAREBOX_CMD_DESC("K3 keywriter support")
+ BAREBOX_CMD_OPTS("-sbocrx")
+ BAREBOX_CMD_GROUP(CMD_GRP_HWMANIP)
+ BAREBOX_CMD_HELP(cmd_k3_keywriter_help)
+BAREBOX_CMD_END
diff --git a/common/Kconfig b/common/Kconfig
index d923d4c4b6..59fafb462a 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -1327,3 +1327,9 @@ source "common/Kconfig.debug"
config DDR_SPD
bool
select CRC_ITU_T
+
+config K3_KEYWRITER_LITE
+ bool
+ select DIGEST
+ select DIGEST_SHA512_GENERIC
+ depends on MACH_AM62LX
diff --git a/common/Makefile b/common/Makefile
index d501a6a275..8769d04d04 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -85,6 +85,7 @@ obj-$(CONFIG_SERIAL_DEV_BUS) += serdev.o
obj-$(CONFIG_USB_GADGET) += usbgadget.o
obj-$(CONFIG_FASTBOOT_BASE) += fastboot.o
obj-$(CONFIG_CDEV_ALIAS) += cdev-alias.o
+obj-$(CONFIG_K3_KEYWRITER_LITE) += k3-keywriter-lite.o
# dependencies on generated files need to be listed explicitly
$(obj)/version.o: include/generated/compile.h
diff --git a/common/k3-keywriter-lite.c b/common/k3-keywriter-lite.c
new file mode 100644
index 0000000000..0919372c1b
--- /dev/null
+++ b/common/k3-keywriter-lite.c
@@ -0,0 +1,293 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#define pr_fmt(fmt) "k3-keywriter: " fmt
+
+#include <digest.h>
+#include <string.h>
+#include <stdio.h>
+#include <dma.h>
+#include <memory.h>
+#include <linux/arm-smccc.h>
+#include <linux/bits.h>
+#include <linux/bitfield.h>
+#include <crypto/sha.h>
+#include <soc/k3/keywriter-lite.h>
+
+/* from https://software-dl.ti.com/tisci/esd/latest/6_topic_user_guides/key_writer_lite.html */
+
+#define PROGRAMMING_MODE_ONESHOT 0 /* all supported fields at once */
+#define PROGRAMMING_MODE_MULTISHOT 1 /* a subset of supported fields at once */
+#define PROGRAMMING_MODE_SMPKH 2 /* ust SMPKH */
+#define PROGRAMMING_MODE_BMPKH 3 /* just BMPKH */
+#define PROGRAMMING_MODE_KEY_COUNT 4 /* just key count */
+#define PROGRAMMING_MODE_KEY_REVISION 5 /* just key revision */
+#define PROGRAMMING_MODE_SBL_SWREV 6 /* just SBL swrev */
+#define PROGRAMMING_MODE_SYSFW_SWREV 7 /* just SYSFW swrev */
+#define PROGRAMMING_MODE_BRDCFG_SWREV 8 /* just BRDCFG swrev */
+#define PROGRAMMING_MODE_MSV 9 /* just MSV */
+#define PROGRAMMING_MODE_JTAG 10 /* just JTAG unlock disable */
+#define PROGRAMMING_MODE_BOOT_MODE 11 /* just efuse boot modes */
+#define PROGRAMMING_MODE_EXTENDED_OTP 12 /* just extended otp */
+
+/*
+ * action_flags
+ * see gen_keywr_cert_helpers.sh:
+ * 16#${wp_flag}${rp_flag}${ovrd_flag}${active_flag}
+ */
+#define ACTION_FLAG_ENABLE 0x5a
+#define ACTION_FLAG_DISABLE 0xa5
+
+#define ACTION_FLAG_WP GENMASK(31, 24)
+#define ACTION_FLAG_RP GENMASK(23, 16)
+#define ACTION_FLAG_OVRD GENMASK(15, 8)
+#define ACTION_FLAG_ACTIVE GENMASK(7, 0)
+
+static unsigned int k3_kwl_set_flags(unsigned int f)
+{
+ unsigned int en = ACTION_FLAG_ENABLE;
+ unsigned int dis = ACTION_FLAG_DISABLE;
+
+ return FIELD_PREP(ACTION_FLAG_WP, f & FLAG_WP ? en : dis) |
+ FIELD_PREP(ACTION_FLAG_RP, f & FLAG_RP ? en : dis) |
+ FIELD_PREP(ACTION_FLAG_OVRD, f & FLAG_OVRD ? en : dis) |
+ FIELD_PREP(ACTION_FLAG_ACTIVE, f & FLAG_ACTIVE ? en : dis);
+}
+
+int k3_kwl_set_smpkh(struct mpkh *mpkh, const char *sha, unsigned int flags)
+{
+ mpkh->field_header = SMPKH_MAGIC;
+ mpkh->action_flags = k3_kwl_set_flags(flags);
+ memcpy(mpkh->mpkh, sha, SHA512_DIGEST_SIZE);
+
+ return 0;
+}
+
+int k3_kwl_set_bmpkh(struct mpkh *mpkh, const char *sha, unsigned int flags)
+{
+ mpkh->field_header = BMPKH_MAGIC;
+ mpkh->action_flags = k3_kwl_set_flags(flags);
+ memcpy(mpkh->mpkh, sha, SHA512_DIGEST_SIZE);
+
+ return 0;
+}
+
+int k3_kwl_set_keycnt(struct key_cnt *k, unsigned int count, unsigned int flags)
+{
+ if (count < 1 || count > 2) {
+ pr_err("Only 1 or 2 allowed for key count\n");
+ return -EINVAL;
+ }
+
+ k->field_header = KEY_CNT_MAGIC;
+ k->action_flags = k3_kwl_set_flags(flags);
+ k->count = BIT(count) - 1;
+
+ return 0;
+}
+
+int k3_kwl_set_key_revision(struct key_revision *k, unsigned int revision,
+ unsigned int flags)
+{
+ if (revision < 1 || revision > 2) {
+ pr_err("Only 1 or 2 allowed for key revision\n");
+ return -EINVAL;
+ }
+
+ k->field_header = KEY_REVISION_MAGIC;
+ k->action_flags = k3_kwl_set_flags(flags);
+ k->revision = BIT(revision) - 1;
+
+ return 0;
+}
+
+int k3_kwl_set_sbl_revision(struct sbl_revision *k, unsigned int revision,
+ unsigned int flags)
+{
+ k->field_header = SBL_REVISION_MAGIC;
+ k->action_flags = k3_kwl_set_flags(flags);
+ k->revision = BIT(revision) - 1;
+
+ return 0;
+}
+
+int k3_kwl_set_brdcfg_revision(struct brdcfg_revision *k, unsigned int revision,
+ unsigned int flags)
+{
+ k->field_header = BRDCFG_REVISION_MAGIC;
+ k->action_flags = k3_kwl_set_flags(flags);
+ k->revision = BIT(revision) - 1;
+
+ return 0;
+}
+
+int k3_kwl_set_msv(struct msv *k, unsigned int msv, unsigned int flags)
+{
+ k->field_header = MSV_MAGIC;
+ k->action_flags = k3_kwl_set_flags(flags);
+ k->msv = msv;
+
+ return 0;
+}
+
+int k3_kwl_set_jtag_disable(struct jtag_disable *k, unsigned int jtag,
+ unsigned int flags)
+{
+ k->field_header = JTAG_DISABLE_MAGIC;
+ k->action_flags = k3_kwl_set_flags(flags);
+ k->jtag = jtag;
+
+ return 0;
+}
+
+int k3_kwl_set_bootmode(struct boot_mode *k, unsigned int fuse_id,
+ unsigned int boot_mode, unsigned int flags)
+{
+ if (fuse_id < 1 || fuse_id > 2) {
+ pr_err("Only 1 or 2 allowed for fuse_id\n");
+ return -EINVAL;
+ }
+
+ k->field_header = BOOT_MODE_MAGIC;
+ k->action_flags = k3_kwl_set_flags(flags);
+ k->fuse_id = fuse_id;
+ k->boot_mode = boot_mode;
+
+ return 0;
+}
+
+int k3_kwl_set_ext_otp(struct ext_otp *k, unsigned int bits, unsigned int index,
+ uint8_t *wprp, uint8_t *otp, unsigned int flags)
+{
+ k->field_header = EXT_OTP_MAGIC;
+ k->action_flags = k3_kwl_set_flags(flags);
+ k->size = bits;
+ k->index = index;
+ memcpy(k->wprp, wprp, sizeof(k->wprp));
+ memcpy(k->otp, otp, sizeof(k->otp));
+
+ return 0;
+}
+
+#define FD FIELD_PREP_CONST(ACTION_FLAG_ACTIVE, ACTION_FLAG_DISABLE)
+
+static struct keywriter_lite_packet keywrite_lite_template = {
+ .tisci_id = TISCI_MSG_KEY_WRITER_LITE,
+ .blob = {
+ .hdr = {
+ .magic = KEYWRITER_LITE_HEADER_MAGIC,
+ .size = sizeof(struct keywriter_lite_payload),
+ .abi_major = 0x0,
+ .abi_minor = 0x1,
+ .cmd_id = PROGRAMMING_MODE_MULTISHOT,
+ },
+
+ .payload = {
+ .mpk_options = {
+ .field_header = MPK_OPTS_MAGIC,
+ .action_flags = FD,
+ },
+ .smpkh = {
+ .field_header = SMPKH_MAGIC,
+ .action_flags = FD,
+ },
+ .bmpkh = {
+ .field_header = BMPKH_MAGIC,
+ .action_flags = FD,
+ },
+ .key_count = {
+ .field_header = KEY_CNT_MAGIC,
+ .action_flags = FD,
+ },
+ .key_revision = {
+ .field_header = KEY_REVISION_MAGIC,
+ .action_flags = FD,
+ },
+ .sbl_rev = {
+ .field_header = SBL_REVISION_MAGIC,
+ .action_flags = FD,
+ },
+ .sysfw_rev = {
+ .field_header = SYSFW_REVISION_MAGIC,
+ .action_flags = FD,
+ },
+ .brdcfg_rev = {
+ .field_header = BRDCFG_REVISION_MAGIC,
+ .action_flags = FD,
+ },
+ .msv_val = {
+ .field_header = MSV_MAGIC,
+ .action_flags = FD,
+ },
+ .jtag_disable = {
+ .field_header = JTAG_DISABLE_MAGIC,
+ .action_flags = FD,
+ },
+ .boot_mode = {
+ .field_header = BOOT_MODE_MAGIC,
+ .action_flags = FD,
+ },
+ .ext_otp = {
+ .field_header = EXT_OTP_MAGIC,
+ .action_flags = FD,
+ },
+ },
+ },
+};
+#undef FD
+
+void k3_kwl_prepare(struct keywriter_lite_packet *p)
+{
+ memcpy(p, &keywrite_lite_template, sizeof(keywrite_lite_template));
+}
+
+int k3_kwl_finalize(struct keywriter_lite_packet *p)
+{
+ struct digest *sha512;
+ int ret;
+
+ sha512 = digest_alloc("sha512");
+ if (!sha512)
+ return -ENOENT;
+
+ ret = digest_digest(sha512, &p->blob, offsetof(typeof(p->blob), hash),
+ p->blob.hash);
+ if (ret)
+ return ret;
+
+ digest_free(sha512);
+
+ return 0;
+}
+
+#define K3_SIP_OTP_WRITEBUFF 0xC2000000
+
+int k3_kwl_fuse_writebuff(struct keywriter_lite_packet *p)
+{
+ struct resource *resource;
+ unsigned long keywriter_lite_data = 0x82000000;
+ struct arm_smccc_res res;
+
+ resource = request_sdram_region("keywriter-lite", keywriter_lite_data,
+ 4096, MEMTYPE_LOADER_DATA, MEMATTRS_RW);
+ if (!resource)
+ return -ENOMEM;
+
+ /*
+ * Yes, we are passing the memory address of the buffer along with
+ * the SMC call, but TF-A will crash when it is different from this
+ * address on AM62L.
+ */
+
+ memcpy((void *)keywriter_lite_data, p, sizeof(keywrite_lite_template));
+
+ /* Make SiP SMC call and send the addr in the parameter register */
+ arm_smccc_smc(K3_SIP_OTP_WRITEBUFF, (unsigned long)keywriter_lite_data,
+ 0, 0, 0, 0, 0, 0, &res);
+
+ if (res.a0 != 0)
+ printf("SMC call failed: Error code %ld\n", res.a0);
+
+ release_sdram_region(resource);
+
+ return res.a0;
+}
diff --git a/include/soc/k3/keywriter-lite.h b/include/soc/k3/keywriter-lite.h
new file mode 100644
index 0000000000..4bf3788ee4
--- /dev/null
+++ b/include/soc/k3/keywriter-lite.h
@@ -0,0 +1,177 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#ifndef __SOC_K3_KEYWRITER_LITE_H
+#define __SOC_K3_KEYWRITER_LITE_H
+
+#include <crypto/sha.h>
+
+/*
+ * structure layout and magic values are from:
+ * https://software-dl.ti.com/tisci/esd/latest/6_topic_user_guides/key_writer_lite.html
+ * with corrections from:
+ * https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1578568/am62l-am62l-secure-boot-keywriter-lite
+ */
+
+#define KEYWRITER_LITE_HEADER_MAGIC 0x9012
+struct keywriter_lite_header {
+ uint16_t magic;
+ uint16_t size;
+ uint8_t abi_major; /* 0x00 */
+ uint8_t abi_minor; /* 0x01 */
+ uint16_t reserved0;
+ uint32_t cmd_id; /* PROGRAMMING_MODE_* */
+ uint32_t reserved1[2];
+} __attribute__((packed));
+
+#define MPK_OPTS_MAGIC 0x4a7e
+struct mpk_opts {
+ uint32_t field_header;
+ uint32_t action_flags;
+ uint16_t options; /* 0x0 */
+ uint8_t resv_field[2]; /* 0x0 */
+ uint32_t reserved[2]; /* 0x0 */
+} __attribute__((packed));
+
+#define SMPKH_MAGIC 0x1234
+#define BMPKH_MAGIC 0x9FFC
+struct mpkh {
+ uint32_t field_header;
+ uint32_t action_flags;
+ uint8_t mpkh[64];
+ uint32_t reserved[2];
+} __attribute__((packed));
+
+#define KEY_CNT_MAGIC 0x5678
+struct key_cnt {
+ uint32_t field_header;
+ uint32_t action_flags;
+ uint32_t count;
+ uint32_t reserved[2];
+} __attribute__((packed));
+
+#define KEY_REVISION_MAGIC 0x62c8
+struct key_revision {
+ uint32_t field_header;
+ uint32_t action_flags;
+ uint32_t revision; /* The key revision value encoded in bit-position format */
+ uint32_t reserved[2];
+} __attribute__((packed));
+
+#define SBL_REVISION_MAGIC 0x8bad
+struct sbl_revision {
+ uint32_t field_header;
+ uint32_t action_flags;
+ uint64_t revision; /* The SBL software revision value encoded in bit-position format */
+ uint32_t reserved[3];
+} __attribute__((packed));
+
+#define SYSFW_REVISION_MAGIC 0x45a9 /* must be typo: same as in struct sbl_revision */
+struct sysfw_revision {
+ uint32_t field_header;
+ uint32_t action_flags;
+ uint64_t revision; /* The SYSFW software revision value encoded in bit-position format */
+ uint32_t reserved[3];
+} __attribute__((packed));
+
+#define BRDCFG_REVISION_MAGIC 0x98dc
+struct brdcfg_revision {
+ uint32_t field_header;
+ uint32_t action_flags;
+ uint64_t revision; /* The BRDCFG software revision value encoded in bit-position format */
+ uint32_t reserved[4];
+} __attribute__((packed));
+
+#define MSV_MAGIC 0x1337
+struct msv {
+ uint32_t field_header;
+ uint32_t action_flags;
+ uint32_t msv; /* The 20-bit MSV value */
+ uint32_t reserved[2];
+} __attribute__((packed));
+
+#define JTAG_DISABLE_MAGIC 0x7421
+struct jtag_disable {
+ uint32_t field_header;
+ uint32_t action_flags;
+ uint32_t jtag; /* The 4-bit jtag unlock disable value */
+ uint32_t reserved[2];
+} __attribute__((packed));
+
+#define BOOT_MODE_MAGIC 0xa1b2
+struct boot_mode {
+ uint32_t field_header;
+ uint32_t action_flags;
+ uint32_t fuse_id; /* The index of the fuse to program currently accepts only 1,2 */
+ uint32_t boot_mode; /* The 25-bit boot mode value to program */
+ uint32_t reserved[2];
+} __attribute__((packed));
+
+#define EXT_OTP_MAGIC 0xd0e5
+struct ext_otp {
+ uint32_t field_header;
+ uint32_t action_flags;
+ uint16_t size; /* The number of bits to program */
+ uint16_t index; /* The index in the 1024-bits space to start programming from */
+ uint8_t wprp[16]; /* Read protect/write protect array */
+ uint8_t otp[128]; /* The 1024 bits extended otp data */
+ uint32_t reserved[4];
+} __attribute__((packed));
+
+struct keywriter_lite_payload {
+ struct mpk_opts mpk_options;
+ struct mpkh smpkh;
+ struct mpkh bmpkh;
+ struct key_cnt key_count;
+ struct key_revision key_revision;
+ struct sbl_revision sbl_rev;
+ struct sysfw_revision sysfw_rev;
+ struct brdcfg_revision brdcfg_rev;
+ struct msv msv_val;
+ struct jtag_disable jtag_disable;
+ struct boot_mode boot_mode;
+ struct ext_otp ext_otp;
+} __attribute__((packed));
+
+#define TISCI_MSG_KEY_WRITER_LITE 0x9045
+
+struct keywriter_lite_blob {
+ struct keywriter_lite_header hdr;
+ struct keywriter_lite_payload payload;
+ unsigned char hash[SHA512_DIGEST_SIZE];
+} __attribute__((packed));
+
+struct keywriter_lite_packet {
+ uint32_t ver_info_unused;
+ uint32_t tisci_id;
+ struct keywriter_lite_blob blob;
+};
+
+enum action_flags {
+ FLAG_WP = BIT(0),
+ FLAG_RP = BIT(1),
+ FLAG_OVRD = BIT(2),
+ FLAG_ACTIVE = BIT(3),
+};
+
+int k3_kwl_set_smpkh(struct mpkh *mpkh, const char *sha, unsigned int flags);
+int k3_kwl_set_bmpkh(struct mpkh *mpkh, const char *sha, unsigned int flags);
+int k3_kwl_set_keycnt(struct key_cnt *k, unsigned int count, unsigned int flags);
+int k3_kwl_set_key_revision(struct key_revision *k, unsigned int revision,
+ unsigned int flags);
+int k3_kwl_set_sbl_revision(struct sbl_revision *k, unsigned int revision,
+ unsigned int flags);
+int k3_kwl_set_brdcfg_revision(struct brdcfg_revision *k, unsigned int revision,
+ unsigned int flags);
+int k3_kwl_set_msv(struct msv *k, unsigned int msv, unsigned int flags);
+int k3_kwl_set_jtag_disable(struct jtag_disable *k, unsigned int jtag,
+ unsigned int flags);
+int k3_kwl_set_bootmode(struct boot_mode *k, unsigned int fuse_id,
+ unsigned int boot_mode, unsigned int flags);
+int k3_kwl_set_ext_otp(struct ext_otp *k, unsigned int bits, unsigned int index,
+ uint8_t *wprp, uint8_t *otp, unsigned int flags);
+
+void k3_kwl_prepare(struct keywriter_lite_packet *p);
+int k3_kwl_finalize(struct keywriter_lite_packet *p);
+int k3_kwl_fuse_writebuff(struct keywriter_lite_packet *p);
+
+
+#endif /* __SOC_K3_KEYWRITER_LITE_H */
--
2.47.3
reply other threads:[~2025-11-10 13:40 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251110133920.3900948-1-s.hauer@pengutronix.de \
--to=s.hauer@pengutronix.de \
--cc=barebox@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox