[PATCH] eng: Add register block specification types

Chris Johns chrisj at rtems.org
Sun Sep 12 01:32:33 UTC 2021


On 11/9/21 12:41 am, Sebastian Huber wrote:
> A register block may be used to specify the memory-mapped interface to
> the hardware.  Register blocks consist of register block members.
> Register block members are either instances of registers or instances of
> other register blocks.  Registers consists of bit fields.

I feel this is for generation of headers of devices for drivers. Is this correct?

What bus interface API you are considering mapping this specification too?

I do not know the purpose of this addition and the long term effect of this
being formalised like this.

> Update #3715.

I could not see this topic in the list for that ticket. I prefer that list stays
as it is.

> ---
> For examples see:
> 
> https://git.rtems.org/rtems-central/tree/spec/dev/grlib/if
> 
>  eng/req/items.rst | 334 ++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 334 insertions(+)
> 
> diff --git a/eng/req/items.rst b/eng/req/items.rst
> index 1489f19..be6ab5f 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
> @@ -1614,6 +1618,67 @@ 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``. This set of
> +attributes specifies a register block.  A register block may be used to specify
> +the memory-mapped interface to the hardware.  

This seems a little simplistic. The FDT specification is a reasonable indicator
hardware and buses are not easy to specify. It also implies a given generated
mapping.

A specified register block needs to be augmented by a bus specification to be
useful in a formalised context/arena.

> 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`. All explicit attributes shall be
> +specified. 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 in
> +    bytes of the register block.

The size seen by software may not be continuous or even directly accessible. It
depends on the bus and again there is nothing here.

> +
> +register-block-type
> +    The attribute value shall be a :ref:`SpecTypeRegisterBlockType`.
> +
> +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.

Why are attributes being left undefined?

> +
>  .. _SpecTypeRequirementItemType:
>  
>  Requirement Item Type
> @@ -3733,6 +3798,12 @@ This type is used by the following types:
>  
>  * :ref:`SpecTypeInterfaceVariableItemType`
>  
> +* :ref:`SpecTypeRegisterBitsDefinition`
> +
> +* :ref:`SpecTypeRegisterBlockItemType`
> +
> +* :ref:`SpecTypeRegisterDefinition`
> +
>  .. _SpecTypeInterfaceCompoundDefinitionKind:
>  
>  Interface Compound Definition Kind
> @@ -3992,6 +4063,12 @@ This type is used by the following types:
>  
>  * :ref:`SpecTypeInterfaceVariableItemType`
>  
> +* :ref:`SpecTypeRegisterBitsDefinition`
> +
> +* :ref:`SpecTypeRegisterBlockItemType`
> +
> +* :ref:`SpecTypeRegisterDefinition`
> +
>  .. _SpecTypeInterfaceEnabledByExpression:
>  
>  Interface Enabled-By Expression
> @@ -4041,6 +4118,10 @@ This type is used by the following types:
>  
>  * :ref:`SpecTypeInterfaceFunctionDefinitionVariant`
>  
> +* :ref:`SpecTypeRegisterBitsDefinitionVariant`
> +
> +* :ref:`SpecTypeRegisterBlockMemberDefinitionVariant`
> +
>  .. _SpecTypeInterfaceEnumDefinitionKind:
>  
>  Interface Enum Definition Kind
> @@ -4182,6 +4263,8 @@ This type is used by the following types:
>  
>  * :ref:`SpecTypeInterfaceGroupItemType`
>  
> +* :ref:`SpecTypeRegisterBlockItemType`
> +
>  .. _SpecTypeInterfaceGroupMembershipLinkRole:
>  
>  Interface Group Membership Link Role
> @@ -4248,6 +4331,8 @@ This type is used by the following types:
>  
>  * :ref:`SpecTypeInterfaceVariableItemType`
>  
> +* :ref:`SpecTypeRegisterBlockItemType`
> +
>  .. _SpecTypeInterfaceParameter:
>  
>  Interface Parameter
> @@ -4423,6 +4508,8 @@ This type is refined by the following types:
>  
>  * :ref:`SpecTypePlacementOrderLinkRole`
>  
> +* :ref:`SpecTypeRegisterBlockIncludeRole`
> +
>  * :ref:`SpecTypeRequirementRefinementLinkRole`
>  
>  * :ref:`SpecTypeRequirementValidationLinkRole`
> @@ -4471,6 +4558,10 @@ This type is used by the following types:
>  
>  * :ref:`SpecTypeNonFunctionalRequirementItemType`
>  
> +* :ref:`SpecTypeRegisterBlockItemType`
> +
> +* :ref:`SpecTypeRegisterDefinition`
> +
>  * :ref:`SpecTypeRequirementItemType`
>  
>  * :ref:`SpecTypeRootItemType`
> @@ -4512,6 +4603,249 @@ 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.

Which is bit 0 in a register? What if a bus remaps the bits?

> +
> +  width
> +      The attribute value shall be an integer number. It shall be the width in
> +      bits of the bit field.
> +
> +* There may by 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`.
> +
> +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 by 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 in
> +    bytes from the register block begin to the register member.
> +
> +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.
> +
> +enabled-by
> +    The attribute value shall be an
> +    :ref:`SpecTypeInterfaceEnabledByExpression`.
> +
> +This type is used by the following types:
> +
> +* :ref:`SpecTypeRegisterBlockMemberDefinitionDirective`
> +
> +.. _SpecTypeRegisterBlockType:
> +
> +Register Block Type
> +^^^^^^^^^^^^^^^^^^^
> +
> +The value shall be a string. It specifies the register block type. The value
> +shall be an element of
> +
> +* "``memory``".
> +
> +This type is used by the following types:
> +
> +* :ref:`SpecTypeRegisterBlockItemType`
> +
> +.. _SpecTypeRegisterDefinition:

I would like to understand how types other than "memory" are handled. I would be
interested to see how this driver is handled:

https://git.rtems.org/rtems/tree/bsps/shared/dev/serial/ns16550.c

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

I have seen a lot of driver code over many years and some where every bit in a
device is defined and added to headers, we have some. The reality is only a
small number of the defines are ever used in a driver because a driver is often
a specific subset of the hardware's functionality. As a result only the used
definitions can be trusted and I have observed a lot broken definitions in files.

My approach is to only add the pieces used and nothing more.

If you wish to define all registers and then bits will you provide suitable
tests for the registers and bits to know they are valid? If they are not should
they be added if you cannot test them? I do not think they should be.

> +
> +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_]*)?$``".

No mention of using names in the datasheet to help make the maintainance of the
code easier?

Chris

> +
> +This type is used by the following types:
> +
> +* :ref:`SpecTypeRegisterBlockMemberDefinition`
> +
>  .. _SpecTypeRequirementReference:
>  
>  Requirement Reference
> 


More information about the devel mailing list