summaryrefslogtreecommitdiff
path: root/src/arch/arm
diff options
context:
space:
mode:
authorCiro Santilli <ciro.santilli@arm.com>2018-09-19 15:50:46 +0100
committerCiro Santilli <ciro.santilli@arm.com>2018-10-19 15:11:33 +0000
commit33b311d8d8b8d527d500d62a35b50be63e41b556 (patch)
treebc5f6f1c069f7d4c03fdcb85f65c8f7aabc2c413 /src/arch/arm
parente9434cff87762255bc055e04a2695e70a53c41a2 (diff)
downloadgem5-33b311d8d8b8d527d500d62a35b50be63e41b556.tar.xz
arm: update hint instruction decoding to match ARMv8.5
This fixes: - unallocated hints that have since been allocated - unallocated and unimplemented hint instructions being treated as Unknown instead of the correct NOP - missing encoding for DBG on A32 Unallocated and unimplemented hints give a warning if executed. The most important fix was for the CSDB Spectre mitigation instruction, which was added recently and previously unallocated and treated as Unknown. The Linux kernel v4.18 ARMv7 uses CSDB it and boot would fail with "undefined instruction" since Linux commit 1d4238c56f9816ce0f9c8dbe42d7f2ad81cb6613 Change-Id: I283da3f08a9af4148edc6fb3ca2930cbb97126b8 Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Reviewed-on: https://gem5-review.googlesource.com/c/13475 Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Diffstat (limited to 'src/arch/arm')
-rw-r--r--src/arch/arm/isa/formats/aarch64.isa82
-rw-r--r--src/arch/arm/isa/formats/branch.isa48
-rw-r--r--src/arch/arm/isa/formats/data.isa43
3 files changed, 136 insertions, 37 deletions
diff --git a/src/arch/arm/isa/formats/aarch64.isa b/src/arch/arm/isa/formats/aarch64.isa
index aa38fd426..cd106abd4 100644
--- a/src/arch/arm/isa/formats/aarch64.isa
+++ b/src/arch/arm/isa/formats/aarch64.isa
@@ -292,22 +292,84 @@ namespace Aarch64
if (rt != 0x1f || l)
return new Unknown64(machInst);
if (crn == 0x2 && op1 == 0x3) {
- switch (op2) {
+ switch (crm) {
case 0x0:
- return new NopInst(machInst);
+ switch (op2) {
+ case 0x0:
+ return new NopInst(machInst);
+ case 0x1:
+ return new YieldInst(machInst);
+ case 0x2:
+ return new WfeInst(machInst);
+ case 0x3:
+ return new WfiInst(machInst);
+ case 0x4:
+ return new SevInst(machInst);
+ case 0x5:
+ return new SevlInst(machInst);
+ }
+ break;
case 0x1:
- return new YieldInst(machInst);
+ switch (op2) {
+ case 0x0:
+ return new WarnUnimplemented(
+ "pacia", machInst);
+ case 0x2:
+ return new WarnUnimplemented(
+ "pacib", machInst);
+ case 0x4:
+ return new WarnUnimplemented(
+ "autia", machInst);
+ case 0x6:
+ return new WarnUnimplemented(
+ "autib", machInst);
+ }
+ break;
case 0x2:
- return new WfeInst(machInst);
+ switch (op2) {
+ case 0x0:
+ return new WarnUnimplemented(
+ "esb", machInst);
+ case 0x1:
+ return new WarnUnimplemented(
+ "psb csync", machInst);
+ case 0x2:
+ return new WarnUnimplemented(
+ "tsb csync", machInst);
+ case 0x4:
+ return new WarnUnimplemented(
+ "csdb", machInst);
+ }
+ break;
case 0x3:
- return new WfiInst(machInst);
+ switch (op2) {
+ case 0x0:
+ case 0x1:
+ return new WarnUnimplemented(
+ "pacia", machInst);
+ case 0x2:
+ case 0x3:
+ return new WarnUnimplemented(
+ "pacib", machInst);
+ case 0x4:
+ case 0x5:
+ return new WarnUnimplemented(
+ "autia", machInst);
+ case 0x6:
+ case 0x7:
+ return new WarnUnimplemented(
+ "autib", machInst);
+ }
+ break;
case 0x4:
- return new SevInst(machInst);
- case 0x5:
- return new SevlInst(machInst);
- default:
- return new Unknown64(machInst);
+ switch (op2 & 0x1) {
+ case 0x0:
+ return new WarnUnimplemented(
+ "bti", machInst);
+ }
+ break;
}
+ return new Unknown64(machInst);
} else if (crn == 0x3 && op1 == 0x3) {
switch (op2) {
case 0x2:
diff --git a/src/arch/arm/isa/formats/branch.isa b/src/arch/arm/isa/formats/branch.isa
index df85b08a7..5f72113ae 100644
--- a/src/arch/arm/isa/formats/branch.isa
+++ b/src/arch/arm/isa/formats/branch.isa
@@ -1,6 +1,6 @@
// -*- mode:c++ -*-
-// Copyright (c) 2010,2012-2013,2017 ARM Limited
+// Copyright (c) 2010,2012-2013,2017-2018 ARM Limited
// All rights reserved
//
// The license below extends only to copyright in the software and shall
@@ -165,31 +165,51 @@ def format Thumb32BranchesAndMiscCtrl() {{
case 0x3a:
{
const uint32_t op1 = bits(machInst, 10, 8);
- const uint32_t op2 = bits(machInst, 7, 0);
+ const uint32_t hint = bits(machInst, 7, 4);
+ const uint32_t option = bits(machInst, 3, 0);
if (op1 != 0) {
const bool enable = bits(machInst, 10, 9) == 0x2;
const uint32_t mods = bits(machInst, 8, 0) |
((enable ? 1 : 0) << 9);
return new Cps(machInst, mods);
- } else if ((op2 & 0xf0) == 0xf0) {
+ } else if (hint == 0xf) {
return new Dbg(machInst);
} else {
- switch (op2) {
+ switch (hint) {
case 0x0:
- return new NopInst(machInst);
+ switch (option) {
+ case 0x0:
+ return new NopInst(machInst);
+ case 0x1:
+ return new YieldInst(machInst);
+ case 0x2:
+ return new WfeInst(machInst);
+ case 0x3:
+ return new WfiInst(machInst);
+ case 0x4:
+ return new SevInst(machInst);
+ case 0x5:
+ return new WarnUnimplemented(
+ "sevl", machInst);
+ }
+ break;
case 0x1:
- return new YieldInst(machInst);
- case 0x2:
- return new WfeInst(machInst);
- case 0x3:
- return new WfiInst(machInst);
- case 0x4:
- return new SevInst(machInst);
- default:
+ switch (option) {
+ case 0x0:
+ return new WarnUnimplemented(
+ "esb", machInst);
+ case 0x2:
+ return new WarnUnimplemented(
+ "tsb csync", machInst);
+ case 0x4:
+ return new WarnUnimplemented(
+ "csdb", machInst);
+ }
break;
}
}
- break;
+ return new WarnUnimplemented(
+ "unallocated_hint", machInst);
}
case 0x3b:
{
diff --git a/src/arch/arm/isa/formats/data.isa b/src/arch/arm/isa/formats/data.isa
index b5e29c583..cff3d22f0 100644
--- a/src/arch/arm/isa/formats/data.isa
+++ b/src/arch/arm/isa/formats/data.isa
@@ -1114,19 +1114,36 @@ def format ArmMisc() {{
false);
case 0x9:
if (RN == 0) {
- switch (IMM) {
- case 0x0:
- return new NopInst(machInst);
- case 0x1:
- return new YieldInst(machInst);
- case 0x2:
- return new WfeInst(machInst);
- case 0x3:
- return new WfiInst(machInst);
- case 0x4:
- return new SevInst(machInst);
- default:
- return new Unknown(machInst);
+ if ((IMM & 0xf0) == 0xf0) {
+ return new Dbg(machInst);
+ } else {
+ switch (IMM) {
+ case 0x0:
+ return new NopInst(machInst);
+ case 0x1:
+ return new YieldInst(machInst);
+ case 0x2:
+ return new WfeInst(machInst);
+ case 0x3:
+ return new WfiInst(machInst);
+ case 0x4:
+ return new SevInst(machInst);
+ case 0x5:
+ return new WarnUnimplemented(
+ "sevl", machInst);
+ case 0x10:
+ return new WarnUnimplemented(
+ "esb", machInst);
+ case 0x12:
+ return new WarnUnimplemented(
+ "tsb csync", machInst);
+ case 0x14:
+ return new WarnUnimplemented(
+ "csdb", machInst);
+ default:
+ return new WarnUnimplemented(
+ "unallocated_hint", machInst);
+ }
}
} else {
return new MsrCpsrImm(machInst, imm, byteMask);