Commit e4db03b9 authored by alex@thinkpad's avatar alex@thinkpad
Browse files

QEMU: attempt to get deterministic execution on CF models when using -icount

operations are slowed down to avoid timing variations
default behavior (without -icount) is not affected
on main firmware, the call/return trace test is now deterministic on all models!
fixme: CF emulation in PIO mode is still non-deterministic

branch : qemu
parent 9f0813a19d4f
......@@ -31,7 +31,7 @@ What works:
- 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)
- Deterministic execution with the ``-icount`` option (SD models only)
- Deterministic execution with the ``-icount`` option (except CF PIO)
- Cache hacks are emulated to some extent (but "uninstalling" them does not work)
- EDMAC memcpy, including geometry parameters (matches the hardware closely, but not perfectly)
- Debugging with GDB:
......@@ -4028,7 +4028,7 @@ unsigned int eos_handle_sddma ( unsigned int parm, EOSState *s, unsigned int add
static int cfdma_read_data(EOSState *s, CFState *cf)
CFD_DPRINTF("Reading %d of %d bytes to %x\n", cf->dma_count - cf->dma_read, cf->dma_count, cf->dma_addr + cf->dma_read);
assert(cf->dma_count % 4 == 0);
/* for some reason, reading many values in a loop sometimes fails */
......@@ -4044,13 +4044,16 @@ static int cfdma_read_data(EOSState *s, CFState *cf)
cf->dma_read += 4;
if (cf->dma_read == cf->dma_count)
if (cf->dma_read == cf->dma_count && cf->dma_wait <= 0)
/* finished? */
assert(cf->dma_wait == 0 || !use_icount);
return 0;
return 1;
......@@ -4071,9 +4074,12 @@ static int cfdma_write_data(EOSState *s, CFState *cf)
cf->dma_written += 4;
if (cf->dma_written == cf->dma_count)
if (cf->dma_written == cf->dma_count && cf->dma_wait <= 0)
/* finished? */
assert(cf->dma_wait == 0 || !use_icount);
return 0;
......@@ -4175,6 +4181,13 @@ unsigned int eos_handle_cfdma ( unsigned int parm, EOSState *s, unsigned int add
if(type & MODE_WRITE)
s->cf.dma_count = value;
/* each iteration of cfdma_read_data / cfdma_write_data usually processes 1 block (512 bytes)
* however, a few iterations will just wait, nondeterministically, for unclear reasons
* to get deterministic execution with -icount, required for tests, we'll slow down the execution
* by forcing some more iterations than actually needed, so total times would be deterministic
* note: under heavy I/O load (e.g. parallel tests) we need to slow down a lot more! */
s->cf.dma_wait = (use_icount) ? value / 512 * 2 + 10 : 0;
......@@ -120,6 +120,7 @@ typedef struct
uint32_t dma_count;
uint32_t dma_read;
uint32_t dma_written;
int dma_wait;
} CFState;
struct palette_entry
aeff2f3f8bc5a332425911eda98d36e0 calls-main.idc
045d7aba80ca76a4bb0360e737f911a2 calls-main-basic.idc
cbf9273cb40972e74f6684db4aeaf7fe calls-main.log
1f9d419b93479dcbe2c848e7f806fdd2 calls-main.idc
591ba7c4eb756a430e70c8c3f5dd28bd calls-main-basic.log
014b72b881c87fb8c36a9b4730add51e calls-main-basic.idc
03065e3aa57faeb902fd4d407e0ffd2f calls-main.idc
558d9ea753bf01a05978d9c01f4c17f9 calls-main-basic.idc
2bb54eb7ac769d367ac763b8be00b6f5 calls-main.log
b20ce229e475768cfbdaa66342b6e63f calls-main.idc
d22eca8d613c32167be59a6871caf217 calls-main-basic.log
9b42402b69b31bb44dab792287a44413 calls-main-basic.idc
cc6bd82c89184e8fe0d2e95385d33302 calls-main.log
76c8e70a73a63665f878939ed22c6f56 calls-main.idc
71971c9c170612335071604ecdfdef5b calls-main-basic.log
36c85e1244cec6d339c8c6af4c43a584 calls-main-basic.idc
30e57238a758584cfa013944290a07d7 calls-main.log
69f490afca0e60c1da122f1423408b54 calls-main.idc
1e3d5fb6c8ea1a2d401c068228e7e22f calls-main-basic.log
2545ba70caf2aac10d81201d109e22fc calls-main-basic.idc
e98937a8f438d635e95327787b73f076 calls-main.log
d624595383d8bcc78eedace18d7a317e calls-main.idc
da4ab15d96aaa11e0111fefb10730397 calls-main-basic.log
479a037f4ff252844830fcfdd98bffa0 calls-main-basic.idc
84fee10818e1c854342c1d4e376312f0 calls-main.log
e316dc83d4fed58331ad74413a5d8217 calls-main.idc
851264dfa8332f65fdd79d6506c0aa6b calls-main-basic.log
529a0a1c364621436779a5ea56449490 calls-main-basic.idc
7db6e8d87ac4b575a93f096103b8fdc3 calls-main.log
49fd5140742638e34bb7802ccc64bb30 calls-main.idc
92230e2d47595165cb2089a207c38d99 calls-main-basic.log
19414536eb149d53a182b6adc8a3d7bd calls-main-basic.idc
39c6975c0496ccdf4b44e40b003d6ce0 calls-main.idc
8d5942b616a7b1c1170d9827d11af3a5 calls-main-basic.idc
37eb3833e89d0bc8868e597eb277f672 calls-main.log
2a04120b8d77739341874a6712f6e5c0 calls-main.idc
513fbb75130ed8e8b838cf006ccf6206 calls-main-basic.log
f3525d08b861debec8c334f15f4268fb calls-main-basic.idc
......@@ -628,7 +628,6 @@ function test_calls_main {
> tests/$CAM/$TEST-basic.log
# also copy the IDC file for checking its MD5
# this works on CF models too, even if some nondeterminism is present
# the IDC needs trimming, too, as it doesn't always stop at the same line
cat $CAM.idc | sed -n "1,/MakeFunction($last_call/ p" > tests/$CAM/$TEST.idc
cat $CAM.idc | tail -n 2 >> tests/$CAM/$TEST.idc
......@@ -695,8 +694,8 @@ done; cleanup
# which loads FROMUTILITY if autoexec.bin is not present on a bootable card.
# There are no timed interrupts here, so the process should be deterministic.
# On SD models, this process is deterministic without any trickery.
# For some reason, the CF emulation is not deterministic even with -icount,
# so we'll only check the IDC for these models (todo: figure out why).
# On CF models, emulation is not deterministic even with -icount (fixme),
# so we'll only check the IDC for these models.
# The results are assumed to be correct, but they were not thoroughly checked.
# Feel free to report bugs, corner cases and so on.
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment