Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

svd2ada raises "CONSTRAINT_ERROR" if derivedFrom is used by tag "enumerationValues" #98

Open
luzidchris opened this issue Dec 12, 2022 · 3 comments

Comments

@luzidchris
Copy link

luzidchris commented Dec 12, 2022

I tried to generate code from this SVD:
https://raw.githubusercontent.com/esp-rs/esp32/master/svd/esp32.svd

svd2ada also aborts if the tag which is referenced by derivedFrom is not defied before the element which makes use of derivedFrom. It's not really nice to fix this manually but it works but I got stuck because derivedFrom is also used in an enumeration - although the field the tag references is located before. svd2ada crashes:

raised CONSTRAINT_ERROR : enumerate 'derivedFrom' is not known: WDT_STG0
[.../svd2ada]
0x4d1443 descriptors__enumerate__read_enumerate at ???
0x4e3e84 descriptors__field__read_field at ???
0x4d6c6d descriptors__register__read_register at ???
0x5197d0 descriptors__peripheral__read_peripheral at ???
0x521b4f descriptors__device__read_device at ???
0x451f1b _ada_svd2ada at ???
0x450e34 main at ???
[/lib/x86_64-linux-gnu/libc.so.6]
0x7fc289c03d8e
0x7fc289c03e3e
[..../svd2ada]
0x450e8c _start at ???
0xfffffffffffffffe

Besides of -p and -o, I've not passed any further arguments to svd2ada.

I'd really be happy if there was solution to fix or work-around this problem...

I've found issue #84 but it seems different to me ...

I'm using the current master of svd2ada for the test:

commit 6eb0b591bf51af383d9ab1a3f2dbda994970ee07 (HEAD -> master, origin/master, origin/HEAD)
@luzidchris
Copy link
Author

Further info:

First, svd2ada complained about I2C, TIMG and MCPWM. I could resolve this be moving tags as mentioned before.

raised CONSTRAINT_ERROR : peripheral 'derivedFrom' is not known: I2C
raised CONSTRAINT_ERROR : peripheral 'derivedFrom' is not known: TIMG
raised CONSTRAINT_ERROR : peripheral 'derivedFrom' is not known: MCPWM

Eventually, I got stuck with this:

raised CONSTRAINT_ERROR : enumerate 'derivedFrom' is not known: WDT_STG0

WDT_STD0 is an enumeration:

                        <field>
                            <name>WDT_STG0</name>
                            <bitOffset>29</bitOffset>
                            <bitWidth>2</bitWidth>
                            <enumeratedValues>
                                <name>WDT_STG0</name>
                                <usage>read-write</usage>
                                <enumeratedValue>
                                    <name>Disable</name>
                                    <description>Disabled</description>
                                    <value>0</value>
                                </enumeratedValue>
                                <enumeratedValue>
                                    <name>Interrupt</name>
                                    <description>Trigger an interrupt</description>
                                    <value>1</value>
                                </enumeratedValue>
                                <enumeratedValue>
                                    <name>ResetCPU</name>
                                    <description>Reset CPU core</description>
                                    <value>2</value>
                                </enumeratedValue>
                                <enumeratedValue>
                                    <name>ResetSystem</name>
                                    <description>Reset System</description>
                                    <value>3</value>
                                </enumeratedValue>
                            </enumeratedValues>
                        </field>

And other enumerations need to reference it:

                        <field>
                            <name>WDT_STG1</name>
                            <bitOffset>27</bitOffset>
                            <bitWidth>2</bitWidth>
                            <enumeratedValues derivedFrom="WDT_STG0" />
                        </field>

@luzidchris
Copy link
Author

I've taken a look at the implementation of 'svd2ada' and did some tests. It seems to me that the issue is caused by Read_Enumerate. The functions is passed a vector of type Enumerate_Values_Vectors.Vector. Package Descriptors.Fields calls the function in context of Read_Field like this (for tag enumeratedValues):

                     Enum : constant Descriptors.Enumerate.Enumerate_T :=
                              Descriptors.Enumerate.Read_Enumerate
                                (Child, Result.Enums, Result.Acc = Write_Only);

