Прошивка OTP (mcom03-otp)

Общие сведения

Память OTP состоит из 128 ячеек. Каждая ячейка состоит из 40 бит:

  • 32 бита полезных данных;

  • 8 бит избыточности, состав:

    • 6 бит ECC;

    • 2 бита признак инверсии.

Для упрощения терминологии в самой утилите и в данной документации все 8 бит избыточности называются ECC.

Сведения о ECC

Перед записью данных блок OTP автоматически рассчитывает 6 бит ECC. При чтении данных по умолчанию блок OTP автоматически исправляет данные. Может быть исправлен один повреждённый бит в ячейке OTP (независимо от того, где этот повреждённый бит находится - в полезных данных или в 6 битах ECC).

Если для каких-то целей требуется прочитать данные без восстановления, то необходимо использовать аргумент --ecc-disable.

Сведения о BRP

Механизм BRP (Bit Repair by Polarity) позволяет записывать данные и ECC в инвертированном виде. Такая ситуация бывает, если команда bisr обнаружила «протекающий» бит (leaky bit) и явно записала его единицей. В дальнейшем при записи в эту ячейку блок OTP автоматически обнаруживает, что в ячейке уже содержится один ненулевой бит. Если в этот бит необходимо записать ноль, то блок OTP автоматически записывает данные и ECC в инвертированном виде, а также записывает единицы в биты [7:6] избыточности как признак инверсии.

При чтении по умолчанию блок OTP проверяет биты [7:6] избыточности и, если обнаруживает там значение, отличное от нуля, то инвертирует прочитанные данные и ECC. В результате получаются исходные данные и ECC.

Если требуется прочитать данные без обратного инвертирования, то необходимо использовать аргумент --brp-disable.

Принцип работы утилиты

Прошивка и чтение выполняются по интерфейсу UART0: MCom-03 BootROM в режиме загрузки по UART принимает образ otp-flasher, otp-flasher запускается на RISC0, повышает частоты, принимает данные для прошивки по UART, прошивает память OTP.

Внимание

Для следующих команд требуется подача внешнего питания OTP VPP:

  • mcom03-otp program-*

  • mcom03-otp bisr

Запись производится 32-битными словами. Память OTP содержит 128 слов. Поля OTP-памяти, которые описаны в главе 5.6.2 (Область OTP памяти) руководства пользователя на микросхему, в данной утилите называются записями. Список записей можно узнать с помощью команды print-records.

Можно прошивать произвольные ячейки OTP, используя имя word_addr_X, где X — это порядковый номер 32-битной ячейки OTP-памяти. Например, word_addr_123 будет означать 32-битное поле с адресом 123. Размер полей word_addr_X всегда равен 32 битам. Такой механизм необходим для прошивки ячеек, у которых нет своего имени.

Любую запись можно прошивать либо набором байт (см. Команда program-bytes), либо в виде целого беззнакового числа (см. Команда program-integer).

Для всех команд поддерживаются следующие аргументы:

  • --port — имя порта на компьютере, к которому подключен UART. По умолчанию: /dev/ttyUSB0

  • --verbose — если указано, то будет печатать трафик, передаваемый по UART. Предназначен для отладки.

  • -n, --dry-run — если указано, то будет только выводить сообщения в консоль, но реального обращения к OTP не будет. В этом режиме не требуется подключенная плата. Можно использовать для проверки подготавливаемых для записи данных.

  • --flasher — имя файла в формате Intel HEX, который подменяет собой оригинальный otp-flasher. Предназначен для отладки otp-flasher.

Для команд чтения (read и dump) доступны аргументы для указания флагов. Эти флаги предназначены для отладки и тестирования, и не должны указываться при обычной работе:

  • --ecc-disable — не восстанавливать данные/ECC. Этот флаг может потребоваться для корректного отображения результата при использовании других флагов из этого списка.

  • --ecc-generate — рассчитать новый ECC для данных.

  • --ecc-test — вернуть синдром (промежуточный результат во время восстановления данных, по которому можно определить ошибку в данных) вместо ECC.

  • --brp-disable — отключить инвертирование при чтении независимо от признака инверсии в ячейке OTP.

  • --brp-generate — инвертировать данные и ECC при чтении независимо от признака инверсии в ячейке OTP.

Справочник:

$ mcom03-otp --help
usage: mcom03-otp [-h] [-p PORT] [-v] [-f FLASHER] [-n] [--version]
                  {program-integer,program-bytes,program-toml,bist,bisr,read,dump,print-records}
                  ...

