Skip to content

Commit

Permalink
arm: Add support for ARMv8 (AArch64 & AArch32)
Browse files Browse the repository at this point in the history
Note: AArch64 and AArch32 interworking is not supported. If you use an AArch64
kernel you are restricted to AArch64 user-mode binaries. This will be addressed
in a later patch.

Note: Virtualization is only supported in AArch32 mode. This will also be fixed
in a later patch.

Contributors:
Giacomo Gabrielli    (TrustZone, LPAE, system-level AArch64, AArch64 NEON, validation)
Thomas Grocutt       (AArch32 Virtualization, AArch64 FP, validation)
Mbou Eyole           (AArch64 NEON, validation)
Ali Saidi            (AArch64 Linux support, code integration, validation)
Edmund Grimley-Evans (AArch64 FP)
William Wang         (AArch64 Linux support)
Rene De Jong         (AArch64 Linux support, performance opt.)
Matt Horsnell        (AArch64 MP, validation)
Matt Evans           (device models, code integration, validation)
Chris Adeniyi-Jones  (AArch64 syscall-emulation)
Prakash Ramrakhyani  (validation)
Dam Sunwoo           (validation)
Chander Sudanthi     (validation)
Stephan Diestelhorst (validation)
Andreas Hansson      (code integration, performance opt.)
Eric Van Hensbergen  (performance opt.)
Gabe Black
  • Loading branch information
ARM gem5 Developers committed Jan 24, 2014
1 parent f3585c8 commit 612f8f0
Show file tree
Hide file tree
Showing 145 changed files with 39,766 additions and 2,533 deletions.
3 changes: 2 additions & 1 deletion configs/common/FSConfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,8 @@ def makeArmSystem(mem_mode, machine_type, mdesc = None,
self.realview = VExpress_ELT()
elif machine_type == "VExpress_EMM":
self.realview = VExpress_EMM()
self.load_addr_mask = 0xffffffff
elif machine_type == "VExpress_EMM64":
self.realview = VExpress_EMM64()
else:
print "Unknown Machine Type"
sys.exit(1)
Expand Down
2 changes: 1 addition & 1 deletion configs/common/O3_ARM_v7a.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ class O3_ARM_v7a_3(DerivO3CPU):
backComSize = 5
forwardComSize = 5
numPhysIntRegs = 128
numPhysFloatRegs = 128
numPhysFloatRegs = 192
numIQEntries = 32
numROBEntries = 40

Expand Down
11 changes: 11 additions & 0 deletions configs/common/Options.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ def addCommonOptions(parser):
default="512MB",
help="Specify the physical memory size (single memory)")

parser.add_option("-l", "--lpae", action="store_true")
parser.add_option("-V", "--virtualisation", action="store_true")

# Cache Options
parser.add_option("--caches", action="store_true")
parser.add_option("--l2cache", action="store_true")
Expand Down Expand Up @@ -197,6 +200,14 @@ def addCommonOptions(parser):
parser.add_option("--at-instruction", action="store_true", default=False,
help="""Treat value of --checkpoint-restore or --take-checkpoint as a
number of instructions.""")
parser.add_option("--spec-input", default="ref", type="choice",
choices=["ref", "test", "train", "smred", "mdred",
"lgred"],
help="Input set size for SPEC CPU2000 benchmarks.")
parser.add_option("--arm-iset", default="arm", type="choice",
choices=["arm", "thumb", "aarch64"],
help="ARM instruction set.")


def addSEOptions(parser):
# Benchmark options
Expand Down
2 changes: 1 addition & 1 deletion configs/common/cpu2000.py
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,7 @@ class vortex(Benchmark):
stdin = None

def __init__(self, isa, os, input_set):
if (isa == 'alpha' or isa == 'arm'):
if (isa in ('alpha', 'arm', 'thumb', 'aarch64')):
self.endian = 'lendian'
elif (isa == 'sparc' or isa == 'sparc32'):
self.endian = 'bendian'
Expand Down
6 changes: 6 additions & 0 deletions configs/example/fs.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,12 @@ def is_kvm_cpu(cpu_class):
if options.script is not None:
test_sys.readfile = options.script

if options.lpae:
test_sys.have_lpae = True

if options.virtualisation:
test_sys.have_virtualization = True

test_sys.init_param = options.init_param

