Return to Unit Reference
Description
The ARMv7 does not support the SWP/SWPB instructions for syncronisation (Lock/Mutex/Semaphore etc) unless enabled.
On ARMv7 Unaligned memory access is always enabled.
On ARMv7 the Extended Page Table format is always enabled.
For usage of barriers (DMB/DSB/ISB) after cache maintenance operations see: ARM.Reference_Manual_1.pdf - Appendix G Barrier Litmus Tests
Constants
To be documented
Type definitions
To be documented
Public variables
To be documented
Function declarations
Initialization functions
procedure ARMv7Init;
Description: To be documented
ARMv7 platform functions
procedure ARMv7CPUInit; assembler; nostackframe;
Description: To be documented
procedure ARMv7FPUInit; assembler; nostackframe;
Description: To be documented
procedure ARMv7MMUInit;
Description: To be documented
procedure ARMv7CacheInit; assembler; nostackframe;
Description: To be documented
procedure ARMv7TimerInit(Frequency:LongWord); assembler; nostackframe;
Description: To be documented
procedure ARMv7PageTableInit;
Description: Initialize the Hardware Page Tables before enabling the MMU
procedure ARMv7SystemCall(Number:LongWord; Param1,Param2,Param3:LongWord); assembler; nostackframe;
Description: To be documented
function ARMv7CPUGetMode:LongWord; assembler; nostackframe;
Description: To be documented
function ARMv7CPUGetState:LongWord; assembler; nostackframe;
Description: To be documented
function ARMv7CPUGetCurrent:LongWord; assembler; nostackframe;
Description: To be documented
function ARMv7CPUGetMainID:LongWord; assembler; nostackframe;
Description: To be documented
function ARMv7CPUGetMultiprocessorID:LongWord; assembler; nostackframe;
Description: To be documented
function ARMv7CPUGetModel:LongWord;
Description: To be documented
function ARMv7CPUGetRevision:LongWord;
Description: To be documented
function ARMv7CPUGetDescription:String;
Description: To be documented
function ARMv7FPUGetState:LongWord; assembler; nostackframe;
Description: To be documented
function ARMv7L1CacheGetType:LongWord; assembler; nostackframe;
Description: To be documented
function ARMv7L1DataCacheGetSize:LongWord; assembler; nostackframe;
Description: To be documented
function ARMv7L1DataCacheGetLineSize:LongWord; assembler; nostackframe;
Description: To be documented
function ARMv7L1InstructionCacheGetSize:LongWord; assembler; nostackframe;
Description: To be documented
function ARMv7L1InstructionCacheGetLineSize:LongWord; assembler; nostackframe;
Description: To be documented
function ARMv7L2CacheGetType:LongWord; assembler; nostackframe;
Description: To be documented
function ARMv7L2CacheGetSize:LongWord; assembler; nostackframe;
Description: To be documented
function ARMv7L2CacheGetLineSize:LongWord; assembler; nostackframe;
Description: To be documented
procedure ARMv7Halt; assembler; nostackframe; public name'_haltproc';
Description: The purpose of the Wait For Interrupt operation is to put the processor in to a low power state
| Note
|
See Standby mode on page A8-810 of the ARMv7 Architecture Reference Manual
|
procedure ARMv7Pause; assembler; nostackframe;
Description: The purpose of the Wait For Interrupt operation is to put the processor in to a low power state
| Note
|
See Standby mode on page A8-810 of the ARMv7 Architecture Reference Manual
|
procedure ARMv7SendEvent; assembler; nostackframe;
Description: To be documented
| Note
|
See Page A8-316 of the ARMv7 Architecture Reference Manual
|
procedure ARMv7WaitForEvent; assembler; nostackframe;
Description: To be documented
| Note
|
See Page A8-808 of the ARMv7 Architecture Reference Manual
|
procedure ARMv7WaitForInterrupt; assembler; nostackframe;
Description: The purpose of the Wait For Interrupt operation is to put the processor in to a low power state
| Note
|
See Standby mode on page A8-810 of the ARMv7 Architecture Reference Manual
|
procedure ARMv7DataMemoryBarrier; assembler; nostackframe;
Description: Perform a data memory barrier operation using the c7 (Cache Operations) register of system control coprocessor CP15
| Note
|
See page A8-90 of the ARMv7 Architecture Reference Manual
Note that this is also available in the FPC RTL as ReadBarrier/WriteBarrier See: \source\rtl\arm\arm.inc
Implementation is exactly the same for either.
|
procedure ARMv7DataSynchronizationBarrier; assembler; nostackframe;
Description: Perform a data synchronization barrier operation
| Note
|
See page A8-92 of the ARMv7 Architecture Reference Manual
|
procedure ARMv7InstructionMemoryBarrier; assembler; nostackframe;
Description: Perform a instruction synchronization barrier operation
| Note
|
See page A8-102 of the ARMv7 Architecture Reference Manual
|
procedure ARMv7InvalidateTLB; assembler; nostackframe;
Description: Perform an invalidate entire TLB operation using the c8 (TLB Operations) register of system control coprocessor CP15
| Note
|
See page B3-138 of the ARMv7 Architecture Reference Manual
|
procedure ARMv7InvalidateDataTLB; assembler; nostackframe;
Description: Perform an invalidate data TLB (Unlocked/Data) operation using the c8 (TLB Operations) register of system control coprocessor CP15
| Note
|
See page B3-138 of the ARMv7 Architecture Reference Manual
|
procedure ARMv7InvalidateInstructionTLB; assembler; nostackframe;
Description: Perform an invalidate instruction TLB (Unlocked/Instruction) operation using the c8 (TLB Operations) register of system control coprocessor CP15
| Note
|
See page B3-138 of the ARMv7 Architecture Reference Manual
|
procedure ARMv7InvalidateCache; assembler; nostackframe;
Description: Perform an invalidate both caches operation using the c7 (Cache Operations) register of system control coprocessor CP15
| Note
|
See page B3-127 of the ARMv7 Architecture Reference Manual
|
procedure ARMv7CleanDataCache; assembler; nostackframe;
Description: Perform a clean entire data cache operation
| Note
|
See page B3-127 of the ARMv7 Architecture Reference Manual
|
procedure ARMv7InvalidateDataCache; assembler; nostackframe;
Description: Perform an invalidate entire data cache operation
| Note
|
See page B3-127 of the ARMv7 Architecture Reference Manual
|
procedure ARMv7InvalidateL1DataCache; assembler; nostackframe;
Description: Perform an invalidate entire L1 data cache operation
| Note
|
See page B3-127 of the ARMv7 Architecture Reference Manual
|
procedure ARMv7CleanAndInvalidateDataCache; assembler; nostackframe;
Description: Perform a clean and invalidate entire data cache operation
| Note
|
See page B3-127 of the ARMv7 Architecture Reference Manual
|
procedure ARMv7InvalidateInstructionCache; assembler; nostackframe;
Description: Perform an invalidate entire instruction cache operation using the c7 (Cache Operations) register of system control coprocessor CP15
| Note
|
See page B3-127 of the ARMv7 Architecture Reference Manual
|
procedure ARMv7CleanDataCacheRange(Address,Size:LongWord); assembler; nostackframe;
Description: Perform a clean data cache by MVA to PoC operation
| Note
|
See page B3-127 of the ARMv7 Architecture Reference Manual
|
procedure ARMv7InvalidateDataCacheRange(Address,Size:LongWord); assembler; nostackframe;
Description: Perform an invalidate data cache by MVA to PoC operation
| Note
|
See page B3-127 of the ARMv7 Architecture Reference Manual
|
procedure ARMv7CleanAndInvalidateDataCacheRange(Address,Size:LongWord); assembler; nostackframe;
Description: Perform a clean and invalidate data cache by MVA to PoC operation
| Note
|
See page B3-127 of the ARMv7 Architecture Reference Manual
|
procedure ARMv7InvalidateInstructionCacheRange(Address,Size:LongWord); assembler; nostackframe;
Description: Perform an invalidate instruction caches by MVA to PoU operation
| Note
|
See page B3-127 of the ARMv7 Architecture Reference Manual
|
procedure ARMv7CleanDataCacheSetWay(SetWay:LongWord); assembler; nostackframe;
Description: Perform a clean data cache line by set/way operation
| SetWay
|
Set/Way/Level will be passed in r0
|
| Note
|
See page B3-127 of the ARMv7 Architecture Reference Manual
|
procedure ARMv7InvalidateDataCacheSetWay(SetWay:LongWord); assembler; nostackframe;
Description: Perform an invalidate data cache line by set/way operation
| SetWay
|
Set/Way/Level will be passed in r0
|
| Note
|
See page B3-127 of the ARMv7 Architecture Reference Manual
|
procedure ARMv7CleanAndInvalidateDataCacheSetWay(SetWay:LongWord); assembler; nostackframe;
Description: Perform a clean and invalidate data cache line by set/way operation
| SetWay
|
Set/Way/Level will be passed in r0
|
| Note
|
See page B3-127 of the ARMv7 Architecture Reference Manual
|
procedure ARMv7FlushPrefetchBuffer; assembler; nostackframe;
Description: Perform an Instruction Synchronization Barrier operation
| Note
|
See page A8-102 of the ARMv7 Architecture Reference Manual
|
procedure ARMv7FlushBranchTargetCache; assembler; nostackframe;
Description: Perform a Flush Entire Branch Target Cache operation
| Note
|
See page B3-127 of the ARMv7 Architecture Reference Manual
|
procedure ARMv7ContextSwitch(OldStack,NewStack:Pointer; NewThread:TThreadHandle); assembler; nostackframe;
Description: Perform a context switch from one thread to another as a result of a thread yielding, sleeping or waiting
| OldStack
|
The address to save the stack pointer to for the current thread (Passed in r0)
|
| NewStack
|
The address to restore the stack pointer from for the new thread (Passed in r1)
|
| NewThread
|
The handle of the new thread to switch to (Passed in r2)
|
| Note
|
At the point of the actual context switch (str sp / ldr sp) the thread stacks will look like this:
(See: ARMv7ThreadSetupStack for additional information)
(Base "Highest Address" of Stack)
.
.
.
.
cpsr <- The current program status register value to load on return from the context switch
lr/pc <- The address to return to from the context switch
lr <- The lr value prior to the context switch
r12 <-
r11 <-
r10 <-
r9 <-
r8 <-
r7 <-
r6 <- The value of these registers prior to the context switch
r5 <-
r4 <-
r3 <-
r2 <-
r1 <-
r0 <-
d15 <-
d14 <-
d13 <-
d12 <-
d11 <-
d10 <-
d9 <-
d8 <- The value of these floating point registers prior to the context switch
d7 <-
d6 <-
d5 <-
d4 <-
d3 <-
d2 <-
d1 <-
d0 <-
fpscr <- The floating point FPSCR register
fpexc <- The floating point FPEXC register (Current StackPointer points to here)
.
.
.
.
(Top "Lowest Address" of Stack)
This form of context switch uses r12 to save the cpsr value (and RFE to restore it). Because this context switch is called from a routine which will have saved the value of r12 (which is caller save in the ARM ABI) then we do not need to save the original value of r12.
The context switch will be performed from SYS mode to SYS mode, the cpsr value will include the control bits (Mode and IRQ/FIQ state) but not the flags values. Again the ARM ABI does not require that the flags be saved by the callee and so the caller would have accounted for any needed flags before calling. If the thread to be resumed was interrupted by an IRQ or FIQ then the cpsr will also contain the flags etc as they were at the point of interrupt. We do not need to account for the state bits in the cpsr since all operations are performed in ARM mode at present.
The main requirement of this routine is to ensure that the context record on the stack matches exactly that which is created on an interrupt and also that created by ThreadSetupStack for a new thread. If this is correct then the next context switch for any given thread can be either by a call to reschedule or by an interrupt. Equally a new thread can be first run from a context switch that resulted from either a call to reschedule or an interrupt.
Note that this routine could use:
pop (lr)
pop (r12)
msr cpsr_c, r12
mov pc, lr
To return but that would mess up the value of r12, lr and the cpsr flags etc if the thread being resumed was interrupted by an IRQ, FIQ or SWI. The use of RFE here allows for exactly the same behaviour no matter which way the context record is saved and restored.
|
procedure ARMv7ContextSwitchIRQ(OldStack,NewStack:Pointer; NewThread:TThreadHandle); assembler; nostackframe;
Description: Perform a context switch from one thread to another as a result of an interrupt request (IRQ)
| OldStack
|
The address to save the stack pointer to for the current thread (Passed in r0)
|
| NewStack
|
The address to restore the stack pointer from for the new thread (Passed in r1)
|
| NewThread
|
The handle of the new thread to switch to (Passed in r2)
|
| Note
|
At the point of the actual context switch (str sp / ldr sp) the thread stacks will look like this:
(See: ARMv7ThreadSetupStack for additional information)
(Base "Highest Address" of Stack)
.
.
.
.
cpsr <- The current program status register value to load on return from the context switch
lr/pc <- The address to return to from the context switch
lr <- The lr value prior to the context switch
r12 <-
r11 <-
r10 <-
r9 <-
r8 <-
r7 <-
r6 <- The value of these registers prior to the context switch
r5 <-
r4 <-
r3 <-
r2 <-
r1 <-
r0 <-
d15 <-
d14 <-
d13 <-
d12 <-
d11 <-
d10 <-
d9 <-
d8 <- The value of these floating point registers prior to the context switch
d7 <-
d6 <-
d5 <-
d4 <-
d3 <-
d2 <-
d1 <-
d0 <-
fpscr <- The floating point FPSCR register
fpexc <- The floating point FPEXC register (Current StackPointer points to here)
.
.
.
.
(Top "Lowest Address" of Stack)
This form of context switch relies on the IRQ handler to save the necessary registers including the lr, cpsr and other general registers from the point at which the thread was interrupted. The thread to be resumed may have been saved by a previous IRQ or by a call to the standard context switch from SchedulerReschule or it may be a new thread to be run for the first time. All of these result in the same context record on the stack and therefore can be resumed the same way.
The context switch will be performed by switching to SYS mode, exchanging the stack pointers and then returning to IRQ mode.
|
procedure ARMv7ContextSwitchFIQ(OldStack,NewStack:Pointer; NewThread:TThreadHandle); assembler; nostackframe;
Description: Perform a context switch from one thread to another as a result of a fast interrupt request (FIQ)
| OldStack
|
The address to save the stack pointer to for the current thread (Passed in r0)
|
| NewStack
|
The address to restore the stack pointer from for the new thread (Passed in r1)
|
| NewThread
|
The handle of the new thread to switch to (Passed in r2)
|
| Note
|
At the point of the actual context switch (str sp / ldr sp) the thread stacks will look like this:
(See: ARMv7ThreadSetupStack for additional information)
(Base "Highest Address" of Stack)
.
.
.
.
cpsr <- The current program status register value to load on return from the context switch
lr/pc <- The address to return to from the context switch
lr <- The lr value prior to the context switch
r12 <-
r11 <-
r10 <-
r9 <-
r8 <-
r7 <-
r6 <- The value of these registers prior to the context switch
r5 <-
r4 <-
r3 <-
r2 <-
r1 <-
r0 <-
d15 <-
d14 <-
d13 <-
d12 <-
d11 <-
d10 <-
d9 <-
d8 <- The value of these floating point registers prior to the context switch
d7 <-
d6 <-
d5 <-
d4 <-
d3 <-
d2 <-
d1 <-
d0 <-
fpscr <- The floating point FPSCR register
fpexc <- The floating point FPEXC register (Current StackPointer points to here)
.
.
.
.
(Top "Lowest Address" of Stack)
This form of context switch relies on the FIQ handler to save the necessary registers including the lr, cpsr and other general registers from the point at which the thread was interrupted. The thread to be resumed may have been saved by a previous FIQ or by a call to the standard context switch from SchedulerReschule or it may be a new thread to be run for the first time. All of these result in the same context record on the stack and therefore can be resumed the same way.
The context switch will be performed by switching to SYS mode, exchanging the stack pointers and then returning to FIQ mode.
|
procedure ARMv7ContextSwitchSWI(OldStack,NewStack:Pointer; NewThread:TThreadHandle); assembler; nostackframe;
Description: Perform a context switch from one thread to another as a result of a software interrupt (SWI)
| OldStack
|
The address to save the stack pointer to for the current thread (Passed in r0)
|
| NewStack
|
The address to restore the stack pointer from for the new thread (Passed in r1)
|
| NewThread
|
The handle of the new thread to switch to (Passed in r2)
|
| Note
|
At the point of the actual context switch (str sp / ldr sp) the thread stacks will look like this:
(See: ARMv7ThreadSetupStack for additional information)
(Base "Highest Address" of Stack)
.
.
.
.
cpsr <- The current program status register value to load on return from the context switch
lr/pc <- The address to return to from the context switch
lr <- The lr value prior to the context switch
r12 <-
r11 <-
r10 <-
r9 <-
r8 <-
r7 <-
r6 <- The value of these registers prior to the context switch
r5 <-
r4 <-
r3 <-
r2 <-
r1 <-
r0 <-
d15 <-
d14 <-
d13 <-
d12 <-
d11 <-
d10 <-
d9 <-
d8 <- The value of these floating point registers prior to the context switch
d7 <-
d6 <-
d5 <-
d4 <-
d3 <-
d2 <-
d1 <-
d0 <-
fpscr <- The floating point FPSCR register
fpexc <- The floating point FPEXC register (Current StackPointer points to here)
.
.
.
.
(Top "Lowest Address" of Stack)
This form of context switch relies on the SWI handler to save the necessary registers including the lr, cpsr and other general registers from the point at which the thread was interrupted. The thread to be resumed may have been saved by a previous SWI or by a call to the standard context switch from SchedulerReschule or it may be a new thread to be run for the first time. All of these result in the same context record on the stack and therefore can be resumed the same way.
The context switch will be performed by switching to SYS mode, exchanging the stack pointers and then returning to SWI (SVC) mode.
|
function ARMv7InterlockedOr(var Target:LongInt; Value:LongInt):LongInt; assembler; nostackframe;
Description: Perform an atomic OR operation using LDREX/STREX
function ARMv7InterlockedXor(var Target:LongInt; Value:LongInt):LongInt; assembler; nostackframe;
Description: Perform an atomic XOR operation using LDREX/STREX
function ARMv7InterlockedAnd(var Target:LongInt; Value:LongInt):LongInt; assembler; nostackframe;
Description: Perform an atomic AND operation using LDREX/STREX
function ARMv7InterlockedDecrement(var Target:LongInt):LongInt; assembler; nostackframe;
Description: Perform an atomic decrement operation using LDREX/STREX
function ARMv7InterlockedIncrement(var Target:LongInt):LongInt; assembler; nostackframe;
Description: Perform an atomic increment operation using LDREX/STREX
function ARMv7InterlockedExchange(var Target:LongInt; Source:LongInt):LongInt; assembler; nostackframe;
Description: Perform an atomic exchange operation using LDREX/STREX
function ARMv7InterlockedAddExchange(var Target:LongInt; Source:LongInt):LongInt; assembler; nostackframe;
Description: Perform an atomic add and exchange operation using LDREX/STREX
function ARMv7InterlockedCompareExchange(var Target:LongInt; Source,Compare:LongInt):LongInt; assembler; nostackframe;
Description: Perform an atomic compare and exchange operation using LDREX/STREX
function ARMv7PageTableGetEntry(Address:PtrUInt):TPageTableEntry;
Description: Get and Decode the entry in the Page Table that corresponds to the supplied virtual address
function ARMv7PageTableSetEntry(const Entry:TPageTableEntry):LongWord;
Description: Encode and Set an entry in the Page Table that corresponds to the supplied virtual address
function ARMv7VectorTableGetEntry(Number:LongWord):PtrUInt;
Description: Return the address of the specified vector table entry number
function ARMv7VectorTableSetEntry(Number:LongWord; Address:PtrUInt):LongWord;
Description: Set the supplied address as the value of the specified vector table entry number
function ARMv7FirstBitSet(Value:LongWord):LongWord; assembler; nostackframe;
Description: To be documented
| Note
|
ARM arm states that CLZ is supported for ARMv5 and above
|
function ARMv7CountLeadingZeros(Value:LongWord):LongWord; assembler; nostackframe;
Description: Equivalent of the GCC Builtin function __builtin_clz
| Note
|
ARM arm states that CLZ is supported for ARMv5 and above
|
ARMv7 thread functions
procedure ARMv7PrimaryInit; assembler; nostackframe;
Description: To be documented
function ARMv7SpinLock(Spin:PSpinEntry):LongWord; assembler; nostackframe;
Description: Lock an existing Spin entry
| Spin
|
Pointer to the Spin entry to lock (Passed in R0)
|
| Return
|
ERROR_SUCCESS if completed or another error code on failure (Returned in R0)
|
function ARMv7SpinUnlock(Spin:PSpinEntry):LongWord; assembler; nostackframe;
Description: Unlock an existing Spin entry
| Spin
|
Pointer to the Spin entry to lock (Passed in R0)
|
| Return
|
ERROR_SUCCESS if completed or another error code on failure (Returned in R0)
|
function ARMv7SpinLockIRQ(Spin:PSpinEntry):LongWord; assembler; nostackframe;
Description: Lock an existing Spin entry, disable IRQ and save the previous IRQ state
| Spin
|
Pointer to the Spin entry to lock (Passed in R0)
|
| Return
|
ERROR_SUCCESS if completed or another error code on failure (Returned in R0)
|
function ARMv7SpinUnlockIRQ(Spin:PSpinEntry):LongWord; assembler; nostackframe;
Description: Unlock an existing Spin entry and restore the previous IRQ state
| Spin
|
Pointer to the Spin entry to lock (Passed in R0)
|
| Return
|
ERROR_SUCCESS if completed or another error code on failure (Returned in R0)
|
function ARMv7SpinLockFIQ(Spin:PSpinEntry):LongWord; assembler; nostackframe;
Description: Lock an existing Spin entry, disable FIQ and save the previous FIQ state
| Spin
|
Pointer to the Spin entry to lock (Passed in R0)
|
| Return
|
ERROR_SUCCESS if completed or another error code on failure (Returned in R0)
|
function ARMv7SpinUnlockFIQ(Spin:PSpinEntry):LongWord; assembler; nostackframe;
Description: Unlock an existing Spin entry and restore the previous FIQ state
| Spin
|
Pointer to the Spin entry to lock (Passed in R0)
|
| Return
|
ERROR_SUCCESS if completed or another error code on failure (Returned in R0)
|
function ARMv7SpinLockIRQFIQ(Spin:PSpinEntry):LongWord; assembler; nostackframe;
Description: Lock an existing Spin entry, disable IRQ and FIQ and save the previous IRQ/FIQ state
| Spin
|
Pointer to the Spin entry to lock (Passed in R0)
|
| Return
|
ERROR_SUCCESS if completed or another error code on failure (Returned in R0)
|
function ARMv7SpinUnlockIRQFIQ(Spin:PSpinEntry):LongWord; assembler; nostackframe;
Description: Unlock an existing Spin entry and restore the previous IRQ/FIQ state
| Spin
|
Pointer to the Spin entry to lock (Passed in R0)
|
| Return
|
ERROR_SUCCESS if completed or another error code on failure (Returned in R0)
|
function ARMv7SpinCheckIRQ(Spin:PSpinEntry):Boolean;
Description: To be documented
| Return
|
True if the mask would enable IRQ on restore, False if it would not
|
function ARMv7SpinCheckFIQ(Spin:PSpinEntry):Boolean;
Description: To be documented
| Return
|
True if the mask would enable FIQ on restore, False if it would not
|
function ARMv7SpinExchangeIRQ(Spin1,Spin2:PSpinEntry):LongWord;
Description: To be documented
function ARMv7SpinExchangeFIQ(Spin1,Spin2:PSpinEntry):LongWord;
Description: To be documented
function ARMv7MutexLock(Mutex:PMutexEntry):LongWord; assembler; nostackframe;
Description: Lock an existing Mutex entry
| Mutex
|
Pointer to the Mutex entry to lock (Passed in R0)
|
| Return
|
ERROR_SUCCESS if completed or another error code on failure (Returned in R0)
|
function ARMv7MutexUnlock(Mutex:PMutexEntry):LongWord; assembler; nostackframe;
Description: Unlock an existing Mutex entry
| Mutex
|
Pointer to the Mutex entry to lock (Passed in R0)
|
| Return
|
ERROR_SUCCESS if completed or another error code on failure (Returned in R0)
|
function ARMv7MutexTryLock(Mutex:PMutexEntry):LongWord; assembler; nostackframe;
Description: Try to lock an existing Mutex entry
| Mutex
|
Pointer to the Mutex entry to try to lock (Passed in R0)
|
| Return
|
ERROR_SUCCESS if completed, ERROR_LOCKED if already locked or another error code on failure (Returned in R0)
|
function ARMv7ThreadGetCurrent:TThreadHandle; assembler; nostackframe;
Description: Get the current thread id from the c13 (Thread and process ID) register of system control coprocessor CP15
function ARMv7ThreadSetCurrent(Thread:TThreadHandle):LongWord; assembler; nostackframe;
Description: Set the current thread id in the c13 (Thread and process ID) register of system control coprocessor CP15
function ARMv7ThreadSetupStack(StackBase:Pointer; StartProc:TThreadStart; ReturnProc:TThreadEnd; Parameter:Pointer):Pointer;
Description: Set up the context record and arguments on the stack for a new thread
| StackBase
|
Pointer to the base (highest address) of the allocated stack (as returned by ThreadAllocateStack
|
| StartProc
|
The procedure the thread will start executing when resumed
|
| ReturnProc
|
The procedure the thread will return to on exit
|
| Return
|
Pointer to the starting address of the stack, which will be the Stack Pointer on the first context switch
|
| Note
|
At the point of a context switch the thread stack will look like this:
(Base "Highest Address" of Stack)
.
.
.
.
cpsr <- The current program status register value to load on return from the context switch
(On Interrupt: Includes the flags and control bits for the interrupted thread)
(On Yield: Includes the control bits only for the yielded thread)
(On Create: Includes the control bits only for the new thread)
lr/pc <- The address to return to from the context switch
(On Interrupt: The location the thread was at before interrupt)
(On Yield: The location to return to in SchedulerReschedule)
(On Create: The location of StartProc for the new thread)
lr <- The lr value prior to the context switch
(On Interrupt: The value of lr before the thread was interrupted)
(On Yield: The location to return to in SchedulerReschedule)
(On Create: The location of ReturnProc for the new thread)
r12 <-
r11 <-
r10 <-
r9 <-
r8 <-
r7 <-
r6 <- The value of these registers prior to the context switch
r5 <- (On Interrupt: The values before the thread was interrupted)
r4 <- (On Yield: The values on return to SchedulerReschedule)
r3 <- (On Create: The values on entry to StartProc as set by ThreadSetupStack)
r2 <-
r1 <-
r0 <-
d15 <-
d14 <-
d13 <-
d12 <-
d11 <-
d10 <-
d9 <-
d8 <- The value of these floating point registers prior to the context switch
d7 <- (On Interrupt: The values before the thread was interrupted)
d6 <- (On Yield: The values on return to SchedulerReschedule)
d5 <- (On Create: The values on entry to StartProc as set by ThreadSetupStack)
d4 <-
d3 <-
d2 <-
d1 <-
d0 <-
fpscr <- The floating point FPSCR register
fpexc <- The floating point FPEXC register (Current StackPointer points to here)
.
.
.
.
(Top "Lowest Address" of Stack)
On exit from a standard context switch as performed by SchedulerReschedule the first value (Highest Address) of lr is used by the RFE (Return From Exception) instruction to load the pc which also loads the saved cpsr value.
On exit from an IRQ or FIQ context switch as performed by SchedulerSwitch the first value (Highest Address) of lr is used by the interrupt handler to return from the interrupt.
A standard context switch uses r12 to save the cpsr value (and RFE to restore it). Because the standard context switch is called from a routine which will have saved the value of r12 (which is caller save in the ARM ABI) then we do not need to save the original value of r12.
An IRQ or FIQ context switch uses the SRS (Store Return State) and RFE (Return From Exception) instructions to save and restore the cpsr value from the spsr value of either IRQ or FIQ mode.
|
Return to Unit Reference