Architecture dependent representation clause

I’m writing a wrapper around some Linux ioctl(2) calls and am using a representation clause to replace the macros in ioctl.h « asm-generic « uapi « include - kernel/git/stable/linux.git - Linux kernel stable tree

However, this header is architecture dependent and has different field sizes and constants for some older architectures: parisc, mips, powerpc, alpha, sparc.

   --  /usr/include/asm-generic/ioctl.h
   type IOC_DIR_Field is (None, Write, Read)
      with Size => 2;
   for IOC_DIR_Field use (0, 1, 2);
   --  parisc: Read and Write are swapped
   --  mips, powerpc, alpha, sparc: IOC_DIR_Field'Size = 3, Write is 4

   type IOC is record
      NR    : UInt8;
      TYP   : UInt8;
      SIZE  : UInt14;         --  13 bits on mips, powerpc, alpha, sparc
      DIR   : IOC_DIR_Field;  --  3 bits on mips, powerpc, alpha, sparc
   end record
      with Size => 32;
   for IOC use record
      NR    at 0 range 0 .. 7;
      TYP   at 1 range 0 .. 7;
      SIZE  at 2 range 0 .. 13;
      DIR   at 2 range 14 .. 15;
   end record;

Should I create a separate package for each architecture to define these fields, or is there a better way to make a representation clause architecture dependent?

What I did in Tash when I needed machine-dependent sizes/alignments was to write a Tcl script to generate a C program which when built against the current Tcl/Tk installation and run generates Ada source code to define the required constants.
I think I could probably have just written the C code straight off, but I was in a Tcl mood at the time.

An alternate solution to the macro problem (I inherited this one) was to write C functions that call the macro and import them to Ada.

I don’t really want to introduce a build dependency on Tcl, but I do think writing wrapper functions in C sounds like a good approach. I’ll give that a shot.

1 Like

What about the GNAT pre-processor (gnatprep) ?

As I said, I had Tcl to hand at the time. Python? (but as you say, the C wrappers look possible; and I think you could define constants in C as well)

Just to follow up, the C wrapper worked out pretty well. I now have an implementation of HAL.SPI that uses Linux spidev. This means you can use Ada_Drivers_Library drivers on any Linux system that has a SPI port defined in devicetree or ACPI.

1 Like