# For now, assign all the CPUs to the same clock domain
Expand Down
9 changes: 7 additions & 2 deletions configs/example/se.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,14 @@ def get_processes(options):
for app in apps:
try:
if buildEnv['TARGET_ISA'] == 'alpha':
exec("workload = %s('alpha', 'tru64', 'ref')" % app)
exec("workload = %s('alpha', 'tru64', '%s')" % (
app, options.spec_input))
elif buildEnv['TARGET_ISA'] == 'arm':
exec("workload = %s('arm_%s', 'linux', '%s')" % (
app, options.arm_iset, options.spec_input))
else:
exec("workload = %s(buildEnv['TARGET_ISA'], 'linux', 'ref')" % app)
exec("workload = %s(buildEnv['TARGET_ISA', 'linux', '%s')" % (
app, options.spec_input))
multiprocesses.append(workload.makeLiveProcess())
except:
print >>sys.stderr, "Unable to find workload for %s: %s" % (buildEnv['TARGET_ISA'], app)
Expand Down
1 change: 1 addition & 0 deletions ext/libelf/elf_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ typedef struct {
#define EM_TINYJ 61 /* Advanced Logic Corp. TinyJ processor. */
#define EM_X86_64 62 /* Advanced Micro Devices x86-64 */
#define EM_AMD64 EM_X86_64 /* Advanced Micro Devices x86-64 (compat) */
#define EM_AARCH64 183 /* AArch64 64 bit ARM. */

/* Non-standard or deprecated. */
#define EM_486 6 /* Intel i486. */
Expand Down
58 changes: 46 additions & 12 deletions src/arch/arm/ArmISA.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2012 ARM Limited
# Copyright (c) 2012-2013 ARM Limited
# All rights reserved.
#
# The license below extends only to copyright in the software and shall
Expand Down Expand Up @@ -34,41 +34,40 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Andreas Sandberg
# Giacomo Gabrielli

from m5.params import *
from m5.proxy import *
from m5.SimObject import SimObject

class ArmISA(SimObject):
type = 'ArmISA'
cxx_class = 'ArmISA::ISA'
cxx_header = "arch/arm/isa.hh"

# 0x35 Implementor is '5' from "M5"
# 0x0 Variant
# 0xf Architecture from CPUID scheme
# 0xc00 Primary part number ("c" or higher implies ARM v7)
# 0x0 Revision
midr = Param.UInt32(0x350fc000, "Main ID Register")
system = Param.System(Parent.any, "System this ISA object belongs to")

midr = Param.UInt32(0x410fc0f0, "MIDR value")

# See section B4.1.93 - B4.1.94 of the ARM ARM
#
# !ThumbEE | !Jazelle | Thumb | ARM
# Note: ThumbEE is disabled for now since we don't support CP14
# config registers and jumping to ThumbEE vectors
id_pfr0 = Param.UInt32(0x00000031, "Processor Feature Register 0")
# !Timer | !Virti | !M Profile | !TrustZone | ARMv4
id_pfr1 = Param.UInt32(0x00000001, "Processor Feature Register 1")
# !Timer | Virti | !M Profile | TrustZone | ARMv4
id_pfr1 = Param.UInt32(0x00001011, "Processor Feature Register 1")

# See section B4.1.89 - B4.1.92 of the ARM ARM
# VMSAv7 support
id_mmfr0 = Param.UInt32(0x00000003, "Memory Model Feature Register 0")
id_mmfr0 = Param.UInt32(0x10201103, "Memory Model Feature Register 0")
id_mmfr1 = Param.UInt32(0x00000000, "Memory Model Feature Register 1")
# no HW access | WFI stalling | ISB and DSB |
# all TLB maintenance | no Harvard
id_mmfr2 = Param.UInt32(0x01230000, "Memory Model Feature Register 2")
# SuperSec | Coherent TLB | Bcast Maint |
# BP Maint | Cache Maint Set/way | Cache Maint MVA
id_mmfr3 = Param.UInt32(0xF0102211, "Memory Model Feature Register 3")
id_mmfr3 = Param.UInt32(0x02102211, "Memory Model Feature Register 3")

# See section B4.1.84 of ARM ARM
# All values are latest for ARMv7-A profile
Expand All @@ -79,5 +78,40 @@ class ArmISA(SimObject):
id_isar4 = Param.UInt32(0x10010142, "Instruction Set Attribute Register 4")
id_isar5 = Param.UInt32(0x00000000, "Instruction Set Attribute Register 5")

fpsid = Param.UInt32(0x410430a0, "Floating-point System ID Register")

# [31:0] is implementation defined
id_aa64afr0_el1 = Param.UInt64(0x0000000000000000,
"AArch64 Auxiliary Feature Register 0")
# Reserved for future expansion
id_aa64afr1_el1 = Param.UInt64(0x0000000000000000,
"AArch64 Auxiliary Feature Register 1")

# 1 CTX CMPs | 2 WRPs | 2 BRPs | !PMU | !Trace | Debug v8-A
id_aa64dfr0_el1 = Param.UInt64(0x0000000000101006,
"AArch64 Debug Feature Register 0")
# Reserved for future expansion
id_aa64dfr1_el1 = Param.UInt64(0x0000000000000000,
"AArch64 Debug Feature Register 1")

# !CRC32 | !SHA2 | !SHA1 | !AES
id_aa64isar0_el1 = Param.UInt64(0x0000000000000000,
"AArch64 Instruction Set Attribute Register 0")
# Reserved for future expansion
id_aa64isar1_el1 = Param.UInt64(0x0000000000000000,
"AArch64 Instruction Set Attribute Register 1")

# 4K | 64K | !16K | !BigEndEL0 | !SNSMem | !BigEnd | 8b ASID | 40b PA
id_aa64mmfr0_el1 = Param.UInt64(0x0000000000f00002,
"AArch64 Memory Model Feature Register 0")
# Reserved for future expansion
id_aa64mmfr1_el1 = Param.UInt64(0x0000000000000000,
"AArch64 Memory Model Feature Register 1")

fpsid = Param.UInt32(0x410430A0, "Floating-point System ID Register")
# !GICv3 CP15 | AdvSIMD | FP | !EL3 | !EL2 | EL1 (AArch64) | EL0 (AArch64)
# (no AArch32/64 interprocessing support for now)
id_aa64pfr0_el1 = Param.UInt64(0x0000000000000011,
"AArch64 Processor Feature Register 0")
# Reserved for future expansion
id_aa64pfr1_el1 = Param.UInt64(0x0000000000000000,
"AArch64 Processor Feature Register 1")
28 changes: 24 additions & 4 deletions src/arch/arm/ArmSystem.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2009 ARM Limited
# Copyright (c) 2009, 2012-2013 ARM Limited
# All rights reserved.
#
# The license below extends only to copyright in the software and shall
Expand Down Expand Up @@ -44,7 +44,8 @@ class ArmMachineType(Enum):
'RealView_PBX' : 1901,
'VExpress_ELT' : 2272,
'VExpress_CA9' : 2272,
'VExpress_EMM' : 2272}
'VExpress_EMM' : 2272,
'VExpress_EMM64' : 2272}

