Reply by otaku January 3, 20072007-01-03
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