Add test cases for triggering program faults - Adds a set of test cases that do things like illegal instructions, load/store faults, misaligned execution, etc. - Minor changes to build rules to allow tests to "fail successfully", and to allow specifying which sims to run on, instead of unconditionally running on all sims. Change-Id: Ie0ae0bf20ed28a610c969e7d8bbb482ce5f69224
diff --git a/build_tools/bazel/kelvin.bzl b/build_tools/bazel/kelvin.bzl index c29614a..484afc4 100644 --- a/build_tools/bazel/kelvin.bzl +++ b/build_tools/bazel/kelvin.bzl
@@ -208,6 +208,9 @@ hw_test_tags = [], iss_test_size = "small", iss_test_tags = [], + expect_success = True, + hw = True, + iss = True, **kwargs): """A sh_test wrapper for kelvin binaries @@ -230,42 +233,46 @@ **kwargs ) + tests = [] + iss_test = "{}_iss".format(name) - native.sh_test( - name = iss_test, - size = iss_test_size, - srcs = [ - "@kelvin_sw//build_tools:test_runner.sh", - ], - args = [ - "$(location %s.elf)" % kelvin_elf, - ], - data = [ - "{}.elf".format(kelvin_elf), - ], - tags = ["iss"] + iss_test_tags + tags, - ) + if iss: + native.sh_test( + name = iss_test, + size = iss_test_size, + srcs = [ + "@kelvin_sw//build_tools:test_runner.sh", + ], + args = [ + "$(location %s.elf)" % kelvin_elf, + ], + data = [ + "{}.elf".format(kelvin_elf), + ], + tags = ["iss"] + iss_test_tags + tags, + ) + tests.append(iss_test) hw_test = "{}_hw".format(name) - native.sh_test( - name = hw_test, - size = hw_test_size, - srcs = ["@kelvin_sw//build_tools:core_sim_test_runner.sh"], - args = [ - "$(location %s.bin)" % kelvin_elf, - ], - data = [ - "{}.bin".format(kelvin_elf), - ], - tags = ["systemc"] + hw_test_tags + tags, - ) + if hw: + native.sh_test( + name = hw_test, + size = hw_test_size, + srcs = ["@kelvin_sw//build_tools:core_sim_test_runner.sh"], + args = [ + "$(location %s.bin)" % kelvin_elf, + str(expect_success), + ], + data = [ + "{}.bin".format(kelvin_elf), + ], + tags = ["systemc"] + hw_test_tags + tags, + ) + tests.append(hw_test) native.test_suite( name = name, - tests = [ - iss_test, - hw_test, - ], + tests = tests, tags = tags )
diff --git a/build_tools/core_sim_test_runner.sh b/build_tools/core_sim_test_runner.sh index eb3ad5a..2d5b029 100755 --- a/build_tools/core_sim_test_runner.sh +++ b/build_tools/core_sim_test_runner.sh
@@ -16,7 +16,7 @@ # Test runner for SystemC simulator. Note the input should be the .bin file. function print_usage { - echo "Usage: core_sim_test_runner.sh <bin location> [extra flags]" + echo "Usage: core_sim_test_runner.sh <bin location> <expected result>" } if [[ $1 == "--help" ]]; then @@ -42,8 +42,19 @@ BIN_FILE=$(realpath $1) shift 1 -SIM_OUT=$(${CORE_SIM} "${BIN_FILE}" $@) +EXPECTED_RESULT=${1:-True} +shift 1 + +SIM_OUT=$(${CORE_SIM} "${BIN_FILE}") RESULT=$? echo "${SIM_OUT}" -exit ${RESULT} +if [[ "${EXPECTED_RESULT}" == "True" ]]; then + exit ${RESULT} +elif [[ "${EXPECTED_RESULT}" == "False" ]]; then + if [[ ${RESULT} -eq 0 ]]; then + exit -1 + else + exit 0 + fi +fi
diff --git a/crt/kelvin_tcm.ld b/crt/kelvin_tcm.ld index b498a59..b24c11a 100644 --- a/crt/kelvin_tcm.ld +++ b/crt/kelvin_tcm.ld
@@ -24,10 +24,12 @@ .init.array : ALIGN(16) { __init_array_start = .; + __init_array_start__ = .; *(.init_array) *(.init_array.*) . = ALIGN(16); __init_array_end = .; + __init_array_end__ = .; } > ITCM .rodata : ALIGN(16) { @@ -52,6 +54,11 @@ *(.sdata.*) *(.data) *(.data.*) + /** + * Memory location for the return value from main, + * which could be inspected by another core in the system. + **/ + _ret = .; . = ALIGN(16); __data_end__ = .; } > DTCM
diff --git a/tests/kelvin_isa/BUILD b/tests/kelvin_isa/BUILD index 5861d6a..dabb7d2 100644 --- a/tests/kelvin_isa/BUILD +++ b/tests/kelvin_isa/BUILD
@@ -33,6 +33,7 @@ deps = [ ":kelvin_test", ], + tags = ["tcm-incompatible"], ) kelvin_test( @@ -47,6 +48,132 @@ ) kelvin_test( + name = "instr_fault", + srcs = [ + "instr_fault.cc", + ], + hw_test_size = "small", + deps = [ + ":kelvin_test", + ], + iss = False, + expect_success = False, + tags = ["intentional_failure"], +) + +kelvin_test( + name = "illegal", + srcs = [ + "illegal.cc", + ], + hw_test_size = "small", + deps = [ + ":kelvin_test", + ], + iss = False, + expect_success = False, + tags = ["intentional_failure"], +) + +kelvin_test( + name = "instr_align_0", + srcs = [ + "instr_align_0.cc", + ], + hw_test_size = "small", + deps = [ + ":kelvin_test", + ], + iss = False, + expect_success = False, + tags = ["intentional_failure"], +) + +kelvin_test( + name = "instr_align_1", + srcs = [ + "instr_align_1.cc", + ], + hw_test_size = "small", + deps = [ + ":kelvin_test", + ], + iss = False, + expect_success = False, + tags = ["intentional_failure"], +) + +kelvin_test( + name = "instr_align_2", + srcs = [ + "instr_align_2.cc", + ], + hw_test_size = "small", + deps = [ + ":kelvin_test", + ], + iss = False, + expect_success = False, + tags = ["intentional_failure"], +) + +kelvin_test( + name = "load_fault_0", + srcs = [ + "load_fault_0.cc", + ], + hw_test_size = "small", + deps = [ + ":kelvin_test", + ], + iss = False, + expect_success = False, + tags = ["intentional_failure"], +) + +kelvin_test( + name = "load_fault_1", + srcs = [ + "load_fault_1.cc", + ], + hw_test_size = "small", + deps = [ + ":kelvin_test", + ], + iss = False, + expect_success = False, + tags = ["intentional_failure"], +) + +kelvin_test( + name = "store_fault_0", + srcs = [ + "store_fault_0.cc", + ], + hw_test_size = "small", + deps = [ + ":kelvin_test", + ], + iss = False, + # This passes on core_sim, but should fail on core_mini_sim. + # expect_success = False, +) + +kelvin_test( + name = "store_fault_1", + srcs = [ + "store_fault_1.cc", + ], + hw_test_size = "small", + deps = [ + ":kelvin_test", + ], + iss = False, + expect_success = False, + tags = ["intentional_failure"], +) + +kelvin_test( name = "acset", srcs = [ "acset.cc", @@ -55,6 +182,7 @@ deps = [ ":kelvin_test", ], + tags = ["tcm-incompatible"], ) kelvin_test( @@ -66,6 +194,7 @@ deps = [ ":kelvin_test", ], + tags = ["tcm-incompatible"], ) kelvin_test( @@ -79,6 +208,7 @@ deps = [ ":kelvin_test", ], + tags = ["tcm-incompatible"], ) kelvin_test( @@ -89,6 +219,7 @@ deps = [ ":kelvin_test", ], + tags = ["tcm-incompatible"], ) kelvin_test( @@ -99,6 +230,7 @@ deps = [ ":kelvin_test", ], + tags = ["tcm-incompatible"], ) kelvin_test( @@ -109,6 +241,7 @@ deps = [ ":kelvin_test", ], + tags = ["tcm-incompatible"], ) kelvin_test( @@ -119,6 +252,7 @@ deps = [ ":kelvin_test", ], + tags = ["tcm-incompatible"], ) kelvin_test( @@ -129,6 +263,7 @@ deps = [ ":kelvin_test", ], + tags = ["tcm-incompatible"], ) cc_library( @@ -147,6 +282,7 @@ ":kelvin_test", ":vdwconv_data", ], + tags = ["tcm-incompatible"], ) kelvin_test( @@ -157,6 +293,7 @@ deps = [ ":kelvin_test", ], + tags = ["tcm-incompatible"], ) kelvin_test( @@ -167,6 +304,7 @@ deps = [ ":kelvin_test", ], + tags = ["tcm-incompatible"], ) kelvin_test( @@ -177,6 +315,7 @@ deps = [ ":kelvin_test", ], + tags = ["tcm-incompatible"], ) kelvin_test( @@ -188,6 +327,7 @@ deps = [ ":kelvin_test", ], + tags = ["tcm-incompatible"], ) kelvin_test( @@ -199,6 +339,7 @@ deps = [ ":kelvin_test", ], + tags = ["tcm-incompatible"], ) kelvin_test( @@ -210,6 +351,7 @@ deps = [ ":kelvin_test", ], + tags = ["tcm-incompatible"], ) kelvin_test( @@ -220,6 +362,7 @@ deps = [ ":kelvin_test", ], + tags = ["tcm-incompatible"], ) kelvin_test( @@ -230,6 +373,7 @@ deps = [ ":kelvin_test", ], + tags = ["tcm-incompatible"], ) kelvin_test( @@ -240,6 +384,7 @@ deps = [ ":kelvin_test", ], + tags = ["tcm-incompatible"], ) kelvin_test( @@ -250,6 +395,7 @@ deps = [ ":kelvin_test", ], + tags = ["tcm-incompatible"], ) kelvin_test( @@ -260,6 +406,7 @@ deps = [ ":kelvin_test", ], + tags = ["tcm-incompatible"], ) kelvin_test( @@ -271,4 +418,5 @@ deps = [ ":kelvin_test", ], + tags = ["tcm-incompatible"], )
diff --git a/tests/kelvin_isa/illegal.cc b/tests/kelvin_isa/illegal.cc new file mode 100644 index 0000000..418ee00 --- /dev/null +++ b/tests/kelvin_isa/illegal.cc
@@ -0,0 +1,21 @@ +// Copyright 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include <cstdint> + +int main(int argc, char** argv) { + asm volatile(".word 0x02007043"); // fmadd.d f0, f0, f0, f0 + + return 0; +}
diff --git a/tests/kelvin_isa/instr_align_0.cc b/tests/kelvin_isa/instr_align_0.cc new file mode 100644 index 0000000..303e279 --- /dev/null +++ b/tests/kelvin_isa/instr_align_0.cc
@@ -0,0 +1,22 @@ +// Copyright 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include <cstdint> + +int main(int argc, char** argv) { + // Instruction address misaligned + asm volatile("la ra, 0x3; jalr ra,ra"); + + return 0; +}
diff --git a/tests/kelvin_isa/instr_align_1.cc b/tests/kelvin_isa/instr_align_1.cc new file mode 100644 index 0000000..1ee81d1 --- /dev/null +++ b/tests/kelvin_isa/instr_align_1.cc
@@ -0,0 +1,22 @@ +// Copyright 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include <cstdint> + +int main(int argc, char** argv) { + // Instruction address misaligned + asm volatile("jal x0, .+2"); + + return 0; +}
diff --git a/tests/kelvin_isa/instr_align_2.cc b/tests/kelvin_isa/instr_align_2.cc new file mode 100644 index 0000000..21aa0b7 --- /dev/null +++ b/tests/kelvin_isa/instr_align_2.cc
@@ -0,0 +1,22 @@ +// Copyright 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include <cstdint> + +int main(int argc, char** argv) { + // Instruction address misaligned + asm volatile("beqz x0, .+2"); + + return 0; +}
diff --git a/tests/kelvin_isa/instr_fault.cc b/tests/kelvin_isa/instr_fault.cc new file mode 100644 index 0000000..c3e974f --- /dev/null +++ b/tests/kelvin_isa/instr_fault.cc
@@ -0,0 +1,19 @@ +// Copyright 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +int main(int argc, char** argv) { + asm volatile("la ra, 0x40000000; jalr ra, ra"); + + return 0; +}
diff --git a/tests/kelvin_isa/load_fault_0.cc b/tests/kelvin_isa/load_fault_0.cc new file mode 100644 index 0000000..c3e974f --- /dev/null +++ b/tests/kelvin_isa/load_fault_0.cc
@@ -0,0 +1,19 @@ +// Copyright 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +int main(int argc, char** argv) { + asm volatile("la ra, 0x40000000; jalr ra, ra"); + + return 0; +}
diff --git a/tests/kelvin_isa/load_fault_1.cc b/tests/kelvin_isa/load_fault_1.cc new file mode 100644 index 0000000..78f7beb --- /dev/null +++ b/tests/kelvin_isa/load_fault_1.cc
@@ -0,0 +1,23 @@ +// Copyright 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include <cstdint> + +int main(int argc, char** argv) { + volatile uint32_t* load_bad_addr = (uint32_t*)0xA0000000; + volatile uint32_t foo = *load_bad_addr; + (void)foo; + + return 0; +}
diff --git a/tests/kelvin_isa/store_fault_0.cc b/tests/kelvin_isa/store_fault_0.cc new file mode 100644 index 0000000..68c5094 --- /dev/null +++ b/tests/kelvin_isa/store_fault_0.cc
@@ -0,0 +1,23 @@ +// Copyright 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include <cstdint> + +int main(int argc, char** argv) { + // Store Fault (internal) + volatile uint32_t* store_bad_addr = (uint32_t*)4L; + *store_bad_addr = 0xdeadbeef; + + return 0; +}
diff --git a/tests/kelvin_isa/store_fault_1.cc b/tests/kelvin_isa/store_fault_1.cc new file mode 100644 index 0000000..bb5d2fc --- /dev/null +++ b/tests/kelvin_isa/store_fault_1.cc
@@ -0,0 +1,23 @@ +// Copyright 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include <cstdint> + +int main(int argc, char** argv) { + // Store Fault (external) + volatile uint32_t* store_bad_addr = (uint32_t*)0xA0000000; + *store_bad_addr = 0xdeadbeef; + + return 0; +}