Hi,
I came across an interesting CPU behaviour - a few cycles after calling a function which is linked to last bytes of MSM always VbusM error event is generated. This problem prevents me from using last bytes of MSM for code.
Here's exactly what I'm doing to trigger mentioned behaviour:
Link the following function to 0x0c1fff80:
void my_artificial_function()
{
int i;
for(i = 0; i < 128; i++)
{
volatile int x = 0xaaaaaaaa;
volatile int y = 0xbbbbbbbb;
volatile int z = 0xcccccccc;
}
}
Disassembled looks as follows:
TEXT Section last_section_code (Little Endian), 0x60 bytes at 0xC1FFF80
0c1fff80 _Z22my_artificial_functionv:
0c1fff80 .text:_Z22my_artificial_functionv:
0c1fff80 last_section_code:
0c1fff80 02ddddaa MVK.S2 0xffffbbbb,B5
0c1fff84 0366662a MVK.S2 0xffffcccc,B6
0c1fff88 0380202a MVK.S2 0x0040,B7
0c1fff8c 0255552a MVK.S2 0xffffaaaa,B4
0c1fff90 02ddddea MVKH.S2 0xbbbb0000,B5
0c1fff94 0366666a MVKH.S2 0xcccc0000,B6
0c1fff98 0255556b MVKH.S2 0xaaaa0000,B4
0c1fff9c 039fe05a || SUB.L2 B7,0x1,B7
0c1fffa0 0ee7 SPLOOPD 6
0c1fffa2 8cf7 || SUBAW.D2 B15,0x4,B15
0c1fffa4 dbef || MVC.S2 B7,ILC
0c1fffa6 7246 || MV.L1X B4,A3
0c1fffa8 2c67 SPMASK L1
0c1fffaa 92c6 ||^ MV.L1X B5,A4
0c1fffac ac35 || STW.D2T1 A3,*B15[1]
0c1fffae 2c67 SPMASK L1
0c1fffb0 b346 ||^ MV.L1X B6,A5
0c1fffb2 cc45 || STW.D2T1 A4,*B15[2]
0c1fffb4 ec55 STW.D2T1 A5,*B15[3]
0c1fffb6 bc45 STW.D2T2 B4,*B15[1]
0c1fffb8 dc55 STW.D2T2 B5,*B15[2]
0c1fffba fc65 STW.D2T2 B6,*B15[3]
0c1fffbc efe001b7 .fphead n, l, W, BU, nobr, nosat, 1111111b
0c1fffc0 00034000 SPKERNEL 0,0
0c1fffc4 000c0362 B.S2 B3
0c1fffc8 07800852 ADDK.S2 16,B15
0c1fffcc 00006000 NOP 4
0c1fffd0 00000000 NOP
0c1fffd4 00000000 NOP
0c1fffd8 00000000 NOP
0c1fffdc 00000000 NOP
After calling this function (doesn't matter where it's called from) the MDMAERREVT / VbusM error event is generated.
Here's the ETB showing execution from just before exception occurence:
"9dd2a5d8","SomeFunc"," CALLP.S2 0x9dd88580,B3"
"9dd88580","$Tramp$S$$_Z22my_artificial_functionv"," MVK.S2 0xffffff80,B31"
"9dd88580","$Tramp$S$$_Z22my_artificial_functionv"," MVK.S2 0xffffff80,B31"
"9dd88584","$Tramp$S$$_Z22my_artificial_functionv"," MVKH.S2 0xc1f0000,B31"
"9dd88584","$Tramp$S$$_Z22my_artificial_functionv"," MVKH.S2 0xc1f0000,B31"
"9dd88588","$Tramp$S$$_Z22my_artificial_functionv"," B.S2 B31"
"9dd8858c","$Tramp$S$$_Z22my_artificial_functionv"," NOP 5"
"0c1fff80","my_artificial_function()",""
"0c1fff84","my_artificial_function()",""
"0c1fff84","my_artificial_function()",""
"0c1fff88","my_artificial_function()",""
"0c1fff8c","my_artificial_function()",""
"0c1fff90","my_artificial_function()",""
"0c1fff94","my_artificial_function()",""
"0c1fff98","my_artificial_function()",""
"0c1fff9c","my_artificial_function()",""
"0c1fff98","my_artificial_function()",""
"0c1fffa0","my_artificial_function()"," SPLOOPD 6"
"0c1fffa2","my_artificial_function()"," || SUBAW.D2 B15,0x4,B15"
"0c1fffa4","my_artificial_function()"," || MVC.S2 B7,ILC"
"0c1fffa6","my_artificial_function()"," || MV.L1X B4,A3"
"0c1fffa8","my_artificial_function()"," SPMASK L1"
"0c1fffaa","my_artificial_function()"," ||^ MV.L1X B5,A4"
"0c1fffac","my_artificial_function()"," || STW.D2T1 A3,*B15[1]"
"0c1fffae","my_artificial_function()"," SPMASK L1"
"0c1fffb0","my_artificial_function()"," ||^ MV.L1X B6,A5"
"0c1fffb2","my_artificial_function()"," || STW.D2T1 A4,*B15[2]"
"0c1fffb4","my_artificial_function()"," STW.D2T1 A5,*B15[3]"
"0c1fffb6","my_artificial_function()"," STW.D2T2 B4,*B15[1]"
"0c1fffb8","my_artificial_function()"," STW.D2T2 B5,*B15[2]"
"0c1fffba","my_artificial_function()"," STW.D2T2 B6,*B15[3]"
"0c1fffaa","my_artificial_function()"," ||^ MV.L1X B5,A4"
"0c1fffac","my_artificial_function()"," || STW.D2T1 A3,*B15[1]"
"0c1fffc0","my_artificial_function()"," SPKERNEL 0,0"
"0c1fffb0","my_artificial_function()"," ||^ MV.L1X B6,A5"
"0c1fffb2","my_artificial_function()"," || STW.D2T1 A4,*B15[2]"
"0c1fffb4","my_artificial_function()"," STW.D2T1 A5,*B15[3]"
"0c1fffb6","my_artificial_function()"," STW.D2T2 B4,*B15[1]"
"0c1fffb8","my_artificial_function()"," STW.D2T2 B5,*B15[2]"
"0c1fffba","my_artificial_function()"," STW.D2T2 B6,*B15[3]"
"0c1fffaa","my_artificial_function()"," ||^ MV.L1X B5,A4"
"0c1fffac","my_artificial_function()"," || STW.D2T1 A3,*B15[1]"
"0c1fffc0","my_artificial_function()"," SPKERNEL 0,0"
"0c1fffb0","my_artificial_function()"," ||^ MV.L1X B6,A5"
"0c1fffb2","my_artificial_function()"," || STW.D2T1 A4,*B15[2]"
"0c1fffb4","my_artificial_function()"," STW.D2T1 A5,*B15[3]"
"","UNKNOWN",""
"","UNKNOWN",""
"","UNKNOWN",""
"","UNKNOWN",""
"","UNKNOWN",""
"","UNKNOWN",""
"0c1fd820","_vector1"," MVC.S2 B15,GPLYB"
Both XMPFAR and XMPFSR don't say much as they're just 0.
Can you please help understand what exactly causes MDMAERREVT?
Could it be that fetch pipeline reads behind the end of function and in result we cross the end of MSM boundary? Can you please confirm?
In this particular case return instruction is at 0x0c1fffc4, which is 60 bytes before end of MSM. If I understand correctly there're 6 stages between PG and E1 in the pipeline, which would mean that theoretically up to 6 fetch packets (i.e. 6 * 32 = 192 bytes) can be read before branch B3 instruction reaches E1 stage. Could this be the cause?
Problem doesn't occur if the function is linked to slightly lower address, for example 0x0c1fff00.
Best regards,
Leon