gic_v3_redistributor.hh revision 13921:cd7f721d8221
16166Ssteve.reinhardt@amd.com/*
26928SBrad.Beckmann@amd.com * Copyright (c) 2018 Metempsy Technology Consulting
36166Ssteve.reinhardt@amd.com * All rights reserved.
46166Ssteve.reinhardt@amd.com *
56166Ssteve.reinhardt@amd.com * Redistribution and use in source and binary forms, with or without
66166Ssteve.reinhardt@amd.com * modification, are permitted provided that the following conditions are
76166Ssteve.reinhardt@amd.com * met: redistributions of source code must retain the above copyright
86166Ssteve.reinhardt@amd.com * notice, this list of conditions and the following disclaimer;
96166Ssteve.reinhardt@amd.com * redistributions in binary form must reproduce the above copyright
106166Ssteve.reinhardt@amd.com * notice, this list of conditions and the following disclaimer in the
116166Ssteve.reinhardt@amd.com * documentation and/or other materials provided with the distribution;
126166Ssteve.reinhardt@amd.com * neither the name of the copyright holders nor the names of its
136166Ssteve.reinhardt@amd.com * contributors may be used to endorse or promote products derived from
146166Ssteve.reinhardt@amd.com * this software without specific prior written permission.
156166Ssteve.reinhardt@amd.com *
166166Ssteve.reinhardt@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
176166Ssteve.reinhardt@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
186166Ssteve.reinhardt@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
196166Ssteve.reinhardt@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
206166Ssteve.reinhardt@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
216166Ssteve.reinhardt@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
226166Ssteve.reinhardt@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
236166Ssteve.reinhardt@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
246166Ssteve.reinhardt@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
256166Ssteve.reinhardt@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
266166Ssteve.reinhardt@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
276166Ssteve.reinhardt@amd.com *
286166Ssteve.reinhardt@amd.com * Authors: Jairo Balart
296166Ssteve.reinhardt@amd.com */
306166Ssteve.reinhardt@amd.com
316166Ssteve.reinhardt@amd.com#ifndef __DEV_ARM_GICV3_REDISTRIBUTOR_H__
326919SBrad.Beckmann@amd.com#define __DEV_ARM_GICV3_REDISTRIBUTOR_H__
336919SBrad.Beckmann@amd.com
346919SBrad.Beckmann@amd.com#include "base/addr_range.hh"
356166Ssteve.reinhardt@amd.com#include "dev/arm/gic_v3.hh"
366919SBrad.Beckmann@amd.com#include "sim/serialize.hh"
376919SBrad.Beckmann@amd.com
386919SBrad.Beckmann@amd.comclass Gicv3CPUInterface;
396919SBrad.Beckmann@amd.comclass Gicv3Distributor;
406919SBrad.Beckmann@amd.com
416919SBrad.Beckmann@amd.comclass Gicv3Redistributor : public Serializable
429113SBrad.Beckmann@amd.com{
436919SBrad.Beckmann@amd.com  private:
446919SBrad.Beckmann@amd.com
458920Snilay@cs.wisc.edu    friend class Gicv3CPUInterface;
466919SBrad.Beckmann@amd.com    friend class Gicv3Distributor;
476919SBrad.Beckmann@amd.com
488920Snilay@cs.wisc.edu  protected:
496919SBrad.Beckmann@amd.com
507570SBrad.Beckmann@amd.com    Gicv3 * gic;
517570SBrad.Beckmann@amd.com    Gicv3Distributor * distributor;
526919SBrad.Beckmann@amd.com    Gicv3CPUInterface * cpuInterface;
536919SBrad.Beckmann@amd.com    uint32_t cpuId;
546166Ssteve.reinhardt@amd.com
557570SBrad.Beckmann@amd.com    /*
567570SBrad.Beckmann@amd.com     * GICv3 defines 2 contiguous 64KB frames for each redistributor.
577570SBrad.Beckmann@amd.com     * Order of frames must be RD_base, SGI_base.
587570SBrad.Beckmann@amd.com     */
597570SBrad.Beckmann@amd.com    static const uint32_t RD_base  = 0x0;
607570SBrad.Beckmann@amd.com    static const uint32_t SGI_base = 0x10000;
617570SBrad.Beckmann@amd.com
627570SBrad.Beckmann@amd.com    enum {
637570SBrad.Beckmann@amd.com        // Control Register
647570SBrad.Beckmann@amd.com        GICR_CTLR  = RD_base + 0x0000,
657570SBrad.Beckmann@amd.com        // Implementer Identification Register
667570SBrad.Beckmann@amd.com        GICR_IIDR  = RD_base + 0x0004,
679841Snilay@cs.wisc.edu        // Type Register
687570SBrad.Beckmann@amd.com        GICR_TYPER = RD_base + 0x0008,
696166Ssteve.reinhardt@amd.com        // Wake Register
706166Ssteve.reinhardt@amd.com        GICR_WAKER = RD_base + 0x0014,
716928SBrad.Beckmann@amd.com        // Peripheral ID0 Register
726928SBrad.Beckmann@amd.com        GICR_PIDR0 = RD_base + 0xffe0,
739793Sakash.bagdia@arm.com        // Peripheral ID1 Register
748436SBrad.Beckmann@amd.com        GICR_PIDR1 = RD_base + 0xffe4,
756928SBrad.Beckmann@amd.com        // Peripheral ID2 Register
766166Ssteve.reinhardt@amd.com        GICR_PIDR2 = RD_base + 0xffe8,
776919SBrad.Beckmann@amd.com        // Peripheral ID3 Register
786919SBrad.Beckmann@amd.com        GICR_PIDR3 = RD_base + 0xffec,
796919SBrad.Beckmann@amd.com        // Peripheral ID4 Register
806919SBrad.Beckmann@amd.com        GICR_PIDR4 = RD_base + 0xffd0,
816919SBrad.Beckmann@amd.com        // Peripheral ID5 Register
828931Sandreas.hansson@arm.com        GICR_PIDR5 = RD_base + 0xffd4,
839577Snilay@cs.wisc.edu        // Peripheral ID6 Register
8410405Sandreas.hansson@arm.com        GICR_PIDR6 = RD_base + 0xffd8,
859827Sakash.bagdia@arm.com        // Peripheral ID7 Register
869827Sakash.bagdia@arm.com        GICR_PIDR7 = RD_base + 0xffdc,
879827Sakash.bagdia@arm.com    };
889827Sakash.bagdia@arm.com
899793Sakash.bagdia@arm.com    static const uint32_t GICR_WAKER_ProcessorSleep = 1 << 1;
909793Sakash.bagdia@arm.com    static const uint32_t GICR_WAKER_ChildrenAsleep = 1 << 2;
919793Sakash.bagdia@arm.com
929827Sakash.bagdia@arm.com    bool peInLowPowerState;
939827Sakash.bagdia@arm.com
949793Sakash.bagdia@arm.com    enum {
959793Sakash.bagdia@arm.com        // Interrupt Group Register 0
969793Sakash.bagdia@arm.com        GICR_IGROUPR0   = SGI_base + 0x0080,
979793Sakash.bagdia@arm.com        // Interrupt Set-Enable Register 0
986289Snate@binkert.org        GICR_ISENABLER0 = SGI_base + 0x0100,
999826Sandreas.hansson@arm.com        // Interrupt Clear-Enable Register 0
1009826Sandreas.hansson@arm.com        GICR_ICENABLER0 = SGI_base + 0x0180,
10110519Snilay@cs.wisc.edu        // Interrupt Set-Pending Register 0
1026166Ssteve.reinhardt@amd.com        GICR_ISPENDR0   = SGI_base + 0x0200,
1039793Sakash.bagdia@arm.com        // Interrupt Clear-Pending Register 0
1049827Sakash.bagdia@arm.com        GICR_ICPENDR0   = SGI_base + 0x0280,
1059827Sakash.bagdia@arm.com        // Interrupt Set-Active Register 0
1069793Sakash.bagdia@arm.com        GICR_ISACTIVER0 = SGI_base + 0x0300,
10710120Snilay@cs.wisc.edu        // Interrupt Clear-Active Register 0
1086166Ssteve.reinhardt@amd.com        GICR_ICACTIVER0 = SGI_base + 0x0380,
10910120Snilay@cs.wisc.edu        // SGI Configuration Register
1106919SBrad.Beckmann@amd.com        GICR_ICFGR0     = SGI_base + 0x0c00,
1116919SBrad.Beckmann@amd.com        // PPI Configuration Register
1126919SBrad.Beckmann@amd.com        GICR_ICFGR1     = SGI_base + 0x0c04,
1136919SBrad.Beckmann@amd.com        // Interrupt Group Modifier Register 0
1148839Sandreas.hansson@arm.com        GICR_IGRPMODR0  = SGI_base + 0x0d00,
1159120Sandreas.hansson@arm.com        // Non-secure Access Control Register
1167938SBrad.Beckmann@amd.com        GICR_NSACR      = SGI_base + 0x0e00,
1177938SBrad.Beckmann@amd.com    };
1187938SBrad.Beckmann@amd.com
1197938SBrad.Beckmann@amd.com    // Interrupt Priority Registers
1207938SBrad.Beckmann@amd.com    static const AddrRange GICR_IPRIORITYR;
1217938SBrad.Beckmann@amd.com
1226166Ssteve.reinhardt@amd.com    // GIC physical LPI Redistributor register
1239120Sandreas.hansson@arm.com    enum {
1249120Sandreas.hansson@arm.com        // Set LPI Pending Register
1259120Sandreas.hansson@arm.com        GICR_SETLPIR = RD_base + 0x0040,
1266166Ssteve.reinhardt@amd.com        // Clear LPI Pending Register
1276166Ssteve.reinhardt@amd.com        GICR_CLRLPIR = RD_base + 0x0048,
1286166Ssteve.reinhardt@amd.com        //Redistributor Properties Base Address Register
1296166Ssteve.reinhardt@amd.com        GICR_PROPBASER = RD_base + 0x0070,
1308801Sgblack@eecs.umich.edu        // Redistributor LPI Pending Table Base Address Register
1316166Ssteve.reinhardt@amd.com        GICR_PENDBASER = RD_base + 0x0078,
1326928SBrad.Beckmann@amd.com        // Redistributor Invalidate LPI Register
1336928SBrad.Beckmann@amd.com        GICR_INVLPIR = RD_base + 0x00A0,
1346928SBrad.Beckmann@amd.com        // Redistributor Invalidate All Register
135        GICR_INVALLR = RD_base + 0x00B0,
136        // Redistributor Synchronize Register
137        GICR_SYNCR = RD_base + 0x00C0,
138    };
139
140    std::vector <uint8_t> irqGroup;
141    std::vector <bool> irqEnabled;
142    std::vector <bool> irqPending;
143    std::vector <bool> irqActive;
144    std::vector <uint8_t> irqPriority;
145    std::vector <Gicv3::IntTriggerType> irqConfig;
146    std::vector <uint8_t> irqGrpmod;
147    std::vector <uint8_t> irqNsacr;
148
149    bool DPG1S;
150    bool DPG1NS;
151    bool DPG0;
152    bool EnableLPIs;
153
154    Addr lpiConfigurationTablePtr;
155    uint8_t lpiIDBits;
156    Addr lpiPendingTablePtr;
157
158    BitUnion8(LPIConfigurationTableEntry)
159        Bitfield<7, 2> priority;
160        Bitfield<1> res1;
161        Bitfield<0> enable;
162    EndBitUnion(LPIConfigurationTableEntry)
163
164    static const uint32_t GICR_CTLR_ENABLE_LPIS = 1 << 0;
165    static const uint32_t GICR_CTLR_DPG0   = 1 << 24;
166    static const uint32_t GICR_CTLR_DPG1NS = 1 << 25;
167    static const uint32_t GICR_CTLR_DPG1S  = 1 << 26;
168
169  public:
170
171    /*
172     * GICv3 defines only 2 64K consecutive frames for the redistributor
173     * (RD_base and SGI_base) but we are using 2 extra 64K stride frames
174     * to match GICv4 that defines 4 64K consecutive frames for them.
175     * Note this must match with DTB/DTS GIC node definition and boot
176     * loader code.
177     */
178    const uint32_t addrRangeSize;
179
180    static const uint32_t SMALLEST_LPI_ID = 8192;
181
182
183    void activateIRQ(uint32_t int_id);
184    bool canBeSelectedFor1toNInterrupt(Gicv3::GroupId group) const;
185    void deactivateIRQ(uint32_t int_id);
186
187    inline Gicv3CPUInterface *
188    getCPUInterface() const
189    {
190        return cpuInterface;
191    }
192
193    Gicv3::GroupId getIntGroup(int int_id) const;
194    Gicv3::IntStatus intStatus(uint32_t int_id) const;
195    void setClrLPI(uint64_t data, bool set);
196    void reset();
197    void sendSGI(uint32_t int_id, Gicv3::GroupId group, bool ns);
198    void serialize(CheckpointOut & cp) const override;
199    void unserialize(CheckpointIn & cp) override;
200    void update();
201    void updateAndInformCPUInterface();
202
203  public:
204
205    Gicv3Redistributor(Gicv3 * gic, uint32_t cpu_id);
206    uint32_t getAffinity() const;
207    void init();
208    void initState();
209    uint64_t read(Addr addr, size_t size, bool is_secure_access);
210    void sendPPInt(uint32_t int_id);
211    void write(Addr addr, uint64_t data, size_t size, bool is_secure_access);
212};
213
214#endif //__DEV_ARM_GICV3_REDISTRIBUTOR_H__
215