arm: update hint instruction decoding to match ARMv8.5
authorCiro Santilli <ciro.santilli@arm.com>
Wed, 19 Sep 2018 14:50:46 +0000 (15:50 +0100)
committerCiro Santilli <ciro.santilli@arm.com>
Fri, 19 Oct 2018 15:11:33 +0000 (15:11 +0000)
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>

src/arch/arm/isa/formats/aarch64.isa
src/arch/arm/isa/formats/branch.isa
src/arch/arm/isa/formats/data.isa

index aa38fd4269b0b5546effb497baa55a2c4a630e67..cd106abd4bd030a5328e0438565af5eaa7e005d9 100644 (file)
@@ -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:
index df85b08a74bafd788d9c43a71627d2ab16e01252..5f72113ae36f4e2930482d7cce2927371d90453c 100644 (file)
@@ -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:
                     {
index b5e29c5830cedb4c6c184a992bc0ccd8e0e69d48..cff3d22f0ab039bed1b20a5267931b94d1a746d4 100644 (file)
@@ -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);