Canon Basic script for running a small binary. The five function addresses listed at start are required to be correct. The initial values are for sx740 1.0.1
The binary is loaded in uncached RAM and executed as-is. The firmware always applies cache and branch predictor related routines on code loaded to RAM, so there is a possibility that this approach is not fully reliable.
' firmware function addresses with thumb bit
dim a_fio_readf=0xE0520E8B ' FIO_ReadFile
dim a_fio_writef=0xE0521027 ' FIO_WriteFile
dim a_fio_removf=0xE0520DF1 ' FIO_RemoveFile (newer cams have an equivalent RemoveFile eventproc)
dim a_umalloc=0xE053A0B1 ' AllocateUncacheableMemory
dim a_ufree=0xE053A0E5 ' used to free AllocateUncacheableMemory allocations (not named)
dim cpuinf_binary="B:/CPUINFO.BIN"
dim cpuinf_data="B:/CPUINFO.DAT"
private sub reg_funcs1()
ExportToEventProcedure("FIO_ReadFile",a_fio_readf|1)
ExportToEventProcedure("FIO_WriteFile",a_fio_writef|1)
ExportToEventProcedure("FIO_RemoveFile",a_fio_removf|1)
ExportToEventProcedure("umalloc",a_umalloc|1)
ExportToEventProcedure("ufree",a_ufree|1)
end sub
private sub Initialize()
reg_funcs1()
buf = umalloc(0x1000)
if buf=0 then
exit sub
end if
bufo = umalloc(0x1000)
if bufo=0 then
ufree(buf)
exit sub
end if
memset(bufo,0,0x1000)
f = OpenFileRD(cpuinf_binary)
FIO_ReadFile(f,buf,0x1000)
CloseFile(f)
ExportToEventProcedure("cpuinfo",buf|1)
cpuinfo(bufo)
FIO_RemoveFile(cpuinf_data)
f = OpenFileCREAT(cpuinf_data)
CloseFile(f)
f = OpenFileWR(cpuinf_data)
FIO_WriteFile(f,bufo,0x1000)
CloseFile(f)
ufree(bufo)
ufree(buf)
end sub
Assembly source for the current CPUINFO code from
here. It now supports ARMv7 VMSA (such as Cortex A9) CPUs.
@ compile with:
@ arm-none-eabi-gcc -Wl,-N,-Ttext,0x800000 -nostdlib -march=armv7 -mthumb cpuinfo.s -o cpuinfo.elf
@ and extract the needed bytes from the binary:
@ arm-none-eabi-objcopy -O binary cpuinfo.elf cpuinfo.bin
@ toolchain: [url]https://launchpad.net/gcc-arm-embedded[/url]
@ 0x00800000 is an arbitrary address, code is position independent anyway
.macro NHSTUB name addr
.globl _\name
.weak _\name
_\name:
ldr.w pc, _\addr
_\addr:
.long \addr
.endm
.globl _start
.org 0
_start:
.text
@ force thumb
.code 16
@ allow new instructions (ldr.w)
.syntax unified
MRC p15, 0, R1,c0,c0 @ ident
STR R1, [R0]
MRC p15, 0, R1,c0,c0,1 @ CTR, cache
ADD R0, R0, #4
STR R1, [R0]
MRC p15, 0, R1,c0,c0,2 @ TCMTR, TCM
ADD R0, R0, #4
STR R1, [R0]
MRC p15, 0, R1,c0,c0,3 @ TLBTR
ADD R0, R0, #4
STR R1, [R0]
MRC p15, 0, R1,c2,c0,2 @ TTBCR
ADD R0, R0, #4
STR R1, [R0]
MRC p15, 0, R1,c2,c0,0 @ TTBR0
ADD R0, R0, #4
STR R1, [R0]
MRC p15, 0, R1,c2,c0,1 @ TTBR1
ADD R0, R0, #4
STR R1, [R0]
MRC p15, 0, R1,c0,c0,5 @ MPIDR
ADD R0, R0, #4
STR R1, [R0]
MRC p15, 0, R1,c0,c0,6 @ REVIDR
ADD R0, R0, #4
STR R1, [R0]
MRC p15, 0, R1,c0,c1,0 @ ID_PFR0
ADD R0, R0, #4
STR R1, [R0]
MRC p15, 0, R1,c0,c1,1 @ ID_PFR1
ADD R0, R0, #4
STR R1, [R0]
MRC p15, 0, R1,c0,c1,2 @ ID_DFR0
ADD R0, R0, #4
STR R1, [R0]
MRC p15, 0, R1,c0,c1,3 @ ID_AFR0
ADD R0, R0, #4
STR R1, [R0]
MRC p15, 0, R1,c0,c1,4 @ ID_MMFR0
ADD R0, R0, #4
STR R1, [R0]
MRC p15, 0, R1,c0,c1,5 @ ID_MMFR1
ADD R0, R0, #4
STR R1, [R0]
MRC p15, 0, R1,c0,c1,6 @ ID_MMFR2
ADD R0, R0, #4
STR R1, [R0]
MRC p15, 0, R1,c0,c1,7 @ ID_MMFR3
ADD R0, R0, #4
STR R1, [R0]
MRC p15, 0, R1,c0,c2,0 @ ID_ISAR0
ADD R0, R0, #4
STR R1, [R0]
MRC p15, 0, R1,c0,c2,1 @ ID_ISAR1
ADD R0, R0, #4
STR R1, [R0]
MRC p15, 0, R1,c0,c2,2 @ ID_ISAR2
ADD R0, R0, #4
STR R1, [R0]
MRC p15, 0, R1,c0,c2,3 @ ID_ISAR3
ADD R0, R0, #4
STR R1, [R0]
MRC p15, 0, R1,c0,c2,4 @ ID_ISAR4
ADD R0, R0, #4
STR R1, [R0]
MRC p15, 0, R1,c0,c2,5 @ ID_ISAR5
ADD R0, R0, #4
STR R1, [R0]
MRC p15, 1, R1,c0,c0,1 @ CLIDR
ADD R0, R0, #4
STR R1, [R0]
MOV R1, #0
MCR p15, 2, R1,c0,c0,0 @ CSSELR (data cache, level0)
MRC p15, 1, R1,c0,c0,0 @ CCSIDR (the currently selected one)
ADD R0, R0, #4
STR R1, [R0]
MOV R1, #1
MCR p15, 2, R1,c0,c0,0 @ CSSELR (inst cache, level0)
MRC p15, 1, R1,c0,c0,0 @ CCSIDR (the currently selected one)
ADD R0, R0, #4
STR R1, [R0]
MRC p15, 0, R1,c1,c0,0 @ SCTLR
ADD R0, R0, #4
STR R1, [R0]
MRC p15, 0, R1,c1,c0,1 @ ACTLR
ADD R0, R0, #4
STR R1, [R0]
@#ifndef CONFIG_QEMU
MRC p15, 0, R1,c15,c0,0 @ ACTLR2
ADD R0, R0, #4
STR R1, [R0]
@#endif
MRC p15, 0, R1,c1,c0,2 @ CPACR
ADD R0, R0, #4
STR R1, [R0]
@"MRC p15, 0, R1,c9,c1,1 @ ATCM region reg, Cortex R4
@"ADD R0, R0, #4
@"STR R1, [R0]
@"MRC p15, 0, R1,c9,c1,0 @ BTCM region reg, Cortex R4
@"ADD R0, R0, #4
@"STR R1, [R0]
MRC p15, 0, R1,c1,c1,2 @ NSACR
ADD R0, R0, #4
STR R1, [R0]
MRC p15, 0, R1,c3,c0,0 @ DACR
ADD R0, R0, #4
STR R1, [R0]
MRC p14, 0, R1,c0,c0,0 @ DBGDIDR
ADD R0, R0, #4
STR R1, [R0]
MRC p14, 0, R1,c1,c0,0 @ DBGDRAR
ADD R0, R0, #4
STR R1, [R0]
MRC p14, 0, R1,c2,c0,0 @ DBGDSAR
ADD R0, R0, #4
STR R1, [R0]
MRC p14, 0, R1,c0,c1,0 @ DBGDSCR
ADD R0, R0, #4
STR R1, [R0]
@".word 0xEEF01A10 @"VMRS R1, FPSID @ Floating Point System ID register
@"ADD R0, R0, #4
@"STR R1, [R0]
@".word 0xEEF71A10 @"VMRS R1, MVFR0 @ Media and VFP Feature Register 0
@"ADD R0, R0, #4
@"STR R1, [R0]
@".word 0xEEF61A10 @"VMRS R1, MVFR1 @ Media and VFP Feature Register 1
@"ADD R0, R0, #4
@"STR R1, [R0]
MRC p15, 4, R1,c15,c0,0 @ config base addr reg (Cortex A9)
ADD R0, R0, #4
STR R1, [R0]
MRC p15, 0, R1,c11,c0,0 @ PLEIDR (Cortex A9)
ADD R0, R0, #4
STR R1, [R0]
MRC p15, 0, R1,c10,c0,0 @ TLB lockdown reg (Cortex A9)
ADD R0, R0, #4
STR R1, [R0]
MRC p15, 0, R1,c10,c2,0 @ PRRR (Cortex A9)
ADD R0, R0, #4
STR R1, [R0]
MRC p15, 0, R1,c10,c2,1 @ NMRR (Cortex A9)
ADD R0, R0, #4
STR R1, [R0]
BX LR
I already executed this on my camera and found no big differences from DIGIC 7.
Running this on R5 or R6 would be more interesting.
Evaluating the CPUINFO.DAT binary is currently only possible on a D6-D7 CHDK cam with patched CPUINFO module.
Porting the evaluator to "PC" would solve that.Index: modules/cpuinfo.c
===================================================================
--- modules/cpuinfo.c (revision 5564)
+++ modules/cpuinfo.c (working copy)
@@ -66,17 +66,36 @@
char buf[100];
char *p;
#ifdef THUMB_FW
+ int pmsa = 0;
struct cpuinfo_word_desc_s *cpuinfo_desc;
- if (cpu_is_vmsa()) {
- FILE *f=fopen("A/MMU_MAP.CSV", "wb");
- memmapping_vmsa(f);
- cpuinfo_get_info_vmsa(cpuinfo);
+
+ finfo = fopen("A/CPUI_V7V.DAT","rb");
+ if (!finfo) {
+ finfo = fopen("A/CPUI_V7P.DAT","rb");
+ pmsa = 1;
+ }
+ if (!finfo) {
+ pmsa = !cpu_is_vmsa();
+ if (cpu_is_vmsa()) {
+ FILE *f=fopen("A/MMU_MAP.CSV", "wb");
+ memmapping_vmsa(f);
+ cpuinfo_get_info_vmsa(cpuinfo);
+ }
+ else {
+ cpuinfo_get_info_pmsa(cpuinfo);
+ }
+ }
+ else {
+ fread(cpuinfo, 4, NUM_CPUINFO_WORDS, finfo);
+ fclose(finfo);
+ }
+ if (!pmsa) {
cpuinfo_desc = (struct cpuinfo_word_desc_s*) cpuinfo_desc_vmsa;
}
else {
- cpuinfo_get_info_pmsa(cpuinfo);
cpuinfo_desc = (struct cpuinfo_word_desc_s*) cpuinfo_desc_pmsa;
}
+
#else
cpuinfo_get_info(cpuinfo);
#endif