File : s-bbbosu-leon3.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 --  This is the LEON3 version of this package
  38 
  39 pragma Restrictions (No_Elaboration_Code);
  40 
  41 with System.BB.Board_Support.LEON_3;
  42 with System.BB.Board_Parameters;
  43 with System.Multiprocessors;
  44 with System.Machine_Code;
  45 
  46 package body System.BB.Board_Support is
  47 
  48    use CPU_Primitives;
  49    use System.BB.Board_Support.LEON_3;
  50    use System.Multiprocessors;
  51 
  52    -----------------------
  53    -- Local Definitions --
  54    -----------------------
  55 
  56    Periodic_Count : constant := Timer_Interval'Last - 1;
  57    --  Value to be loaded in the clock counter to accomplish the
  58    --  Clock_Interrupt_Period.
  59    --
  60    --  One is subtracted from Timer_Interval'Last because the timeout period
  61    --  will count an extra cycle for reloading the counter.
  62 
  63    Poke_Interrupt : constant System.BB.Interrupts.Interrupt_ID := 14;
  64    --  Use interrupt 14 because 15 is unmaskable with PIL field of PSR register
  65    --  (see SPARCv8 manual 7.3. Trap Control).
  66    --
  67    --  The value is copied in trap_handler-bb-sparc.S
  68 
  69    Alarm_CPU : constant System.Multiprocessors.CPU :=
  70                  System.Multiprocessors.CPU'First;
  71    --  CPU which will handle the alarm interrupt
  72 
  73    ----------------------
  74    -- Local Procedures --
  75    ----------------------
  76 
  77    procedure Initialize_Memory;
  78    pragma Inline (Initialize_Memory);
  79    --  Initialize the memory on the board
  80 
  81    procedure Initialize_Clock;
  82    --  Perform all the initialization related to the clock
  83 
  84    ------------------------
  85    -- Alarm_Interrupt_ID --
  86    ------------------------
  87 
  88    function Alarm_Interrupt_ID return Interrupts.Interrupt_ID is
  89    begin
  90       return Board_Parameters.Timer_1_Interrupt;
  91    end Alarm_Interrupt_ID;
  92 
  93    ---------------------------
  94    -- Clear_Alarm_Interrupt --
  95    ---------------------------
  96 
  97    procedure Clear_Alarm_Interrupt is
  98    begin
  99       --  Interrupts are cleared automatically when they are acknowledged
 100 
 101       null;
 102    end Clear_Alarm_Interrupt;
 103 
 104    -----------------------------
 105    -- Clear_Interrupt_Request --
 106    -----------------------------
 107 
 108    procedure Clear_Interrupt_Request
 109      (Interrupt : System.BB.Interrupts.Interrupt_ID)
 110    is
 111    begin
 112       --  Nothing to do for the IPIC
 113 
 114       null;
 115    end Clear_Interrupt_Request;
 116 
 117    --------------------------
 118    -- Clear_Poke_Interrupt --
 119    --------------------------
 120 
 121    procedure Clear_Poke_Interrupt is
 122    begin
 123       --  Interrupts are cleared automatically when they are acknowledged
 124 
 125       null;
 126    end Clear_Poke_Interrupt;
 127 
 128    ----------------------
 129    -- Initialize_Board --
 130    ----------------------
 131 
 132    procedure Initialize_Board is
 133       Is_SMP : constant Boolean := Board_Parameters.Max_Number_Of_CPUs > 1;
 134    begin
 135       --  The initialization of the LEON board consists on initializing the
 136       --  memory, and initializing the clock in order to have the desired
 137       --  granularity and range.
 138 
 139       Initialize_Memory;
 140       Initialize_Clock;
 141 
 142       if Is_SMP then
 143 
 144          --  Enable Poke interrupts for all CPUs
 145 
 146          for CPU_Id in CPU loop
 147             Interrupt_Mask (CPU_Id) :=
 148               Interrupt_Mask (CPU_Id) or 2**Poke_Interrupt;
 149          end loop;
 150       end if;
 151 
 152    end Initialize_Board;
 153 
 154    ----------------------
 155    -- Initialize_Clock --
 156    ----------------------
 157 
 158    procedure Initialize_Clock is
 159       Prescaler               : constant Prescaler_Register :=
 160                                   (Value    => Board_Parameters.Prescaler_Min,
 161                                    Reserved => (others => False));
 162       --  Minimum prescaler to be used to achieve best granularity
 163 
 164       Periodic_Mode : constant Timer_Control_Register :=
 165         (Enable            => True,
 166          Reload_Counter    => True,
 167          Load_Counter      => True,
 168          Interrupt_Enable  => False,
 169          Interrupt_Pending => False,
 170          Chain             => False,
 171          Debug_Halt        => False,
 172          Reserved          => (others => False));
 173 
 174    begin
 175       --  Set the prescaler value to achieve the required granularity
 176 
 177       Prescaler_Reload := Prescaler;
 178 
 179       --  Load the counter for the real-time clock
 180 
 181       Timer_2_Reload := Periodic_Count;
 182 
 183       --  Program the timer in periodic mode to serve as a clock
 184 
 185       Timer_2_Control := Periodic_Mode;
 186    end Initialize_Clock;
 187 
 188    -----------------------
 189    -- Initialize_Memory --
 190    -----------------------
 191 
 192    procedure Initialize_Memory is
 193    begin
 194       --  Nothing to be done for LEON3
 195 
 196       null;
 197    end Initialize_Memory;
 198 
 199    ------------------------
 200    -- Max_Timer_Interval --
 201    ------------------------
 202 
 203    function Max_Timer_Interval return Timer_Interval is
 204    begin
 205       return Timer_Interval'Last;
 206    end Max_Timer_Interval;
 207 
 208    -----------------------
 209    -- Poke_Interrupt_ID --
 210    -----------------------
 211 
 212    function Poke_Interrupt_ID return Interrupts.Interrupt_ID is
 213    begin
 214       return Poke_Interrupt;
 215    end Poke_Interrupt_ID;
 216 
 217    ----------------
 218    -- Power_Down --
 219    ----------------
 220 
 221    procedure Power_Down is
 222    begin
 223       System.Machine_Code.Asm ("wr %%g0, %%asr19", Volatile => True);
 224    end Power_Down;
 225 
 226    ---------------------------
 227    -- Priority_Of_Interrupt --
 228    ---------------------------
 229 
 230    function Priority_Of_Interrupt
 231      (Interrupt : System.BB.Interrupts.Interrupt_ID) return System.Any_Priority
 232    is
 233    begin
 234       --  Assert that it is a real interrupt
 235 
 236       pragma Assert (Interrupt /= System.BB.Interrupts.No_Interrupt);
 237 
 238       return (Any_Priority (Interrupt) + Interrupt_Priority'First - 1);
 239    end Priority_Of_Interrupt;
 240 
 241    ----------------
 242    -- Read_Clock --
 243    ----------------
 244 
 245    function Read_Clock return Timer_Interval is
 246    begin
 247       return Periodic_Count - Timer_2_Counter;
 248    end Read_Clock;
 249 
 250    ---------------
 251    -- Set_Alarm --
 252    ---------------
 253 
 254    procedure Set_Alarm (Ticks : Timer_Interval) is
 255       One_Shot_Mode : constant Timer_Control_Register :=
 256         (Enable            => True,
 257          Reload_Counter    => False,
 258          Load_Counter      => True,
 259          Interrupt_Enable  => True,
 260          Interrupt_Pending => False,
 261          Chain             => False,
 262          Debug_Halt        => False,
 263          Reserved => (others => False));
 264 
 265    begin
 266       --  Alarm Clock downcount will reach 0 in Ticks. The granularity of
 267       --  time intervals is equal to Clock Period.
 268 
 269       --  Set the prescaler: already done in Initialize_Clock
 270 
 271       --  Load the counter
 272 
 273       Timer_1_Reload := Ticks;
 274 
 275       --  Program the timer in one-shot mode
 276 
 277       Timer_1_Control := One_Shot_Mode;
 278 
 279       --   Enable Timer 1 Interrupts
 280 
 281       Interrupt_Mask (Alarm_CPU) :=
 282         Interrupt_Mask (Alarm_CPU) or 2**Board_Parameters.Timer_1_Interrupt;
 283    end Set_Alarm;
 284 
 285    --------------------------
 286    -- Set_Current_Priority --
 287    --------------------------
 288 
 289    procedure Set_Current_Priority (Priority : Integer) is
 290    begin
 291       null; --  No board-specific actions necessary
 292    end Set_Current_Priority;
 293 
 294    ---------------------------
 295    -- Get_Interrupt_Request --
 296    ---------------------------
 297 
 298    function Get_Interrupt_Request
 299      (Vector : CPU_Primitives.Vector_Id)
 300       return System.BB.Interrupts.Interrupt_ID
 301    is
 302    begin
 303       --  The range corresponding to asynchronous traps is 16#11# .. 16#1F#
 304 
 305       pragma Assert (Vector in 16#11# .. 16#1F#);
 306 
 307       return System.BB.Interrupts.Interrupt_ID (Vector - 16#10#);
 308    end Get_Interrupt_Request;
 309 
 310    -------------------------------
 311    -- Install_Interrupt_Handler --
 312    -------------------------------
 313 
 314    procedure Install_Interrupt_Handler
 315      (Handler   : Address;
 316       Interrupt : Interrupts.Interrupt_ID;
 317       Prio      : Interrupt_Priority)
 318    is
 319       pragma Unreferenced (Prio);
 320    begin
 321       CPU_Primitives.Install_Trap_Handler
 322         (Handler, CPU_Primitives.Vector_Id (Interrupt + 16#10#));
 323    end Install_Interrupt_Handler;
 324 
 325 end System.BB.Board_Support;