-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathstartup.adb
223 lines (189 loc) · 7.26 KB
/
startup.adb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
-- Copyright (C) 2016-2024 Free Software Foundation, Inc.
--
-- This file is part of the FreeRTOS-Ada project. This file is
-- free software; you can redistribute it and/or modify it under
-- terms of the GNU General Public License as published by the Free
-- Software Foundation; either version 3, or (at your option) any
-- later version. This file is distributed in the hope that it will
-- be useful, but WITHOUT ANY WARRANTY; without even the implied
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--
-- As a special exception under Section 7 of GPL version 3, you are
-- granted additional permissions described in the GCC Runtime
-- Library Exception, version 3.1, as published by the Free Software
-- Foundation.
--
-- You should have received a copy of the GNU General Public License
-- and a copy of the GCC Runtime Library Exception along with this
-- program; see the files COPYING3 and COPYING.RUNTIME respectively.
-- If not, see <http://www.gnu.org/licenses/>.
with Interfaces;
with System.Machine_Code;
with System.Parameters;
with System.Storage_Elements;
-- For environment task creation
with Environment_Task;
with System.FreeRTOS.Tasks;
package body Startup is
-- Program_Initialization is the program entry point.
procedure Program_Initialization
with
Export,
Convention => Ada,
External_Name => "program_initialization",
No_Return;
-- If the link includes a symbol _default_initial_stack,
-- use this as the storage size: otherwise, use 1024.
--
-- Used in Set_Up_Heap, but declared here because the argument for
-- pragma "Weak_External" must be a library-level entity.
Default_Initial_Stack : constant System.Parameters.Size_Type
with
Import,
Convention => Ada,
External_Name => "_default_initial_stack";
pragma Weak_External (Default_Initial_Stack);
procedure Set_Up_Heap;
-- Separate to reduce the complexity of this file.
procedure Set_Up_Heap is separate;
procedure Set_Up_Clock;
-- Separate to reduce the complexity of this file.
procedure Set_Up_Clock is separate;
procedure Program_Initialization is
-- The following symbols must be exported from the linker script:
--
-- _start_flash_data: where rw data to be copied to sram starts in flash
-- _start_sram_data: where rw data is to be copied to in sram
-- _end_sram_data: first free location after rw data in sram
-- _start_bss: where to start initializing bss to zero
-- _end_bss: first free location after bss
-- _end_stack: first free location after stack
-- _isr_vector is set up in interrupt_vectors.s.
use System.Storage_Elements;
ISR_Vector : Storage_Element
with Import, Convention => Asm, External_Name => "_isr_vector";
Sdata : Storage_Element
with Import, Convention => Asm, External_Name => "_start_sram_data";
Edata : Storage_Element
with Import, Convention => Asm, External_Name => "_end_sram_data";
Sbss : Storage_Element
with Import, Convention => Asm, External_Name => "_start_bss";
Ebss : Storage_Element
with Import, Convention => Asm, External_Name => "_end_bss";
Data_Size : constant Storage_Offset := Edata'Address - Sdata'Address;
-- Index from 1 so as to avoid subtracting 1 from the size
Data_In_Flash : Storage_Array (1 .. Data_Size)
with Import, Convention => Asm, External_Name => "_start_flash_data";
Data_In_Sram : Storage_Array (1 .. Data_Size)
with Import, Convention => Asm, External_Name => "_start_sram_data";
Bss_Size : constant Storage_Offset := Ebss'Address - Sbss'Address;
Bss : Storage_Array (1 .. Bss_Size)
with Import, Convention => Ada, External_Name => "_start_bss";
type CP_Access is (Denied, Privileged, Reserved, Full)
with
Size => 2;
pragma Unreferenced (Privileged, Reserved);
type CP_Accesses is array (0 .. 15) of CP_Access
with
Component_Size => 2,
Size => 32;
type SCB_Registers is record
VTOR : System.Address;
CPACR : CP_Accesses := (others => Denied);
end record
with
Volatile;
for SCB_Registers use record
VTOR at 16#08# range 0 .. 31;
CPACR at 16#88# range 0 .. 31;
end record;
SCB : SCB_Registers
with
Import,
Convention => Ada,
Address => System'To_Address (16#E000_ED00#);
begin
-- Copy data to SRAM
Data_In_Sram := Data_In_Flash;
-- Initialize BSS in SRAM
Bss := (others => 0);
-- Enable FPU
SCB.CPACR := (10 => Full, 11 => Full, others => Denied);
-- Wait for store to complete, restart pipeline
System.Machine_Code.Asm ("dsb", Volatile => True);
System.Machine_Code.Asm ("isb", Volatile => True);
SCB.VTOR := ISR_Vector'Address;
Set_Up_Heap;
Set_Up_Clock;
Environment_Task.Create;
-- Start the scheduler, which will run the environment task to
-- perform elaboration and then execute the Ada main program.
System.FreeRTOS.Tasks.Start_Scheduler;
end Program_Initialization;
--------------------------
-- Interrupt Handlers --
--------------------------
-- The interrupt vector is set up in interrupt_vectors.s, using
-- the handlers defined here.
-- These handlers are all defined as Weak so that they can be
-- replaced by real handlers at link time.
-- If we defined the weak handlers in interrupt_vectors.s, the
-- references would be satisfied internally and so couldn't be
-- replaced by the real handler.
procedure HardFault_Handler
with Export, Convention => Ada, External_Name => "HardFault_Handler";
pragma Weak_External (HardFault_Handler);
procedure HardFault_Handler is
begin
loop
null;
end loop;
end HardFault_Handler;
-- Provided by FreeRTOS.
procedure SVC_Handler
with Export, Convention => Ada, External_Name => "SVC_Handler";
pragma Weak_External (SVC_Handler);
procedure SVC_Handler is
begin
loop
null;
end loop;
end SVC_Handler;
-- Provided by FreeRTOS.
procedure PendSV_Handler
with Export, Convention => Ada, External_Name => "PendSV_Handler";
pragma Weak_External (PendSV_Handler);
procedure PendSV_Handler is
begin
loop
null;
end loop;
end PendSV_Handler;
-- Provided by FreeRTOS.
procedure SysTick_Handler
with Export, Convention => Ada, External_Name => "SysTick_Handler";
pragma Weak_External (SysTick_Handler);
procedure SysTick_Handler is
begin
loop
null;
end loop;
end SysTick_Handler;
-- The real IRQ_Handler, in System.Interrupts, uses ipsr to find
-- which interrupt happened.
procedure IRQ_Handler
with Export, Convention => Ada, External_Name => "IRQ_Handler";
pragma Weak_External (IRQ_Handler);
procedure IRQ_Handler is
IPSR : Interfaces.Unsigned_32
with Volatile; -- don't want it to be optimised away
begin
System.Machine_Code.Asm
("mrs %0, ipsr",
Outputs => Interfaces.Unsigned_32'Asm_Output ("=r", IPSR),
Volatile => True);
loop
null;
end loop;
end IRQ_Handler;
end Startup;