Skip to content
This repository has been archived by the owner on Oct 1, 2021. It is now read-only.

Merge OTP for factory jig information #62

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 27 additions & 56 deletions src/modules/systemlib/otp.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,78 +71,49 @@ int val_read(void *dest, volatile const void *src, int bytes)
int write_otp(uint8_t id_type, uint32_t vid, uint32_t pid, char *signature)
{

warnx("write_otp: PX4 / %02X / %02lX / %02lX / ... etc \n", id_type, (unsigned long)vid, (unsigned long)pid);
warnx("write_otp: PX4 / %02X / %02X / %02X / ... etc \n", id_type, vid, pid);

int errors = 0;

// descriptor
if (F_write_byte(ADDR_OTP_START, 'P')) {
if (F_write_byte(ADDR_OTP_START, 'P')){
errors++;
}

// write the 'P' from PX4. to first byte in OTP
if (F_write_byte(ADDR_OTP_START + 1, 'X')) {
errors++; // write the 'P' from PX4. to first byte in OTP
}

if (F_write_byte(ADDR_OTP_START + 2, '4')) {
errors++;
}

if (F_write_byte(ADDR_OTP_START + 3, '\0')) {
errors++;
}

}
// write the 'P' from PX4. to first byte in OTP
if (F_write_byte(ADDR_OTP_START + 1, 'X')){
errors++; // write the 'P' from PX4. to first byte in OTP
}
if (F_write_byte(ADDR_OTP_START + 2, '4')){
errors++;
}
if (F_write_byte(ADDR_OTP_START + 3, '\0')){
errors++;
}
//id_type
if (F_write_byte(ADDR_OTP_START + 4, id_type)) {
errors++;
if (F_write_byte(ADDR_OTP_START + 4, id_type)){
}

// vid and pid are 4 bytes each
if (F_write_word(ADDR_OTP_START + 5, vid)) {
errors++;
}

if (F_write_word(ADDR_OTP_START + 9, pid)) {
errors++;
}
if (F_write_word(ADDR_OTP_START + 5, vid)){
errors++;
}
if (F_write_word(ADDR_OTP_START + 9, pid)){
errors++;
}

// leave some 19 bytes of space, and go to the next block...
// then the auth sig starts
for (int i = 0 ; i < 128 ; i++) {
if (F_write_byte(ADDR_OTP_START + 32 + i, signature[i])) {
errors++;
}
if (F_write_byte(ADDR_OTP_START + 32 + i, signature[i])){
errors++;
}
}

return errors;
}

int lock_otp(void)
int lock_otp(int blocknum)
{
//determine the required locking size - can only write full lock bytes */
// int size = sizeof(struct otp) / 32;
//
// struct otp_lock otp_lock_mem;
//
// memset(&otp_lock_mem, OTP_LOCK_UNLOCKED, sizeof(otp_lock_mem));
// for (int i = 0; i < sizeof(otp_lock_mem) / sizeof(otp_lock_mem.lock_bytes[0]); i++)
// otp_lock_mem.lock_bytes[i] = OTP_LOCK_LOCKED;
//XXX add the actual call here to write the OTP_LOCK bytes only at final stage
// val_copy(lock_ptr, &otp_lock_mem, sizeof(otp_lock_mem));

int locksize = 5;

int errors = 0;

// or just realise it's exctly 5x 32byte blocks we need to lock. 1 block for ID,type,vid,pid, and 4 blocks for certificate, which is 128 bytes.
for (int i = 0 ; i < locksize ; i++) {
if (F_write_byte(ADDR_OTP_LOCK_START + i, OTP_LOCK_LOCKED)) {
errors++;
}
}

return errors;
return F_write_byte(ADDR_OTP_LOCK_START + blocknum, OTP_LOCK_LOCKED);
}


Expand Down Expand Up @@ -185,7 +156,7 @@ void F_lock(void)
}

// flash write word.
int F_write_word(unsigned long Address, uint32_t Data)
int F_write_word(uint32_t Address, uint32_t Data)
{
unsigned char octet[4] = {0, 0, 0, 0};

Expand All @@ -200,7 +171,7 @@ int F_write_word(unsigned long Address, uint32_t Data)
}