positional arguments:
  {program-integer,program-bytes,program-toml,bist,bisr,read,dump,print-records}
    program-integer     Program single record of OTP memory by integer value
    program-bytes       Program single record of OTP memory by raw value
    program-toml        Progream OTP by data from TOML file
    bist                Run BIST for OTP region (check for leaky bits)
    bisr                Run BISR for OTP region (fix for 1 leaky bit per cell)
    read                Read data from OTP and save to file
    dump                Read data from OTP and show all records of OTP
    print-records       Print known OTP records and bitfields

options:
  -h, --help            show this help message and exit
  -p PORT, --port PORT  serial port on host the device UART0 is connected to (default:
                        /dev/ttyUSB0)
  -v, --verbose         show UART traffic (default: False)
  -f FLASHER, --flasher FLASHER
                        path to Intel HEX baremetal application to be executed on RISC0 (use HEX
                        distributed with the tool if not specified) (default: None)
  -n, --dry-run         Only print messages but do not access to OTP (default: False)
  --version             show program's version number and exit

Команда program-integer

Прошивает (с проверкой) одну запись целочисленным беззнаковым значением. Запись указывается по имени. Можно использовать для любых записей, но необходимо учитывать, что при прошивке байты будут записаны в обратном порядке, так как будут приведены к little-endian.

Пример:

mcom03-otp program-integer serial 123456
# или
mcom03-otp program-integer serial 0x1e240
mcom03-otp dump | grep serial  # выведет "serial: 0x1e240 (123456)"

mcom03-otp program-integer duk 0x7e42f8ec980980e904b2008fd98c1dd4
mcom03-otp dump | grep duk"  # выведет "duk: d41d8cd98f00b204e9800998ecf8427e"

Поддерживаются имена word_addr_X для прошивки произвольных ячеек OTP. Например:

mcom03-otp program-integer word_addr_123 0x12345  # записать по адресу 123 число 0x12345

Справочник:

$ mcom03-otp program-integer --help
usage: mcom03-otp program-integer [-h] name value

positional arguments:
  name        Name of record (see 'print-records' command)
  value       Integer value to program. Will write as little-endian.

options:
  -h, --help  show this help message and exit

Команда program-bytes

Прошивает (с проверкой) одну запись произвольными данными, представленными последовательностью тетрад. Размер данных должен быть равен размеру прошиваемой записи. Данные могут быть указаны слитно, либо байты могут быть разделены пробелами.

Распределение по ячейкам при записи:

mcom03-otp program-bytes duk d41d8cd98f00b204e9800998ecf8427e
                             ^^^^^^^^                         ячейка 4
                             ^^                               ячейка 4 биты [7:0]
                               ^^                             ячейка 4 биты [15:8]
                                 ^^                           ячейка 4 биты [23:16]
                                   ^^                         ячейка 4 биты [31:24]
                                     ^^^^^^^^                 ячейка 5
                                             ^^^^^^^^         ячейка 6
                                                     ^^^^^^^^ ячейка 7

Пример:

mcom03-otp program-bytes duk d41d8cd98f00b204e9800998ecf8427e
# или
mcom03-otp program-bytes duk "d4 1d 8c d9 8f 00 b2 04 e9 80 09 98 ec f8 42 7e"
mcom03-otp dump | grep duk  # выведет "duk: d41d8cd98f00b204e9800998ecf8427e"

mcom03-otp program-bytes serial 54657374  # слово "Test"
mcom03-otp dump | grep serial  # выведет "serial: 0x74736554 (1953719636)"

Поддерживаются имена word_addr_X для прошивки произвольных ячеек OTP. Например:

mcom03-otp program-bytes word_addr_123 8899aabb  # записать по адресу 123 байты 88 99 aa bb

Справочник:

$ mcom03-otp program-bytes --help
usage: mcom03-otp program-bytes [-h] name value

positional arguments:
  name        Name of record (see 'print-records' command)
  value       Raw hex data to program (example: 016578616d706c65). First bytes will write to lower
              address (as big-endian)

options:
  -h, --help  show this help message and exit

Команда program-toml

Читает данные из файла TOML и прошивает все ненулевые записи в OTP (с проверкой). Те записи, у которых есть битовые поля, могут быть описаны как просто число, либо как список битовых полей. Например, содержимое:

otp.fuse1.user = 0xf
otp.fuse1.lock_bootrom = 0
otp.fuse1.lock_fw = 0
otp.fuse1.lock = 1

Равносильно содержимому:

otp.fuse1 = 0x8000000f

Поддерживаются имена word_addr_X для прошивки произвольных ячеек OTP. Например:

