I've been working for the past week on getting the power management
working for the iPAQ 214.
This has lead me to end up tracing through the entire suspend/resume
procedures (of a popular operating system).
The suspend code writes the resume address to SDRAM+0x0800 and also
writes the address of a data area to +0x0804. On resume, the ROM code
(running in the on-chip SRAM) places the data area address into r0 and
jumps to the address at +0x0800. I've implemented this in haret so that
I could use both the RESUMETRACES and the RESUMEINTOBOOT. The former now
works but I had to make some significant changes. Was the existing
hookResume() code specific to a particular machine / version of winCE?
As well as bypassing the checking of whats at the resume vector in
winvectors.cpp, I've had to make a new copy of the stackJumper which
saves r0 and recovers it before jumping back to the real resume vector:
resumeJumper:
resumeStack: .long 0
resumeData: .long 0
resumeExecCode: .long 0
resumeReturnCode: .long 0
resumeR0Store: .long 0
resumeIn:
str r0, [pc, #(resumeR0Store - . - 8)]
ldr r0, [pc, #(resumeData - . - 8)]
ldr sp, [pc, #(resumeStack - . - 8)]
add lr, pc, #(resumeOut - . - 8)
ldr pc, [pc, #(resumeExecCode - . - 8)]
resumeOut:
ldr r0, [pc, #(resumeR0Store - . - 8)]
ldr pc, [pc, #(resumeReturnCode - . - 8)]
and the appropriate changes to winvectors.cpp and winvectors.h
I put the resumeIn address into +0x0800 but, on the way into suspend
windows stores its own resume vector there so I have to replace the
instruction that does it with a 'nop'. Its not exactly elegant and
currently requires knowing where the specific instruction will be in
virtual memory. It does the job on this particular system though. I'll
clean it up a bit and make a complete patch but wondered if you can
think of a better way of doing it.
Of course, with that, the resume into boot also works. Unfortunately
linux won't bring up the LCD so I'm having to pay closer attention to
what windows does during resume.
I've been tracing it with MMUTRACE and WIRQ, but unfortunately I can't
get completely through the suspend code watching the PXA3xx's ACCR
register (which is of most interest at the moment) without it giving up.
The lines in haretlog.txt are:
002523: 09bdb659: mmutrace 8004b4e0: a8b14038(?) a9340000 8034f7c0
(a9340000)
002523: 09bdb659: giving up - clearing mapping
The offending code is this (disassembled by objdump):
8004b4dc: e2922010 adds r2, r2, #16 ; 0x10
8004b4e0: a8b14038 ldmgeia r1!, {r3, r4, r5, lr} @ <--
haret mmutrace gives up here
8004b4e4: a8a04038 stmgeia r0!, {r3, r4, r5, lr}
8004b4e8: 0a00000f beq 0x8004b52c
8004b4ec: c2522010 subgts r2, r2, #16 ; 0x10
The address I was watching was 0x4134000 which is mapped to 0xa9340000.
I'm guessing this is just an instruction that HaRET can't emulate. I've
had a quick look at l1trace.cpp:tryEmulate() but can't work out how it
fits in. Do you know of this instruction and can we add it to the
emulation code? Presumably 'stmgeia' will cause the same issue.
Thanks,
Oliver
_______________________________________________
Haret mailing list
[email protected]
https://handhelds.org/mailman/listinfo/haret