链接文件的配置
.lsl文件中对应的CSA
section_layout :tc0:csa
{
group (ordered, align = 64, attributes=rw, run_addr=(CSA_START_TC0))
reserved "csa_tc0" (size = 64 * (CSA_TC0));
"_lc_ub_csa_01" := "_lc_ub_csa_tc0"; /* common cstart interface for first or single core */
"_lc_ue_csa_01" := "_lc_ue_csa_tc0"; /* common cstart interface for first or single core */
}
启动代码的初始化
cstart.c文件中上下文的初始化
int i,k;
int no_of_csas;
int * csa;
unsigned int seg_nr,seg_idx,pcxi_val = 0;
_Bool first = true;
static __far int (*const csa_area_begin[])[16] = {_lc_ub_csa_01(0xD0004000)};
static __far int (*const csa_area_end[])[16] = {_lc_ue_csa_01(0xD0005000)};
for(i=0; i<MAX_NR_OF_CSA_AREAS(1); i++)
{
no_of_csas = csa_area_end[i] - csa_area_begin[i];
for(k=0; k<no_of_csas(64); k++)
{
csa = csa_area_begin[i][k];
*csa = pcxi_val;
seg_nr = (((unsigned int)csa >> 28) & 0xf) << 16;
seg_idx = (((unsigned int)csa >> 6) & 0xffff);
pcxi_val = seg_nr | seg_idx;
if(first)
{
first = false;
__mtcr(LCX(0xFE3C), pcxi_val);
}
}
__mtcr(FCX(0xFE38), pcxi_val);
}
初始化代码的作用是预留一条CSA,如下0xD0004000-0xD0004030,每个CSA条目的PCXI位置存放的都是上一条CSA的地址,组成一个空闲CSA链表,例如0xD0004040(000D0100)地址处PCXI解析出来的数值为0xD0004000。CSA在RAM中的内容如下:
0xD0004000: 00000000 00000000 00000000 00000000
0xD0004010: 00000000 00000000 00000000 00000000
0xD0004020: 00000000 00000000 00000000 00000000
0xD0004030: 00000000 00000000 00000000 00000000
0xD0004040: 000D0100 00000000 00000000 00000000
0xD0004050: 00000000 00000000 00000000 00000000
0xD0004060: 00000000 00000000 00000000 00000000
0xD0004070: 00000000 00000000 00000000 00000000
0xD0004080: 000D0101 00000000 00000000 00000000
0xD0004090: 00000000 00000000 00000000 00000000
0xD00040A0: 00000000 00000000 00000000 00000000
0xD00040B0: 00000000 00000000 00000000 00000000
...........
0xD0004FC0: 000D013E 00000000 00000000 00000000
0xD0004FD0: 00000000 00000000 00000000 00000000
0xD0004FE0: 00000000 00000000 00000000 00000000
0xD0004FF0: 00000000 00000000 00000000 00000000
更新FCX寄存器内容为0x000D013E。
更新LCX寄存器的内容为0x000D0100。
代码内容
#define CPU_PC 0xFE08U
#define CPU_PSW 0xFE04U
#define CPU_FCX 0xFE38U
#define CPU_LCX 0xFE3CU
#define CPU_PCXI 0xFE00U
unsigned int g_A10_Val[6];
unsigned int g_A11_Val[6];
unsigned int g_PC_Val[6];
unsigned int g_PSW_Val[6];
unsigned int g_FCX_Val[6];
unsigned int g_LCX_Val[6];
unsigned int g_PCXI_Val[6];
__attribute__((always_inline)) static inline unsigned int get_A10(void)
{
register unsigned int result;
__asm("mov.d %0, a10" : "=d"(result)::);
return(result);
}
__attribute__((always_inline)) static inline unsigned int get_A11(void)
{
register unsigned int result;
__asm("mov.d %0, a11" : "=d"(result)::);
return(result);
}
void test_func_4(void) //阶段六
{
g_A10_Val[5] = get_A10();
g_A11_Val[5] = get_A11();
g_PC_Val[5] = __mfcr(CPU_PC);
g_PSW_Val[5] = __mfcr(CPU_PSW);
g_FCX_Val[5] = __mfcr(CPU_FCX);
g_LCX_Val[5] = __mfcr(CPU_LCX);
g_PCXI_Val[5] = __mfcr(CPU_PCXI);
}
void test_func_3(void) //阶段五
{
g_A10_Val[4] = get_A10();
g_A11_Val[4] = get_A11();
g_PC_Val[4] = __mfcr(CPU_PC);
g_PSW_Val[4] = __mfcr(CPU_PSW);
g_FCX_Val[4] = __mfcr(CPU_FCX);
g_LCX_Val[4] = __mfcr(CPU_LCX);
g_PCXI_Val[4] = __mfcr(CPU_PCXI);
test_func_4();
}
void test_func_2(void) //阶段四
{
g_A10_Val[3] = get_A10();
g_A11_Val[3] = get_A11();
g_PC_Val[3] = __mfcr(CPU_PC);
g_PSW_Val[3] = __mfcr(CPU_PSW);
g_FCX_Val[3] = __mfcr(CPU_FCX);
g_LCX_Val[3] = __mfcr(CPU_LCX);
g_PCXI_Val[3] = __mfcr(CPU_PCXI);
test_func_3();
}
void test_func_1(void)//阶段二
{
g_A10_Val[1] = get_A10();
g_A11_Val[1] = get_A11();
g_PC_Val[1] = __mfcr(CPU_PC);
g_PSW_Val[1] = __mfcr(CPU_PSW);
g_FCX_Val[1] = __mfcr(CPU_FCX);
g_LCX_Val[1] = __mfcr(CPU_LCX);
g_PCXI_Val[1] = __mfcr(CPU_PCXI);
}
unsigned int test_func_recursive(unsigned int in)
{
unsigned int fcx = __mfcr(CPU_FCX);
unsigned int lcx = __mfcr(CPU_LCX);
unsigned int pcxi = __mfcr(CPU_PCXI);
unsigned int ret_val;
if(0 == in)
{
ret_val = 1;
}
else
{
ret_val = in * test_func_recursive(in - 1);
}
return ret_val;
}
int main(void)
{
g_A10_Val[0] = get_A10();
g_A11_Val[0] = get_A11();
g_PC_Val[0] = __mfcr(CPU_PC);
g_PSW_Val[0] = __mfcr(CPU_PSW);
g_FCX_Val[0] = __mfcr(CPU_FCX);
g_LCX_Val[0] = __mfcr(CPU_LCX);
g_PCXI_Val[0] = __mfcr(CPU_PCXI); //阶段一
test_func_1(); //阶段二
g_A10_Val[2] = get_A10();
g_A11_Val[2] = get_A11();
g_PC_Val[2] = __mfcr(CPU_PC);
g_PSW_Val[2] = __mfcr(CPU_PSW);
g_FCX_Val[2] = __mfcr(CPU_FCX);
g_LCX_Val[2] = __mfcr(CPU_LCX);
g_PCXI_Val[2] = __mfcr(CPU_PCXI); //阶段三
test_func_2();
unsigned int tmp_ret = test_func_recursive(10); //阶段七
tmp_ret = test_func_recursive(63); 阶段八
}
调试结果分析
阶段一、
0xD0004FC0: 00000000 00000980 70009000 AFFFD106 //PCXI PSW A10 A11
0xD0004FD0: 0000007A 00000020 0000007E 00000367 //D8 D9 D10 D11
0xD0004FE0: C0000136 AFFFD106 F0060000 D0004FC0 //A12 A13 A14 A15
0xD0004FF0: 00002C6C 00000000 00001800 0000013F //D12 D13 D14 D15
A10 - 0x70009000 //
A11 - 0x800008FC //由main接口调用test_func_1()接口的下一条指令地址
PC - 0x800000C4
PSW - 0x981 //IO-2(管理模式),CDE=1, CDC=1,GW=1
FCX - 0xD013E //0xD0004F80
LCX - 0xD0100 //0xD0004000
PCXI - 0x1D013F //UL=1,0xD0004FC0
阶段二,调用test_func_1();
上下文内容更新,启动代码里会创建一个预留CSA,所以这里的地址是从0xD0004F80开始。
0xD0004F80: 001D013F 00000981 70009000 800008FC //PCXI PSW A10 A11
0xD0004F90: 0000007A 00000020 0000007E 0000036E //D8 D9 D10 D11
0xD0004FA0: C0000136 AFFFD106 F0060000 90000090 //A12 A13 A14 A15
0xD0004FB0: 00002C6D 00000000 00001800 001D013F //D12 D13 D14 D15
0xD0004FC0: 00000000 00000980 70009000 AFFFD106 //PCXI PSW A10 A11
0xD0004FD0: 0000007A 00000020 0000007E 00000367 //D8 D9 D10 D11
0xD0004FE0: C0000136 AFFFD106 F0060000 D0004FC0 //A12 A13 A14 A15
0xD0004FF0: 00002C6C 00000000 00001800 0000013F //D12 D13 D14 D15
A10 - 0x70009000 //未发生堆栈
A11 - 0x80000106 //由main接口调用test_func_1()接口的下一条指令地址
PC - 0x800001A6
PSW - 0x982 //IO-2(管理模式),CDE=1, CDC=2,GW=1
FCX - 0xD013D //0xD0004F40
LCX - 0xD0100 //0xD0004000
PCXI - 0x1D013E //UL=1,0xD0004F80
阶段三
0xD0004F80: 000D013D 00000981 70009000 800008FC //PCXI PSW A10 A11
0xD0004F90: 0000007A 00000020 0000007E 0000036E //D8 D9 D10 D11
0xD0004FA0: C0000136 AFFFD106 F0060000 90000090 //A12 A13 A14 A15
0xD0004FB0: 00002C6D 00000000 00001800 001D013F //D12 D13 D14 D15
0xD0004FC0: 00000000 00000980 70009000 AFFFD106 //PCXI PSW A10 A11
0xD0004FD0: 0000007A 00000020 0000007E 00000367 //D8 D9 D10 D11
0xD0004FE0: C0000136 AFFFD106 F0060000 D0004FC0 //A12 A13 A14 A15
0xD0004FF0: 00002C6C 00000000 00001800 0000013F //D12 D13 D14 D15
A10 - 0x70009000 //未发生堆栈
A11 - 0x800008FC //由main接口调用test_func_1()接口的下一条指令地址
PC - 0x8000012A
PSW - 0x981 //IO-2(管理模式),CDE=1, CDC=1,GW=1
FCX - 0xD013E //0xD0004F40
LCX - 0xD0100 //0xD0004000
PCXI - 0x1D013F //UL=1,0xD0004F80
0xD0004F80处数据为(0x000D013D),这个从test_func_1()接口返回时,0xD0004F80作为最后一个空闲CSA,需指向上一个空闲CSA的地址,形成空闲CSA链表,CSA地址存放的PCXI和PCXI寄存器的值没有直接关系。
阶段四、
0xD0004F80: 001D013F 00000981 70009000 800008FC //PCXI PSW A10 A11
0xD0004F90: 0000007A 00000020 0000007E 0000036E //D8 D9 D10 D11
0xD0004FA0: C0000136 AFFFD106 F0060000 90000090 //A12 A13 A14 A15
0xD0004FB0: 00002C6D 00000000 00001800 001D013F //D12 D13 D14 D15
A10 - 0x70009000
A11 - 0x8000024C
PC - 0x8000020A
PSW - 0x982 IO-2(管理模式),CDE=1, CDC=2,GW=1
FCX - 0xD013D//0xD0004F40
LCX - 0xD0100
PCXI - 0x1D013E//UL=1,0xD0004F80
阶段五、调用test_func_3()接口
0xD0004F40: 001D013E 00000982 70009000 8000016C //PCXI PSW A10 A11
0xD0004F50: 0000007A 00000020 0000007E 0000036E //D8 D9 D10 D11
0xD0004F60: C0000136 AFFFD106 F0060000 90000090 //A12 A13 A14 A15
0xD0004F70: 00002C6D 00000000 00001800 001D013E //D12 D13 D14 D15
0xD0004F80: 001D013F 00000981 70009000 800008FC //PCXI PSW A10 A11
0xD0004F90: 0000007A 00000020 0000007E 0000036E //D8 D9 D10 D11
0xD0004FA0: C0000136 AFFFD106 F0060000 90000090 //A12 A13 A14 A15
0xD0004FB0: 00002C6D 00000000 00001800 001D013F //D12 D13 D14 D15
A10 - 0x70009000
A11 - 0x8000024C
PC - 0x80000272
PSW - 0x983 IO-2(管理模式),CDE=1, CDC=3,GW=1
FCX - 0xD013C//0xD0004F00
LCX - 0xD0100
PCXI - 0x1D013D//UL=1,0xD0004F40
阶段六、调用test_func_4()接口
0xD0004F00: 001D013D 00000983 70009000 8000024C //PCXI PSW A10 A11
0xD0004F10: 0000007A 00000020 0000007E 0000036E //D8 D9 D10 D11
0xD0004F20: C0000136 AFFFD106 F0060000 90000090 //A12 A13 A14 A15
0xD0004F30: 00002C6D 00000000 00001800 001D013D //D12 D13 D14 D15
0xD0004F40: 001D013E 00000982 70009000 8000016C //PCXI PSW A10 A11
0xD0004F50: 0000007A 00000020 0000007E 0000036E //D8 D9 D10 D11
0xD0004F60: C0000136 AFFFD106 F0060000 90000090 //A12 A13 A14 A15
0xD0004F70: 00002C6D 00000000 00001800 001D013E //D12 D13 D14 D15
0xD0004F80: 001D013F 00000981 70009000 800008FC //PCXI PSW A10 A11
0xD0004F90: 0000007A 00000020 0000007E 0000036E //D8 D9 D10 D11
0xD0004FA0: C0000136 AFFFD106 F0060000 90000090 //A12 A13 A14 A15
0xD0004FB0: 00002C6D 00000000 00001800 001D013F //D12 D13 D14 D15
A10 - 0x70009000
A11 - 0x8000024C
PC - 0x800002DA
PSW - 0x984 IO-2(管理模式),CDE=1, CDC=4,GW=1
FCX - 0xD013B//0xD0004EC0
LCX - 0xD0100
PCXI - 0x1D013C//UL=1,0xD0004F00
阶段七、调用test_func_recursive(10)
0xD0004D00: 001D0135 0000098B 70009000 80000332 //PCXI PSW A10 A11
0xD0004D10: 0000007A 00000020 0000007E 0000036E //D8 D9 D10 D11
0xD0004D20: C0000136 AFFFD106 F0060000 90000090 //A12 A13 A14 A15
0xD0004D30: 00002C6D 00000000 00001800 00000001 //D12 D13 D14 D15
0xD0004D40: 001D0136 0000098A 70009000 80000332 //PCXI PSW A10 A11
0xD0004D50: 0000007A 00000020 0000007E 0000036E //D8 D9 D10 D11
0xD0004D60: C0000136 AFFFD106 F0060000 90000090 //A12 A13 A14 A15
0xD0004D70: 00002C6D 00000000 00001800 00000002 //D12 D13 D14 D15
0xD0004D80: 001D0137 00000989 70009000 80000332 //PCXI PSW A10 A11
0xD0004D90: 0000007A 00000020 0000007E 0000036E //D8 D9 D10 D11
0xD0004DA0: C0000136 AFFFD106 F0060000 90000090 //A12 A13 A14 A15
0xD0004DB0: 00002C6D 00000000 00001800 00000003 //D12 D13 D14 D15
0xD0004DC0: 001D0138 00000988 70009000 80000332 //PCXI PSW A10 A11
0xD0004DD0: 0000007A 00000020 0000007E 0000036E //D8 D9 D10 D11
0xD0004DE0: C0000136 AFFFD106 F0060000 90000090 //A12 A13 A14 A15
0xD0004DF0: 00002C6D 00000000 00001800 00000004 //D12 D13 D14 D15
0xD0004E00: 001D0139 00000987 70009000 80000332 //PCXI PSW A10 A11
0xD0004E10: 0000007A 00000020 0000007E 0000036E //D8 D9 D10 D11
0xD0004E20: C0000136 AFFFD106 F0060000 90000090 //A12 A13 A14 A15
0xD0004E30: 00002C6D 00000000 00001800 00000005 //D12 D13 D14 D15
0xD0004E40: 001D013A 00000986 70009000 80000332 //PCXI PSW A10 A11
0xD0004E50: 0000007A 00000020 0000007E 0000036E //D8 D9 D10 D11
0xD0004E60: C0000136 AFFFD106 F0060000 90000090 //A12 A13 A14 A15
0xD0004E70: 00002C6D 00000000 00001800 00000006 //D12 D13 D14 D15
0xD0004E80: 001D013B 00000985 70009000 80000332 //PCXI PSW A10 A11
0xD0004E90: 0000007A 00000020 0000007E 0000036E //D8 D9 D10 D11
0xD0004EA0: C0000136 AFFFD106 F0060000 90000090 //A12 A13 A14 A15
0xD0004EB0: 00002C6D 00000000 00001800 00000007 //D12 D13 D14 D15
0xD0004EC0: 001D013C 00000984 70009000 80000332 //PCXI PSW A10 A11
0xD0004ED0: 0000007A 00000020 0000007E 0000036E //D8 D9 D10 D11
0xD0004EE0: C0000136 AFFFD106 F0060000 90000090 //A12 A13 A14 A15
0xD0004EF0: 00002C6D 00000000 00001800 00000008 //D12 D13 D14 D15
0xD0004F00: 001D013D 00000983 70009000 80000332 //PCXI PSW A10 A11
0xD0004F10: 0000007A 00000020 0000007E 0000036E //D8 D9 D10 D11
0xD0004F20: C0000136 AFFFD106 F0060000 90000090 //A12 A13 A14 A15
0xD0004F30: 00002C6D 00000000 00001800 00000009 //D12 D13 D14 D15
0xD0004F40: 001D013E 00000982 70009000 80000332 //PCXI PSW A10 A11
0xD0004F50: 0000007A 00000020 0000007E 0000036E //D8 D9 D10 D11
0xD0004F60: C0000136 AFFFD106 F0060000 90000090 //A12 A13 A14 A15
0xD0004F70: 00002C6D 00000000 00001800 0000000A //D12 D13 D14 D15
0xD0004F80: 001D013F 00000981 70009000 800008FC //PCXI PSW A10 A11
0xD0004F90: 0000007A 00000020 0000007E 0000036E //D8 D9 D10 D11
0xD0004FA0: C0000136 AFFFD106 F0060000 90000090 //A12 A13 A14 A15
0xD0004FB0: 00002C6D 00000000 00001800 001D013F //D12 D13 D14 D15
0xD0004FC0: 00000000 00000980 70009000 AFFFD106 //PCXI PSW A10 A11
0xD0004FD0: 0000007A 00000020 0000007E 0000036E //D8 D9 D10 D11
0xD0004FE0: C0000136 AFFFD106 F0060000 D0004FC0 //A12 A13 A14 A15
0xD0004FF0: 00002C6D 00000000 00001800 0000013F //D12 D13 D14 D15
阶段八、
会进入Trap,上下文Trap。