otp.word_addr_123 = 0x12345678  # записать по смещению 123 число 0x12345678

Если требуется указать недокументированный бит, то его можно указывать в формате reserved_bit_X, где X - это номер бита в записи. Например:

otp.flags.reserved_bit_21 = 1

Пример:

mcom03-otp program-toml file.toml

Справочник:

$ mcom03-otp program-toml --help
usage: mcom03-otp program-toml [-h] [--save-to-bin-file SAVE_TO_BIN_FILE] toml_file

positional arguments:
  toml_file             Name of TOML file

options:
  -h, --help            show this help message and exit
  --save-to-bin-file SAVE_TO_BIN_FILE
                        Also save result to binary image

Команда bist

Запускает внутреннюю проверку OTP. Останавливается с ошибкой, если находит ячейку OTP, которая содержит два или более бита данных или ECC в состоянии «1». Изначально все ячейки OTP должны содержать нулевые значения. Но иногда встречаются «протекающие» биты, которые могут читаться единицами. Проверка предназначена для поиска ячеек, в которых содержится более одного такого бита. Но также она будет срабатывать на любые ячейки, в которых записаны данные и ECC, в которых более одного бита находятся в состоянии «1» (это любое ненулевое значение данных с корректным ECC).

Команда bist не производит никаких изменений и может работать без напряжения Vpp.

Дополнительные аргументы:

  • --addr — адрес, начиная с которого будет проводиться проверка. Значение по умолчанию: 0.

  • --count — количество 32-битных слов для проверки. Если не указано, то до конца памяти OTP.

Пример:

mcom03-otp bist  # проверить всю память OTP
mcom03-otp bist --addr 60  # проверить память OTP, начиная с адреса 60
mcom03-otp bist --addr 60 --count 10  # проверить 10 ячеек памяти OTP, начиная с адреса 60

Справочник:

$ mcom03-otp bist --help
usage: mcom03-otp bist [-h] [--count COUNT] [--addr ADDR]

options:
  -h, --help     show this help message and exit
  --count COUNT  Count of OTP words to process
  --addr ADDR    Process data starting from ADDR (in words)

Команда bisr

Команда аналогична команде bist, но помимо поиска «протекающих» бит, явным образом записывает в них единицу. Команда bisr завершится с ошибкой только, если в одной ячейке будет обнаружено более одного бита в состоянии «1» («подтекающих» или записанных туда явно).

После выполнения команды в ячейке всё равно будет читаться нулевое значение, так как один бит, выставленный в единицу, будет исправляться при чтении с помощью ECC (если при чтении не был указан аргумент --ecc-disable).

Запись в такую ячейку также будет проходить без ошибок, даже если в такой исправленный бит необходимо записать ноль, благодаря механизму bit repair.

Команда bisr предполагает возможность записи, поэтому для её работы требуется напряжение Vpp.

Дополнительные аргументы:

  • --addr — адрес, начиная с которого будет проводиться проверка. Значение по умолчанию: 0.

  • --count — количество 32-битных слов для проверки. Если не указано, то до конца памяти OTP.

Пример:

mcom03-otp bisr  # проверить всю память OTP
mcom03-otp bisr --addr 60  # проверить память OTP, начиная с адреса 60
mcom03-otp bisr --addr 60 --count 10  # проверить 10 ячеек памяти OTP, начиная с адреса 60

Справочник:

$ mcom03-otp bisr --help
usage: mcom03-otp bisr [-h] [--count COUNT] [--addr ADDR]

options:
  -h, --help     show this help message and exit
  --count COUNT  Count of OTP words to process
  --addr ADDR    Process data starting from ADDR (in words)

Команда read

Читает содержимое OTP и сохраняет в файл или выводит в stdout, если имя файла не указано.

Дополнительные аргументы:

  • --output-format — указывает, в каком формате сохранять данные. Возможные значения: text, bin или json. По умолчанию используется формат text.

  • --addr — адрес, начиная с которого будет читать OTP. Значение по умолчанию: 0.

  • --count — количество 32-битных слов для чтения. Если не указано, то до конца памяти OTP.

Пример:

# сохранить всё содержимое OTP в файл
mcom03-otp read --count 128 --output-format bin saved.bin

# сохранить 1 слово (4 байта) по адресу 3 (серийный номер)
mcom03-otp read --addr 3 --count 1 otp-serial.txt

# прочитать 16 слов (64 байта) OTP и отобразить их через утилиту hexdump
mcom03-otp read --count 16 --output-format bin | hexdump -Cv

Справочник:

