Skip to content

Commit a0a0ef9

Browse files
authored
Fixed the issue of the data/bss section cannot be read from ARM FVP debug tool in cortex-A8 GNU port. (#302)
https://msazure.visualstudio.com/One/_workitems/edit/25139203/
1 parent 6aeefea commit a0a0ef9

7 files changed

Lines changed: 557 additions & 27 deletions

File tree

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// ------------------------------------------------------------
2+
// Cortex-A8 MPCore - Interrupt Controller functions
3+
// Header File
4+
//
5+
// Copyright (c) 2011-2018 Arm Limited (or its affiliates). All rights reserved.
6+
// Use, modification and redistribution of this file is subject to your possession of a
7+
// valid End User License Agreement for the Arm Product of which these examples are part of
8+
// and your compliance with all applicable terms and conditions of such licence agreement.
9+
// ------------------------------------------------------------
10+
11+
#ifndef _CORTEXA_GIC_
12+
#define _CORTEXA_GIC_
13+
14+
// ------------------------------------------------------------
15+
// GIC
16+
// ------------------------------------------------------------
17+
18+
// Typical calls to enable interrupt ID X:
19+
// enable_irq_id(X) <-- Enable that ID
20+
// set_irq_priority(X, 0) <-- Set the priority of X to 0 (the max priority)
21+
// set_priority_mask(0x1F) <-- Set Core's priority mask to 0x1F (the lowest priority)
22+
// enable_GIC() <-- Enable the GIC (global)
23+
// enable_gic_processor_interface() <-- Enable the CPU interface (local to the core)
24+
//
25+
26+
27+
// Global enable of the Interrupt Distributor
28+
void enableGIC(void);
29+
30+
// Global disable of the Interrupt Distributor
31+
void disableGIC(void);
32+
33+
// Enables the interrupt source number ID
34+
void enableIntID(unsigned int ID);
35+
36+
// Disables the interrupt source number ID
37+
void disableIntID(unsigned int ID);
38+
39+
// Sets the priority of the specified ID
40+
void setIntPriority(unsigned int ID, unsigned int priority);
41+
42+
// Enables the processor interface
43+
// Must be done on each core separately
44+
void enableGICProcessorInterface(void);
45+
46+
// Disables the processor interface
47+
// Must be done on each core separately
48+
void disableGICProcessorInterface(void);
49+
50+
// Sets the Priority mask register for the core run on
51+
// The reset value masks ALL interrupts!
52+
void setPriorityMask(unsigned int priority);
53+
54+
// Sets the Binary Point Register for the core run on
55+
void setBinaryPoint(unsigned int priority);
56+
57+
// Returns the value of the Interrupt Acknowledge Register
58+
unsigned int readIntAck(void);
59+
60+
// Writes ID to the End Of Interrupt register
61+
void writeEOI(unsigned int ID);
62+
63+
// ------------------------------------------------------------
64+
// SGI
65+
// ------------------------------------------------------------
66+
67+
// Send a software generate interrupt
68+
void sendSGI(unsigned int ID, unsigned int core_list, unsigned int filter_list);
69+
70+
#endif
71+
72+
// ------------------------------------------------------------
73+
// End of MP_GIC.h
74+
// ------------------------------------------------------------
Lines changed: 294 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
1+
//----------------------------------------------------------------
2+
// Copyright (c) 2005-2018 Arm Limited (or its affiliates). All rights reserved.
3+
// Use, modification and redistribution of this file is subject to your possession of a
4+
// valid End User License Agreement for the Arm Product of which these examples are part of
5+
// and your compliance with all applicable terms and conditions of such licence agreement.
6+
//
7+
// Cortex-A8MP example - Startup Code
8+
//----------------------------------------------------------------
9+
.text
10+
11+
//----------------------------------------------------------------
12+
// GIC. Generic Interrupt Controller Architecture Specification
13+
//----------------------------------------------------------------
14+
15+
// CPU Interface offset from base of private peripheral space --> 0x0100
16+
// Interrupt Distributor offset from base of private peripheral space --> 0x1000
17+
18+
// Typical calls to enable interrupt ID X:
19+
// enableIntID(X) <-- Enable that ID
20+
// setIntPriority(X, 0) <-- Set the priority of X to 0 (the max priority)
21+
// setPriorityMask(0x1F) <-- Set CPU's priority mask to 0x1F (the lowest priority)
22+
// enableGIC() <-- Enable the GIC (global)
23+
// enableGICProcessorInterface() <-- Enable the CPU interface (local to the CPU)
24+
25+
26+
// void enableGIC(void)
27+
// Global enable of the Interrupt Distributor
28+
.global enableGIC
29+
.type enableGIC,function
30+
enableGIC:
31+
// Get base address of private peripheral space
32+
MRC p15, 4, r0, c15, c0, 0 // Read periph base address
33+
ADD r0, r0, #0x1000 // Add the GIC offset
34+
35+
LDR r1, [r0] // Read the GIC Enable Register (ICDDCR)
36+
ORR r1, r1, #0x01 // Set bit 0, the enable bit
37+
STR r1, [r0] // Write the GIC Enable Register (ICDDCR)
38+
39+
BX lr
40+
41+
// ------------------------------------------------------------
42+
43+
.global disableGIC
44+
.type disableGIC,function
45+
// void disableGIC(void)
46+
// Global disable of the Interrupt Distributor
47+
disableGIC:
48+
// Get base address of private peripheral space
49+
MRC p15, 4, r0, c15, c0, 0 // Read periph base address
50+
ADD r0, r0, #0x1000 // Add the GIC offset
51+
52+
LDR r1, [r0] // Read the GIC Enable Register (ICDDCR)
53+
BIC r1, r1, #0x01 // Clear bit 0, the enable bit
54+
STR r1, [r0] // Write the GIC Enable Register (ICDDCR)
55+
56+
BX lr
57+
58+
59+
// ------------------------------------------------------------
60+
61+
.global enableIntID
62+
.type enableIntID,function
63+
// void enableIntID(unsigned int ID)
64+
// Enables the interrupt source number ID
65+
enableIntID:
66+
// Get base address of private peripheral space
67+
MOV r1, r0 // Back up passed in ID value
68+
MRC p15, 4, r0, c15, c0, 0 // Read periph base address
69+
70+
// Each interrupt source has an enable bit in the GIC. These
71+
// are grouped into registers, with 32 sources per register
72+
// First, we need to identify which 32-bit block the interrupt lives in
73+
MOV r2, r1 // Make working copy of ID in r2
74+
MOV r2, r2, LSR #5 // LSR by 5 places, affective divide by 32
75+
// r2 now contains the 32-bit block this ID lives in
76+
MOV r2, r2, LSL #2 // Now multiply by 4, to convert offset into an address offset (four bytes per reg)
77+
78+
// Now work out which bit within the 32-bit block the ID is
79+
AND r1, r1, #0x1F // Mask off to give offset within 32-bit block
80+
MOV r3, #1 // Move enable value into r3
81+
MOV r3, r3, LSL r1 // Shift it left to position of ID
82+
83+
ADD r2, r2, #0x1100 // Add the base offset of the Enable Set registers to the offset for the ID
84+
STR r3, [r0, r2] // Store out (ICDISER)
85+
86+
BX lr
87+
88+
89+
// ------------------------------------------------------------
90+
91+
.global disableIntID
92+
.type disableIntID,function
93+
// void disableIntID(unsigned int ID)
94+
// Disables the interrupt source number ID
95+
disableIntID:
96+
// Get base address of private peripheral space
97+
MOV r1, r0 // Back up passed in ID value
98+
MRC p15, 4, r0, c15, c0, 0 // Read periph base address
99+
100+
// First, we need to identify which 32-bit block the interrupt lives in
101+
MOV r2, r1 // Make working copy of ID in r2
102+
MOV r2, r2, LSR #5 // LSR by 5 places, affective divide by 32
103+
// r2 now contains the 32-bit block this ID lives in
104+
MOV r2, r2, LSL #2 // Now multiply by 4, to convert offset into an address offset (four bytes per reg)
105+
106+
// Now work out which bit within the 32-bit block the ID is
107+
AND r1, r1, #0x1F // Mask off to give offset within 32-bit block
108+
MOV r3, #1 // Move enable value into r3
109+
MOV r3, r3, LSL r1 // Shift it left to position of ID in 32-bit block
110+
111+
ADD r2, r2, #0x1180 // Add the base offset of the Enable Clear registers to the offset for the ID
112+
STR r3, [r0, r2] // Store out (ICDICER)
113+
114+
BX lr
115+
116+
117+
// ------------------------------------------------------------
118+
119+
.global setIntPriority
120+
.type setIntPriority,function
121+
// void setIntPriority(unsigned int ID, unsigned int priority)
122+
// Sets the priority of the specified ID
123+
// r0 = ID
124+
// r1 = priority
125+
setIntPriority:
126+
// Get base address of private peripheral space
127+
MOV r2, r0 // Back up passed in ID value
128+
MRC p15, 4, r0, c15, c0, 0 // Read periph base address
129+
130+
// r0 = base addr
131+
// r1 = priority
132+
// r2 = ID
133+
134+
// Make sure that priority value is only 5 bits, and convert to expected format
135+
AND r1, r1, #0x1F
136+
MOV r1, r1, LSL #3
137+
138+
// Find which register this ID lives in
139+
BIC r3, r2, #0x03 // Make a copy of the ID, clearing off the bottom two bits
140+
// There are four IDs per reg, by clearing the bottom two bits we get an address offset
141+
ADD r3, r3, #0x1400 // Now add the offset of the Priority Level registers from the base of the private peripheral space
142+
ADD r0, r0, r3 // Now add in the base address of the private peripheral space, giving us the absolute address
143+
144+
// Now work out which ID in the register it is
145+
AND r2, r2, #0x03 // Clear all but the bottom two bits, leaves which ID in the reg it is (which byte)
146+
MOV r2, r2, LSL #3 // Multiply by 8, this gives a bit offset
147+
148+
// Read -> Modify -> Write
149+
MOV r12, #0xFF // 8 bit field mask
150+
MOV r12, r12, LSL r2 // Move mask into correct bit position
151+
MOV r1, r1, LSL r2 // Also, move passed in priority value into correct bit position
152+
153+
LDR r3, [r0] // Read current value of the Priority Level register (ICDIPR)
154+
BIC r3, r3, r12 // Clear appropriate field
155+
ORR r3, r3, r1 // Now OR in the priority value
156+
STR r3, [r0] // And store it back again (ICDIPR)
157+
158+
BX lr
159+
160+
161+
// ------------------------------------------------------------
162+
163+
.global enableGICProcessorInterface
164+
.type enableGICProcessorInterface,function
165+
// void enableGICProcessorInterface(void)
166+
// Enables the processor interface
167+
// Must be done on each core separately
168+
enableGICProcessorInterface:
169+
MRC p15, 4, r0, c15, c0, 0 // Read periph base address
170+
ADD r0, r0, #0x2000
171+
172+
LDR r1, [r0, #0x0] // Read the Processor Interface Control register (ICCICR/ICPICR)
173+
ORR r1, r1, #0x03 // Bit 0: Enables secure interrupts, Bit 1: Enables Non-Secure interrupts
174+
BIC r1, r1, #0x08 // Bit 3: Ensure Group 0 interrupts are signalled using IRQ, not FIQ
175+
STR r1, [r0, #0x0] // Write the Processor Interface Control register (ICCICR/ICPICR)
176+
177+
BX lr
178+
179+
180+
181+
// ------------------------------------------------------------
182+
183+
.global disableGICProcessorInterface
184+
.type disableGICProcessorInterface,function
185+
// void disableGICProcessorInterface(void)
186+
// Disables the processor interface
187+
// Must be done on each core separately
188+
disableGICProcessorInterface:
189+
190+
MRC p15, 4, r0, c15, c0, 0 // Read periph base address
191+
ADD r0, r0, #0x2000
192+
193+
LDR r1, [r0, #0x0] // Read the Processor Interface Control register (ICCICR/ICPICR)
194+
BIC r1, r1, #0x03 // Bit 0: Enables secure interrupts, Bit 1: Enables Non-Secure interrupts
195+
STR r1, [r0, #0x0] // Write the Processor Interface Control register (ICCICR/ICPICR)
196+
197+
BX lr
198+
199+
200+
201+
// ------------------------------------------------------------
202+
203+
.global setPriorityMask
204+
.type setPriorityMask,function
205+
// void setPriorityMask(unsigned int priority)
206+
// Sets the Priority mask register for the CPU run on
207+
// The reset value masks ALL interrupts!
208+
setPriorityMask:
209+
210+
// Get base address of private peripheral space
211+
MRC p15, 4, r1, c15, c0, 0 // Read periph base address
212+
ADD r1, r1, #0x2000
213+
214+
STR r0, [r1, #0x4] // Write the Priority Mask register (ICCPMR/ICCIPMR)
215+
216+
BX lr
217+
218+
219+
// ------------------------------------------------------------
220+
221+
.global setBinaryPoint
222+
.type setBinaryPoint,function
223+
// void setBinaryPoint(unsigned int priority)
224+
// Sets the Binary Point Register for the CPU run on
225+
setBinaryPoint:
226+
227+
// Get base address of private peripheral space
228+
MRC p15, 4, r1, c15, c0, 0 // Read periph base address
229+
ADD r1, r1, #0x2000
230+
231+
STR r0, [r1, #0x8] // Write the Binary register (ICCBPR/ICCBPR)
232+
233+
BX lr
234+
235+
236+
// ------------------------------------------------------------
237+
238+
.global readIntAck
239+
.type readIntAck,function
240+
// unsigned int readIntAck(void)
241+
// Returns the value of the Interrupt Acknowledge Register
242+
readIntAck:
243+
MRC p15, 4, r0, c15, c0, 0 // Read periph base address
244+
ADD r0, r0, #0x2000
245+
246+
LDR r0, [r0, #0xC] // Read the Interrupt Acknowledge Register (ICCIAR)
247+
BX lr
248+
249+
250+
// ------------------------------------------------------------
251+
252+
.global writeEOI
253+
.type writeEOI,function
254+
// void writeEOI(unsigned int ID)
255+
// Writes ID to the End Of Interrupt register
256+
writeEOI:
257+
258+
// Get base address of private peripheral space
259+
MRC p15, 4, r1, c15, c0, 0 // Read periph base address
260+
ADD r1, r1, #0x2000
261+
262+
STR r0, [r1, #0x10] // Write ID to the End of Interrupt register (ICCEOIR)
263+
264+
BX lr
265+
266+
267+
//----------------------------------------------------------------
268+
// SGI
269+
//----------------------------------------------------------------
270+
271+
.global sendSGI
272+
.type sendSGI,function
273+
// void sendSGI(unsigned int ID, unsigned int target_list, unsigned int filter_list)//
274+
// Send a software generate interrupt
275+
sendSGI:
276+
AND r3, r0, #0x0F // Mask off unused bits of ID, and move to r3
277+
AND r1, r1, #0x0F // Mask off unused bits of target_filter
278+
AND r2, r2, #0x0F // Mask off unused bits of filter_list
279+
280+
ORR r3, r3, r1, LSL #16 // Combine ID and target_filter
281+
ORR r3, r3, r2, LSL #24 // and now the filter list
282+
283+
// Get the address of the GIC
284+
MRC p15, 4, r0, c15, c0, 0 // Read periph base address
285+
ADD r0, r0, #0x1F00 // Add offset of the sgi_trigger reg
286+
287+
STR r3, [r0] // Write to the Software Generated Interrupt Register (ICDSGIR)
288+
289+
BX lr
290+
291+
292+
//----------------------------------------------------------------
293+
// End of MP_GIC.s
294+
//----------------------------------------------------------------

0 commit comments

Comments
 (0)