3.4. Accessing registers

This section describes how to access registers in the target.

CADIRegRead() and CADIRegWrite() are used to access registers and process an array of accesses with elements of type CADIReg_t. The elements of the array:

Example 3.5 shows one way to implement a read access to a register with a width of 512 bits:

Example 3.5. Accessing registers in the target

//"register_info" is a CADIRegInfo_t representing a register with a
//bitwidth of 512 bits, reading and displaying the register's contents;
//"cadi" is a pointer to a CADI object

uint32_t regCount = (register_info.bitsWide + 127)/128;
uint32_t regWidthInBytes = (register_info.bitsWide + 7)/8;
eslapi::CADIReg_t* reg = new eslapi::CADIReg_t[regCount]();

for (uint32_t i = 0; i < regCount; i++)
{
   reg[i].regNumber = register_info.regNumber;
   reg[i].offset128 = i;
   reg[i].isUndefined = false;
   reg[i].attribute = register_info.attribute;
   memset(reg[i].bytes, 0, sizeof(uint8_t) * 16);
}

uint32_t numOfRegsWritten = 0;
eslapi::CADIReturn_t status = 
      cadi->CADIRegRead(regCount, reg, &numOfRegsWritten, 
                        0 /* no side effects */); 

//...check status...

if (numOfRegsWritten > 0)
{
   printf("0x");
}

//start with the most significant bits to bring it in a
//readable form
for (uint32_t i = 0; i < numOfRegsWritten; i++)
{
   uint8_t currentBuffer = reg[numOfRegsWritten - 1 - i].bytes;
   uint32_t bytesInBuffer =
                     regWidthInBytes - ((numOfRegsWritten - 1 - i) * 16);
   if (bytesInBuffer >= 16)
      bytesInBuffer = 16;

   for (uint32_t j = bytesInBuffer; j > 0; j--)
   {
      printf("%02x", currentBuffer[j-1]);
   }
}

delete[] reg;

In addition to the forwarded array of CADIReg_t data objects, the number of requested accesses is passed as regCount. The number of successful register accesses is returned in the numRegsRead (or numRegWritten) parameter.

Note

The contents of the CADIReg_t data buffer must be accessed in little endian, even if the target uses a different endianess. That is, the element with the smallest index of the buffer array contains the least significant byte (LSB). This implicitly means that the access with offset 0, for registers wider than 128 bytes, addresses the 16 LSBs.

The caller sets the doSideEffects parameter to specify whether the target must perform side effects associated with the access:

CADIRegRead() might have a side effect for a clear-on-read. Typically, a target must omit all side effects for a read access if the doSideEffects parameter is set to false. This corresponds to a debug read that must not interfere with the execution of the target.

A possible side effect for a write access to a register by CADIRegWrite() would be triggering an interrupt. For a write access, the target can decide which side effects to perform. It might be for example necessary to change the mode of a processor according to the contents of a register even if doSideEffects is set to false.

Copyright © 2008-2014 ARM. All rights reserved.ARM DUI 0444M
Non-ConfidentialID051314