OTP Access Utility Guide (Klamath: SL261x)
Introduction
This document describes the usage of the OTP access utilities for
klamath: SL261x in u-boot environment:
U-Boot environment : otpread / otpwrite
OTP (One-Time Programmable) memory allows permanent configuration of security keys, boot policies, and OEM information.
OTP Field Definitions Table
Each OTP index has a fixed access permission and a valid data mask. Only bits set in the mask are allowed to be programmed.
“Atomic Item” indicates whether the field MUST be programmed as part of the atomic security provisioning group.
Index |
Name |
Read / Write Permission |
Mask |
Atomic Item |
Comments |
|---|---|---|---|---|---|
44 |
OTP_SYNA_IMAGE_SECURE_BOOT_EN |
Read / Write |
0xFFFFFFFF |
NO |
Enable the syna image secure boot feature |
72 |
OTP_JTAG_ACCESS_CONTROL |
Read / Write |
0xFFFFFFFF |
NO |
JTAG access control |
80 |
OTP_K0_OEM_HASH_0 |
Read / Write |
0xFFFFFFFF |
YES |
OEM Root Public Key Hash word 0 (512-bit) |
81 |
OTP_K0_OEM_HASH_1 |
Read / Write |
0xFFFFFFFF |
YES |
OEM Root Public Key Hash word 1 |
82 |
OTP_K0_OEM_HASH_2 |
Read / Write |
0xFFFFFFFF |
YES |
OEM Root Public Key Hash word 2 |
83 |
OTP_K0_OEM_HASH_3 |
Read / Write |
0xFFFFFFFF |
YES |
OEM Root Public Key Hash word 3 |
84 |
OTP_K0_OEM_HASH_4 |
Read / Write |
0xFFFFFFFF |
YES |
OEM Root Public Key Hash word 4 |
85 |
OTP_K0_OEM_HASH_5 |
Read / Write |
0xFFFFFFFF |
YES |
OEM Root Public Key Hash word 5 |
86 |
OTP_K0_OEM_HASH_6 |
Read / Write |
0xFFFFFFFF |
YES |
OEM Root Public Key Hash word 6 |
87 |
OTP_K0_OEM_HASH_7 |
Read / Write |
0xFFFFFFFF |
YES |
OEM Root Public Key Hash word 7 |
88 |
OTP_K0_OEM_HASH_8 |
Read / Write |
0xFFFFFFFF |
YES |
OEM Root Public Key Hash word 8 |
89 |
OTP_K0_OEM_HASH_9 |
Read / Write |
0xFFFFFFFF |
YES |
OEM Root Public Key Hash word 9 |
90 |
OTP_K0_OEM_HASH_10 |
Read / Write |
0xFFFFFFFF |
YES |
OEM Root Public Key Hash word 10 |
91 |
OTP_K0_OEM_HASH_11 |
Read / Write |
0xFFFFFFFF |
YES |
OEM Root Public Key Hash word 11 |
92 |
OTP_K0_OEM_HASH_12 |
Read / Write |
0xFFFFFFFF |
YES |
OEM Root Public Key Hash word 12 |
93 |
OTP_K0_OEM_HASH_13 |
Read / Write |
0xFFFFFFFF |
YES |
OEM Root Public Key Hash word 13 |
94 |
OTP_K0_OEM_HASH_14 |
Read / Write |
0xFFFFFFFF |
YES |
OEM Root Public Key Hash word 14 |
95 |
OTP_K0_OEM_HASH_15 |
Read / Write |
0xFFFFFFFF |
YES |
OEM Root Public Key Hash word 15 |
112 |
OTP_CCGK_0 |
Write Only |
0xFFFFFFFF |
YES |
Customer Chip Global Key Word 0 (256-bit) |
113 |
OTP_CCGK_1 |
Write Only |
0xFFFFFFFF |
YES |
Customer Chip Global Key Word 1 |
114 |
OTP_CCGK_2 |
Write Only |
0xFFFFFFFF |
YES |
Customer Chip Global Key Word 2 |
115 |
OTP_CCGK_3 |
Write Only |
0xFFFFFFFF |
YES |
Customer Chip Global Key Word 3 |
116 |
OTP_CCGK_4 |
Write Only |
0xFFFFFFFF |
YES |
Customer Chip Global Key Word 4 |
117 |
OTP_CCGK_5 |
Write Only |
0xFFFFFFFF |
YES |
Customer Chip Global Key Word 5 |
118 |
OTP_CCGK_6 |
Write Only |
0xFFFFFFFF |
YES |
Customer Chip Global Key Word 6 |
119 |
OTP_CCGK_7 |
Write Only |
0xFFFFFFFF |
YES |
Customer Chip Global Key Word 7 |
120 |
OTP_CCUK_0 |
Write Only |
0xFFFFFFFF |
NO |
Customer Chip Unique Key Word 0 (256-bit) |
121 |
OTP_CCUK_1 |
Write Only |
0xFFFFFFFF |
NO |
Customer Chip Unique Key Word 1 |
122 |
OTP_CCUK_2 |
Write Only |
0xFFFFFFFF |
NO |
Customer Chip Unique Key Word 2 |
123 |
OTP_CCUK_3 |
Write Only |
0xFFFFFFFF |
NO |
Customer Chip Unique Key Word 3 |
124 |
OTP_CCUK_4 |
Write Only |
0xFFFFFFFF |
NO |
Customer Chip Unique Key Word 4 |
125 |
OTP_CCUK_5 |
Write Only |
0xFFFFFFFF |
NO |
Customer Chip Unique Key Word 5 |
126 |
OTP_CCUK_6 |
Write Only |
0xFFFFFFFF |
NO |
Customer Chip Unique Key Word 6 |
127 |
OTP_CCUK_7 |
Write Only |
0xFFFFFFFF |
NO |
Customer Chip Unique Key Word 7 |
128 |
OTP_CCUK_ID_0 |
Read / Write |
0xFFFFFFFF |
NO |
Customer Chip Unique Key ID Word 0 (64-bit) |
129 |
OTP_CCUK_ID_1 |
Read / Write |
0xFFFFFFFF |
NO |
Customer Chip Unique Key ID Word 1 |
131 |
OTP_OEM_IMAGE_SECURE_BOOT_EN |
Read / Write |
0xFFFFFFFF |
NO |
Enable OEM Image Secure Boot |
135 |
OTP_OEM_SEGID |
Read / Write |
0xFFFFFFFF |
YES |
OEM segmentation ID |
145 |
OTP_OEM_IMAGE_VERSION |
Read / Write |
0xFFFFFFFF |
NO |
OEM image version |
556 |
OTP_SOC_UID_0 |
Read Only |
0xFFFFFFFF |
NO |
SoC Unique ID Word 0 |
557 |
OTP_SOC_UID_1 |
Read Only |
0xFFFFFFFF |
NO |
SoC Unique ID Word 1 |
558 |
OTP_SOC_UID_2 |
Read Only |
0xFFFFFFFF |
NO |
SoC Unique ID Word 2 |
559 |
OTP_SOC_UID_3 |
Read Only |
0xFFFFFFFF |
NO |
SoC Unique ID Word 3 |
577 |
OTP_MAC_ADDRESS_0 |
Read / Write |
0xFFFFFFFF |
NO |
MAC address |
578 |
OTP_MAC_ADDRESS_1 |
Read / Write |
0xFFFFFFFF |
NO |
MAC address |
Notes:
- OTP_OEM_IMAGE_SECURE_BOOT_EN:
This field controls the OEM image secure boot feature. The default value is 0x00000000, which means that OEM secure boot is disabled.
The valid configuration values are:
0x00000000– Secure boot is disabled.
0x00010001– Secure boot is enabled in development mode.
0x10011001– Secure boot is enabled in production mode.The image production flag policy is defined as follows:
When OTP_OEM_IMAGE_SECURE_BOOT_EN is set to
0x00010001(development mode), the device allows images withImage_production_flagset to either 0 or 1 to boot.When OTP_OEM_IMAGE_SECURE_BOOT_EN is set to
0x10011001(production mode), the device allows only images withImage_production_flagset to1to boot.During image signing, the user can select the
Image_production_flagaccording to the intended image type:
Image_production_flag = 0 – Development image.
Image_production_flag = 1 – Production image.
During secure boot, the device checks the
Image_production_flagin the image header against the configured OTP_OEM_IMAGE_SECURE_BOOT_EN policy to determine whether the image is allowed to boot.
- OTP_SYNA_IMAGE_SECURE_BOOT_EN:
This field controls the Syna image secure boot feature. In Astra chips before shipping, It is enabled by default. So the official release of Astra preboot images are built with security features enabled. In general, customers do not need to change this value.
The valid configuration values are:
0x00000000– Syna secure boot is disabled.
0x10011001– Syna secure boot is enabled.
- OTP_JTAG_ACCESS_CONTROL:
This field controls JTAG access for the M52 and A55 domains.
For safety and integrity checking, the 32-bit field contains two identical 16-bit copies:
Bits
[15:0]– Primary JTAG access control valueBits
[31:16]– Duplicate of bits[15:0]Bits
[31:16]must have the same value as bits[15:0]. A mismatch between the primary and duplicate fields indicates an invalid or corrupted configuration.The default value is
0x00000000, which means that JTAG access is open (enabled) for all domains.The bit definitions are as follows:
Bits
Field
Description
[1:0]
M52_SEC
M52 Secure JTAG access control
[3:2]
A55_SEC
A55 Secure JTAG access control
[5:4]
M52_NS
M52 Non-Secure JTAG access control
[7:6]
A55_NS
A55 Non-Secure JTAG access control
[15:8]
Reserved
Reserved
[17:16]
M52_SEC_dup
Duplicate of M52_SEC
[19:18]
A55_SEC_dup
Duplicate of A55_SEC
[21:20]
M52_NS_dup
Duplicate of M52_NS
[23:22]
A55_NS_dup
Duplicate of A55_NS
[31:24]
Reserved
Reserved
Each 2-bit JTAG access control field uses the following policy:
Value
JTAG Access Policy
2’b00
Open
2’b01
Certificate-controlled
2’b1x
Closed
The access policy is applied independently to each JTAG domain.
For example:
M52_SEC = 2'b00means M52 Secure JTAG access is open.
M52_SEC = 2'b01means M52 Secure JTAG access is controlled by certificate authentication.
M52_SEC = 2'b10or2'b11means M52 Secure JTAG access is closed.The same policy applies to
A55_SEC,M52_NS, andA55_NS.When programming
OTP_JTAG_ACCESS_CONTROL, the lower 16-bit value must also be duplicated into the upper 16 bits.The 32-bit value shall therefore follow the format:
OTP_JTAG_ACCESS_CONTROL[31:16] = OTP_JTAG_ACCESS_CONTROL[15:0]For example, if the primary configuration is:
OTP_JTAG_ACCESS_CONTROL[15:0] = 0x0055then the complete 32-bit value must be:
OTP_JTAG_ACCESS_CONTROL = 0x00550055Similarly, the default configuration is:
OTP_JTAG_ACCESS_CONTROL[15:0] = 0x0000 OTP_JTAG_ACCESS_CONTROL[31:16] = 0x0000 OTP_JTAG_ACCESS_CONTROL = 0x00000000A valid programmed value must satisfy the following condition:
OTP_JTAG_ACCESS_CONTROL[31:16] == OTP_JTAG_ACCESS_CONTROL[15:0]
- OTP_CCUK_ID_0 and OTP_CCUK_ID_1:
These two fields are used to store a 64-bit Customer Chip Unique Key ID. The CCUK ID is an optional field that can be used to associate the CCUK. It does not affect the functionality of the CCUK itself. Please program the OTP_CCUK_ID_0 and OTP_CCUK_ID_1 in the same session as it’s a 64-bit value spanning across two 32-bit fields.
- OTP_OEM_IMAGE_VERSION:
This field is used to store a version number for the CCGK derived images (i.e., tzk, bl, firmware, boot, fastlogo) to implement anti-rollback mechanisms. Supported OEM image version range is 0~31. Default value is 0. User can choose to increase the version number when there’s a need to prevent older OEM image from booting.
- OTP_SOC_UID_0-3:
The OTP_SOC_UID_0-3 fields collectively store the 128-bit unique ID. Each field contains a 32-bit word of the 128-bit unique ID. These fields are programmed by Synaptics before the chips are shipped to customers.
- OTP_MAC_ADDRESS_0 and OTP_MAC_ADDRESS_1:
These fields are used to store the 48-bit Ethernet MAC address in OTP. The MAC address is divided into two 32-bit OTP fields:
OTP Field
OTP Index
MAC Address Data
OTP_MAC_ADDRESS_0
577
Lower 32 bits of the MAC address
OTP_MAC_ADDRESS_1
578
Upper 16 bits of the MAC address
For example, given the following Ethernet MAC address:
ether = 56:E5:F7:CB:FE:E3
The six MAC address bytes are:
56 E5 F7 CB FE E3 | | | | +----------+-- OTP_MAC_ADDRESS_0 +------------------- OTP_MAC_ADDRESS_1The MAC address is programmed into the OTP fields as follows:
OTP_MAC_ADDRESS_0contains the lower four bytesF7:CB:FE:E3, resulting in the 32-bit value0xF7CBFEE3.
OTP_MAC_ADDRESS_1contains the upper two bytes56:E5in bits[15:0], resulting in the 32-bit value0x000056E5. Bits[31:16]are unused and should be set to zero.The corresponding OTP programming commands are:
otpwrite 577 0xf7cbfee3 0xffffffff otpwrite 578 0x000056e5 0xffffffffTherefore, the MAC address mapping is:
MAC Address: 56:E5:F7:CB:FE:E3 +---------+-------------+ | 56 E5 | F7 CB FE E3 | +---------+-------------+ | | v v OTP 578 OTP 577 0x000056E5 0xF7CBFEE3After programming, the two OTP fields together represent the original 48-bit Ethernet MAC address
56:E5:F7:CB:FE:E3.
U-BOOT OTP Commands
otpread
- Usage:
otpread <otp_index> otpread 577 otpread 578
- Return Codes:
0x00000000 : Success 0xFF000001 : STATUS_FAILURE 0xFF000050 : STATUS_OTP_INVALID_IDX 0xFF000052 : STATUS_OTP_ERROR_WRITEONLY_FIELD
- Examples:
=> otpread 577 otp operation succeed read otp[577] data=0xf7cbfee3 => otpread 578 otp operation succeed read otp[578] data=0x000056e5
If a write-only field is read:
- Return Code:
0xFF000052 : STATUS_OTP_ERROR_WRITEONLY_FIELD
- Returned Data:
0xDEADBEAF (INVALID DUMMY DATA)
- Examples:
=> otpread 112 otp operation failed read otp[112] data=0xdeadbeaf
otpwrite
- Usage:
otpwrite <otp_index> <data> <mask> otpwrite 577 0xf7cbfee3 0xFFFFFFFF otpwrite 578 0x000056e5 0xFFFFFFFF
- Return Codes:
0x00000000 : Success 0xFF000001 : STATUS_FAILURE 0xFF000050 : STATUS_OTP_INVALID_IDX 0xFF000051 : STATUS_OTP_ERROR_READONLY_FIELD
- Examples:
=> otpwrite 577 0xf7cbfee3 0xFFFFFFFF otp operation succeed => otpwrite 578 0x000056e5 0xFFFFFFFF otp operation succeed
Tools to generate OTP commands
It is strongly recommended to use the helper script gen_otp_command.py to generate OTP programming commands instead of writing them by hand.
The tool can be found under Factory repository at
factory/scripts/[klamath]. Where klamath: SL26xx
- Examples: (Klamath: SL26xx)
$sdk/factory/scripts/klamath$ ./gen_otp_command.py
When the command completes, following file will be generated in the current directory:
otp_commands_uboot.txt: U-Boot otpwrite commands
The script performs the following:
- Reads OTP configuration from
configs/oem_config.conf
keys/AES_CCGK.bin
keys/generic/oem/K0_OEM.EC551.pub.pem
A sample configs/oem_config.conf configuration file is shown below
### OEM Configuration File
### This file contains default settings for OTP programming during manufacturing.
### Modify the parameters as needed for your specific OEM requirements.
### Items commented out are optional and can be enabled if required.
[Chip Info]
chip_name = klamath
chip_rev = A0
[Segmentation ID]
oem_segid = 0x4F4C4548
[Version]
oem_version = 0
[Image Production Flag]
Image_production_flag = 1
[OTP_OEM_IMAGE_SECURE_BOOT_EN]
oem_security_enable = 0x10011001
[OTP_OEM_IMAGE_VERSION]
oem_image_version = 0
[OTP_JTAG_ACCESS_CONTROL]
jtag_access_control = 0x00000000
Below is a sample execution log:
$sdk/factory/scripts/klamath/factory$ ./gen_otp_command.py [SKIP] OTP_REE_VERSION is zero; command not generated. [SKIP] OTP_JTAG_ACCESS_CONTROL is zero; command not generated. otpwrite 80 0x92dc58d7 0xffffffff [Atomic] otpwrite 81 0x81a0c5cc 0xffffffff [Atomic] otpwrite 82 0x7b4b0fae 0xffffffff [Atomic] otpwrite 83 0x9dac32a9 0xffffffff [Atomic] otpwrite 84 0xd4a4ea7e 0xffffffff [Atomic] otpwrite 85 0x83596267 0xffffffff [Atomic] otpwrite 86 0xadb93b00 0xffffffff [Atomic] otpwrite 87 0x753ac64c 0xffffffff [Atomic] otpwrite 88 0x2c2f2c42 0xffffffff [Atomic] otpwrite 89 0xf1bee7aa 0xffffffff [Atomic] otpwrite 90 0xbb063fe1 0xffffffff [Atomic] otpwrite 91 0x56cbb296 0xffffffff [Atomic] otpwrite 92 0x4c6c5b6d 0xffffffff [Atomic] otpwrite 93 0xcbca7c34 0xffffffff [Atomic] otpwrite 94 0x8977cb87 0xffffffff [Atomic] otpwrite 95 0xa661193e 0xffffffff [Atomic] otpwrite 112 0x1869752d 0xffffffff [Atomic] otpwrite 113 0x6f143de3 0xffffffff [Atomic] otpwrite 114 0x54884e23 0xffffffff [Atomic] otpwrite 115 0x316736ee 0xffffffff [Atomic] otpwrite 116 0x91cbcdad 0xffffffff [Atomic] otpwrite 117 0xaff45729 0xffffffff [Atomic] otpwrite 118 0x798ebbe7 0xffffffff [Atomic] otpwrite 119 0x18438e6f 0xffffffff [Atomic] otpwrite 131 0x10011001 0xffffffff otpwrite 135 0x4f4c4548 0xffffffff [OK] Wrote 26 commands to otp_commands_uboot.txt
Notes:
- otp_commands_uboot.txt contains commands in the form to perform in u-boot:
otpwrite <idx> <value> <mask>