1/* 2 * Copyright (c) 2015, 2017 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions are 16 * met: redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer; 18 * redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution; 21 * neither the name of the copyright holders nor the names of its 22 * contributors may be used to endorse or promote products derived from 23 * this software without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 * Authors: Andreas Sandberg 38 */ 39 40#ifndef __ARCH_ARM_KVM_ARMV8_CPU_HH__ 41#define __ARCH_ARM_KVM_ARMV8_CPU_HH__ 42 43#include <set> 44#include <vector> 45 46#include "arch/arm/intregs.hh" 47#include "arch/arm/kvm/base_cpu.hh" 48#include "arch/arm/miscregs.hh" 49 50struct ArmV8KvmCPUParams; 51 52/** 53 * This is an implementation of a KVM-based ARMv8-compatible CPU. 54 * 55 * Known limitations: 56 * <ul> 57 * 58 * <li>The system-register-based generic timer can only be simulated 59 * by the host kernel. Workaround: Use a memory mapped timer 60 * instead to simulate the timer in gem5. 61 * 62 * <li>Simulating devices (e.g., the generic timer) in the host 63 * kernel requires that the host kernel also simulates the 64 * GIC. 65 * 66 * <li>ID registers in the host and in gem5 must match for switching 67 * between simulated CPUs and KVM. This is particularly 68 * important for ID registers describing memory system 69 * capabilities (e.g., ASID size, physical address size). 70 * 71 * <li>Switching between a virtualized CPU and a simulated CPU is 72 * currently not supported if in-kernel device emulation is 73 * used. This could be worked around by adding support for 74 * switching to the gem5 (e.g., the KvmGic) side of the device 75 * models. A simpler workaround is to avoid in-kernel device 76 * models altogether. 77 * 78 * </ul> 79 * 80 */ 81class ArmV8KvmCPU : public BaseArmKvmCPU 82{ 83 public: 84 ArmV8KvmCPU(ArmV8KvmCPUParams *params); 85 virtual ~ArmV8KvmCPU(); 86 87 void startup() override; 88 89 void dump() const override; 90 91 protected: 92 void updateKvmState() override; 93 void updateThreadContext() override; 94 95 protected: 96 /** Mapping between integer registers in gem5 and KVM */ 97 struct IntRegInfo { 98 IntRegInfo(uint64_t _kvm, IntRegIndex _idx, const char *_name) 99 : kvm(_kvm), idx(_idx), name(_name) {} 100 101 /** Register index in KVM */ 102 uint64_t kvm; 103 /** Register index in gem5 */ 104 IntRegIndex idx; 105 /** Name to use in debug dumps */ 106 const char *name; 107 }; 108 109 /** Mapping between misc registers in gem5 and registers in KVM */ 110 struct MiscRegInfo { 111 MiscRegInfo(uint64_t _kvm, MiscRegIndex _idx, const char *_name, 112 bool _is_device = false) 113 : kvm(_kvm), idx(_idx), name(_name), is_device(_is_device) {} 114 115 /** Register index in KVM */ 116 uint64_t kvm; 117 /** Register index in gem5 */ 118 MiscRegIndex idx; 119 /** Name to use in debug dumps */ 120 const char *name; 121 /** is device register? (needs 'effectful' state update) */ 122 bool is_device; 123 }; 124 125 /** 126 * Get a map between system registers in kvm and gem5 registers 127 * 128 * This method returns a mapping between system registers in kvm 129 * and misc regs in gem5. The actual mapping is only created the 130 * first time the method is called and stored in a cache 131 * (ArmV8KvmCPU::sysRegMap). 132 * 133 * @return Vector of kvm<->misc reg mappings. 134 */ 135 const std::vector<ArmV8KvmCPU::MiscRegInfo> &getSysRegMap() const; 136 137 /** Mapping between gem5 integer registers and integer registers in kvm */ 138 static const std::vector<ArmV8KvmCPU::IntRegInfo> intRegMap; 139 /** Mapping between gem5 misc registers and registers in kvm */ 140 static const std::vector<ArmV8KvmCPU::MiscRegInfo> miscRegMap; 141 /** Device registers (needing "effectful" MiscReg writes) */ 142 static const std::set<MiscRegIndex> deviceRegSet; 143 /** Mapping between gem5 ID misc registers and registers in kvm */ 144 static const std::vector<ArmV8KvmCPU::MiscRegInfo> miscRegIdMap; 145 146 /** Cached mapping between system registers in kvm and misc regs in gem5 */ 147 mutable std::vector<ArmV8KvmCPU::MiscRegInfo> sysRegMap; 148}; 149 150#endif // __ARCH_ARM_KVM_ARMV8_CPU_HH__ 151