File : s-bcpith-xtratum-sparc.adb
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS --
4 -- --
5 -- SYSTEM.BB.CPU_PRIMITIVES.INSTALL_TRAP_HANDLER --
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-2013, 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 ------------------------------------------------------------------------------
30
31 -- This is a SPARC (LEON3) XtratuM version of this procedure
32
33 with System.Machine_Code; use System.Machine_Code;
34
35 separate (System.BB.CPU_Primitives)
36 procedure Install_Trap_Handler
37 (Service_Routine : Address;
38 Vector : Vector_Id;
39 Synchronous : Boolean := False)
40 is
41 XM_DCACHE : constant := 1;
42 -- Id for the data cache
43
44 procedure XM_Flush_Cache (Cache : Integer);
45 pragma Import (C, XM_Flush_Cache, "XM_flush_cache");
46 -- Flush cache. Use Cache => 1 for data cache, Cache => 2 for instruction
47 -- cache, or Cache => 3 for both.
48
49 begin
50 -- Install the 4 instructions in the SPARC trap table to point to the
51 -- shared interrupt service routine (Common_ISR).
52
53 -- sethi %hi(Common_Handler), %l4
54
55 -- The 22 most significant bits of Common_Handler are obtained shifting 10
56 -- times to the right, which is equivalent to divide by 2**10.
57
58 Trap_Table (Vector).First_Instr :=
59 16#29000000# + SSE.To_Integer (Common_Handler'Address) / 2**10;
60
61 -- jmp %l4 + %lo(Common_Handler)
62
63 -- The 10 least significant bits of Common_Handler are obtained by masking,
64 -- which is equivalent to mod by 2**10.
65
66 Trap_Table (Vector).Second_Instr :=
67 16#81C52000# + SSE.To_Integer (Common_Handler'Address) mod 2**10;
68
69 -- mov Vector, %l3
70
71 Trap_Table (Vector).Third_Instr :=
72 16#A6102000# + SSE.Integer_Address (Vector);
73
74 -- If the handler is for a synchronous trap then we set bit number
75 -- 8 (in l3) to 1. This bit indicates to the underlying trap handler
76 -- (common_handler) that this is a synchronous trap and it must return
77 -- to the instruction following the trap.
78
79 if Synchronous then
80 Trap_Table (Vector).Third_Instr :=
81 Trap_Table (Vector).Third_Instr + SSE.Integer_Address (16#100#);
82 end if;
83
84 -- nop
85
86 Trap_Table (Vector).Fourth_Instr := 16#01000000#;
87
88 -- Flush the data cache since we are modifying the memory area that
89 -- corresponds to instructions (trap table). This is a good idea even for
90 -- systems where we don't support cache control, such as ERC32, as there
91 -- still may be variants with cache.
92
93 -- As installing interrupt handlers is not time critical, the few extra
94 -- instructions do not matter much.
95
96 XM_Flush_Cache (XM_DCACHE);
97
98 -- Put the address of the user handler in the User_Vector_Table, so that
99 -- the Common_Handler can know where to jump when a trap (synchronous or
100 -- asynchronous) occurs.
101
102 User_Vector_Table (Vector) := Service_Routine;
103 end Install_Trap_Handler;