comp.lang.ada
 help / color / mirror / Atom feed
* Best representation for spares
@ 2014-02-14  1:07 Rego, P.
  2014-02-14  9:19 ` Simon Wright
  0 siblings, 1 reply; 23+ messages in thread
From: Rego, P. @ 2014-02-14  1:07 UTC (permalink / raw)


When in a chip mapping, if we have spare (not used) bits, is it better to 'complete' the spaces, so now we have a contiguous type definition for all bits; or is it better to not complete the spaces, and do not consume more stack than necessary? I have seen both approaches, so still did not get a conclusion.

For example, using a Raspberry Pi bits definitions for auxiliary registers in BCM2835 chip:

   type Auxiliary_Interrupt_Status_Type is
      record
         Mini_Uart_IRQ : Boolean;
         SPI_1_IRQ     : Boolean;
         SPI_2_IRQ     : Boolean;
      end record;
   pragma Pack (Auxiliary_Interrupt_Status_Type);
   for Auxiliary_Interrupt_Status_Type'Size use 3;

   type Auxiliary_Enables_Type is
      record
         Mini_Uart_Enable : Boolean;
         SPI_1_Enable     : Boolean;
         SPI_2_Enable     : Boolean;
      end record;
   pragma Pack (Auxiliary_Enables_Type);
   for Auxiliary_Enables_Type'Size use 3;

   type Auxiliary_Peripherals_Register_Map_Type is
      record
         AUX_IRQ            : Auxiliary_Interrupt_Status_Type;
         AUX_ENABLES        : Auxiliary_Enables_Type;
      ... 
      end record;
   for Auxiliary_Peripherals_Register_Map_Type use
      record
         AUX_IRQ            at 16#00# range 00 .. 02;
         AUX_ENABLES        at 16#04# range 00 .. 02;
      end record;

using this kind of definitions, the compiler warns (correctly) me 
   warning: 29-bit gap before component "AUX_ENABLES" 

Would it be better if the definition were something like 

   type Auxiliary_Interrupt_Status_Type is
      record
         Mini_Uart_IRQ : Boolean;
         SPI_1_IRQ     : Boolean;
         SPI_2_IRQ     : Boolean;
         Spare         : Some_Type_With_29_Bits; 
      end record;
   pragma Pack (Auxiliary_Interrupt_Status_Type);
   for Auxiliary_Interrupt_Status_Type'Size use 32;

   ...
   for Auxiliary_Peripherals_Register_Map_Type use
      record
         AUX_IRQ            at 16#00# range 00 .. 32;
         AUX_ENABLES        at 16#04# range 00 .. 02;
      end record;

or just ignore the warning?

Regards,
Rego.


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Best representation for spares
  2014-02-14  1:07 Best representation for spares Rego, P.
@ 2014-02-14  9:19 ` Simon Wright
  2014-02-15 16:06   ` Rego, P.
  0 siblings, 1 reply; 23+ messages in thread
From: Simon Wright @ 2014-02-14  9:19 UTC (permalink / raw)


"Rego, P." <pvrego@gmail.com> writes:

> using this kind of definitions, the compiler warns (correctly) me
>    warning: 29-bit gap before component "AUX_ENABLES"

I'd much prefer to fill this space. And, on the whole, better with zeros
(unless, of course, 'unused' means 'don't even write to this bit').

Something like

   type Zero_Bit is range 0 .. 0;
   type Zero_Bits is array (Positive range <>) of Zero_Bit;
   for Zero_Bits'Component_Size use 1;

   type Auxiliary_Interrupt_Status_Type is
      record
         Mini_Uart_IRQ : Boolean;
         SPI_1_IRQ     : Boolean;
         SPI_2_IRQ     : Boolean;
         Spare         : Zero_Bits (3 .. 31);
      end record;
   pragma Pack (Auxiliary_Interrupt_Status_Type);
   for Auxiliary_Interrupt_Status_Type'Size use 32;


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Best representation for spares
  2014-02-14  9:19 ` Simon Wright
@ 2014-02-15 16:06   ` Rego, P.
  2014-02-15 17:49     ` Jeffrey Carter
  2014-02-15 19:55     ` Niklas Holsti
  0 siblings, 2 replies; 23+ messages in thread
From: Rego, P. @ 2014-02-15 16:06 UTC (permalink / raw)


On Friday, February 14, 2014 7:19:20 AM UTC-2, Simon Wright wrote:
> I'd much prefer to fill this space. And, on the whole, better with zeros
> (unless, of course, 'unused' means 'don't even write to this bit').
> Something like
>    type Zero_Bit is range 0 .. 0;
>    type Zero_Bits is array (Positive range <>) of Zero_Bit;
>    for Zero_Bits'Component_Size use 1;
>    type Auxiliary_Interrupt_Status_Type is
>       record
>          Mini_Uart_IRQ : Boolean;
>          SPI_1_IRQ     : Boolean;
>          SPI_2_IRQ     : Boolean;
>          Spare         : Zero_Bits (3 .. 31);
>       end record;
>    pragma Pack (Auxiliary_Interrupt_Status_Type);
>    for Auxiliary_Interrupt_Status_Type'Size use 32;

Great, I will use this. Even more that the datasheet says 'Reserved, write zero, read as don't care'. Thanks.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Best representation for spares
  2014-02-15 16:06   ` Rego, P.
