[PATCH v2] eng: Add register block specification types

Chris Johns chrisj at rtems.org
Mon Sep 27 00:23:12 UTC 2021


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.

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.

> 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.

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

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.

> 
> 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.

> 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.

> 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?

> +
> +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 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.

> +
> +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.

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.


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
> 


More information about the devel mailing list