Skip to content

Commit

Permalink
Fixed the issue of the data/bss section cannot be read from ARM FVP d…
Browse files Browse the repository at this point in the history
  • Loading branch information
yajunxiaMS authored Sep 18, 2023
1 parent 6aeefea commit a0a0ef9
Show file tree
Hide file tree
Showing 7 changed files with 557 additions and 27 deletions.
74 changes: 74 additions & 0 deletions ports/cortex_a8/gnu/example_build/MP_GIC.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// ------------------------------------------------------------
// Cortex-A8 MPCore - Interrupt Controller functions
// Header File
//
// Copyright (c) 2011-2018 Arm Limited (or its affiliates). All rights reserved.
// Use, modification and redistribution of this file is subject to your possession of a
// valid End User License Agreement for the Arm Product of which these examples are part of
// and your compliance with all applicable terms and conditions of such licence agreement.
// ------------------------------------------------------------

#ifndef _CORTEXA_GIC_
#define _CORTEXA_GIC_

// ------------------------------------------------------------
// GIC
// ------------------------------------------------------------

// Typical calls to enable interrupt ID X:
// enable_irq_id(X) <-- Enable that ID
// set_irq_priority(X, 0) <-- Set the priority of X to 0 (the max priority)
// set_priority_mask(0x1F) <-- Set Core's priority mask to 0x1F (the lowest priority)
// enable_GIC() <-- Enable the GIC (global)
// enable_gic_processor_interface() <-- Enable the CPU interface (local to the core)
//


// Global enable of the Interrupt Distributor
void enableGIC(void);

// Global disable of the Interrupt Distributor
void disableGIC(void);

// Enables the interrupt source number ID
void enableIntID(unsigned int ID);

// Disables the interrupt source number ID
void disableIntID(unsigned int ID);

// Sets the priority of the specified ID
void setIntPriority(unsigned int ID, unsigned int priority);

// Enables the processor interface
// Must be done on each core separately
void enableGICProcessorInterface(void);

// Disables the processor interface
// Must be done on each core separately
void disableGICProcessorInterface(void);

// Sets the Priority mask register for the core run on
// The reset value masks ALL interrupts!
void setPriorityMask(unsigned int priority);

// Sets the Binary Point Register for the core run on
void setBinaryPoint(unsigned int priority);

// Returns the value of the Interrupt Acknowledge Register
unsigned int readIntAck(void);

// Writes ID to the End Of Interrupt register
void writeEOI(unsigned int ID);

// ------------------------------------------------------------
// SGI
// ------------------------------------------------------------

// Send a software generate interrupt
void sendSGI(unsigned int ID, unsigned int core_list, unsigned int filter_list);

#endif

// ------------------------------------------------------------
// End of MP_GIC.h
// ------------------------------------------------------------
294 changes: 294 additions & 0 deletions ports/cortex_a8/gnu/example_build/MP_GIC.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,294 @@
//----------------------------------------------------------------
// Copyright (c) 2005-2018 Arm Limited (or its affiliates). All rights reserved.
// Use, modification and redistribution of this file is subject to your possession of a
// valid End User License Agreement for the Arm Product of which these examples are part of
// and your compliance with all applicable terms and conditions of such licence agreement.
//
// Cortex-A8MP example - Startup Code
//----------------------------------------------------------------
.text

//----------------------------------------------------------------
// GIC. Generic Interrupt Controller Architecture Specification
//----------------------------------------------------------------

// CPU Interface offset from base of private peripheral space --> 0x0100
// Interrupt Distributor offset from base of private peripheral space --> 0x1000

// Typical calls to enable interrupt ID X:
// enableIntID(X) <-- Enable that ID
// setIntPriority(X, 0) <-- Set the priority of X to 0 (the max priority)
// setPriorityMask(0x1F) <-- Set CPU's priority mask to 0x1F (the lowest priority)
// enableGIC() <-- Enable the GIC (global)
// enableGICProcessorInterface() <-- Enable the CPU interface (local to the CPU)


// void enableGIC(void)
// Global enable of the Interrupt Distributor
.global enableGIC
.type enableGIC,function
enableGIC:
// Get base address of private peripheral space
MRC p15, 4, r0, c15, c0, 0 // Read periph base address
ADD r0, r0, #0x1000 // Add the GIC offset

LDR r1, [r0] // Read the GIC Enable Register (ICDDCR)
ORR r1, r1, #0x01 // Set bit 0, the enable bit
STR r1, [r0] // Write the GIC Enable Register (ICDDCR)

BX lr