@ 2014-02-15 17:49     ` Jeffrey Carter
  2014-02-15 20:21       ` Rego, P.
  2014-02-15 19:55     ` Niklas Holsti
  1 sibling, 1 reply; 23+ messages in thread
From: Jeffrey Carter @ 2014-02-15 17:49 UTC (permalink / raw)


On 02/15/2014 09:06 AM, Rego, P. wrote:
> On Friday, February 14, 2014 7:19:20 AM UTC-2, Simon Wright wrote:
>> I'd much prefer to fill this space. And, on the whole, better with zeros
>> (unless, of course, 'unused' means 'don't even write to this bit').
>> Something like
>>     type Zero_Bit is range 0 .. 0;
>>     type Zero_Bits is array (Positive range <>) of Zero_Bit;
>>     for Zero_Bits'Component_Size use 1;
>>     type Auxiliary_Interrupt_Status_Type is
>>        record
>>           Mini_Uart_IRQ : Boolean;
>>           SPI_1_IRQ     : Boolean;
>>           SPI_2_IRQ     : Boolean;
>>           Spare         : Zero_Bits (3 .. 31);
>>        end record;
>>     pragma Pack (Auxiliary_Interrupt_Status_Type);
>>     for Auxiliary_Interrupt_Status_Type'Size use 32;
>
> Great, I will use this. Even more that the datasheet says 'Reserved, write zero, read as don't care'. Thanks.

Note that this does not guarantee that the contents of Spare are zeroes. 
Uninitialized objects, other than access objects, contain "stack junk", whatever 
happens to be in the memory that the object occupies. As a result, they may 
contain invalid values.

To force Spare to contain zeroes, you have to initialize it:

type Auxiliary_Interrupt_Status_Type is record
    Mini_Uart_IRQ : Boolean;
    SPI_1_IRQ     : Boolean;
    SPI_2_IRQ     : Boolean;
    Spare         : Zero_Bits (3 .. 31) := (3 .. 31 => 0);
end record;
for Auxiliary_Interrupt_Status_Type'Size use 32;

-- 
Jeff Carter
"In the frozen land of Nador they were forced to
eat Robin's minstrels, and there was much rejoicing."
Monty Python & the Holy Grail
70


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Best representation for spares
  2014-02-15 16:06   ` Rego, P.
  2014-02-15 17:49     ` Jeffrey Carter
@ 2014-02-15 19:55     ` Niklas Holsti
  2014-02-15 20:25       ` Rego, P.
  1 sibling, 1 reply; 23+ messages in thread
From: Niklas Holsti @ 2014-02-15 19:55 UTC (permalink / raw)


On 14-02-15 18:06 , Rego, P. wrote:
> On Friday, February 14, 2014 7:19:20 AM UTC-2, Simon Wright wrote:
>> I'd much prefer to fill this space. And, on the whole, better with zeros
>> (unless, of course, 'unused' means 'don't even write to this bit').
>> Something like
>>    type Zero_Bit is range 0 .. 0;
>>    type Zero_Bits is array (Positive range <>) of Zero_Bit;
>>    for Zero_Bits'Component_Size use 1;
>>    type Auxiliary_Interrupt_Status_Type is
>>       record
>>          Mini_Uart_IRQ : Boolean;
>>          SPI_1_IRQ     : Boolean;
>>          SPI_2_IRQ     : Boolean;
>>          Spare         : Zero_Bits (3 .. 31);
>>       end record;
>>    pragma Pack (Auxiliary_Interrupt_Status_Type);
>>    for Auxiliary_Interrupt_Status_Type'Size use 32;
> 
> Great, I will use this.

I wouldn't, not if the program will read the record from the HW. See below.

> Even more that the datasheet says 'Reserved, write zero,

"Write zero" implies, to me, that you definitely must declare record
components for these bits, if you are going to write the record to the
HW, and you must set the bits to zero before writing to HW.

If you instead leave a gap in the record you have no way to control what
values the bits in the gap have (except through Unchecked_Conversion,
which would be a dirty trick).

> read as don't care'.

That implies, to me, that the bits read from the HW are not necessarily
zero. If you declare these bits using the Zero_Bits type, and then read
the record from the HW, you can get an "invalid" value -- any '1' bits
will violate the constraint on Zero_Bit. This creates an inconsistency
in the state of your program, which is IMO risky.

I would declare these "reserved" bits with a type that can take any
value that the HW can produce.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Best representation for spares
  2014-02-15 17:49     ` Jeffrey Carter
