File : s-bcprmu-leon3.adb


   1 ------------------------------------------------------------------------------
   2 --                                                                          --
   3 --                 GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS                 --
   4 --                                                                          --
   5 --                 SYSTEM.BB.CPU_PRIMITIVES.MULTIPROCESSORS                 --
   6 --                                                                          --
   7 --                                 B o d y                                  --
   8 --                                                                          --
   9 --                     Copyright (C) 2010-2016, AdaCore                     --
  10 --                                                                          --
  11 -- GNARL is free software; you can  redistribute it  and/or modify it under --
  12 -- terms of the  GNU General Public License as published  by the Free Soft- --
  13 -- ware  Foundation;  either version 3,  or (at your option) any later ver- --
  14 -- sion. GNARL is distributed in the hope that it will be useful, but WITH- --
  15 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
  16 -- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
  17 --                                                                          --
  18 --                                                                          --
  19 --                                                                          --
  20 --                                                                          --
  21 --                                                                          --
  22 -- You should have received a copy of the GNU General Public License and    --
  23 -- a copy of the GCC Runtime Library Exception along with this program;     --
  24 -- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
  25 -- <http://www.gnu.org/licenses/>.                                          --
  26 --                                                                          --
  27 ------------------------------------------------------------------------------
  28 
  29 pragma Restrictions (No_Elaboration_Code);
  30 
  31 with System.Machine_Code;
  32 with System.BB.Time;
  33 with System.BB.Timing_Events;
  34 with System.BB.Board_Support;
  35 with System.BB.Board_Support.LEON_3;
  36 with System.BB.Interrupts;
  37 with System.BB.Threads;
  38 with System.BB.Threads.Queues;
  39 with System.BB.Protection;
  40 with Interfaces;
  41 
  42 package body System.BB.CPU_Primitives.Multiprocessors is
  43 
  44    use System.Machine_Code;
  45    use Board_Support;
  46    use Board_Support.LEON_3;
  47    use Interfaces;
  48    use System.Multiprocessors;
  49 
  50    procedure Poke_Handler (Interrupt : Interrupts.Interrupt_ID);
  51    --  Handler for the Poke interrupt
  52 
  53    function ASR_17 return Unsigned_32;
  54    --  Return current value of the ASR 17 register
  55 
  56    ------------
  57    -- ASR_17 --
  58    ------------
  59 
  60    function ASR_17 return Unsigned_32 is
  61       R : Unsigned_32;
  62    begin
  63       Asm ("mov %%asr17, %0" & ASCII.LF & ASCII.HT,
  64            Outputs => Unsigned_32'Asm_Output ("=r", R),
  65            Volatile => True);
  66       return R;
  67    end ASR_17;
  68 
  69    -----------------
  70    -- Current_CPU --
  71    -----------------
  72 
  73    function Current_CPU return CPU is
  74 
  75       --  Get CPU Id from bits 31-28 of the Asr17 register
  76 
  77      (if CPU'Last = 1 then 1 else CPU (Shift_Right (ASR_17, 28) + 1));
  78 
  79    --------------
  80    -- Poke_CPU --
  81    --------------
  82 
  83    procedure Poke_CPU (CPU_Id : CPU) is
  84    begin
  85       --  There is no need to protect access to the register since the only
  86       --  operation applied to it is this assignment and it's always with the
  87       --  same value (2**Poke_Interrupt_ID).
  88 
  89       --  No race condition possible here.
  90 
  91       Interrupt_Force (CPU_Id) :=
  92         Interrupt_Force (CPU_Id) or 2**Poke_Interrupt_ID;
  93    end Poke_CPU;
  94 
  95    ---------------
  96    -- Start_CPU --
  97    ---------------
  98 
  99    procedure Start_CPU (CPU_Id : CPU) is
 100       Reg : Multiprocessor_Status_Register;
 101    begin
 102       --  Set bit n in Status Register to start CPU n
 103 
 104       Reg := Multiprocessor_Status;
 105       Reg.Status := 2**(CPU'Pos (CPU_Id) - 1);
 106       Multiprocessor_Status := Reg;
 107    end Start_CPU;
 108 
 109    --------------------
 110    -- Start_All_CPUs --
 111    --------------------
 112 
 113    procedure Start_All_CPUs is
 114    begin
 115       --  Nothing to do when there's only one CPU
 116 
 117       if CPU'Range_Length > 1 then
 118          Interrupts.Attach_Handler
 119            (Poke_Handler'Access, Poke_Interrupt_ID, Interrupt_Priority'Last);
 120 
 121          for CPU_Id in CPU'First + 1 .. CPU'Last loop
 122             Start_CPU (CPU_Id);
 123          end loop;
 124       end if;
 125    end Start_All_CPUs;
 126 
 127    ------------------
 128    -- Poke_Handler --
 129    ------------------
 130 
 131    procedure Poke_Handler (Interrupt : Interrupts.Interrupt_ID) is
 132       use type Threads.Thread_States;
 133 
 134       Now : Time.Time;
 135 
 136    begin
 137       --  Make sure we are handling the right interrupt
 138 
 139       pragma Assert (Interrupt = Board_Support.Poke_Interrupt_ID);
 140 
 141       Board_Support.Clear_Poke_Interrupt;
 142 
 143       --  The access to the queues must be protected
 144 
 145       Protection.Enter_Kernel;
 146 
 147       Now := Time.Clock;
 148 
 149       --  Execute expired events of the current CPU
 150 
 151       Timing_Events.Execute_Expired_Timing_Events (Now);
 152 
 153       --  Wake up alarms
 154 
 155       Threads.Queues.Wakeup_Expired_Alarms (Now);
 156 
 157       Protection.Leave_Kernel;
 158    end Poke_Handler;
 159 
 160 end System.BB.CPU_Primitives.Multiprocessors;