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;