#!/usr/bin/env bash # Build + link + run CoreMark under MAME, and fail unless CoreMark's own # report says the results are right. # # Usage: # bash tests/coremark/runCoreMark.sh # ITERATIONS from build.sh # ITERATIONS=10 bash tests/coremark/runCoreMark.sh # bash tests/coremark/runCoreMark.sh --layer2 # # The gate reads CoreMark's printed report (core_portme.c captures the # console in bank 2 and runMultiSeg.sh prints it as MAME-TEXT lines) and # requires: # - "Correct operation validated": CoreMark compared its list, matrix and # state CRCs with the known values for these seeds, and the run lasted # at least 10 s by core_portme.c's clock (the harness's emulated # milliseconds); # - the seed, list, matrix, state and final CRCs below, so a failure names # the wrong one. crcfinal chains every iteration's results. # The done sentinel alone only proved that CoreMark returned: a compiler # whose CoreMark printed list 0x9865 / matrix 0xa7f7 / state 0xe10b passed. set -eu SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" source "$SCRIPT_DIR/../../scripts/common.sh" CM_OBJ="$SCRIPT_DIR/build" RT="$PROJECT_ROOT/runtime" # CoreMark's known values for the 2K performance run (seeds 0, 0, 0x66). WANT_SEEDCRC=0xe9f5 WANT_CRCLIST=0xe714 WANT_CRCMATRIX=0x1fd7 WANT_CRCSTATE=0x8e3a # crcfinal by iteration count, from the vendored sources built for the host # (posix port, `coremark.exe 0x0 0x0 0x66 N`). crcFinalFor() { case "$1" in 1) echo 0xe714 ;; 2) echo 0x72be ;; 3) echo 0x2e87 ;; 4) echo 0x9f95 ;; 5) echo 0xf24c ;; 6) echo 0x9db0 ;; 7) echo 0x3413 ;; 8) echo 0xccd1 ;; 9) echo 0x7de8 ;; 10) echo 0xfcaf ;; 20) echo 0x4983 ;; 30) echo 0xf8b3 ;; 50) echo 0x0158 ;; 100) echo 0x988c ;; *) echo "" ;; esac } cd "$SCRIPT_DIR" rm -rf "$CM_OBJ" bash "$SCRIPT_DIR/build.sh" "$@" # Link. CoreMark plus the runtime it pulls in (printf, soft-float) is more # than the ~44 KB bank 0 has below the IO window, so it links multi-segment # like the Lua test: text packs into 48 KB chunks from bank 0, the rest at # bank 4+ (runMultiSeg.sh places each segment from the manifest). "$PROJECT_ROOT/tools/link816" -o coreMark.bin --text-base 0x1000 \ --segment-cap 0xB000 \ --segment-bank-base 0x040000 \ --manifest coreMark.manifest.json \ "$RT/crt0.o" \ "$RT/libc.o" "$RT/libgcc.o" "$RT/softFloat.o" "$RT/softDouble.o" \ "$RT/math.o" "$RT/strtol.o" "$RT/snprintf.o" \ "$RT/qsort.o" "$RT/timeExt.o" "$RT/extras.o" \ $CM_OBJ/*.o ls -la coreMark*.bin echo "" # The run ends on portable_fini's 0xC0DE sentinel at $02:5000 ($BEEF there # means CoreMark started but never finished). The tick and text addresses # are core_portme.c's CM_TICK_ADDR and CM_OUT_ADDR. 900 emulated seconds # only caps a hang; the wall time follows CoreMark's own run time. runOk=1 OUT=$(MAME_CHECK_FRAME=54000 MAME_SECS=905 MAME_TIMEOUT=900 MAME_RAMSIZE=4M \ MAME_DONE_ADDR=0x025000 MAME_DONE_VAL=0xC0DE \ MAME_TICK_ADDR=0x025010 MAME_TEXT_ADDR=0x026000 \ bash "$PROJECT_ROOT/scripts/runMultiSeg.sh" \ "$SCRIPT_DIR/coreMark.manifest.json" \ --check 0x025000=c0de) || runOk=0 echo "$OUT" [ $runOk -eq 1 ] || die "CoreMark: no 0xC0DE done sentinel (hang or crash)" report=$(sed -n 's/^MAME-TEXT //p' <<< "$OUT") # One "name : value" field of the report, e.g. field '[0]crclist'. field() { awk -F' *: ' -v k="$1" '$1 == k && !seen { print $2; seen = 1 }' <<< "$report" } bad=0 expect() { local got got=$(field "$1") if [ "$got" != "$2" ]; then warn "CoreMark: $1 is '${got:-missing}', expected $2" bad=1 fi } iterations=$(field "Iterations") wantFinal=$(crcFinalFor "$iterations") expect "seedcrc" "$WANT_SEEDCRC" expect "[0]crclist" "$WANT_CRCLIST" expect "[0]crcmatrix" "$WANT_CRCMATRIX" expect "[0]crcstate" "$WANT_CRCSTATE" if [ -n "$wantFinal" ]; then expect "[0]crcfinal" "$wantFinal" else warn "CoreMark: no known crcfinal for ${iterations:-?} iterations; not checked" fi if ! grep -q '^Correct operation validated' <<< "$report"; then warn "CoreMark did not report \"Correct operation validated\" (its ERROR lines are above)" bad=1 fi [ $bad -eq 0 ] || die "CoreMark: results not validated (warnings above)" log "CoreMark OK: $iterations iterations, CRCs match, $(field 'Total time (secs)') s, $(field 'Iterations/Sec') iterations/s"