Read about our upcoming Code of Conduct on this issue

Commit 6a3d280d authored by alex@thinkpad's avatar alex@thinkpad
Browse files

Merged qemu into 1300D

--HG--
branch : 1300D
......@@ -6,7 +6,7 @@ _CONFIGS_compile_name = _compile
_CONFIGS_clean_name = _clean
_CONFIGS_install_name = _install
_CONFIGS_to_filter_out =
_CONFIGS_to_filter_out = CONFIG_QEMU
_CONFIGS_to_compile = $(filter-out $(_CONFIGS_to_filter_out), $(ML_SETUP_CONFIGS_WITH_DIR))
......@@ -77,17 +77,16 @@ prepare_zip: FORCE
$(eval export INSTALL_FINISH)
$(eval export WIFI_SD)
$(call rm_dir, $(INSTALL_DIR)/)
$(warning removing $(INSTALL_DIR))
$(call rm_files, $(PLATFORM_PATH)/*/magiclantern.sym) # only check module dependencies on current camera model
$(warning removing $(PLATFORM_PATH)/*/magiclantern.sym)
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 ../$@ < \
../$(SRC_DIR)/zip.txt -r .\
../$(SRC_DIR)/zip.txt -r .
$(call rm_dir, $(INSTALL_DIR)/)
zip:: | prepare_zip
......@@ -95,7 +94,7 @@ zip:: magiclantern-$(VERSION).zip print_build_info
install_qemu:: | prepare_zip
install_qemu:: install
$(call build,MTOOLS,cd $(TOP_DIR)/../qemu/; ./mtools_copy_ml.sh $(INSTALL_DIR))
$(call build,MTOOLS,cd $(QEMU_PATH)/; ./mtools_copy_ml.sh $(INSTALL_DIR))
clean::
$(call rm_dir, zip)
......
......@@ -5,7 +5,7 @@ UNAME:=$(shell uname)
ifeq ($(UNAME), Darwin)
# Variable declaration for Mac OS X
UMOUNT=hdiutil unmount
UMOUNT=hdiutil eject
CF_CARD="/Volumes/EOS_DIGITAL"
STAT_CMD=stat -f "%N: %z bytes"
else
......@@ -178,6 +178,13 @@ AWK=awk
PYTHON=python2
RST2LATEX=rst2latex.py
#
# QEMU installation directory
# used for "make install_qemu"
#
QEMU_DIR ?= qemu-eos
QEMU_PATH=$(TOP_DIR)/../$(QEMU_DIR)
# Naming convention for Magic Lantern builds:
# General rules:
# - Always specify the camera and its firmware version number in the build name (e.g. 550d.fw109)
......
# parses Canon SRec records (stored with tag #0x200) of Canon DSLR updates
# version 0.6 (17Sep2011)
# version 0.7 (22Jan2018)
# by Arm.Indy, based on initial work by JollyRoger who identified the format
# See http://en.wikipedia.org/wiki/SREC_%28file_format%29
# Updated to decode lens firmware updates (*.lfu)
"""
record format is: type(1byte), len(1byte), address(depending on type), data (0 to 16 bytes), checksum(1 byte)
length is including fields [len, address if present, data]
......@@ -9,8 +10,10 @@ checksum is computed on same fields as length
record types are:
00, len, 0000, filename, checksum
01, len, address(2bytes), data, checksum
02, len, address(3bytes), data, checksum
03, len, address(4bytes), data, checksum
07, len, data, checksum
08, len, data, checksum
09, len, data, checksum
"""
......@@ -71,6 +74,7 @@ while currentAddress < size:
i+=1
fileName = m[ currentAddress: i ]
print '%s' % fileName,
print '%d.%d.%d' % (ord(m[0x26]), ord(m[0x27]), ord(m[0x28]))
fileLen = 0
......@@ -98,11 +102,15 @@ while currentAddress < size:
addrLen = 4
addr = getLongBE(m, currentAddress)
dataLen = rlen-addrLen-1
elif rtype == 2: #like S2
addrLen = 3
addr = getLongBE(m, currentAddress) >> 8
dataLen = rlen-addrLen-1
elif rtype == 1: #like S1
addrLen = 2
addr = getShortBE(m, currentAddress)
dataLen = rlen-addrLen-1
elif rtype == 7 or rtype == 9: #like S7 and S9
elif rtype == 7 or rtype == 8 or rtype == 9: #like S7 and S8 and S9
addrLen = 0
dataLen = rlen-1
endBlockFound = True
......@@ -124,15 +132,8 @@ while currentAddress < size:
fc.write('S'+'{0:1}'.format(rtype)+hexlify(m[offset+1:offset+rlen+2])+'\n')
currentAddress += addrLen
if addrLen == 4:
if options.verbose:
print "0x%06x: %02x %02x %08x" % ( offset, rtype, rlen, addr ),
elif addrLen == 2:
if options.verbose:
print "0x%06x: %02x %02x %04x" % ( offset, rtype, rlen, addr ),
else:
if options.verbose:
print "0x%06x: %02x %02x %s" % ( offset, rtype, rlen, addrLen*" " ),
if options.verbose:
print ("0x%06x: %02x %02x %8x") % ( offset, rtype, rlen, addr),
data = m[currentAddress: currentAddress+dataLen]
dataAscii = ''
for c in data:
......@@ -165,4 +166,4 @@ while currentAddress < size:
print "%d bytes saved, " % fileLen,
else:
print "%d bytes, " % fileLen,
print "0x%x-0x%x" % (startAddr, endAddr)
\ No newline at end of file
print "0x%x-0x%x" % (startAddr, endAddr)
This diff is collapsed.
.. If you see this (unformatted) text on Bitbucket, please try reloading the page.
How can I run Magic Lantern in QEMU?
====================================
This guide shows you how to emulate Magic Lantern (or plain Canon firmware) in QEMU.
Eager to get started? Scroll down to `Installation`_.
.. class:: align-center
|pic1| |pic2|
......@@ -14,25 +14,27 @@ Eager to get started? Scroll down to `Installation`_.
.. |pic2| image:: doc/img/qemu-M2-hello.jpg
:width: 32.3 %
.. contents::
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:
......@@ -60,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``
......@@ -93,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``
......@@ -139,6 +134,11 @@ without additional gymnastics (you will **not** have to merge ``qemu`` into your
/path/to/magic-lantern$ cd contrib/qemu
/path/to/magic-lantern/contrib/qemu$ ./install.sh
By default, QEMU will be installed in the ``qemu-eos`` directory,
near the ``magic-lantern`` one, at the same level - e.g. ``/path/to/qemu-eos``.
Please refer to `HACKING.rst <HACKING.rst#rst-header-how-is-this-code-organazized>`__
for details on the directory structure and how to change the installation directory.
|
3. Follow the instructions; you will have to supply your ROM files and compile QEMU:
......@@ -146,11 +146,11 @@ without additional gymnastics (you will **not** have to merge ``qemu`` into your
.. code:: shell
# replace camera model (60D) with yours
/path/to/qemu$ cp /path/to/sdcard/ML/LOGS/ROM*.BIN 60D/
/path/to/qemu$ cd qemu-2.5.0
/path/to/qemu/qemu-2.5.0$ ../configure_eos.sh
/path/to/qemu/qemu-2.5.0$ make -j2
/path/to/qemu/qemu-2.5.0$ cd ..
/path/to/qemu-eos$ cp /path/to/sdcard/ML/LOGS/ROM*.BIN 60D/
/path/to/qemu-eos$ cd qemu-2.5.0
/path/to/qemu-eos/qemu-2.5.0$ ../configure_eos.sh
/path/to/qemu-eos/qemu-2.5.0$ make -j2
/path/to/qemu-eos/qemu-2.5.0$ cd ..
Some recent camera models also use a serial flash. To list them, run this command:
......@@ -176,7 +176,7 @@ without additional gymnastics (you will **not** have to merge ``qemu`` into your
.. code:: shell
# all EOS models should run this without any trickery
/path/to/qemu$ ./run_canon_fw.sh 60D,firmware="boot=1"
/path/to/qemu-eos$ ./run_canon_fw.sh 60D,firmware="boot=1"
|
......@@ -185,13 +185,13 @@ without additional gymnastics (you will **not** have to merge ``qemu`` into your
.. code:: shell
# from the QEMU directory
/path/to/qemu$ make -C ../magic-lantern 60D_install_qemu
/path/to/qemu-eos$ make -C ../magic-lantern 60D_install_qemu
# some models will work only with this:
/path/to/qemu$ ./run_canon_fw.sh 60D,firmware="boot=1"
/path/to/qemu-eos$ ./run_canon_fw.sh 60D,firmware="boot=1"
# some models require running under GDB (they won't boot the GUI otherwise)
/path/to/qemu$ ./run_canon_fw.sh EOSM,firmware="boot=1" -s -S & arm-none-eabi-gdb -x EOSM/patches.gdb -ex quit
/path/to/qemu-eos$ ./run_canon_fw.sh EOSM,firmware="boot=1" -s -S & arm-none-eabi-gdb -x EOSM/patches.gdb -ex quit
|
......@@ -206,16 +206,16 @@ it is possible to install QEMU and ML development tools
Running Canon firmware
----------------------
From the QEMU directory, use the ``run_canon_fw.sh`` script and make sure
From the ``qemu-eos`` directory, use the ``run_canon_fw.sh`` script and make sure
the `boot flag <http://magiclantern.wikia.com/wiki/Bootflags>`_ is disabled:
.. code:: shell
# from the qemu directory
# from the qemu-eos directory
./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
......@@ -240,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
---------------------
......@@ -284,33 +285,33 @@ To install Magic Lantern to the virtual card, you may:
make 60D_clean
make 60D_install_qemu
They also work from the qemu directory:
They also work from the ``qemu-eos`` directory:
.. code:: shell
# from the qemu directory
# from the qemu-eos directory
make -C ../magic-lantern/platform/60D.111 clean
make -C ../magic-lantern/platform/60D.111 install_qemu
.. code:: shell
# from the qemu directory
# from the qemu-eos directory
make -C ../magic-lantern 5D3.113_clean
make -C ../magic-lantern 5D3.113_install_qemu
Please note: ``make install_qemu`` is a recent addition and may not be available in all branches.
In this case, you may either use the first method, or sync with the "unified" branch (``hg merge unified``),
or manually import changeset `27f4105 <https://bitbucket.org/hudson/magic-lantern/commits/27f4105cfa83>`_.
or manually import changeset `d5ad86f <https://bitbucket.org/hudson/magic-lantern/commits/d5ad86f0d284>`_.
Unfortunately, these rules won't work from ``Makefile.user``.
The included card images are already bootable for EOS firmwares (but not for PowerShots).
After you have copied Magic Lantern to the card, you may run it from the ``qemu`` directory
After you have copied Magic Lantern to the card, you may run it from the ``qemu-eos`` directory
(near the ``magic-lantern`` one, at the same level):
.. code:: shell
# from the qemu directory
# from the qemu-eos directory
./run_canon_fw.sh 60D,firmware="boot=1"
# or, if your camera requires patches.gdb:
......@@ -401,7 +402,7 @@ Running ML Lua scripts
.. code:: shell
# from the qemu directory
# from the qemu-eos directory
wget http://builds.magiclantern.fm/jenkins/job/lua_fix/431/artifact/platform/60D.111/magiclantern-lua_fix.2017Dec23.60D111.zip
unzip magiclantern-lua_fix.2017Dec23.60D111.zip -d ml-tmp
./mtools_copy_ml.sh ml-tmp
......@@ -444,19 +445,19 @@ The invocation looks like this (notice the ``113``):
And the directory layout should be like this::
/path/to/qemu/5D3/113/ROM0.BIN
/path/to/qemu/5D3/113/ROM1.BIN
/path/to/qemu/5D3/123/ROM0.BIN
/path/to/qemu/5D3/123/ROM1.BIN
/path/to/qemu/5D3/113/ROM0.BIN
/path/to/qemu/5D3/debugmsg.gdb # common to both versions
/path/to/qemu/5D3/patches.gdb # common to both versions
/path/to/qemu-eos/5D3/113/ROM0.BIN
/path/to/qemu-eos/5D3/113/ROM1.BIN
/path/to/qemu-eos/5D3/123/ROM0.BIN
/path/to/qemu-eos/5D3/123/ROM1.BIN
/path/to/qemu-eos/5D3/113/ROM0.BIN
/path/to/qemu-eos/5D3/debugmsg.gdb # common to both versions
/path/to/qemu-eos/5D3/patches.gdb # common to both versions
Compare this to a camera model where only one firmware version is supported::
/path/to/qemu/60D/ROM0.BIN
/path/to/qemu/60D/ROM1.BIN
/path/to/qemu/5D3/patches.gdb
/path/to/qemu-eos/60D/ROM0.BIN
/path/to/qemu-eos/60D/ROM1.BIN
/path/to/qemu-eos/5D3/patches.gdb
You may also store ``debugmsg.gdb`` and ``patches.gdb`` under the firmware version subdirectory if you prefer, but other QEMU-related scripts won't pick them up.
......@@ -479,6 +480,20 @@ Note: you need to copy the raw contents of the entire card, not just one partiti
dd if=/dev/mmcblk0 of=sd.img # not mmcblk0p1
Tip: to save disk space, format the SD card first, copy the desired files,
then create the image as `qcow2 <https://rwmj.wordpress.com/2010/05/18/tip-compress-raw-disk-images-using-qcow2/>`_:
.. code:: shell
qemu-img convert -f raw -O qcow2 /dev/mmcblk0 sd.qcow2
then update ``run_canon_fw.sh`` to use the new image::
-drive if=sd,format=qcow2,file=sd.qcow2
That way, a 64GB card with Magic Lantern installed, after formatting in camera
with the option to keep ML on the card, will only take up about 15MB as a ``qcow2`` image.
Running from the physical SD/CF card
````````````````````````````````````
You may also start QEMU from the same card you use in the physical camera —
......@@ -712,7 +727,7 @@ This is tricky and not automated. You need to be careful with the following glob
.. code:: shell
QEMU_MONITOR=qemu.monitor$QEMU_JOB_ID
GDB_PORT=$((1234+$QEMU_JOB_ID))
GDB_PORT=$((1234+QEMU_JOB_ID))
./run_canon_fw.sh EOSM2,firmware="boot=0" -S -gdb tcp::$GDB_PORT &
arm-none-eabi-gdb -ex "set \$TCP_PORT=$GDB_PORT" -x EOSM2/patches.gdb -ex quit &
......@@ -825,10 +840,11 @@ It works for modules as well:
cd modules/lua
# add some qprintf call in lua_init for testing
make clean; make # regular build
make clean; make CONFIG_QEMU=y # debug build for QEMU
# todo: make install_qemu doesn't work here yet
make clean; make # regular build
make clean; make CONFIG_QEMU=y # debug build for QEMU
make clean; make install_qemu # build and install a regular build to the QEMU SD/CF image
make clean; make install_qemu CONFIG_QEMU=y # build and install a QEMU build to the QEMU SD/CF image
Tracing guest events (execution, I/O, debug messages, RAM, function calls...)
`````````````````````````````````````````````````````````````````````````````
......@@ -874,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 :)
......@@ -893,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:
......@@ -995,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.
......@@ -1063,9 +1073,23 @@ Instrumentation
`TODO (see QEMU forum thread) <http://www.magiclantern.fm/forum/index.php?topic=2864.msg184125#msg184125>`_
The instrumentation framework provides the following features:
Hacking
-------
- log all debug messages from Canon: ``-d debugmsg``
- log all memory accesses: ``-d rom/ram/romr/ramw/etc``
- 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``
- identify memory blocks copied from ROM to RAM: ``-d romcpy``
- check for memory errors (a la valgrind): ``-d memchk``
Debugging symbols from ML can be made available to instrumentation routines from environment variables (see ``export_ml_syms.sh``).
The address of DebugMsg is exported by ``run_canon_fw.sh`` (extracted from the GDB script, where it's commented out for speed reasons).
Development and reverse engineering guide
-----------------------------------------
For the following topics, please see `HACKING.rst <HACKING.rst>`_:
......@@ -1089,15 +1113,19 @@ History
:2015: `100D emulation, serial flash and GDB scripts from nkls <http://www.magiclantern.fm/forum/index.php?topic=2864.msg153064#msg153064>`_
:2016: `More EOS models boot Canon GUI (no menus yet) <http://www.magiclantern.fm/forum/index.php?topic=2864.msg168603#msg168603>`_
:2016: `Low-level button codes and GUI modes understood <http://www.magiclantern.fm/forum/index.php?topic=2864.msg169517#msg169517>`_
:2016: `Users start wondering why the heck are we spending most of our time on this <http://www.magiclantern.fm/forum/index.php?topic=2864.msg169970#msg169970>`_
:2016: `Users start wondering why the heck are we wasting our time on this <http://www.magiclantern.fm/forum/index.php?topic=2864.msg169970#msg169970>`_
:2016: `Leegong from Nikon Hacker starts documenting MPU messages <http://www.magiclantern.fm/forum/index.php?topic=17596.msg171304#msg171304>`_
:2017: `500D menu navigation! (Greg) <http://www.magiclantern.fm/forum/index.php?topic=2864.msg179867#msg179867>`_
:2017: `nkls solves an important issue that was very hard to track down! <http://www.magiclantern.fm/forum/index.php?topic=2864.msg183311#msg183311>`_
:2017: `Menu navigation works on most D4 and 5 models <http://www.magiclantern.fm/forum/index.php?topic=2864.msg181786#msg181786>`_
:2017: `Menu navigation works on most DIGIC 4 and 5 models <http://www.magiclantern.fm/forum/index.php?topic=2864.msg181786#msg181786>`_
:2017: Working on `Mac (dfort) <http://www.magiclantern.fm/forum/index.php?topic=2864.msg184981#msg184981>`_
and `Windows 10 / Linux subsystem (g3gg0) <http://www.magiclantern.fm/forum/index.php?topic=20214.0>`_
:2017: `EOS M2 porting walkthrough <http://www.magiclantern.fm/forum/index.php?topic=15895.msg185103#msg185103>`_
:2017: `Automated tests for ML builds in QEMU <http://www.magiclantern.fm/forum/index.php?topic=20560>`_
: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