summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDylan Johnson <Dylan.Johnson@ARM.com>2016-08-02 10:38:02 +0100
committerDylan Johnson <Dylan.Johnson@ARM.com>2016-08-02 10:38:02 +0100
commit2950a95672599a9baf9007c18faf210ff9c3e392 (patch)
treeca19e4c650f16aad2a0a377b72ae287e248b5250 /src
parentc53a57f74f31c2593665bae716c5c3679aab5595 (diff)
downloadgem5-2950a95672599a9baf9007c18faf210ff9c3e392.tar.xz
arm: Add AArch64 hypervisor call instruction 'hvc'
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
Diffstat (limited to 'src')
-rw-r--r--src/arch/arm/faults.cc6
-rw-r--r--src/arch/arm/faults.hh4
-rw-r--r--src/arch/arm/isa/formats/aarch64.isa4
-rw-r--r--src/arch/arm/isa/insts/misc64.isa20
4 files changed, 30 insertions, 4 deletions
diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc
index e7a461ef6..061e1299a 100644
--- a/src/arch/arm/faults.cc
+++ b/src/arch/arm/faults.cc
@@ -841,6 +841,12 @@ HypervisorCall::HypervisorCall(ExtMachInst _machInst, uint32_t _imm) :
{}
ExceptionClass
+HypervisorCall::ec(ThreadContext *tc) const
+{
+ return from64 ? EC_HVC_64 : vals.ec;
+}
+
+ExceptionClass
HypervisorTrap::ec(ThreadContext *tc) const
{
return (overrideEc != EC_INVALID) ? overrideEc : vals.ec;
diff --git a/src/arch/arm/faults.hh b/src/arch/arm/faults.hh
index 02d2e81f5..da501a109 100644
--- a/src/arch/arm/faults.hh
+++ b/src/arch/arm/faults.hh
@@ -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>
diff --git a/src/arch/arm/isa/formats/aarch64.isa b/src/arch/arm/isa/formats/aarch64.isa
index 2d94aff51..c3fa74274 100644
--- a/src/arch/arm/isa/formats/aarch64.isa
+++ b/src/arch/arm/isa/formats/aarch64.isa
@@ -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:
diff --git a/src/arch/arm/isa/insts/misc64.isa b/src/arch/arm/isa/insts/misc64.isa
index 7e88bebbb..08902abe8 100644
--- a/src/arch/arm/isa/insts/misc64.isa
+++ b/src/arch/arm/isa/insts/misc64.isa
@@ -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;