Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

Configure Software Protection Unit (SWPU) objects in TRAVEO™ T2G devices - KBA234634

Configure Software Protection Unit (SWPU) objects in TRAVEO™ T2G devices - KBA234634

IFX_Publisher1
Community Manager
Community Manager
Community Manager
250 sign-ins First comment on KBA 250 replies posted

Configure Software Protection Unit (SWPU) objects in TRAVEO™ T2G devices - KBA234634

Community Translation: TRAVEO™ T2Gデバイスのソフトウェアプロテクションユニット(SWPU)オブジェクトを構成する – KBA234634

Version: **

Use Software Protection Unit (SWPU) objects to define flash write (or erase) permissions. To accomplish this, configure SWPU object(s) in supervisory flash (SFLASH) memory of TRAVEO™ T2G by programming the SWPU object parameters to Row 59 of SFLASH.

This KBA explains the following topics:

  1. Organization of SFLASH Row 59
  2. Adding an SWPU/FWPU object to SFLASH Row 59
  3. Programming SFLASH Row 59
  4. Updating the attributes in SRAM
  5. Points to consider when SWPU objects are used in the software

 

  1. Default organization of SFLASH Row 59

The following table shows the default values of the SFLASH Row 59.

Table 1. Default organization of SFLASH Row 59

Row 59

Address

Default

Name

1700_7600

0x30

PU_OBJECT_SIZE

1700_7601

0x00

PU_OBJECT_SIZE

1700_7602

0x00

PU_OBJECT_SIZE

1700_7603

0x00

PU_OBJECT_SIZE

1700_7604

0x00

N_FWPU0

1700_7605

0x00

N_FWPU1

1700_7606

0x00

N_FWPU2

1700_7607

0x00

N_FWPU3

1700_7608

0x01

N_ERPU0

1700_7609

0x00

N_ERPU1

1700_760A

0x00

N_ERPU2

1700_760B

0x00

N_ERPU3

1700_760C

0x68

ERPU0_SL_OFFSET_0

1700_760D

0x00

ERPU0_SL_OFFSET_1

1700_760E

0x00

ERPU0_SL_OFFSET_2

1700_760F

0x00

ERPU0_SL_OFFSET_3

1700_7610

0x18

ERPU0_FUSE_SIZE_0

1700_7611

0x00

ERPU0_FUSE_SIZE_1

1700_7612

0x00

ERPU0_FUSE_SIZE_2

1700_7613

0x80

ERPU0_FUSE_SIZE_3

1700_7614

0x07

ERPU0_SL_ATT_0

1700_7615

0x00

ERPU0_SL_ATT_1

1700_7616

0xFF

ERPU0_SL_ATT_2

1700_7617

0x00

ERPU0_SL_ATT_3

1700_7618

0x07

ERPU0_MS_ATT_0

1700_7619

0x00

ERPU0_MS_ATT_1

1700_761A

0xFF

ERPU0_MS_ATT_2

1700_761B

0x00

ERPU0_MS_ATT_3

1700_761C

0x01

N_EWPU0

1700_761D

0x00

N_EWPU1

1700_761E

0x00

N_EWPU2

1700_761F

0x00

N_EWPU3

1700_7620

0x68

EWPU0_SL_OFFSET_0

1700_7621

0x00

EWPU0_SL_OFFSET_1

1700_7622

0x00

EWPU0_SL_OFFSET_2

1700_7623

0x00

EWPU0_SL_OFFSET_3

1700_7624

0x18

EWPU0_FUSE_SIZE_0

1700_7625

0x00

EWPU0_FUSE_SIZE_1

1700_7626

0x00

EWPU0_FUSE_SIZE_2

1700_7627

0x80

EWPU0_FUSE_SIZE_3

1700_7628

0x07

EWPU0_SL_ATT_0

1700_7629

0x00

EWPU0_SL_ATT_1

1700_762A

0xFF

EWPU0_SL_ATT_2

1700_762B

0x00

EWPU0_SL_ATT_3

1700_762C

0x07

EWPU0_MS_ATT_0

1700_762D

0x00

EWPU0_MS_ATT_1

1700_762E

0xFF

EWPU0_MS_ATT_2

1700_762F

0x00

EWPU0_MS_ATT_3

1700_7630

0x00

App Protection

1700_7631

0x00

App Protection

------------

0x00

App Protection

------------

0x00

App Protection

------------

0x00

App Protection

1700_77FF

0x00

App Protection

 