class ArmSystem(System):
type = 'ArmSystem'
Expand All @@ -54,15 +55,34 @@ class ArmSystem(System):
boot_loader = Param.String("", "File that contains the boot loader code if any")
gic_cpu_addr = Param.Addr(0, "Addres of the GIC CPU interface")
flags_addr = Param.Addr(0, "Address of the flags register for MP booting")
have_security = Param.Bool(False,
"True if Security Extensions are implemented")
have_virtualization = Param.Bool(False,
"True if Virtualization Extensions are implemented")
have_lpae = Param.Bool(False, "True if LPAE is implemented")
have_generic_timer = Param.Bool(False,
"True if the Generic Timer extension is implemented")
highest_el_is_64 = Param.Bool(False,
"True if the register width of the highest implemented exception level "
"is 64 bits (ARMv8)")
reset_addr_64 = Param.UInt64(0x0,
"Reset address if the highest implemented exception level is 64 bits "
"(ARMv8)")
phys_addr_range_64 = Param.UInt8(40,
"Supported physical address range in bits when using AArch64 (ARMv8)")
have_large_asid_64 = Param.Bool(False,
"True if ASID is 16 bits in AArch64 (ARMv8)")

class LinuxArmSystem(ArmSystem):
type = 'LinuxArmSystem'
cxx_header = "arch/arm/linux/system.hh"
load_addr_mask = 0x0fffffff
machine_type = Param.ArmMachineType('RealView_PBX',
"Machine id from http://www.arm.linux.org.uk/developer/machines/")
atags_addr = Param.Addr(0x100,
"Address where default atags structure should be written")
atags_addr = Param.Addr("Address where default atags structure should " \
"be written")
boot_release_addr = Param.Addr(0xfff8, "Address where secondary CPUs " \
"spin waiting boot in the loader")
dtb_filename = Param.String("",
"File that contains the Device Tree Blob. Don't use DTB if empty.")
early_kernel_symbols = Param.Bool(False,
Expand Down
29 changes: 28 additions & 1 deletion src/arch/arm/ArmTLB.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- mode:python -*-

# Copyright (c) 2009 ARM Limited
# Copyright (c) 2009, 2013 ARM Limited
# All rights reserved.
#
# The license below extends only to copyright in the software and shall
Expand Down Expand Up @@ -42,10 +42,12 @@
from m5.proxy import *
from MemObject import MemObject

# Basic stage 1 translation objects
class ArmTableWalker(MemObject):
type = 'ArmTableWalker'
cxx_class = 'ArmISA::TableWalker'
cxx_header = "arch/arm/table_walker.hh"
is_stage2 = Param.Bool(False, "Is this object for stage 2 translation?")
port = MasterPort("Port for TableWalker to do walk the translation with")
sys = Param.System(Parent.any, "system object parameter")
num_squash_per_cycle = Param.Unsigned(2,
Expand All @@ -57,3 +59,28 @@ class ArmTLB(SimObject):
cxx_header = "arch/arm/tlb.hh"
size = Param.Int(64, "TLB size")
walker = Param.ArmTableWalker(ArmTableWalker(), "HW Table walker")
is_stage2 = Param.Bool(False, "Is this a stage 2 TLB?")

# Stage 2 translation objects, only used when virtualisation is being used
class ArmStage2TableWalker(ArmTableWalker):
is_stage2 = True

class ArmStage2TLB(ArmTLB):
size = 32
walker = ArmStage2TableWalker()
is_stage2 = True

class ArmStage2MMU(SimObject):
type = 'ArmStage2MMU'
cxx_class = 'ArmISA::Stage2MMU'
cxx_header = 'arch/arm/stage2_mmu.hh'
tlb = Param.ArmTLB("Stage 1 TLB")
stage2_tlb = Param.ArmTLB("Stage 2 TLB")

class ArmStage2IMMU(ArmStage2MMU):
tlb = Parent.itb
stage2_tlb = ArmStage2TLB(walker = ArmStage2TableWalker())

class ArmStage2DMMU(ArmStage2MMU):
tlb = Parent.dtb
stage2_tlb = ArmStage2TLB(walker = ArmStage2TableWalker())
9 changes: 8 additions & 1 deletion src/arch/arm/SConscript
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- mode:python -*-

# Copyright (c) 2009 ARM Limited
# Copyright (c) 2009, 2012-2013 ARM Limited
# All rights reserved.
#
# The license below extends only to copyright in the software and shall
Expand Down Expand Up @@ -49,12 +49,17 @@ if env['TARGET_ISA'] == 'arm':
Dir('isa/formats')
Source('decoder.cc')
Source('faults.cc')
Source('insts/branch64.cc')
Source('insts/data64.cc')
Source('insts/macromem.cc')
Source('insts/mem.cc')
Source('insts/mem64.cc')
Source('insts/misc.cc')
Source('insts/misc64.cc')
Source('insts/pred_inst.cc')
Source('insts/static_inst.cc')
Source('insts/vfp.cc')
Source('insts/fplib.cc')
Source('interrupts.cc')
Source('isa.cc')
Source('linux/linux.cc')
Expand All @@ -67,6 +72,8 @@ if env['TARGET_ISA'] == 'arm':
Source('stacktrace.cc')
Source('system.cc')
Source('table_walker.cc')
Source('stage2_mmu.cc')
Source('stage2_lookup.cc')
Source('tlb.cc')
Source('utility.cc')
Source('vtophys.cc')
Expand Down
21 changes: 18 additions & 3 deletions src/arch/arm/decoder.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
/*
* Copyright (c) 2012-2013 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed hereunder. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* Copyright (c) 2012 Google
* All rights reserved.
*
Expand Down Expand Up @@ -47,9 +59,11 @@ Decoder::process()

if (!emi.thumb) {
emi.instBits = data;
emi.sevenAndFour = bits(data, 7) && bits(data, 4);
emi.isMisc = (bits(data, 24, 23) == 0x2 &&
bits(data, 20) == 0);
if (!emi.aarch64) {
emi.sevenAndFour = bits(data, 7) && bits(data, 4);
emi.isMisc = (bits(data, 24, 23) == 0x2 &&
bits(data, 20) == 0);
}
consumeBytes(4);
DPRINTF(Decoder, "Arm inst: %#x.\n", (uint64_t)emi);
} else {
Expand Down Expand Up @@ -112,6 +126,7 @@ Decoder::moreBytes(const PCState &pc, Addr fetchPC, MachInst inst)
data = inst;
offset = (fetchPC >= pc.instAddr()) ? 0 : pc.instAddr() - fetchPC;
emi.thumb = pc.thumb();
emi.aarch64 = pc.aarch64();
emi.fpscrLen = fpscrLen;
emi.fpscrStride = fpscrStride;

Expand Down
12 changes: 12 additions & 0 deletions src/arch/arm/decoder.hh
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
/*
* Copyright (c) 2013 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed hereunder. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* Copyright (c) 2012 Google
* All rights reserved.
*
Expand Down
Loading

0 comments on commit 612f8f0

Please sign in to comment.