Skip to content

Commit

Permalink
arm: mvebu: efuse: add read-only build-time option to protect efuses
Browse files Browse the repository at this point in the history
Add new configuration option MVEBU_EFUSE_READONLY for building a
read-only efuse driver.
Unlike the eixsting MVEBU_EFUSE_FAKE, read-only mode allows reading the
actual efuse values, e.g. for investigating problematic units with
burned fuses, while protecting the fuse registers from user error.

Signed-off-by: Josua Mayer <[email protected]>
  • Loading branch information
Josua-SR committed Aug 20, 2024
1 parent b87edcd commit 09646d0
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 10 deletions.
8 changes: 8 additions & 0 deletions arch/arm/mach-mvebu/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,14 @@ config MVEBU_EFUSE_FAKE
from a memory block.
This is can be used for testing prog scripts.

config MVEBU_EFUSE_READONLY
bool "Read-only eFuse access"
depends on MVEBU_EFUSE
help
This enables a "read-only" mode where eFuses can only be read.
This is can be used for testing and validating units without any
danger of user error.

config MVEBU_EFUSE_VHV_GPIO
string "VHV_Enable GPIO name for eFuse programming"
depends on MVEBU_EFUSE && !ARMADA_3700
Expand Down
38 changes: 28 additions & 10 deletions arch/arm/mach-mvebu/efuse.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,26 @@ struct mvebu_hd_efuse {
u32 reserved0;
};

#ifndef CONFIG_MVEBU_EFUSE_READONLY
typedef struct mvebu_hd_efuse mvebu_hd_efuse;
typedef u32 mvebu_ld_efuse;
#else
typedef const struct mvebu_hd_efuse mvebu_hd_efuse;
typedef const u32 mvebu_ld_efuse;
#endif

#ifndef DRY_RUN
static struct mvebu_hd_efuse *efuses =
(struct mvebu_hd_efuse *)(MBUS_EFUSE_BASE + 0xF9000);
static u32 *ld_efuses = (void *)MBUS_EFUSE_BASE + 0xF8F00;
static mvebu_hd_efuse *efuses =
(mvebu_hd_efuse *)(MBUS_EFUSE_BASE + 0xF9000);
static mvebu_ld_efuse *ld_efuses = (void *)MBUS_EFUSE_BASE + 0xF8F00;
#else
static struct mvebu_hd_efuse efuses[EFUSE_LINE_MAX + 1];
static u32 ld_efuses[EFUSE_LD_WORDS];
static mvebu_hd_efuse efuses[EFUSE_LINE_MAX + 1];
static mvebu_ld_efuse ld_efuses[EFUSE_LD_WORDS];
#endif

static int efuse_initialised;

static struct mvebu_hd_efuse *get_efuse_line(int nr)
static mvebu_hd_efuse *get_efuse_line(int nr)
{
if (nr < 0 || nr > 63 || !efuse_initialised)
return NULL;
Expand Down Expand Up @@ -102,9 +110,10 @@ static void disable_efuse_program(void)
#endif
}

static int do_prog_efuse(struct mvebu_hd_efuse *efuse,
static int do_prog_efuse(mvebu_hd_efuse *efuse,
struct efuse_val *new_val, u32 mask0, u32 mask1)
{
#ifndef CONFIG_MVEBU_EFUSE_READONLY
struct efuse_val val;

val.dwords.d[0] = readl(&efuse->bits_31_0);
Expand All @@ -126,11 +135,15 @@ static int do_prog_efuse(struct mvebu_hd_efuse *efuse,
mdelay(5);

return 0;
#else
printf("Error: Operating in read-only mode, writing not allowed.\n");
return -EPERM;
#endif
}

static int prog_efuse(int nr, struct efuse_val *new_val, u32 mask0, u32 mask1)
{
struct mvebu_hd_efuse *efuse;
mvebu_hd_efuse *efuse;
int res = 0;

res = mvebu_efuse_init_hw();
Expand Down Expand Up @@ -168,8 +181,9 @@ static int prog_efuse(int nr, struct efuse_val *new_val, u32 mask0, u32 mask1)

int mvebu_prog_ld_efuse(int ld1, u32 word, u32 val)
{
#ifndef CONFIG_MVEBU_EFUSE_READONLY
int i, res;
u32 line[EFUSE_LD_WORDS];
mvebu_ld_efuse line[EFUSE_LD_WORDS];

res = mvebu_efuse_init_hw();
if (res)
Expand Down Expand Up @@ -206,6 +220,10 @@ int mvebu_prog_ld_efuse(int ld1, u32 word, u32 val)
disable_efuse_program();

return 0;
#else
printf("Error: Operating in read-only mode, writing not allowed.\n");
return -EPERM;
#endif
}

int mvebu_efuse_init_hw(void)
Expand All @@ -228,7 +246,7 @@ int mvebu_efuse_init_hw(void)

int mvebu_read_efuse(int nr, struct efuse_val *val)
{
struct mvebu_hd_efuse *efuse;
mvebu_hd_efuse *efuse;
int res;

res = mvebu_efuse_init_hw();
Expand Down

0 comments on commit 09646d0

Please sign in to comment.