Burning ODM_RESERVED fuses after ODM_PRODUCTION_MODE is not working


We are trying to burn the ODM_RESERVED[0-3] fuses (on L4T 35.4.1). This works if we do it before burning any other fuses, but after we burn the KEK, PKC & ODM_PRODUCTION_MODE the driver does not burn the ODM_RESERVED[0-3] anymore. There is no error message in the kernel log.

The fuse specification document says that the ODM_RESERVED fuses should still be burnable when the ODM_PRODUCTION_MODE fuse is burned. This is also what I find in the code if I look at the tegra-fuse-burn driver. I don’t want to experiment too much with this because the fuse burning is irreversible and I don’t want to ruin the modules.

This is what we do to try burning the fuses:

11:34:32 $ sudo cat /sys/devices/platform/efuse-burn/odm_production_mode

11:34:58 $ sudo cat /sys/devices/platform/efuse-burn/odm_lock

11:35:17 $ sudo cat /sys/devices/platform/efuse-burn/reserved_odm0

11:35:41 $ echo "0x12345678" | sudo tee /sys/devices/platform/efuse-burn/reserved_odm0

11:36:05 $ sudo cat /sys/devices/platform/efuse-burn/reserved_odm0

*after reboot*

11:39:36 $ sudo cat /sys/devices/platform/efuse-burn/reserved_odm0

How can I burn the ODM_RESERVED fuses after burning the other fuses?


hello h123,

that’s incorrect approach for burning fuse.
you may put the target enter forced-recovery mode, and running with odmfuse.sh.
please see-also developer guide, Sign and Flash Secured Images in Separate Steps.

it’s suggest to burn all fuses together even though ODM_RESERVED fuses could be add after ODM_PRODUCTION. once SecurityMode has burned, there is no way back. (even by adding keys to non-fuse fields)
hence, the recommended way is to burn all fuses together instead of burning fuses step-by-step.

Hi JerryChang,

According to the documentation the the ODM_RESERVED fuses are field programmable. How are we supposed to burn them in the field if it has to be done through recovery mode? We are already burning all the other fuses in one step during production. The ODM_RESERVED fuses we cannot burn yet at that time, because their content is not known at that point.

The fuse specification clearly says that they can be burned in the field: “The consecutive registers are reserved for the customer use, including ODM/software versioning. These fuses are field programmable, Reserved_ODM{0:3} can be individually locked against further burning using corresponding bits in ODM_Lock, bit [b] locks Reserved_ODM{b}.”. Also from the source code of the kernel driver it is clear that the kernel driver can be used for burning the fuses, so why do you say we cannot use it? It works fine, if the other fuses aren’t burned yet. So to me this just looks like a bug.

We need a way to burn the ODM_RESERVED fuses at the end of our production line from the linux kernel. Can you maybe suggest another way that we can use, if our current sysfs method is not recommended?

Thank you,

hello h123,

FYI, it should be possible to burn ODM fuse from kernel. (I’ll also revise my previous comments)
however, let me arrange resources to check whether fuse burning is allowed from non-secure zone.

1 Like

Do you have any examples how to do that? after odm_production_mode is blown?

Before odm_producteon_mode is blown I could simply use:
echo "0x12345678" | sudo tee /sys/devices/platform/efuse-burn/reserved_odm0

But after odm_production_mode is blown that command has no effect. Is there a different way to blow reservled_odm fuses in the field?

hello aleksei.fedotov,

it should be the same for burning that fuse variable.
please setup $ dmesg --follow to gather the kernel logs when you trying to blow reservled_odm fuses in the field.

It does not show any logs when I try to blow reserved_odm fuse:

root@localhost:~# dmesg -c > /dev/null                                                 <- clean dmesg from earlier messages
root@localhost:~# cat /sys/devices/platform/tegra-fuse/odm_lock    <- odm fuses are not locked
root@localhost:~# cat /sys/devices/platform/tegra-fuse/reserved_odm0 
root@localhost:~# echo 0x12345678 > /sys/devices/platform/tegra-fuse/reserved_odm0          < trying to blow a fuse
root@localhost:~# echo $?                            <- no error
root@localhost:~# cat /sys/devices/platform/tegra-fuse/reserved_odm0         <- but the fuse is unchanged
root@localhost:~# dmesg                                       <-- no new logs since 'dmesg -c'
1 Like

Dear @JerryChang , is there any update on this? Could you reproduce this problem internally?

Hi @JerryChang, Has there been any progress on your side trying to reproduce this issue? We are still blocked on this as we cannot burn the fuses at the moment.

hello h123,

sorry for late reply, we’ve also checked with internal team for this. (we had no conclusions yet)
anyways, by checking [Fuse Specification Application Note], could you please examine this fuse variable, FUSE_SECURE_PROVISION_INFO, and sharing the results for reference.

also, please install this utility… $ sudo apt-get install busybox
and dumping the register 0x03820028 for confirmation, i.e. $ sudo busybox devmem 0x03820028

Hi JerryChang,

Thank you for your reply. How can I read the FUSE_SECURE_PROVISION_INFO fuse? I don’t see a matching file in the sysfs entries. The register dump is below.

16:26:32 $ sudo busybox devmem 0x03820028

Hi JerryChang,

Do you have any news on this topic?

it’s already in the internal investigation; we’re checking whether this is enable burn protection by accidentally.

Hi JerryChang,

Do you already have more news on when I can expect a solution for this?

hello h123,

we’re able to reproduce this issue locally. fuse burn is working before we burn production_mode fuse.
however, it’s not root cause yet. we need more time for digging into this.

1 Like

Hi JerryChang,

Could you give an update on this? Can you already provide us with a patch that we can apply, or a workaround?

could you please check the value of the register 0x0382002c when you are attempting a burn operation,
for instance, $ sudo busybox devmem 0x0382002c