From the above organization, size of the Row is 512 bytes. Each element in this Row has 1-byte data.

SWPU comprises FWPU (Flash write protection unit), ERPU (eFuse read protection unit) and EWPU (eFuse write protection unit).

Following is the significance of each entry in this Row:

  • PU_OBJECT_SIZE: The first four bytes defines the PU_OBJECT_SIZE which is the total number of configured elements in the Row. In the default configuration, we have a total of 0x30 bytes (including the 4 bytes object size) which starts from 0x1700_7600 to 0x1700_762F.

  • N_FWPU0-3:  These four bytes define the number of FWPU objects added. In the default configuration, there are zero Flash Write Protection Objects added.
  • N_ERPU0-3: These four bytes define the number of ERPUs added. In the default configuration, one ERPU is added.

Since there is one entry for ERPU, the next 16 bytes should indicate the configurations of that ERPU.

  • ERPU0_SL_OFFSET_0-3: Four bytes indicate the offset of the slave address.
  • ERPU0_FUSE_SIZE_0-3: Four bytes indicate the slave size.

Note: The most significant bit (MSB) indicates that the slave region is enabled. Hence the entry is 0x80 for ERPU0_FUSE_SIZE_3.

  • ERPU0_SL_ATT_0-3: These four bytes indicate the Slave Attributes which are arranged as follows:

uint32_t UR                  : 1;

uint32_t PR                  : 1;

uint32_t NS                  : 1;

uint32_t reserved0    : 13;

uint32_t PC_MASK   : 16;

As ERPU0_SL_ATT_0 is 0x07, User Read (UR), Privileged Read (PR) and Non-Secure access (NS) is allowed. As ERPU0_SL_ATT_2 is 0xFF, all eight Protection Contexts (PC’s) can have access.

  • ERPU0_MS_ATT 0-3: These four bytes define the Master Attributes for accessing the slave attributes. The format of these four bytes is the same as that of the Slave Attributes explained before.
  • N_EWPU0-3: These four bytes define the number of EWPUs added. In the default configuration, one EWPU is added.

The next 16 bytes define the configurations of the eFuse Write Protection Object and is similar to that of the eFuse Read Protection Object. The only difference is that the attributes would define the Write Access permissions instead of the Read Access permissions.

uint32_t UW                 : 1;

uint32_t PW                 : 1;

uint32_t NS                  : 1;

uint32_t reserved0    : 13;

uint32_t PC_MASK   : 16;

As EWPU0_SL_ATT_0 is 0x07, User Write (UW), Privileged Write (PW) and Non-Secure access (NS) is allowed. As EWPU0_SL_ATT_2 is 0xFF, all eight PC’s can have access.

2. Adding an FWPU object to this Row

The default SFLASH configurations of Row 59 does not have an entry for FWPU object. The user needs to add an entry.

Let us explain this with an example.

Note: In this example, consider adding an FWPU object within the SWPU (a maximum of 16 FWPU objects can be added).

If the user wants to add one FWPU object, N_FWPU0 should be 0x01. N_FWPU1, N_FWPU2 and N_FWPU3 should be 0x00.

As we have added an entry for FWPU object, the next 16 bytes should define the configurations of that FWPU object. If the user wants to add two FWPU objects, then the next 32 bytes should be used for defining the configurations of the two FWPU objects (16 bytes each).

Let us consider the case in which protection needs to be applied to Sector Number 1 of code flash. This would be the second sector and the address would be 0x1000_0000+ (32*1024) = 0x1000_8000.

Note: For an FWPU object, the absolute 32-bit address needs to be specified. Also, the last two bits should be 0 for alignment purpose.

This means four bytes for slave address shall correspond to 0x00 0x80 0x00 0x10.

As we need to protect this full sector, the slave size shall be 0x8000 and the four bytes for size shall correspond to 0x00 0x80 0x00 0x80.

Note: The fourth byte is 0x80 since the MSB indicates that the region is enabled.

Assuming the case with full access rights for all PCs, we have:

  1. Four bytes of Slave Attributes corresponding to 0x07 0x00 0xFF 0x00
  2. Four bytes of Master Attributes corresponding to 0x07 0x00 0xFF 0x00

Note: The configuration of attributes is dependent on the protection requirements of the application.

Considering all these entries, the new configuration of Row 59 looks like the one shown in the following table:

Table 2: Modified organization of SFLASH Row 59

Row 59

Address

Default

Name

1700_7600

0x40

PU_OBJECT_SIZE

1700_7601

0x00

