diff --git a/build.lua b/build.lua index fd8582fd9..cc550cb9e 100644 --- a/build.lua +++ b/build.lua @@ -13,11 +13,18 @@ vars.plats = { "pc86", "rpi", } +vars.plats_with_tests = { + "qemuppc", +} local plat_packages = {} +local test_packages = {} for _, p in ipairs(vars.plats) do plat_packages[#plat_packages+1] = "plat/"..p.."+pkg" end +for _, p in ipairs(vars.plats_with_tests) do + test_packages[#test_packages+1] = "plat/"..p.."/tests+tests" +end installable { name = "ack", @@ -35,6 +42,9 @@ installable { "util/opt+pkg", "examples+pkg", plat_packages + }, + deps = { + test_packages } } diff --git a/plat/qemuppc/build-pkg.lua b/plat/qemuppc/build-pkg.lua index e30e83efc..0478bbd4d 100644 --- a/plat/qemuppc/build-pkg.lua +++ b/plat/qemuppc/build-pkg.lua @@ -18,6 +18,7 @@ installable { "+tools", "+libs", "./include+pkg", + "util/amisc+aslod-pkg", ["$(PLATIND)/qemuppc/boot.o"] = "+boot", ["$(PLATIND)/qemuppc/libsys.a"] = "./libsys+lib", } diff --git a/plat/qemuppc/tests/_dummy.c b/plat/qemuppc/tests/_dummy.c new file mode 100644 index 000000000..4a56d8238 --- /dev/null +++ b/plat/qemuppc/tests/_dummy.c @@ -0,0 +1,8 @@ +#include "test.h" + +/* Bypasses the CRT, so there's no stdio or BSS initialisation. */ +void _m_a_i_n(void) +{ + ASSERT(0 == 0); + finished(); +} \ No newline at end of file diff --git a/plat/qemuppc/tests/build.lua b/plat/qemuppc/tests/build.lua new file mode 100644 index 000000000..ec4cbf610 --- /dev/null +++ b/plat/qemuppc/tests/build.lua @@ -0,0 +1,44 @@ +include("plat/build.lua") + +local qemu = "qemu-system-ppc" +local tests = {} + +if os.execute("which "..qemu.." > /dev/null") ~= 0 then + print("warning: skipping tests which require ", qemu) +else + local testcases = filenamesof("./*.c", "./*.s", "./*.e") + + for _, f in ipairs(testcases) do + local fs = replace(basename(f), "%..$", "") + + local bin = ackprogram { + name = fs.."_bin", + srcs = { f }, + deps = { "plat/qemuppc/tests/lib+lib" }, + vars = { + plat = "qemuppc", + lang = "e", + } + } + + tests[#tests+1] = normalrule { + name = fs, + outleaves = { "stamp" }, + ins = { + bin, + "./testdriver.sh" + }, + commands = { + "%{ins[2]} "..qemu.." %{ins[1]} 5", + "touch %{outs}" + } + } + end +end + +normalrule { + name = "tests", + outleaves = { "stamp" }, + ins = tests, + commands = { "touch %{outs}" } +} \ No newline at end of file diff --git a/plat/qemuppc/tests/div.c b/plat/qemuppc/tests/div.c new file mode 100644 index 000000000..dfa96ae16 --- /dev/null +++ b/plat/qemuppc/tests/div.c @@ -0,0 +1,17 @@ +#include "test.h" + +/* Constants in globals to defeat constant folding. */ +int three = 3; +int two = 2; +int one = 1; +int zero = 0; + +/* Bypasses the CRT, so there's no stdio or BSS initialisation. */ +void _m_a_i_n(void) +{ + ASSERT((three/two) == 1); + ASSERT((-three/two) == -1); + ASSERT((-three/-two) == 1); + ASSERT((three/-two) == -1); + finished(); +} \ No newline at end of file diff --git a/plat/qemuppc/tests/lib/build.lua b/plat/qemuppc/tests/lib/build.lua new file mode 100644 index 000000000..cb6b5cbea --- /dev/null +++ b/plat/qemuppc/tests/lib/build.lua @@ -0,0 +1,8 @@ +include("plat/build.lua") + +acklibrary { + name = "lib", + srcs = { "./test.c" }, + hdrs = { "./test.h" }, + vars = { plat = "qemuppc" } +} diff --git a/plat/qemuppc/tests/lib/test.c b/plat/qemuppc/tests/lib/test.c new file mode 100644 index 000000000..9da7e8101 --- /dev/null +++ b/plat/qemuppc/tests/lib/test.c @@ -0,0 +1,29 @@ +#include "test.h" + +void finished(void) +{ + static const char s[] = "@@FINISHED\n"; + write(1, s, sizeof(s)); +} + +void writehex(uint32_t code) +{ + char buf[8]; + char* p = &buf[8]; + + do + { + *--p = "0123456789abcdef"[code & 0xf]; + code >>= 4; + } + while (code > 0); + + write(1, p, buf+8-p); +} + +void fail(uint32_t code) +{ + write(1, "@@FAIL ", 7); + writehex(code); + write(1, "\n", 1); +} diff --git a/plat/qemuppc/tests/lib/test.h b/plat/qemuppc/tests/lib/test.h new file mode 100644 index 000000000..96537a2cb --- /dev/null +++ b/plat/qemuppc/tests/lib/test.h @@ -0,0 +1,14 @@ +#ifndef TEST_H +#define TEST_H + +#include +#include + +extern void finished(void); +extern void writehex(uint32_t code); +extern void fail(uint32_t code); + +#define ASSERT(condition) \ + if (!(condition)) fail(__LINE__) + +#endif diff --git a/plat/qemuppc/tests/testdriver.sh b/plat/qemuppc/tests/testdriver.sh new file mode 100755 index 000000000..84abdab1a --- /dev/null +++ b/plat/qemuppc/tests/testdriver.sh @@ -0,0 +1,27 @@ +#!/bin/sh +qemu=$1 +img=$2 +timeout=$3 + +pipe=/tmp/testdriver.$$.pipe +mknod $pipe p +trap "rm $pipe" EXIT + +timeout $timeout $qemu -nographic -kernel $img >$pipe 2>&1 & +pid=$! + +status=0 +while read line < $pipe; do + case "$line" in + *@@FAIL*) + echo $line + status=1 + ;; + + *@@FINISHED*) + kill $pid + ;; + esac +done + +exit $status