1、上下文类型(主要是翻译架构文档)
-
上文
上文的内容由A[10]-A[15]、D[8]-D[15]、PCXI和PSW。 -
下文
下文的内容由A[2]-A[7]、D[0]-D[7]、A[11]和PCXI。
如上图所示,寄存器存储顺序是按照图中的顺序。
比如实际代码调试:
下文保存
地址 | 内容 |
---|---|
0xD0004F00 | PCXI(0x2BD013D) |
0xD0004F04 | A11 |
0xD0004F08 | A2 |
0xD0004F0C | A3 |
0xD0004F10 | D0 |
0xD0004F14 | D1 |
0xD0004F18 | D2 |
0xD0004F1C | D3 |
0xD0004F20 | A4 |
0xD0004F24 | A5 |
0xD0004F28 | A6 |
0xD0004F2C | A7 |
0xD0004F30 | D4 |
0xD0004F34 | D5 |
0xD0004F38 | D6 |
0xD0004F3C | D7 |
1.1 上下文保存区域
该体系结构使用固定大小的上下文保存区域的链接列表。CSA是16个字的存储器存储,对齐在16字的边界上。每个CSA可以恰好包含一个上上下文或一个下上下文。CSA链接在一起通过链接词。
链接字包括两个字段,用于将给定CSA链接到链中的下一个CSA。字段为4位段以及16位偏移。段号和偏移量用于生成链接上下文的有效地址(EA)。见图13。
指针偏移值增加1总是将EA增加到16个字位置的地址
高于前一个。CSA在每个地址段中的总可用范围为4 MB,从而产生存储2e16个CSA的空间。
1.2、任务切换操作
当表-7中列出的事件或指令之一发生时,切换任务。当遇到这些事件或指令之一时,将保存或恢复任务的上文或下文。**上文是由于外部中断、陷阱或函数调用而自动保存的。****下文是通过指令显式保存的。**在表7中,“保存”是在从链接字读取FCX的下一个值后,通过空闲CSA列表头指针寄存器(FCX)进行存储“存储”是通过指令的有效地址进行的存储,不更改CSA列表或FCX寄存器“还原”与“保存”相反,“加载”与“存储”相反。
就寄存器内容的维护方式而言,在上文和下文中对寄存器的处理有着本质的区别。下文寄存器与全局寄存器类似,因为中断处理程序、陷阱处理程序或被调用的函数看到的值与中断、陷阱或调用之前寄存器中出现的值相同。在中断、陷阱处理程序或调用函数中对这些寄存器所做的任何更改,在事件返回后仍会存在,因为它们不会作为从调用返回(RET)或从异常返回(RFE)语义的一部分自动恢复。这意味着下文寄存器可以用于将参数传递给被调用的函数,并传递这些函数的返回值。这也意味着中断和陷阱处理程序在使用寄存器之前必须保存它们在这些寄存器中找到的原始值,并在退出之前恢复原始值。
上文寄存器不能保证是静态硬件寄存器。从概念上讲,函数调用或中断处理程序总是从其自己的一组专用上文寄存器开始执行。被中断或调用函数的上文寄存器不会被继承。
只有A[10](SP)、A[11](RA)、PSW、PCXI和(在陷阱的情况下)D[15]寄存器在被调用函数、陷阱处理程序或中断处理程序中以体系结构定义的值开始。一个函数、陷阱处理程序或中断处理程序在向其写入值之前读取任何其他上文寄存器,它正在执行未定义的操作。
1.3、上下文保存区域(CSAs)和上下文链表
上文和下文保存在上下文保存区域(CSAs)中。未使用的CSA在空闲上下文列表(FCX)中链接在一起。包含已保存的上或下文的CSA在“上一个上下文列表”(PCX)中链接在一起。下图(图14)显示了两个上下文列表中CSA的简单配置。
FCX寄存器的内容总是指向空闲上下文列表中的可用CSA。该CSA链接词指向空闲上下文列表中的下一个可用CSA。
在第一个可用CSA中保存上或下文之前,读取其链接字,为FCX提供新值。因此,对于内存子系统来说,上下文保存是一种读取/修改/写入操作。FCX的新值指向下一个可用CSA,可立即用于后续的上部或下部上下文保存。
LCX寄存器指向空闲列表中的最后CSA之一,用于识别即将到来的空闲CSA列表耗尽。当尝试执行上下文保存的操作时,如果FCX的值与LCX的值匹配,则该操作完成,并对下一条指令使用空闲CSA列表耗尽陷阱(FCD);即FCD陷阱的返回地址是陷阱/中断/被调用例程的第一条指令或SVLCX或BISR指令之后的指令。请参阅第8页的“上下文管理(陷阱类3)”。
陷阱处理程序所采取的操作取决于软件实现。例如,如果确定CSA列表耗尽是由不可恢复的软件错误引起的,它可能会发出系统重置。然而,通常情况下,它通过分配额外的内存或终止一个或多个任务并声明其CSA调用链来扩展空闲列表。在这些情况下,陷阱处理程序将以RFE指令退出。
在第一次使用之前,必须将空闲上下文列表中最后一个CSA中的链接字设置为null。这对于支撑FCU陷阱是必要的。在首次使用CSA之前,PCX指针值应为null。这是为了支持CSU(调用堆栈欠流)陷阱。
PCXI.PCX字段指向保存先前上下文的CSA。PCXI.UL位标识保存的上下文是上文(PCXI.UL1)还是下文(PCXI.UL0)。如果类型与执行上下文还原操作时预期的类型不匹配,则会发生CYTP异常,并捕获上下文管理陷阱。
在执行了上下文保存操作之后,将更新返回地址A[11](RA):
- 对于调用,a[11](RA)会更新为函数返回地址。
- 对于同步陷阱,a[11](RA)将使用引发陷阱的指令的PC进行更新。
- 对于系统调用和异步陷阱或中断,a[11](RA)会随着要执行的下一条指令的PC而更新。
当执行下文保存操作时,a[11](RA)的值被包括在保存的上下文中,并被放置在CSA的第二个字中。该A[11](RA)相应地通过下文恢复来恢复。
调用深度控制字段(PSW.CDC)由两个子字段组成;一个调用深度计数器,以及一个确定计数器宽度和溢出时间的掩码。
调用时,调用深度计数器递增,返回时恢复到以前的值。计数器溢出时会发生异常。其目的是防止软件错误导致“失控递归”并耗尽CSA自由列表。
1.4、中断和Trap的上下文切换
当发生中断或陷阱(例如NMI或SYSTRAP)时,处理器将当前任务的上文保存在内存中,暂停当前任务的执行,然后开始执行中断或陷阱处理程序。
如果在执行中断或陷阱时,处理器未使用中断堆栈(PSW.IS位==0),则堆栈指针将加载ISP(中断堆栈指针)的当前内容。然后将PSW.IS位设置为一(1)以指示从中断堆栈执行。
中断控制寄存器(ICR)保存当前CPU优先级号(ICR.CCPN)、中断使能位(ICR.IE)和挂起中断优先级号(ICR.PIPN)。这些字段以及上一个CPU优先级号和上一个中断使能都是中断管理系统的一部分。
ICR。CCPN通常仅在用于命令中断服务的中断服务例程(ISR)中为非零。它保存在一个与PSW分离的寄存器中,不属于RTOS处理的在软件管理任务(SMT)之间切换的上下文的一部分。
在ISR内启动的Trap处理程序中,PCXI.PIE通常仅为零,例如,在外围服务请求期间发生的NMI或SYSTRAP。
对于中断和陷阱,当前PCXI中的现有PCPN和PIE值都保存在上文的CSA中,并且ICR中的现有IE和CCPN值被复制到PCXI.PIE和PCXI.PCPN字段。一旦处理了中断或陷阱,必要时会重新加载保存的下文,并恢复执行中断的任务(RFE)。
在中断或陷阱中,当前任务上下文的上层上下文由硬件保存为中断或陷阱序列的显式部分。对于可以完全在中断上保存的这组寄存器中执行的小型中断和陷阱处理程序,不需要进一步保存上下文。处理程序可以立即执行并返回。通常,进行调用或需要更多寄存器的处理程序执行BISR(开始中断服务例程)或SVLCX(保存下文)指令,以保存未作为中断或陷阱序列的一部分保存的下文寄存器。该指令必须在修改任何相关寄存器之前发出,但它不必是处理程序中的第一条指令。
具有关键响应时间要求的中断处理程序可以使用上文寄存器立即执行其初始时间关键处理。在那之后,他们可以执行BISR并继续进行不那么耗时的处理。BISR重新启用中断,因此它将时间关键的处理与时间不太关键的处理分开使用。
陷阱处理程序通常没有关键的响应时间要求,但是那些可能发生在ISR中的或可能将中断延迟太久的陷阱处理程序也可以采用类似的方法来区分不可中断和可中断执行段。
1.5、函数调用的上下文切换
当进行函数调用(执行call指令)时,必须保存并恢复调用例程的上下文,以便在从函数返回后恢复调用方的执行。
在函数调用中,硬件会保存整个上文寄存器集。此外,CALL指令对上文的保存与调用跳转并行进行。此外,恢复上文由RET(Return)指令执行,并与返回跳转并行进行。被调用的函数不需要保存和恢复调用方的上下文,也不需要限制其对上文寄存器的使用。调用函数和被调用函数必须在使用下文寄存器时进行协作。
1.6、FCALL/FRET快速函数调用与返回
在不需要保存和恢复上层上下文寄存器的情况下,可以优先使用FCALL指令而不是CALL指令。FCALL指令执行调用跳转,并并行地将当前返回地址(A11)保存到堆栈。没有保存其他状态。因此,被调用的函数在与调用方相同的上下文中开始执行(A10和A11除外)。
要从FCALL调用的函数返回,将执行FRET指令。这执行到当前返回地址(A11)的跳转,并从堆栈加载回先前的A11。没有加载其他状态。因此,调用方函数使用被调用函数修改的上下文恢复执行。调用函数和被调用函数必须在使用所有寄存器时进行协作。
1.7、上下文保存和恢复示例
本节提供了上下文保存操作的示例和上下文恢复操作的示例。
1.7.1、上下文保存
图15显示了此示例的免费和以前的上下文列表。空闲上下文列表(FCX)包含三个空闲CSA(3、4和5),前一个上下文列表(PCX)包含两个CSA(2和1)。
FCX指向CSA3,这是第一个可用的CSA。CSA3的链接字指向CSA4;CSA4的链接字指向CSA5。PCX指向上一上下文列表中最近保存的CSA。CSA2的链接字指向CSA1。CSA1包含在CSA2之前保存的上下文。
当执行上下文保存操作时,自由上下文列表(CSA3)中的第一CSA被取下,并被放置在先前上下文列表的前面。
图16显示了在上下文保存操作期间所采取的步骤。图中的数字对应于图后列出的步骤。
1.将CSA3中的链接字的内容加载到NEW_FCX中。NEW_FCX现在指向CSA4。NEW_FCX是一个内部缓冲区,用户无法访问。
2.PCX的内容被写入CSA3的链接字中。CSA3的链接字现在指向CSA2。
3.FCX的内容被写入PCX。PCX现在指向CSA3,它位于上一个上下文列表的前面。
4.将NEW_FCX加载到FCX中。处理器SFR和CSA如图17所示。现在将要保存的处理器上下文写入CSA3的其余部分。
1.7.2、上下文恢复
图18中的示例显示了包含三个CSA(3、2和1)的先前上下文列表(PCX)和包含两个CSA(4和5)的自由上下文列表(FCX)。
FCX指向CSA4,这是自由上下文列表中第一个可用的CSA。PCX指向CSA3,这是上一个上下文列表中最近保存的CSA。
CSA3的链接字指向CSA2;CSA2的链接字指向CSA1;CSA4的链接字指向CSA5。
当执行上下文恢复操作时,前一上下文列表(CSA3)中的第一CSA被取下并被放置在自由上下文列表的前面。
图19显示了在上下文恢复操作期间所采取的步骤。图中的数字对应于以下步骤:
1.将CSA3中的链接字的内容加载到NEW_PCX中。NEW_PCX现在指向CSA2。NEW_PCX是一个内部缓冲区,用户无法访问。
2.FCX的内容被写入CSA3的链接字中。CSA3的链接字现在指向CSA4。
3.PCX的内容被写入FCX。FCX现在指向位于空闲上下文列表前面的CSA3。
4.将NEW_PCX加载到PCX中。
处理器SFR和CSA现在如图20所示。然后将恢复的上下文写入上或下文寄存器。
参考文档:TriCore_TC162P_core_architecture_volume_1_of_2