[PATCH v2] eng: Add register block specification types

Sebastian Huber sebastian.huber at embedded-brains.de
Wed Mar 22 16:59:18 UTC 2023


Hello Chris,

I would like to come back to this topic, because it blocks the 
integration of the sparc/gr712rc and sparc/gr740 changes we have done 
for the pre-qualification activity.

On 27.09.21 02:23, Chris Johns wrote:
> On 24/9/21 11:09 pm, Sebastian Huber wrote:
>> A register block may be used to specify the interface of devices which
>> use a linear address space.  Register blocks consist of register block
> 
> Can we please move away from the "linear address" in the definitions? As stated
> previously it only serves a specialized version of a bus and register-block.
> What about something like this:
> 
> A register block specifies a word addressable set of elements in a device
> software is required to access and manipulate. The mechanics software uses to
> access a register element in a register-block is defined by the bus-interface.
> The software and register may be a direct coupling to the CPU bus as found in a
> linear cache coherent memory mapped device or the access may be indirect through
> a bus hierarchy that may require more than one software action to complete.
> Device and register specifications are independent of the CPU architecture and
> connecting bus architectures.

A linear address space is just an address space in which a single 
integer is sufficient to address something. So a word addressable set of 
elements in a device is a linear address space. In contrast to for 
example the AArch32 system register space, which uses a coprocessor 
index, Opcode_1, CRn, CRm, and Opcode_2. An address space granule is the 
smallest block of memory that can be addressed. This could be a subword 
depending on what a word is and the bus system capabilities.

The offsets in the register block specification are just the offset you 
find in the corresponding datasheet.

> 
> I know this is just the commit message but I think this should be in the manual.
> 
> bus-interface:
> 
> A bus interface is the mechanics software uses to access a register word element
> in a device. A bus interface specifies the requirements needed by software to
> access a register word. It must consider timing, CPU word size to device word
> size, byte ordering for word sizes greater than 8bits, cache considerations and
> sequencing of multiple software accesses if required.
> 
> I would like to see a bus-interface section and the device reference it. It only
> needs to cover the type of bus interface you need to specify at this point in time.

At the moment I just have a header file generator for memory-mapped 
devices. I don't think there will be major issues to adopt the generator 
to output interfaces for some bus space API.

> 
>> use a linear address space.
>> members specified by the ``definition`` attribute.  Register block
>> members are either instances of registers specified by the ``registers``
>> attribute or instances of other register blocks specified by links with
>> the "register-block-include" link role.  Registers consists of bit
>> fields.
> 
> Registers are defined in terms of the device word size. The bus interface needs
> to deal with the CPU word size to device word size.

I don't think that a single "word size" is sufficient. A device may have 
registers of different sizes. For example an array of 8-bit registers 
with priorities and a 32-bit status register. Some devices may only have 
64-bit registers, so here using a "word" makes sense, but not in the 
general case.

> 
> Is the bit ordering the CPU architecture order or some other form of ordering?

It would be up to a bus interface specification to deal with bit 
orderings. For an isolated register block specification the bit ordering 
should match with the datasheet.

> 
> The register block members are placed into the address space of
>> the device relative to the base address of the register block.  Register
>> member offests and the register block size are specified in units of the
>> address space granule.  The address space granule is usually 8-bits also
>> known as one byte.
> 
> This paragraph would be much simpler and clearer if defined in terms of a bus
> interface. The use of "usually" could be avoided.

Ok, I will move the "usually" stuff to a paragraph which states what the 
abstract terms mean if you have a memory-mapped device.

