| # Copyright (c) 2020 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 2019 Google, Inc. |
| # |
| # 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 m5.params import * |
| from m5.util.fdthelper import * |
| from m5.SimObject import SimObject |
| |
| from m5.objects.FastModel import AmbaInitiatorSocket, AmbaTargetSocket |
| from m5.objects.Gic import BaseGic |
| from m5.objects.IntPin import VectorIntSourcePin |
| from m5.objects.SystemC import SystemC_ScModule |
| |
| GICV3_COMMS_TARGET_ROLE = "GICV3 COMMS TARGET" |
| GICV3_COMMS_INITIATOR_ROLE = "GICV3 COMMS INITIATOR" |
| |
| Port.compat(GICV3_COMMS_TARGET_ROLE, GICV3_COMMS_INITIATOR_ROLE) |
| |
| |
| class Gicv3CommsTargetSocket(Port): |
| def __init__(self, desc): |
| super().__init__(GICV3_COMMS_INITIATOR_ROLE, desc) |
| |
| |
| class Gicv3CommsInitiatorSocket(Port): |
| def __init__(self, desc): |
| super().__init__(GICV3_COMMS_TARGET_ROLE, desc, is_source=True) |
| |
| |
| class VectorGicv3CommsInitiatorSocket(VectorPort): |
| def __init__(self, desc): |
| super().__init__(GICV3_COMMS_TARGET_ROLE, desc, is_source=True) |
| |
| |
| class SCFastModelGIC(SystemC_ScModule): |
| type = "SCFastModelGIC" |
| cxx_class = "gem5::fastmodel::SCGIC" |
| cxx_header = "arch/arm/fastmodel/GIC/gic.hh" |
| |
| enabled = Param.Bool( |
| True, |
| "Enable GICv3 functionality; when false the " |
| "component is inactive. has_gicv3 will replace this when GIC_IRI " |
| "replaces GICv3IRI.", |
| ) |
| has_gicv3 = Param.Bool( |
| False, |
| "Enable GICv3 functionality; when false " |
| 'the component is inactive. This will replace "enabled" ' |
| "parameter.", |
| ) |
| has_gicv4_1 = Param.Bool( |
| False, |
| "Enable GICv4.1 functionality; when " |
| "false the component is inactive.", |
| ) |
| vPEID_bits = Param.Unsigned(16, "Number of bits of vPEID with GICv4.1.") |
| print_mmap = Param.Bool(False, "Print memory map to stdout") |
| monolithic = Param.Bool( |
| False, "Indicate that the implementation is not " "distributed" |
| ) |
| direct_lpi_support = Param.Bool( |
| False, "Enable support for LPI " "operations through GICR registers" |
| ) |
| cpu_affinities = Param.String( |
| "", |
| "A comma separated list of dotted quads " |
| "containing the affinities of all PEs connected to this IRI.", |
| ) |
| non_ARE_core_count = Param.Unsigned( |
| 8, |
| "Maximum number of non-ARE cores; " |
| "normally used to pass the cluster-level NUM_CORES parameter to " |
| "the top-level redistributor.", |
| ) |
| reg_base = Param.Addr(0x2C010000, "Base for decoding GICv3 registers.") |
| reg_base_per_redistributor = Param.String( |
| "", |
| "Base address for each " |
| "redistributor in the form " |
| "'0.0.0.0=0x2c010000, 0.0.0.1=0x2c020000'. All redistributors " |
| "must be specified and this overrides the reg-base parameter " |
| "(except that reg-base will still be used for the top-level " |
| "redistributor).", |
| ) |
| gicd_alias = Param.Addr( |
| 0x0, |
| "In GICv2 mode: the base address for a 4k " |
| "page alias of the first 4k of the Distributor page, in GICv3 " |
| "mode. the base address of a 64KB page containing message based " |
| "SPI signalling register aliases(0:Disabled)", |
| ) |
| has_two_security_states = Param.Bool( |
| True, "If true, has two security " "states" |
| ) |
| DS_fixed_to_zero = Param.Bool( |
| False, "Enable/disable support of single " "security state" |
| ) |
| IIDR = Param.UInt32(0x0, "GICD_IIDR and GICR_IIDR value") |
| gicv2_only = Param.Bool( |
| False, |
| "If true, when using the GICv3 model, " "pretend to be a GICv2 system", |
| ) |
| STATUSR_implemented = Param.Bool( |
| True, "Determines whether the " "GICR_STATUSR register is implemented." |
| ) |
| priority_bits_implemented = Param.Unsigned( |
| 5, "Number of implemented " "priority bits" |
| ) |
| itargets_razwi = Param.Bool( |
| False, "If true, the GICD_ITARGETS registers " "are RAZ/WI" |
| ) |
| icfgr_sgi_mask = Param.UInt32( |
| 0x0, "Mask for writes to ICFGR registers " "that configure SGIs" |
| ) |
| icfgr_ppi_mask = Param.UInt32( |
| 0xAAAAAAAA, "Mask for writes to ICFGR " "registers that configure PPIs" |
| ) |
| icfgr_spi_mask = Param.UInt32( |
| 0xAAAAAAAA, "Mask for writes to ICFGR " "registers that configure SPIs" |
| ) |
| icfgr_sgi_reset = Param.UInt32( |
| 0xAAAAAAAA, "Reset value for ICFGR " "registers that configure SGIs" |
| ) |
| icfgr_ppi_reset = Param.UInt32( |
| 0x0, "Reset value for ICFGR regesters " "that configure PPIs" |
| ) |
| icfgr_spi_reset = Param.UInt32( |
| 0x0, "Reset value for ICFGR regesters " "that configure SPIs" |
| ) |
| icfgr_ppi_rsvd_bit = Param.Bool( |
| False, |
| "If ARE=0, the value of reserved " |
| "bits i.e. bit 0,2,4..30 of ICFGRn for n>0", |
| ) |
| igroup_sgi_mask = Param.UInt16( |
| 0xFFFF, "Mask for writes to SGI bits in " "IGROUP registers" |
| ) |
| igroup_ppi_mask = Param.UInt16( |
| 0xFFFF, "Mask for writes to PPI bits in " "IGROUP registers" |
| ) |
| igroup_sgi_reset = Param.UInt16( |
| 0x0, "Reset value for SGI bits in IGROUP " "registers" |
| ) |
| igroup_ppi_reset = Param.UInt16( |
| 0x0, "Reset value for SGI bits in IGROUP " "registers" |
| ) |
| ppi_implemented_mask = Param.UInt16( |
| 0xFFFF, |
| "Mask of PPIs that are " |
| "implemented. One bit per PPI bit 0 == PPI 16 (first PPI). This " |
| "will affect other masks.", |
| ) |
| spi_count = Param.UInt16(224, "Number of SPIs that are implemented.") |
| lockable_spi_count = Param.Unsigned( |
| 0, |
| "Number of SPIs that are locked " |
| "down when CFGSDISABLE signal is asserted. Only applies for " |
| "GICv2.", |
| ) |
| iri_id_bits = Param.Unsigned( |
| 16, |
| "Number of bits used to represent " |
| "interrupts IDs in the Distributor and Redistributors, forced to " |
| "10 if LPIs are not supported", |
| ) |
| delay_redistributor_accesses = Param.Bool( |
| True, |
| "Delay memory accesses " |
| "from the redistributor until GICR_SYNCR is read.", |
| ) |
| gicd_pidr = Param.UInt64( |
| 0x0, |
| "The value for the GICD_PIDR registers, if " |
| "non-zero. Note: fixed fields (device type etc.) will be " |
| "overriden in this value.", |
| ) |
| gicr_pidr = Param.UInt64( |
| 0x0, |
| "The value for the GICR_PIDR registers, if " |
| "non-zero. Note: fixed fields (device type etc.) will be " |
| "overriden in this value.", |
| ) |
| its_count = Param.Unsigned( |
| 0, |
| "Number of Interrupt Translation Services " |
| "to be instantiated (0=none)", |
| ) |
| its0_base = Param.Addr( |
| 0, "Register base address for ITS0 " "(automatic if 0)." |
| ) |
| its1_base = Param.Addr( |
| 0, "Register base address for ITS1 " "(automatic if 0)." |
| ) |
| its2_base = Param.Addr( |
| 0, "Register base address for ITS2 " "(automatic if 0)." |
| ) |
| its3_base = Param.Addr( |
| 0, "Register base address for ITS3 " "(automatic if 0)." |
| ) |
| gits_pidr = Param.UInt64( |
| 0x0, |
| "The value for the GITS_PIDR registers, if " |
| "non-zero. Note: fixed fields (device type etc.) will be " |
| "overriden in this value.", |
| ) |
| gits_baser0_type = Param.Unsigned( |
| 0, |
| "Type field for GITS_BASER0 " |
| "register. 0 = Unimplemented; 1 = Devices; " |
| "2 = Virtual Processors; 3 = Physical Processors; 4 = Collections", |
| ) |
| gits_baser1_type = Param.Unsigned( |
| 0, |
| "Type field for GITS_BASER1 " |
| "register. 0 = Unimplemented; 1 = Devices; " |
| "2 = Virtual Processors; 3 = Physical Processors; 4 = Collections", |
| ) |
| gits_baser2_type = Param.Unsigned( |
| 0, |
| "Type field for GITS_BASER2 " |
| "register. 0 = Unimplemented; 1 = Devices; " |
| "2 = Virtual Processors; 3 = Physical Processors; 4 = Collections", |
| ) |
| gits_baser3_type = Param.Unsigned( |
| 0, |
| "Type field for GITS_BASER3 " |
| "register. 0 = Unimplemented; 1 = Devices; " |
| "2 = Virtual Processors; 3 = Physical Processors; 4 = Collections", |
| ) |
| gits_baser4_type = Param.Unsigned( |
| 0, |
| "Type field for GITS_BASER4 " |
| "register. 0 = Unimplemented; 1 = Devices; " |
| "2 = Virtual Processors; 3 = Physical Processors; 4 = Collections", |
| ) |
| gits_baser5_type = Param.Unsigned( |
| 0, |
| "Type field for GITS_BASER5 " |
| "register. 0 = Unimplemented; 1 = Devices; " |
| "2 = Virtual Processors; 3 = Physical Processors; 4 = Collections", |
| ) |
| gits_baser6_type = Param.Unsigned( |
| 0, |
| "Type field for GITS_BASER6 " |
| "register. 0 = Unimplemented; 1 = Devices; " |
| "2 = Virtual Processors; 3 = Physical Processors; 4 = Collections", |
| ) |
| gits_baser7_type = Param.Unsigned( |
| 0, |
| "Type field for GITS_BASER7 " |
| "register. 0 = Unimplemented; 1 = Devices; " |
| "2 = Virtual Processors; 3 = Physical Processors; 4 = Collections", |
| ) |
| gits_baser0_entry_bytes = Param.Unsigned( |
| 8, "Number of bytes required per " "entry for GITS_BASER0 register." |
| ) |
| gits_baser1_entry_bytes = Param.Unsigned( |
| 8, "Number of bytes required per " "entry for GITS_BASER1 register." |
| ) |
| gits_baser2_entry_bytes = Param.Unsigned( |
| 8, "Number of bytes required per " "entry for GITS_BASER2 register." |
| ) |
| gits_baser3_entry_bytes = Param.Unsigned( |
| 8, "Number of bytes required per " "entry for GITS_BASER3 register." |
| ) |
| gits_baser4_entry_bytes = Param.Unsigned( |
| 8, "Number of bytes required per " "entry for GITS_BASER4 register." |
| ) |
| gits_baser5_entry_bytes = Param.Unsigned( |
| 8, "Number of bytes required per " "entry for GITS_BASER5 register." |
| ) |
| gits_baser6_entry_bytes = Param.Unsigned( |
| 8, "Number of bytes required per " "entry for GITS_BASER6 register." |
| ) |
| gits_baser7_entry_bytes = Param.Unsigned( |
| 8, "Number of bytes required per " "entry for GITS_BASER7 register." |
| ) |
| gits_baser0_indirect_raz = Param.Bool( |
| False, "Indirect field for " "GITS_BASER0 register is RAZ/WI." |
| ) |
| gits_baser1_indirect_raz = Param.Bool( |
| False, "Indirect field for " "GITS_BASER1 register is RAZ/WI." |
| ) |
| gits_baser2_indirect_raz = Param.Bool( |
| False, "Indirect field for " "GITS_BASER2 register is RAZ/WI." |
| ) |
| gits_baser3_indirect_raz = Param.Bool( |
| False, "Indirect field for " "GITS_BASER3 register is RAZ/WI." |
| ) |
| gits_baser4_indirect_raz = Param.Bool( |
| False, "Indirect field for " "GITS_BASER4 register is RAZ/WI." |
| ) |
| gits_baser5_indirect_raz = Param.Bool( |
| False, "Indirect field for " "GITS_BASER5 register is RAZ/WI." |
| ) |
| gits_baser6_indirect_raz = Param.Bool( |
| False, "Indirect field for " "GITS_BASER6 register is RAZ/WI." |
| ) |
| gits_baser7_indirect_raz = Param.Bool( |
| False, "Indirect field for " "GITS_BASER7 register is RAZ/WI." |
| ) |
| its_baser_force_page_alignement = Param.Bool( |
| True, |
| "Force alignement of " |
| "address writen to a GITS_BASER register to the page size " |
| "configured", |
| ) |
| processor_numbers = Param.String( |
| "", |
| "Specify processor numbers (as " |
| "appears in GICR_TYPER) in the form 0.0.0.0=0,0.0.0.1=1 etc.) If " |
| "not specified, will number processors starting at 0.", |
| ) |
| supports_shareability = Param.Bool( |
| True, |
| "Device supports shareability " |
| "attributes on outgoing memory bus (i.e. is modelling an ACElite " |
| "port rather than an AXI4 port).", |
| ) |
| a3_affinity_supported = Param.Bool( |
| False, "Device supports affinity " "level 3 values that are non-zero." |
| ) |
| SGI_RSS_support = Param.Bool( |
| False, "Device has support for the Range " "Selector feature for SGI" |
| ) |
| gicr_propbaser_read_only = Param.Bool( |
| False, "GICR_PROPBASER register is " "read-only." |
| ) |
| gicr_propbaser_reset = Param.UInt64( |
| 0x0, "Value of GICR_PROPBASER on " "reset." |
| ) |
| its_device_bits = Param.Unsigned( |
| 16, "Number of bits supported for ITS " "device IDs." |
| ) |
| its_entry_size = Param.Unsigned( |
| 8, "Number of bytes required to store " "each entry in the ITT tables." |
| ) |
| its_id_bits = Param.Unsigned( |
| 16, "Number of interrupt bits supported by " "ITS." |
| ) |
| its_collection_id_bits = Param.Unsigned( |
| 0, |
| "Number of collection bits " |
| "supported by ITS (optional parameter, 0 => 16bits support and " |
| "GITS_TYPER.CIL=0", |
| ) |
| its_cumulative_collection_tables = Param.Bool( |
| True, |
| "When true, the " |
| "supported amount of collections is the sum of GITS_TYPER.HCC and " |
| "the number of collections supported in memory, otherwise, simply " |
| "the number supported in memory only. Irrelevant when HCC=0", |
| ) |
| delay_ITS_accesses = Param.Bool( |
| True, "Delay accesses from the ITS until " "GICR_SYNCR is read." |
| ) |
| local_SEIs = Param.Bool(False, "Generate SEI to signal internal issues") |
| local_VSEIs = Param.Bool(False, "Generate VSEI to signal internal issues") |
| ITS_use_physical_target_addresses = Param.Bool( |
| True, |
| "Use physical " |
| "hardware adresses for targets in ITS commands -- must be true " |
| "for distributed implementations", |
| ) |
| ITS_hardware_collection_count = Param.Unsigned( |
| 0, "Number of hardware " "collections held exclusively in the ITS" |
| ) |
| ITS_MOVALL_update_collections = Param.Bool( |
| False, "Whether MOVALL command " "updates the collection entires" |
| ) |
| ITS_TRANSLATE64R = Param.Bool( |
| False, |
| "Add an implementation specific " |
| "register at 0x10008 supporting 64 bit TRANSLATER (dev[63:32], " |
| "interupt[31:0])", |
| ) |
| enable_protocol_checking = Param.Bool( |
| False, "Enable/disable protocol " "checking at cpu interface" |
| ) |
| fixed_routed_spis = Param.String( |
| "", |
| "Value of IROUTER[n] register in the " |
| "form 'n=a.b.c.d, n=*'. The RM bit of IROUTER is 0 when n=a.b.c.d " |
| "is used else 1 when n=* is used. n can be >= 32 and <= 1019", |
| ) |
| irouter_default_mask = Param.String( |
| "", |
| "Default Mask value for " |
| "IROUTER[32..1019] register in the form 'a.b.c.d'", |
| ) |
| irouter_default_reset = Param.String( |
| "", |
| "Default Reset Value of " |
| "IROUTER[32..1019] register in the form 'a.b.c.d' or *", |
| ) |
| irouter_reset_values = Param.String( |
| "", |
| "Reset Value of IROUTER[n] " |
| "register in the form 'n=a.b.c.d or n=*'.n can be >= 32 and " |
| "<= 1019", |
| ) |
| irouter_mask_values = Param.String( |
| "", |
| "Mask Value of IROUTER[n] register " |
| "in the form 'n=a.b.c.d'.n can be >= 32 and <= 1019", |
| ) |
| ITS_threaded_command_queue = Param.Bool( |
| True, |
| "Enable execution of ITS " |
| "commands in a separate thread which is sometimes required for " |
| "cosimulation", |
| ) |
| ITS_legacy_iidr_typer_offset = Param.Bool( |
| False, |
| "Put the GITS_IIDR and " |
| "GITS_TYPER registers at their older offset of 0x8 and 0x4 " |
| "respectively", |
| ) |
| redistributor_threaded_command_queue = Param.Bool( |
| True, |
| "Enable execution " |
| "of redistributor delayed transactions in a separate thread which " |
| "is sometimes required for cosimulation", |
| ) |
| ignore_generate_sgi_when_no_are = Param.Bool( |
| False, |
| "Ignore GenerateSGI " |
| "packets coming form the CPU interface if both ARE_S and ARE_NS " |
| "are 0", |
| ) |
| trace_speculative_lpi_property_updates = Param.Bool( |
| False, |
| "Trace LPI " |
| "propery updates performed on speculative accesses (useful for " |
| "debuging LPI)", |
| ) |
| virtual_lpi_support = Param.Bool( |
| False, |
| "GICv4 Virtual LPIs and Direct " "injection of Virtual LPIs supported", |
| ) |
| virtual_priority_bits = Param.Unsigned( |
| 5, "Number of implemented virtual " "priority bits" |
| ) |
| LPI_cache_type = Param.Unsigned( |
| 1, "Cache type for LPIs, 0:No caching, " "1:Full caching" |
| ) |
| LPI_cache_check_data = Param.Bool( |
| False, |
| "Enable Cached LPI data against " |
| "memory checking when available for cache type", |
| ) |
| DPG_bits_implemented = Param.Bool( |
| False, |
| "Enable implementation of " |
| "interrupt group participation bits or DPG bits in GICR_CTLR", |
| ) |
| DPG_ARE_only = Param.Bool( |
| False, |
| "Limit application of DPG bits to " "interrupt groups for which ARE=1", |
| ) |
| ARE_fixed_to_one = Param.Bool( |
| False, |
| "GICv2 compatibility is not " |
| "supported and GICD_CTLR.ARE_* is always one", |
| ) |
| legacy_sgi_enable_rao = Param.Bool( |
| False, "Enables for SGI associated " "with an ARE=0 regime are RAO/WI" |
| ) |
| pa_size = Param.Unsigned(48, "Number of valid bits in physical address") |
| MSI_IIDR = Param.UInt32(0x0, "Value returned in MSI_IIDR registers.") |
| MSI_NS_frame0_base = Param.Addr( |
| 0x0, |
| "If non-zero, sets the base " |
| "address used for non-secure MSI frame 0 registers.", |
| ) |
| MSI_NS_frame0_max_SPI = Param.UInt16( |
| 0, |
| "Maximum SPI ID supported by " |
| "non-secure MSI frame 0. Set to 0 to disable frame.", |
| ) |
| MSI_NS_frame0_min_SPI = Param.UInt16( |
| 0, |
| "Minimum SPI ID supported by " |
| "non-secure MSI frame 0. Set to 0 to disable frame.", |
| ) |
| MSI_NS_frame1_base = Param.Addr( |
| 0x0, |
| "If non-zero, sets the base " |
| "address used for non-secure MSI frame 1 registers.", |
| ) |
| MSI_NS_frame1_max_SPI = Param.UInt16( |
| 0, |
| "Maximum SPI ID supported by " |
| "non-secure MSI frame 1. Set to 0 to disable frame.", |
| ) |
| MSI_NS_frame1_min_SPI = Param.UInt16( |
| 0, |
| "Minimum SPI ID supported by " |
| "non-secure MSI frame 1. Set to 0 to disable frame.", |
| ) |
| MSI_NS_frame2_base = Param.Addr( |
| 0x0, |
| "If non-zero, sets the base address " |
| "used for non-secure MSI frame 2 registers.", |
| ) |
| MSI_NS_frame2_max_SPI = Param.UInt16( |
| 0, |
| "Maximum SPI ID supported by " |
| "non-secure MSI frame 2. Set to 0 to disable frame.", |
| ) |
| MSI_NS_frame2_min_SPI = Param.UInt16( |
| 0, |
| "Minimum SPI ID supported by " |
| "non-secure MSI frame 2. Set to 0 to disable frame.", |
| ) |
| MSI_NS_frame3_base = Param.Addr( |
| 0x0, |
| "If non-zero, sets the base address " |
| "used for non-secure MSI frame 3 registers.", |
| ) |
| MSI_NS_frame3_max_SPI = Param.UInt16( |
| 0, |
| "Maximum SPI ID supported by " |
| "non-secure MSI frame 3. Set to 0 to disable frame.", |
| ) |
| MSI_NS_frame3_min_SPI = Param.UInt16( |
| 0, |
| "Minimum SPI ID supported by " |
| "non-secure MSI frame 3. Set to 0 to disable frame.", |
| ) |
| MSI_NS_frame4_base = Param.Addr( |
| 0x0, |
| "If non-zero, sets the base address " |
| "used for non-secure MSI frame 4 registers.", |
| ) |
| MSI_NS_frame4_max_SPI = Param.UInt16( |
| 0, |
| "Maximum SPI ID supported by " |
| "non-secure MSI frame 4. Set to 0 to disable frame.", |
| ) |
| MSI_NS_frame4_min_SPI = Param.UInt16( |
| 0, |
| "Minimum SPI ID supported by " |
| "non-secure MSI frame 4. Set to 0 to disable frame.", |
| ) |
| MSI_NS_frame5_base = Param.Addr( |
| 0x0, |
| "If non-zero, sets the base address " |
| "used for non-secure MSI frame 5 registers.", |
| ) |
| MSI_NS_frame5_max_SPI = Param.UInt16( |
| 0, |
| "Maximum SPI ID supported by " |
| "non-secure MSI frame 5. Set to 0 to disable frame.", |
| ) |
| MSI_NS_frame5_min_SPI = Param.UInt16( |
| 0, |
| "Minimum SPI ID supported by " |
| "non-secure MSI frame 5. Set to 0 to disable frame.", |
| ) |
| MSI_NS_frame6_base = Param.Addr( |
| 0x0, |
| "If non-zero, sets the base address " |
| "used for non-secure MSI frame 6 registers.", |
| ) |
| MSI_NS_frame6_max_SPI = Param.UInt16( |
| 0, |
| "Maximum SPI ID supported by " |
| "non-secure MSI frame 6. Set to 0 to disable frame.", |
| ) |
| MSI_NS_frame6_min_SPI = Param.UInt16( |
| 0, |
| "Minimum SPI ID supported by " |
| "non-secure MSI frame 6. Set to 0 to disable frame.", |
| ) |
| MSI_NS_frame7_base = Param.Addr( |
| 0x0, |
| "If non-zero, sets the base address " |
| "used for non-secure MSI frame 7 registers.", |
| ) |
| MSI_NS_frame7_max_SPI = Param.UInt16( |
| 0, |
| "Maximum SPI ID supported by " |
| "non-secure MSI frame 7. Set to 0 to disable frame.", |
| ) |
| MSI_NS_frame7_min_SPI = Param.UInt16( |
| 0, |
| "Minimum SPI ID supported by " |
| "non-secure MSI frame 7. Set to 0 to disable frame.", |
| ) |
| MSI_PIDR = Param.UInt64( |
| 0x0, |
| "The value for the MSI_PIDR registers, if " |
| "non-zero and distributor supports GICv2m. Note: fixed fields " |
| "(device type etc.) will be overriden in this value.", |
| ) |
| MSI_S_frame0_base = Param.Addr( |
| 0x0, |
| "If non-zero, sets the base address " |
| "used for secure MSI frame 0 registers.", |
| ) |
| MSI_S_frame0_max_SPI = Param.UInt16( |
| 0, |
| "Maximum SPI ID supported by " |
| "secure MSI frame 0. Set to 0 to disable frame.", |
| ) |
| MSI_S_frame0_min_SPI = Param.UInt16( |
| 0, |
| "Minimum SPI ID supported by " |
| "secure MSI frame 0. Set to 0 to disable frame.", |
| ) |
| MSI_S_frame1_base = Param.Addr( |
| 0x0, |
| "If non-zero, sets the base address " |
| "used for secure MSI frame 1 registers.", |
| ) |
| MSI_S_frame1_max_SPI = Param.UInt16( |
| 0, |
| "Maximum SPI ID supported by " |
| "secure MSI frame 1. Set to 0 to disable frame.", |
| ) |
| MSI_S_frame1_min_SPI = Param.UInt16( |
| 0, |
| "Minimum SPI ID supported by " |
| "secure MSI frame 1. Set to 0 to disable frame.", |
| ) |
| MSI_S_frame2_base = Param.Addr( |
| 0x0, |
| "If non-zero, sets the base address " |
| "used for secure MSI frame 2 registers.", |
| ) |
| MSI_S_frame2_max_SPI = Param.UInt16( |
| 0, |
| "Maximum SPI ID supported by " |
| "secure MSI frame 2. Set to 0 to disable frame.", |
| ) |
| MSI_S_frame2_min_SPI = Param.UInt16( |
| 0, |
| "Minimum SPI ID supported by " |
| "secure MSI frame 2. Set to 0 to disable frame.", |
| ) |
| MSI_S_frame3_base = Param.Addr( |
| 0x0, |
| "If non-zero, sets the base address " |
| "used for secure MSI frame 3 registers.", |
| ) |
| MSI_S_frame3_max_SPI = Param.UInt16( |
| 0, |
| "Maximum SPI ID supported by " |
| "secure MSI frame 3. Set to 0 to disable frame.", |
| ) |
| MSI_S_frame3_min_SPI = Param.UInt16( |
| 0, |
| "Minimum SPI ID supported by " |
| "secure MSI frame 3. Set to 0 to disable frame.", |
| ) |
| MSI_S_frame4_base = Param.Addr( |
| 0x0, |
| "If non-zero, sets the base address " |
| "used for secure MSI frame 4 registers.", |
| ) |
| MSI_S_frame4_max_SPI = Param.UInt16( |
| 0, |
| "Maximum SPI ID supported by " |
| "secure MSI frame 4. Set to 0 to disable frame.", |
| ) |
| MSI_S_frame4_min_SPI = Param.UInt16( |
| 0, |
| "Minimum SPI ID supported by " |
| "secure MSI frame 4. Set to 0 to disable frame.", |
| ) |
| MSI_S_frame5_base = Param.Addr( |
| 0x0, |
| "If non-zero, sets the base address " |
| "used for secure MSI frame 5 registers.", |
| ) |
| MSI_S_frame5_max_SPI = Param.UInt16( |
| 0, |
| "Maximum SPI ID supported by " |
| "secure MSI frame 5. Set to 0 to disable frame.", |
| ) |
| MSI_S_frame5_min_SPI = Param.UInt16( |
| 0, |
| "Minimum SPI ID supported by " |
| "secure MSI frame 5. Set to 0 to disable frame.", |
| ) |
| MSI_S_frame6_base = Param.Addr( |
| 0x0, |
| "If non-zero, sets the base address " |
| "used for secure MSI frame 6 registers.", |
| ) |
| MSI_S_frame6_max_SPI = Param.UInt16( |
| 0, |
| "Maximum SPI ID supported by " |
| "secure MSI frame 6. Set to 0 to disable frame.", |
| ) |
| MSI_S_frame6_min_SPI = Param.UInt16( |
| 0, |
| "Minimum SPI ID supported by " |
| "secure MSI frame 6. Set to 0 to disable frame.", |
| ) |
| MSI_S_frame7_base = Param.Addr( |
| 0x0, |
| "If non-zero, sets the base address " |
| "used for secure MSI frame 7 registers.", |
| ) |
| MSI_S_frame7_max_SPI = Param.UInt16( |
| 0, |
| "Maximum SPI ID supported by " |
| "secure MSI frame 7. Set to 0 to disable frame.", |
| ) |
| MSI_S_frame7_min_SPI = Param.UInt16( |
| 0, |
| "Minimum SPI ID supported by " |
| "secure MSI frame 7. Set to 0 to disable frame.", |
| ) |
| outer_cacheability_support = Param.Bool( |
| False, |
| "Allow configuration of " |
| "outer cachability attributes in ITS and Redistributor", |
| ) |
| wakeup_on_reset = Param.Bool( |
| False, |
| "Go against specification and start " |
| "redistributors in woken-up state at reset. This allows software " |
| "that was written for previous versions of the GICv3 " |
| "specification to work correctly. This should not be used for " |
| "production code or when the distributor is used separately from " |
| "the core fast model.", |
| ) |
| SPI_MBIS = Param.Bool( |
| True, "Distributor supports meassage based " "signaling of SPI" |
| ) |
| SPI_unimplemented = Param.String( |
| "", |
| "A comma spearated list of " |
| "unimplemented SPIs ranges for sparse SPI defintion(for ex: " |
| "'35, 39-42, 73)'", |
| ) |
| irm_razwi = Param.Bool( |
| False, "GICD_IROUTERn.InterruptRoutingMode is " "RAZ/WI" |
| ) |
| common_LPI_configuration = Param.Unsigned( |
| 0, |
| "Describes which " |
| "re-distributors share (and must be configured with the same) " |
| "LPI configuration table as described in GICR_TYPER( 0:All, " |
| "1:A.x.x.x, 2:A.B.x.x, 3:A.B.C.x", |
| ) |
| single_set_support = Param.Bool( |
| False, |
| "When true, forces redistributors " |
| "to recall interrupts with a clear rather than issue a second Set " |
| "command", |
| ) |
| has_mpam = Param.Unsigned( |
| 0, |
| "Implement ARMv8.4 MPAM Registers and " |
| "associated functionality.\n\nPossible values of this parameter " |
| "are:\n - 0, feature is not enabled.\n - 1, feature is " |
| "implemented if ARMv8.4 is enabled.\n - 2, feature is " |
| "implemented.", |
| ) |
| mpam_max_partid = Param.UInt16(0xFFFF, "MPAM Maximum PARTID Supported") |
| mpam_max_pmg = Param.Unsigned(255, "MPAM Maximum PMG Supported") |
| output_attributes = Param.String( |
| "ExtendedID[62:55]=MPAM_PMG, " |
| "ExtendedID[54:39]=MPAM_PARTID, ExtendedID[38]=MPAM_NS", |
| "User-defined transform to be applied to bus attributes like " |
| "RequestorID, ExtendedID or UserFlags. Currently, only works for " |
| "MPAM Attributes encoding into bus attributes.", |
| ) |
| has_DirtyVLPIOnLoad = Param.Bool( |
| False, |
| "GICR_VPENDBASER.Dirty reflects " |
| "transient loading state when valid=1", |
| ) |
| allow_LPIEN_clear = Param.Bool( |
| False, "Allow RW behaviour on " "GICR_CTLR.LPIEN isntead of set once" |
| ) |
| GICD_legacy_reg_reserved = Param.Bool( |
| False, |
| "When ARE is RAO/WI, makes " |
| "superfluous registers in GICD reserved (including for the " |
| "purpose of STATUSR updates)", |
| ) |
| extended_spi_count = Param.Unsigned(0, "Number of extended SPI supported") |
| extended_ppi_count = Param.Unsigned(0, "Number of extended PPI supported") |
| consolidators = Param.String( |
| "", |
| "Specify consolidators' base addresses, " |
| "interrupt line counts and base interrupt IDs, in the form " |
| "'baseAddr0:itlineCount0:baseINTID0, " |
| "baseAddr1:itlineCount1:baseINTID1, [etc]' " |
| "(eg '0x3f100000:64:4096, 0x3f200000:64:4224'). The " |
| "consolidators' count is inferred from the list (maximum of 4). " |
| "If not specified, the component contains no consolidators.", |
| ) |
| |
| |
| class FastModelGIC(BaseGic): |
| type = "FastModelGIC" |
| cxx_class = "gem5::fastmodel::GIC" |
| cxx_header = "arch/arm/fastmodel/GIC/gic.hh" |
| |
| sc_gic = Param.SCFastModelGIC( |
| SCFastModelGIC(), "SystemC version of the GIC" |
| ) |
| |
| amba_m = AmbaInitiatorSocket(64, "Memory initiator socket") |
| amba_s = AmbaTargetSocket(64, "Memory target socket") |
| |
| redistributor = VectorGicv3CommsInitiatorSocket( |
| "GIC communication initiator" |
| ) |
| |
| wake_request = VectorIntSourcePin("GIC wake request initiator") |
| |
| # Used for DTB autogeneration |
| _state = FdtState(addr_cells=2, size_cells=2, interrupt_cells=3) |
| |
| def get_redist_bases(self): |
| """ |
| The format of reg_base_per_redistributor is |
| '0.0.0.0=0x2c010000,0.0.0.1=0x2c020000...' |
| Return an array of base addresses |
| """ |
| redists = self.sc_gic.reg_base_per_redistributor.split(",") |
| # make sure we have at least one redistributor |
| assert len(redists) > 0 and "=" in redists[0] |
| return [int(r.split("=")[1], 16) for r in redists] |
| |
| def get_addr_ranges(self): |
| """Return address ranges that should be served by this GIC""" |
| sc_gic = self.sc_gic |
| gic_frame_size = 0x10000 |
| # Add range of distributor |
| ranges = [AddrRange(sc_gic.reg_base, size=gic_frame_size)] |
| # Add ranges of redistributors |
| redist_frame_size = gic_frame_size * (4 if sc_gic.has_gicv4_1 else 2) |
| ranges += [ |
| AddrRange(redist_base, size=redist_frame_size) |
| for redist_base in self.get_redist_bases() |
| ] |
| # Add ranges of ITSs |
| its_bases = [ |
| sc_gic.its0_base, |
| sc_gic.its1_base, |
| sc_gic.its2_base, |
| sc_gic.its3_base, |
| ] |
| ranges += [ |
| AddrRange(its_bases[i], size=2 * gic_frame_size) |
| for i in range(sc_gic.its_count) |
| ] |
| |
| return ranges |
| |
| def interruptCells(self, int_type, int_num, int_trigger, int_affinity=0): |
| """ |
| Interupt cells generation helper: |
| Following specifications described in |
| |
| Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.txt |
| """ |
| prop = self._state.interruptCells(0) |
| assert len(prop) >= 3 |
| prop[0] = int_type |
| prop[1] = int_num |
| prop[2] = int_trigger |
| return prop |
| |
| def generateDeviceTree(self, state): |
| sc_gic = self.sc_gic |
| |
| node = FdtNode("interrupt-controller") |
| node.appendCompatible(["arm,gic-v3"]) |
| node.append(self._state.interruptCellsProperty()) |
| node.append(self._state.addrCellsProperty()) |
| node.append(self._state.sizeCellsProperty()) |
| node.append(FdtProperty("ranges")) |
| node.append(FdtProperty("interrupt-controller")) |
| |
| redist_stride = 0x40000 if sc_gic.has_gicv4_1 else 0x20000 |
| node.append( |
| FdtPropertyWords( |
| "redistributor-stride", state.sizeCells(redist_stride) |
| ) |
| ) |
| |
| regs = ( |
| state.addrCells(sc_gic.reg_base) |
| + state.sizeCells(0x10000) |
| + state.addrCells(self.get_redist_bases()[0]) |
| + state.sizeCells(0x2000000) |
| ) |
| |
| node.append(FdtPropertyWords("reg", regs)) |
| # Maintenance interrupt (PPI 25). |
| node.append( |
| FdtPropertyWords("interrupts", self.interruptCells(1, 9, 0x4)) |
| ) |
| |
| node.appendPhandle(self) |
| |
| # Generate the ITS device tree |
| its_frame_size = 0x10000 |
| its_bases = [ |
| sc_gic.its0_base, |
| sc_gic.its1_base, |
| sc_gic.its2_base, |
| sc_gic.its3_base, |
| ] |
| for its_base in its_bases: |
| its_node = self.generateBasicPioDeviceNode( |
| state, "gic-its", its_base, 2 * its_frame_size |
| ) |
| its_node.appendCompatible(["arm,gic-v3-its"]) |
| its_node.append(FdtProperty("msi-controller")) |
| its_node.append(FdtPropertyWords("#msi-cells", [1])) |
| node.append(its_node) |
| |
| yield node |