Fixed the issue of the data/bss section cannot be read from ARM FVP debug tool in cortex-A9 GNU port. (#303)

https://msazure.visualstudio.com/One/_workitems/edit/25153785/
This commit is contained in:
Yajun Xia
2023-09-18 16:36:36 +08:00
committed by GitHub
parent a0a0ef9385
commit d43cba10b2
7 changed files with 871 additions and 27 deletions
File diff suppressed because it is too large Load Diff
+120
View File
@@ -0,0 +1,120 @@
// ------------------------------------------------------------
// Cortex-A 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_H
#define _CORTEXA_GIC_H
#define SPURIOUS (255)
// PPI IDs:
#define MPCORE_PPI_PRIVATE_TIMER (29)
#define MPCORE_PPI_PRIVATE_WD (30)
#define MPCORE_PPI_GLOBAL_TIMER (27)
#define MPCORE_PPI_LEGACY_IRQ (31)
#define MPCORE_PPI_LEGACY_FIQ (28)
// ------------------------------------------------------------
// GIC
// ------------------------------------------------------------
// 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 Core's priority mask to 0x1F (the lowest priority)
// enableGIC() <-- Enable the GIC (global)
// enableGICProcessorInterface() <-- 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);
// 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!
//
// NOTE: Bits 2:0 of this register are SBZ, the function does perform any shifting!
void setPriorityMask(unsigned int priority);
// Sets the Binary Point Register for the core run on
void setBinaryPoint(unsigned int priority);
// Sets the priority of the specified ID
void setIntPriority(unsigned int ID, unsigned int priority);
// Returns the priority of the specified ID
unsigned int getIntPriority(unsigned int ID, unsigned int priority);
#define MPCORE_IC_TARGET_NONE (0x0)
#define MPCORE_IC_TARGET_CPU0 (0x1)
#define MPCORE_IC_TARGET_CPU1 (0x2)
#define MPCORE_IC_TARGET_CPU2 (0x4)
#define MPCORE_IC_TARGET_CPU3 (0x8)
// Sets the target CPUs of the specified ID
// For 'target' use one of the above defines
void setIntTarget(unsigned int ID, unsigned int target);
// Returns the target CPUs of the specified ID
unsigned int getIntTarget(unsigned int ID);
// 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);
// ------------------------------------------------------------
// TrustZone
// ------------------------------------------------------------
// Enables the sending of secure interrupts as FIQs
void enableSecureFIQs(void);
// Disables the sending of secure interrupts as FIQs
void disableSecureFIQs(void);
// Sets the specified ID as secure
void makeIntSecure(unsigned int ID);
// Set the specified ID as non-secure
void makeIntNonSecure(unsigned int ID);
// Returns the security of the specified ID
unsigned int getIntSecurity(unsigned int ID);
#endif
// ------------------------------------------------------------
// End of MP_GIC.h
// ------------------------------------------------------------
@@ -0,0 +1,118 @@
// ------------------------------------------------------------
// Cortex-A MPCore - Private timer functions
//
// Copyright ARM Ltd 2009. All rights reserved.
// ------------------------------------------------------------
.text
.align 4
// PPI ID 29
// Typical set of calls to enable Timer:
// init_private_timer(0xXXXX, 0) <-- Counter down value of 0xXXXX, with auto-reload
// start_private_timer()
// Timer offset from base of private peripheral space --> 0x600
// ------------------------------------------------------------
.global init_private_timer
.type init_private_timer,function
// void init_private_timer(unsigned int load_value, unsigned int auto_reload)
// Sets up the private timer
// r0: initial load value
// r1: IF 0 (AutoReload) ELSE (SingleShot)
init_private_timer:
// Get base address of private perpherial space
MOV r2, r0 // Make a copy of r0 before corrupting
MRC p15, 4, r0, c15, c0, 0 // Read periph base address
// Set the load value
STR r2, [r0, #0x600]
// Control register bit layout
// Bit 0 - Enable
// Bit 1 - Auto-Reload // see DE681117
// Bit 2 - IRQ Generation
// Form control reg value
CMP r1, #0 // Check whether to enable auto-reload
MOVNE r2, #0x04 // No auto-reload
MOVEQ r2, #0x06 // With auto-reload
// Store to control register
STR r2, [r0, #0x608]
BX lr
// ------------------------------------------------------------
// void start_private_timer(void)
// Starts the private timer
.global start_private_timer
.type start_private_timer,function
start_private_timer:
MRC p15, 4, r0, c15, c0, 0 // Read periph base address
LDR r1, [r0, #0x608] // Read control reg
ORR r1, r1, #0x01 // Set enable bit
STR r1, [r0, #0x608] // Write modified value back
BX lr
// ------------------------------------------------------------
// void stop_private_timer(void)
// Stops the private timer
.global stop_private_timer
.type stop_private_timer,function
stop_private_timer:
MRC p15, 4, r0, c15, c0, 0 // Read periph base address
LDR r1, [r0, #0x608] // Read control reg
BIC r1, r1, #0x01 // Clear enable bit
STR r1, [r0, #0x608] // Write modified value back
BX lr
// ------------------------------------------------------------
// unsigned int read_private_timer(void)
// Reads the current value of the timer count register
.global get_private_timer_count
.type get_private_timer_count,function
get_private_timer_count:
MRC p15, 4, r0, c15, c0, 0 // Read periph base address
LDR r0, [r0, #0x604] // Read count register
BX lr
// ------------------------------------------------------------
// void clear_private_timer_irq(void)
// Clears the private timer interrupt
.global clear_private_timer_irq
.type clear_private_timer_irq,function
clear_private_timer_irq:
MRC p15, 4, r0, c15, c0, 0 // Read periph base address
// Clear the interrupt by writing 0x1 to the Timer's Interrupt Status register
MOV r1, #1
STR r1, [r0, #0x60C]
BX lr
// ------------------------------------------------------------
// End of code
// ------------------------------------------------------------
// ------------------------------------------------------------
// End of MP_PrivateTimer.s
// ------------------------------------------------------------
@@ -0,0 +1,36 @@
// ------------------------------------------------------------
// Cortex-A MPCore - Private timer functions
// Header Filer
//
// Copyright ARM Ltd 2009. All rights reserved.
// ------------------------------------------------------------
#ifndef _CORTEXA_PRIVATE_TIMER_
#define _CORTEXA_PRIVATE_TIMER_
// Typical set of calls to enable Timer:
// init_private_timer(0xXXXX, 0) <-- Counter down value of 0xXXXX, with auto-reload
// start_private_timer()
// Sets up the private timer
// r0: initial load value
// r1: IF 0 (AutoReload) ELSE (SingleShot)
void init_private_timer(unsigned int load_value, unsigned int auto_reload);
// Starts the private timer
void start_private_timer(void);
// Stops the private timer
void stop_private_timer(void);
// Reads the current value of the timer count register
unsigned int get_private_timer_count(void);
// Clears the private timer interrupt
void clear_private_timer_irq(void);
#endif
// ------------------------------------------------------------
// End of MP_PrivateTimer.h
// ------------------------------------------------------------
@@ -1,6 +1,8 @@
arm-none-eabi-gcc -c -g -mcpu=cortex-a9 reset.S
arm-none-eabi-gcc -c -g -mcpu=cortex-a9 crt0.S
arm-none-eabi-gcc -c -g -mcpu=cortex-a9 tx_initialize_low_level.S
arm-none-eabi-gcc -c -g -mcpu=cortex-a9 MP_GIC.s
arm-none-eabi-gcc -c -g -mcpu=cortex-a9 MP_PrivateTimer.s
arm-none-eabi-gcc -c -g -mcpu=cortex-a9 V7.s
arm-none-eabi-gcc -c -g -mcpu=cortex-a9 -I../../../../common/inc -I../inc sample_threadx.c
arm-none-eabi-gcc -g -mcpu=cortex-a8 -T sample_threadx.ld --specs=nosys.specs -o sample_threadx.out -Wl,-Map=sample_threadx.map tx_initialize_low_level.o sample_threadx.o tx.a
arm-none-eabi-gcc -g -nostartfiles -mcpu=cortex-a9 -T sample_threadx.ld --specs=nosys.specs -o sample_threadx.out -Wl,-Map=sample_threadx.map MP_GIC.o MP_PrivateTimer.o V7.o crt0.o reset.o tx_initialize_low_level.o sample_threadx.o tx.a
@@ -41,8 +41,13 @@ SYS_STACK_SIZE = 1024 // System stack size
.global _end
.global _sp
.global _stack_bottom
.global __vectors
.global disableHighVecs
.global enableGIC
.global enableGICProcessorInterface
.global enableCaches
.global init_private_timer
.global start_private_timer
/* Define the 16-bit Thumb mode veneer for _tx_initialize_low_level for
applications calling this function from to 16-bit Thumb mode. */
@@ -160,6 +165,57 @@ _stack_error_loop:
ADD r1, r1, #8 // Increment to next free word
STR r1, [r2] // Save first free memory address
PUSH {lr}
/* Setup the vector table. */
LDR r0, =__vectors // Get address of vector table
MCR p15, 0, r0, c12, c0, 0 // Write vector table address to CP15
BL disableHighVecs // Disable high vectors
//
// GIC Init
// ---------
BL enableGIC
BL enableGICProcessorInterface
//
// Enable Private Timer for periodic IRQ
// --------------------------------------
MOV r0, #0x1F
BL setPriorityMask // Set priority mask (local)
// [EL] Change start - don't enable interrupts here!
//CPSIE i // Clear CPSR I bit
// [EL] Change end
// Enable the Private Timer Interrupt Source
MOV r0, #29
MOV r1, #0
BL enableIntID
// Set the priority
MOV r0, #29
MOV r1, #0
BL setIntPriority
// Configure Timer
MOV r0, #0xF0000
MOV r1, #0x0
BL init_private_timer
BL start_private_timer
//
// Enable receipt of SGI 0
// ------------------------
MOV r0, #0x0 // ID
BL enableIntID
// Set the priority
MOV r0, #0x0 // ID
MOV r1, #0x0 // Priority
BL setIntPriority
POP {lr}
#ifdef __THUMB_INTERWORK
BX lr // Return to caller
#else
@@ -202,16 +258,16 @@ __tx_irq_processing_return:
if nested IRQ interrupts are desired. Interrupts may be re-enabled over
small code sequences where lr is saved before enabling interrupts and
restored after interrupts are again disabled. */
PUSH {r4, r5} // Save some preserved registers (r5 is saved just for 8-byte alignment)
BL readIntAck
MOV r4, r0
/* Interrupt nesting is allowed after calling _tx_thread_irq_nesting_start
from IRQ mode with interrupts disabled. This routine switches to the
system mode and returns with IRQ interrupts enabled.
CMP r0, #29 // If not Private Timer interrupt (ID 29), by pass
BNE by_pass_timer_interrupt
NOTE: It is very important to ensure all IRQ interrupts are cleared
prior to enabling nested IRQ interrupts. */
#ifdef TX_ENABLE_IRQ_NESTING
BL _tx_thread_irq_nesting_start
#endif
BL clear_private_timer_irq
DSB
/* For debug purpose, execute the timer interrupt processing here. In
a real system, some kind of status indication would have to be checked
@@ -219,13 +275,10 @@ __tx_irq_processing_return:
BL _tx_timer_interrupt // Timer interrupt handler
/* If interrupt nesting was started earlier, the end of interrupt nesting
service must be called before returning to _tx_thread_context_restore.
This routine returns in processing in IRQ mode with interrupts disabled. */
#ifdef TX_ENABLE_IRQ_NESTING
BL _tx_thread_irq_nesting_end
#endif
by_pass_timer_interrupt:
MOV r0, r4
BL writeEOI
POP {r4, r5} // Recover preserved registers
/* Jump to context restore to restore system context. */
B _tx_thread_context_restore
@@ -1,18 +1,18 @@
>output thread_0_counter
2913840557
10
>output thread_1_counter
2913840557
599068
>output thread_2_counter
2913840557
599046
>output thread_3_counter
2913840557
23
>output thread_4_counter
2913840557
23
>output thread_5_counter
2913840557
9
>output thread_6_counter
2913840557
23
>output thread_7_counter
2913840557
23
>log file
Stopped duplicating logging output