gic_v3_redistributor.hh revision 13928
112855Sgabeblack@google.com/*
212855Sgabeblack@google.com * Copyright (c) 2018 Metempsy Technology Consulting
312855Sgabeblack@google.com * All rights reserved.
412855Sgabeblack@google.com *
512855Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
612855Sgabeblack@google.com * modification, are permitted provided that the following conditions are
712855Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
812855Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
912855Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
1012855Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
1112855Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
1212855Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
1312855Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
1412855Sgabeblack@google.com * this software without specific prior written permission.
1512855Sgabeblack@google.com *
1612855Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1712855Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1812855Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1912855Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2012855Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2112855Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2212855Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2312855Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2412855Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2512855Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2612855Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2712855Sgabeblack@google.com *
2812855Sgabeblack@google.com * Authors: Jairo Balart
2912855Sgabeblack@google.com */
3012855Sgabeblack@google.com
3112855Sgabeblack@google.com#ifndef __DEV_ARM_GICV3_REDISTRIBUTOR_H__
3212855Sgabeblack@google.com#define __DEV_ARM_GICV3_REDISTRIBUTOR_H__
3312855Sgabeblack@google.com
3412855Sgabeblack@google.com#include "base/addr_range.hh"
3512855Sgabeblack@google.com#include "dev/arm/gic_v3.hh"
3612855Sgabeblack@google.com#include "sim/serialize.hh"
3712855Sgabeblack@google.com
3812855Sgabeblack@google.comclass Gicv3CPUInterface;
3912855Sgabeblack@google.comclass Gicv3Distributor;
4012855Sgabeblack@google.com
4112855Sgabeblack@google.comclass Gicv3Redistributor : public Serializable
4212855Sgabeblack@google.com{
4312855Sgabeblack@google.com  private:
4412855Sgabeblack@google.com
4512855Sgabeblack@google.com    friend class Gicv3CPUInterface;
4612855Sgabeblack@google.com    friend class Gicv3Distributor;
4712855Sgabeblack@google.com
4812855Sgabeblack@google.com  protected:
4912855Sgabeblack@google.com
5012855Sgabeblack@google.com    Gicv3 * gic;
5112855Sgabeblack@google.com    Gicv3Distributor * distributor;
5212855Sgabeblack@google.com    Gicv3CPUInterface * cpuInterface;
5312855Sgabeblack@google.com    uint32_t cpuId;
5412855Sgabeblack@google.com    PortProxy * memProxy;
5512855Sgabeblack@google.com
5612855Sgabeblack@google.com    /*
5712855Sgabeblack@google.com     * GICv3 defines 2 contiguous 64KB frames for each redistributor.
5812855Sgabeblack@google.com     * Order of frames must be RD_base, SGI_base.
5912855Sgabeblack@google.com     */
6012855Sgabeblack@google.com    static const uint32_t RD_base  = 0x0;
6112855Sgabeblack@google.com    static const uint32_t SGI_base = 0x10000;
6212855Sgabeblack@google.com
6312855Sgabeblack@google.com    enum {
6412855Sgabeblack@google.com        // Control Register
6512855Sgabeblack@google.com        GICR_CTLR  = RD_base + 0x0000,
6612855Sgabeblack@google.com        // Implementer Identification Register
6712855Sgabeblack@google.com        GICR_IIDR  = RD_base + 0x0004,
6812855Sgabeblack@google.com        // Type Register
6912855Sgabeblack@google.com        GICR_TYPER = RD_base + 0x0008,
7012855Sgabeblack@google.com        // Wake Register
7112855Sgabeblack@google.com        GICR_WAKER = RD_base + 0x0014,
7212855Sgabeblack@google.com        // Peripheral ID0 Register
7312855Sgabeblack@google.com        GICR_PIDR0 = RD_base + 0xffe0,
7412855Sgabeblack@google.com        // Peripheral ID1 Register
7512855Sgabeblack@google.com        GICR_PIDR1 = RD_base + 0xffe4,
7612855Sgabeblack@google.com        // Peripheral ID2 Register
7712855Sgabeblack@google.com        GICR_PIDR2 = RD_base + 0xffe8,
7812855Sgabeblack@google.com        // Peripheral ID3 Register
7912855Sgabeblack@google.com        GICR_PIDR3 = RD_base + 0xffec,
8012855Sgabeblack@google.com        // Peripheral ID4 Register
8112855Sgabeblack@google.com        GICR_PIDR4 = RD_base + 0xffd0,
8212855Sgabeblack@google.com        // Peripheral ID5 Register
8312855Sgabeblack@google.com        GICR_PIDR5 = RD_base + 0xffd4,
8412855Sgabeblack@google.com        // Peripheral ID6 Register
8512855Sgabeblack@google.com        GICR_PIDR6 = RD_base + 0xffd8,
8612855Sgabeblack@google.com        // Peripheral ID7 Register
8712855Sgabeblack@google.com        GICR_PIDR7 = RD_base + 0xffdc,
8812855Sgabeblack@google.com    };
8912855Sgabeblack@google.com
9012855Sgabeblack@google.com    static const uint32_t GICR_WAKER_ProcessorSleep = 1 << 1;
9112855Sgabeblack@google.com    static const uint32_t GICR_WAKER_ChildrenAsleep = 1 << 2;
9212855Sgabeblack@google.com
9312855Sgabeblack@google.com    bool peInLowPowerState;
9412855Sgabeblack@google.com
9512855Sgabeblack@google.com    enum {
9612855Sgabeblack@google.com        // Interrupt Group Register 0
9712855Sgabeblack@google.com        GICR_IGROUPR0   = SGI_base + 0x0080,
9812855Sgabeblack@google.com        // Interrupt Set-Enable Register 0
9912855Sgabeblack@google.com        GICR_ISENABLER0 = SGI_base + 0x0100,
10012855Sgabeblack@google.com        // Interrupt Clear-Enable Register 0
10112855Sgabeblack@google.com        GICR_ICENABLER0 = SGI_base + 0x0180,
10212855Sgabeblack@google.com        // Interrupt Set-Pending Register 0
10312855Sgabeblack@google.com        GICR_ISPENDR0   = SGI_base + 0x0200,
10412855Sgabeblack@google.com        // Interrupt Clear-Pending Register 0
10512855Sgabeblack@google.com        GICR_ICPENDR0   = SGI_base + 0x0280,
10612855Sgabeblack@google.com        // Interrupt Set-Active Register 0
10712855Sgabeblack@google.com        GICR_ISACTIVER0 = SGI_base + 0x0300,
10812855Sgabeblack@google.com        // Interrupt Clear-Active Register 0
10912855Sgabeblack@google.com        GICR_ICACTIVER0 = SGI_base + 0x0380,
11012855Sgabeblack@google.com        // SGI Configuration Register
11112855Sgabeblack@google.com        GICR_ICFGR0     = SGI_base + 0x0c00,
11212855Sgabeblack@google.com        // PPI Configuration Register
11312855Sgabeblack@google.com        GICR_ICFGR1     = SGI_base + 0x0c04,
11412855Sgabeblack@google.com        // Interrupt Group Modifier Register 0
11512855Sgabeblack@google.com        GICR_IGRPMODR0  = SGI_base + 0x0d00,
11612855Sgabeblack@google.com        // Non-secure Access Control Register
11712855Sgabeblack@google.com        GICR_NSACR      = SGI_base + 0x0e00,
11812855Sgabeblack@google.com    };
11912855Sgabeblack@google.com
12012855Sgabeblack@google.com    // Interrupt Priority Registers
12112855Sgabeblack@google.com    static const AddrRange GICR_IPRIORITYR;
12212855Sgabeblack@google.com
12312855Sgabeblack@google.com    // GIC physical LPI Redistributor register
12412855Sgabeblack@google.com    enum {
12512855Sgabeblack@google.com        // Set LPI Pending Register
12612855Sgabeblack@google.com        GICR_SETLPIR = RD_base + 0x0040,
12712855Sgabeblack@google.com        // Clear LPI Pending Register
12812855Sgabeblack@google.com        GICR_CLRLPIR = RD_base + 0x0048,
12912855Sgabeblack@google.com        //Redistributor Properties Base Address Register
13012855Sgabeblack@google.com        GICR_PROPBASER = RD_base + 0x0070,
13112855Sgabeblack@google.com        // Redistributor LPI Pending Table Base Address Register
13212855Sgabeblack@google.com        GICR_PENDBASER = RD_base + 0x0078,
13312855Sgabeblack@google.com        // Redistributor Invalidate LPI Register
13412855Sgabeblack@google.com        GICR_INVLPIR = RD_base + 0x00A0,
13512855Sgabeblack@google.com        // Redistributor Invalidate All Register
13612855Sgabeblack@google.com        GICR_INVALLR = RD_base + 0x00B0,
13712855Sgabeblack@google.com        // Redistributor Synchronize Register
13812855Sgabeblack@google.com        GICR_SYNCR = RD_base + 0x00C0,
13912855Sgabeblack@google.com    };
14012855Sgabeblack@google.com
14112855Sgabeblack@google.com    std::vector <uint8_t> irqGroup;
14212855Sgabeblack@google.com    std::vector <bool> irqEnabled;
14312855Sgabeblack@google.com    std::vector <bool> irqPending;
14412855Sgabeblack@google.com    std::vector <bool> irqActive;
14512855Sgabeblack@google.com    std::vector <uint8_t> irqPriority;
14612855Sgabeblack@google.com    std::vector <Gicv3::IntTriggerType> irqConfig;
14712855Sgabeblack@google.com    std::vector <uint8_t> irqGrpmod;
14812855Sgabeblack@google.com    std::vector <uint8_t> irqNsacr;
14912855Sgabeblack@google.com
15012855Sgabeblack@google.com    bool DPG1S;
15112855Sgabeblack@google.com    bool DPG1NS;
15212855Sgabeblack@google.com    bool DPG0;
15312855Sgabeblack@google.com    bool EnableLPIs;
15412855Sgabeblack@google.com
15512855Sgabeblack@google.com    Addr lpiConfigurationTablePtr;
15612855Sgabeblack@google.com    uint8_t lpiIDBits;
15712855Sgabeblack@google.com    Addr lpiPendingTablePtr;
15812855Sgabeblack@google.com
15912855Sgabeblack@google.com    BitUnion8(LPIConfigurationTableEntry)
16012855Sgabeblack@google.com        Bitfield<7, 2> priority;
16112855Sgabeblack@google.com        Bitfield<1> res1;
16212855Sgabeblack@google.com        Bitfield<0> enable;
16312855Sgabeblack@google.com    EndBitUnion(LPIConfigurationTableEntry)
16412855Sgabeblack@google.com
16512855Sgabeblack@google.com    static const uint32_t GICR_CTLR_ENABLE_LPIS = 1 << 0;
16612855Sgabeblack@google.com    static const uint32_t GICR_CTLR_DPG0   = 1 << 24;
16712855Sgabeblack@google.com    static const uint32_t GICR_CTLR_DPG1NS = 1 << 25;
16812855Sgabeblack@google.com    static const uint32_t GICR_CTLR_DPG1S  = 1 << 26;
16912855Sgabeblack@google.com
17012855Sgabeblack@google.com  public:
17112855Sgabeblack@google.com
17212855Sgabeblack@google.com    /*
17312855Sgabeblack@google.com     * GICv3 defines only 2 64K consecutive frames for the redistributor
17412855Sgabeblack@google.com     * (RD_base and SGI_base) but we are using 2 extra 64K stride frames
17512855Sgabeblack@google.com     * to match GICv4 that defines 4 64K consecutive frames for them.
17612855Sgabeblack@google.com     * Note this must match with DTB/DTS GIC node definition and boot
17712855Sgabeblack@google.com     * loader code.
17812855Sgabeblack@google.com     */
17912855Sgabeblack@google.com    const uint32_t addrRangeSize;
18012855Sgabeblack@google.com
18112855Sgabeblack@google.com    static const uint32_t SMALLEST_LPI_ID = 8192;
18212855Sgabeblack@google.com
18312855Sgabeblack@google.com
18412855Sgabeblack@google.com    void activateIRQ(uint32_t int_id);
18512855Sgabeblack@google.com    bool canBeSelectedFor1toNInterrupt(Gicv3::GroupId group) const;
18612855Sgabeblack@google.com    void deactivateIRQ(uint32_t int_id);
18712855Sgabeblack@google.com
18812855Sgabeblack@google.com    inline Gicv3CPUInterface *
18912855Sgabeblack@google.com    getCPUInterface() const
19012855Sgabeblack@google.com    {
19112855Sgabeblack@google.com        return cpuInterface;
19212855Sgabeblack@google.com    }
19312855Sgabeblack@google.com
19412855Sgabeblack@google.com    uint32_t
19512855Sgabeblack@google.com    processorNumber() const
19612855Sgabeblack@google.com    {
19712855Sgabeblack@google.com        return cpuId;
19812855Sgabeblack@google.com    }
19912855Sgabeblack@google.com
20012855Sgabeblack@google.com    Gicv3::GroupId getIntGroup(int int_id) const;
20112855Sgabeblack@google.com    Gicv3::IntStatus intStatus(uint32_t int_id) const;
20212855Sgabeblack@google.com    uint8_t readEntryLPI(uint32_t intid);
20312855Sgabeblack@google.com    void writeEntryLPI(uint32_t intid, uint8_t lpi_entry);
20412855Sgabeblack@google.com    bool isPendingLPI(uint32_t intid);
20512855Sgabeblack@google.com    void setClrLPI(uint64_t data, bool set);
20612855Sgabeblack@google.com    void reset();
20712855Sgabeblack@google.com    void sendSGI(uint32_t int_id, Gicv3::GroupId group, bool ns);
20812855Sgabeblack@google.com    void serialize(CheckpointOut & cp) const override;
20912855Sgabeblack@google.com    void unserialize(CheckpointIn & cp) override;
21012855Sgabeblack@google.com    void update();
21112855Sgabeblack@google.com    void updateAndInformCPUInterface();
21212855Sgabeblack@google.com
21312855Sgabeblack@google.com  public:
21412855Sgabeblack@google.com
21512855Sgabeblack@google.com    Gicv3Redistributor(Gicv3 * gic, uint32_t cpu_id);
21612855Sgabeblack@google.com    uint32_t getAffinity() const;
21712855Sgabeblack@google.com    void init();
21812855Sgabeblack@google.com    void initState();
21912855Sgabeblack@google.com    uint64_t read(Addr addr, size_t size, bool is_secure_access);
22012855Sgabeblack@google.com    void sendPPInt(uint32_t int_id);
22112855Sgabeblack@google.com    void write(Addr addr, uint64_t data, size_t size, bool is_secure_access);
22212855Sgabeblack@google.com};
22312855Sgabeblack@google.com
22412855Sgabeblack@google.com#endif //__DEV_ARM_GICV3_REDISTRIBUTOR_H__
22512855Sgabeblack@google.com