arm: Add AArch64 hypervisor call instruction 'hvc'
authorDylan Johnson <Dylan.Johnson@ARM.com>
Tue, 2 Aug 2016 09:38:02 +0000 (10:38 +0100)
committerDylan Johnson <Dylan.Johnson@ARM.com>
Tue, 2 Aug 2016 09:38:02 +0000 (10:38 +0100)
This patch adds the AArch64 instruction hvc which raises an exception
from EL1 into EL2. The host OS uses this instruction to world switch
into the guest.

Change-Id: I930ee43f4f0abd4b35a68eb2a72e44e3ea6570be

src/arch/arm/faults.cc
src/arch/arm/faults.hh
src/arch/arm/isa/formats/aarch64.isa
src/arch/arm/isa/insts/misc64.isa

index e7a461ef6c464f6e2bbf658bd3e8f27988d8af3e..061e1299af5eb4e3872f8668e3dabdd75ee2279b 100644 (file)
@@ -840,6 +840,12 @@ HypervisorCall::HypervisorCall(ExtMachInst _machInst, uint32_t _imm) :
         ArmFaultVals<HypervisorCall>(_machInst, _imm)
 {}
 
+ExceptionClass
+HypervisorCall::ec(ThreadContext *tc) const
+{
+    return from64 ? EC_HVC_64 : vals.ec;
+}
+
 ExceptionClass
 HypervisorTrap::ec(ThreadContext *tc) const
 {
index 02d2e81f506f27f8e05ecb1ad8be78d0934707db..da501a1094ffa3bf5e6dd439aee82af99445f5e8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2012-2013 ARM Limited
+ * Copyright (c) 2010, 2012-2013, 2016 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -352,6 +352,8 @@ class HypervisorCall : public ArmFaultVals<HypervisorCall>
 {
   public:
     HypervisorCall(ExtMachInst _machInst, uint32_t _imm);
+
+    ExceptionClass ec(ThreadContext *tc) const;
 };
 
 class HypervisorTrap : public ArmFaultVals<HypervisorTrap>
index 2d94aff518a87a73926f22a4b218d07bda461561..c3fa742747753aeeb8efe1223be7dd622aeb75fb 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (c) 2011-2015 ARM Limited
+// Copyright (c) 2011-2016 ARM Limited
 // All rights reserved
 //
 // The license below extends only to copyright in the software and shall
@@ -250,7 +250,7 @@ namespace Aarch64
                   case 0x01:
                     return new Svc64(machInst);
                   case 0x02:
-                    return new FailUnimplemented("hvc", machInst);
+                    return new Hvc64(machInst);
                   case 0x03:
                     return new Smc64(machInst);
                   case 0x04:
index 7e88bebbb37e415eadb473ddfc67477c96a4a05b..08902abe89310bb70615a1b5d567b4274291238f 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode:c++ -*-
 
-// Copyright (c) 2011-2013 ARM Limited
+// Copyright (c) 2011-2013, 2016 ARM Limited
 // All rights reserved
 //
 // The license below extends only to copyright in the software and shall
@@ -49,6 +49,24 @@ let {{
     decoder_output = BasicConstructor64.subst(svcIop)
     exec_output = BasicExecute.subst(svcIop)
 
+    hvcCode = '''
+    SCR scr = Scr64;
+
+    if (!ArmSystem::haveVirtualization(xc->tcBase()) ||
+        (ArmSystem::haveSecurity(xc->tcBase()) && !scr.hce)) {
+        fault = disabledFault();
+    } else {
+        fault = std::make_shared<HypervisorCall>(machInst, bits(machInst, 20, 5));
+    }
+    '''
+
+    hvcIop = InstObjParams("hvc", "Hvc64", "ArmStaticInst",
+                           hvcCode, ["IsSyscall", "IsNonSpeculative",
+                                     "IsSerializeAfter"])
+    header_output += BasicDeclare.subst(hvcIop)
+    decoder_output += BasicConstructor64.subst(hvcIop)
+    exec_output += BasicExecute.subst(hvcIop)
+
     # @todo: extend to take into account Virtualization.
     smcCode = '''
     SCR scr = Scr64;