comp.lang.ada
 help / color / mirror / Atom feed
From: Niklas Holsti <niklas.holsti@tidorum.invalid>
Subject: Re: Forcing GNAT to use 32-bit load/store instructions on ARM?
Date: Tue, 01 Jul 2014 07:30:18 +0300
Date: 2014-07-01T07:30:18+03:00	[thread overview]
Message-ID: <c1erqpFr163U1@mid.individual.net> (raw)
In-Reply-To: <0e0b9ac2-e793-4cc5-8d8d-d3441ca28a58@googlegroups.com>

On 14-07-01 01:11 , daniel.dmk@googlemail.com wrote:
> Hello,
> 
> I've started using GNAT GPL for ARM (hosted on Windows) and I'm
> working on some code in SPARK 2014 to interface to memory-mapped
> registers to control registers on the STM32 F4 microcontroller,
> however I'm having trouble where GNAT is using byte loads/stores
> to the registers, instead of word load/stores (32-bit).
> 
> For a lot of registers on the STM32 it is necessary to always
> access the registers using 32-bit load/store instructions. Using
> half-word (16-bit) or byte (8-bit) accesses generates a CPU fault
> with these registers.
> 
> I'm representing the 32-bit register as a record as follows:
> 
>    type Bits_1 is mod 2**1 with Size => 1;
> 
>    type CR_Register is
>       record
>          RNGEN : Bits_1;
>          IE    : Bits_1;
>       end record;
>    for CR_Register use
>       record
>          RNGEN at 0 range 2 .. 2; -- bits 0 .. 1 are reserved
>          IE    at 0 range 3 .. 3;
>          -- bits 4 .. 31 are reserved
>       end record;
>    for CR_Register'Size use 32;
> 
> I then define the register of type CR_Register at the peripheral's
> base address:
> 
>    CR : CR_Register
>      with Size => 32,
>        Volatile,
>        Async_Readers, Async_Writers,
>        Address => System'To_Address(Base_Address);
> 
> I'm using a record instead of a simple Unsigned_32 type so that:
> 1) I can hide access to the "reserved" parts of the register,
> 2) The code to modify the register is straightfoward.
> 
> For example, enabling the peripheral is done by setting
> the RNGEN bit to 1:
> 
>    CR.RNGEN := 1;
> 
> However, the GNAT compiler uses the ARM instruction ldrb to
> load the lower 8 bits of the register, modify the byte (or
> 16#40#), then use strb to write the lower 8-bits back to memory.
> This causes a fault since the register must be accessed
> using a 32-bit load/store instructions (the ldr and str
> instructions).
> 
> Does anyone know how I can force GNAT to generate the
> appropriate instructions?
> 
> Things I have tried:
> 1) Using the Atomic aspect on the record type and CR object
>    had no effect on the code generated.
> 2) Using Pack.
> 3) Declaring the bits inside the register as: Bits_32 range 0 .. 1;

I agree in general with Jeff's answer that if you need specific machine
instructions, and the compiler documentation does not promise to
generate such instructions under certain conditions, you should use
assembly language.

But if you are willing to take the risk of not being sure, have you
tried to define "Reserved" components for bits 0..1 and 4..31 to fill
the gaps in the record type?

Filling the gaps with named components would also be safer from the HW
point of view, because any 32-bit store into the register necessarily
must write the reserved bits too, and usually the HW documentation says
that one should write zero to reserved bits. Your current, gappy record
type may write anything to those bits.

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

  parent reply	other threads:[~2014-07-01  4:30 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-06-30 22:11 Forcing GNAT to use 32-bit load/store instructions on ARM? daniel.dmk
2014-06-30 23:41 ` Jeffrey Carter
2014-07-01 12:06   ` Simon Clubley
2014-07-01 15:44     ` Niklas Holsti
2014-07-01 17:26       ` Simon Clubley
2014-07-01 17:18     ` Simon Wright
2014-07-01 19:43       ` Simon Wright
2014-07-01 17:28     ` Jeffrey Carter
2014-07-01  0:55 ` anon
2014-07-01  4:30 ` Niklas Holsti [this message]
2014-07-01  8:11 ` Dmitry A. Kazakov
2014-07-01 12:09   ` Simon Clubley
2014-07-01 12:20     ` Dmitry A. Kazakov
2014-07-01 17:00       ` Simon Clubley
2014-07-01 19:36         ` Dmitry A. Kazakov
2014-07-01 20:08           ` Simon Clubley
2014-07-02 22:24             ` Randy Brukardt
2014-07-06 20:40               ` MatthiasR
2014-07-07  0:25                 ` Simon Clubley
2014-07-07 22:38                 ` Randy Brukardt
2014-07-08  6:51                   ` Simon Wright
2014-07-10 11:47                     ` Simon Wright
2014-07-10 13:06                       ` Simon Clubley
2014-07-11 18:05                         ` Simon Wright
2014-07-11 20:22                           ` Simon Clubley
2014-07-08  8:50                   ` Brian Drummond
2014-07-08 12:12                   ` Simon Clubley
2014-07-08 13:26                     ` G.B.
2014-07-08 17:13                       ` Simon Clubley
2014-07-08 15:36                     ` Adam Beneschan
2014-07-08 15:40                       ` Adam Beneschan
2014-07-08 20:34                     ` Randy Brukardt
2014-07-09  7:31                       ` Dmitry A. Kazakov
2014-07-10  0:11                         ` Simon Clubley
2014-07-20 11:35                   ` MatthiasR
2014-07-20 15:49                     ` Simon Clubley
2014-07-26 11:05                       ` MatthiasR
2014-08-10 11:20                         ` MatthiasR
2014-07-01 12:03 ` Simon Clubley
2014-07-01 19:52   ` daniel.dmk
2014-07-01 20:40     ` Simon Clubley
2014-07-01 20:55       ` Simon Clubley
2014-07-01 21:01       ` Niklas Holsti
2014-07-01 21:20         ` Simon Clubley
2014-07-01 22:38           ` Niklas Holsti
2014-07-02 16:49             ` Simon Clubley
2014-07-01 21:55         ` daniel.dmk
2014-07-02  7:30     ` Simon Wright
2014-07-02 18:52       ` daniel.dmk
2014-07-04 23:51       ` Niklas Holsti
2014-07-05  0:18         ` Niklas Holsti
replies disabled

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