PU_OBJECT_SIZE

1700_7602

0x00

PU_OBJECT_SIZE

1700_7603

0x00

PU_OBJECT_SIZE

1700_7604

0x01

N_FWPU0

1700_7605

0x00

N_FWPU1

1700_7606

0x00

N_FWPU2

1700_7607

0x00

N_FWPU3

1700_7608

0x00

FWPU0_SL _0

1700_7609

0x80

FWPU0_SL _1

1700_760A

0x00

FWPU0_SL _2

1700_760B

0x10

FWPU0_SL _3

1700_760C

0x00

FWPU0_SIZE_0

1700_760D

0x80

FWPU0_SIZE_1

1700_760E

0x00

FWPU0_SIZE_2

1700_760F

0x80

FWPU0_SIZE_3

1700_7610

0x07

FWPU0_SL_ATT_0

1700_7611

0x00

FWPU0_SL_ATT_1

1700_7612

0xFF

FWPU0_SL_ATT_2

1700_7613

0x00

FWPU0_SL_ATT_3

1700_7614

0x07

FWPU0_MS_ATT_0

1700_7615

0x00

FWPU0_MS_ATT_1

1700_7616

0xFF

FWPU0_MS_ATT_2

1700_7617

0x00

FWPU0_MS_ATT_3

1700_7618

0x01

N_ERPU0

1700_7619

0x00

N_ERPU1

1700_761A

0x00

N_ERPU2

1700_761B

0x00

N_ERPU3

1700_761C

0x68

ERPU0_SL_OFFSET_0

1700_761D

0x00

ERPU0_SL_OFFSET_1

1700_761E

0x00

ERPU0_SL_OFFSET_2

1700_761F

0x00

ERPU0_SL_OFFSET_3

1700_7620

0x18

ERPU0_FUSE_SIZE_0

1700_7621

0x00

ERPU0_FUSE_SIZE_1

1700_7622

0x00

ERPU0_FUSE_SIZE_2

1700_7623

0x80

ERPU0_FUSE_SIZE_3

1700_7624

0x07

ERPU0_SL_ATT_0

1700_7625

0x00

ERPU0_SL_ATT_1

1700_7626

0xFF

ERPU0_SL_ATT_2

1700_7627

0x00

ERPU0_SL_ATT_3

1700_7628

0x07

ERPU0_MS_ATT_0

1700_7629

0x00

ERPU0_MS_ATT_1

1700_762A

0xFF

ERPU0_MS_ATT_2

1700_762B

0x00

ERPU0_MS_ATT_3

1700_762C

0x01

N_EWPU0

1700_762D

0x00

N_EWPU1

1700_762E

0x00

N_EWPU2

1700_762F

0x00

N_EWPU3

1700_7630

0x68

EWPU0_SL_OFFSET_0

1700_7631

0x00

EWPU0_SL_OFFSET_1

1700_7632

0x00

EWPU0_SL_OFFSET_2

1700_7633

0x00

EWPU0_SL_OFFSET_3

1700_7634

0x18

EWPU0_FUSE_SIZE_0

1700_7635

0x00

EWPU0_FUSE_SIZE_1

1700_7636

0x00

EWPU0_FUSE_SIZE_2

1700_7637

0x80

EWPU0_FUSE_SIZE_3

1700_7638

0x07

EWPU0_SL_ATT_0

1700_7639

0x00

EWPU0_SL_ATT_1

1700_763A

0xFF

EWPU0_SL_ATT_2

1700_763B

0x00

EWPU0_SL_ATT_3

1700_763C

0x07

EWPU0_MS_ATT_0

1700_763D

0x00

EWPU0_MS_ATT_1

1700_763E

0xFF

EWPU0_MS_ATT_2

1700_763F

0x00

EWPU0_MS_ATT_3

1700_7640

0x00

App Protection

1700_7641

0x00

App Protection

------------

0x00

App Protection

------------

0x00

App Protection

------------

0x00

App Protection

1700_77FF

0x00

App Protection

 

Note:

  1. The new entries added are marked in green.
  2. The default protection configurations of eFuse is pushed down.
  1. Programming Row 59

First set up the data that needs to be programmed to Row 59 according to the row organization explained above. User can use “Write ROW” SROM API to program the data to Row 59 of SFLASH. See the device architecture TRM for details on how to use this SROM API.

Note: The user may also prepare a HEX or ELF file and use any programmer tool to program the data object. Programmer tools can also trigger WriteRow system call.

  1. Updating the attributes in SRAM

