3.3.6 Querying the hardware resource for register information

The register information is organized hierarchically. The caller must query this hierarchy to obtain information on a specific register.

Figure 3-2 Register organization
To view this graphic, your browser must support the SVG format. Either install a browser with native support, or install an appropriate plugin such as Adobe SVG Viewer.


The first step is to examine the information that the target features provide. It contains the number of available register groups. Calling CADIRegGetGroups() for a specific group retrieves more detailed information. The call scheme is similar to a typical one.

Register groups are groups of registers that, for example, provide a dedicated functionality such as separating integer and floating point registers or that are used in a specific user mode. A register can be part of more than one register group.

Note:

Register IDs must be unique within a target component.

After obtaining the register group information, you query the register map for a register group by calling CADIRegGetMap(). In contrast to a typical call scheme, this method additionally receives the register group ID specified in CADIRegGroupt_t.

This data structure holds the number of registers that are assigned to this group. The correct size can be determined and used for the forwarded array. The result of this call is an array containing more detailed information on all registers available from this group.

To retrieve the information on all registers of a target component, the caller might iterate over all register groups and call CADIRegGetMap(), resulting in a concatenated list.

A register might, however, be part of more than one register group, and the resulting list might have multiple entries for the same register.

Accessing register information
// "cadi" points to a CADI 2.0 interface.
eslapi::CADITargetFeatures_t target_features;
eslapi::CADIReturn_t status;
status = cadi->CADIXfaceGetFeatures(&target_features);
// ...check status and do some setup stuff...
eslapi::CADIRegGroup_t* reg_groups =
         new eslapi::CADIRegGroup_t[target_features.nrRegisterGroups]();
uint32_t groupIndex = 0;
uint32_t actualNumOfRegGroups = 0;
status = cadi->CADIRegGetGroups(groupIndex,
                                target_features.nrRegisterGroups,
                                &actualNumOfRegGroups,
                                reg_groups);
// ...check status...
for (uint32_t regCnt = 0; regCnt < actualNumOfRegGroups; regCnt++)
{
   uint32_t startRegisterIndex = 0;
   uint32_t desiredNumOfRegisters = reg_groups[regCnt].numRegsInGroup;
   uint32_t actualNumOfRegisters = 0;
   eslapi::CADIRegInfo_t* reg =
                     new eslapi::CADIRegInfo_t[desiredNumOfRegisters]();
   status = cadi->CADIRegGetMap(reg_groups[regCnt].groupID,
                                startRegisterIndex, desiredNumOfRegisters,
                                &actualNumOfRegisters, reg);
   // ...check status and use the obtained register information...
   delete[] reg;
}
delete[] reg_groups;
// ...

An alternative, and much more convenient, way to obtain all register information is to call CADIRegGetMap() with CADI_REG_ALLGROUPS as register group ID. This alternative also eliminates redundant entries.

To allocate an array of an appropriate size, the caller can either roughly estimate the required number or sum up the number of registers for each register group. The method must result in an array that is larger than (if there are multiple entries) or equal to the required size:

Alternative method to obtain register information
// ...
eslapi::CADIReturn_t status;
eslapi::CADIRegGroup_t* reg_groups =
       new eslapi::CADIRegGroup_t[target_features.nrRegisterGroups]();
uint32_t groupIndex = 0;
uint32_t actualNumOfRegGroups = 0;
status = cadi->CADIRegGetGroups(groupIndex, target_features.nrRegisterGroups,
                                &actualNumOfRegGroups, reg_groups);
// ...check status...
uint32_t startRegisterIndex = 0;
uint32_t actualNumOfRegisters = 0;
uint32_t numOfAllRegisters = 0;
for (uint32_t regCnt = 0; regCnt < actualNumOfRegGroups; regCnt++)
{
   //sum up the numbers of registers in the register groups
   numOfAllRegisters += reg_groups[regCnt].numRegsInGroup;
}
// Allocated array is large enough for all registers.
eslapi::CADIRegInfo_t* all_registers =
                       new eslapi::CADIRegInfo_t[numOfAllRegisters]();
status = cadi->CADIRegGetMap(eslapi::CADI_REG_ALLGROUPS, startRegisterIndex,
                             numOfAllRegisters, &actualNumOfAllRegisters,
                             all_registers);
// ...check status and do something with all_registers...
delete[] all_registers;
delete[] reg_groups;
// ...

CADI supports compound registers. Compound registers are composed of several other registers. For example, a 32-bit integer register might be composed of two 16-bit integer registers whose interpretation depends on the configuration of the processor.

A compound register is treated like any other register of the CADI interface. It can be directly used to read or write contents. It is also possible to manipulate an individual register in a compound register. You can use the CADIRegGetCompound() method to retrieve a list with the IDs for the component registers. It applies the typical query scheme and receives the compound registers ID as an additional parameter.

Note:

The number of components in a compound register is accessible through a union in CADIRegDetails_t data object of a CADIRegInfo_t.
Determining the number of compound registers
// cadi is a pointer to a cadi 2.0 interface.
// registerInfos is an array of CADIRegInfo_t of length actualNumOfRegisters,
// obtained from a call to CADI::CADIRegGetMap().
for(uint32_t i=0; i < actualNumOfRegisters; i++)
{
    if (registerInfos[i].details.type == eslapi::CADI_REGTYPE_Compound)
    {        
        uint32_t desiredNumOfComponents;
        desiredNumOfComponents = (uint32_t)registerInfos[i].details.u.compound.count;
        uint32_t actualNumOfComponents = 0;
        uint32_t *components = new uint32_t[desiredNumOfComponents]();
        cadi->CADIRegGetCompound(registerInfos[i].regNumber,0,desiredNumOfComponents,
                                        &actualNumOfComponents, components);
        for (uint32_t j = 0; j < actualNumOfComponents; j++)
        {
            // Do something with components.
        }
    }
}

Note:

A set of registers must not form a cyclic graph. A compound register must not be the parent of another compound register that directly or implicitly points back to the parent.
Non-ConfidentialPDF file icon PDF versionARM 100963_0200_00_en
Copyright © 2014–2017 ARM Limited or its affiliates. All rights reserved.