# HG changeset patch # User alex@thinkpad # Branch qemu # Node ID 7b9fa551c350e8b792eb036fa08ccb9e77adbf40 # Parent 302adc0d16c39584663676c5a7faad8a9920455f QEMU: initial support for 1300D, thanks adamnock diff -r 302adc0d16c3 -r 7b9fa551c350 contrib/qemu/eos/eos.c --- a/contrib/qemu/eos/eos.c +++ b/contrib/qemu/eos/eos.c @@ -2219,12 +2219,21 @@ #endif break; - case 0xF48C: - /* 6D: return -1 here to launch "System & Display Check & Adjustment program" */ - msg = "70D/6D SD detect?"; - ret = 0x10C; - break; - + case 0xF48C: + if(strcmp(s->model->name, "1300D") == 0) + { + /* 1300D: return 0 here to bypass "System & Display Check & Adjustment program" */ + msg = "System check"; + ret = 0; + } + else + { + /* 6D: return -1 here to launch "System & Display Check & Adjustment program" */ + msg = "70D/6D SD detect?"; + ret = 0x10C; + } + break; + case 0x019C: /* 5D3: return 1 to launch "System & Display Check & Adjustment program" */ case 0x0080: /* same for 1000D */ msg = "System check"; diff -r 302adc0d16c3 -r 7b9fa551c350 contrib/qemu/eos/model_list.c --- a/contrib/qemu/eos/model_list.c +++ b/contrib/qemu/eos/model_list.c @@ -219,6 +219,13 @@ .card_led_address = 0xC0220134, }, { + .name = "1300D", + .digic_version = 4, + .rom0_size = 0x02000000, + .rom1_size = 0x02000000, + .firmware_start = 0xFF0C0000, + }, + { .name = "EOSM", .digic_version = 5, .current_task_addr = 0x3DE78, # HG changeset patch # User alex@thinkpad # Branch qemu # Node ID bd309657da051d2db8102236a394de55daf67b4f # Parent 7b9fa551c350e8b792eb036fa08ccb9e77adbf40 QEMU: model the first ROM copy as I/O memory, to allow logging diff -r 7b9fa551c350 -r bd309657da05 contrib/qemu/eos/eos.c --- a/contrib/qemu/eos/eos.c +++ b/contrib/qemu/eos/eos.c @@ -299,6 +299,55 @@ }; #endif +static uint64_t eos_rom_read(void * opaque, hwaddr addr, uint32_t size) +{ + const char * msg = 0; + EOSState * s = (EOSState *)((intptr_t) opaque & ~1); + uint32_t rom_id = (intptr_t) opaque & 1; + uint32_t rom_addr = (rom_id) ? ROM1_ADDR : ROM0_ADDR;; + uint32_t rom_size = (rom_id) ? ROM1_SIZE : ROM0_SIZE; + uint32_t address = rom_addr + addr; + uint32_t ret = 0; + + switch(size) + { + /* read from the mirrored copy (modeled as regular RAM) */ + case 1: + cpu_physical_memory_read(address + rom_size, &ret, 1); + break; + case 2: + cpu_physical_memory_read(address + rom_size, &ret, 2); + break; + case 4: + cpu_physical_memory_read(address + rom_size, &ret, 4); + break; + } + + char name[16]; + snprintf(name, sizeof(name), "ROM%d:%d", rom_id, size); + if (msg) + { + /* fixme: -d rom */ + io_log(name, s, address, MODE_READ, 0, ret, msg, 0, 0); + } + return ret; +} + +static void eos_rom_write(void * opaque, hwaddr addr, uint64_t val, uint32_t size) +{ + EOSState * s = (EOSState *)((intptr_t) opaque & ~1); + uint32_t rom_id = (intptr_t) opaque & 1; + uint32_t rom_addr = (rom_id) ? ROM1_ADDR : ROM0_ADDR;; + uint32_t address = rom_addr + addr; + + printf("ROM(0x%08x) <= 0x%x (ignored)\n", address, (uint32_t)val); +} + +static const MemoryRegionOps rom_ops = { + .read = eos_rom_read, + .write = eos_rom_write, + .endianness = DEVICE_NATIVE_ENDIAN, +}; void eos_load_image(EOSState *s, const char * file_rel, int offset, int max_size, uint32_t addr, int swap_endian) @@ -996,6 +1045,36 @@ /** EOS CPU SETUP **/ +static void eos_init_rom(EOSState *s, int rom_id, MemoryRegion * rom, MemoryRegion * rom_flash, uint32_t rom_addr, uint32_t rom_size, uint64_t rom_limit) +{ + char name[32]; + + /* base address: use for flash emulation and model as I/O memory to log accesses */ + /* fixme: any side effects? only do this when -d rom is used? */ + sprintf(name, "eos.rom%d_flash", rom_id); + /* fixme: not a very nice way to pass both EOSState * and rom ID */ + memory_region_init_io(rom_flash, NULL, &rom_ops, (void *)((uintptr_t) s | rom_id), name, rom_size); + memory_region_add_subregion(s->system_mem, rom_addr, rom_flash); + + /* mirror addresses: use for execution (model as RAM + aliases) */ + for(uint64_t offset = rom_addr + rom_size; offset < rom_limit; offset += rom_size) + { + if (offset == rom_addr + rom_size) + { + sprintf(name, "eos.rom%d", rom_id); + memory_region_init_ram(rom, NULL, name, rom_size, &error_abort); + memory_region_add_subregion(s->system_mem, offset, rom); + } + else + { + sprintf(name, "eos.rom%d_mirror", rom_id); + MemoryRegion *image = g_new(MemoryRegion, 1); + memory_region_init_alias(image, NULL, name, rom, 0x00000000, rom_size); + memory_region_add_subregion(s->system_mem, offset, image); + } + } +} + static EOSState *eos_init_cpu(struct eos_model_desc * model) { @@ -1074,35 +1153,12 @@ /* set up ROM0 */ if (ROM0_SIZE) { - memory_region_init_ram(&s->rom0, NULL, "eos.rom0", ROM0_SIZE, &error_abort); - memory_region_add_subregion(s->system_mem, ROM0_ADDR, &s->rom0); - - for(uint64_t offset = ROM0_ADDR + ROM0_SIZE; offset < ROM1_ADDR; offset += ROM0_SIZE) - { - char name[32]; - MemoryRegion *image = g_new(MemoryRegion, 1); - sprintf(name, "eos.rom0_mirror_%02X", (uint32_t)offset >> 24); - - memory_region_init_alias(image, NULL, name, &s->rom0, 0x00000000, ROM0_SIZE); - memory_region_add_subregion(s->system_mem, offset, image); - } + eos_init_rom(s, 0, &s->rom0, &s->rom0_flash, ROM0_ADDR, ROM0_SIZE, ROM1_SIZE); } if (ROM1_SIZE) { - /* set up ROM1 */ - memory_region_init_ram(&s->rom1, NULL, "eos.rom1", ROM1_SIZE, &error_abort); - memory_region_add_subregion(s->system_mem, ROM1_ADDR, &s->rom1); - - for(uint64_t offset = ROM1_ADDR + ROM1_SIZE; offset < 0x100000000; offset += ROM1_SIZE) - { - char name[32]; - MemoryRegion *image = g_new(MemoryRegion, 1); - sprintf(name, "eos.rom1_mirror_%02X", (uint32_t)offset >> 24); - - memory_region_init_alias(image, NULL, name, &s->rom1, 0x00000000, ROM1_SIZE); - memory_region_add_subregion(s->system_mem, offset, image); - } + eos_init_rom(s, 1, &s->rom1, &s->rom1_flash, ROM1_ADDR, ROM1_SIZE, 0x100000000); } //memory_region_init_ram(&s->rom1, "eos.rom", 0x10000000, &error_abort); @@ -1237,13 +1293,13 @@ /* populate ROM0 */ if (ROM0_SIZE) { - eos_load_image(s, "ROM0.BIN", 0, ROM0_SIZE, ROM0_ADDR, 0); + eos_load_image(s, "ROM0.BIN", 0, ROM0_SIZE, ROM0_ADDR + ROM0_SIZE, 0); } /* populate ROM1 */ if (ROM1_SIZE) { - eos_load_image(s, "ROM1.BIN", 0, ROM1_SIZE, ROM1_ADDR, 0); + eos_load_image(s, "ROM1.BIN", 0, ROM1_SIZE, ROM1_ADDR + ROM1_SIZE, 0); } /* init SD card */ diff -r 7b9fa551c350 -r bd309657da05 contrib/qemu/eos/eos.h --- a/contrib/qemu/eos/eos.h +++ b/contrib/qemu/eos/eos.h @@ -227,6 +227,8 @@ MemoryRegion ram_extra; MemoryRegion rom0; MemoryRegion rom1; + MemoryRegion rom0_flash; + MemoryRegion rom1_flash; uint8_t *rom0_data; uint8_t *rom1_data; MemoryRegion iomem; # HG changeset patch # User alex@thinkpad # Branch qemu # Node ID 31e44e87a862538b33a6788abe22484f0ead614c # Parent bd309657da051d2db8102236a394de55daf67b4f QEMU: return flash model ID for 1300D (fixes startup assertion) diff -r bd309657da05 -r 31e44e87a862 contrib/qemu/eos/eos.c --- a/contrib/qemu/eos/eos.c +++ b/contrib/qemu/eos/eos.c @@ -323,6 +323,27 @@ break; } + if (strcmp(s->model->name, "1300D") == 0) + { + switch (address) + { + case 0xF8000000: + case 0xF8000001: + case 0xF8000002: + { + /* fixme: a bit hackish */ + unsigned int lr = CURRENT_CPU->env.regs[14]; + if (size == 1 && lr == 0x1D4D4) + { + msg = "Flash model ID?"; + const int model_id[] = { 0xC2, 0x25, 0x39 }; + ret = model_id[address & 3]; + break; + } + } + } + } + char name[16]; snprintf(name, sizeof(name), "ROM%d:%d", rom_id, size); if (msg) # HG changeset patch # User alex@thinkpad # Branch qemu # Node ID d38957f91fb7b994ee9f9e904d86055a957b189e # Parent 31e44e87a862538b33a6788abe22484f0ead614c QEMU: partial MPU support for 1300D (status register not implemented; is it required?) diff -r 31e44e87a862 -r d38957f91fb7 contrib/qemu/eos/model_list.c --- a/contrib/qemu/eos/model_list.c +++ b/contrib/qemu/eos/model_list.c @@ -224,6 +224,7 @@ .rom0_size = 0x02000000, .rom1_size = 0x02000000, .firmware_start = 0xFF0C0000, + .mpu_request_register = 0xC022D0C4, }, { .name = "EOSM", diff -r 31e44e87a862 -r d38957f91fb7 contrib/qemu/eos/mpu.c --- a/contrib/qemu/eos/mpu.c +++ b/contrib/qemu/eos/mpu.c @@ -245,6 +245,8 @@ * - tst 0x2 in SIO3 and MREQ ISRs * - should return 0x44 when sending data to MPU * - and 0x47 when receiving data from MPU + * - 1300D uses 0x83DC00 = reqest to send, 0x93D800 idle + * - status register appears to be 0xC022F484 (fixme) */ int ret = 0; @@ -258,7 +260,7 @@ int prev_value = s->mpu.status; s->mpu.status = value; - if (value & 2) + if (value & 0x100002) { if (s->mpu.receiving) { @@ -285,7 +287,7 @@ } } } - else if (prev_value & 2) + else if (prev_value & 0x100002) { /* receive request: transition of bit (1<<1) from high to low */ msg = "Receive request %s"; @@ -713,6 +715,7 @@ /* 1200D works with 60D MPU spells... and BOOTS THE GUI!!! */ MPU_SPELL_SET_OTHER_CAM(1200D, 60D) + MPU_SPELL_SET_OTHER_CAM(1300D, 60D) /* same for 1100D */ MPU_SPELL_SET_OTHER_CAM(1100D, 60D) # HG changeset patch # User alex@thinkpad # Branch qemu # Node ID d2dd4b217fd77334f3aba2cc70ab454643367a35 # Parent d38957f91fb7b994ee9f9e904d86055a957b189e 1300D mpu status register (unused?!) diff -r d38957f91fb7 -r d2dd4b217fd7 contrib/qemu/eos/mpu.c --- a/contrib/qemu/eos/mpu.c +++ b/contrib/qemu/eos/mpu.c @@ -320,12 +320,12 @@ s->mpu.sending = 0; } - ret = (s->mpu.sending && !s->mpu.receiving) ? 0x3 : /* I have data to send */ - (!s->mpu.sending && s->mpu.receiving) ? 0x0 : /* I'm ready to receive data */ - (s->mpu.sending && s->mpu.receiving) ? 0x1 : /* I'm ready to send and receive data */ - 0x2 ; /* I believe this is some error code */ - ret |= (s->mpu.status & 0xFFFFFFFC); /* The other bits are unknown; - they are set to 0x44 by writing to the register */ + ret = (s->mpu.sending && !s->mpu.receiving) ? 0x40003 : /* I have data to send */ + (!s->mpu.sending && s->mpu.receiving) ? 0x00000 : /* I'm ready to receive data */ + (s->mpu.sending && s->mpu.receiving) ? 0x00001 : /* I'm ready to send and receive data */ + 0x40002 ; /* I believe this is some error code */ + ret |= (s->mpu.status & 0xFFFBFFFC); /* The other bits are unknown; + they are set to 0x44 by writing to the register */ msg = "status (sending=%d, receiving=%d)"; msg_arg1 = s->mpu.sending; # HG changeset patch # User alex@thinkpad # Branch qemu # Node ID e7709fad7e4984c9f839fffbc8f30209323c3b55 # Parent d2dd4b217fd77334f3aba2cc70ab454643367a35 1300d gdb diff -r d2dd4b217fd7 -r e7709fad7e49 contrib/qemu/scripts/1300D/debugmsg.gdb --- /dev/null +++ b/contrib/qemu/scripts/1300D/debugmsg.gdb @@ -0,0 +1,38 @@ +# ./run_canon_fw.sh 1200D -s -S & arm-none-eabi-gdb -x 1200D/debugmsg.gdb + +source -v debug-logging.gdb + +b *0xFE1201BC +commands + silent + printf "read_gpio(%x)\n", $r0 + c +end + +b *0xFE1201D0 +commands + silent + printf "read_gpio: %x & %x\n", $r0, $r2 + c +end + + +b *0x27C4 +commands + silent + printf "sub_27C4(%x, %x, %x, %x)\n", $r0, $r1, $r2, $r3 + set $out1 = $r1 + set $out2 = $r2 + set $out3 = $r3 + tbreak *($lr & ~1) + commands + silent + printf "sub_27C4 => %x (%x, %x, %x)\n", $r0, *(int*)$out1, *(int*)$out2, *(int*)$out3 + c + end + + c +end + + +cont