light_fk723m1_zgt6_0.1.0_eec20f14/source/cpu/armv7/system_armv7m-startup_utilities.adb

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
--
--  Copyright (C) 2024, Vadim Godunko <vgodunko@gmail.com>
--
--  SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
--

pragma Restrictions (No_Elaboration_Code);
pragma Ada_2022;

with Interfaces;
with System.Storage_Elements;

with System_ARMv7M.SCB;
with System_Types;

package body System_ARMv7M.Startup_Utilities is

   procedure Copy
     (Start_Address : System.Address;
      End_Address   : System.Address;
      Load_Address  : System.Address);
   --  Copy data starting from Load_Address to the memory region at
   --  Start_Address .. End_Address-4.

   procedure Fill
     (Start_Address : System.Address;
      End_Address   : System.Address);
   --  Fill memory at Start_Address .. End_Address-4 by zero.

   ----------
   -- Copy --
   ----------

   procedure Copy
     (Start_Address : System.Address;
      End_Address   : System.Address;
      Load_Address  : System.Address)
   is
      use type System.Address;
      use type System.Storage_Elements.Storage_Offset;

      Source_Address      : System.Address := Load_Address;
      Destination_Address : System.Address := Start_Address;

   begin
      if Source_Address /= Destination_Address then
         while Destination_Address /= End_Address loop
            declare
               Source      : constant Interfaces.Unsigned_32
                 with Import, Address => Source_Address;
               Destination : Interfaces.Unsigned_32
                 with Import, Address => Destination_Address;

            begin
               Destination         := Source;

               Source_Address      :=
                 @ + Interfaces.Unsigned_32'Max_Size_In_Storage_Elements;
               Destination_Address :=
                 @ + Interfaces.Unsigned_32'Max_Size_In_Storage_Elements;
            end;
         end loop;
      end if;
   end Copy;

   -----------------------
   -- Copy_Data_Section --
   -----------------------

   procedure Copy_Data_Section is
      sidata : constant System.Storage_Elements.Integer_Address
        with Import, Convention => C, External_Name => "_sidata";
      sdata  : constant System.Storage_Elements.Integer_Address
        with Import, Convention => C, External_Name => "_sdata";
      edata  : constant System.Storage_Elements.Integer_Address
        with Import, Convention => C, External_Name => "_edata";

   begin
      Copy (sdata'Address, edata'Address, sidata'Address);
   end Copy_Data_Section;

   ----------------------------
   -- Copy_DTCM_Data_Section --
   ----------------------------

   procedure Copy_DTCM_Data_Section is
      siitcmtext : constant System_Types.Unsigned_32
        with Import, Convention => C, External_Name => "_siitcmtext";
      sitcmtext  : constant System_Types.Unsigned_32
        with Import, Convention => C, External_Name => "_sitcmtext";
      eitcmtext  : constant System_Types.Unsigned_32
        with Import, Convention => C, External_Name => "_eitcmtext";

   begin
      Copy (sitcmtext'Address, eitcmtext'Address, siitcmtext'Address);
   end Copy_DTCM_Data_Section;

   ----------------------------
   -- Copy_ITCM_Text_Section --
   ----------------------------

   procedure Copy_ITCM_Text_Section is
      sidtcmdata : constant System_Types.Unsigned_32
        with Import, Convention => C, External_Name => "_sidtcmdata";
      sdtcmdata  : constant System_Types.Unsigned_32
        with Import, Convention => C, External_Name => "_sdtcmdata";
      edtcmdata  : constant System_Types.Unsigned_32
        with Import, Convention => C, External_Name => "_edtcmdata";

   begin
      Copy (sdtcmdata'Address, edtcmdata'Address, sidtcmdata'Address);
   end Copy_ITCM_Text_Section;

   ----------------
   -- Enable_FPU --
   ----------------

   procedure Enable_FPU is
      Aux : SCB.SCB_CPACR_Register := SCB.SCB.CPACR;

   begin
      Aux.CP10 := 2#11#;
      Aux.CP11 := 2#11#;

      SCB.SCB.CPACR := Aux;
   end Enable_FPU;

   ----------
   -- Fill --
   ----------

   procedure Fill
     (Start_Address : System.Address;
      End_Address   : System.Address)
   is

      use type System.Address;
      use type System.Storage_Elements.Storage_Offset;

      Destination_Address : System.Address := Start_Address;

   begin
      while Destination_Address /= End_Address loop
         declare
            Destination : Interfaces.Unsigned_32
              with Import, Address => Destination_Address;

         begin
            Destination         := 0;

            Destination_Address :=
              @ + Interfaces.Unsigned_32'Max_Size_In_Storage_Elements;
         end;
      end loop;
   end Fill;

   ----------------------
   -- Fill_BSS_Section --
   ----------------------

   procedure Fill_BSS_Section is
      sbss : constant System_Types.Unsigned_32
        with Import, Convention => C, External_Name => "_sbss";
      ebss : constant System_Types.Unsigned_32
        with Import, Convention => C, External_Name => "_ebss";

   begin
      Fill (sbss'Address, ebss'Address);
   end Fill_BSS_Section;

   ---------------------------
   -- Fill_DTCM_BSS_Section --
   ---------------------------

   procedure Fill_DTCM_BSS_Section is
      sdtcmbss : constant System_Types.Unsigned_32
        with Import, Convention => C, External_Name => "_sdtcmbss";
      edtcmbss : constant System_Types.Unsigned_32
        with Import, Convention => C, External_Name => "_edtcmbss";

   begin
      Fill (sdtcmbss'Address, edtcmbss'Address);
   end Fill_DTCM_BSS_Section;

end System_ARMv7M.Startup_Utilities;