@ 2014-02-15 20:21       ` Rego, P.
  0 siblings, 0 replies; 23+ messages in thread
From: Rego, P. @ 2014-02-15 20:21 UTC (permalink / raw)


On Saturday, February 15, 2014 3:49:21 PM UTC-2, Jeffrey Carter wrote:
> Note that this does not guarantee that the contents of Spare are zeroes. 
> Uninitialized objects, other than access objects, contain "stack junk", whatever 
> happens to be in the memory that the object occupies. As a result, they may 
> contain invalid values.
> To force Spare to contain zeroes, you have to initialize it:

Ok, I agree,


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Best representation for spares
  2014-02-15 19:55     ` Niklas Holsti
@ 2014-02-15 20:25       ` Rego, P.
  2014-02-15 21:35         ` Rego, P.
                           ` (2 more replies)
  0 siblings, 3 replies; 23+ messages in thread
From: Rego, P. @ 2014-02-15 20:25 UTC (permalink / raw)


On Saturday, February 15, 2014 5:55:30 PM UTC-2, Niklas Holsti wrote:

> I wouldn't, not if the program will read the record from the HW. See below.
> > Even more that the datasheet says 'Reserved, write zero,
> "Write zero" implies, to me, that you definitely must declare record
> components for these bits, if you are going to write the record to the
> HW, and you must set the bits to zero before writing to HW.
> If you instead leave a gap in the record you have no way to control what
> values the bits in the gap have (except through Unchecked_Conversion,
> which would be a dirty trick).
> > read as don't care'.
> That implies, to me, that the bits read from the HW are not necessarily
> zero. If you declare these bits using the Zero_Bits type, and then read
> the record from the HW, you can get an "invalid" value -- any '1' bits
> will violate the constraint on Zero_Bit. This creates an inconsistency
> in the state of your program, which is IMO risky.
> I would declare these "reserved" bits with a type that can take any
> value that the HW can produce.

Ok, I guess you are right.

So I think it's better to use something like

   type Zero_Bit is new Boolean; 
   type Zero_Bits is array (Positive range <>) of Zero_Bit; 
   for Zero_Bits'Component_Size use 1; 

   type Auxiliary_Interrupt_Status_Type is 
      record 
         Mini_Uart_IRQ : Boolean; 
         SPI_1_IRQ     : Boolean; 
         SPI_2_IRQ     : Boolean; 
         Spare         : Zero_Bits (3 .. 31) := (3 .. 31 => 0); 
      end record;



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Best representation for spares
  2014-02-15 20:25       ` Rego, P.
@ 2014-02-15 21:35         ` Rego, P.
  2014-02-16 10:02           ` Niklas Holsti
  2014-02-16 12:10           ` Simon Wright
  2014-02-15 21:41         ` Jeffrey Carter
  2014-02-16 12:06         ` Simon Wright
  2 siblings, 2 replies; 23+ messages in thread
From: Rego, P. @ 2014-02-15 21:35 UTC (permalink / raw)


On Saturday, February 15, 2014 6:25:27 PM UTC-2, Rego, P. wrote:
>    type Zero_Bit is new Boolean; 
>    type Zero_Bits is array (Positive range <>) of Zero_Bit; 
>    for Zero_Bits'Component_Size use 1; 
>    type Auxiliary_Interrupt_Status_Type is 
>       record 
>          Mini_Uart_IRQ : Boolean; 
>          SPI_1_IRQ     : Boolean; 
>          SPI_2_IRQ     : Boolean; 
>          Spare         : Zero_Bits (3 .. 31) := (3 .. 31 => 0); 
>       end record;

The only thing when I use this approach, in

Auxiliary_Peripherals_Register_Map : Auxiliary_Peripherals_Register_Map_Type;
for Auxiliary_Peripherals_Register_Map'Address use System'To_Address (16#7E21_5000#);

I get from compiler the warnings

> default initialization of "Auxiliary_Peripherals_Register_Map" may modify overlaid storage
> use pragma Import for "Auxiliary_Peripherals_Register_Map" to suppress initialization (RM B.1(24))

But in this case I do not want to suppress initialization. What to do to eliminate this warning?

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Best representation for spares
  2014-02-15 20:25       ` Rego, P.
  2014-02-15 21:35         ` Rego, P.
@ 2014-02-15 21:41         ` Jeffrey Carter
  2014-02-15 22:37           ` Rego, P.
  2014-02-16 12:06         ` Simon Wright
  2 siblings, 1 reply; 23+ messages in thread
