File : s-bbbosu-8349e.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-2005 The European Space Agency            --
  11 --                     Copyright (C) 2003-2016, AdaCore                     --
  12 --                                                                          --
  13 -- GNAT 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.  GNAT 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 -- GNAT was originally developed  by the GNAT team at  New York 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 with Interfaces; use Interfaces;
  38 
  39 with System.BB.Board_Parameters; use System.BB.Board_Parameters;
  40 with System.BB.Parameters;
  41 with System.BB.Protection;
  42 
  43 package body System.BB.Board_Support is
  44 
  45    --  Mapping between priorities and interrupt source.
  46 
  47    --    HPI is not used; MIXA, MIXB, SYSA, SYSD groups are grouped.
  48 
  49    --    All external and internal interrupts are routed to /int.
  50 
  51    --    Interrupt ipp_ind_ext_int[0] is configured as an external maskable
  52    --    interrupt (See initialization of SEMSR).
  53 
  54    --    MCP interrupts are not handled by the runtime.
  55 
  56    --    External IRQ interrupts are configured as level sensitive.
  57 
  58    --  Here is the table between IPIC priority and Interrupt source. This is
  59    --  extracted from Table 8-28, using the fact that only grouped scheme are
  60    --  used. Interrupt_ID is the interrupt number for the IPIC, which according
  61    --  to Table 8-6 is also the interrupt vector, which by definition is also
  62    --  the Ada Interrupt_ID.
  63 
  64    --  Priority  Interrupt source              Interrupt_ID
  65    --     1      (HPI)
  66    --     2      MIXA0 ipi_int_internal[32]    64
  67    --     3      MIXA1 ipi_int_internal[33]    65
  68    --     4      MIXA2 ipi_int_internal[34]    66
  69    --     5      MIXA3 ipi_int_internal[35]    67
  70    --     6      (MIXB0 - Spread)
  71    --     7-10   (Reserved)
  72    --    11      (MIXA1 - Spread)
  73    --    12-15   (Reserved)
  74    --    16      MIXB0 RTC ALR                 68
  75    --    17      MIXB1 MU                      69
  76    --    18      MIXB2 SBA                     70
  77    --    19      MIXB3 DMA                     71
  78    --    20      (MIXB1 - Spread)
  79    --    21      SYSA0 TSEC1 Tx                32
  80    --    22      SYSA1 TSEC1 Rx                33
  81    --    23      SYSA2 TSEC1 Err               34
  82    --    24      SYSA3 TSEC2 Tx                35
  83    --    25      (MIXA2 - Spread)
  84    --    26      SYSA4 TSEC2 Rx                36
  85    --    27      SYSA5 TSEC2 Err               37
  86    --    28      SYSA6 USB DR                  38
  87    --    29      SYSA7 USB MPH                 39
  88    --    30      MIXA4 ipp_ind_ext_int[0]      48
  89    --    31      MIXA5 ipp_ind_ext_int[1]      17
  90    --    32      MIXA6 ipp_ind_ext_int[2]      18
  91    --    33      MIXA7 ipp_ind_ext_int[3]      19
  92    --    34      (MIXB2 - Spread)
  93    --    35-38   (Reserved)
  94    --    39      (MIXA3 - Spread)
  95    --    40-43   (Reserved)
  96    --    44      MIXB4 IRQ4                    20
  97    --    45      MIXB5 IRQ5                    21
  98    --    46      MIXB6 IRQ6                    22
  99    --    47      MIXB7 IRQ7                    23
 100    --    48      (MIXB3 - Spread)
 101    --    49      SYSD0 UART1                    9
 102    --    50      SYSD1 UART2                   10
 103    --    51      SYSD2 SEC                     11
 104    --    52      (SYSD3 - Reserved)
 105    --    53      (MIXA4 - Spread)
 106    --    54      (SYSD4 - Reserved)
 107    --    55      SYSD5 I2C1                    14
 108    --    56      SYSD6 I2C2                    15
 109    --    57      SYSD7 SPI                     16
 110    --    58      (MIXB4 - Spread)
 111    --    59      GTM4                          72
 112    --    60      (Reserved)
 113    --    61      (SYSA0 - Spread)
 114    --    62      GTM8                          73
 115    --    63      (Reserved)
 116    --    64      (SYSD0 - Spread)
 117    --    65      (Reserved)
 118    --    66      GPIO1                         74
 119    --    67      (MIXA5 - Spread)
 120    --    68      GPIO2                         75
 121    --    69      (Reserved)
 122    --    70      (SYSA1 - Spread)
 123    --    71      DDR                           76
 124    --    72      (Reserved)
 125    --    73      (SYSD1 - Spread)
 126    --    74      (Reserved)
 127    --    75      LBC                           77
 128    --    76      (MIXB5 - Spread)
 129    --    77      GTM2                          78
 130    --    78      (Reserved)
 131    --    79      (SYSA2 - Spread)
 132    --    80      GTM6                          79
 133    --    81      (Reserved)
 134    --    82      (SYSD2 - Spread)
 135    --    83      (Reserved)
 136    --    84      PMC                           80
 137    --    85      (MIXA6 - Spread)
 138    --    86      (Reserved)
 139    --    87      (Reserved)
 140    --    88      (SYSA3 - Spread)
 141    --    89      (Reserved)
 142    --    90      (Reserved)
 143    --    91      (SYSD3 (Spread))
 144    --    92      (Reserved)
 145    --    93      (Reserved)
 146    --    94      (MIXB6 (Spread))
 147    --    95      GTM3                          84
 148    --    96      (Reserved)
 149    --    97      (SYSA4 (Spread))
 150    --    98      GTM7                          85
 151    --    99      (Reserved)
 152    --   100      (SYSD4 - Spread)
 153    --   101      (Reserved)
 154    --   102      (Reserved)
 155    --   103      (MIXA7 - Spread)
 156    --   104      (Reserved)
 157    --   105      (Reserved)
 158    --   106      (SYSA5 - Spread)
 159    --   107      (Reserved)
 160    --   108      (Reserved)
 161    --   109      (SYSD5 - Spread)
 162    --   110      (Reserved)
 163    --   111      (Reserved)
 164    --   112      (MIXB7 - Spread)
 165    --   113      GTM1                          90
 166    --   114      (Reserved)
 167    --   115      (SYSA6 - Spread)
 168    --   116      GTM5                          91
 169    --   117      (Reserved)
 170    --   118      (SYSD6 - Spread)
 171    --   119      (Reserved)
 172    --   120      (Reserved)
 173    --   121      (Reserved)
 174    --   122      (Reserved)
 175    --   123      (SYSA7 - Spread)
 176    --   124      (Reserved)
 177    --   125      (Reserved)
 178    --   126      (SYSD7 - Spread)
 179    --   127      (Reserved)
 180    --   128      (Reserved)
 181 
 182    procedure Define_Interrupt_Priority
 183      (Interrupt : System.BB.Interrupts.Interrupt_ID;
 184       Priority : Interrupt_Priority;
 185       Mask_Bit : Natural);
 186    pragma Export (Ada, Define_Interrupt_Priority,
 187                  "__gnat_define_interrupt_priority");
 188    --  This is a user service to define the priority of interrupts and its
 189    --  corresponding mask bit. It can be called at most once per interrupt.
 190 
 191    use System.BB.Interrupts;
 192 
 193    subtype Mask_Bit_Number is Natural range 0 .. 95;
 194    --  Bit number in the SIMSR_H/SIMSR_L/SEMSR registers. Bit numbers 0 to 31
 195    --  means bit 0 (MSB) to 31 (LSB) of SIMSR_H, bit numbers 32 to 63 means
 196    --  bit 0 (MSB) to 31 (LSB) of SIMSR_L, and bit numbers 64 to 95 means
 197    --  bit 0 (MSB) to 31 (LSB) of SEMSR.
 198 
 199    type Interrupt_Priorities_Type is
 200      array (System.BB.Interrupts.Interrupt_ID
 201               range 0 .. System.BB.Parameters.Number_Of_Interrupt_ID - 1)
 202      of Any_Priority;
 203    --  Type for the interrupt to priority map
 204 
 205    Interrupt_Priorities : Interrupt_Priorities_Type := (others => 0);
 206    --  Map that associate an interrupt id with its priority
 207 
 208    type Priority_Mask is record
 209       SIMSR_H : Unsigned_32;
 210       --  SIMSR_H value
 211 
 212       SIMSR_L : Unsigned_32;
 213       --  SIMSR_L value
 214 
 215       SEMSR : Unsigned_32;
 216       --  SEMSR value
 217    end record;
 218 
 219    type Priority_Mask_Map_Type is
 220      array (Priority'Last .. Interrupt_Priority'Last) of Priority_Mask;
 221    --  Interrupt mask values for each interrupt priority and for non-interrupt
 222    --  priorities (Priority'Last is used for that case).
 223 
 224    Priority_Masks : Priority_Mask_Map_Type := (others => (0, 0, 0));
 225    --  Mask for eash priority. Initially all interrupts are masked
 226 
 227    SEMSR : Unsigned_32;
 228    for SEMSR'Address use IMMRBAR + 16#0738#;
 229    pragma Volatile (SEMSR);
 230    pragma Import (Ada, SEMSR);
 231    --  System External interrupt Mask Register
 232 
 233    SIMSR_H : Unsigned_32;
 234    for SIMSR_H'Address use IMMRBAR + 16#0720#;
 235    pragma Volatile (SIMSR_H);
 236    pragma Import (Ada, SIMSR_H);
 237    --  System Internal interrupt Mask Register (High)
 238 
 239    SIMSR_L : Unsigned_32;
 240    for SIMSR_L'Address use IMMRBAR + 16#0724#;
 241    pragma Volatile (SIMSR_L);
 242    pragma Import (Ada, SIMSR_L);
 243    --  System Internal interrupt Mask Register (Low)
 244 
 245    ----------------------
 246    -- Initialize_Board --
 247    ----------------------
 248 
 249    procedure Initialize_Board is
 250       SICFR : Unsigned_32;
 251       for SICFR'Address use IMMRBAR + 16#0700#;
 252       pragma Volatile (SICFR);
 253       pragma Import (Ada, SICFR);
 254 
 255       SIPRR_A : Unsigned_32;
 256       for SIPRR_A'Address use IMMRBAR + 16#0710#;
 257       pragma Volatile (SIPRR_A);
 258       pragma Import (Ada, SIPRR_A);
 259 
 260       SIPRR_D : Unsigned_32;
 261       for SIPRR_D'Address use IMMRBAR + 16#071C#;
 262       pragma Volatile (SIPRR_D);
 263       pragma Import (Ada, SIPRR_D);
 264 
 265       SICNR : Unsigned_32;
 266       for SICNR'Address use IMMRBAR + 16#0728#;
 267       pragma Volatile (SICNR);
 268       pragma Import (Ada, SICNR);
 269 
 270       SMPRR_A : Unsigned_32;
 271       for SMPRR_A'Address use IMMRBAR + 16#0730#;
 272       pragma Volatile (SMPRR_A);
 273       pragma Import (Ada, SMPRR_A);
 274 
 275       SMPRR_B : Unsigned_32;
 276       for SMPRR_B'Address use IMMRBAR + 16#0734#;
 277       pragma Volatile (SMPRR_B);
 278       pragma Import (Ada, SMPRR_B);
 279 
 280       SECNR : Unsigned_32;
 281       for SECNR'Address use IMMRBAR + 16#073C#;
 282       pragma Volatile (SECNR);
 283       pragma Import (Ada, SECNR);
 284 
 285    begin
 286       --  Initialize IPIC
 287 
 288       --  At that point, all interrupts should be masked in the MSR
 289 
 290       --           H         M M   I    I        H
 291       --           P         P P   P    P        P
 292       --           I         S S   S    S        E
 293       --                     B A   D    A        T
 294 
 295       SICFR := 2#0_0000000_0_0_0_0_0_00_0_000000_00_00000000#;
 296 
 297       --  SYSA      0P  1P  2P  3P  --   4P  5P  6P  7P  --
 298 
 299       SIPRR_A := 2#000_001_010_011_0000_100_101_110_111_0000#;
 300 
 301       --  SYSD      0P  1P  2P  3P  --   4P  5P  6P  7P  --
 302 
 303       SIPRR_D := 2#000_001_010_011_0000_100_101_110_111_0000#;
 304 
 305       --     SYSD0T 1T                   SYSA0T 1T
 306 
 307       SICNR := 2#00_00_000000000000_00000000_00_00_0000#;
 308 
 309       --  SMPRR_A   0P  1P  2P  3P  --   4P  5P  6P  7P  --
 310 
 311       SMPRR_A := 2#000_001_010_011_0000_100_101_110_111_0000#;
 312 
 313       --  SMPRR_B   0P  1P  2P  3P  --   4P  5P  6P  7P  --
 314 
 315       SMPRR_B := 2#000_001_010_011_0000_100_101_110_111_0000#;
 316 
 317       --     MIXB0T 1T  MIXA0T 1T      EDI
 318 
 319       SECNR := 2#00_00_0000_00_00_0000_00000000_00000000#;
 320 
 321       --  Mask all interrupts, and steer ipp_ind_ext_int[0] as external
 322       --  interrupt request.
 323 
 324       SIMSR_H := 2#00000000_00000000_00000000_000_00_000#;
 325       SIMSR_L := 2#00000000_00000000_0_000_00_0000_00_0000#;
 326       SEMSR   := 2#00000000_00000000_0_000000000000000#;
 327    end Initialize_Board;
 328 
 329    ---------------------------
 330    -- Clear_Alarm_Interrupt --
 331    ---------------------------
 332 
 333    procedure Clear_Alarm_Interrupt is
 334    begin
 335       --  Nothing to do on standard powerpc
 336 
 337       null;
 338    end Clear_Alarm_Interrupt;
 339 
 340    ---------------------------
 341    -- Get_Interrupt_Request --
 342    ---------------------------
 343 
 344    function Get_Interrupt_Request
 345      (Vector : CPU_Specific.Vector_Id) return Interrupt_ID
 346    is
 347       pragma Unreferenced (Vector);
 348 
 349       SIVCR : Unsigned_32;
 350       for SIVCR'Address use IMMRBAR + 16#0704#;
 351       pragma Volatile (SIVCR);
 352       pragma Import (Ada, SIVCR);
 353       --  The SIVCR register contains the regular unmasked interrupt source
 354       --  of the highest priority level.
 355 
 356    begin
 357       return System.BB.Interrupts.Interrupt_ID (SIVCR and 16#7F#);
 358    end Get_Interrupt_Request;
 359 
 360    -------------------------------
 361    -- Install_Interrupt_Handler --
 362    -------------------------------
 363 
 364    procedure Install_Interrupt_Handler
 365      (Handler   : Address;
 366       Interrupt : Interrupts.Interrupt_ID;
 367       Prio      : Interrupt_Priority)
 368    is
 369       pragma Unreferenced (Interrupt, Prio);
 370    begin
 371       CPU_Specific.Install_Exception_Handler
 372         (Handler, CPU_Specific.External_Interrupt_Excp);
 373    end Install_Interrupt_Handler;
 374 
 375    ---------------------------
 376    -- Priority_Of_Interrupt --
 377    ---------------------------
 378 
 379    function Priority_Of_Interrupt
 380      (Interrupt : System.BB.Interrupts.Interrupt_ID) return System.Any_Priority
 381    is
 382       Result : constant Any_Priority := Interrupt_Priorities (Interrupt);
 383 
 384    begin
 385       --  The priority of an interrupt should be in the Interrupt_Priority
 386       --  range. A failure indicates a spurious interrupt, or an interrupt
 387       --  that was unmasked directly.
 388 
 389       pragma Assert (Result in Interrupt_Priority);
 390 
 391       return Result;
 392    end Priority_Of_Interrupt;
 393 
 394    ----------------
 395    -- Power_Down --
 396    ----------------
 397 
 398    procedure Power_Down is
 399    begin
 400       null;
 401    end Power_Down;
 402 
 403    -----------------------------
 404    -- Clear_Interrupt_Request --
 405    -----------------------------
 406 
 407    procedure Clear_Interrupt_Request
 408      (Interrupt : System.BB.Interrupts.Interrupt_ID)
 409    is
 410    begin
 411       --  Nothing to do for the IPIC
 412       null;
 413    end Clear_Interrupt_Request;
 414 
 415    --------------------------
 416    -- Set_Current_Priority --
 417    --------------------------
 418 
 419    procedure Set_Current_Priority (Priority : Integer) is
 420    begin
 421       --  Note that Priority cannot be the last one, as this procedure is
 422       --  unable to disable the decrementer interrupt.
 423 
 424       pragma Assert (Priority /= Interrupt_Priority'Last);
 425 
 426       --  Must be called with MSR.IE set to 0, to avoid unprioritized
 427       --  interrupt delivery.
 428 
 429       if Priority < System.Interrupt_Priority'First then
 430          SIMSR_H := Priority_Masks (System.Priority'Last).SIMSR_H;
 431          SIMSR_L := Priority_Masks (System.Priority'Last).SIMSR_L;
 432          SEMSR   := Priority_Masks (System.Priority'Last).SEMSR;
 433       else
 434          SIMSR_H := Priority_Masks (Priority).SIMSR_H;
 435          SIMSR_L := Priority_Masks (Priority).SIMSR_L;
 436          SEMSR   := Priority_Masks (Priority).SEMSR;
 437       end if;
 438    end Set_Current_Priority;
 439 
 440    -------------------------------
 441    -- Define_Interrupt_Priority --
 442    -------------------------------
 443 
 444    procedure Define_Interrupt_Priority
 445      (Interrupt : System.BB.Interrupts.Interrupt_ID;
 446       Priority  : Interrupt_Priority;
 447       Mask_Bit  : Natural)
 448    is
 449       Mask : Unsigned_32;
 450       --  Bit to set in the mask register
 451 
 452       subtype Int32_Bit_Number is Natural range 0 .. 31;
 453       --  Constrain the right operand of exponentiation so that the compiler
 454       --  is able to replace it by a shift.
 455 
 456    begin
 457       --  Check the priority was never defined for this interrupt
 458 
 459       pragma Assert (Interrupt_Priorities (Interrupt) = 0);
 460 
 461       Protection.Enter_Kernel;
 462 
 463       --  Save the values
 464 
 465       Interrupt_Priorities (Interrupt) := Priority;
 466 
 467       --  Regenerate masks
 468 
 469       case Mask_Bit_Number (Mask_Bit) is
 470          when 0 .. 31 =>
 471             Mask := 2 ** Int32_Bit_Number (31 - Mask_Bit);
 472 
 473             for P in System.Priority'Last .. Priority - 1 loop
 474                Priority_Masks (P).SIMSR_H :=
 475                  Priority_Masks (P).SIMSR_H or Mask;
 476             end loop;
 477 
 478          when 32 .. 63 =>
 479             Mask := 2 ** Int32_Bit_Number (63 - Mask_Bit);
 480 
 481             for P in System.Priority'Last .. Priority - 1 loop
 482                Priority_Masks (P).SIMSR_L :=
 483                  Priority_Masks (P).SIMSR_L or Mask;
 484             end loop;
 485 
 486          when 64 .. 95 =>
 487             Mask := 2 ** Int32_Bit_Number (95 - Mask_Bit);
 488 
 489             for P in System.Priority'Last .. Priority - 1 loop
 490                Priority_Masks (P).SEMSR :=
 491                  Priority_Masks (P).SEMSR or Mask;
 492             end loop;
 493       end case;
 494 
 495       --  Will set mask registers
 496 
 497       Protection.Leave_Kernel;
 498    end Define_Interrupt_Priority;
 499 
 500 end System.BB.Board_Support;