> 
>>
>> Update #3715.
>> ---
>> For examples see:
>>
>> https://git.rtems.org/rtems-central/tree/spec/dev/grlib/if
>>
>> v2:
>>
>> Clarify wording and remove the "register-block-type" attribute.
>>
>>   eng/req/items.rst | 322 ++++++++++++++++++++++++++++++++++++++++++++++
>>   1 file changed, 322 insertions(+)
>>
>> diff --git a/eng/req/items.rst b/eng/req/items.rst
>> index e1b64b6..924e79d 100644
>> --- a/eng/req/items.rst
>> +++ b/eng/req/items.rst
>> @@ -103,6 +103,8 @@ The specification item types have the following hierarchy:
>>   
>>       * :ref:`SpecTypeInterfaceVariableItemType`
>>   
>> +    * :ref:`SpecTypeRegisterBlockItemType`
>> +
>>     * :ref:`SpecTypeRequirementItemType`
>>   
>>       * :ref:`SpecTypeFunctionalRequirementItemType`
>> @@ -1143,6 +1145,8 @@ This type is refined by the following types:
>>   
>>   * :ref:`SpecTypeInterfaceVariableItemType`
>>   
>> +* :ref:`SpecTypeRegisterBlockItemType`
>> +
>>   .. _SpecTypeApplicationConfigurationGroupItemType:
>>   
>>   Application Configuration Group Item Type
>> @@ -1615,6 +1619,68 @@ name
>>   notes
>>       The attribute value shall be an :ref:`SpecTypeInterfaceNotes`.
>>   
>> +.. _SpecTypeRegisterBlockItemType:
>> +
>> +Register Block Item Type
>> +^^^^^^^^^^^^^^^^^^^^^^^^
>> +
>> +This type refines the :ref:`SpecTypeInterfaceItemType` through the
>> +``interface-type`` attribute if the value is ``register-block``.
> 
> bus-interface rather than interface-type?
> 
>> This set of
>> +attributes specifies a register block.  A register block may be used to specify
>> +the interface of devices which use a linear address space.
> 
> How about ...
> 
> A register block is a set of bus interface addressable device words. Offset
> values are relative to the device's address bus.
> 
>>   Register blocks
>> +consist of register block members specified by the ``definition`` attribute.
>> +Register block members are either instances of registers specified by the
>> +``registers`` attribute or instances of other register blocks specified by
>> +links with the :ref:`SpecTypeRegisterBlockIncludeRole`.  Registers consists of
>> +bit fields (see :ref:`SpecTypeRegisterBitsDefinition`.  The register block
>> +members are placed into the address space of the device relative to the base
>> +address of the register block.
> 
> This should be part of the bus-interface not the register block.

What I would like to specify is a set of registers. Each register has an 
address and contains a set of bits. I really don't understand what is 
the point with the bus interface here. All the datasheets I have seen so 
far use one or more integers (or enumerators) to identify a register and 
a registers contains a certain amount of bits. I used this register 
block specification also for network switches which are accessed through 
SPI.

> 
>> Register member offests and the register block
>> +size are specified in units of the address space granule. The address space
>> +granule is usually 8-bits also known as one byte. All explicit attributes shall
>> +be specified.
> 
> This may only be true for a linear memory mapped cache coherent bus-interface.
> The register block spec becomes much simpler with the introduction of a bus
> interface construct as most of these words could be removed.
> 
> And for you the bus-interface is simply "linear memory mapped cache coherent"
> and in that you only need a simple statement on CPU word to device word mapping,
> ie 1:1, the timing, ie timing is controlled by the CPU bus interface, and cache
> coherence, ie the mapped address space needs to be cache coherent.
> 
> An important aspect of this approach to the specification is the implementation
> is not detailed and if you wish to implement volatile structs and pointers
> (<shudder>) or alternatively inline functions you can. The specification is the
> same.

I don't see a restriction here with the current specification approach. 
You can use a register bock specification and generate code for a 
particular bus system. You just have to know the bus system.

> 
>> The explicit attributes for this type are:
>> +
>> +brief
>> +    The attribute value shall be an :ref:`SpecTypeInterfaceBriefDescription`.
>> +
>> +definition
>> +    The attribute value shall be a list. Each list element shall be a
>> +    :ref:`SpecTypeRegisterBlockMemberDefinitionDirective`.
>> +
>> +description
>> +    The attribute value shall be an :ref:`SpecTypeInterfaceDescription`.
>> +
>> +identifier
>> +    The attribute value shall be an :ref:`SpecTypeInterfaceGroupIdentifier`.
>> +
>> +name
>> +    The attribute value shall be a string. It shall be the name of the register
>> +    block.
>> +
>> +notes
>> +    The attribute value shall be an :ref:`SpecTypeInterfaceNotes`.
>> +
>> +register-block-group
>> +    The attribute value shall be a string. It shall be the name of the
>> +    interface group defined for the register block.  For the group identifier
>> +    see the ``identifier`` attribute.
>> +
>> +register-block-size
>> +    The attribute value shall be an integer number. It shall be the size of the
>> +    register block in units of the address space granule.
> 
> Signed or unsigned? I only ask because it seems the ability to have a negative
> integer value does not make sense. Does signed require testing of this?

Ok, I can review the integers in the documentation and add 
signed/unsigned if necessary.

> 
>> +
>> +register-prefix
>> +    The attribute value shall be an optional string. If the value is present,
>> +    then it will be used to prefix register bit field names, otherwise the
>> +    value of the ``name`` attribute will be used.
>> +
>> +registers
>> +    The attribute value shall be a list. Each list element shall be a
>> +    :ref:`SpecTypeRegisterDefinition`.
>> +
>> +In addition to the explicit attributes, generic attributes may be specified.
>> +Each generic attribute key shall be a :ref:`SpecTypeName`. The attribute value
>> +may have any type.
>> +
>>   .. _SpecTypeRequirementItemType:
>>   
>>   Requirement Item Type
>> @@ -3857,6 +3923,12 @@ This type is used by the following types:
>>   
>>   * :ref:`SpecTypeInterfaceVariableItemType`
>>   
>> +* :ref:`SpecTypeRegisterBitsDefinition`
>> +
>> +* :ref:`SpecTypeRegisterBlockItemType`
>> +
>> +* :ref:`SpecTypeRegisterDefinition`
>> +
>>   .. _SpecTypeInterfaceCompoundDefinitionKind:
>>   
>>   Interface Compound Definition Kind
>> @@ -4116,6 +4188,12 @@ This type is used by the following types:
>>   
>>   * :ref:`SpecTypeInterfaceVariableItemType`
>>   
>> +* :ref:`SpecTypeRegisterBitsDefinition`
>> +
>> +* :ref:`SpecTypeRegisterBlockItemType`
>> +
>> +* :ref:`SpecTypeRegisterDefinition`
>> +
>>   .. _SpecTypeInterfaceEnabledByExpression:
>>   
>>   Interface Enabled-By Expression
>> @@ -4165,6 +4243,10 @@ This type is used by the following types:
>>   
>>   * :ref:`SpecTypeInterfaceFunctionDefinitionVariant`
>>   
>> +* :ref:`SpecTypeRegisterBitsDefinitionVariant`
>> +
>> +* :ref:`SpecTypeRegisterBlockMemberDefinitionVariant`
>> +
>>   .. _SpecTypeInterfaceEnumDefinitionKind:
>>   
>>   Interface Enum Definition Kind
>> @@ -4306,6 +4388,8 @@ This type is used by the following types:
>>   
>>   * :ref:`SpecTypeInterfaceGroupItemType`
>>   
>> +* :ref:`SpecTypeRegisterBlockItemType`
>> +
>>   .. _SpecTypeInterfaceGroupMembershipLinkRole:
>>   
>>   Interface Group Membership Link Role
>> @@ -4372,6 +4456,8 @@ This type is used by the following types:
>>   
>>   * :ref:`SpecTypeInterfaceVariableItemType`
>>   
>> +* :ref:`SpecTypeRegisterBlockItemType`
>> +
>>   .. _SpecTypeInterfaceParameter:
>>   
>>   Interface Parameter
>> @@ -4537,6 +4623,8 @@ This type is refined by the following types:
>>   
>>   * :ref:`SpecTypePlacementOrderLinkRole`
>>   
>> +* :ref:`SpecTypeRegisterBlockIncludeRole`
>> +
>>   * :ref:`SpecTypeRequirementRefinementLinkRole`
>>   
>>   * :ref:`SpecTypeRequirementValidationLinkRole`
>> @@ -4585,6 +4673,10 @@ This type is used by the following types:
>>   
>>   * :ref:`SpecTypeNonFunctionalRequirementItemType`
>>   
>> +* :ref:`SpecTypeRegisterBlockItemType`
>> +
>> +* :ref:`SpecTypeRegisterDefinition`
>> +
>>   * :ref:`SpecTypeRequirementItemType`
>>   
>>   * :ref:`SpecTypeRootItemType`
>> @@ -4626,6 +4718,236 @@ value is ``placement-order``. This link role defines the placement order of
>>   items in a container item (for example an interface function in a header file
>>   or a documentation section).
>>   
>> +.. _SpecTypeRegisterBitsDefinition:
>> +
>> +Register Bits Definition
>> +^^^^^^^^^^^^^^^^^^^^^^^^
>> +
>> +A value of this type shall be of one of the following variants:
>> +
>> +* The value may be a set of attributes. This set of attributes specifies
>> +  register bits. All explicit attributes shall be specified. The explicit
>> +  attributes for this type are:
>> +
>> +  access
>> +      The attribute value shall be a list of strings. It shall be the list of
>> +      access attributes.
>> +
>> +  brief
>> +      The attribute value shall be an :ref:`SpecTypeInterfaceBriefDescription`.
>> +
>> +  description
>> +      The attribute value shall be an :ref:`SpecTypeInterfaceDescription`.
>> +
>> +  name
>> +      The attribute value shall be a string. It shall be the name of the
>> +      register bit field.
>> +
>> +  start
>> +      The attribute value shall be an integer number. It shall be the start bit
>> +      of the bit field.  Bit ``0`` is the least-significant bit.
>> +
>> +  width
>> +      The attribute value shall be an integer number. It shall be the width in
>> +      bits of the bit field.
>> +
>> +* There may be no value (null).
>> +
>> +This type is used by the following types:
>> +
>> +* :ref:`SpecTypeRegisterBitsDefinitionDirective`
>> +
>> +* :ref:`SpecTypeRegisterBitsDefinitionVariant`
>> +
>> +.. _SpecTypeRegisterBitsDefinitionDirective:
>> +
>> +Register Bits Definition Directive
>> +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>> +
>> +This set of attributes specifies a register bits directive. All explicit
>> +attributes shall be specified. The explicit attributes for this type are:
>> +
>> +default
>> +    The attribute value shall be a list. Each list element shall be a
>> +    :ref:`SpecTypeRegisterBitsDefinition`. The default definition will be used
>> +    if no variant-specific definition is enabled.
>> +
>> +variants
>> +    The attribute value shall be a list. Each list element shall be a
>> +    :ref:`SpecTypeRegisterBitsDefinitionVariant`.
>> +
>> +This type is used by the following types:
>> +
>> +* :ref:`SpecTypeRegisterDefinition`
>> +
>> +.. _SpecTypeRegisterBitsDefinitionVariant:
>> +
>> +Register Bits Definition Variant
>> +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>> +
>> +This set of attributes specifies a register bits variant. All explicit
>> +attributes shall be specified. The explicit attributes for this type are:
>> +
>> +definition
>> +    The attribute value shall be a list. Each list element shall be a
>> +    :ref:`SpecTypeRegisterBitsDefinition`. The definition will be used if the
>> +    expression defined by the ``enabled-by`` attribute evaluates to true.  In
>> +    generated header files, the expression is evaluated by the C preprocessor.
>> +
>> +enabled-by
>> +    The attribute value shall be an
>> +    :ref:`SpecTypeInterfaceEnabledByExpression`.
>> +
> 
> Where does read-only, write only or clear-on-read go?

This would be in the "access" attribute.

> 
>> +This type is used by the following types:
>> +
>> +* :ref:`SpecTypeRegisterBitsDefinitionDirective`
>> +
>> +.. _SpecTypeRegisterBlockIncludeRole:
>> +
>> +Register Block Include Role
>> +^^^^^^^^^^^^^^^^^^^^^^^^^^^
>> +
>> +This type refines the :ref:`SpecTypeLink` through the ``role`` attribute if the
>> +value is ``register-block-include``. It defines the register block include role
>> +of links.  Links of this role are used to build register blocks using other
>> +register blocks. All explicit attributes shall be specified. The explicit
>> +attributes for this type are:
>> +
>> +name
>> +    The attribute value shall be a string. It shall be the unique name to
>> +    identify the included register block within the item.
>> +
>> +.. _SpecTypeRegisterBlockMemberDefinition:
>> +
>> +Register Block Member Definition
>> +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>> +
>> +A value of this type shall be of one of the following variants:
>> +
>> +* The value may be a set of attributes. This set of attributes specifies a
>> +  register block member definition. All explicit attributes shall be specified.
>> +  The explicit attributes for this type are:
>> +
>> +  count
>> +      The attribute value shall be an integer number. It shall be the count of
>> +      registers of the register block member.
>> +
>> +  name
>> +      The attribute value shall be a :ref:`SpecTypeRegisterName`.
>> +
>> +* There may be no value (null).
>> +
>> +This type is used by the following types:
>> +
>> +* :ref:`SpecTypeRegisterBlockMemberDefinitionDirective`
>> +
>> +* :ref:`SpecTypeRegisterBlockMemberDefinitionVariant`
>> +
>> +.. _SpecTypeRegisterBlockMemberDefinitionDirective:
>> +
>> +Register Block Member Definition Directive
>> +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>> +
>> +This set of attributes specifies a register block member definition directive.
>> +All explicit attributes shall be specified. The explicit attributes for this
>> +type are:
>> +
>> +default
>> +    The attribute value shall be a
>> +    :ref:`SpecTypeRegisterBlockMemberDefinition`. The default definition will
>> +    be used if no variant-specific definition is enabled.
>> +
>> +offset
>> +    The attribute value shall be an integer number. It shall be the offset from
>> +    the register block begin to the register member in units of the address
>> +    space granule.
>> +
>> +variants
>> +    The attribute value shall be a list. Each list element shall be a
>> +    :ref:`SpecTypeRegisterBlockMemberDefinitionVariant`.
>> +
>> +This type is used by the following types:
>> +
>> +* :ref:`SpecTypeRegisterBlockItemType`
>> +
>> +.. _SpecTypeRegisterBlockMemberDefinitionVariant:
>> +
>> +Register Block Member Definition Variant
>> +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>> +
>> +This set of attributes specifies a register block member definition variant.
>> +All explicit attributes shall be specified. The explicit attributes for this
>> +type are:
>> +
>> +definition
>> +    The attribute value shall be a
>> +    :ref:`SpecTypeRegisterBlockMemberDefinition`. The definition will be used
>> +    if the expression defined by the ``enabled-by`` attribute evaluates to
>> +    true.  In generated header files, the expression is evaluated by the C
>> +    preprocessor.
> 
> Te definitions and the implementation need to be separate headers. Currently
> they are the same header and this seems wrong to me.

What do you mean with definitions and implementation? Currently, a 
generated header file looks like this:

https://git.rtems.org/sebh/rtems.git/tree/bsps/include/grlib/irqamp-regs.h?h=qual-82

> 
>> +
>> +enabled-by
>> +    The attribute value shall be an
>> +    :ref:`SpecTypeInterfaceEnabledByExpression`.
>> +
>> +This type is used by the following types:
>> +
>> +* :ref:`SpecTypeRegisterBlockMemberDefinitionDirective`
>> +
>> +.. _SpecTypeRegisterDefinition:
>> +
>> +Register Definition
>> +^^^^^^^^^^^^^^^^^^^
>> +
>> +This set of attributes specifies a register. All explicit attributes shall be
>> +specified. The explicit attributes for this type are:
>> +
>> +bits
>> +    The attribute value shall be a list. Each list element shall be a
>> +    :ref:`SpecTypeRegisterBitsDefinitionDirective`.
>> +
>> +brief
>> +    The attribute value shall be an :ref:`SpecTypeInterfaceBriefDescription`.
>> +
>> +description
>> +    The attribute value shall be an :ref:`SpecTypeInterfaceDescription`.
>> +
>> +name
>> +    The attribute value shall be a string. It shall be the unique name to
>> +    identify the register definition.
>> +
>> +width
>> +    The attribute value shall be an integer number. It shall be the width of
>> +    the register in bits.
> 
> Are you sure you want to vary the size of registers in a block? It implies
> different addressing modes for the bus and that sort of specification is
> complicated.

Yes, this is necessary. I have seen devices with 8-bit and 32-bit registers.

> 
> For example in a memory mapped struct with uint32_t, uint16_t and uint8_t fields
> the compiler may generating different size bus cycles. It may be a requirement
> the 16bit and 8bit registers are accessed as 32bit device word reads and writes.
> A constraint like this limits the use of volatile struct pointers.

For grlib, there are IO functions like this:

https://git.rtems.org/sebh/rtems.git/tree/bsps/sparc/include/grlib/io.h?h=qual-82

It seems that the compiler generates the right load/store instructions. 
This could be changed to inline assembly if needed.

We don't have a bus space API in RTEMS. It would be good to have one, 
however, I don't have one right now.

> 
> 
> Chris
> 
> 
>> +
>> +In addition to the explicit attributes, generic attributes may be specified.
>> +Each generic attribute key shall be a :ref:`SpecTypeName`. The attribute value
>> +may have any type.
>> +
>> +This type is used by the following types:
>> +
>> +* :ref:`SpecTypeRegisterBlockItemType`
>> +
>> +.. _SpecTypeRegisterName:
>> +
>> +Register Name
>> +^^^^^^^^^^^^^
>> +
>> +The value shall be a string. The name consists either of an identifier, or an
>> +identifier and an alias. The identifier and alias are separated by a colon
>> +(``:``).  The identifier shall match with the name of a register definition of
>> +the item (see :ref:`SpecTypeRegisterDefinition`) or the name of a register
>> +block include of the item (see :ref:`SpecTypeRegisterBlockIncludeRole`).  If no
>> +alias is specified, then the identifier is used for the register block member
>> +name, otherwise the alias is used.  If the register block member names are not
>> +unique within the item, then a postfix number is appended to the names.  The
>> +number starts with zero for each set of names. The value shall match with the
>> +regular expression "``^[a-zA-Z_][a-zA-Z0-9_]*(:[a-zA-Z_][a-zA-Z0-9_]*)?$``".
>> +
>> +This type is used by the following types:
>> +
>> +* :ref:`SpecTypeRegisterBlockMemberDefinition`
>> +
>>   .. _SpecTypeRequirementRefinementLinkRole:
>>   
>>   Requirement Refinement Link Role
>>

-- 
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.huber at embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


More information about the devel mailing list