From: Jeffrey Carter @ 2014-02-15 21:41 UTC (permalink / raw)


On 02/15/2014 01:25 PM, Rego, P. wrote:
>
>     type Zero_Bit is new Boolean;
>     type Zero_Bits is array (Positive range <>) of Zero_Bit;
>     for Zero_Bits'Component_Size use 1;
>
>     type Auxiliary_Interrupt_Status_Type is
>        record
>           Mini_Uart_IRQ : Boolean;
>           SPI_1_IRQ     : Boolean;
>           SPI_2_IRQ     : Boolean;
>           Spare         : Zero_Bits (3 .. 31) := (3 .. 31 => 0);

Zero is not a valid value for the components of Spare, since it's a boolean type.

-- 
Jeff Carter
"In the frozen land of Nador they were forced to
eat Robin's minstrels, and there was much rejoicing."
Monty Python & the Holy Grail
70


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Best representation for spares
  2014-02-15 21:41         ` Jeffrey Carter
@ 2014-02-15 22:37           ` Rego, P.
  2014-02-15 22:41             ` Rego, P.
  2014-02-16  0:39             ` Jeffrey Carter
  0 siblings, 2 replies; 23+ messages in thread
From: Rego, P. @ 2014-02-15 22:37 UTC (permalink / raw)


On Saturday, February 15, 2014 7:41:56 PM UTC-2, Jeffrey Carter wrote:
> Zero is not a valid value for the components of Spare, since it's a boolean type.


Oh yes, I actually used 
    type Zero_Bit is range 0 .. 1; 
    Spare : Zero_Bits (3 .. 31) := (3 .. 31 => 0);

but in this case
> default initialization of "Auxiliary_Peripherals_Register_Map" may modify overlaid storage 
> use pragma Import for "Auxiliary_Peripherals_Register_Map" to suppress initialization (RM B.1(24)) 

Do you have an idea?




^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Best representation for spares
  2014-02-15 22:37           ` Rego, P.
@ 2014-02-15 22:41             ` Rego, P.
  2014-02-16  0:39             ` Jeffrey Carter
  1 sibling, 0 replies; 23+ messages in thread
From: Rego, P. @ 2014-02-15 22:41 UTC (permalink / raw)


On Saturday, February 15, 2014 8:37:36 PM UTC-2, Rego, P. wrote:
> On Saturday, February 15, 2014 7:41:56 PM UTC-2, Jeffrey Carter wrote:
> 
> > Zero is not a valid value for the components of Spare, since it's a boolean type.
> 
> 
> 
> 
> 
> Oh yes, I actually used 
> 
>     type Zero_Bit is range 0 .. 1; 
> 
>     Spare : Zero_Bits (3 .. 31) := (3 .. 31 => 0);
> 
> 
> 
> but in this case
> 
> > default initialization of "Auxiliary_Peripherals_Register_Map" may modify overlaid storage 
> 
> > use pragma Import for "Auxiliary_Peripherals_Register_Map" to suppress initialization (RM B.1(24)) 
> 
> 
> 
> Do you have an idea?

I took a look on ARM B.1(24), and it says

"The declaration of an imported object shall not include an explicit initialization expression. Default initializations are not performed."

So what should actually happen in this case if I use 
 Spare : Zero_Bits (3 .. 31) := (3 .. 31 => 0);
?


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Best representation for spares
  2014-02-15 22:37           ` Rego, P.
  2014-02-15 22:41             ` Rego, P.
@ 2014-02-16  0:39             ` Jeffrey Carter
  1 sibling, 0 replies; 23+ messages in thread
From: Jeffrey Carter @ 2014-02-16  0:39 UTC (permalink / raw)


On 02/15/2014 03:37 PM, Rego, P. wrote:
>
> but in this case
>> default initialization of "Auxiliary_Peripherals_Register_Map" may modify overlaid storage
>> use pragma Import for "Auxiliary_Peripherals_Register_Map" to suppress initialization (RM B.1(24))

If you want the initialization to occur, then you can ignore this warning, or 
look into turning it off (which is compiler dependent).

-- 
Jeff Carter
"In the frozen land of Nador they were forced to
eat Robin's minstrels, and there was much rejoicing."
Monty Python & the Holy Grail
70

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Best representation for spares
  2014-02-15 21:35         ` Rego, P.
@ 2014-02-16 10:02           ` Niklas Holsti
  2014-02-16 13:40             ` Rego, P.
  2014-02-16 12:10           ` Simon Wright
  1 sibling, 1 reply; 23+ messages in thread
From: Niklas Holsti @ 2014-02-16 10:02 UTC (permalink / raw)