The SWPU configurations in SFLASH is copied to dedicated SRAM (first 2KB of SRAM0 which is protected) during the TRAVEO™ T2G internal boot process. The attributes in SRAM shall be used for protection of the corresponding flash or eFuse region. These attributes in SRAM can also be updated using the “Write SWPU” SROM API (if needed):

The FWPUs, ERPUs and EWPUs are copied from SFLASH into SRAM in the following order:

- FWPUs for Boot
- FWPUs for Application
- ERPUs for Boot
- ERPUs for Application
- EWPUs for Boot
- EWPUs for Application.

The indexing starts at 0 from top to bottom. This should be considered when giving the PU ID, for “Write SWPU” or “Read SWPU” SROM APIs.

In the above example, the PU ID for the FWPU object added is 0. If user does not want to update the attributes in SRAM using “Write SWPU” SROM API, user can still use the already programmed attributes in SFLASH as the same copy  is available in SRAM. 

Note: TRAVEO™ T2G internal boot configures 0 FWPU, 1 ERPU and 1 EWPU.

  1. Points to consider when SWPU objects are used in the software

    1. The address configured for the SWPU objects (For example, address of FWPU objects) should be arranged in the increasing order.
    2. 
    If an SWPU object entry overlaps with a previous object entry, then this entry is skipped that is, only the lowest SWPU object ID will be retained.
    3. If NC ECC fault(s) are pending in the SRAM controller #0 and SWPUs are populated in the design, then Flash and eFuse system calls (For example, BlowFuseBit and ProgramRow.) will return a misleading status of 0xf0000005 ("Page is write protected") even for the non-protected row or 0xf0000002 ("Invalid Fuse address") for valid eFuse address. To work around this problem, if the NC ECC fault(s) are not due to hardware malfunction (That is, if the faults are due to usage of non-initialized SRAM or improper SRAM initialization), then clearing of these pending faults will resolve the issue. Pending faults can be cleared by making use of any of the Fault Structures. An example code that can be used to clear the pending faults is listed as follows:

#define REG32(addr) ( *( (volatile uint32_t *)(addr) ) )
#define FAULT_STRUCT_NUM 0
#define FAULT_STRUCT_PENDING1_ADDR(struct) (0x40210044U + ((struct) * 0x0100U))
#define RAMC0_NC_ECC_MASK (0x08000000U)
#define FAULT_STRUCT_MASK1_ADDR(struct) (0x40210054U + ((struct) * 0x0100U))
#define FAULT_STRUCT_STATUS_ADDR(struct) (0x4021000CU + ((struct) * 0x0100U))
/*
 * Clears pending NC ECC of SRAM Controller 0
 * Here FAULT_STRUCT_NUM is the number of any unused FAULT Structure set in FAULT_STRUCT_NUM define
 */
void Clear_SRAM_NC_ECC()
{
   /* preserve value of Fault mask1 register*/
   /* it is needed only if RAMC0_NC_ECC should not be present in FAULT MASK1 register*/
   uint32_t mask_bkp = REG32(FAULT_STRUCT_MASK1_ADDR(FAULT_STRUCT_NUM));
   /* check if there is pending RAMC0_NC_ECC */
   if (REG32(FAULT_STRUCT_PENDING1_ADDR(FAULT_STRUCT_NUM)) & RAMC0_NC_ECC_MASK)
   {
    /* set Fault mask to pass the fault from Pending to Status register*/
    /* if it is acceptable to have RAMC0_NC_ECC fault masked whole time then the instruction should be moved
        outside from the routine to be performed only once. Also preserve and restore of FAULT_STRUCT_MASK1
       register should be removed */
    REG32(FAULT_STRUCT_MASK1_ADDR(FAULT_STRUCT_NUM)) |= RAMC0_NC_ECC_MASK;
    do
    {
      /* Clear Fault Status register to receive next masked pending fault*/
      REG32(FAULT_STRUCT_STATUS_ADDR(FAULT_STRUCT_NUM)) = 0;
    }
    /* repeat until all pending RAMC0_NC_ECC are cleared */
    while (REG32(FAULT_STRUCT_PENDING1_ADDR(FAULT_STRUCT_NUM)) & RAMC0_NC_ECC_MASK);
   }
   /* restore value of Fault mask1 register*/
   /* it is only needed if it was preserved earlier */
   REG32(FAULT_STRUCT_MASK1_ADDR(FAULT_STRUCT_NUM)) = mask_bkp;
}

423 Views