qemu: add 'check' and 'check-only' targets

Adds an Expect script to launch QEMU, run xtest and return a pass/fail
status. This makes it even easier to launch non-regression tests and
possibly integrate into a CI loop.

The script may be invoked through 'make check' or 'make check-only'.
The former considers dependencies, while the latter just runs the script.

The output of serial ports 0 and 1 are saved to serial0.log and
serial1.log, respectively.

Expect may be installed with 'sudo apt-get install expect' on Debian/
Ubuntu distributions.

Sample output:

 $ make -j9 check
 <snip>
 expect qemu-check.exp -- \
         --bios /home/jerome/work/optee_repo/out/bios-qemu/bios.bin
 Starting QEMU... done, guest is booted.
 Loading OP-TEE driver and tee-supplicant... done.
 Running: xtest...
 ##########################################<snip>
 Status: PASS (404 test cases)

Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Reviewed-by: Pascal Brand <pascal.brand@linaro.org>
diff --git a/.gitignore b/.gitignore
index 89ff7b0..33205cd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
 Makefile
 *.swp
+/serial0.log
+/serial1.log
diff --git a/qemu-check.exp b/qemu-check.exp
new file mode 100644
index 0000000..eb78650
--- /dev/null
+++ b/qemu-check.exp
@@ -0,0 +1,86 @@
+#!/usr/bin/expect -f
+#
+# This scripts starts QEMU, loads and boots Linux/OP-TEE, then runs
+# xtest in the guest. The return code is 0 for success, >0 for error.
+#
+# Options:
+#   --bios    Path to the binary to be run [../out/bios-qemu/bios.bin]
+#   -q        Suppress output to stdout (quiet)
+
+set bios "../out/bios-qemu/bios.bin"
+set cmd "xtest"
+set quiet 0
+
+# The time required to run some tests (e.g., key generation tests [4007.*])
+# can be significant and vary widely -- typically, from about one minute to
+# several minutes depending on the host machine.
+# So, set an infinite timeout.
+set timeout -1
+
+# Parse command line
+set myargs $argv
+while {[llength $myargs]} {
+	set myargs [lassign $myargs arg]
+	switch -exact -- $arg {
+		"--bios"	{set myargs [lassign $myargs ::bios]}
+		"-q"		{set ::quiet 1}
+	}
+}
+
+proc info arg {
+	if {$::quiet==1} { return }
+	puts -nonewline $arg
+	flush stdout
+}
+
+# Disable echoing of guest output
+log_user 0
+# Save guest console output to a file
+log_file -a -noappend "serial0.log"
+info "Starting QEMU..."
+spawn ../qemu/arm-softmmu/qemu-system-arm -machine virt -cpu cortex-a15 -m 1057 -serial stdio -serial file:serial1.log -bios $bios
+expect "*Please press Enter to activate this console. "
+send -- "\r"
+expect "root@Vexpress:/ "
+info " done, guest is booted.\nLoading OP-TEE driver and tee-supplicant..."
+send -- "modprobe optee_armtz\r"
+expect "root@Vexpress:/ "
+sleep 1
+send -- "tee-supplicant&\r"
+expect "root@Vexpress:/ "
+sleep 1
+info " done.\nRunning: $cmd...\n"
+send -- "$cmd\r"
+expect {
+	# Exit with error status as soon as a test fails
+	-re {  XTEST_TEE_([^ ]+) FAIL} {
+		info "$expect_out(1,string) FAIL"
+		exit 1
+	}
+	# Crude progress indicator: print one # when each test [sub]case starts
+	-re {([\*o]) XTEST_TEE_([^ ]+) } {
+		set casenum $expect_out(2,string)
+		if {$expect_out(1,string) == "o"} {
+			if {$star == 1} {
+				# Do not count first subcase ('o') since start
+				# of test ('*') was counted already
+				set star 0
+				exp_continue
+			}
+		} else {
+			set star 1
+		}
+		info "#"
+		incr ncases
+		exp_continue
+	}
+	# Exit when result separator is seen
+	"+-----------------------------------------------------\r\r" {}
+	timeout {
+		info "!!! Timeout\n"
+		info "TIMEOUT - test case too long or hung? ($casenum)\n"
+		exit 2
+	}
+}
+info "\nStatus: PASS ($ncases test cases)\n"
+
diff --git a/qemu.mk b/qemu.mk
index 800f398..1b1930e 100644
--- a/qemu.mk
+++ b/qemu.mk
@@ -39,7 +39,8 @@
 ################################################################################
 all: bios-qemu linux optee-os optee-client optee-linuxdriver qemu soc-term xtest
 all-clean: bios-qemu-clean busybox-clean linux-clean optee-os-clean \
-	optee-client-clean optee-linuxdriver-clean qemu-clean soc-term-clean
+	optee-client-clean optee-linuxdriver-clean qemu-clean soc-term-clean \
+	check-clean
 
 -include toolchain.mk
 
@@ -265,3 +266,16 @@
 		-m 1057 \
 		-bios $(ROOT)/out/bios-qemu/bios.bin
 
+
+ifneq ($(filter check,$(MAKECMDGOALS)),)
+CHECK_DEPS := all
+endif
+
+check: $(CHECK_DEPS)
+	expect qemu-check.exp -- \
+		--bios $(ROOT)/out/bios-qemu/bios.bin
+
+check-only: check
+
+check-clean:
+	rm -f serial0.log serial1.log