On 14-02-15 23:35 , Rego, P. wrote:
> On Saturday, February 15, 2014 6:25:27 PM UTC-2, Rego, P. wrote:
>>    type Zero_Bit is new Boolean; 
>>    type Zero_Bits is array (Positive range <>) of Zero_Bit; 
>>    for Zero_Bits'Component_Size use 1; 
>>    type Auxiliary_Interrupt_Status_Type is 
>>       record 
>>          Mini_Uart_IRQ : Boolean; 
>>          SPI_1_IRQ     : Boolean; 
>>          SPI_2_IRQ     : Boolean; 
>>          Spare         : Zero_Bits (3 .. 31) := (3 .. 31 => 0); 
>>       end record;
> 
> The only thing when I use this approach, in
> 
> Auxiliary_Peripherals_Register_Map : Auxiliary_Peripherals_Register_Map_Type;

(You are using a different record type name here -- not
Auxiliary_Interrupt_Status_Type -- I assume it is an unimportant mistake.)

> for Auxiliary_Peripherals_Register_Map'Address use
>    System'To_Address (16#7E21_5000#);

Here you are "overlaying" a record object on a specific storage
location, presumably a memory-mapped I/O control register. This is OK,
but it has consequences...

> I get from compiler the warnings
> 
>> default initialization of "Auxiliary_Peripherals_Register_Map"
>> may modify overlaid storage
>> use pragma Import for "Auxiliary_Peripherals_Register_Map" to
>> suppress initialization (RM B.1(24))

The compiler is warning you that the initialization of the Spare
component will take place during the elaboration of the declaration of
Auxiliary_Peripherals_Register_Map, which is usually not what one wants
to happen with memory-mapped I/O registers. Usually, such registers are
initialized by explicit assignment statements later on, in the system
initialization procedure.

> But in this case I do not want to suppress initialization.

Why not? If the Spare bits are documented as "reserved", there should
not be any need to initialize just them, and your record type (the one
that is declared in the quote) does not default-initialize any other
components, which means that the default initialization gives them some
garbage values. Or leaves them unchanged, if it can write only to the
Spare bits (unlikely, and partial-word access to mmio registers is
usually not desirable anyway -- look into using the Atomic aspect for
such objects).

> What to do to eliminate this warning?

You can suppy an explicit initialization in the object declaration, even
one using the default initial values for all components:

Auxiliary_Peripherals_Register_Map:
   Auxiliary_Peripherals_Register_Map_Type
      := (others => <>);
--    ^^^^^^^^^^^^^^^^^^
--    Explicit initialization using default initial values.

for Auxiliary_Peripherals_Register_Map'Address use
   System'To_Address (16#7E21_5000#);

However, this assigns *unknown* values to the components without default
initial values, that is, the xxx_IRQ components. You probably want to
initialize these components to False, to avoid spurious invocation of
the interrupt handlers.

I would not put any default initializations in record types that I
intend to overlay onto mmio registers.

> I took a look on ARM B.1(24), and it says
>
> "The declaration of an imported object shall not include
> an explicit initialization expression. Default
> initializations are not performed."
>
> So what should actually happen in this case if I use
>  Spare : Zero_Bits (3 .. 31) := (3 .. 31 => 0);

That is a default initialization. As the RM says, if the object is
imported, the default initialization is not done, just as if you had
declared the component without it, as

   Spare : Zero_Bits (3 .. 31);

Moreover, the RM section you quote makes it illegal to give an explicit
initialization (as in my example above) for an imported object. Thus, to
"initialize" an imported object, you must use an ordinary assignment
statement. The declaration of an imported object cannot initialize it.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Best representation for spares
  2014-02-15 20:25       ` Rego, P.
  2014-02-15 21:35         ` Rego, P.
  2014-02-15 21:41         ` Jeffrey Carter
@ 2014-02-16 12:06         ` Simon Wright
  2014-02-16 13:45           ` Rego, P.
  2 siblings, 1 reply; 23+ messages in thread
From: Simon Wright @ 2014-02-16 12:06 UTC (permalink / raw)


"Rego, P." <pvrego@gmail.com> writes:

> So I think it's better to use something like
>
>    type Zero_Bit is new Boolean; 
>    type Zero_Bits is array (Positive range <>) of Zero_Bit; 
>    for Zero_Bits'Component_Size use 1; 

Yes, though 0..1 would have done too; but if you're going to do this
don't call it Zero_Bit! Padding_Bit, perhaps.


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Best representation for spares
  2014-02-15 21:35         ` Rego, P.
  2014-02-16 10:02           ` Niklas Holsti
@ 2014-02-16 12:10           ` Simon Wright
  2014-02-16 13:43             ` Rego, P.
  1 sibling, 1 reply; 23+ messages in thread
From: Simon Wright @ 2014-02-16 12:10 UTC (permalink / raw)


"Rego, P." <pvrego@gmail.com> writes:

> I get from compiler the warnings
>
>> default initialization of "Auxiliary_Peripherals_Register_Map" may
>> modify overlaid storage
>> use pragma Import for "Auxiliary_Peripherals_Register_Map" to
>> suppress initialization (RM B.1(24))
>
> But in this case I do not want to suppress initialization. What to do
> to eliminate this warning?

With GNAT, you could put pragma Warnings (Off) just before the
statement, and pragma Warnings (On) just after.


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Best representation for spares
  2014-02-16 10:02           ` Niklas Holsti