Vector Result.Enums is used by Read_Enumerate to check for an existing type it can derive from if derivedFrom is not empty. In my opinion this is the wrong vector because Result.Enums contains the enumeration value tags, not the enumerationValues tags which is the parent of one or more enumeration value tags.
To find the enumerationValues tag another tag references using derivedFrom, it would be necessary to search Vec which is passed to Read_Field:

   function Read_Field
     (Elt            : DOM.Core.Element;
      Vec            : Field_Vectors.Vector;
      Default_Access : Access_Type;
      Default_Read   : Read_Action_Type)
      return Field_T;

I ran out of time to further analyze the issue but I'll come back to this as soon as I know more. I just wanted to quickly share my view on this before anyone spends effort on this..

@luzidchris luzidchris changed the title svd2ada crashes if derivedFrom references tags defined after current tag and always if used for enumeration values svd2ada raises "CONSTRAINT_ERROR" if derivedFrom is used by tag "enumerationValues" Dec 13, 2022
@luzidchris
Copy link
Author

luzidchris commented Dec 27, 2022

Just spend some more time on this but it's not possible to quickly fix this because it's necessary to search the list of enumeration values of all elements containing enums. As mentioned before, Read_Enumerate is only passed the list of enumerations of the register the current element belongs to. In my case, the enumeration value which serves as template of the current one is defined by one of the previous registers and the enumeration values of this one are not visible to Read_Enumerate.

The solution would be similar to what was done for peripheralType (see descriptors-peripheral.adb, function Read_Peripheral):

      if Derived_From /= "" then
         declare
            Oth : constant Peripheral_Access :=
                    Periph_Db.Get_Peripheral (Derived_From);
         begin
            if Oth /= null then
--              for P of Vector loop
--                 if Unbounded.To_String (P.Name) = Derived_From then
               Result   := Oth.all;
               --  Deep copy of the registers list
               Result.Content.Clear;

               for Elt of Oth.Content loop
                  Result.Content.Append (Deep_Copy (Elt));
               end loop;

               --  Do not inherit interrupts
               Result.Interrupts.Clear;

            else
               raise Constraint_Error with
                 "peripheral 'derivedFrom' is not known: " & Derived_From;
            end if;
         end;
      end if;

For this type a Periph_Db is available which can be used to query the element referenced by derivedFrom. For enumerations, as mentioned before, Vector is searched for the element, but it only contains the enums just read for the current field (see descriptors-enumerate.adb, function Read_Enumerate):

            for Oth of Vector loop
               if Unbounded.To_String (Oth.Name) = Derived_From then
                  --  Copy the derived from enumerate type into the new value
                  Result := Oth;
                  Found := True;
                  exit;
               end if;
            end loop;

            if not Found then
               raise Constraint_Error with
                 "enumerate 'derivedFrom' is not known: " & Derived_From;
            end if;

Since the loop shown above is still visible as commented code, I assume a similar problem has been found before.

In any case, the "database" would only contain the elements already read? I don't know whether or not it's allowed to reference elements which are defined after the element which makes use of derivedFrom. If that's possible it might be necessary to process the elements in multiple phase but I've not seen any SVD yet.

In the initial post, I've referenced an SVD file published by the Rust community, so it might be designed to better match their requirements, but the other files I've found for ESP32 make use of derivedFrom in the same way:

Community version:
https://github.com/posborne/cmsis-svd/blob/master/data/Espressif-Community/esp32.svd

Official version:
https://github.com/posborne/cmsis-svd/blob/master/data/Espressif/esp32.svd
https://raw.githubusercontent.com/espressif/svd/main/svd/esp32.svd

I understood from other posts that AdaCore's focus is not really Espressif, or other architectures besides of ARM in general, when it comes to the "community" releases, but I hope the description here helps to understand the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant