1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
| set -uo pipefail
cd "$(dirname "$0")/.."
: "${CARGO_TARGET_DIR:=$PWD/target}"
export CARGO_TARGET_DIR
TRIPLE=aarch64-unknown-none-softfloat
LOGDIR="${LOGDIR:-$CARGO_TARGET_DIR/aarch64-check}"
mkdir -p "$LOGDIR"
FAIL=0
pass() { echo "PASS $1"; }
fail() { echo "FAIL $1"; FAIL=1; }
expect() { if grep -qE "$3" "$1"; then pass "$2"; else fail "$2 (no /$3/ in $1)"; fi
}
cargo build --bin rustbelt-aarch64 --features aarch64-fault --target "$TRIPLE" 2>"$LOGDIR/build-fault.log" \
|| { echo "FAIL build (fault)"; cat "$LOGDIR/build-fault.log"; exit 1; }
cp "$CARGO_TARGET_DIR/$TRIPLE/debug/rustbelt-aarch64" "$LOGDIR/rustbelt-aarch64-fault.elf"
cargo build --bin rustbelt-aarch64 --features aarch64 --target "$TRIPLE" 2>"$LOGDIR/build.log" \
|| { echo "FAIL build"; cat "$LOGDIR/build.log"; exit 1; }
DISK="$LOGDIR/blank.img"
[ -f "$DISK" ] || truncate -s 1M "$DISK"
RB_TIMEOUT=30 scripts/run-aarch64.sh --no-build -- \
-device virtio-rng-device \
-drive if=none,id=d0,format=raw,file="$DISK" -device virtio-blk-device,drive=d0 \
>"$LOGDIR/el1.log" 2>&1
rc=$?
L="$LOGDIR/el1.log"
[ $rc = 0 ] && pass "EL1 boot: QEMU exit status 0" || fail "EL1 boot: QEMU exit status $rc (want 0)"
expect "$L" "banner" '^Rustbelt 0\.22\.0 \(stage 22: arm64 bring-up\)'
expect "$L" "at EL1" 'entered at EL1, running at EL1'
expect "$L" "exception vectors" 'exception vectors installed'
expect "$L" "MMU on, higher half reads back" '\[mmu\] on \(SCTLR_EL1\.M = 1\).*reads 0x5ca1ab1e'
expect "$L" "UART through the higher half" 'UART at 0xffffff8009000000'
expect "$L" "heap" 'sums to 500500'
expect "$L" "DTB: GICv2 found" '\[dtb\] .*GICv2, distributor at 0x8000000'
expect "$L" "DTB: timer INTID 27" 'virtual timer = PPI 11 \(INTID 27\)'
expect "$L" "virtio: rng listed" 'device ID 4 \(entropy'
expect "$L" "virtio: block listed" 'device ID 2 \(block'
expect "$L" "timer ticks 1..5" '\[timer\] tick 5'
expect "$L" "100 ticks timed" '100 ticks took [0-9]+ ms'
expect "$L" "clean exit line" 'leaving QEMU through semihosting SYS_EXIT, status 0'
RB_TIMEOUT=30 scripts/run-aarch64.sh --no-build --el2 >"$LOGDIR/el2.log" 2>&1
rc=$?
L="$LOGDIR/el2.log"
[ $rc = 0 ] && pass "EL2 boot: QEMU exit status 0" || fail "EL2 boot: QEMU exit status $rc (want 0)"
expect "$L" "EL2 -> EL1 drop" 'entered at EL2, running at EL1'
expect "$L" "EL2 boot ticks" '\[timer\] tick 5'
RB_TIMEOUT=30 RB_KERNEL="$LOGDIR/rustbelt-aarch64-fault.elf" scripts/run-aarch64.sh --no-build >"$LOGDIR/fault.log" 2>&1
rc=$?
L="$LOGDIR/fault.log"
[ $rc = 3 ] && pass "fault: QEMU exit status 3" || fail "fault: QEMU exit status $rc (want 3)"
expect "$L" "fault: ESR data abort" 'ESR_EL1=0x96[0-9a-f]{6} \(EC 0x25: data abort'
expect "$L" "fault: ELR/FAR" 'ELR_EL1=0x402[0-9a-f]+ FAR_EL1=0x1000000000'
grep -h '^\[run-aarch64\] qemu pid' "$LOGDIR"/el1.log "$LOGDIR"/el2.log "$LOGDIR"/fault.log
if [ $FAIL = 0 ]; then echo "aarch64-check: ALL PASS (logs in $LOGDIR)"; else echo "aarch64-check: FAILED (logs in $LOGDIR)"; fi
exit $FAIL
|