@ 2014-02-16 13:40             ` Rego, P.
  2014-02-16 16:26               ` Rego, P.
  2014-02-16 16:33               ` Niklas Holsti
  0 siblings, 2 replies; 23+ messages in thread
From: Rego, P. @ 2014-02-16 13:40 UTC (permalink / raw)


On Sunday, February 16, 2014 7:02:41 AM UTC-3, Niklas Holsti wrote:
> Here you are "overlaying" a record object on a specific storage
> location, presumably a memory-mapped I/O control register. This is OK,
> but it has consequences...
But is there a diffferent way to memory-map the registers?

> The compiler is warning you that the initialization of the Spare
> component will take place during the elaboration of the declaration of
> Auxiliary_Peripherals_Register_Map, which is usually not what one wants
> to happen with memory-mapped I/O registers. Usually, such registers are
> initialized by explicit assignment statements later on, in the system
> initialization procedure.

Yes, I was thinking about it. I think it's better to not initialize the spares in the type definition and include this in the system initialization. You are right.

> > But in this case I do not want to suppress initialization.
> Why not? If the Spare bits are documented as "reserved", there should
> not be any need to initialize just them, and your record type (the one
> that is declared in the quote) does not default-initialize any other
> components, which means that the default initialization gives them some
> garbage values. Or leaves them unchanged, if it can write only to the
> Spare bits (unlikely, and partial-word access to mmio registers is
> usually not desirable anyway -- look into using the Atomic aspect for
> such objects).

There are some points in datasheet which are a little confusing, it says the spare is "reserved", but also says "write zero" in some cases (not all).

> > What to do to eliminate this warning?
> You can suppy an explicit initialization in the object declaration, even
> one using the default initial values for all components:
> Auxiliary_Peripherals_Register_Map:
>    Auxiliary_Peripherals_Register_Map_Type
>       := (others => <>);
> --    ^^^^^^^^^^^^^^^^^^
> --    Explicit initialization using default initial values.
Ok Fine.

> for Auxiliary_Peripherals_Register_Map'Address use
>    System'To_Address (16#7E21_5000#);
> However, this assigns *unknown* values to the components without default
> initial values, that is, the xxx_IRQ components. You probably want to
> initialize these components to False, to avoid spurious invocation of
> the interrupt handlers.
> I would not put any default initializations in record types that I
> intend to overlay onto mmio registers.

I did not get. Is is better to use
Auxiliary_Peripherals_Register_Map: 
   Auxiliary_Peripherals_Register_Map_Type 
      := (others => <>);
or just initialize in system initialization?
(or both?)

> That is a default initialization. As the RM says, if the object is
> imported, the default initialization is not done, just as if you had
> declared the component without it, as
>    Spare : Zero_Bits (3 .. 31);
> Moreover, the RM section you quote makes it illegal to give an explicit
> initialization (as in my example above) for an imported object. Thus, to
> "initialize" an imported object, you must use an ordinary assignment
> statement. The declaration of an imported object cannot initialize it.

Ok.

--
Regards,
Rego.


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Best representation for spares
  2014-02-16 12:10           ` Simon Wright
@ 2014-02-16 13:43             ` Rego, P.
  2014-02-16 14:25               ` Robert A Duff
  0 siblings, 1 reply; 23+ messages in thread
From: Rego, P. @ 2014-02-16 13:43 UTC (permalink / raw)


On Sunday, February 16, 2014 9:10:11 AM UTC-3, Simon Wright wrote:
> With GNAT, you could put pragma Warnings (Off) just before the
> statement, and pragma Warnings (On) just after.

Ah, pragma Warnings (Off) is not fair. When I get the warning, I prefer to believe in the compiler. So it must exist a better way to do it (and do not get the warning).


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Best representation for spares
  2014-02-16 12:06         ` Simon Wright
@ 2014-02-16 13:45           ` Rego, P.
  0 siblings, 0 replies; 23+ messages in thread
From: Rego, P. @ 2014-02-16 13:45 UTC (permalink / raw)