// ------------------------------------------------------------

.global disableGIC
.type disableGIC,function
// void disableGIC(void)
// Global disable of the Interrupt Distributor
disableGIC:
// Get base address of private peripheral space
MRC p15, 4, r0, c15, c0, 0 // Read periph base address
ADD r0, r0, #0x1000 // Add the GIC offset

LDR r1, [r0] // Read the GIC Enable Register (ICDDCR)
BIC r1, r1, #0x01 // Clear bit 0, the enable bit
STR r1, [r0] // Write the GIC Enable Register (ICDDCR)

BX lr


// ------------------------------------------------------------

.global enableIntID
.type enableIntID,function
// void enableIntID(unsigned int ID)
// Enables the interrupt source number ID
enableIntID:
// Get base address of private peripheral space
MOV r1, r0 // Back up passed in ID value
MRC p15, 4, r0, c15, c0, 0 // Read periph base address

// Each interrupt source has an enable bit in the GIC. These
// are grouped into registers, with 32 sources per register
// First, we need to identify which 32-bit block the interrupt lives in
MOV r2, r1 // Make working copy of ID in r2
MOV r2, r2, LSR #5 // LSR by 5 places, affective divide by 32
// r2 now contains the 32-bit block this ID lives in
MOV r2, r2, LSL #2 // Now multiply by 4, to convert offset into an address offset (four bytes per reg)

// Now work out which bit within the 32-bit block the ID is
AND r1, r1, #0x1F // Mask off to give offset within 32-bit block
MOV r3, #1 // Move enable value into r3
MOV r3, r3, LSL r1 // Shift it left to position of ID

ADD r2, r2, #0x1100 // Add the base offset of the Enable Set registers to the offset for the ID
STR r3, [r0, r2] // Store out (ICDISER)

BX lr


// ------------------------------------------------------------

.global disableIntID
.type disableIntID,function
// void disableIntID(unsigned int ID)
// Disables the interrupt source number ID
disableIntID:
// Get base address of private peripheral space
MOV r1, r0 // Back up passed in ID value
MRC p15, 4, r0, c15, c0, 0 // Read periph base address

// First, we need to identify which 32-bit block the interrupt lives in
MOV r2, r1 // Make working copy of ID in r2
MOV r2, r2, LSR #5 // LSR by 5 places, affective divide by 32
// r2 now contains the 32-bit block this ID lives in
MOV r2, r2, LSL #2 // Now multiply by 4, to convert offset into an address offset (four bytes per reg)

// Now work out which bit within the 32-bit block the ID is
AND r1, r1, #0x1F // Mask off to give offset within 32-bit block
MOV r3, #1 // Move enable value into r3
MOV r3, r3, LSL r1 // Shift it left to position of ID in 32-bit block

ADD r2, r2, #0x1180 // Add the base offset of the Enable Clear registers to the offset for the ID
STR r3, [r0, r2] // Store out (ICDICER)

BX lr


// ------------------------------------------------------------

.global setIntPriority
.type setIntPriority,function
// void setIntPriority(unsigned int ID, unsigned int priority)
// Sets the priority of the specified ID
// r0 = ID
// r1 = priority
setIntPriority:
// Get base address of private peripheral space
MOV r2, r0 // Back up passed in ID value
MRC p15, 4, r0, c15, c0, 0 // Read periph base address

// r0 = base addr
// r1 = priority
// r2 = ID

// Make sure that priority value is only 5 bits, and convert to expected format
AND r1, r1, #0x1F
MOV r1, r1, LSL #3

// Find which register this ID lives in
BIC r3, r2, #0x03 // Make a copy of the ID, clearing off the bottom two bits
// There are four IDs per reg, by clearing the bottom two bits we get an address offset
ADD r3, r3, #0x1400 // Now add the offset of the Priority Level registers from the base of the private peripheral space
ADD r0, r0, r3 // Now add in the base address of the private peripheral space, giving us the absolute address

// Now work out which ID in the register it is
AND r2, r2, #0x03 // Clear all but the bottom two bits, leaves which ID in the reg it is (which byte)
MOV r2, r2, LSL #3 // Multiply by 8, this gives a bit offset

// Read -> Modify -> Write
MOV r12, #0xFF // 8 bit field mask
MOV r12, r12, LSL r2 // Move mask into correct bit position
MOV r1, r1, LSL r2 // Also, move passed in priority value into correct bit position

LDR r3, [r0] // Read current value of the Priority Level register (ICDIPR)
BIC r3, r3, r12 // Clear appropriate field
ORR r3, r3, r1 // Now OR in the priority value
STR r3, [r0] // And store it back again (ICDIPR)

