SMMUv3.py revision 14252
114039Sstacze01@arm.com# Copyright (c) 2013, 2018-2019 ARM Limited 214039Sstacze01@arm.com# All rights reserved 314039Sstacze01@arm.com# 414039Sstacze01@arm.com# The license below extends only to copyright in the software and shall 514039Sstacze01@arm.com# not be construed as granting a license to any other intellectual 614039Sstacze01@arm.com# property including but not limited to intellectual property relating 714039Sstacze01@arm.com# to a hardware implementation of the functionality of the software 814039Sstacze01@arm.com# licensed hereunder. You may use the software subject to the license 914039Sstacze01@arm.com# terms below provided that you ensure that this notice is replicated 1014039Sstacze01@arm.com# unmodified and in its entirety in all distributions of the software, 1114039Sstacze01@arm.com# modified or unmodified, in source code or in binary form. 1214039Sstacze01@arm.com# 1314039Sstacze01@arm.com# Redistribution and use in source and binary forms, with or without 1414039Sstacze01@arm.com# modification, are permitted provided that the following conditions are 1514039Sstacze01@arm.com# met: redistributions of source code must retain the above copyright 1614039Sstacze01@arm.com# notice, this list of conditions and the following disclaimer; 1714039Sstacze01@arm.com# redistributions in binary form must reproduce the above copyright 1814039Sstacze01@arm.com# notice, this list of conditions and the following disclaimer in the 1914039Sstacze01@arm.com# documentation and/or other materials provided with the distribution; 2014039Sstacze01@arm.com# neither the name of the copyright holders nor the names of its 2114039Sstacze01@arm.com# contributors may be used to endorse or promote products derived from 2214039Sstacze01@arm.com# this software without specific prior written permission. 2314039Sstacze01@arm.com# 2414039Sstacze01@arm.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2514039Sstacze01@arm.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2614039Sstacze01@arm.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2714039Sstacze01@arm.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2814039Sstacze01@arm.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2914039Sstacze01@arm.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3014039Sstacze01@arm.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3114039Sstacze01@arm.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3214039Sstacze01@arm.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3314039Sstacze01@arm.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3414039Sstacze01@arm.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3514039Sstacze01@arm.com# 3614039Sstacze01@arm.com# Authors: Stan Czerniawski 3714039Sstacze01@arm.com# Giacomo Travaglini 3814039Sstacze01@arm.com 3914039Sstacze01@arm.comfrom m5.params import * 4014039Sstacze01@arm.comfrom m5.proxy import * 4114039Sstacze01@arm.comfrom m5.util.fdthelper import * 4214039Sstacze01@arm.comfrom m5.SimObject import * 4314252Sgabeblack@google.comfrom m5.objects.ClockedObject import ClockedObject 4414039Sstacze01@arm.com 4514252Sgabeblack@google.comclass SMMUv3SlaveInterface(ClockedObject): 4614039Sstacze01@arm.com type = 'SMMUv3SlaveInterface' 4714039Sstacze01@arm.com cxx_header = 'dev/arm/smmu_v3_slaveifc.hh' 4814039Sstacze01@arm.com 4914039Sstacze01@arm.com slave = SlavePort('Device port') 5014039Sstacze01@arm.com ats_master = MasterPort('ATS master port') 5114039Sstacze01@arm.com ats_slave = SlavePort('ATS slave port') 5214039Sstacze01@arm.com 5314039Sstacze01@arm.com port_width = Param.Unsigned(16, 'Port width in bytes (= 1 beat)') 5414039Sstacze01@arm.com wrbuf_slots = Param.Unsigned(16, 'Write buffer size (in beats)') 5514039Sstacze01@arm.com xlate_slots = Param.Unsigned(16, 'Translation slots') 5614039Sstacze01@arm.com 5714039Sstacze01@arm.com utlb_entries = Param.Unsigned(32, 'Micro TLB size (entries)') 5814039Sstacze01@arm.com utlb_assoc = Param.Unsigned(0, 'Micro TLB associativity (0=full)') 5914039Sstacze01@arm.com utlb_policy = Param.String('rr', 'Micro TLB replacement policy') 6014039Sstacze01@arm.com utlb_enable = Param.Bool(True, 'Micro TLB enable') 6114039Sstacze01@arm.com utlb_lat = Param.Cycles(1, 'Micro TLB lookup latency') 6214039Sstacze01@arm.com utlb_slots = Param.Cycles(1, 'Micro TLB lookup slots') 6314039Sstacze01@arm.com 6414039Sstacze01@arm.com tlb_entries = Param.Unsigned(2048, 'Main TLB size (entries)') 6514039Sstacze01@arm.com tlb_assoc = Param.Unsigned(4, 'Main TLB associativity (0=full)') 6614039Sstacze01@arm.com tlb_policy = Param.String('rr', 'Main TLB replacement policy') 6714039Sstacze01@arm.com tlb_enable = Param.Bool(True, 'Main TLB enable') 6814039Sstacze01@arm.com tlb_lat = Param.Cycles(3, 'Main TLB lookup latency') 6914039Sstacze01@arm.com tlb_slots = Param.Cycles(3, 'Main TLB lookup slots') 7014039Sstacze01@arm.com 7114039Sstacze01@arm.com prefetch_enable = Param.Bool(False, 7214039Sstacze01@arm.com 'Enable prefetch') 7314039Sstacze01@arm.com prefetch_reserve_last_way = Param.Bool(True, 7414039Sstacze01@arm.com 'Reserve last way of the main TLB for prefetched entries') 7514039Sstacze01@arm.com 7614252Sgabeblack@google.comclass SMMUv3(ClockedObject): 7714039Sstacze01@arm.com type = 'SMMUv3' 7814039Sstacze01@arm.com cxx_header = 'dev/arm/smmu_v3.hh' 7914039Sstacze01@arm.com 8014039Sstacze01@arm.com master = MasterPort('Master port') 8114039Sstacze01@arm.com master_walker = MasterPort( 8214039Sstacze01@arm.com 'Master port for SMMU initiated HWTW requests (optional)') 8314039Sstacze01@arm.com control = SlavePort('Control port for accessing memory-mapped registers') 8414039Sstacze01@arm.com sample_period = Param.Clock('10us', 'Stats sample period') 8514039Sstacze01@arm.com reg_map = Param.AddrRange('Address range for control registers') 8614039Sstacze01@arm.com system = Param.System(Parent.any, "System this device is part of") 8714039Sstacze01@arm.com 8814039Sstacze01@arm.com slave_interfaces = VectorParam.SMMUv3SlaveInterface([], "Slave interfaces") 8914039Sstacze01@arm.com 9014039Sstacze01@arm.com # SLAVE INTERFACE<->SMMU link parameters 9114039Sstacze01@arm.com ifc_smmu_lat = Param.Cycles(8, 'IFC to SMMU communication latency') 9214039Sstacze01@arm.com smmu_ifc_lat = Param.Cycles(8, 'SMMU to IFC communication latency') 9314039Sstacze01@arm.com 9414039Sstacze01@arm.com # SMMU parameters 9514039Sstacze01@arm.com xlate_slots = Param.Unsigned(64, 'SMMU translation slots') 9614039Sstacze01@arm.com ptw_slots = Param.Unsigned(16, 'SMMU page table walk slots') 9714039Sstacze01@arm.com 9814039Sstacze01@arm.com master_port_width = Param.Unsigned(16, 9914039Sstacze01@arm.com 'Master port width in bytes (= 1 beat)') 10014039Sstacze01@arm.com 10114039Sstacze01@arm.com tlb_entries = Param.Unsigned(2048, 'TLB size (entries)') 10214039Sstacze01@arm.com tlb_assoc = Param.Unsigned(4, 'TLB associativity (0=full)') 10314039Sstacze01@arm.com tlb_policy = Param.String('rr', 'TLB replacement policy') 10414039Sstacze01@arm.com tlb_enable = Param.Bool(False, 'TLB enable') 10514039Sstacze01@arm.com tlb_lat = Param.Cycles(3, 'TLB lookup latency') 10614039Sstacze01@arm.com tlb_slots = Param.Cycles(3, 'TLB lookup slots') 10714039Sstacze01@arm.com 10814039Sstacze01@arm.com cfg_entries = Param.Unsigned(64, 'Config cache size (entries)') 10914039Sstacze01@arm.com cfg_assoc = Param.Unsigned(4, 'Config cache associativity (0=full)') 11014039Sstacze01@arm.com cfg_policy = Param.String('rr', 'Config cache replacement policy') 11114039Sstacze01@arm.com cfg_enable = Param.Bool(True, 'Config cache enable') 11214039Sstacze01@arm.com cfg_lat = Param.Cycles(3, 'Config cache lookup latency') 11314039Sstacze01@arm.com cfg_slots = Param.Cycles(3, 'Config cache lookup slots') 11414039Sstacze01@arm.com 11514039Sstacze01@arm.com ipa_entries = Param.Unsigned(128, 'IPA cache size (entries)') 11614039Sstacze01@arm.com ipa_assoc = Param.Unsigned(4, 'IPA cache associativity (0=full)') 11714039Sstacze01@arm.com ipa_policy = Param.String('rr', 'IPA cache replacement policy') 11814039Sstacze01@arm.com ipa_enable = Param.Bool(False, 'IPA cache enable') 11914039Sstacze01@arm.com ipa_lat = Param.Cycles(3, 'IPA cache lookup lantency') 12014039Sstacze01@arm.com ipa_slots = Param.Cycles(3, 'IPA cache lookup slots') 12114039Sstacze01@arm.com 12214039Sstacze01@arm.com walk_S1L0 = Param.Unsigned(4, 'Walk cache S1L0 size (entries)') 12314039Sstacze01@arm.com walk_S1L1 = Param.Unsigned(28, 'Walk cache S1L1 size (entries)') 12414039Sstacze01@arm.com walk_S1L2 = Param.Unsigned(348, 'Walk cache S1L2 size (entries)') 12514039Sstacze01@arm.com walk_S1L3 = Param.Unsigned(4, 'Walk cache S1L3 size (entries)') 12614039Sstacze01@arm.com walk_S2L0 = Param.Unsigned(4, 'Walk cache S2L0 size (entries)') 12714039Sstacze01@arm.com walk_S2L1 = Param.Unsigned(28, 'Walk cache S2L1 size (entries)') 12814039Sstacze01@arm.com walk_S2L2 = Param.Unsigned(92, 'Walk cache S2L2 size (entries)') 12914039Sstacze01@arm.com walk_S2L3 = Param.Unsigned(4, 'Walk cache S2L3 size (entries)') 13014039Sstacze01@arm.com walk_assoc = Param.Unsigned(4, 'Walk cache associativity (0=full)') 13114039Sstacze01@arm.com walk_policy = Param.String('rr', 'Walk cache replacement policy') 13214039Sstacze01@arm.com walk_enable = Param.Bool(True, 'Walk cache enable') 13314039Sstacze01@arm.com wc_nonfinal_enable = Param.Bool(False, 13414039Sstacze01@arm.com 'Nonfinal translations use walk cache') 13514039Sstacze01@arm.com wc_s1_levels = Param.Unsigned(7, 13614039Sstacze01@arm.com 'S1 PT levels cached in walk cache (bit 0 is L0, bit 1 is L1, etc)') 13714039Sstacze01@arm.com wc_s2_levels = Param.Unsigned(7, 13814039Sstacze01@arm.com 'S2 PT levels cached in walk cache (bit 0 is L0, bit 1 is L1, etc)') 13914039Sstacze01@arm.com 14014039Sstacze01@arm.com walk_lat = Param.Cycles(4, 'Walk cache lookup latency') 14114039Sstacze01@arm.com walk_slots = Param.Cycles(4, 'Walk cache lookup slots') 14214039Sstacze01@arm.com 14314039Sstacze01@arm.com # [28:27] ST_LEVEL = 0b01, 2-level Stream Table supported in addition 14414039Sstacze01@arm.com # to Linear Stream table. 14514039Sstacze01@arm.com # [25:24] STALL_MODEL = 0b01, Stall is not supported, all faults 14614039Sstacze01@arm.com # terminate transaction. 14714039Sstacze01@arm.com # [22:21] TTENDIAN = 0b10, Endianness support for translation table walks 14814039Sstacze01@arm.com # (0b10 = Little-endian). 14914039Sstacze01@arm.com # [19] CD2L = 0b1, 2-level CD table supported. 15014039Sstacze01@arm.com # [18] VMID16 = 0b1, 16-bit VMID supported. 15114039Sstacze01@arm.com # [12] ASID16 = 0b1, 16-bit ASID supported. 15214039Sstacze01@arm.com # [3:2] TTF = 0b10, Translation Table Formats (Stage 1/2) 15314039Sstacze01@arm.com # (0b10 = AArch64). 15414039Sstacze01@arm.com # [1] S1P = 0b1, Stage 1 translation supported. 15514039Sstacze01@arm.com # [0] S2P = 0b1, Stage 2 translation supported. 15614039Sstacze01@arm.com smmu_idr0 = Param.UInt32(0x094C100F, "SMMU_IDR0 register"); 15714039Sstacze01@arm.com 15814039Sstacze01@arm.com # [25:21] CMDQS = 0b00101, Maximum number of Command queue entries 15914039Sstacze01@arm.com # as log 2 (entries) (0b00101 = 32 entries). 16014039Sstacze01@arm.com smmu_idr1 = Param.UInt32(0x00A00000, "SMMU_IDR1 register"); 16114039Sstacze01@arm.com 16214039Sstacze01@arm.com smmu_idr2 = Param.UInt32(0, "SMMU_IDR2 register"); 16314039Sstacze01@arm.com smmu_idr3 = Param.UInt32(0, "SMMU_IDR3 register"); 16414039Sstacze01@arm.com smmu_idr4 = Param.UInt32(0, "SMMU_IDR4 register"); 16514039Sstacze01@arm.com 16614039Sstacze01@arm.com # [6] GRAN64K = 0b1, 64KB translation granule supported. 16714039Sstacze01@arm.com # [4] GRAN4K = 0b1, 4KB translation granule supported. 16814039Sstacze01@arm.com # [2:0] OAS = 0b101, Output Address Size (0b101 = 48-bit). 16914039Sstacze01@arm.com smmu_idr5 = Param.UInt32(0x55, "SMMU_IDR5 register"); 17014039Sstacze01@arm.com smmu_iidr = Param.UInt32(0, "SMMU_IIDR register"); 17114039Sstacze01@arm.com 17214039Sstacze01@arm.com # [7:0] (0 = SMMUv3.0) (1 = SMMUv3.1) 17314039Sstacze01@arm.com smmu_aidr = Param.UInt32(0, "SMMU_AIDR register"); 17414039Sstacze01@arm.com 17514039Sstacze01@arm.com def generateDeviceTree(self, state): 17614039Sstacze01@arm.com reg_addr = self.reg_map.start 17714039Sstacze01@arm.com reg_size = self.reg_map.size() 17814039Sstacze01@arm.com node = FdtNode("smmuv3@%x" % long(reg_addr)) 17914039Sstacze01@arm.com node.appendCompatible("arm,smmu-v3") 18014039Sstacze01@arm.com node.append(FdtPropertyWords("reg", 18114039Sstacze01@arm.com state.addrCells(reg_addr) + 18214039Sstacze01@arm.com state.sizeCells(reg_size))) 18314039Sstacze01@arm.com node.append(FdtPropertyWords("#iommu-cells", [1])) 18414039Sstacze01@arm.com 18514039Sstacze01@arm.com node.appendPhandle(self) 18614039Sstacze01@arm.com yield node 18714039Sstacze01@arm.com 18814039Sstacze01@arm.com def connect(self, device, bus): 18914039Sstacze01@arm.com """ 19014039Sstacze01@arm.com Helper method used to connect the SMMU. The master could 19114039Sstacze01@arm.com be either a dma port (if the SMMU is attached directly to a 19214039Sstacze01@arm.com dma device), or to a master port (this is the case where the SMMU 19314039Sstacze01@arm.com is attached to a bridge). 19414039Sstacze01@arm.com """ 19514039Sstacze01@arm.com 19614039Sstacze01@arm.com self.master = bus.slave 19714039Sstacze01@arm.com self.control = bus.master 19814039Sstacze01@arm.com 19914039Sstacze01@arm.com slave_interface = SMMUv3SlaveInterface() 20014039Sstacze01@arm.com 20114039Sstacze01@arm.com if hasattr(device, "master"): 20214039Sstacze01@arm.com slave_interface.slave = device.master 20314039Sstacze01@arm.com elif hasattr(device, "dma"): 20414039Sstacze01@arm.com slave_interface.slave = device.dma 20514039Sstacze01@arm.com else: 20614039Sstacze01@arm.com print("Unable to attach SMMUv3\n") 20714039Sstacze01@arm.com sys.exit(1) 20814039Sstacze01@arm.com 20914039Sstacze01@arm.com self.slave_interfaces.append(slave_interface) 210