$ mcom03-otp read --help
usage: mcom03-otp read [-h] [--output-format {text,bin,json}] [--count COUNT] [--addr ADDR]
                       [--ecc-disable] [--ecc-generate] [--ecc-test] [--brp-disable]
                       [--brp-generate]
                       [fname]

positional arguments:
  fname                 File name to save

options:
  -h, --help            show this help message and exit
  --output-format {text,bin,json}
                        Output format
  --count COUNT         Count of OTP words to process
  --addr ADDR           Process data starting from ADDR (in words)
  --ecc-disable         Disable ECC correction
  --ecc-generate        With --ecc-disable will recalc ECC for data
  --ecc-test            Read syndrome instead of ECC
  --brp-disable         Disable invert even if BRP used
  --brp-generate        Force data inversion and ECC even if BRP in not used

Формат text

Каждая строка содержит:

[<адрес>] value: <значение>, ecc: <значение ECC>, correct: <результат проверки ECC>

Например:

[0] value: 0x00000000, ecc: 0x00, correct: True
[1] value: 0x00000000, ecc: 0x00, correct: True
...

Формат bin

В начале файла сохраняются все полезные данные (по 4 байта для каждой ячейки OTP), а в конце файла сохраняются ECC (по 1 байту для каждой ячейки OTP). Например, если использовать аргументы:

mcom03-otp read --addr 70 --count 10 --output-format bin saved.bin

Будет создан файл, в котором содержатся ячейки OTP с 70 по 79. Размер файла будет равен 50 байтам: первые 40 байт - это сами данные, последние 10 байт - это ECC. В бинарном формате результат проверки ECC не сохраняется.

Например, если в ячейках OTP содержатся данные:

[0] value: 0x13121110, ecc: 0x39
[1] value: 0x17161514, ecc: 0x9
[2] value: 0x1B1A1918, ecc: 0x14
[3] value: 0x1F1E1D1C, ecc: 0x24
[4] value: 0x23222120, ecc: 0x3D
[5] value: 0x27262524, ecc: 0xD
[6] value: 0x2B2A2928, ecc: 0x10
[7] value: 0x2F2E2D2C, ecc: 0x20

то при выполнении команды:

mcom03-otp read --count 8 --output-format bin saved.bin

будет создан бинарный файл размером 40 байт с содержимым (hexdump -C saved.bin):

00000000  10 11 12 13 14 15 16 17  18 19 1A 1B 1C 1D 1E 1F   - данные из ячеек 0, 1, 2, 3
00000010  20 21 22 23 24 25 26 27  28 29 2A 2B 2C 2D 2E 2F   - данные из ячеек 4, 5, 6, 7
00000020  39 09 14 24 3D 0D 10 20                            - ECC из ячеек 0...7

Формат json

В качестве индекса используется адрес ячейки OTP. Например, для команды:

mcom03-otp read --addr 70 --count 2 --output-format json

Будет выведено:

{
  "70": {
    "value": 0,
    "ecc": 0,
    "is_correct": true
  },
  "71": {
    "value": 0,
    "ecc": 0,
    "is_correct": true
  }
}

Команда dump

Читает содержимое OTP и выводит в текстовом виде в stdout. Если в недокументированных записях содержатся ненулевые значения, то такие записи называются word_addr_X (где X - адрес OTP) и они выводятся как 32-битное число. Если запись содержит битовые поля и установлены недокументированные биты, то такие биты называет reserved_bit_X (где X - это номер бита в записи).

Дополнительные аргументы:

  • --toml — выводит в формате TOML, который может быть использован для прошивки через команду program-toml.

  • --count — ограничить количество слов OTP для чтения и вывода.

  • --from-file — будет использовать указанный файловый образ вместо реального OTP. В этом случае подключенная плата не требуется.

Пример:

mcom03-otp dump
mcom03-otp dump --toml

Справочник:

$ mcom03-otp dump --help
usage: mcom03-otp dump [-h] [--from-file FROM_FILE] [--toml] [--count COUNT] [--ecc-disable]
                       [--ecc-generate] [--ecc-test] [--brp-disable] [--brp-generate]

options:
  -h, --help            show this help message and exit
  --from-file FROM_FILE
                        If specified then use this binary image file instead of real OTP
  --toml                Output in TOML format
  --count COUNT         Count of OTP words to process
  --ecc-disable         Disable ECC correction
  --ecc-generate        With --ecc-disable will recalc ECC for data
  --ecc-test            Read syndrome instead of ECC
  --brp-disable         Disable invert even if BRP used
  --brp-generate        Force data inversion and ECC even if BRP in not used