113531Sjairo.balart@metempsy.com/*
214167Sgiacomo.travaglini@arm.com * Copyright (c) 2019 ARM Limited
314167Sgiacomo.travaglini@arm.com * All rights reserved
414167Sgiacomo.travaglini@arm.com *
514167Sgiacomo.travaglini@arm.com * The license below extends only to copyright in the software and shall
614167Sgiacomo.travaglini@arm.com * not be construed as granting a license to any other intellectual
714167Sgiacomo.travaglini@arm.com * property including but not limited to intellectual property relating
814167Sgiacomo.travaglini@arm.com * to a hardware implementation of the functionality of the software
914167Sgiacomo.travaglini@arm.com * licensed hereunder.  You may use the software subject to the license
1014167Sgiacomo.travaglini@arm.com * terms below provided that you ensure that this notice is replicated
1114167Sgiacomo.travaglini@arm.com * unmodified and in its entirety in all distributions of the software,
1214167Sgiacomo.travaglini@arm.com * modified or unmodified, in source code or in binary form.
1314167Sgiacomo.travaglini@arm.com *
1413531Sjairo.balart@metempsy.com * Copyright (c) 2018 Metempsy Technology Consulting
1513531Sjairo.balart@metempsy.com * All rights reserved.
1613531Sjairo.balart@metempsy.com *
1713531Sjairo.balart@metempsy.com * Redistribution and use in source and binary forms, with or without
1813531Sjairo.balart@metempsy.com * modification, are permitted provided that the following conditions are
1913531Sjairo.balart@metempsy.com * met: redistributions of source code must retain the above copyright
2013531Sjairo.balart@metempsy.com * notice, this list of conditions and the following disclaimer;
2113531Sjairo.balart@metempsy.com * redistributions in binary form must reproduce the above copyright
2213531Sjairo.balart@metempsy.com * notice, this list of conditions and the following disclaimer in the
2313531Sjairo.balart@metempsy.com * documentation and/or other materials provided with the distribution;
2413531Sjairo.balart@metempsy.com * neither the name of the copyright holders nor the names of its
2513531Sjairo.balart@metempsy.com * contributors may be used to endorse or promote products derived from
2613531Sjairo.balart@metempsy.com * this software without specific prior written permission.
2713531Sjairo.balart@metempsy.com *
2813531Sjairo.balart@metempsy.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2913531Sjairo.balart@metempsy.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3013531Sjairo.balart@metempsy.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3113531Sjairo.balart@metempsy.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3213531Sjairo.balart@metempsy.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3313531Sjairo.balart@metempsy.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3413531Sjairo.balart@metempsy.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3513531Sjairo.balart@metempsy.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3613531Sjairo.balart@metempsy.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3713531Sjairo.balart@metempsy.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3813531Sjairo.balart@metempsy.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3913531Sjairo.balart@metempsy.com *
4013531Sjairo.balart@metempsy.com * Authors: Jairo Balart
4113531Sjairo.balart@metempsy.com */
4213531Sjairo.balart@metempsy.com
4313531Sjairo.balart@metempsy.com#ifndef __DEV_ARM_GICV3_DISTRIBUTOR_H__
4413531Sjairo.balart@metempsy.com#define __DEV_ARM_GICV3_DISTRIBUTOR_H__
4513531Sjairo.balart@metempsy.com
4613531Sjairo.balart@metempsy.com#include "base/addr_range.hh"
4713531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3.hh"
4813531Sjairo.balart@metempsy.com#include "sim/serialize.hh"
4913531Sjairo.balart@metempsy.com
5013531Sjairo.balart@metempsy.comclass Gicv3Distributor : public Serializable
5113531Sjairo.balart@metempsy.com{
5213531Sjairo.balart@metempsy.com  private:
5313531Sjairo.balart@metempsy.com
5413531Sjairo.balart@metempsy.com    friend class Gicv3Redistributor;
5513531Sjairo.balart@metempsy.com    friend class Gicv3CPUInterface;
5614168Sgiacomo.travaglini@arm.com    friend class Gicv3Its;
5713531Sjairo.balart@metempsy.com
5813531Sjairo.balart@metempsy.com  protected:
5913531Sjairo.balart@metempsy.com
6013531Sjairo.balart@metempsy.com    Gicv3 * gic;
6113531Sjairo.balart@metempsy.com    const uint32_t itLines;
6213531Sjairo.balart@metempsy.com
6313531Sjairo.balart@metempsy.com    enum {
6413531Sjairo.balart@metempsy.com        // Control Register
6513531Sjairo.balart@metempsy.com        GICD_CTLR  = 0x0000,
6613531Sjairo.balart@metempsy.com        // Interrupt Controller Type Register
6713531Sjairo.balart@metempsy.com        GICD_TYPER = 0x0004,
6813531Sjairo.balart@metempsy.com        // Implementer Identification Register
6913531Sjairo.balart@metempsy.com        GICD_IIDR = 0x0008,
7013531Sjairo.balart@metempsy.com        // Error Reporting Status Register
7113531Sjairo.balart@metempsy.com        GICD_STATUSR = 0x0010,
7214253Sgiacomo.travaglini@arm.com        // Set Non-secure SPI Pending Register
7314253Sgiacomo.travaglini@arm.com        GICD_SETSPI_NSR = 0x0040,
7414253Sgiacomo.travaglini@arm.com        // Clear Non-secure SPI Pending Register
7514253Sgiacomo.travaglini@arm.com        GICD_CLRSPI_NSR = 0x0048,
7614253Sgiacomo.travaglini@arm.com        // Set Secure SPI Pending Register
7714253Sgiacomo.travaglini@arm.com        GICD_SETSPI_SR = 0x0050,
7814253Sgiacomo.travaglini@arm.com        // Clear Secure SPI Pending Register
7914253Sgiacomo.travaglini@arm.com        GICD_CLRSPI_SR = 0x0058,
8014251Sgiacomo.travaglini@arm.com        // Software Generated Interrupt Register
8114251Sgiacomo.travaglini@arm.com        GICD_SGIR = 0x0f00,
8213531Sjairo.balart@metempsy.com        // Peripheral ID0 Register
8313531Sjairo.balart@metempsy.com        GICD_PIDR0 = 0xffe0,
8413531Sjairo.balart@metempsy.com        // Peripheral ID1 Register
8513531Sjairo.balart@metempsy.com        GICD_PIDR1 = 0xffe4,
8613531Sjairo.balart@metempsy.com        // Peripheral ID2 Register
8713531Sjairo.balart@metempsy.com        GICD_PIDR2 = 0xffe8,
8813531Sjairo.balart@metempsy.com        // Peripheral ID3 Register
8913531Sjairo.balart@metempsy.com        GICD_PIDR3 = 0xffec,
9013531Sjairo.balart@metempsy.com        // Peripheral ID4 Register
9113531Sjairo.balart@metempsy.com        GICD_PIDR4 = 0xffd0,
9213531Sjairo.balart@metempsy.com        // Peripheral ID5 Register
9313531Sjairo.balart@metempsy.com        GICD_PIDR5 = 0xffd4,
9413531Sjairo.balart@metempsy.com        // Peripheral ID6 Register
9513531Sjairo.balart@metempsy.com        GICD_PIDR6 = 0xffd8,
9613531Sjairo.balart@metempsy.com        // Peripheral ID7 Register
9713531Sjairo.balart@metempsy.com        GICD_PIDR7 = 0xffdc,
9813531Sjairo.balart@metempsy.com    };
9913531Sjairo.balart@metempsy.com
10013531Sjairo.balart@metempsy.com    // Interrupt Group Registers
10113531Sjairo.balart@metempsy.com    static const AddrRange GICD_IGROUPR;
10213531Sjairo.balart@metempsy.com    // Interrupt Set-Enable Registers
10313531Sjairo.balart@metempsy.com    static const AddrRange GICD_ISENABLER;
10413531Sjairo.balart@metempsy.com    // Interrupt Clear-Enable Registers
10513531Sjairo.balart@metempsy.com    static const AddrRange GICD_ICENABLER;
10613531Sjairo.balart@metempsy.com    // Interrupt Set-Pending Registers
10713531Sjairo.balart@metempsy.com    static const AddrRange GICD_ISPENDR;
10813531Sjairo.balart@metempsy.com    // Interrupt Clear-Pending Registers
10913531Sjairo.balart@metempsy.com    static const AddrRange GICD_ICPENDR;
11013531Sjairo.balart@metempsy.com    // Interrupt Set-Active Registers
11113531Sjairo.balart@metempsy.com    static const AddrRange GICD_ISACTIVER;
11213531Sjairo.balart@metempsy.com    // Interrupt Clear-Active Registers
11313531Sjairo.balart@metempsy.com    static const AddrRange GICD_ICACTIVER;
11413531Sjairo.balart@metempsy.com    // Interrupt Priority Registers
11513531Sjairo.balart@metempsy.com    static const AddrRange GICD_IPRIORITYR;
11613531Sjairo.balart@metempsy.com    // Interrupt Processor Targets Registers
11713531Sjairo.balart@metempsy.com    static const AddrRange GICD_ITARGETSR; // GICv2 legacy
11813531Sjairo.balart@metempsy.com    // Interrupt Configuration Registers
11913531Sjairo.balart@metempsy.com    static const AddrRange GICD_ICFGR;
12013531Sjairo.balart@metempsy.com    // Interrupt Group Modifier Registers
12113531Sjairo.balart@metempsy.com    static const AddrRange GICD_IGRPMODR;
12213531Sjairo.balart@metempsy.com    // Non-secure Access Control Registers
12313531Sjairo.balart@metempsy.com    static const AddrRange GICD_NSACR;
12413531Sjairo.balart@metempsy.com    // SGI Clear-Pending Registers
12513531Sjairo.balart@metempsy.com    static const AddrRange GICD_CPENDSGIR; // GICv2 legacy
12613531Sjairo.balart@metempsy.com    // SGI Set-Pending Registers
12713531Sjairo.balart@metempsy.com    static const AddrRange GICD_SPENDSGIR; // GICv2 legacy
12813531Sjairo.balart@metempsy.com    // Interrupt Routing Registers
12913531Sjairo.balart@metempsy.com    static const AddrRange GICD_IROUTER;
13013531Sjairo.balart@metempsy.com
13113531Sjairo.balart@metempsy.com    BitUnion64(IROUTER)
13213756Sjairo.balart@metempsy.com        Bitfield<63, 40> res0_1;
13313756Sjairo.balart@metempsy.com        Bitfield<39, 32> Aff3;
13413756Sjairo.balart@metempsy.com        Bitfield<31>     IRM;
13513756Sjairo.balart@metempsy.com        Bitfield<30, 24> res0_2;
13613756Sjairo.balart@metempsy.com        Bitfield<23, 16> Aff2;
13713756Sjairo.balart@metempsy.com        Bitfield<15, 8>  Aff1;
13813756Sjairo.balart@metempsy.com        Bitfield<7, 0>   Aff0;
13913531Sjairo.balart@metempsy.com    EndBitUnion(IROUTER)
14013531Sjairo.balart@metempsy.com
14113756Sjairo.balart@metempsy.com    static const uint32_t GICD_CTLR_ENABLEGRP0   = 1 << 0;
14213756Sjairo.balart@metempsy.com    static const uint32_t GICD_CTLR_ENABLEGRP1   = 1 << 0;
14313531Sjairo.balart@metempsy.com    static const uint32_t GICD_CTLR_ENABLEGRP1NS = 1 << 1;
14413756Sjairo.balart@metempsy.com    static const uint32_t GICD_CTLR_ENABLEGRP1A  = 1 << 1;
14513756Sjairo.balart@metempsy.com    static const uint32_t GICD_CTLR_ENABLEGRP1S  = 1 << 2;
14613756Sjairo.balart@metempsy.com    static const uint32_t GICD_CTLR_DS           = 1 << 6;
14713531Sjairo.balart@metempsy.com
14813531Sjairo.balart@metempsy.com    bool ARE;
14913531Sjairo.balart@metempsy.com    bool DS;
15013531Sjairo.balart@metempsy.com    bool EnableGrp1S;
15113531Sjairo.balart@metempsy.com    bool EnableGrp1NS;
15213531Sjairo.balart@metempsy.com    bool EnableGrp0;
15313531Sjairo.balart@metempsy.com    std::vector <uint8_t> irqGroup;
15413531Sjairo.balart@metempsy.com    std::vector <bool> irqEnabled;
15513531Sjairo.balart@metempsy.com    std::vector <bool> irqPending;
15613531Sjairo.balart@metempsy.com    std::vector <bool> irqActive;
15713531Sjairo.balart@metempsy.com    std::vector <uint8_t> irqPriority;
15813531Sjairo.balart@metempsy.com    std::vector <Gicv3::IntTriggerType> irqConfig;
15913531Sjairo.balart@metempsy.com    std::vector <uint8_t> irqGrpmod;
16013531Sjairo.balart@metempsy.com    std::vector <uint8_t> irqNsacr;
16113531Sjairo.balart@metempsy.com    std::vector <IROUTER> irqAffinityRouting;
16213531Sjairo.balart@metempsy.com
16314257Sgiacomo.travaglini@arm.com    uint32_t gicdTyper;
16414167Sgiacomo.travaglini@arm.com    uint32_t gicdPidr0;
16514167Sgiacomo.travaglini@arm.com    uint32_t gicdPidr1;
16614167Sgiacomo.travaglini@arm.com    uint32_t gicdPidr2;
16714167Sgiacomo.travaglini@arm.com    uint32_t gicdPidr3;
16814167Sgiacomo.travaglini@arm.com    uint32_t gicdPidr4;
16914167Sgiacomo.travaglini@arm.com
17013531Sjairo.balart@metempsy.com  public:
17113531Sjairo.balart@metempsy.com
17213531Sjairo.balart@metempsy.com    static const uint32_t ADDR_RANGE_SIZE = 0x10000;
17313927Sgiacomo.travaglini@arm.com    static const uint32_t IDBITS = 0xf;
17413531Sjairo.balart@metempsy.com
17513756Sjairo.balart@metempsy.com  protected:
17613531Sjairo.balart@metempsy.com
17713756Sjairo.balart@metempsy.com    void activateIRQ(uint32_t int_id);
17813756Sjairo.balart@metempsy.com    void deactivateIRQ(uint32_t int_id);
17913756Sjairo.balart@metempsy.com    void fullUpdate();
18013756Sjairo.balart@metempsy.com    Gicv3::GroupId getIntGroup(int int_id) const;
18113531Sjairo.balart@metempsy.com
18213756Sjairo.balart@metempsy.com    inline bool
18313756Sjairo.balart@metempsy.com    groupEnabled(Gicv3::GroupId group) const
18413531Sjairo.balart@metempsy.com    {
18513531Sjairo.balart@metempsy.com        if (DS == 0) {
18613531Sjairo.balart@metempsy.com            switch (group) {
18713531Sjairo.balart@metempsy.com              case Gicv3::G0S:
18813531Sjairo.balart@metempsy.com                return EnableGrp0;
18913531Sjairo.balart@metempsy.com
19013531Sjairo.balart@metempsy.com              case Gicv3::G1S:
19113531Sjairo.balart@metempsy.com                return EnableGrp1S;
19213531Sjairo.balart@metempsy.com
19313531Sjairo.balart@metempsy.com              case Gicv3::G1NS:
19413531Sjairo.balart@metempsy.com                return EnableGrp1NS;
19513531Sjairo.balart@metempsy.com
19613531Sjairo.balart@metempsy.com              default:
19713531Sjairo.balart@metempsy.com                panic("Gicv3Distributor::groupEnabled(): "
19813531Sjairo.balart@metempsy.com                        "invalid group!\n");
19913531Sjairo.balart@metempsy.com            }
20013531Sjairo.balart@metempsy.com        } else {
20113531Sjairo.balart@metempsy.com            switch (group) {
20213531Sjairo.balart@metempsy.com              case Gicv3::G0S:
20313531Sjairo.balart@metempsy.com                return EnableGrp0;
20413531Sjairo.balart@metempsy.com
20513531Sjairo.balart@metempsy.com              case Gicv3::G1S:
20613531Sjairo.balart@metempsy.com              case Gicv3::G1NS:
20713531Sjairo.balart@metempsy.com                return EnableGrp1NS;
20813531Sjairo.balart@metempsy.com
20913531Sjairo.balart@metempsy.com              default:
21013531Sjairo.balart@metempsy.com                panic("Gicv3Distributor::groupEnabled(): "
21113531Sjairo.balart@metempsy.com                        "invalid group!\n");
21213531Sjairo.balart@metempsy.com            }
21313531Sjairo.balart@metempsy.com        }
21413531Sjairo.balart@metempsy.com    }
21513531Sjairo.balart@metempsy.com
21613756Sjairo.balart@metempsy.com    Gicv3::IntStatus intStatus(uint32_t int_id) const;
21713531Sjairo.balart@metempsy.com
21813813Sgiacomo.travaglini@arm.com    inline bool isNotSPI(uint32_t int_id) const
21913531Sjairo.balart@metempsy.com    {
22013531Sjairo.balart@metempsy.com        if (int_id < (Gicv3::SGI_MAX + Gicv3::PPI_MAX) || int_id >= itLines) {
22113531Sjairo.balart@metempsy.com            return true;
22213531Sjairo.balart@metempsy.com        } else {
22313531Sjairo.balart@metempsy.com            return false;
22413531Sjairo.balart@metempsy.com        }
22513531Sjairo.balart@metempsy.com    }
22613531Sjairo.balart@metempsy.com
22713813Sgiacomo.travaglini@arm.com    inline bool nsAccessToSecInt(uint32_t int_id, bool is_secure_access) const
22813531Sjairo.balart@metempsy.com    {
22913531Sjairo.balart@metempsy.com        return !DS && !is_secure_access && getIntGroup(int_id) != Gicv3::G1NS;
23013531Sjairo.balart@metempsy.com    }
23113531Sjairo.balart@metempsy.com
23213756Sjairo.balart@metempsy.com    void serialize(CheckpointOut & cp) const override;
23313756Sjairo.balart@metempsy.com    void unserialize(CheckpointIn & cp) override;
23413756Sjairo.balart@metempsy.com    void update();
23514231Sgiacomo.travaglini@arm.com    Gicv3CPUInterface* route(uint32_t int_id);
23613531Sjairo.balart@metempsy.com
23713756Sjairo.balart@metempsy.com  public:
23813756Sjairo.balart@metempsy.com
23913756Sjairo.balart@metempsy.com    Gicv3Distributor(Gicv3 * gic, uint32_t it_lines);
24013756Sjairo.balart@metempsy.com
24113756Sjairo.balart@metempsy.com    void deassertSPI(uint32_t int_id);
24214231Sgiacomo.travaglini@arm.com    void clearIrqCpuInterface(uint32_t int_id);
24313756Sjairo.balart@metempsy.com    void init();
24413756Sjairo.balart@metempsy.com    uint64_t read(Addr addr, size_t size, bool is_secure_access);
24513756Sjairo.balart@metempsy.com    void sendInt(uint32_t int_id);
24613756Sjairo.balart@metempsy.com    void write(Addr addr, uint64_t data, size_t size,
24713756Sjairo.balart@metempsy.com               bool is_secure_access);
24813531Sjairo.balart@metempsy.com};
24913531Sjairo.balart@metempsy.com
25013531Sjairo.balart@metempsy.com#endif //__DEV_ARM_GICV3_DISTRIBUTOR_H__
251