11# pyOCD debugger
2- # Copyright (c) 2016-2020 Arm Limited
2+ # Copyright (c) 2016-2020,2025 Arm Limited
33# SPDX-License-Identifier: Apache-2.0
44#
55# Licensed under the Apache License, Version 2.0 (the "License");
1515# limitations under the License.
1616
1717from .provider import (TargetThread , ThreadProvider )
18- from .common import (read_c_string , HandlerModeThread , EXC_RETURN_EXT_FRAME_MASK )
18+ from .common import (read_c_string , HandlerModeThread , EXC_RETURN_EXT_FRAME_MASK , EXC_RETURN_SECURE_STACK_MASK )
1919from ..core import exceptions
2020from ..core .target import Target
2121from ..core .plugin import Plugin
@@ -157,6 +157,7 @@ def __init__(self, parent, thread):
157157 super (FreeRTOSThreadContext , self ).__init__ (parent )
158158 self ._thread = thread
159159 self ._has_fpu = self .core .has_fpu
160+ self ._has_security_extension = Target .SecurityState .SECURE in self .core .supported_security_states
160161
161162 def read_core_registers_raw (self , reg_list ):
162163 reg_list = [index_for_reg (reg ) for reg in reg_list ]
@@ -179,11 +180,10 @@ def read_core_registers_raw(self, reg_list):
179180 else :
180181 sp = self ._thread .get_stack_pointer ()
181182
182- # Determine which register offset table to use and the offsets past the saved state.
183- hwStacked = 0x20
184- swStacked = 0x20
185- table = self .NOFPU_REGISTER_OFFSETS
186- if self ._has_fpu :
183+ # Read exception LR (holds EXC_RETURN) to determine stacking info.
184+ hasExtendedFrame = False
185+ hasSecureStack = False
186+ if self ._has_fpu or self ._has_security_extension :
187187 try :
188188 if inException and self .core .is_vector_catch ():
189189 # Vector catch has just occurred, take live LR
@@ -193,20 +193,39 @@ def read_core_registers_raw(self, reg_list):
193193 offset = self .FPU_BASIC_REGISTER_OFFSETS [- 1 ]
194194 exceptionLR = self ._parent .read32 (sp + offset )
195195
196- # Check bit 4 of the saved exception LR to determine if FPU registers were stacked.
197- if (exceptionLR & EXC_RETURN_EXT_FRAME_MASK ) ! = 0 :
198- table = self . FPU_BASIC_REGISTER_OFFSETS
199- swStacked = 0x24
200- else :
201- table = self . FPU_EXTENDED_REGISTER_OFFSETS
202- hwStacked = 0x68
203- swStacked = 0x64
196+ # Check bit 4 of the exception LR to determine if FPU registers were stacked.
197+ if (exceptionLR & EXC_RETURN_EXT_FRAME_MASK ) = = 0 :
198+ hasExtendedFrame = True
199+
200+ # Check bit 6 of the exception LR to determine if Secure stack is used.
201+ if ( exceptionLR & EXC_RETURN_SECURE_STACK_MASK ) != 0 :
202+ hasSecureStack = True
203+
204204 except exceptions .TransferError :
205205 LOG .debug ("Transfer error while reading thread's saved LR" )
206206
207+ # Determine which register offset table to use and the offsets past the saved state.
208+ if self ._has_fpu :
209+ if hasExtendedFrame :
210+ table = self .FPU_EXTENDED_REGISTER_OFFSETS
211+ hwStacked = 0x68
212+ swStacked = 0x64
213+ else :
214+ table = self .FPU_BASIC_REGISTER_OFFSETS
215+ hwStacked = 0x20
216+ swStacked = 0x24
217+ else :
218+ table = self .NOFPU_REGISTER_OFFSETS
219+ hwStacked = 0x20
220+ swStacked = 0x20
221+
207222 for reg in reg_list :
208- # Must handle stack pointer specially.
209- if reg == 13 :
223+
224+ # Must handle stack pointer(s) specially.
225+ if (reg == index_for_reg ('sp' ) or
226+ reg == index_for_reg ('psp' ) or
227+ (reg == index_for_reg ('psp_s' ) and hasSecureStack ) or
228+ (reg == index_for_reg ('psp_ns' ) and not hasSecureStack )):
210229 if inException :
211230 reg_vals .append (sp + hwStacked )
212231 else :
0 commit comments