gic_v3_redistributor.hh revision 13878
18442Sgblack@eecs.umich.edu/*
28442Sgblack@eecs.umich.edu * Copyright (c) 2018 Metempsy Technology Consulting
311328Ssteve.reinhardt@amd.com * All rights reserved.
48442Sgblack@eecs.umich.edu *
58442Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
68442Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
78442Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
88442Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
98442Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
108442Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
118442Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
128442Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
138442Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
148442Sgblack@eecs.umich.edu * this software without specific prior written permission.
158442Sgblack@eecs.umich.edu *
168442Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
178442Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
188442Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
198442Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
208442Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
218442Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
228442Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
238442Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
248442Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
258442Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
268442Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
278442Sgblack@eecs.umich.edu *
288442Sgblack@eecs.umich.edu * Authors: Jairo Balart
298442Sgblack@eecs.umich.edu */
308442Sgblack@eecs.umich.edu
318442Sgblack@eecs.umich.edu#ifndef __DEV_ARM_GICV3_REDISTRIBUTOR_H__
328442Sgblack@eecs.umich.edu#define __DEV_ARM_GICV3_REDISTRIBUTOR_H__
338442Sgblack@eecs.umich.edu
348442Sgblack@eecs.umich.edu#include "base/addr_range.hh"
3511328Ssteve.reinhardt@amd.com#include "dev/arm/gic_v3.hh"
3611328Ssteve.reinhardt@amd.com#include "sim/serialize.hh"
378442Sgblack@eecs.umich.edu
388442Sgblack@eecs.umich.educlass Gicv3CPUInterface;
398442Sgblack@eecs.umich.educlass Gicv3Distributor;
408442Sgblack@eecs.umich.edu
418442Sgblack@eecs.umich.educlass Gicv3Redistributor : public Serializable
428442Sgblack@eecs.umich.edu{
438442Sgblack@eecs.umich.edu  private:
4411303Ssteve.reinhardt@amd.com
458442Sgblack@eecs.umich.edu    friend class Gicv3CPUInterface;
468442Sgblack@eecs.umich.edu    friend class Gicv3Distributor;
4711303Ssteve.reinhardt@amd.com
4811303Ssteve.reinhardt@amd.com  protected:
498442Sgblack@eecs.umich.edu
5011303Ssteve.reinhardt@amd.com    Gicv3 * gic;
518442Sgblack@eecs.umich.edu    Gicv3Distributor * distributor;
528442Sgblack@eecs.umich.edu    Gicv3CPUInterface * cpuInterface;
5311328Ssteve.reinhardt@amd.com    uint32_t cpuId;
5411328Ssteve.reinhardt@amd.com
5511328Ssteve.reinhardt@amd.com    /*
568442Sgblack@eecs.umich.edu     * GICv3 defines 2 contiguous 64KB frames for each redistributor.
578442Sgblack@eecs.umich.edu     * Order of frames must be RD_base, SGI_base.
588442Sgblack@eecs.umich.edu     */
598442Sgblack@eecs.umich.edu    static const uint32_t RD_base  = 0x0;
608442Sgblack@eecs.umich.edu    static const uint32_t SGI_base = 0x10000;
618442Sgblack@eecs.umich.edu
628442Sgblack@eecs.umich.edu    enum {
638442Sgblack@eecs.umich.edu        // Control Register
648442Sgblack@eecs.umich.edu        GICR_CTLR  = RD_base + 0x0000,
658442Sgblack@eecs.umich.edu        // Implementer Identification Register
668442Sgblack@eecs.umich.edu        GICR_IIDR  = RD_base + 0x0004,
678442Sgblack@eecs.umich.edu        // Type Register
688442Sgblack@eecs.umich.edu        GICR_TYPER = RD_base + 0x0008,
698442Sgblack@eecs.umich.edu        // Wake Register
708442Sgblack@eecs.umich.edu        GICR_WAKER = RD_base + 0x0014,
718442Sgblack@eecs.umich.edu        // Peripheral ID0 Register
728442Sgblack@eecs.umich.edu        GICR_PIDR0 = RD_base + 0xffe0,
738442Sgblack@eecs.umich.edu        // Peripheral ID1 Register
748442Sgblack@eecs.umich.edu        GICR_PIDR1 = RD_base + 0xffe4,
758442Sgblack@eecs.umich.edu        // Peripheral ID2 Register
768442Sgblack@eecs.umich.edu        GICR_PIDR2 = RD_base + 0xffe8,
7711328Ssteve.reinhardt@amd.com        // Peripheral ID3 Register
7811328Ssteve.reinhardt@amd.com        GICR_PIDR3 = RD_base + 0xffec,
7911328Ssteve.reinhardt@amd.com        // Peripheral ID4 Register
8011328Ssteve.reinhardt@amd.com        GICR_PIDR4 = RD_base + 0xffd0,
8111328Ssteve.reinhardt@amd.com        // Peripheral ID5 Register
8211328Ssteve.reinhardt@amd.com        GICR_PIDR5 = RD_base + 0xffd4,
8311328Ssteve.reinhardt@amd.com        // Peripheral ID6 Register
8411328Ssteve.reinhardt@amd.com        GICR_PIDR6 = RD_base + 0xffd8,
8511328Ssteve.reinhardt@amd.com        // Peripheral ID7 Register
8611328Ssteve.reinhardt@amd.com        GICR_PIDR7 = RD_base + 0xffdc,
8711328Ssteve.reinhardt@amd.com    };
8811328Ssteve.reinhardt@amd.com
8911328Ssteve.reinhardt@amd.com    static const uint32_t GICR_WAKER_ProcessorSleep = 1 << 1;
9011328Ssteve.reinhardt@amd.com    static const uint32_t GICR_WAKER_ChildrenAsleep = 1 << 2;
9111328Ssteve.reinhardt@amd.com
9211328Ssteve.reinhardt@amd.com    bool peInLowPowerState;
9311328Ssteve.reinhardt@amd.com
9411328Ssteve.reinhardt@amd.com    enum {
9511328Ssteve.reinhardt@amd.com        // Interrupt Group Register 0
9611328Ssteve.reinhardt@amd.com        GICR_IGROUPR0   = SGI_base + 0x0080,
9711328Ssteve.reinhardt@amd.com        // Interrupt Set-Enable Register 0
9811328Ssteve.reinhardt@amd.com        GICR_ISENABLER0 = SGI_base + 0x0100,
9911328Ssteve.reinhardt@amd.com        // Interrupt Clear-Enable Register 0
1008442Sgblack@eecs.umich.edu        GICR_ICENABLER0 = SGI_base + 0x0180,
1018442Sgblack@eecs.umich.edu        // Interrupt Set-Pending Register 0
1028442Sgblack@eecs.umich.edu        GICR_ISPENDR0   = SGI_base + 0x0200,
1038442Sgblack@eecs.umich.edu        // Interrupt Clear-Pending Register 0
1048442Sgblack@eecs.umich.edu        GICR_ICPENDR0   = SGI_base + 0x0280,
1058442Sgblack@eecs.umich.edu        // Interrupt Set-Active Register 0
10611301Ssteve.reinhardt@amd.com        GICR_ISACTIVER0 = SGI_base + 0x0300,
1078442Sgblack@eecs.umich.edu        // Interrupt Clear-Active Register 0
1088442Sgblack@eecs.umich.edu        GICR_ICACTIVER0 = SGI_base + 0x0380,
1098442Sgblack@eecs.umich.edu        // SGI Configuration Register
1108442Sgblack@eecs.umich.edu        GICR_ICFGR0     = SGI_base + 0x0c00,
1118442Sgblack@eecs.umich.edu        // PPI Configuration Register
1128442Sgblack@eecs.umich.edu        GICR_ICFGR1     = SGI_base + 0x0c04,
1138442Sgblack@eecs.umich.edu        // Interrupt Group Modifier Register 0
1148442Sgblack@eecs.umich.edu        GICR_IGRPMODR0  = SGI_base + 0x0d00,
1158442Sgblack@eecs.umich.edu        // Non-secure Access Control Register
1168442Sgblack@eecs.umich.edu        GICR_NSACR      = SGI_base + 0x0e00,
1178442Sgblack@eecs.umich.edu    };
11811328Ssteve.reinhardt@amd.com
11911328Ssteve.reinhardt@amd.com    // Interrupt Priority Registers
12011328Ssteve.reinhardt@amd.com    static const AddrRange GICR_IPRIORITYR;
12111328Ssteve.reinhardt@amd.com
12211328Ssteve.reinhardt@amd.com    // GIC physical LPI Redistributor register
12311328Ssteve.reinhardt@amd.com    enum {
12411328Ssteve.reinhardt@amd.com        // Set LPI Pending Register
12511328Ssteve.reinhardt@amd.com        GICR_SETLPIR = RD_base + 0x0040,
12611328Ssteve.reinhardt@amd.com        // Clear LPI Pending Register
12711328Ssteve.reinhardt@amd.com        GICR_CLRLPIR = RD_base + 0x0048,
12811328Ssteve.reinhardt@amd.com        //Redistributor Properties Base Address Register
12911328Ssteve.reinhardt@amd.com        GICR_PROPBASER = RD_base + 0x0070,
13011328Ssteve.reinhardt@amd.com        // Redistributor LPI Pending Table Base Address Register
13111328Ssteve.reinhardt@amd.com        GICR_PENDBASER = RD_base + 0x0078,
13211328Ssteve.reinhardt@amd.com        // Redistributor Invalidate LPI Register
13311328Ssteve.reinhardt@amd.com        GICR_INVLPIR = RD_base + 0x00A0,
13411328Ssteve.reinhardt@amd.com        // Redistributor Invalidate All Register
13511328Ssteve.reinhardt@amd.com        GICR_INVALLR = RD_base + 0x00B0,
13611328Ssteve.reinhardt@amd.com        // Redistributor Synchronize Register
13711328Ssteve.reinhardt@amd.com        GICR_SYNCR = RD_base + 0x00C0,
13811328Ssteve.reinhardt@amd.com    };
13911328Ssteve.reinhardt@amd.com
14011328Ssteve.reinhardt@amd.com    std::vector <uint8_t> irqGroup;
14111328Ssteve.reinhardt@amd.com    std::vector <bool> irqEnabled;
1428442Sgblack@eecs.umich.edu    std::vector <bool> irqPending;
1438442Sgblack@eecs.umich.edu    std::vector <bool> irqActive;
1448442Sgblack@eecs.umich.edu    std::vector <uint8_t> irqPriority;
1458442Sgblack@eecs.umich.edu    std::vector <Gicv3::IntTriggerType> irqConfig;
1468442Sgblack@eecs.umich.edu    std::vector <uint8_t> irqGrpmod;
1478442Sgblack@eecs.umich.edu    std::vector <uint8_t> irqNsacr;
1488442Sgblack@eecs.umich.edu
1498442Sgblack@eecs.umich.edu    bool DPG1S;
1508442Sgblack@eecs.umich.edu    bool DPG1NS;
1518444Sgblack@eecs.umich.edu    bool DPG0;
1528442Sgblack@eecs.umich.edu    bool EnableLPIs;
1538442Sgblack@eecs.umich.edu
15411328Ssteve.reinhardt@amd.com    Addr lpiConfigurationTablePtr;
15511328Ssteve.reinhardt@amd.com    uint8_t lpiIDBits;
15611328Ssteve.reinhardt@amd.com    Addr lpiPendingTablePtr;
15711328Ssteve.reinhardt@amd.com
15811328Ssteve.reinhardt@amd.com    BitUnion8(LPIConfigurationTableEntry)
15911328Ssteve.reinhardt@amd.com        Bitfield<7, 2> priority;
16011328Ssteve.reinhardt@amd.com        Bitfield<1> res1;
16111328Ssteve.reinhardt@amd.com        Bitfield<0> enable;
16211328Ssteve.reinhardt@amd.com    EndBitUnion(LPIConfigurationTableEntry)
16311328Ssteve.reinhardt@amd.com
16411328Ssteve.reinhardt@amd.com    std::vector<LPIConfigurationTableEntry> lpiConfigurationTable;
16511328Ssteve.reinhardt@amd.com
16611328Ssteve.reinhardt@amd.com    static const uint32_t GICR_CTLR_ENABLE_LPIS = 1 << 0;
16711328Ssteve.reinhardt@amd.com    static const uint32_t GICR_CTLR_DPG0   = 1 << 24;
16811328Ssteve.reinhardt@amd.com    static const uint32_t GICR_CTLR_DPG1NS = 1 << 25;
16911328Ssteve.reinhardt@amd.com    static const uint32_t GICR_CTLR_DPG1S  = 1 << 26;
17011328Ssteve.reinhardt@amd.com
17111328Ssteve.reinhardt@amd.com  public:
17211328Ssteve.reinhardt@amd.com
17311328Ssteve.reinhardt@amd.com    /*
17411328Ssteve.reinhardt@amd.com     * GICv3 defines only 2 64K consecutive frames for the redistributor
17511328Ssteve.reinhardt@amd.com     * (RD_base and SGI_base) but we are using 2 extra 64K stride frames
1768442Sgblack@eecs.umich.edu     * to match GICv4 that defines 4 64K consecutive frames for them.
1778442Sgblack@eecs.umich.edu     * Note this must match with DTB/DTS GIC node definition and boot
1788442Sgblack@eecs.umich.edu     * loader code.
1798442Sgblack@eecs.umich.edu     */
1808442Sgblack@eecs.umich.edu    const uint32_t addrRangeSize;
18111301Ssteve.reinhardt@amd.com
18211301Ssteve.reinhardt@amd.com    static const uint32_t SMALLEST_LPI_ID = 8192;
18311301Ssteve.reinhardt@amd.com
18411301Ssteve.reinhardt@amd.com
18511301Ssteve.reinhardt@amd.com    void activateIRQ(uint32_t int_id);
18611301Ssteve.reinhardt@amd.com    bool canBeSelectedFor1toNInterrupt(Gicv3::GroupId group) const;
1878442Sgblack@eecs.umich.edu    void deactivateIRQ(uint32_t int_id);
1888442Sgblack@eecs.umich.edu
1898442Sgblack@eecs.umich.edu    inline Gicv3CPUInterface *
1908442Sgblack@eecs.umich.edu    getCPUInterface() const
1918442Sgblack@eecs.umich.edu    {
1928442Sgblack@eecs.umich.edu        return cpuInterface;
19311328Ssteve.reinhardt@amd.com    }
19411328Ssteve.reinhardt@amd.com
19511328Ssteve.reinhardt@amd.com    Gicv3::GroupId getIntGroup(int int_id) const;
19611328Ssteve.reinhardt@amd.com    Gicv3::IntStatus intStatus(uint32_t int_id) const;
19711328Ssteve.reinhardt@amd.com    void setClrLPI(uint64_t data, bool set);
19811328Ssteve.reinhardt@amd.com    void reset();
19911328Ssteve.reinhardt@amd.com    void sendSGI(uint32_t int_id, Gicv3::GroupId group, bool ns);
20011328Ssteve.reinhardt@amd.com    void serialize(CheckpointOut & cp) const override;
20111328Ssteve.reinhardt@amd.com    void unserialize(CheckpointIn & cp) override;
20211328Ssteve.reinhardt@amd.com    void update();
20311328Ssteve.reinhardt@amd.com    void updateAndInformCPUInterface();
20411328Ssteve.reinhardt@amd.com
20511328Ssteve.reinhardt@amd.com  public:
20611328Ssteve.reinhardt@amd.com
20711328Ssteve.reinhardt@amd.com    Gicv3Redistributor(Gicv3 * gic, uint32_t cpu_id);
20811328Ssteve.reinhardt@amd.com    void invalLpiConfig(uint32_t lpi_entry_index);
20911328Ssteve.reinhardt@amd.com    uint32_t getAffinity() const;
21011328Ssteve.reinhardt@amd.com    void init();
21111328Ssteve.reinhardt@amd.com    void initState();
21211328Ssteve.reinhardt@amd.com    uint64_t read(Addr addr, size_t size, bool is_secure_access);
21311328Ssteve.reinhardt@amd.com    void sendPPInt(uint32_t int_id);
21411328Ssteve.reinhardt@amd.com    void write(Addr addr, uint64_t data, size_t size, bool is_secure_access);
21511328Ssteve.reinhardt@amd.com};
21611328Ssteve.reinhardt@amd.com
21711328Ssteve.reinhardt@amd.com#endif //__DEV_ARM_GICV3_REDISTRIBUTOR_H__
2188442Sgblack@eecs.umich.edu