On Sunday, February 16, 2014 9:06:48 AM UTC-3, Simon Wright wrote:
> Yes, though 0..1 would have done too; but if you're going to do this
> don't call it Zero_Bit! Padding_Bit, perhaps.

Oh Yes!! I am using actually 

   type Spare_Bit_Type is range 0 .. 1;

   type Spare_Type is array (Natural range <>) of Spare_Bit_Type;
   for Spare_Type'Component_Size use 1;

Thanks!

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Best representation for spares
  2014-02-16 13:43             ` Rego, P.
@ 2014-02-16 14:25               ` Robert A Duff
  2014-02-16 16:21                 ` Rego, P.
  0 siblings, 1 reply; 23+ messages in thread
From: Robert A Duff @ 2014-02-16 14:25 UTC (permalink / raw)


"Rego, P." <pvrego@gmail.com> writes:

> On Sunday, February 16, 2014 9:10:11 AM UTC-3, Simon Wright wrote:
>> With GNAT, you could put pragma Warnings (Off) just before the
>> statement, and pragma Warnings (On) just after.
>
> Ah, pragma Warnings (Off) is not fair. When I get the warning, I
> prefer to believe in the compiler. So it must exist a better way to do
> it (and do not get the warning).

You are wrong to always believe in the compiler.  In GNAT, and most
other compilers for Ada or any other language, a warning indicates
that something MIGHT be wrong, not that something definitely IS wrong.

You are smarter than the compiler (although perhaps not as detail
oriented).  When you see a warning, you should inspect the code, and if
you think the code is correct, use pragma Warnings (Off, ...) to
suppress it, along with a comment explaining why.  Don't write
less-elegant code just to make the compiler shut up.

- Bob


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Best representation for spares
  2014-02-16 14:25               ` Robert A Duff
@ 2014-02-16 16:21                 ` Rego, P.
  0 siblings, 0 replies; 23+ messages in thread
From: Rego, P. @ 2014-02-16 16:21 UTC (permalink / raw)


On Sunday, February 16, 2014 11:25:35 AM UTC-3, Robert A Duff wrote:
> You are wrong to always believe in the compiler.  In GNAT, and most 
> other compilers for Ada or any other language, a warning indicates
> that something MIGHT be wrong, not that something definitely IS wrong.
> You are smarter than the compiler (although perhaps not as detail
> oriented).  When you see a warning, you should inspect the code, and if
> you think the code is correct, use pragma Warnings (Off, ...) to
> suppress it, along with a comment explaining why.  Don't write
> less-elegant code just to make the compiler shut up.

Ok. Good advice.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Best representation for spares
  2014-02-16 13:40             ` Rego, P.
@ 2014-02-16 16:26               ` Rego, P.
  2014-02-16 18:50                 ` Niklas Holsti
  2014-02-16 16:33               ` Niklas Holsti
  1 sibling, 1 reply; 23+ messages in thread
From: Rego, P. @ 2014-02-16 16:26 UTC (permalink / raw)


On Sunday, February 16, 2014 10:40:11 AM UTC-3, Rego, P. wrote:
> I did not get. Is is better to use
> Auxiliary_Peripherals_Register_Map: 
>    Auxiliary_Peripherals_Register_Map_Type 
>       := (others => <>);
> or just initialize in system initialization?
> (or both?)

Now I guess RPi board talked to me :-)
I tried to use both approaches joint and separately, and in all initialization attempts from definition I got an 

raised STORAGE_ERROR : stack overflow (or erroneous memory access)

which only was resolved when I removed both initializations kinds. So it seems to be safer to initialize the registers in run-time, inside a specific initialize procedure.


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Best representation for spares
  2014-02-16 13:40             ` Rego, P.
  2014-02-16 16:26               ` Rego, P.
@ 2014-02-16 16:33               ` Niklas Holsti
  1 sibling, 0 replies; 23+ messages in thread
From: Niklas Holsti @ 2014-02-16 16:33 UTC (permalink / raw)


On 14-02-16 15:40 , Rego, P. wrote:
> On Sunday, February 16, 2014 7:02:41 AM UTC-3, Niklas Holsti wrote:
>> Here you are "overlaying" a record object on a specific storage
>> location, presumably a memory-mapped I/O control register. This is OK,
>> but it has consequences...
> But is there a diffferent way to memory-map the registers?