BX lr


// ------------------------------------------------------------

.global enableGICProcessorInterface
.type enableGICProcessorInterface,function
// void enableGICProcessorInterface(void)
// Enables the processor interface
// Must be done on each core separately
enableGICProcessorInterface:
MRC p15, 4, r0, c15, c0, 0 // Read periph base address
ADD r0, r0, #0x2000

LDR r1, [r0, #0x0] // Read the Processor Interface Control register (ICCICR/ICPICR)
ORR r1, r1, #0x03 // Bit 0: Enables secure interrupts, Bit 1: Enables Non-Secure interrupts
BIC r1, r1, #0x08 // Bit 3: Ensure Group 0 interrupts are signalled using IRQ, not FIQ
STR r1, [r0, #0x0] // Write the Processor Interface Control register (ICCICR/ICPICR)

BX lr



// ------------------------------------------------------------

.global disableGICProcessorInterface
.type disableGICProcessorInterface,function
// void disableGICProcessorInterface(void)
// Disables the processor interface
// Must be done on each core separately
disableGICProcessorInterface:

MRC p15, 4, r0, c15, c0, 0 // Read periph base address
ADD r0, r0, #0x2000

LDR r1, [r0, #0x0] // Read the Processor Interface Control register (ICCICR/ICPICR)
BIC r1, r1, #0x03 // Bit 0: Enables secure interrupts, Bit 1: Enables Non-Secure interrupts
STR r1, [r0, #0x0] // Write the Processor Interface Control register (ICCICR/ICPICR)

BX lr



// ------------------------------------------------------------

.global setPriorityMask
.type setPriorityMask,function
// void setPriorityMask(unsigned int priority)
// Sets the Priority mask register for the CPU run on
// The reset value masks ALL interrupts!
setPriorityMask:

// Get base address of private peripheral space
MRC p15, 4, r1, c15, c0, 0 // Read periph base address
ADD r1, r1, #0x2000

STR r0, [r1, #0x4] // Write the Priority Mask register (ICCPMR/ICCIPMR)

BX lr


// ------------------------------------------------------------

.global setBinaryPoint
.type setBinaryPoint,function
// void setBinaryPoint(unsigned int priority)
// Sets the Binary Point Register for the CPU run on
setBinaryPoint:

// Get base address of private peripheral space
MRC p15, 4, r1, c15, c0, 0 // Read periph base address
ADD r1, r1, #0x2000

STR r0, [r1, #0x8] // Write the Binary register (ICCBPR/ICCBPR)

BX lr


// ------------------------------------------------------------

.global readIntAck
.type readIntAck,function
// unsigned int readIntAck(void)
// Returns the value of the Interrupt Acknowledge Register
readIntAck:
MRC p15, 4, r0, c15, c0, 0 // Read periph base address
ADD r0, r0, #0x2000

LDR r0, [r0, #0xC] // Read the Interrupt Acknowledge Register (ICCIAR)
BX lr


// ------------------------------------------------------------

.global writeEOI
.type writeEOI,function
// void writeEOI(unsigned int ID)
// Writes ID to the End Of Interrupt register
writeEOI:

// Get base address of private peripheral space
MRC p15, 4, r1, c15, c0, 0 // Read periph base address
ADD r1, r1, #0x2000

STR r0, [r1, #0x10] // Write ID to the End of Interrupt register (ICCEOIR)

BX lr


//----------------------------------------------------------------
// SGI
//----------------------------------------------------------------

.global sendSGI
.type sendSGI,function
// void sendSGI(unsigned int ID, unsigned int target_list, unsigned int filter_list)//
// Send a software generate interrupt
sendSGI:
AND r3, r0, #0x0F // Mask off unused bits of ID, and move to r3
AND r1, r1, #0x0F // Mask off unused bits of target_filter
AND r2, r2, #0x0F // Mask off unused bits of filter_list

ORR r3, r3, r1, LSL #16 // Combine ID and target_filter
ORR r3, r3, r2, LSL #24 // and now the filter list

// Get the address of the GIC
MRC p15, 4, r0, c15, c0, 0 // Read periph base address
ADD r0, r0, #0x1F00 // Add offset of the sgi_trigger reg

STR r3, [r0] // Write to the Software Generated Interrupt Register (ICDSGIR)

BX lr


//----------------------------------------------------------------
// End of MP_GIC.s
//----------------------------------------------------------------
Loading

0 comments on commit a0a0ef9

Please sign in to comment.