Read about our upcoming Code of Conduct on this issue

Commit 9677c3fc authored by alex@thinkpad's avatar alex@thinkpad
Browse files

Merged qemu into 1200D

--HG--
branch : 1200D
......@@ -82,7 +82,7 @@ prepare_zip: FORCE
mkdir -p $(INSTALL_DIR)
# zip.txt must be the first item on the list!
magiclantern-$(VERSION).zip: install installer_check installdoc
magiclantern-$(VERSION).zip: install installer_check installdoc minimal_check
-$(call rm_files, $@)
chmod -x $(INSTALL_DIR)/autoexec.bin
cd $(INSTALL_DIR); zip -z ../$@ < \
......
......@@ -30,8 +30,8 @@ The default directory structure looks like this::
│ │ └── ...
│ │
│ ├── minimal/ # minimal targets, for experiments
│ │ ├── 5D3.113 # these will use other files from the platform directory
│ │ ├── EOSM # if only one firmware version is supported, it can be omitted
│ │ ├── hello-world # these will use other files from the platform directory
│ │ ├── qemu-frsp # compile with "make MODEL=EOSM" or "make MODEL=5D3 FW_VERSION=123"
│ │ └── ...
│ │
│ ├── installer/ # for building ML-SETUP.FIR (which enables/disables the boot flag)
......@@ -302,11 +302,19 @@ Initial firmware analysis
DIGIC 5 and earlier models will start the bootloader at ``0xFFFF0000`` (HIVECS)
and will jump to main firmware at ``0xFF810000``, ``0xFF010000`` or ``0xFF0C0000``.
There is one main ROM (ROM1) at ``0xF8000000``, 4/8/16/32 MiB mirrored until ``0xFFFFFFFF``,
and there may be a second ROM (ROM0) at 0xF0000000, mirrored until ``0xF8000000 - 1 = 0xF7FFFFFF``.
and there may be a second ROM (ROM0) at ``0xF0000000``, mirrored until ``0xF8000000 - 1 = 0xF7FFFFFF``.
Some DIGIC 5 models also use a serial flash for storing properties (persistent settings).
DIGIC 6 will start at ``*(uint32_t*)0xFC000000``,
DIGIC 6 models will start at ``*(uint32_t*)0xFC000000``,
bootloader is at 0xFE020000 and main firmware starts at 0xFE0A0000. There is
a 32 MiB ROM mirrored at 0xFC000000 and 0xFE000000 (there may be others).
There is a serial flash as well, used for storing properties.
DIGIC 7 models will start at ``0xE0000000`` in ARM mode
and will jump to main firmware at ``0xE0040000`` in Thumb mode.
There is a 32 MiB ROM (ROM0) at ``0xE0000000``, mirrored until ``0xEFFFFFFF``,
and an unusually slow 16 MiB ROM (ROM1) at ``0xF0000000``, mirrored until ``0xFFFFFFFF``.
No serial flash was identified.
The ROM load address is the one you have used when dumping it (usually one of the mirrors).
The memory map is printed when starting QEMU — you'll see where each ROM is loaded
......@@ -335,17 +343,7 @@ Initial firmware analysis
3) Add a very simple definition for your camera and get an `initial test run`_.
Try to guess some missing bits from the error messages, if possible.
4) (optional) Export the functions called during your test run:
.. code:: shell
./run_canon_fw.sh EOSM2,firmware="boot=0" -d idc
...
EOSM2.idc saved.
Load the IDC script into IDA, or convert it if you are using a different disassembler.
5) Code blocks copied from ROM to RAM
4) Code blocks copied from ROM to RAM
.. code:: shell
......@@ -367,6 +365,30 @@ Initial firmware analysis
If you are analyzing the bootloader, extract and load the first two blobs in the same way.
Other models may have slightly different configurations, so YMMV.
5) Export the functions called during your test run:
.. code:: shell
./run_canon_fw.sh EOSM2,firmware="boot=0" -d idc
...
EOSM2.idc saved.
Load the IDC script into IDA, or convert it if you are using a different disassembler.
Locate ``task_create``, ``register_func``, ``register_interrupt`` and ``CreateStateObject``
and add GDB stubs for them in ``CAM/debugmsg.gdb``. Run the firmware under GDB
to identify some (thousands of) named functions.
.. code:: shell
./run_canon_fw.sh EOSM2,firmware="boot=0" -d debugmsg -s -S & arm-none-eabi-gdb -x EOSM2/debugmsg.gdb
...
named_functions.idc saved.
Load the new IDC script into IDA and start hacking!
Repeat this procedure as the emulation is getting better, to identify new functions.
|
Initial test run
......
......@@ -21,20 +21,20 @@ Current state
What works:
- Canon GUI with menu navigation — most DIGIC 3, 4 and 5 models,
- Canon GUI with menu navigation — most DIGIC 3, 4 and 5 models
- Limited support for DIGIC 2, 6 and 7 models
- Limited support for some PowerShot models (including recent EOS M models)
- Limited support for secondary DryOS cores (such as Eeko or 5D4 AE processor)
- File I/O works on most models (both SD and CF); might be unreliable
- Bootloader emulation works on all supported models (from DIGIC 2 to DIGIC 7)
- Loading AUTOEXEC.BIN / DISKBOOT.BIN from the virtual SD/CF card (from DIGIC 2 to DIGIC 6)
- Loading AUTOEXEC.BIN / DISKBOOT.BIN from the virtual SD/CF card (from DIGIC 2 to DIGIC 7)
- Unmodified autoexec.bin works on many single-core camera models
(and, with major limitations, on dual-core models)
- ML modules and Lua scripts (within the limitations of the emulation)
- DryOS/VxWorks timer (heartbeat) and task switching (all supported models)
- UART emulation (DryOS shell aka Dry-shell or DrySh on DIGIC 4, 5 and 6 models)
- UART emulation (DryOS shell aka Dry-shell or DrySh on DIGIC 4, 5, 6 and 7 models)
- Deterministic execution with the ``-icount`` option (except CF PIO)
- Cache hacks are emulated to some extent (but "uninstalling" them does not work)
- Cache hacks are emulated to some extent, but not exactly accurate
- EDMAC memcpy, including geometry parameters (matches the hardware closely, but not perfectly)
- Debugging with GDB:
......@@ -62,7 +62,7 @@ What works:
- log hardware devices: ``-d mpu/sflash/sdcf/uart/int``
- log all debug messages from Canon: ``-d debugmsg``
- log all memory accesses: ``-d rom/ram/romr/ramw/etc``
- log all function calls: ``-d calls``, ``-d calls,tail``
- log all function calls: ``-d calls``
- log all DryOS/VxWorks task switches: ``-d tasks``
- track all function calls to provide a stack trace: ``-d callstack``
- export all called functions to IDC script: ``-d idc``
......@@ -95,13 +95,6 @@ Common issues and workarounds
__ `Opening the card door`_
- dm-spy-experiments: saving the log and anything executed afterwards may not work
- issue: cache hacks are not emulated very well
- workaround: compile with ``CONFIG_QEMU=y``
|
.. _netcat-issue:
- Netcat issues when interacting with ``qemu.monitor``
......@@ -222,7 +215,7 @@ the `boot flag <http://magiclantern.wikia.com/wiki/Bootflags>`_ is disabled:
./run_canon_fw.sh 60D,firmware="boot=0"
Some models may need additional patches to run — these are stored under ``CAM/patches.gdb``.
To emulate these models, you will also need arm-none-eabi-gdb:
To emulate these models, you will also need ``arm-none-eabi-gdb`` or ``gdb-multiarch``:
.. code:: shell
......@@ -247,6 +240,7 @@ __ `Debugging with GDB`_
.. code:: shell
./run_canon_fw.sh 60D,firmware="boot=0" -s -S & arm-none-eabi-gdb -x 60D/debugmsg.gdb
./run_canon_fw.sh 60D,firmware="boot=0" -s -S & gdb-multiarch -x 60D/debugmsg.gdb
Running Magic Lantern
---------------------
......@@ -896,17 +890,11 @@ Memory access trace (ROM reads, RAM writes) — very verbose:
./run_canon_fw.sh 60D,firmware="boot=0" -d romr,ramw
Call/return trace (not including tail function calls):
.. code:: shell
./run_canon_fw.sh 60D,firmware="boot=0" -d calls
Also with tail calls, redirected to a log file:
Call/return trace, redirected to a log file:
.. code:: shell
./run_canon_fw.sh 60D,firmware="boot=0" -d calls,tail &> calls.log
./run_canon_fw.sh 60D,firmware="boot=0" -d calls &> calls.log
Tip: set your editor to highlight the log file as if it were Python code.
You'll get collapse markers for free :)
......@@ -915,7 +903,7 @@ Also with debug messages, I/O events and interrupts, redirected to file
.. code:: shell
./run_canon_fw.sh 60D,firmware="boot=0" -d debugmsg,calls,tail,io,int &> full.log
./run_canon_fw.sh 60D,firmware="boot=0" -d debugmsg,calls,io,int &> full.log
Filter the logs with grep:
......@@ -1017,7 +1005,7 @@ Printing call stack from GDB
The ``callstack`` option from QEMU (``eos/dbi/logging.c``) can be very useful to find where a function was called from.
This works even when gdb's ``backtrace`` command cannot figure it out from the stack contents, does not require any debugging symbols,
but you need to run the emulation with instrumentation enabled: ``-d callstack`` or ``-d callstack,tail``.
but you need to run the emulation with instrumentation enabled: ``-d callstack``.
Then, in GDB, use ``print_current_location_with_callstack`` to see the call stack for the current DryOS task.
......@@ -1089,7 +1077,7 @@ The instrumentation framework provides the following features:
- log all debug messages from Canon: ``-d debugmsg``
- log all memory accesses: ``-d rom/ram/romr/ramw/etc``
- log all function calls: ``-d calls``, ``-d calls,tail``
- log all function calls: ``-d calls``
- log all DryOS/VxWorks task switches: ``-d tasks``
- track all function calls to provide a stack trace: ``-d callstack``
- export all called functions to IDC script: ``-d idc``
......@@ -1137,6 +1125,7 @@ History
:2017: `RTC emulation, many patches no longer needed <http://www.magiclantern.fm/forum/index.php?topic=2864.msg190823#msg190823>`_ (g3gg0)
:2017: `Major progress with DIGIC 6 emulation <http://www.magiclantern.fm/forum/index.php?topic=17360.msg194898#msg194898>`_
:2017: `Menu navigation works on 20 EOS models! (DIGIC 3-5) <http://www.magiclantern.fm/forum/index.php?topic=2864.msg195117#msg195117>`_
:2018: `Initial support for DIGIC 7 EOS models (77D, 200D, 6D Mark II) <https://www.magiclantern.fm/forum/index.php?topic=19737.msg200799#msg200799>`_
......
......@@ -279,7 +279,7 @@ static FILE * idc = NULL;
static void close_idc(void)
{
fprintf(idc, "}\n");
fclose(idc);
fclose(idc); idc = 0;
fprintf(stderr, "%s saved.\n", idc_path);
}
......@@ -290,7 +290,7 @@ static void eos_idc_log_call(EOSState *s, CPUState *cpu, CPUARMState *env,
if (!idc)
{
snprintf(idc_path, sizeof(idc_path), "%s.idc", MACHINE_GET_CLASS(current_machine)->name);
snprintf(idc_path, sizeof(idc_path), "%s/calls.idc", s->model->name);
fprintf(stderr, "Exporting called functions to %s.\n", idc_path);
idc = fopen(idc_path, "w");
assert(idc);
......@@ -597,7 +597,8 @@ void eos_callstack_print_verbose(EOSState *s)
len += eos_indent(len, CALLSTACK_RIGHT_ALIGN);
eos_print_location(s, ret, sp, " at ", "\n");
uint32_t pc0 = pc & ~1;
assert(pc0 == 0x18);
uint32_t vbar = CURRENT_CPU->env.cp15.vbar_s;
assert(pc0 == vbar + 0x18);
}
else
{
......@@ -658,6 +659,11 @@ int eos_print_location_gdb(EOSState *s)
ret = stack_lr - 4;
}
/* on multicore machines, print CPU index for each message */
if (CPU_NEXT(first_cpu)) {
fprintf(stderr, "[CPU%d] ", current_cpu->cpu_index);
}
if (interrupt_level) {
return fprintf(stderr, "[%s INT-%02Xh:%08x %s] ", KCYN, s->irq_id, ret, KRESET);
} else {
......@@ -1000,6 +1006,9 @@ static void eos_callstack_log_exec(EOSState *s, CPUState *cpu, TranslationBlock
uint32_t lr0 = lr & ~1;
uint32_t prev_pc0 = prev_pc & ~1;
uint32_t vbar = env->cp15.vbar_s;
assert(vbar == 0 || s->model->digic_version == 7);
/* tb->pc always has the Thumb bit cleared */
assert(pc0 == tb->pc);
......@@ -1022,7 +1031,7 @@ static void eos_callstack_log_exec(EOSState *s, CPUState *cpu, TranslationBlock
goto end;
}
if (pc0 == 0x18)
if (pc0 == vbar + 0x18)
{
/* handle interrupt jumps first */
......@@ -1057,7 +1066,7 @@ static void eos_callstack_log_exec(EOSState *s, CPUState *cpu, TranslationBlock
goto end;
}
if (prev_pc0 == 0x18)
if (prev_pc0 == vbar + 0x18)
{
/* jump from the interrupt vector - ignore */
goto end;
......@@ -1492,10 +1501,10 @@ recheck:
/* assume tail call
* fixme: in IDC, these must be defined before their caller,
* as IDA frequently gets them wrong */
if (qemu_loglevel_mask(EOS_LOG_TAIL_CALLS)) {
if (!qemu_loglevel_mask(EOS_LOG_NO_TAIL_CALLS)) {
goto function_call;
}
/* without -d tail, report as jump */
/* with -d notail, report as jump */
}
else
{
......@@ -1514,8 +1523,8 @@ recheck:
* note: most cases appear to be valid tail calls,
* but not identified properly because of
* a missed function call right before this */
if (qemu_loglevel_mask(EOS_LOG_TAIL_CALLS)) {
/* note: many warnings without -d tail */
if (!qemu_loglevel_mask(EOS_LOG_NO_TAIL_CALLS)) {
/* note: many warnings with -d notail */
/* there's also a false warning at first jump */
if (!(id == 0x7F && call_stack_num[id] == 0))
{
......@@ -1530,7 +1539,7 @@ recheck:
if (abs((int)pc - (int)prev_pc) > 0x100)
{
goto function_call;
/* without -d tail, report as jump */
/* with -d notail, report as jump */
}
}
}
......@@ -1609,6 +1618,8 @@ static void eos_tasks_log_exec(EOSState *s, CPUState *cpu, TranslationBlock *tb)
prev_lr = lr;
}
#ifdef __SIZEOF_INT128__
static uint32_t block_start; /* destination address */
static uint32_t block_size;
static uint32_t block_offset; /* start + offset = source address */
......@@ -1620,14 +1631,54 @@ static uint32_t last_write_addr;
static uint32_t last_write_size;
static __uint128_t last_write_value;
static void romcpy_log_n_reset_block(void)
static char dd_path[100];
static FILE * dd = 0;
static void close_dd(void)
{
fclose(dd); dd = 0;
fprintf(stderr, "%s saved.\n", dd_path);
}
static void romcpy_log_block(EOSState *s)
{
uint32_t block_rom_start = block_start + block_offset;
fprintf(stderr, "[ROMCPY] 0x%-8X -> 0x%-8X size 0x%-8X at 0x%-8X\n",
block_rom_start, block_start, block_size, block_pc
);
hwaddr l = block_size;
hwaddr block_rom_start_rel;
MemoryRegion * mr = address_space_translate(&address_space_memory, block_rom_start, &block_rom_start_rel, &l, 0);
assert(l == block_size);
if (strcmp(mr->name, "eos.rom0") == 0 ||
strcmp(mr->name, "eos.rom1") == 0)
{
if (!dd)
{
snprintf(dd_path, sizeof(dd_path), "%s/romcpy.sh", s->model->name);
fprintf(stderr, "Logging ROM-copied blocks to %s.\n", dd_path);
dd = fopen(dd_path, "w");
assert(dd);
atexit(close_dd);
}
/* fixme: dd executes a bit slow with bs=1 */
fprintf(dd, "dd if=ROM%c.BIN of=%s.0x%X.bin bs=1 skip=$((0x%X)) count=$((0x%X))\n",
mr->name[7],
s->model->name, block_start, (int)block_rom_start_rel, block_size
);
}
}
static void romcpy_log_n_reset_block(EOSState *s)
{
if (block_size >= 64)
{
/* block large enough to report? */
fprintf(stderr, "[ROMCPY] 0x%-8X -> 0x%-8X size 0x%-8X at 0x%-8X\n",
block_start + block_offset, block_start, block_size, block_pc
);
romcpy_log_block(s);
}
/* reset block */
......@@ -1733,7 +1784,7 @@ static void eos_romcpy_log_mem(EOSState *s, MemoryRegion *mr, hwaddr _addr, uint
/* not growing current block; assume a new one might have been started */
qemu_log_mask(EOS_LOG_VERBOSE, "new block (previous %x-%x)\n", block_start, block_start + block_size);
uint32_t pc = CURRENT_CPU->env.regs[15];
romcpy_log_n_reset_block();
romcpy_log_n_reset_block(s);
romcpy_new_block(last_write_addr, last_read_addr, item_size, pc);
}
}
......@@ -1741,15 +1792,29 @@ static void eos_romcpy_log_mem(EOSState *s, MemoryRegion *mr, hwaddr _addr, uint
else /* some other value written to memory */
{
qemu_log_mask(EOS_LOG_VERBOSE, "reset block (previous %x-%x)\n", block_start, block_size);
romcpy_log_n_reset_block();
romcpy_log_n_reset_block(s);
}
}
}
#else /* no int128_t available */
static void eos_romcpy_log_mem(EOSState *s, MemoryRegion *mr, hwaddr _addr, uint64_t _value, uint32_t size, int flags)
{
fprintf(stderr, "FIXME: ROMCPY not supported on this platform.\n");
}
#endif
static uint64_t saved_loglevel = 0;
static void tb_exec_cb(void *opaque, CPUState *cpu, TranslationBlock *tb)
{
if (current_cpu->cpu_index)
{
/* ignore CPU1 for now */
return;
}
if (qemu_loglevel_mask(EOS_LOG_AUTOEXEC) &&
saved_loglevel != 0 &&
saved_loglevel != qemu_loglevel)
......@@ -1808,7 +1873,7 @@ static void load_symbols(const char * elf_filename)
fprintf(stderr, "[EOS] loading symbols from %s ", elf_filename);
uint64_t lo, hi;
int size = load_elf(elf_filename, 0, 0, 0, &lo, &hi, 0, EM_ARM, 1);
fprintf(stderr, "(%lX-%lX)\n", lo, hi);
fprintf(stderr, "(%X - %X)\n", (int) lo, (int) hi);
assert(size > 0);
}
......
......@@ -533,7 +533,7 @@ static void exec_log_memcpy(EOSState *s, uint32_t pc, CPUARMState *env)
memcpy_chk[id] = mem_status_checksum(memcpy_src[id], memcpy_num[id]);
if (qemu_loglevel_mask(EOS_LOG_VERBOSE)) {
eos_callstack_indent(s);
fprintf(stderr, "Flags checksum: %lx\n", memcpy_chk[id]);
fprintf(stderr, "Flags checksum: %"PRIx64"\n", memcpy_chk[id]);
}
}
for (int id = 0; id < COUNT(memcpy_lr); id++)
......
......@@ -500,6 +500,9 @@ static int edmac_do_transfer(EOSState *s, int channel)
(((xa + off1a) * yb + xa + off2b) * xn +
(xb + off1b) * yb + xb + off3);
/* we must have some valid address configured */
assert(s->edmac.ch[channel].addr);
if (channel & 8)
{
/* from memory to image processing modules */
......@@ -565,7 +568,20 @@ static int edmac_do_transfer(EOSState *s, int channel)
load_fullres_14bit_raw(s, s->edmac.conn_data[conn].buf, raw_width, raw_height);
}
}
else if (conn == 6 || conn == 7)
{
/* pass-through; wait for data sent by some other channel on the same connection */
/* nothing to do here */
}
else
{
fprintf(stderr, "[ENGINE] FIXME: returning dummy data on <%d>\n", conn);
s->edmac.conn_data[conn].buf = malloc(transfer_data_size);
assert(s->edmac.conn_data[conn].buf);
s->edmac.conn_data[conn].data_size = transfer_data_size;
memset(s->edmac.conn_data[conn].buf, 0, transfer_data_size);
}
if (s->edmac.conn_data[conn].data_size < transfer_data_size)
{
fprintf(stderr, "[EDMAC#%d] Data %s; will try again later.\n", channel,
......@@ -629,6 +645,14 @@ static int edmac_do_transfer(EOSState *s, int channel)
/* assume 200 MB/s transfer speed */
int delay = transfer_data_size * 1e6 / (200*1024*1024) / 0x100;
if (channel & 8)
{
/* additional delay for read channels */
/* required by to pass the memory benchmark (?!) */
delay++;
}
fprintf(stderr, "[EDMAC#%d] transfer delay %d x 256 us.\n", channel, delay);
edmac_trigger_interrupt(s, channel, delay);
......@@ -857,8 +881,14 @@ unsigned int eos_handle_edmac_chsw ( unsigned int parm, EOSState *s, unsigned in
unsigned int ret = 0;
/* fixme: reads not implemented */
assert(type & MODE_WRITE);
if (!(type & MODE_WRITE))
{
/* apparently these reads are just bugs in Canon code */
msg = KLRED"unexpected read"KRESET;
// assert(0);
goto end;
}
if (value == 0x80000000)
{
/* ?! used on M3 */
......
This diff is collapsed.
......@@ -66,8 +66,8 @@
#define ATCM_SIZE s->model->atcm_size
#define RAM_SIZE s->model->ram_size
#define CACHING_BIT s->model->caching_bit
#define IO_MEM_START 0xC0000000 /* common to all DIGICs */
#define MMIO_ADDR s->model->mmio_addr
#define MMIO_SIZE s->model->mmio_size
/* defines for memory/register access */
#define INT_ENTRIES 0x200
......@@ -225,9 +225,9 @@ typedef struct
typedef struct
{
EDmacChState ch[64];
uint32_t read_conn[48]; /* each connection can get data from a single read channel */
uint32_t read_conn[64]; /* each connection can get data from a single read channel */
uint32_t write_conn[64]; /* each write channel can get data from a single connection */
EDmacData conn_data[48]; /* for each connection: memory contents transferred via EDMAC (malloc'd) */
EDmacData conn_data[64]; /* for each connection: memory contents transferred via EDMAC (malloc'd) */
uint32_t pending[64]; /* for each channel: true if a transfer is scheduled */
} EDMACState;
......@@ -266,7 +266,7 @@ typedef struct
MemoryRegion ram_extra;
MemoryRegion rom0;
MemoryRegion rom1;
MemoryRegion iomem;
MemoryRegion mmio;
qemu_irq interrupt;
QemuThread interrupt_thread_id;
uint32_t verbosity;
......@@ -275,9 +275,11 @@ typedef struct
uint32_t irq_schedule[INT_ENTRIES];
uint32_t irq_id;
uint32_t digic_timer;
uint32_t digic_timer_last_read;
uint32_t timer_reload_value[20];
uint32_t timer_current_value[20];
uint32_t timer_enabled[20];
struct HPTimer UTimers[8];
struct HPTimer HPTimers[16];
uint32_t clock_enable;
uint32_t clock_enable_6;
......@@ -351,6 +353,7 @@ unsigned int eos_handle_rom ( unsigned int parm, EOSState *s, unsigned int addre
unsigned int eos_handle_flashctrl ( unsigned int parm, EOSState *s, unsigned int address, unsigned char type, unsigned int value );
unsigned int eos_handle_dma ( unsigned int parm, EOSState *s, unsigned int address, unsigned char type, unsigned int value );
unsigned int eos_handle_xdmac ( unsigned int parm, EOSState *s, unsigned int address, unsigned char type, unsigned int value );
unsigned int eos_handle_xdmac7 ( unsigned int parm, EOSState *s, unsigned int address, unsigned char type, unsigned int value );
unsigned int eos_handle_ram ( unsigned int parm, EOSState *s, unsigned int address, unsigned char type, unsigned int value );
unsigned int eos_handle_sio ( unsigned int parm, EOSState *s, unsigned int address, unsigned char type, unsigned int value );
unsigned int eos_handle_i2c ( unsigned int parm, EOSState *s, unsigned int address, unsigned char type, unsigned int value );
......@@ -360,6 +363,7 @@ unsigned int eos_handle_uart_dma ( unsigned int parm, EOSState *s, unsigned int
unsigned int eos_handle_timers ( unsigned int parm, EOSState *s, unsigned int address, unsigned char type, unsigned int value );
unsigned int eos_handle_timers_ ( unsigned int parm, EOSState *s, unsigned int address, unsigned char type, unsigned int value );
unsigned int eos_handle_digic_timer ( unsigned int parm, EOSState *s, unsigned int address, unsigned char type, unsigned int value );
unsigned int eos_handle_utimer ( unsigned int parm, EOSState *s, unsigned int address, unsigned char type, unsigned int value );
unsigned int eos_handle_hptimer ( unsigned int parm, EOSState *s, unsigned int address, unsigned char type, unsigned int value );
unsigned int eos_handle_intengine ( unsigned int parm, EOSState *s, unsigned int address, unsigned char type, unsigned int value );
unsigned int eos_handle_intengine_vx ( unsigned int parm, EOSState *s, unsigned int address, unsigned char type, unsigned int value );
......@@ -383,6 +387,8 @@ unsigned int eos_handle_adc ( unsigned int parm, EOSState *s, unsigned int addre
unsigned int eos_handle_jpcore( unsigned int parm, EOSState *s, unsigned int address, unsigned char type, unsigned int value );
unsigned int eos_handle_eeko_comm( unsigned int parm, EOSState *s, unsigned int address, unsigned char type, unsigned int value );
unsigned int eos_handle_memdiv( unsigned int parm, EOSState *s, unsigned int address, unsigned char type, unsigned int value );
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_digic6 ( unsigned int parm, EOSState *s, unsigned int address, unsigned char type, unsigned int value );
......
......@@ -28,15 +28,15 @@ unsigned int eos_handle_ml_helpers ( unsigned int parm, EOSState *s, unsigned in
{
if(type & MODE_WRITE)
{
switch (address)
switch (address & 0xFF)
{
case REG_PRINT_CHAR: /* print in blue */
case REG_PRINT_CHAR & 0xFF: /* print in blue */
{
print_char(value);
return 0;
}
case REG_PRINT_NUM: /* print an int32 from the guest */
case REG_PRINT_NUM & 0xFF: /* print an int32 from the guest */
{
char num[32];
snprintf(num, sizeof(num), "0x%x (%d) ", (uint32_t)value, (uint32_t)value);
......@@ -47,72 +47,17 @@ unsigned int eos_handle_ml_helpers ( unsigned int parm, EOSState *s, unsigned in
return 0;
}
case REG_DISAS_32: /* disassemble address (32-bit, ARM or Thumb) */
case REG_DISAS_32 & 0xFF: /* disassemble address (32-bit, ARM or Thumb) */
fprintf(stderr, KGRN);
target_disas(stderr, CPU(arm_env_get_cpu(&s->cpu0->env)), value & ~1, 4, value & 1);
fprintf(stderr, KRESET);
return 0;
case REG_SHUTDOWN:
fprintf(stderr, "Goodbye!\n");
qemu_system_shutdown_request();
return 0;
case REG_BMP_VRAM:
s->disp.bmp_vram = (uint32_t) value;
return 0;
case REG_IMG_VRAM:
s->disp.img_vram = (uint32_t) value;
if (value)
{
eos_load_image(s, "VRAM/PH-LV/LV-000.422", 0, -1, value, 0);
}
else
{
fprintf(stderr, "Image buffer disabled\n");
}
return 0;
case REG_RAW_BUFF:
s->disp.raw_buff = (uint32_t) value;
if (value)
{
/* fixme: hardcoded strip offset */
eos_load_image(s, "VRAM/PH-LV/RAW-000.DNG", 33792, -1, value, 1);
}
else
{
fprintf<