File : s-bbbosu-leon.adb


   1 ------------------------------------------------------------------------------
   2 --                                                                          --
   3 --                  GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS                --
   4 --                                                                          --
   5 --                S Y S T E M . B B . B O A R D _ S U P P O R T             --
   6 --                                                                          --
   7 --                                  B o d y                                 --
   8 --                                                                          --
   9 --        Copyright (C) 1999-2002 Universidad Politecnica de Madrid         --
  10 --             Copyright (C) 2003-2006 The European Space Agency            --
  11 --                     Copyright (C) 2003-2016, AdaCore                     --
  12 --                                                                          --
  13 -- GNARL is free software; you can  redistribute it  and/or modify it under --
  14 -- terms of the  GNU General Public License as published  by the Free Soft- --
  15 -- ware  Foundation;  either version 3,  or (at your option) any later ver- --
  16 -- sion. GNARL is distributed in the hope that it will be useful, but WITH- --
  17 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
  18 -- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
  19 --                                                                          --
  20 --                                                                          --
  21 --                                                                          --
  22 --                                                                          --
  23 --                                                                          --
  24 -- You should have received a copy of the GNU General Public License and    --
  25 -- a copy of the GCC Runtime Library Exception along with this program;     --
  26 -- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
  27 -- <http://www.gnu.org/licenses/>.                                          --
  28 --                                                                          --
  29 -- GNARL was developed by the GNARL team at Florida State University.       --
  30 -- Extensive contributions were provided by Ada Core Technologies, Inc.     --
  31 --                                                                          --
  32 -- The port of GNARL to bare board targets was initially developed by the   --
  33 -- Real-Time Systems Group at the Technical University of Madrid.           --
  34 --                                                                          --
  35 ------------------------------------------------------------------------------
  36 
  37 pragma Restrictions (No_Elaboration_Code);
  38 
  39 with System.BB.Board_Support.LEON; use System.BB.Board_Support.LEON;
  40 with System.BB.Parameters;
  41 with System.BB.Board_Parameters;
  42 
  43 package body System.BB.Board_Support is
  44    use CPU_Primitives;
  45 
  46    -----------------------
  47    -- Local Definitions --
  48    -----------------------
  49 
  50    Periodic_Count : constant := 2**24 - 2;
  51    --  Value to be loaded in the clock counter to accomplish the
  52    --  Clock_Interrupt_Period.
  53    --
  54    --  One is subtracted from Timers_Counter'Last (2**24 -1) because the
  55    --  timeout period will count an extra cycle for reloading the counter.
  56 
  57    --  Constants defining the external interrupts
  58 
  59    General_Purpose_Timer : constant := 8;
  60 
  61    ----------------------
  62    -- Local Procedures --
  63    ----------------------
  64 
  65    procedure Initialize_Memory;
  66    pragma Inline (Initialize_Memory);
  67    --  Initialize the memory on the board
  68 
  69    procedure Initialize_Clock;
  70    --  Perform all the initialization related to the clock
  71 
  72    ------------------------
  73    -- Alarm_Interrupt_ID --
  74    ------------------------
  75 
  76    function Alarm_Interrupt_ID return Interrupts.Interrupt_ID is
  77    begin
  78       return General_Purpose_Timer;
  79    end Alarm_Interrupt_ID;
  80 
  81    ---------------------------
  82    -- Clear_Alarm_Interrupt --
  83    ---------------------------
  84 
  85    procedure Clear_Alarm_Interrupt is
  86    begin
  87       --  Interrupts are cleared automatically when they are acknowledged
  88 
  89       null;
  90    end Clear_Alarm_Interrupt;
  91 
  92    -----------------------------
  93    -- Clear_Interrupt_Request --
  94    -----------------------------
  95 
  96    procedure Clear_Interrupt_Request (Interrupt : Interrupts.Interrupt_ID) is
  97    begin
  98       null;
  99    end Clear_Interrupt_Request;
 100 
 101    --------------------------
 102    -- Clear_Poke_Interrupt --
 103    --------------------------
 104 
 105    procedure Clear_Poke_Interrupt is
 106    begin
 107       --  No Poke interrupt available for leon
 108 
 109       raise Program_Error;
 110    end Clear_Poke_Interrupt;
 111 
 112    ----------------------
 113    -- Initialize_Board --
 114    ----------------------
 115 
 116    procedure Initialize_Board is
 117    begin
 118       --  The initialization of the LEON board consists on initializing the
 119       --  memory, and initializing the clock in order to have the desired
 120       --  granularity and range.
 121 
 122       Initialize_Memory;
 123       Initialize_Clock;
 124    end Initialize_Board;
 125 
 126    ----------------------
 127    -- Initialize_Clock --
 128    ----------------------
 129 
 130    procedure Initialize_Clock is
 131       Prescaler : constant Prescaler_Register :=
 132                     (Value => Board_Parameters.Prescaler_Min,
 133                      Reserved => (others => False));
 134       --  Minimum prescaler to be used to achieve best granularity
 135 
 136       Real_Time_Clock_Reload : constant Timer_Register :=
 137                                  (Timer_Value => Periodic_Count,
 138                                   Reserved    => (others => False));
 139       --  Periodic count to be used for the clock
 140 
 141       Real_Time_Clock_Control : constant Timer_Control_Register :=
 142                                   (Enable         => True,
 143                                    Reload_Counter => True,
 144                                    Load_Counter   => True,
 145                                    Reserved       => (others => False));
 146       --  Program the timer in periodic mode to serve as a clock
 147 
 148    begin
 149       --  Set the prescaler value to achieve the required granularity
 150 
 151       Prescaler_Reload := Prescaler;
 152 
 153       --  Load the counter for the real-time clock
 154 
 155       Timer_2_Reload := Real_Time_Clock_Reload;
 156 
 157       --  Enable Timer 2
 158 
 159       Timer_2_Control := Real_Time_Clock_Control;
 160    end Initialize_Clock;
 161 
 162    -----------------------
 163    -- Initialize_Memory --
 164    -----------------------
 165 
 166    procedure Initialize_Memory is
 167    begin
 168       --  Nothing to be done for LEON
 169 
 170       null;
 171    end Initialize_Memory;
 172 
 173    ------------------------
 174    -- Max_Timer_Interval --
 175    ------------------------
 176 
 177    function Max_Timer_Interval return Timer_Interval is
 178    begin
 179       return Periodic_Count;
 180    end Max_Timer_Interval;
 181 
 182    -----------------------
 183    -- Poke_Interrupt_ID --
 184    -----------------------
 185 
 186    function Poke_Interrupt_ID return Interrupts.Interrupt_ID is
 187    begin
 188       --  No Poke interrupt available for leon
 189 
 190       raise Program_Error;
 191 
 192       --  Unreachable code
 193 
 194       return Interrupts.Interrupt_ID'First;
 195    end Poke_Interrupt_ID;
 196 
 197    ----------------
 198    -- Power_Down --
 199    ----------------
 200 
 201    procedure Power_Down is
 202    begin
 203       null;
 204    end Power_Down;
 205 
 206    ---------------------------
 207    -- Priority_Of_Interrupt --
 208    ---------------------------
 209 
 210    function Priority_Of_Interrupt
 211      (Interrupt : System.BB.Interrupts.Interrupt_ID) return System.Any_Priority
 212    is
 213    begin
 214       --  Assert that it is a real interrupt
 215 
 216       pragma Assert (Interrupt /= System.BB.Interrupts.No_Interrupt);
 217 
 218       return (Any_Priority (Interrupt) + Interrupt_Priority'First - 1);
 219    end Priority_Of_Interrupt;
 220 
 221    ----------------
 222    -- Read_Clock --
 223    ----------------
 224 
 225    function Read_Clock return Timer_Interval is
 226       Timer_Counter : constant Timer_Register := Timer_2_Counter;
 227       --  Make copy of atomic variable to avoid warning on partial access
 228 
 229    begin
 230       return Timer_Interval (Periodic_Count - Timer_Counter.Timer_Value);
 231    end Read_Clock;
 232 
 233    ---------------
 234    -- Set_Alarm --
 235    ---------------
 236 
 237    procedure Set_Alarm (Ticks : Timer_Interval) is
 238       Timer_Reload_Aux : constant Timer_Register :=
 239                            (Timer_Value => Timers_Counter (Ticks),
 240                             Reserved    => (others => False));
 241       --  Load the required ticks
 242 
 243       Timer_Control_Aux : constant Timer_Control_Register :=
 244                             (Enable         => True,
 245                              Reload_Counter => False,
 246                              Load_Counter   => True,
 247                              Reserved       => (others => False));
 248       --  Program the timer in one-shot mode
 249 
 250       Interrupt_Mask_Aux : Interrupt_Mask_and_Priority_Register;
 251 
 252    begin
 253       --  Alarm Clock downcount will reach 0 in Ticks. The granularity of
 254       --  time intervals is equal to Clock Period.
 255 
 256       --  Set the prescaler: already done in Initialize_Clock
 257 
 258       --  Load the counter
 259 
 260       Timer_1_Reload := Timer_Reload_Aux;
 261 
 262       --  Write Timer Control Register
 263 
 264       Timer_1_Control := Timer_Control_Aux;
 265 
 266       --   Enable Timer 1 Interrupts
 267 
 268       Interrupt_Mask_Aux := Interrupt_Mask_and_Priority;
 269       Interrupt_Mask_Aux.Timer_1 := True;
 270       Interrupt_Mask_and_Priority := Interrupt_Mask_Aux;
 271    end Set_Alarm;
 272 
 273    --------------------------
 274    -- Set_Current_Priority --
 275    --------------------------
 276 
 277    procedure Set_Current_Priority (Priority : Integer) is
 278    begin
 279       null; --  No board-specific actions necessary
 280    end Set_Current_Priority;
 281 
 282    ---------------------------
 283    -- Get_Interrupt_Request --
 284    ---------------------------
 285 
 286    function Get_Interrupt_Request
 287      (Vector : CPU_Primitives.Vector_Id)
 288       return System.BB.Interrupts.Interrupt_ID
 289    is
 290    begin
 291       --  The range corresponding to asynchronous traps is 16#11# .. 16#1F#
 292 
 293       pragma Assert (Vector in 16#11# .. 16#1F#);
 294 
 295       return System.BB.Interrupts.Interrupt_ID (Vector - 16#10#);
 296    end Get_Interrupt_Request;
 297 
 298    -------------------------------
 299    -- Install_Interrupt_Handler --
 300    -------------------------------
 301 
 302    procedure Install_Interrupt_Handler
 303      (Handler   : Address;
 304       Interrupt : Interrupts.Interrupt_ID;
 305       Prio      : Interrupt_Priority)
 306    is
 307       pragma Unreferenced (Prio);
 308    begin
 309       CPU_Primitives.Install_Trap_Handler
 310         (Handler, CPU_Primitives.Vector_Id (Interrupt + 16#10#));
 311    end Install_Interrupt_Handler;
 312 
 313 end System.BB.Board_Support;