Feh.
Ignore the previous - I was being stupid .. :)
J
Reply by otaku●January 3, 20072007-01-03
Hi All.
I've hacked together a bit of flashing code across JTAG on ARM920T -
very simple stuff using a semaphore to indicate a service request. It
all seems to work seamlessly ( at least for the copy code ), and it
resumes execution properly after each block of data.
Unfortunately, once it leaves the "copy" code I hit a snag : PC becomes
corrupt. I'm currently thinking I've mucked up the instruction count for
the final PC fixup, and that I'm off by one or two which means in more
complex code ( ie : not the semaphore polling code )I've a higher chance
of executing code out of sequence.
//Halt code
/* STR r0, [r0] - Save R0 before use */
Data[0] = 0xe5800000;
Data[1] = 0x00;
debug_exec(Data, DEBUG_SPEED);
/* STR r1, [r0] - Save R1 before use */
Data[0] = 0xe5801000;
Data[1] = 0x00;
debug_exec(Data, DEBUG_SPEED);
/* STR r2, [r0] - Save R2 before use */
Data[0] = 0xe5802000;
Data[1] = 0x00;
debug_exec(Data, DEBUG_SPEED);
/* MOV r0, PC - Copy PC to R0 */
Data[0] = 0xe1a0000f;
Data[1] = 0x00;
debug_exec(Data, DEBUG_SPEED);
regs->r[0]=Data[1]; //Read out R0
/* STR r0, [r0] - Save PC into R0 */
Data[0] = 0xe5800000;
Data[1] = 0x00;
debug_exec(Data, DEBUG_SPEED);
regs->r[1]=Data[1]; //Read out R1
/* NOP - Read out R2 */
Data[0] = 0xe1a00000;
Data[1] = 0x00;
debug_exec(Data, DEBUG_SPEED);
regs->r[2]=Data[1]; //Read out R2
/* NOP */
Data[0] = 0xe1a00000;
Data[1] = 0x00;
debug_exec(Data, DEBUG_SPEED);
/* NOP - Read out R1 */
Data[0] = 0xe1a00000;
Data[1] = 0x00;
debug_exec(Data, DEBUG_SPEED);
regs->pc=Data[1]-0xXX; //Read out PC
//Halt Code Ends
//Resume Code
/* LDR r2, [r0] - restore R2 */
Data[0] = 0xe5902000;
Data[1]=0;
debug_exec(Data, DEBUG_SPEED);
/* LDR r1, [r0] - restore R1 */
Data[0] = 0xe5901000;
Data[1]=0;
debug_exec(Data, DEBUG_SPEED);
/* LDR r0, [r0] */
Data[0] = 0xe5900000;
Data[1]=0;
debug_exec(Data, DEBUG_SPEED);
/* NOP - scan in value for r2 */
Data[0] = 0xe1a00000;
Data[1] = regs->r[2];
debug_exec(Data, DEBUG_SPEED);
/* MOV PC, r0 - put r0 into PC */
/* - scan in value for r1 */
Data[0] = 0xe1a0f000;
Data[1] = regs->r[1];
debug_exec(Data, DEBUG_SPEED);
/* LDR r0, [r0] */
/* - scan in value for pc */
Data[0] = 0xe5900000;
Data[1] = regs->pc;
debug_exec(Data, DEBUG_SPEED);
/* NOP */
Data[0] = 0xe1a00000;
Data[1]=0;
debug_exec(Data, DEBUG_SPEED);
/* NOP */
Data[0] = 0xe1a00000;
Data[1]=0;
debug_exec(Data, DEBUG_SPEED);
/* NOP - scan in value for r0 */
Data[0] = 0xe1a00000;
Data[1] = regs->r[0];
debug_exec(Data, DEBUG_SPEED);
/* SUB PC, PC, #0xXX - jump back PC */
Data[0] = 0xe24ff0XX;
Data[1]=0;
debug_exec(Data, DEBUG_SPEED);
Data[0] = 0xe1a00000;
Data[1]=0;
debug_exec(Data, SYSTEM_SPEED);
//Resume Code Ends.
The code I'm injecting into the cache only ever affects R0-R2, and PC.
So : My question is - what are the two vlues of 0xXX above ?
in the Halt code section, does the count start with "MOV r0, PC" , or 4
execs later, with the value of R0 being read ?
I _think_ its the former, and the fixup is 0x20.
More confusingly , in the resume secion - where do you start counting
the instructions from : "MOV PC, r0" , or again 4 exec later, with the
data being loaded in ?
Any suggestions/corrections gratefully recieved.
J