blob: 15e15dc0cfdbd21a1f7f5bb0fe87375b2db6ef83 [file] [log] [blame]
# Copyright (c) 2021 The Regents of the University of California
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from typing import Optional
from ...utils.requires import requires
from .base_cpu_core import BaseCPUCore
from .cpu_types import CPUTypes
from ...isas import ISA
from ...utils.requires import requires
from ...runtime import get_runtime_isa
import importlib
import platform
class SimpleCore(BaseCPUCore):
"""
A SimpleCore instantiates a core based on the CPUType enum pass. The
SimpleCore creates a single SimObject of that type.
"""
def __init__(
self, cpu_type: CPUTypes, core_id: int, isa: Optional[ISA] = None
):
# If the ISA is not specified, we infer it via the `get_runtime_isa`
# function.
if isa:
requires(isa_required=isa)
isa = isa
else:
isa = get_runtime_isa()
super().__init__(
core=SimpleCore.cpu_simobject_factory(
isa=isa, cpu_type=cpu_type, core_id=core_id
),
isa=isa,
)
self._cpu_type = cpu_type
def get_type(self) -> CPUTypes:
return self._cpu_type
@classmethod
def cpu_simobject_factory(cls, cpu_type: CPUTypes, isa: ISA, core_id: int):
"""
A factory used to return the SimObject core object given the cpu type,
and ISA target. An exception will be thrown if there is an
incompatibility.
:param cpu_type: The target CPU type.
:param isa: The target ISA.
:param core_id: The id of the core to be returned.
"""
assert isa is not None
requires(isa_required=isa)
_isa_string_map = {
ISA.X86: "X86",
ISA.ARM: "Arm",
ISA.RISCV: "Riscv",
ISA.SPARC: "Sparc",
ISA.POWER: "Power",
ISA.MIPS: "Mips",
}
_cpu_types_string_map = {
CPUTypes.ATOMIC: "AtomicSimpleCPU",
CPUTypes.O3: "O3CPU",
CPUTypes.TIMING: "TimingSimpleCPU",
CPUTypes.KVM: "KvmCPU",
CPUTypes.MINOR: "MinorCPU",
}
if isa not in _isa_string_map:
raise NotImplementedError(
f"ISA '{isa.name}' does not have an"
"entry in `AbstractCore.cpu_simobject_factory._isa_string_map`"
)
if cpu_type not in _cpu_types_string_map:
raise NotImplementedError(
f"CPUType '{cpu_type.name}' "
"does not have an entry in "
"`AbstractCore.cpu_simobject_factory._cpu_types_string_map`"
)
if cpu_type == CPUTypes.KVM:
# For some reason, the KVM CPU is under "m5.objects" not the
# "m5.objects.{ISA}CPU".
module_str = f"m5.objects"
else:
module_str = f"m5.objects.{_isa_string_map[isa]}CPU"
# GEM5 compiles two versions of KVM for ARM depending upon the host CPU
# : ArmKvmCPU and ArmV8KvmCPU for 32 bit (Armv7l) and 64 bit (Armv8)
# respectively.
if (
isa.name == "ARM"
and cpu_type == CPUTypes.KVM
and platform.architecture()[0] == "64bit"
):
cpu_class_str = (
f"{_isa_string_map[isa]}V8"
f"{_cpu_types_string_map[cpu_type]}"
)
else:
cpu_class_str = (
f"{_isa_string_map[isa]}" f"{_cpu_types_string_map[cpu_type]}"
)
try:
to_return_cls = getattr(
importlib.import_module(module_str), cpu_class_str
)
except ImportError:
raise Exception(
f"Cannot find CPU type '{cpu_type.name}' for '{isa.name}' "
"ISA. Please ensure you have compiled the correct version of "
"gem5."
)
return to_return_cls(cpu_id=core_id)