# HG changeset patch # User alex@thinkpad # Date 1546534814 -3600 # Thu Jan 03 18:00:14 2019 +0100 # Branch qemu # Node ID b1d5651364a72d0bab2b6aa5879163c7d6b43537 # Parent c49103df1af9f9675c645fd8197e356056f9f5c1 M50 draft patch diff -r c49103df1af9 -r b1d5651364a7 contrib/qemu/eos/eos.c --- a/contrib/qemu/eos/eos.c Sat Mar 31 10:43:22 2018 +0200 +++ b/contrib/qemu/eos/eos.c Thu Jan 03 18:00:14 2019 +0100 @@ -156,12 +156,15 @@ { "Interrupt", 0xD5011000, 0xD5011FFF, eos_handle_intengine, 2 }, /* second core in D7 */ { "Interrupt", 0xD02C0200, 0xD02C02FF, eos_handle_intengine, 3 }, /* 5D3 eeko */ { "Interrupt", 0xC1000000, 0xC100FFFF, eos_handle_intengine_gic, 7 },/* D7 */ + { "Interrupt", 0xD0211000, 0xD0211FFF, eos_handle_intengine, 8 }, /* first core in D8 */ { "Timers", 0xC0210000, 0xC0210FFF, eos_handle_timers, 0 }, /* DIGIC 4/5/6 countdown timers */ { "Timers", 0xD02C1500, 0xD02C15FF, eos_handle_timers, 2 }, /* Eeko countdown timer */ { "Timer", 0xC0242014, 0xC0242014, eos_handle_digic_timer, 0 }, { "Timer", 0xD400000C, 0xD400000C, eos_handle_digic_timer, 1 }, { "Timer", 0xD9820014, 0xD9820014, eos_handle_digic_timer, 2 }, /* D7: maybe? firmware waits for this register to change */ + { "Timer", 0xD020000C, 0xD020000C, eos_handle_digic_timer, 3 }, /* D8 */ { "UTimer", 0xD4000240, 0xD4000440, eos_handle_utimer, 1 }, /* D6: timers 9...16 */ + { "UTimer", 0xD0200240, 0xD0200440, eos_handle_utimer, 2 }, /* D8: same? */ { "HPTimer", 0xC0243000, 0xC0243FFF, eos_handle_hptimer, 0 }, /* DIGIC 2/3/4/5/6 HPTimers */ { "GPIO", 0xC0220000, 0xC022FFFF, eos_handle_gpio, 0 }, { "Basic", 0xC0100000, 0xC0100FFF, eos_handle_basic, 0 }, @@ -175,6 +178,7 @@ { "SDIO86", 0xC8060000, 0xC8060FFF, eos_handle_sdio, 0x86 }, { "SFIO87", 0xC8070000, 0xC8070FFF, eos_handle_sfio, 0x87 }, { "SFIO88", 0xC8080000, 0xC8080FFF, eos_handle_sfio, 0x88 }, + { "SDIOM50", 0xD0740000, 0xD0740FFF, eos_handle_sdio, 0x50 }, { "ADTGDMA", 0xC0500060, 0xC050007F, eos_handle_adtg_dma, 0 }, { "UartDMA", 0xC05000C0, 0xC05000DF, eos_handle_uart_dma, 0 }, { "CFDMA0*", 0xC0500000, 0xC05000FF, eos_handle_cfdma, 0x0F }, @@ -188,6 +192,7 @@ { "SDDMA82*", 0xC8020000, 0xC80200FF, eos_handle_sddma, 0x82F }, { "SFDMA83*", 0xC8030000, 0xC80300FF, eos_handle_sfdma, 0x83F }, { "SFDMA84*", 0xC8040000, 0xC80400FF, eos_handle_sfdma, 0x84F }, + { "SDDMAM50", 0xD0710000, 0xD0710FFF, eos_handle_sddma, 0x50 }, { "CFATA0", 0xC0600000, 0xC060FFFF, eos_handle_cfata, 0 }, { "CFATA2", 0xC0620000, 0xC062FFFF, eos_handle_cfata, 2 }, { "CFATA16", 0xC0700000, 0xC070FFFF, eos_handle_cfata, 0x10 }, @@ -203,6 +208,8 @@ { "SIO6", 0xC0820600, 0xC08206FF, eos_handle_sio, 6 }, { "SIO7", 0xC0820700, 0xC08207FF, eos_handle_sio, 7 }, { "SIO8", 0xC0820800, 0xC08208FF, eos_handle_sio, 8 }, + { "SIO9", 0xC0820900, 0xC08209FF, eos_handle_sio, 9 }, + { "SIO10", 0xC0820A00, 0xC0820AFF, eos_handle_sio, 10 }, { "MREQ", 0xC0203000, 0xC02030FF, eos_handle_mreq, 0 }, { "DMA1", 0xC0A10000, 0xC0A100FF, eos_handle_dma, 1 }, { "DMA2", 0xC0A20000, 0xC0A200FF, eos_handle_dma, 2 }, @@ -243,6 +250,9 @@ { "XDMAC7", 0xC9200000, 0xC920003F, eos_handle_xdmac7, 0 }, { "XDMAC7", 0xC9200040, 0xC920007F, eos_handle_xdmac7, 1 }, { "XDMAC7", 0xC9200080, 0xC92000BF, eos_handle_xdmac7, 2 }, + //{ "XDMAC8", 0xC9200D00, 0xC9200D3F, eos_handle_xdmac8, 0 }, /* not implemented */ + //{ "XDMAC8", 0xC9200D40, 0xC9200D7F, eos_handle_xdmac8, 1 }, + //{ "XDMAC8", 0xC9200D80, 0xC9200DBF, eos_handle_xdmac8, 2 }, { "MEMDIV", 0xD9001600, 0xD900FFFF, eos_handle_memdiv, 0 }, @@ -252,6 +262,8 @@ { "DIGIC6", 0xD0000000, 0xDFFFFFFF, eos_handle_digic6, 0 }, { "DIGIC6", 0xC8100000, 0xC8100FFF, eos_handle_digic6, 1 }, + { "BOOT8", 0xBFE01FC4, 0xBFE01FCF, eos_handle_boot_digic8, 0 }, + { "ML helpers", 0xCF123000, 0xCF1230FF, eos_handle_ml_helpers, 0 }, { "ML helpers", 0xC0123400, 0xC01234FF, eos_handle_ml_helpers, 1 }, }; @@ -1116,7 +1128,8 @@ &first, &last ); } - else if (strcmp(s->model->name, "EOSM3") == 0) + else if (strcmp(s->model->name, "EOSM3") == 0 || + strcmp(s->model->name, "M50" ) == 0) { uint64_t size = height * s->disp.bmp_pitch; MemoryRegionSection section = memory_region_find( @@ -1297,13 +1310,15 @@ (s->model->digic_version <= 4) ? "arm946-eos" : /* apparently the same for DIGIC 2, 3 and 4 */ (s->model->digic_version == 5) ? "arm946-eos5" : /* minor differences */ (s->model->digic_version == 7) ? "cortex-a9-eos" : /* dual core */ + (s->model->digic_version == 8) ? "cortex-a9-eos" : /* same as D7? */ (s->model->digic_version >= 6) ? "cortex-r4-eos" : /* also used on Eeko (fake version 50) */ "arm946"; /* unused here */ s->cpu0 = cpu_arm_init(cpu_name); assert(s->cpu0); - if (s->model->digic_version == 7) + if (s->model->digic_version == 7 || + s->model->digic_version == 8) { s->cpu1 = cpu_arm_init(cpu_name); assert(s->cpu1); @@ -1588,7 +1603,8 @@ fprintf(stderr, "Start address: 0x%08X\n", s->cpu0->env.regs[15]); } - if (s->model->digic_version == 7) + if (s->model->digic_version == 7 || + s->model->digic_version == 8) { /* fixme: what configures this address as startup? */ s->cpu0->env.regs[15] = 0xE0000000; @@ -2030,7 +2046,8 @@ { case 0xC0201000: /* DIGIC 2,3 */ case 0xC0201004: /* DIGIC 4,5 (returns irq_id << 2) */ - case 0xD4011000: /* DIGIC 6 */ + case 0xD4011000: /* DIGIC 6,7 */ + case 0xD0211000: /* DIGIC 8 */ case 0xD02C0290: /* 5D3 EEKO */ if(type & MODE_WRITE) { @@ -2058,7 +2075,8 @@ break; case 0xC0201010: /* DIGIC <= 5 */ - case 0xD4011010: /* DIGIC 6 */ + case 0xD4011010: /* DIGIC 6,7 */ + case 0xD0211010: /* DIGIC 8 */ case 0xD02C029C: /* 5D3 EEKO */ if(type & MODE_WRITE) { @@ -2086,7 +2104,8 @@ break; case 0xC0201200: /* DIGIC <= 5 */ - case 0xD4011200: /* DIGIC 6 */ + case 0xD4011200: /* DIGIC 6,7 */ + case 0xD0211200: /* DIGIC 8 */ case 0xD02C02CC: /* 5D3 EEKO */ if(type & MODE_WRITE) { @@ -2515,7 +2534,8 @@ if (type & MODE_WRITE) { if (s->model->digic_version == 6 || - s->model->digic_version == 7) + s->model->digic_version == 7 || + s->model->digic_version == 8) { s->card_led = ((value & 0x0F000F) == 0x0D0002) ? 1 : @@ -5378,6 +5398,29 @@ } +unsigned int eos_handle_boot_digic8( unsigned int parm, EOSState *s, unsigned int address, unsigned char type, unsigned int value ) +{ + const char * msg = 0; + unsigned int ret = 0; + + static uint32_t boot_addr; + + switch (address) + { + case 0xBFE01FC4: + msg = "Flags?"; + break; + + case 0xBFE01FC8: + msg = "Boot address?"; + MMIO_VAR(boot_addr); + break; + } + + io_log("BOOT8", s, address, type, value, ret, msg, 0, 0); + return ret; +} + unsigned int eos_handle_digic6 ( unsigned int parm, EOSState *s, unsigned int address, unsigned char type, unsigned int value ) { const char * msg = 0; @@ -5429,6 +5472,9 @@ case 0xD20F0000: /* M3: many reads from FC000382, value seems ignored */ return 0; + case 0xD0304238: /* M50 */ + value = (value & 0xFFFF) / 2 | (value & 0xFFFF0000); + /* fall through */ case 0xD2013800: /* D6 */ case 0xD201381C: /* D6 */ case 0xD2018200: /* 5D4 */ @@ -5456,11 +5502,13 @@ break; case 0xD2018228: /* 5D4 */ + case 0xD0304230: /* M50 */ msg = "BMP VRAM"; MMIO_VAR(s->disp.bmp_vram); break; case 0xD201822C: /* 5D4 */ + case 0xD0304234: /* M50 */ msg = "BMP pitch"; MMIO_VAR(s->disp.bmp_pitch); break; @@ -5612,7 +5660,60 @@ msg = "Wake up CPU1?"; /* M5: wake up the second CPU? */ assert(s->cpu1); CPU(s->cpu1)->halted = 0; - break; + printf(KLRED"Wake up CPU1\n"KRESET); + break; + + case 0xD0110404: + msg = "Wake up CPU1?"; /* M50: wake up the second CPU? */ + assert(s->cpu1); + CPU(s->cpu1)->halted = 0; + printf(KLRED"Wake up CPU1\n"KRESET); + ret = 1; + break; + + case 0xD7100014: + case 0xD7100020: + case 0xD7100000: + case 0xD0740010: + case 0xD98000BC: + case 0xDE000000: + case 0xDE000014: + case 0xDE000020: + case 0xD7301000: + msg = "M50 loop"; + ret = rand(); + break; + + case 0xD01302B4: + msg = "EEP_CS2"; + break; + + case 0xD01322B4: + msg = "EEP_CS2 ack"; + ret = (rand() & 1) ? 0xD0002 : 0xC0003; + break; + + case 0xD0213024: + msg = "SubCPU ack?"; + break; + + case 0xD02100AC: + msg = "SubCPU wakeup?"; + //~ eos_trigger_int(s, 0x19A, 1000); + break; + + case 0xD0040000: + msg = "Busy waiting?"; + if (!qemu_loglevel_mask(EOS_LOG_VERBOSE)) { + /* quiet */ + return 0; + } + break; + + case 0xD0132280: + msg = "M50 SD detect"; + ret = 0; + //~ ret = 0x10000; } io_log("DIGIC6", s, address, type, value, ret, msg, 0, 0); diff -r c49103df1af9 -r b1d5651364a7 contrib/qemu/eos/eos.h --- a/contrib/qemu/eos/eos.h Sat Mar 31 10:43:22 2018 +0200 +++ b/contrib/qemu/eos/eos.h Thu Jan 03 18:00:14 2019 +0100 @@ -390,6 +390,7 @@ unsigned int eos_handle_rom_id( unsigned int parm, EOSState *s, unsigned int address, unsigned char type, unsigned int value ); unsigned int eos_handle_adtg_dma ( unsigned int parm, EOSState *s, unsigned int address, unsigned char type, unsigned int value ); +unsigned int eos_handle_boot_digic8 ( unsigned int parm, EOSState *s, unsigned int address, unsigned char type, unsigned int value ); unsigned int eos_handle_digic6 ( unsigned int parm, EOSState *s, unsigned int address, unsigned char type, unsigned int value ); void eos_set_mem_w ( EOSState *s, uint32_t addr, uint32_t val ); diff -r c49103df1af9 -r b1d5651364a7 contrib/qemu/eos/model_list.c --- a/contrib/qemu/eos/model_list.c Sat Mar 31 10:43:22 2018 +0200 +++ b/contrib/qemu/eos/model_list.c Thu Jan 03 18:00:14 2019 +0100 @@ -632,6 +632,44 @@ .ram_extra_size = 0x01000000, .current_task_addr = 0x1020, }, +/*************************** DIGIC VIII ********************************/ + { + /* defaults for DIGIC 8 cameras */ + .digic_version = 8, + .firmware_start = 0xE0040000, /* M50: same as D7 */ + .bootflags_addr = 0xE1FF8000, + .rom0_addr = 0xE0000000, + .rom0_size = 0x02000000, + .rom1_addr = 0xF0000000, + .rom1_size = 0x01000000, + //.ram_size = 0x40000000, /* prefer to specify exact size for each model */ + .caching_bit = 0x40000000, + .mmio_addr = 0xBFE00000, /* fixme: BFE is configured as regular RAM, but certain values are expected */ + .mmio_size = 0x1F200000, + .ram_extra_addr = 0xDF000000, + .ram_extra_size = 0x01000000, + .current_task_name_offs = 0x09, + .dryos_timer_id = 1, + .dryos_timer_interrupt = 0x1B, + .hptimer_interrupt = 0x28, + .sd_driver_interrupt = 0xEE, /* M50: OK */ + .sd_dma_interrupt = 0xBE, + }, + { + .name = "M50", + .digic_version = 8, + .ram_size = 0x40000000, /* 1GB */ + .card_led_address = 0xD01300E4, + .current_task_addr = 0x28, /* fixme: read from virtual memory */ + .uart_rx_interrupt = 0x15D, + .uart_tx_interrupt = 0x16D, + //.serial_flash_size = 0x1000000, + //.serial_flash_sio_ch = 10, + //.serial_flash_interrupt = 0xFE, + //.serial_flash_cs_register = 0xD01302B4, + //.serial_flash_cs_bitmask = 0x00010000, /* 0xC0003 / 0xD0002 */ + .dedicated_movie_mode = 0, + }, { .name = NULL, .digic_version = 0, diff -r c49103df1af9 -r b1d5651364a7 contrib/qemu/scripts/M50/debugmsg.gdb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/contrib/qemu/scripts/M50/debugmsg.gdb Thu Jan 03 18:00:14 2019 +0100 @@ -0,0 +1,295 @@ +# ./run_canon_fw.sh M50 -d debugmsg +# ./run_canon_fw.sh M50 -d debugmsg -s -S & arm-none-eabi-gdb -x M50/debugmsg.gdb + +source -v debug-logging.gdb + +# To get debugging symbols from Magic Lantern, uncomment one of these: +symbol-file ../magic-lantern/platform/M50.101/magiclantern +#symbol-file ../magic-lantern/platform/M50.101/autoexec +#symbol-file ../magic-lantern/platform/M50.101/stubs.o + +macro define CURRENT_TASK 0x1028 +macro define CURRENT_ISR (*(int*)0x100C ? (*(int*)0x1010) : 0) +macro define NUM_CORES 2 +macro define NULL_STR 0xE0041041 + +# GDB hook is very slow; -d debugmsg is much faster +# ./run_canon_fw.sh will use this address, don't delete it +# b *0xE0577EC4 +# DebugMsg_log + +b *0xE078645C +assert_log + +b *0xE0545DD6 +task_create_log + +# what's the difference?! +b *0xE0545FFA +task_create_log + +b *0xE05777C4 +register_interrupt_log + +b *0xE0572140 +register_func_log + +if 0 + b *0xE0572758 + create_semaphore8_log + + b *0xE057281E + take_semaphore_log +end + +b *0xE05591FA +CreateStateObject_log + +b *0xE02A8994 +mpu_send_log + +b *0xE016F2D6 +generic_log + +b *0xE074F014 +generic_log + + +b *0xE00508B4 +generic_log + +b *0xE0577ADC +generic_log + +b *0xE0670468 +commands + silent + print_current_location + printf "I2C_Write(%x, %x, %x, %x)\n", $r0, $r1, $r2, $r3 + set $r0 = 0 + set $pc = $lr + c +end + +b *0xE05734AA +commands + silent + print_current_location + printf "!! NIGHTMARE !! S_PROPAD_INVALIDPARAMETER 20003\n" + set $r0 = 0 + set $pc = $lr + c +end + +b *0xE0044912 +commands + silent + print_current_location + printf "DataLoad_wait hack\n" + set $r1 = 1000 + c +end + +b *0xE004A48C +commands + silent + print_current_location + printf "lens init?\n" + set $r0 = 0 + set $pc = $lr + c +end + +b *0xE01E12D4 +commands + silent + print_current_location + printf "RemCPUSwChk\n" + set $r0 = 0 + set $pc = $lr + c +end + +b *0xE016F2D6 +commands + silent + print_current_location + printf "conductor\n" + set $r0 = 0 + set $pc = $lr + c +end + +if 0 +b *0xE01E1274 +commands + silent + print_current_location + printf "SwitchCheck\n" + set $r0 = 5 + set $r1 = 0 + set $pc = 0xE07599BC + c +end +end + +b *0xE07599BC +commands + silent + print_current_location + KRED + printf "LED drive %x %x\n", $r0, $r1 + KRESET + log_result + c +end + +if 0 +b *0xE05E98D2 +commands + silent + print_current_location + printf "rtc drv\n" + set $r0 = 0 + set $pc = $lr + c +end +end + +#b *0x1b1d40 +#b *0x1b1c40 +#b my_cstart +#b my_dcache_clean + +#b *0xE0004cea thread 2 +#b *0xe00400fe +#commands +# dump binary memory 40000000.bin 0x40000000 0x40100000 +# dump binary memory DF000000.bin 0xDF000000 0xDF100000 +#end + +# i2c_read +b *0xE06703C8 +generic_log + +# i2c_write +b *0xE0670468 +generic_log + +# hpcopy +if 0 +b *0xE02E029E +commands + silent + print_current_location + KRED + printf "HPCopy(%x, %x, %x)\n", $r0, $r1, $r2 + KRESET + set $r2 = 0x4 + tbreak *($lr & ~1) + commands + silent + print_current_location + KRED + printf "HPCopy ret %x\n", $r0 + KRESET + end +end +#generic_log +end + + +# HPCopy +# Hardware protocol looks complex; emulating from GDB for now +b *0xE02E029E +commands + silent + print_current_location + KRED + printf "HPCopy(%x, %x, %x)\n", $r0, $r1, $r2 + KRESET + + # execute plain memcpy instead (same arguments) + set $pc = 0xE065E861 + + # we need to return 0 on success, unlike memcpy + tbreak *($lr & ~1) + commands + silent + set $r0 = 0 + c + end + c +end + +b *0xE01E12D4 + +b *0xE0659924 +commands + silent + print_current_location + KRED + printf "Wakeup\n" + KRESET + c +end + +b *0xE01E1274 +commands + silent + print_current_location + KRED + printf "SwitchCheck skipping\n" + KRESET + set $pc = $lr + c +end + +b *0xE01A4B4E +commands + silent + print_current_location + KRED + printf "RTCMgrState_S00_I00 skipping\n" + KRESET + set $pc = $lr + c +end + +b *0xE01E3752 +commands + silent + print_current_location + KRED + printf "PhySw stuff skipping\n" + KRESET + set $pc = $lr + c +end + +b *0xE0040C90 +commands + silent + print_current_location + KRED + printf "take_sem WaitCCInit\n" + KRESET + set $r1 = 1000 + c +end + +b *0xE00EE244 +commands + silent + print_current_location + KRED + printf "SubCPU something skipping\n" + KRESET + set $pc = $lr + c +end + +#b *0xE00504B6 + + +cont