gic_v3_redistributor.hh revision 14231
113531Sjairo.balart@metempsy.com/*
213531Sjairo.balart@metempsy.com * Copyright (c) 2018 Metempsy Technology Consulting
313531Sjairo.balart@metempsy.com * All rights reserved.
413531Sjairo.balart@metempsy.com *
513531Sjairo.balart@metempsy.com * Redistribution and use in source and binary forms, with or without
613531Sjairo.balart@metempsy.com * modification, are permitted provided that the following conditions are
713531Sjairo.balart@metempsy.com * met: redistributions of source code must retain the above copyright
813531Sjairo.balart@metempsy.com * notice, this list of conditions and the following disclaimer;
913531Sjairo.balart@metempsy.com * redistributions in binary form must reproduce the above copyright
1013531Sjairo.balart@metempsy.com * notice, this list of conditions and the following disclaimer in the
1113531Sjairo.balart@metempsy.com * documentation and/or other materials provided with the distribution;
1213531Sjairo.balart@metempsy.com * neither the name of the copyright holders nor the names of its
1313531Sjairo.balart@metempsy.com * contributors may be used to endorse or promote products derived from
1413531Sjairo.balart@metempsy.com * this software without specific prior written permission.
1513531Sjairo.balart@metempsy.com *
1613531Sjairo.balart@metempsy.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1713531Sjairo.balart@metempsy.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1813531Sjairo.balart@metempsy.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1913531Sjairo.balart@metempsy.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2013531Sjairo.balart@metempsy.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2113531Sjairo.balart@metempsy.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2213531Sjairo.balart@metempsy.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2313531Sjairo.balart@metempsy.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2413531Sjairo.balart@metempsy.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2513531Sjairo.balart@metempsy.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2613531Sjairo.balart@metempsy.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2713531Sjairo.balart@metempsy.com *
2813531Sjairo.balart@metempsy.com * Authors: Jairo Balart
2913531Sjairo.balart@metempsy.com */
3013531Sjairo.balart@metempsy.com
3113531Sjairo.balart@metempsy.com#ifndef __DEV_ARM_GICV3_REDISTRIBUTOR_H__
3213531Sjairo.balart@metempsy.com#define __DEV_ARM_GICV3_REDISTRIBUTOR_H__
3313531Sjairo.balart@metempsy.com
3413531Sjairo.balart@metempsy.com#include "base/addr_range.hh"
3513531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3.hh"
3613531Sjairo.balart@metempsy.com#include "sim/serialize.hh"
3713531Sjairo.balart@metempsy.com
3813756Sjairo.balart@metempsy.comclass Gicv3CPUInterface;
3913531Sjairo.balart@metempsy.comclass Gicv3Distributor;
4013996Sgiacomo.travaglini@arm.comclass Gicv3Its;
4113531Sjairo.balart@metempsy.com
4213531Sjairo.balart@metempsy.comclass Gicv3Redistributor : public Serializable
4313531Sjairo.balart@metempsy.com{
4413531Sjairo.balart@metempsy.com  private:
4513531Sjairo.balart@metempsy.com
4613531Sjairo.balart@metempsy.com    friend class Gicv3CPUInterface;
4713531Sjairo.balart@metempsy.com    friend class Gicv3Distributor;
4813996Sgiacomo.travaglini@arm.com    friend class Gicv3Its;
4913531Sjairo.balart@metempsy.com
5013531Sjairo.balart@metempsy.com  protected:
5113531Sjairo.balart@metempsy.com
5213531Sjairo.balart@metempsy.com    Gicv3 * gic;
5313531Sjairo.balart@metempsy.com    Gicv3Distributor * distributor;
5413531Sjairo.balart@metempsy.com    Gicv3CPUInterface * cpuInterface;
5513531Sjairo.balart@metempsy.com    uint32_t cpuId;
5613928Sgiacomo.travaglini@arm.com    PortProxy * memProxy;
5713531Sjairo.balart@metempsy.com
5813531Sjairo.balart@metempsy.com    /*
5913531Sjairo.balart@metempsy.com     * GICv3 defines 2 contiguous 64KB frames for each redistributor.
6013531Sjairo.balart@metempsy.com     * Order of frames must be RD_base, SGI_base.
6113531Sjairo.balart@metempsy.com     */
6213756Sjairo.balart@metempsy.com    static const uint32_t RD_base  = 0x0;
6313531Sjairo.balart@metempsy.com    static const uint32_t SGI_base = 0x10000;
6413531Sjairo.balart@metempsy.com
6513531Sjairo.balart@metempsy.com    enum {
6613531Sjairo.balart@metempsy.com        // Control Register
6713531Sjairo.balart@metempsy.com        GICR_CTLR  = RD_base + 0x0000,
6813531Sjairo.balart@metempsy.com        // Implementer Identification Register
6913756Sjairo.balart@metempsy.com        GICR_IIDR  = RD_base + 0x0004,
7013531Sjairo.balart@metempsy.com        // Type Register
7113531Sjairo.balart@metempsy.com        GICR_TYPER = RD_base + 0x0008,
7213531Sjairo.balart@metempsy.com        // Wake Register
7313531Sjairo.balart@metempsy.com        GICR_WAKER = RD_base + 0x0014,
7413531Sjairo.balart@metempsy.com        // Peripheral ID0 Register
7513531Sjairo.balart@metempsy.com        GICR_PIDR0 = RD_base + 0xffe0,
7613531Sjairo.balart@metempsy.com        // Peripheral ID1 Register
7713531Sjairo.balart@metempsy.com        GICR_PIDR1 = RD_base + 0xffe4,
7813531Sjairo.balart@metempsy.com        // Peripheral ID2 Register
7913531Sjairo.balart@metempsy.com        GICR_PIDR2 = RD_base + 0xffe8,
8013531Sjairo.balart@metempsy.com        // Peripheral ID3 Register
8113531Sjairo.balart@metempsy.com        GICR_PIDR3 = RD_base + 0xffec,
8213531Sjairo.balart@metempsy.com        // Peripheral ID4 Register
8313531Sjairo.balart@metempsy.com        GICR_PIDR4 = RD_base + 0xffd0,
8413531Sjairo.balart@metempsy.com        // Peripheral ID5 Register
8513531Sjairo.balart@metempsy.com        GICR_PIDR5 = RD_base + 0xffd4,
8613531Sjairo.balart@metempsy.com        // Peripheral ID6 Register
8713531Sjairo.balart@metempsy.com        GICR_PIDR6 = RD_base + 0xffd8,
8813531Sjairo.balart@metempsy.com        // Peripheral ID7 Register
8913531Sjairo.balart@metempsy.com        GICR_PIDR7 = RD_base + 0xffdc,
9013531Sjairo.balart@metempsy.com    };
9113531Sjairo.balart@metempsy.com
9213531Sjairo.balart@metempsy.com    static const uint32_t GICR_WAKER_ProcessorSleep = 1 << 1;
9313531Sjairo.balart@metempsy.com    static const uint32_t GICR_WAKER_ChildrenAsleep = 1 << 2;
9413531Sjairo.balart@metempsy.com
9513531Sjairo.balart@metempsy.com    bool peInLowPowerState;
9613531Sjairo.balart@metempsy.com
9713531Sjairo.balart@metempsy.com    enum {
9813531Sjairo.balart@metempsy.com        // Interrupt Group Register 0
9913531Sjairo.balart@metempsy.com        GICR_IGROUPR0   = SGI_base + 0x0080,
10013531Sjairo.balart@metempsy.com        // Interrupt Set-Enable Register 0
10113531Sjairo.balart@metempsy.com        GICR_ISENABLER0 = SGI_base + 0x0100,
10213531Sjairo.balart@metempsy.com        // Interrupt Clear-Enable Register 0
10313531Sjairo.balart@metempsy.com        GICR_ICENABLER0 = SGI_base + 0x0180,
10413531Sjairo.balart@metempsy.com        // Interrupt Set-Pending Register 0
10513756Sjairo.balart@metempsy.com        GICR_ISPENDR0   = SGI_base + 0x0200,
10613531Sjairo.balart@metempsy.com        // Interrupt Clear-Pending Register 0
10713756Sjairo.balart@metempsy.com        GICR_ICPENDR0   = SGI_base + 0x0280,
10813531Sjairo.balart@metempsy.com        // Interrupt Set-Active Register 0
10913531Sjairo.balart@metempsy.com        GICR_ISACTIVER0 = SGI_base + 0x0300,
11013531Sjairo.balart@metempsy.com        // Interrupt Clear-Active Register 0
11113531Sjairo.balart@metempsy.com        GICR_ICACTIVER0 = SGI_base + 0x0380,
11213531Sjairo.balart@metempsy.com        // SGI Configuration Register
11313756Sjairo.balart@metempsy.com        GICR_ICFGR0     = SGI_base + 0x0c00,
11413531Sjairo.balart@metempsy.com        // PPI Configuration Register
11513756Sjairo.balart@metempsy.com        GICR_ICFGR1     = SGI_base + 0x0c04,
11613531Sjairo.balart@metempsy.com        // Interrupt Group Modifier Register 0
11713756Sjairo.balart@metempsy.com        GICR_IGRPMODR0  = SGI_base + 0x0d00,
11813531Sjairo.balart@metempsy.com        // Non-secure Access Control Register
11913756Sjairo.balart@metempsy.com        GICR_NSACR      = SGI_base + 0x0e00,
12013531Sjairo.balart@metempsy.com    };
12113531Sjairo.balart@metempsy.com
12213531Sjairo.balart@metempsy.com    // Interrupt Priority Registers
12313531Sjairo.balart@metempsy.com    static const AddrRange GICR_IPRIORITYR;
12413531Sjairo.balart@metempsy.com
12513690Sjairo.balart@metempsy.com    // GIC physical LPI Redistributor register
12613690Sjairo.balart@metempsy.com    enum {
12713690Sjairo.balart@metempsy.com        // Set LPI Pending Register
12813690Sjairo.balart@metempsy.com        GICR_SETLPIR = RD_base + 0x0040,
12913690Sjairo.balart@metempsy.com        // Clear LPI Pending Register
13013690Sjairo.balart@metempsy.com        GICR_CLRLPIR = RD_base + 0x0048,
13113690Sjairo.balart@metempsy.com        //Redistributor Properties Base Address Register
13213690Sjairo.balart@metempsy.com        GICR_PROPBASER = RD_base + 0x0070,
13313690Sjairo.balart@metempsy.com        // Redistributor LPI Pending Table Base Address Register
13413690Sjairo.balart@metempsy.com        GICR_PENDBASER = RD_base + 0x0078,
13513690Sjairo.balart@metempsy.com        // Redistributor Invalidate LPI Register
13613690Sjairo.balart@metempsy.com        GICR_INVLPIR = RD_base + 0x00A0,
13713690Sjairo.balart@metempsy.com        // Redistributor Invalidate All Register
13813690Sjairo.balart@metempsy.com        GICR_INVALLR = RD_base + 0x00B0,
13913690Sjairo.balart@metempsy.com        // Redistributor Synchronize Register
14013690Sjairo.balart@metempsy.com        GICR_SYNCR = RD_base + 0x00C0,
14113690Sjairo.balart@metempsy.com    };
14213690Sjairo.balart@metempsy.com
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
15213531Sjairo.balart@metempsy.com    bool DPG1S;
15313531Sjairo.balart@metempsy.com    bool DPG1NS;
15413531Sjairo.balart@metempsy.com    bool DPG0;
15513690Sjairo.balart@metempsy.com    bool EnableLPIs;
15613531Sjairo.balart@metempsy.com
15713690Sjairo.balart@metempsy.com    Addr lpiConfigurationTablePtr;
15813690Sjairo.balart@metempsy.com    uint8_t lpiIDBits;
15913690Sjairo.balart@metempsy.com    Addr lpiPendingTablePtr;
16013690Sjairo.balart@metempsy.com
16113690Sjairo.balart@metempsy.com    BitUnion8(LPIConfigurationTableEntry)
16213690Sjairo.balart@metempsy.com        Bitfield<7, 2> priority;
16313690Sjairo.balart@metempsy.com        Bitfield<1> res1;
16413690Sjairo.balart@metempsy.com        Bitfield<0> enable;
16513690Sjairo.balart@metempsy.com    EndBitUnion(LPIConfigurationTableEntry)
16613690Sjairo.balart@metempsy.com
16713690Sjairo.balart@metempsy.com    static const uint32_t GICR_CTLR_ENABLE_LPIS = 1 << 0;
16813756Sjairo.balart@metempsy.com    static const uint32_t GICR_CTLR_DPG0   = 1 << 24;
16913531Sjairo.balart@metempsy.com    static const uint32_t GICR_CTLR_DPG1NS = 1 << 25;
17013756Sjairo.balart@metempsy.com    static const uint32_t GICR_CTLR_DPG1S  = 1 << 26;
17113531Sjairo.balart@metempsy.com
17213531Sjairo.balart@metempsy.com  public:
17313531Sjairo.balart@metempsy.com
17413531Sjairo.balart@metempsy.com    /*
17513531Sjairo.balart@metempsy.com     * GICv3 defines only 2 64K consecutive frames for the redistributor
17613531Sjairo.balart@metempsy.com     * (RD_base and SGI_base) but we are using 2 extra 64K stride frames
17713531Sjairo.balart@metempsy.com     * to match GICv4 that defines 4 64K consecutive frames for them.
17813531Sjairo.balart@metempsy.com     * Note this must match with DTB/DTS GIC node definition and boot
17913531Sjairo.balart@metempsy.com     * loader code.
18013531Sjairo.balart@metempsy.com     */
18113878Sgiacomo.travaglini@arm.com    const uint32_t addrRangeSize;
18213531Sjairo.balart@metempsy.com
18313690Sjairo.balart@metempsy.com    static const uint32_t SMALLEST_LPI_ID = 8192;
18413690Sjairo.balart@metempsy.com
18513531Sjairo.balart@metempsy.com
18613756Sjairo.balart@metempsy.com    void activateIRQ(uint32_t int_id);
18713756Sjairo.balart@metempsy.com    bool canBeSelectedFor1toNInterrupt(Gicv3::GroupId group) const;
18813756Sjairo.balart@metempsy.com    void deactivateIRQ(uint32_t int_id);
18913531Sjairo.balart@metempsy.com
19013756Sjairo.balart@metempsy.com    inline Gicv3CPUInterface *
19113531Sjairo.balart@metempsy.com    getCPUInterface() const
19213531Sjairo.balart@metempsy.com    {
19313531Sjairo.balart@metempsy.com        return cpuInterface;
19413531Sjairo.balart@metempsy.com    }
19513531Sjairo.balart@metempsy.com
19613924Sgiacomo.travaglini@arm.com    uint32_t
19713924Sgiacomo.travaglini@arm.com    processorNumber() const
19813924Sgiacomo.travaglini@arm.com    {
19913924Sgiacomo.travaglini@arm.com        return cpuId;
20013924Sgiacomo.travaglini@arm.com    }
20113924Sgiacomo.travaglini@arm.com
20213756Sjairo.balart@metempsy.com    Gicv3::GroupId getIntGroup(int int_id) const;
20313756Sjairo.balart@metempsy.com    Gicv3::IntStatus intStatus(uint32_t int_id) const;
20413924Sgiacomo.travaglini@arm.com    uint8_t readEntryLPI(uint32_t intid);
20513924Sgiacomo.travaglini@arm.com    void writeEntryLPI(uint32_t intid, uint8_t lpi_entry);
20613924Sgiacomo.travaglini@arm.com    bool isPendingLPI(uint32_t intid);
20713690Sjairo.balart@metempsy.com    void setClrLPI(uint64_t data, bool set);
20813531Sjairo.balart@metempsy.com    void reset();
20913756Sjairo.balart@metempsy.com    void sendSGI(uint32_t int_id, Gicv3::GroupId group, bool ns);
21013756Sjairo.balart@metempsy.com    void serialize(CheckpointOut & cp) const override;
21113756Sjairo.balart@metempsy.com    void unserialize(CheckpointIn & cp) override;
21213531Sjairo.balart@metempsy.com    void update();
21314231Sgiacomo.travaglini@arm.com    void updateDistributor();
21413756Sjairo.balart@metempsy.com
21513756Sjairo.balart@metempsy.com  public:
21613756Sjairo.balart@metempsy.com
21713756Sjairo.balart@metempsy.com    Gicv3Redistributor(Gicv3 * gic, uint32_t cpu_id);
21813756Sjairo.balart@metempsy.com    uint32_t getAffinity() const;
21913756Sjairo.balart@metempsy.com    void init();
22013756Sjairo.balart@metempsy.com    void initState();
22113756Sjairo.balart@metempsy.com    uint64_t read(Addr addr, size_t size, bool is_secure_access);
22213756Sjairo.balart@metempsy.com    void sendPPInt(uint32_t int_id);
22313756Sjairo.balart@metempsy.com    void write(Addr addr, uint64_t data, size_t size, bool is_secure_access);
22413531Sjairo.balart@metempsy.com};
22513531Sjairo.balart@metempsy.com
22613531Sjairo.balart@metempsy.com#endif //__DEV_ARM_GICV3_REDISTRIBUTOR_H__
227