// flash write byte
int F_write_byte(unsigned long Address, uint8_t Data)
int F_write_byte(uint32_t Address, uint8_t Data)
{
volatile int status = F_COMPLETE;

Expand Down
48 changes: 25 additions & 23 deletions src/modules/systemlib/otp.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ __BEGIN_DECLS
#define OTP_LOCK_LOCKED 0x00
#define OTP_LOCK_UNLOCKED 0xFF


#define OTP_NUM_BLOCKS 16
#define OTP_BLOCK_SIZE 32

#include <unistd.h>
#include <stdint.h>
Expand All @@ -65,33 +66,34 @@ __BEGIN_DECLS
#define F_COMPLETE 5

typedef struct {
volatile unsigned long accesscontrol; // 0x00
volatile unsigned long key; // 0x04
volatile unsigned long optionkey; // 0x08
volatile unsigned long status; // 0x0C
volatile unsigned long control; // 0x10
volatile unsigned long optioncontrol; //0x14
volatile uint32_t accesscontrol; // 0x00
volatile uint32_t key; // 0x04
volatile uint32_t optionkey; // 0x08
volatile uint32_t status; // 0x0C
volatile uint32_t control; // 0x10
volatile uint32_t optioncontrol; //0x14
} flash_registers;

#define PERIPH_BASE ((unsigned long)0x40000000) //Peripheral base address
#define PERIPH_BASE ((uint32_t)0x40000000) //Peripheral base address
#define AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000)
#define F_R_BASE (AHB1PERIPH_BASE + 0x3C00)
#define FLASH ((flash_registers *) F_R_BASE)

#define F_BSY ((unsigned long)0x00010000) //FLASH Busy flag bit
#define F_OPERR ((unsigned long)0x00000002) //FLASH operation Error flag bit
#define F_WRPERR ((unsigned long)0x00000010) //FLASH Write protected error flag bit
#define CR_PSIZE_MASK ((unsigned long)0xFFFFFCFF)
#define F_PSIZE_WORD ((unsigned long)0x00000200)
#define F_PSIZE_BYTE ((unsigned long)0x00000000)
#define F_CR_PG ((unsigned long)0x00000001) // a bit in the F_CR register
#define F_CR_LOCK ((unsigned long)0x80000000) // also another bit.

#define F_KEY1 ((unsigned long)0x45670123)
#define F_KEY2 ((unsigned long)0xCDEF89AB)
#define F_BSY ((uint32_t)0x00010000) //FLASH Busy flag bit
#define F_OPERR ((uint32_t)0x00000002) //FLASH operation Error flag bit
#define F_WRPERR ((uint32_t)0x00000010) //FLASH Write protected error flag bit
#define CR_PSIZE_MASK ((uint32_t)0xFFFFFCFF)
#define F_PSIZE_WORD ((uint32_t)0x00000200)
#define F_PSIZE_BYTE ((uint32_t)0x00000000)
#define F_CR_PG ((uint32_t)0x00000001) // a bit in the F_CR register
#define F_CR_LOCK ((uint32_t)0x80000000) // also another bit.

#define F_KEY1 ((uint32_t)0x45670123)
#define F_KEY2 ((uint32_t)0xCDEF89AB)
#define IS_F_ADDRESS(ADDRESS) ((((ADDRESS) >= 0x08000000) && ((ADDRESS) < 0x080FFFFF)) || (((ADDRESS) >= 0x1FFF7800) && ((ADDRESS) < 0x1FFF7A0F)))


#define F_OTP_BLOCK_PTR(blocknum) ((volatile uint8_t *) (ADDR_OTP_START + OTP_BLOCK_SIZE * (blocknum)))
#define F_OTP_IS_LOCKED(blocknum) (((volatile uint8_t *) ADDR_OTP_LOCK_START)[blocknum] == 0)

#pragma pack(push, 1)

Expand Down Expand Up @@ -141,11 +143,11 @@ __EXPORT void F_lock(void);
__EXPORT int val_read(void *dest, volatile const void *src, int bytes);
__EXPORT int val_write(volatile void *dest, const void *src, int bytes);
__EXPORT int write_otp(uint8_t id_type, uint32_t vid, uint32_t pid, char *signature);
__EXPORT int lock_otp(void);
__EXPORT int lock_otp(int blocknum);


__EXPORT int F_write_byte(unsigned long Address, uint8_t Data);
__EXPORT int F_write_word(unsigned long Address, uint32_t Data);
__EXPORT int F_write_byte(uint32_t Address, uint8_t Data);
__EXPORT int F_write_word(uint32_t Address, uint32_t Data);

__END_DECLS

Expand Down
96 changes: 96 additions & 0 deletions src/systemcmds/otp/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@

nsh> otp
otp: usage:
otp show - show all block contents and lock bitsotp write <blocknum> <32 hex bytes, LSB first, no spaces> <crc32 for bytes> - will print values after readback
otp read <blocknum> - will print 32 bytes readback from block (and the current CRC)
otp lock <blocknum> <blocknum> - will permanently lock the specified block number

# show is intended to be human readable
nsh> otp show
0: L 5058340000ac26000010000000ffffffffffffffffffffffffffffffffffffff 55393c7b
1: L 3296c91156c6a2cd9d472bd768e74ad9c731d43b9180a994f9b927517e41425a e50fcf15
2: L 5207fe5842dd9bcd27f2077759ca977292334e8c366969f3797efaaa6940ad00 26df18c8
3: L c0190f185410e5fd13dce5b37b8f8030ab84e1fa1c026088eb1ee4b224fb662b ae616df5
4: L a800a8110a956c55fe43698fa584e9a1d7f8b10495e3460c1de681c0c7b89875 3245288a
5: U ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e666fea6
6: U ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e666fea6
7: U ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e666fea6
8: U ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e666fea6
9: U ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e666fea6
10: U 5058340000002600001000000000000000000000000000000000000000000000 2fab057d
11: U ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e666fea6
12: U ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e666fea6
13: U ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e666fea6
14: U ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e666fea6
15: U ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e666fea6

# the readback for writing to block 10 failed (OTP bits can _only_ be changed to zero)
# even if unlocked there is NO WAY to change the back to a one. So be careful even
# if testing
nsh> otp write 10 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e666fea6
otp: Write not accepted

# Because of this, we check a crc32 that must be included with each write command
# if wrong we will not do the write
nsh> otp write 10 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e666fea67
otp: CRC does not match bytes

# The _only_ response that indicates success is WRITTEN
# This demonstrates writing ffs
nsh> otp write 11 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e666fea6
WRITTEN

# This demonstrates writing some other string of bytes
nsh> otp write 11 5058340000ac26000010000000ffffffffffffffffffffffffffffffffffffff 55393c7b
WRITTEN

# See the happy bytes now on block 11
nsh> otp show
0: L 5058340000ac26000010000000ffffffffffffffffffffffffffffffffffffff 55393c7b
1: L 3296c91156c6a2cd9d472bd768e74ad9c731d43b9180a994f9b927517e41425a e50fcf15
2: L 5207fe5842dd9bcd27f2077759ca977292334e8c366969f3797efaaa6940ad00 26df18c8
3: L c0190f185410e5fd13dce5b37b8f8030ab84e1fa1c026088eb1ee4b224fb662b ae616df5
4: L a800a8110a956c55fe43698fa584e9a1d7f8b10495e3460c1de681c0c7b89875 3245288a
5: U ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e666fea6
6: U ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e666fea6
7: U ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e666fea6
8: U ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e666fea6
9: U ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e666fea6
10: U 5058340000002600001000000000000000000000000000000000000000000000 2fab057d
11: U 5058340000ac26000010000000ffffffffffffffffffffffffffffffffffffff 55393c7b
12: U ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e666fea6
13: U ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e666fea6
14: U ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e666fea6
15: U ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e666fea6

# To prevent locking incorrect blocks, the block number must be given twice
nsh> otp lock 10
otp: Invalid arguments
otp: usage:
otp show - show all block contents and lock bitsotp write <blocknum> <32 hex bytes, LSB first, no spaces> <crc32 for bytes> - will print values after readback
otp read <blocknum> - will print 32 bytes readback from block (and the current CRC)
otp lock <blocknum> <blocknum> - will permanently lock the specified block number

# The _only_ response that indicates success for the lock command is LOCKED
nsh> otp lock 10 10
LOCKED

# Notice that block 10 is now locked
nsh> otp show
0: L 5058340000ac26000010000000ffffffffffffffffffffffffffffffffffffff 55393c7b
1: L 3296c91156c6a2cd9d472bd768e74ad9c731d43b9180a994f9b927517e41425a e50fcf15
2: L 5207fe5842dd9bcd27f2077759ca977292334e8c366969f3797efaaa6940ad00 26df18c8
3: L c0190f185410e5fd13dce5b37b8f8030ab84e1fa1c026088eb1ee4b224fb662b ae616df5
4: L a800a8110a956c55fe43698fa584e9a1d7f8b10495e3460c1de681c0c7b89875 3245288a
5: U ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e666fea6
6: U ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e666fea6
7: U ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e666fea6
8: U ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e666fea6
9: U ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e666fea6
10: L 5058340000002600001000000000000000000000000000000000000000000000 2fab057d
11: U 5058340000ac26000010000000ffffffffffffffffffffffffffffffffffffff 55393c7b
12: U ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e666fea6
13: U ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e666fea6
14: U ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e666fea6
15: U ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e666fea6
nsh>
43 changes: 43 additions & 0 deletions src/systemcmds/otp/module.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
############################################################################
#
# Copyright (c) 2012, 2013 PX4 Development Team. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name PX4 nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################

#
# OTP program/read/lock utility.
#

MODULE_COMMAND = otp
SRCS = otp.c

MODULE_STACKSIZE = 1800

MAXOPTIMIZATION = -Os
Loading