gic_v3_distributor.hh revision 14168
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,
7213531Sjairo.balart@metempsy.com        // Peripheral ID0 Register
7313531Sjairo.balart@metempsy.com        GICD_PIDR0 = 0xffe0,
7413531Sjairo.balart@metempsy.com        // Peripheral ID1 Register
7513531Sjairo.balart@metempsy.com        GICD_PIDR1 = 0xffe4,
7613531Sjairo.balart@metempsy.com        // Peripheral ID2 Register
7713531Sjairo.balart@metempsy.com        GICD_PIDR2 = 0xffe8,
7813531Sjairo.balart@metempsy.com        // Peripheral ID3 Register
7913531Sjairo.balart@metempsy.com        GICD_PIDR3 = 0xffec,
8013531Sjairo.balart@metempsy.com        // Peripheral ID4 Register
8113531Sjairo.balart@metempsy.com        GICD_PIDR4 = 0xffd0,
8213531Sjairo.balart@metempsy.com        // Peripheral ID5 Register
8313531Sjairo.balart@metempsy.com        GICD_PIDR5 = 0xffd4,
8413531Sjairo.balart@metempsy.com        // Peripheral ID6 Register
8513531Sjairo.balart@metempsy.com        GICD_PIDR6 = 0xffd8,
8613531Sjairo.balart@metempsy.com        // Peripheral ID7 Register
8713531Sjairo.balart@metempsy.com        GICD_PIDR7 = 0xffdc,
8813531Sjairo.balart@metempsy.com    };
8913531Sjairo.balart@metempsy.com
9013531Sjairo.balart@metempsy.com    // Interrupt Group Registers
9113531Sjairo.balart@metempsy.com    static const AddrRange GICD_IGROUPR;
9213531Sjairo.balart@metempsy.com    // Interrupt Set-Enable Registers
9313531Sjairo.balart@metempsy.com    static const AddrRange GICD_ISENABLER;
9413531Sjairo.balart@metempsy.com    // Interrupt Clear-Enable Registers
9513531Sjairo.balart@metempsy.com    static const AddrRange GICD_ICENABLER;
9613531Sjairo.balart@metempsy.com    // Interrupt Set-Pending Registers
9713531Sjairo.balart@metempsy.com    static const AddrRange GICD_ISPENDR;
9813531Sjairo.balart@metempsy.com    // Interrupt Clear-Pending Registers
9913531Sjairo.balart@metempsy.com    static const AddrRange GICD_ICPENDR;
10013531Sjairo.balart@metempsy.com    // Interrupt Set-Active Registers
10113531Sjairo.balart@metempsy.com    static const AddrRange GICD_ISACTIVER;
10213531Sjairo.balart@metempsy.com    // Interrupt Clear-Active Registers
10313531Sjairo.balart@metempsy.com    static const AddrRange GICD_ICACTIVER;
10413531Sjairo.balart@metempsy.com    // Interrupt Priority Registers
10513531Sjairo.balart@metempsy.com    static const AddrRange GICD_IPRIORITYR;
10613531Sjairo.balart@metempsy.com    // Interrupt Processor Targets Registers
10713531Sjairo.balart@metempsy.com    static const AddrRange GICD_ITARGETSR; // GICv2 legacy
10813531Sjairo.balart@metempsy.com    // Interrupt Configuration Registers
10913531Sjairo.balart@metempsy.com    static const AddrRange GICD_ICFGR;
11013531Sjairo.balart@metempsy.com    // Interrupt Group Modifier Registers
11113531Sjairo.balart@metempsy.com    static const AddrRange GICD_IGRPMODR;
11213531Sjairo.balart@metempsy.com    // Non-secure Access Control Registers
11313531Sjairo.balart@metempsy.com    static const AddrRange GICD_NSACR;
11413531Sjairo.balart@metempsy.com    // SGI Clear-Pending Registers
11513531Sjairo.balart@metempsy.com    static const AddrRange GICD_CPENDSGIR; // GICv2 legacy
11613531Sjairo.balart@metempsy.com    // SGI Set-Pending Registers
11713531Sjairo.balart@metempsy.com    static const AddrRange GICD_SPENDSGIR; // GICv2 legacy
11813531Sjairo.balart@metempsy.com    // Interrupt Routing Registers
11913531Sjairo.balart@metempsy.com    static const AddrRange GICD_IROUTER;
12013531Sjairo.balart@metempsy.com
12113531Sjairo.balart@metempsy.com    BitUnion64(IROUTER)
12213756Sjairo.balart@metempsy.com        Bitfield<63, 40> res0_1;
12313756Sjairo.balart@metempsy.com        Bitfield<39, 32> Aff3;
12413756Sjairo.balart@metempsy.com        Bitfield<31>     IRM;
12513756Sjairo.balart@metempsy.com        Bitfield<30, 24> res0_2;
12613756Sjairo.balart@metempsy.com        Bitfield<23, 16> Aff2;
12713756Sjairo.balart@metempsy.com        Bitfield<15, 8>  Aff1;
12813756Sjairo.balart@metempsy.com        Bitfield<7, 0>   Aff0;
12913531Sjairo.balart@metempsy.com    EndBitUnion(IROUTER)
13013531Sjairo.balart@metempsy.com
13113756Sjairo.balart@metempsy.com    static const uint32_t GICD_CTLR_ENABLEGRP0   = 1 << 0;
13213756Sjairo.balart@metempsy.com    static const uint32_t GICD_CTLR_ENABLEGRP1   = 1 << 0;
13313531Sjairo.balart@metempsy.com    static const uint32_t GICD_CTLR_ENABLEGRP1NS = 1 << 1;
13413756Sjairo.balart@metempsy.com    static const uint32_t GICD_CTLR_ENABLEGRP1A  = 1 << 1;
13513756Sjairo.balart@metempsy.com    static const uint32_t GICD_CTLR_ENABLEGRP1S  = 1 << 2;
13613756Sjairo.balart@metempsy.com    static const uint32_t GICD_CTLR_DS           = 1 << 6;
13713531Sjairo.balart@metempsy.com
13813531Sjairo.balart@metempsy.com    bool ARE;
13913531Sjairo.balart@metempsy.com    bool DS;
14013531Sjairo.balart@metempsy.com    bool EnableGrp1S;
14113531Sjairo.balart@metempsy.com    bool EnableGrp1NS;
14213531Sjairo.balart@metempsy.com    bool EnableGrp0;
14313531Sjairo.balart@metempsy.com    std::vector <uint8_t> irqGroup;
14413531Sjairo.balart@metempsy.com    std::vector <bool> irqEnabled;
14513531Sjairo.balart@metempsy.com    std::vector <bool> irqPending;
14613531Sjairo.balart@metempsy.com    std::vector <bool> irqActive;
14713531Sjairo.balart@metempsy.com    std::vector <uint8_t> irqPriority;
14813531Sjairo.balart@metempsy.com    std::vector <Gicv3::IntTriggerType> irqConfig;
14913531Sjairo.balart@metempsy.com    std::vector <uint8_t> irqGrpmod;
15013531Sjairo.balart@metempsy.com    std::vector <uint8_t> irqNsacr;
15113531Sjairo.balart@metempsy.com    std::vector <IROUTER> irqAffinityRouting;
15213531Sjairo.balart@metempsy.com
15314167Sgiacomo.travaglini@arm.com    uint32_t gicdPidr0;
15414167Sgiacomo.travaglini@arm.com    uint32_t gicdPidr1;
15514167Sgiacomo.travaglini@arm.com    uint32_t gicdPidr2;
15614167Sgiacomo.travaglini@arm.com    uint32_t gicdPidr3;
15714167Sgiacomo.travaglini@arm.com    uint32_t gicdPidr4;
15814167Sgiacomo.travaglini@arm.com
15913531Sjairo.balart@metempsy.com  public:
16013531Sjairo.balart@metempsy.com
16113531Sjairo.balart@metempsy.com    static const uint32_t ADDR_RANGE_SIZE = 0x10000;
16213927Sgiacomo.travaglini@arm.com    static const uint32_t IDBITS = 0xf;
16313531Sjairo.balart@metempsy.com
16413756Sjairo.balart@metempsy.com  protected:
16513531Sjairo.balart@metempsy.com
16613756Sjairo.balart@metempsy.com    void activateIRQ(uint32_t int_id);
16713756Sjairo.balart@metempsy.com    void deactivateIRQ(uint32_t int_id);
16813756Sjairo.balart@metempsy.com    void fullUpdate();
16913756Sjairo.balart@metempsy.com    Gicv3::GroupId getIntGroup(int int_id) const;
17013531Sjairo.balart@metempsy.com
17113756Sjairo.balart@metempsy.com    inline bool
17213756Sjairo.balart@metempsy.com    groupEnabled(Gicv3::GroupId group) const
17313531Sjairo.balart@metempsy.com    {
17413531Sjairo.balart@metempsy.com        if (DS == 0) {
17513531Sjairo.balart@metempsy.com            switch (group) {
17613531Sjairo.balart@metempsy.com              case Gicv3::G0S:
17713531Sjairo.balart@metempsy.com                return EnableGrp0;
17813531Sjairo.balart@metempsy.com
17913531Sjairo.balart@metempsy.com              case Gicv3::G1S:
18013531Sjairo.balart@metempsy.com                return EnableGrp1S;
18113531Sjairo.balart@metempsy.com
18213531Sjairo.balart@metempsy.com              case Gicv3::G1NS:
18313531Sjairo.balart@metempsy.com                return EnableGrp1NS;
18413531Sjairo.balart@metempsy.com
18513531Sjairo.balart@metempsy.com              default:
18613531Sjairo.balart@metempsy.com                panic("Gicv3Distributor::groupEnabled(): "
18713531Sjairo.balart@metempsy.com                        "invalid group!\n");
18813531Sjairo.balart@metempsy.com            }
18913531Sjairo.balart@metempsy.com        } else {
19013531Sjairo.balart@metempsy.com            switch (group) {
19113531Sjairo.balart@metempsy.com              case Gicv3::G0S:
19213531Sjairo.balart@metempsy.com                return EnableGrp0;
19313531Sjairo.balart@metempsy.com
19413531Sjairo.balart@metempsy.com              case Gicv3::G1S:
19513531Sjairo.balart@metempsy.com              case Gicv3::G1NS:
19613531Sjairo.balart@metempsy.com                return EnableGrp1NS;
19713531Sjairo.balart@metempsy.com
19813531Sjairo.balart@metempsy.com              default:
19913531Sjairo.balart@metempsy.com                panic("Gicv3Distributor::groupEnabled(): "
20013531Sjairo.balart@metempsy.com                        "invalid group!\n");
20113531Sjairo.balart@metempsy.com            }
20213531Sjairo.balart@metempsy.com        }
20313531Sjairo.balart@metempsy.com    }
20413531Sjairo.balart@metempsy.com
20513756Sjairo.balart@metempsy.com    Gicv3::IntStatus intStatus(uint32_t int_id) const;
20613531Sjairo.balart@metempsy.com
20713813Sgiacomo.travaglini@arm.com    inline bool isNotSPI(uint32_t int_id) const
20813531Sjairo.balart@metempsy.com    {
20913531Sjairo.balart@metempsy.com        if (int_id < (Gicv3::SGI_MAX + Gicv3::PPI_MAX) || int_id >= itLines) {
21013531Sjairo.balart@metempsy.com            return true;
21113531Sjairo.balart@metempsy.com        } else {
21213531Sjairo.balart@metempsy.com            return false;
21313531Sjairo.balart@metempsy.com        }
21413531Sjairo.balart@metempsy.com    }
21513531Sjairo.balart@metempsy.com
21613813Sgiacomo.travaglini@arm.com    inline bool nsAccessToSecInt(uint32_t int_id, bool is_secure_access) const
21713531Sjairo.balart@metempsy.com    {
21813531Sjairo.balart@metempsy.com        return !DS && !is_secure_access && getIntGroup(int_id) != Gicv3::G1NS;
21913531Sjairo.balart@metempsy.com    }
22013531Sjairo.balart@metempsy.com
22113756Sjairo.balart@metempsy.com    void reset();
22213756Sjairo.balart@metempsy.com    void serialize(CheckpointOut & cp) const override;
22313756Sjairo.balart@metempsy.com    void unserialize(CheckpointIn & cp) override;
22413756Sjairo.balart@metempsy.com    void update();
22513756Sjairo.balart@metempsy.com    void updateAndInformCPUInterfaces();
22613531Sjairo.balart@metempsy.com
22713756Sjairo.balart@metempsy.com  public:
22813756Sjairo.balart@metempsy.com
22913756Sjairo.balart@metempsy.com    Gicv3Distributor(Gicv3 * gic, uint32_t it_lines);
23013756Sjairo.balart@metempsy.com
23113756Sjairo.balart@metempsy.com    void deassertSPI(uint32_t int_id);
23213756Sjairo.balart@metempsy.com    void init();
23313756Sjairo.balart@metempsy.com    void initState();
23413756Sjairo.balart@metempsy.com    uint64_t read(Addr addr, size_t size, bool is_secure_access);
23513756Sjairo.balart@metempsy.com    void sendInt(uint32_t int_id);
23613756Sjairo.balart@metempsy.com    void write(Addr addr, uint64_t data, size_t size,
23713756Sjairo.balart@metempsy.com               bool is_secure_access);
23813531Sjairo.balart@metempsy.com};
23913531Sjairo.balart@metempsy.com
24013531Sjairo.balart@metempsy.com#endif //__DEV_ARM_GICV3_DISTRIBUTOR_H__
241