You can use System.Address_To_Access_Conversions to create a reference
(pointer, access) to the memory address, and then use that pointer:

    package Conversions is new System.Address_To_Access_Conversions (
       Object => Mem_Mapped_Reg_T);

    Ptr : Conversions.Object_Pointer :=
       Conversions.To_Pointer (System'To_Address (16#.....#));

    Reg : Mem_Mapped_Reg_T;

    Reg := Ptr.all;
    ...
    Ptr.all := Reg;

>> If the Spare bits are documented as "reserved", there should
>> not be any need to initialize just them...
> 
> There are some points in datasheet which are a little confusing,
> it says the spare is "reserved", but also says "write zero" in
> some cases (not all).

The bits are typically "reserved" because some later version of the HW
may define some meaning for them, for example to activate some advanced
HW functions that are not available now.

Usually, in order to write anything to a MMIO register, the program has
to write the *entire* register at once, using a word-sized memory-store
instruction. Writing only one bit, or only some other part of the
register, is not usually supported by the HW (except on some small
microcontrollers with bit-addressed memory). This means that you cannot
avoid writing the reserved bits too. The datasheet is saying that you
should write zeroes to the reserved bits, and then nothing bad will
happen even in the future -- no new surprising effects will happen even
if the program is executed in some new version of the HW where the
reserved bits have been given some new functions.

It does not mean (usually) that you *must* initialize these bits to
zero; it means that writing zero is safe, while writing something else
may not be.

> I did not get. Is is better to use
> Auxiliary_Peripherals_Register_Map: 
>    Auxiliary_Peripherals_Register_Map_Type 
>       := (others => <>);
> or just initialize in system initialization?

I would initialize only in the system init, using an assignment
statement. Using either an overlay, or a pointer from
Address_To_Access_Conversions. The pointer method has the advantage that
you can then default-initialize Spares, and it will work:

   Reg_Init : Memory_Mapped_Reg_T;
   ...
   Reg_Init.X := ...;
   Reg_Init.Y := ...;

   Ptr.all := Reg_Init;

Reg_Init.Spares can be default initialized (e.g. to zero), and those
zeroes will be written to Ptr.all. But I would probably write use an
aggregate expression, and not a variable:

   Ptr.all := (X => ..., Y => ..., Spares => ...);

and not bother with default initializations.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Best representation for spares
  2014-02-16 16:26               ` Rego, P.
@ 2014-02-16 18:50                 ` Niklas Holsti
  0 siblings, 0 replies; 23+ messages in thread
From: Niklas Holsti @ 2014-02-16 18:50 UTC (permalink / raw)


On 14-02-16 18:26 , Rego, P. wrote:
> On Sunday, February 16, 2014 10:40:11 AM UTC-3, Rego, P. wrote:
>> I did not get. Is is better to use
>> Auxiliary_Peripherals_Register_Map: 
>>    Auxiliary_Peripherals_Register_Map_Type 
>>       := (others => <>);
>> or just initialize in system initialization?
>> (or both?)
> 
> Now I guess RPi board talked to me :-)
> I tried to use both approaches joint and separately, and in all
> initialization attempts from definition I got an 
> 
> raised STORAGE_ERROR : stack overflow (or erroneous memory access)
> 
> which only was resolved when I removed both initializations
> kinds. So it seems to be safer to initialize the registers
> in run-time, inside a specific initialize procedure.

Oho, Raspberry Pi? Probably not bare-board, so which OS?

In general OSes, I/O registers are typically *not* directly accessible
from user processes, so the exception is probably coming from an
erroneous memory access. That is, the address of the MMIO register is
not accessible to your process, which runs in its own virtual memory
address space.

If this is the reason for the error, it will happen also if you use an
assignment statement to set the register from some initialization procedure.

You either have to use a driver, or take some action to map the MMIO
address into your process space. I don't know how this works on the RPi.
I found some advice at
https://sites.google.com/site/semilleroadt/raspberry-pi-tutorials/gpio;
I assume some moore googling will bring lots of info.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2014-02-16 18:50 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-02-14  1:07 Best representation for spares Rego, P.
2014-02-14  9:19 ` Simon Wright
2014-02-15 16:06   ` Rego, P.
2014-02-15 17:49     ` Jeffrey Carter
2014-02-15 20:21       ` Rego, P.
2014-02-15 19:55     ` Niklas Holsti
2014-02-15 20:25       ` Rego, P.
2014-02-15 21:35         ` Rego, P.
2014-02-16 10:02           ` Niklas Holsti
2014-02-16 13:40             ` Rego, P.
2014-02-16 16:26               ` Rego, P.
2014-02-16 18:50                 ` Niklas Holsti
2014-02-16 16:33               ` Niklas Holsti
2014-02-16 12:10           ` Simon Wright
2014-02-16 13:43             ` Rego, P.
2014-02-16 14:25               ` Robert A Duff
2014-02-16 16:21                 ` Rego, P.
2014-02-15 21:41         ` Jeffrey Carter
2014-02-15 22:37           ` Rego, P.
2014-02-15 22:41             ` Rego, P.
2014-02-16  0:39             ` Jeffrey Carter
2014-02-16 12:06         ` Simon Wright
2014-02-16 13:45           ` Rego, P.

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox