[EXTERNAL] Re: Proposal for a New Command to U-Boot Fuse Programming

Harsha Vardhan V M h-vm at ti.com
Fri Jan 10 06:42:47 CET 2025



On 07/01/25 03:53, Tom Rini wrote:
> On Mon, Jan 06, 2025 at 12:06:25PM +0530, Harsha Vardhan V M wrote:
> 
>> I would like to propose a new command for U-Boot's fuse programming
>> functionality to address the challenges posed by the current implementation.
>> While the existing fuse prog command works well for programming individual
>> fuse values, it becomes cumbersome especially when dealing with large-scale
>> programming requirements.
>>
>> Current Command: fuse prog [-y] <bank> <word> <hexval> [<hexval>...]
>>
>> This command programs one or more fuse words starting from a specific <bank>
>> and <word> with the hex values given as input.
>>
>> While functional, it lacks the efficiency and robustness needed for
>> programming a significant number of fuses or handling structured fuse
>> configuration data. Repeatedly specifying values for each fuse bank and word
>> is not only time-consuming but also prone to errors during manual input or
>> scripting. This approach does not leverage the ability to process
>> pre-structured data in memory. For users with complex programming needs, the
>> current method becomes an obstacle rather than a tool.
>>
>> Proposed Command: fuse writebuff
> 
> It would be good to provide some documentation links to the fuses that
> you're wanting to deal with. What we have now works on a number of
> diverse SoCs, even if for some cases it might be best to write a
> script that's run rather than copy/paste things live. Any sort of new
> mechanism needs to get feedback from users at other semiconductor
> vendors to make sure it's generic enough for everyones needs. Thanks.
> 

Hi Tom and Simon,

The buffer is not a text file. It is a structure in memory. The buffer 
is structured to contain all necessary information for the fuse 
programming process. This can include metadata, fuse programming data 
etc. The exact structure of the buffer can determined by the command_id, 
which provides flexibility for supporting different use cases. The 
memory buffer is typically prepared in user-space code or a script and 
loaded in memory before invoking the fuse writebuff command. It is not 
stored as a text file or any other file format, as the command operates 
directly on memory addresses.

Example of a buffer:

struct fuse_buffer {
     struct fuse_mpkh smpkh;
     struct fuse_msv msv;
     struct fuse_key_cnt key_cnt;
     u8 buffer_hash[64];
};

This fuse_buffer struct will be loaded in memory containing all the 
necessary information for fuse programming.

struct fuse_mpkh {
     u8 mpkh[64]; // public key hash
     u8 bch[8];
     u32 attributes; // read-protect, write-protect, override, active flag
     u32 reserved[2];
};
struct fuse_msv {
     u32 msv_with_bch; //model specific value
     u32 attributes;
     u32 reserved[2];
};
struct fuse_key_cnt {
     u32 key_cnt; //key count
     u32 attributes;
     u32 reserved[2];
};

-> eFUSE layout is abstract and isn't public as its programming and 
layout itself is security sensitive (it has authentication and 
decryption keys etc). So, fuse prog doesn't work as there is no 
"banks/offset" here.
-> Platform Security Core running Secure SW exposes APIs through which 
these Keys and its attributes can be programmed. Whole content maybe 
encrypted for enhanced security on unsecure factory floor.
-> There is a definite order in which these fields needs to be programmed.

Its possible to break the struct into 32bit values and send them across 
but we would end up with ~30 odd fuse prog cmds which is inefficient and 
error prone.
It would be hard on secure core to also ensure correctness of operations 
against all sorts of silly errors (such of accidentally skipping a word 
or mess up ordering) which can render Silicon unusable.

So passing a opaque pointer with a command_id to Secure core is all that 
fuse cmd needs to do which is what writebuff supports.

This can be extended to any vendor; It's just an opaque pointer handoff. 
I see at least one other vendor do it in custom way: 
arch/arm/mach-imx/cmd_dek.c which could benefit from this new cmd fuse 
writebuff.

Here’s how the fuse writebuff command works in a typical flow:
1. Buffer Preparation: Vendors or developers create a complete buffer 
(e.g., key.bin) containing all fuse programming data using 
vendor-specific scripts or tools and copied to SD card.
2. The buffer is loaded into memory using commands like:
fatload mmc 1 0x80000000 key.bin
3. The fuse writebuff command passes the memory address (0x80000000) and 
command_id to the secure core:
fuse writebuff <command_id> 0x80000000
4. The secure core receives the memory address as a pointer and 
validates, interprets it based on the command_id and then programs the 
fuses.

Thanks,
Harsha
<h-vm at ti.com>


More information about the U-Boot mailing list