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