From: Gabe Black Date: Thu, 15 Oct 2020 18:51:05 +0000 (-0700) Subject: fastmodel: Wrap the PL330 DMA controller fast model. X-Git-Tag: develop-gem5-snapshot~466 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2f8b5acba110aaf70b646503398c7f3341b49732;p=gem5.git fastmodel: Wrap the PL330 DMA controller fast model. Change-Id: I0290e52ede4dca1252ca224abcc85c2c8086ea3c Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/37216 Reviewed-by: Giacomo Travaglini Maintainer: Gabe Black Tested-by: kokoro --- diff --git a/src/arch/arm/fastmodel/PL330_DMAC/FastModelPL330.py b/src/arch/arm/fastmodel/PL330_DMAC/FastModelPL330.py new file mode 100644 index 000000000..5116006b9 --- /dev/null +++ b/src/arch/arm/fastmodel/PL330_DMAC/FastModelPL330.py @@ -0,0 +1,170 @@ +# Copyright 2020 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.objects.FastModel import AmbaInitiatorSocket, AmbaTargetSocket +from m5.objects.IntPin import IntSourcePin +from m5.objects.SystemC import SystemC_ScModule + +class FastModelPL330(SystemC_ScModule): + type = 'FastModelPL330' + cxx_class = 'FastModel::PL330' + cxx_header = 'arch/arm/fastmodel/PL330_DMAC/pl330.hh' + + clock = Param.Frequency("Clock frequency") + + irq_0 = IntSourcePin("Sets when DMASEV 0") + irq_1 = IntSourcePin("Sets when DMASEV 1") + irq_2 = IntSourcePin("Sets when DMASEV 2") + irq_3 = IntSourcePin("Sets when DMASEV 3") + irq_4 = IntSourcePin("Sets when DMASEV 4") + irq_5 = IntSourcePin("Sets when DMASEV 5") + irq_6 = IntSourcePin("Sets when DMASEV 6") + irq_7 = IntSourcePin("Sets when DMASEV 7") + irq_8 = IntSourcePin("Sets when DMASEV 8") + irq_9 = IntSourcePin("Sets when DMASEV 9") + irq_10 = IntSourcePin("Sets when DMASEV 10") + irq_11 = IntSourcePin("Sets when DMASEV 11") + irq_12 = IntSourcePin("Sets when DMASEV 12") + irq_13 = IntSourcePin("Sets when DMASEV 13") + irq_14 = IntSourcePin("Sets when DMASEV 14") + irq_15 = IntSourcePin("Sets when DMASEV 15") + irq_16 = IntSourcePin("Sets when DMASEV 16") + irq_17 = IntSourcePin("Sets when DMASEV 17") + irq_18 = IntSourcePin("Sets when DMASEV 18") + irq_19 = IntSourcePin("Sets when DMASEV 19") + irq_20 = IntSourcePin("Sets when DMASEV 20") + irq_21 = IntSourcePin("Sets when DMASEV 21") + irq_22 = IntSourcePin("Sets when DMASEV 22") + irq_23 = IntSourcePin("Sets when DMASEV 23") + irq_24 = IntSourcePin("Sets when DMASEV 24") + irq_25 = IntSourcePin("Sets when DMASEV 25") + irq_26 = IntSourcePin("Sets when DMASEV 26") + irq_27 = IntSourcePin("Sets when DMASEV 27") + irq_28 = IntSourcePin("Sets when DMASEV 28") + irq_29 = IntSourcePin("Sets when DMASEV 29") + irq_30 = IntSourcePin("Sets when DMASEV 30") + irq_31 = IntSourcePin("Sets when DMASEV 31") + irq_abort = IntSourcePin("Undefined instruction or instruction error") + + fifo_size = Param.UInt32(16, "Channel FIFO size in bytes") + max_transfer = Param.UInt32(256, "Largest atomic transfer") + generate_clear = Param.Bool(False, "Generate clear response") + activate_delay = Param.UInt32(0, "request delay") + revision = Param.String("r0p0", "revision ID") + + max_irqs = Param.UInt32(32, "number of interrupts") + buffer_depth = Param.UInt32(16, "buffer depth") + lsq_read_size = Param.UInt32(4, "LSQ read buffer depth") + lsq_write_size = Param.UInt32(4, "LSQ write buffer depth") + read_issuing_capability = Param.UInt32(1, "AXI read issuing capability") + write_issuing_capability = Param.UInt32(1, "AXI write issuing capability") + axi_bus_width = Param.UInt32(32, "AXI bus width") + cache_line_words = Param.UInt32(1, "number of words in a cache line") + cache_lines = Param.UInt32(1, "number of cache lines") + max_channels = Param.UInt32(8, "virtual channels") + controller_nsecure = Param.Bool(False, "Controller non-secure at reset " + "(boot_manager_ns)") + irq_nsecure = Param.UInt32(0, "Interrupts non-secure at reset") + periph_nsecure = Param.Bool(False, "Peripherals non-secure at reset") + controller_boots = Param.Bool(True, "DMA boots from reset") + reset_pc = Param.UInt32(0x60000000, "DMA PC at reset") + max_periph = Param.UInt32(32, "number of peripheral interfaces") + perip_request_acceptance_0 = \ + Param.UInt32(2, "Peripheral 0 request acceptance" ) + perip_request_acceptance_1 = \ + Param.UInt32(2, "Peripheral 1 request acceptance" ) + perip_request_acceptance_2 = \ + Param.UInt32(2, "Peripheral 2 request acceptance" ) + perip_request_acceptance_3 = \ + Param.UInt32(2, "Peripheral 3 request acceptance" ) + perip_request_acceptance_4 = \ + Param.UInt32(2, "Peripheral 4 request acceptance" ) + perip_request_acceptance_5 = \ + Param.UInt32(2, "Peripheral 5 request acceptance" ) + perip_request_acceptance_6 = \ + Param.UInt32(2, "Peripheral 6 request acceptance" ) + perip_request_acceptance_7 = \ + Param.UInt32(2, "Peripheral 7 request acceptance" ) + perip_request_acceptance_8 = \ + Param.UInt32(2, "Peripheral 8 request acceptance" ) + perip_request_acceptance_9 = \ + Param.UInt32(2, "Peripheral 9 request acceptance" ) + perip_request_acceptance_10 = \ + Param.UInt32(2, "Peripheral 10 request acceptance") + perip_request_acceptance_11 = \ + Param.UInt32(2, "Peripheral 11 request acceptance") + perip_request_acceptance_12 = \ + Param.UInt32(2, "Peripheral 12 request acceptance") + perip_request_acceptance_13 = \ + Param.UInt32(2, "Peripheral 13 request acceptance") + perip_request_acceptance_14 = \ + Param.UInt32(2, "Peripheral 14 request acceptance") + perip_request_acceptance_15 = \ + Param.UInt32(2, "Peripheral 15 request acceptance") + perip_request_acceptance_16 = \ + Param.UInt32(2, "Peripheral 16 request acceptance") + perip_request_acceptance_17 = \ + Param.UInt32(2, "Peripheral 17 request acceptance") + perip_request_acceptance_18 = \ + Param.UInt32(2, "Peripheral 18 request acceptance") + perip_request_acceptance_19 = \ + Param.UInt32(2, "Peripheral 19 request acceptance") + perip_request_acceptance_20 = \ + Param.UInt32(2, "Peripheral 20 request acceptance") + perip_request_acceptance_21 = \ + Param.UInt32(2, "Peripheral 21 request acceptance") + perip_request_acceptance_22 = \ + Param.UInt32(2, "Peripheral 22 request acceptance") + perip_request_acceptance_23 = \ + Param.UInt32(2, "Peripheral 23 request acceptance") + perip_request_acceptance_24 = \ + Param.UInt32(2, "Peripheral 24 request acceptance") + perip_request_acceptance_25 = \ + Param.UInt32(2, "Peripheral 25 request acceptance") + perip_request_acceptance_26 = \ + Param.UInt32(2, "Peripheral 26 request acceptance") + perip_request_acceptance_27 = \ + Param.UInt32(2, "Peripheral 27 request acceptance") + perip_request_acceptance_28 = \ + Param.UInt32(2, "Peripheral 28 request acceptance") + perip_request_acceptance_29 = \ + Param.UInt32(2, "Peripheral 29 request acceptance") + perip_request_acceptance_30 = \ + Param.UInt32(2, "Peripheral 30 request acceptance") + perip_request_acceptance_31 = \ + Param.UInt32(2, "Peripheral 31 request acceptance") + + # Singleton IRQ abort signal port + # 32 bit wide IRQ master DMASEV port + dma = AmbaInitiatorSocket(64, "Memory accesses") + pio_s = AmbaTargetSocket(64, "Register accesses (secure)") + pio_ns = AmbaTargetSocket(64, "Register accesses (non-secure)") + + # irq_abort_master_port + # irq_master_port + # pvbus_m + # pvbus_s + # pvbus_s_ns diff --git a/src/arch/arm/fastmodel/PL330_DMAC/PL330.lisa b/src/arch/arm/fastmodel/PL330_DMAC/PL330.lisa new file mode 100644 index 000000000..3c31c90d8 --- /dev/null +++ b/src/arch/arm/fastmodel/PL330_DMAC/PL330.lisa @@ -0,0 +1,88 @@ +/* + * Copyright 2020 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. + */ + +component PL330 +{ + composition + { + pl330 : PL330_DMAC(); + + // Clocks. + clock1Hz : MasterClock(); + clockDiv : ClockDivider(); + + // Bridges. + + // For DMA accesses. + dma_out : PVBus2AMBAPV(); + + // For register accesses. + pio_s_in : AMBAPV2PVBus(); + pio_s_ns_in : AMBAPV2PVBus(); + } + + connection + { + // Outgoing DMA accesses. + pl330.pvbus_m => dma_out.pvbus_s; + dma_out.amba_pv_m => self.amba_m; + + // Incoming register accesses. + self.amba_s => pio_s_in.amba_pv_s; + pio_s_in.pvbus_m => pl330.pvbus_s; + self.amba_s_ns => pio_s_ns_in.amba_pv_s; + pio_s_ns_in.pvbus_m => pl330.pvbus_s_ns; + + // Clocks. + clock1Hz.clk_out => clockDiv.clk_in; + clockDiv.clk_out => pl330.clk_in; + + // Interrupts. + pl330.irq_master_port => self.irq; + pl330.irq_abort_master_port => self.irq_abort; + } + + properties + { + component_type = "System"; + } + + slave port clock_rate_s + { + behavior set_mul_div(uint64_t mul, uint64_t div) + { + clockDiv.rate.set64(mul, div); + } + } + + master port amba_m; + slave port amba_s; + slave port amba_s_ns; + + master port irq[32]; + master port irq_abort; +} diff --git a/src/arch/arm/fastmodel/PL330_DMAC/PL330.sgproj b/src/arch/arm/fastmodel/PL330_DMAC/PL330.sgproj new file mode 100644 index 000000000..31eef3597 --- /dev/null +++ b/src/arch/arm/fastmodel/PL330_DMAC/PL330.sgproj @@ -0,0 +1,28 @@ +sgproject "PL330.sgproj" +{ +TOP_LEVEL_COMPONENT = "PL330"; +ACTIVE_CONFIG_LINUX = "gcc"; +ACTIVE_CONFIG_WINDOWS = "Win64-Release-VC2015"; +config "gcc" +{ + ADDITIONAL_COMPILER_SETTINGS = "-O3 -Wall -std=c++14 -Wno-deprecated -Wno-unused-function -I../../../../../"; + ADDITIONAL_LINKER_SETTINGS = "-Wl,--no-undefined"; + BUILD_DIR = "./gcc"; + COMPILER = "gcc-6.4"; + CONFIG_DESCRIPTION = ""; + CONFIG_NAME = "gcc"; + PLATFORM = "Linux64"; + PREPROCESSOR_DEFINES = "NDEBUG"; + SIMGEN_COMMAND_LINE = "--num-comps-file 50"; + TARGET_MAXVIEW = "0"; + TARGET_SYSTEMC = "1"; + TARGET_SYSTEMC_AUTO = "1"; +} +files +{ + path = "PL330.lisa"; + path = "${PVLIB_HOME}/etc/sglib.sgrepo"; + path = "../protocol/SignalInterruptProtocol.lisa"; + path = "../protocol/ExportedClockRateControlProtocol.lisa"; +} +} diff --git a/src/arch/arm/fastmodel/PL330_DMAC/SConscript b/src/arch/arm/fastmodel/PL330_DMAC/SConscript new file mode 100644 index 000000000..97f15f66f --- /dev/null +++ b/src/arch/arm/fastmodel/PL330_DMAC/SConscript @@ -0,0 +1,37 @@ +# Copyright 2020 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. + +Import('*') + +if not env['USE_ARM_FASTMODEL'] or env['TARGET_ISA'] != 'arm': + Return() + +protocol_dir = Dir('..').Dir('protocol') + +ArmFastModelComponent(File('PL330.sgproj'), File('PL330.lisa'), + protocol_dir.File('SignalInterruptProtocol.lisa') + ).prepare_env(env) +SimObject('FastModelPL330.py') +Source('pl330.cc') diff --git a/src/arch/arm/fastmodel/PL330_DMAC/pl330.cc b/src/arch/arm/fastmodel/PL330_DMAC/pl330.cc new file mode 100644 index 000000000..e8353041e --- /dev/null +++ b/src/arch/arm/fastmodel/PL330_DMAC/pl330.cc @@ -0,0 +1,261 @@ +/* + * 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. + */ + +#include "arch/arm/fastmodel/PL330_DMAC/pl330.hh" + +#include + +#include "params/FastModelPL330.hh" +#include "sim/core.hh" + +namespace FastModel +{ + +PL330::PL330(const FastModelPL330Params ¶ms, + sc_core::sc_module_name _name) : + scx_evs_PL330(_name), clockPeriod(params.clock), + dma(amba_m, params.name + ".dma", -1), + pioS(amba_s, params.name + ".pio_s", -1), + pioNs(amba_s_ns, params.name + ".pio_ns", -1), + irqAbortReceiver("irq_abort_receiver") +{ + set_parameter("pl330.fifo_size", params.fifo_size); + set_parameter("pl330.max_transfer", params.max_transfer); + set_parameter("pl330.generate_clear", params.generate_clear); + set_parameter("pl330.activate_delay", params.activate_delay); + set_parameter("pl330.revision", params.revision); + set_parameter("pl330.p_max_irqs", params.max_irqs); + set_parameter("pl330.p_buffer_depth", params.buffer_depth); + set_parameter("pl330.p_lsq_read_size", params.lsq_read_size); + set_parameter("pl330.p_lsq_write_size", params.lsq_write_size); + set_parameter("pl330.p_read_issuing_capability", + params.read_issuing_capability); + set_parameter("pl330.p_write_issuing_capability", + params.write_issuing_capability); + set_parameter("pl330.p_axi_bus_width_param", params.axi_bus_width); + set_parameter("pl330.p_cache_line_words", params.cache_line_words); + set_parameter("pl330.p_cache_lines", params.cache_lines); + set_parameter("pl330.p_max_channels", params.max_channels); + set_parameter("pl330.p_controller_nsecure", params.controller_nsecure); + set_parameter("pl330.p_irq_nsecure", params.irq_nsecure); + set_parameter("pl330.p_periph_nsecure", params.periph_nsecure); + set_parameter("pl330.p_controller_boots", params.controller_boots); + set_parameter("pl330.p_reset_pc", params.reset_pc); + set_parameter("pl330.p_max_periph", params.max_periph); + set_parameter("pl330.p_perip_request_acceptance_0", + params.perip_request_acceptance_0); + set_parameter("pl330.p_perip_request_acceptance_1", + params.perip_request_acceptance_1); + set_parameter("pl330.p_perip_request_acceptance_2", + params.perip_request_acceptance_2); + set_parameter("pl330.p_perip_request_acceptance_3", + params.perip_request_acceptance_3); + set_parameter("pl330.p_perip_request_acceptance_4", + params.perip_request_acceptance_4); + set_parameter("pl330.p_perip_request_acceptance_5", + params.perip_request_acceptance_5); + set_parameter("pl330.p_perip_request_acceptance_6", + params.perip_request_acceptance_6); + set_parameter("pl330.p_perip_request_acceptance_7", + params.perip_request_acceptance_7); + set_parameter("pl330.p_perip_request_acceptance_8", + params.perip_request_acceptance_8); + set_parameter("pl330.p_perip_request_acceptance_9", + params.perip_request_acceptance_9); + set_parameter("pl330.p_perip_request_acceptance_10", + params.perip_request_acceptance_10); + set_parameter("pl330.p_perip_request_acceptance_11", + params.perip_request_acceptance_11); + set_parameter("pl330.p_perip_request_acceptance_12", + params.perip_request_acceptance_12); + set_parameter("pl330.p_perip_request_acceptance_13", + params.perip_request_acceptance_13); + set_parameter("pl330.p_perip_request_acceptance_14", + params.perip_request_acceptance_14); + set_parameter("pl330.p_perip_request_acceptance_15", + params.perip_request_acceptance_15); + set_parameter("pl330.p_perip_request_acceptance_16", + params.perip_request_acceptance_16); + set_parameter("pl330.p_perip_request_acceptance_17", + params.perip_request_acceptance_17); + set_parameter("pl330.p_perip_request_acceptance_18", + params.perip_request_acceptance_18); + set_parameter("pl330.p_perip_request_acceptance_19", + params.perip_request_acceptance_19); + set_parameter("pl330.p_perip_request_acceptance_20", + params.perip_request_acceptance_20); + set_parameter("pl330.p_perip_request_acceptance_21", + params.perip_request_acceptance_21); + set_parameter("pl330.p_perip_request_acceptance_22", + params.perip_request_acceptance_22); + set_parameter("pl330.p_perip_request_acceptance_23", + params.perip_request_acceptance_23); + set_parameter("pl330.p_perip_request_acceptance_24", + params.perip_request_acceptance_24); + set_parameter("pl330.p_perip_request_acceptance_25", + params.perip_request_acceptance_25); + set_parameter("pl330.p_perip_request_acceptance_26", + params.perip_request_acceptance_26); + set_parameter("pl330.p_perip_request_acceptance_27", + params.perip_request_acceptance_27); + set_parameter("pl330.p_perip_request_acceptance_28", + params.perip_request_acceptance_28); + set_parameter("pl330.p_perip_request_acceptance_29", + params.perip_request_acceptance_29); + set_parameter("pl330.p_perip_request_acceptance_30", + params.perip_request_acceptance_30); + set_parameter("pl330.p_perip_request_acceptance_31", + params.perip_request_acceptance_31); + + // Plumb up the mechanism which lets us set the clock rate inside the EVS. + clockRateControl.bind(this->clock_rate_s); + + // Allocate all the source pins for each interrupt port. + allocateIrq(0, params.port_irq_0_connection_count); + allocateIrq(1, params.port_irq_1_connection_count); + allocateIrq(2, params.port_irq_2_connection_count); + allocateIrq(3, params.port_irq_3_connection_count); + allocateIrq(4, params.port_irq_4_connection_count); + allocateIrq(5, params.port_irq_5_connection_count); + allocateIrq(6, params.port_irq_6_connection_count); + allocateIrq(7, params.port_irq_7_connection_count); + allocateIrq(8, params.port_irq_8_connection_count); + allocateIrq(9, params.port_irq_9_connection_count); + allocateIrq(10, params.port_irq_10_connection_count); + allocateIrq(11, params.port_irq_11_connection_count); + allocateIrq(12, params.port_irq_12_connection_count); + allocateIrq(13, params.port_irq_13_connection_count); + allocateIrq(14, params.port_irq_14_connection_count); + allocateIrq(15, params.port_irq_15_connection_count); + allocateIrq(16, params.port_irq_16_connection_count); + allocateIrq(17, params.port_irq_17_connection_count); + allocateIrq(18, params.port_irq_18_connection_count); + allocateIrq(19, params.port_irq_19_connection_count); + allocateIrq(20, params.port_irq_20_connection_count); + allocateIrq(21, params.port_irq_21_connection_count); + allocateIrq(22, params.port_irq_22_connection_count); + allocateIrq(23, params.port_irq_23_connection_count); + allocateIrq(24, params.port_irq_24_connection_count); + allocateIrq(25, params.port_irq_25_connection_count); + allocateIrq(26, params.port_irq_26_connection_count); + allocateIrq(27, params.port_irq_27_connection_count); + allocateIrq(28, params.port_irq_28_connection_count); + allocateIrq(29, params.port_irq_29_connection_count); + allocateIrq(30, params.port_irq_30_connection_count); + allocateIrq(31, params.port_irq_31_connection_count); + + // Plumb the interrupts from inside the EVS to any external sinks. + for (int i = 0; i < 32; i++) { + // Create a receiver to receive interrupts from the EVS. + irqReceiver.emplace_back( + new SignalReceiver(csprintf("irq_receiver[%d]", i))); + + // Attach the receiver to the socket coming out of the EVS. + irq[i].bind(irqReceiver[i]->signal_in); + + // Set up a handler for when the signal changes state. + auto on_change = [&port = irqPort[i]](bool status) + { + // Loop through all the connections and propogate the signal. + for (auto &pin: port) + status ? pin->raise() : pin->lower(); + }; + + // Install the handler. + irqReceiver[i]->onChange(on_change); + } + + // Set up the abort IRQ pins. + for (int i = 0; i < params.port_irq_abort_connection_count; i++) { + irqAbortPort.emplace_back(new IntSourcePin( + csprintf("%s.irq_abort_master_port[%d]", name(), i), + i, this)); + } + + // Attach the receiver (already set up) to the EVS. + irq_abort.bind(irqAbortReceiver.signal_in); + + // Set up a handler. + auto abort_change = [this](bool status) { + for (auto &pin: irqAbortPort) + status ? pin->raise() : pin->lower(); + }; + + // And install it. + irqAbortReceiver.onChange(abort_change); +} + +void +PL330::allocateIrq(int idx, int count) +{ + for (int i = 0; i < count; i++) { + irqPort[idx].emplace_back(new IntSourcePin( + csprintf("%s.irq_master_port[%d][%d]", name(), idx, i), + i, this)); + } +} + +::Port & +PL330::gem5_getPort(const std::string &if_name, int idx) +{ + if (if_name == "dma") { + return dma; + } else if (if_name == "pio_s") { + return pioS; + } else if (if_name == "pio_ns") { + return pioNs; + } else if (if_name.substr(0, 4) == "irq_") { + auto suffix = if_name.substr(4); + + if (suffix == "abort") + return *irqAbortPort.at(idx); + + // Existing functions like stoull, and to_number which uses it, skip + // leading whitespace and ignore non-numeric characters at the end of + // the string. We're going to be more picky than that. + int port = -1; + if (suffix.size() == 1 && isdigit(suffix[0])) { + port = suffix[0] - '0'; + } else if (suffix.size() == 2 && isdigit(suffix[0]) && + isdigit(suffix[1])) { + port = (suffix[1] - '0') * 10 + (suffix[0] - '0'); + } + if (port != -1 && port < irqPort.size()) + return *irqPort[port].at(idx); + } + + return scx_evs_PL330::gem5_getPort(if_name, idx); +} + +void +PL330::start_of_simulation() +{ + // Set the clock rate using the divider inside the EVS. + clockRateControl->set_mul_div(SimClock::Int::s, clockPeriod); +} + +} // namespace FastModel diff --git a/src/arch/arm/fastmodel/PL330_DMAC/pl330.hh b/src/arch/arm/fastmodel/PL330_DMAC/pl330.hh new file mode 100644 index 000000000..3db6d9627 --- /dev/null +++ b/src/arch/arm/fastmodel/PL330_DMAC/pl330.hh @@ -0,0 +1,91 @@ +/* + * Copyright 2020 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. + */ + +#ifndef __ARCH_ARM_FASTMODEL_PL330_PL330_HH__ +#define __ARCH_ARM_FASTMODEL_PL330_PL330_HH__ + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Woverloaded-virtual" +#include + +#pragma GCC diagnostic pop + +#include +#include + +#include "arch/arm/fastmodel/amba_ports.hh" +#include "arch/arm/fastmodel/common/signal_receiver.hh" +#include "arch/arm/fastmodel/protocol/exported_clock_rate_control.hh" +#include "dev/intpin.hh" +#include "params/FastModelPL330.hh" +#include "scx_evs_PL330.h" +#include "systemc/ext/core/sc_module_name.hh" +#include "systemc/sc_port_wrapper.hh" + +namespace FastModel +{ + +class PL330 : public scx_evs_PL330 +{ + private: + Tick clockPeriod; + + AmbaInitiator dma; + AmbaTarget pioS, pioNs; + + ClockRateControlInitiatorSocket clockRateControl; + + using IntSource = IntSourcePin; + + std::array>, 32> irqPort; + std::vector> irqReceiver; + + std::vector> irqAbortPort; + SignalReceiver irqAbortReceiver; + + void allocateIrq(int idx, int count); + + public: + PL330(const FastModelPL330Params ¶ms, sc_core::sc_module_name _name); + PL330(const FastModelPL330Params ¶ms) : + PL330(params, params.name.c_str()) + {} + + ::Port &gem5_getPort(const std::string &if_name, int idx=-1) override; + + void + end_of_elaboration() override + { + scx_evs_PL330::end_of_elaboration(); + scx_evs_PL330::start_of_simulation(); + } + void start_of_simulation() override; +}; + +} // namespace FastModel + +#endif // __ARCH_ARM_FASTMODEL_PL330_PL330_HH__