gic_v3_cpu_interface.hh revision 13531:e6f1bf55d038
1/*
2 * Copyright (c) 2018 Metempsy Technology Consulting
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Jairo Balart
29 */
30
31#ifndef __DEV_ARM_GICV3_CPU_INTERFACE_H__
32#define __DEV_ARM_GICV3_CPU_INTERFACE_H__
33
34#include "arch/arm/isa_device.hh"
35#include "dev/arm/gic_v3.hh"
36
37class Gicv3Redistributor;
38class Gicv3Distributor;
39
40class Gicv3CPUInterface : public ArmISA::BaseISADevice, public Serializable
41{
42  private:
43
44    friend class Gicv3Redistributor;
45    friend class Gicv3Distributor;
46
47  protected:
48
49    Gicv3 * gic;
50    Gicv3Redistributor * redistributor;
51    Gicv3Distributor * distributor;
52    uint32_t cpuId;
53
54    static const uint32_t ICC_SRE_EL1_SRE = 1 << 0;
55    static const uint32_t ICC_SRE_EL1_DFB = 1 << 1;
56    static const uint32_t ICC_SRE_EL1_DIB = 1 << 2;
57
58    static const uint32_t ICC_SRE_EL2_SRE = 1 << 0;
59    static const uint32_t ICC_SRE_EL2_DFB = 1 << 1;
60    static const uint32_t ICC_SRE_EL2_DIB = 1 << 2;
61    static const uint32_t ICC_SRE_EL2_ENABLE = 1 << 3;
62
63    static const uint32_t ICC_SRE_EL3_SRE = 1 << 0;
64    static const uint32_t ICC_SRE_EL3_DFB = 1 << 1;
65    static const uint32_t ICC_SRE_EL3_DIB = 1 << 2;
66    static const uint32_t ICC_SRE_EL3_ENABLE = 1 << 3;
67
68    static const uint32_t ICC_CTLR_EL3_CBPR_EL1S = 1 << 0;
69    static const uint32_t ICC_CTLR_EL3_CBPR_EL1NS = 1 << 1;
70    static const uint32_t ICC_CTLR_EL3_EOIMODE_EL3 = 1 << 2;
71    static const uint32_t ICC_CTLR_EL3_EOIMODE_EL1S = 1 << 3;
72    static const uint32_t ICC_CTLR_EL3_EOIMODE_EL1NS = 1 << 4;
73    static const uint32_t ICC_CTLR_EL3_RM = 1 << 5;
74    static const uint32_t ICC_CTLR_EL3_PMHE = 1 << 6;
75    static const uint32_t ICC_CTLR_EL3_PRIBITS_SHIFT = 8;
76    static const uint32_t ICC_CTLR_EL3_IDBITS_SHIFT = 11;
77    static const uint32_t ICC_CTLR_EL3_SEIS = 1 << 14;
78    static const uint32_t ICC_CTLR_EL3_A3V = 1 << 15;
79    static const uint32_t ICC_CTLR_EL3_nDS = 1 << 17;
80    static const uint32_t ICC_CTLR_EL3_RSS = 1 << 18;
81
82    static const uint32_t ICC_CTLR_EL1_CBPR = 1 << 0;
83    static const uint32_t ICC_CTLR_EL1_EOIMODE = 1 << 1;
84    static const uint32_t ICC_CTLR_EL1_PMHE = 1 << 6;
85    static const uint32_t ICC_CTLR_EL1_SEIS = 1 << 14;
86    static const uint32_t ICC_CTLR_EL1_A3V = 1 << 15;
87    static const uint32_t ICC_CTLR_EL1_RSS = 1 << 18;
88    static const uint32_t ICC_CTLR_EL1_PRIBITS_SHIFT = 8;
89    static const uint32_t ICC_CTLR_EL1_PRIBITS_MASK =
90        7U << ICC_CTLR_EL1_PRIBITS_SHIFT;
91    static const uint32_t ICC_CTLR_EL1_IDBITS_SHIFT = 11;
92
93    static const uint32_t ICC_IGRPEN0_EL1_ENABLE = 1 << 0;
94    static const uint32_t ICC_IGRPEN1_EL1_ENABLE = 1 << 0;
95
96    static const uint32_t ICC_IGRPEN1_EL3_ENABLEGRP1NS = 1 << 0;
97    static const uint32_t ICC_IGRPEN1_EL3_ENABLEGRP1S = 1 << 1;
98
99    static const uint8_t PRIORITY_BITS = 5;
100
101    /* Minimum BPR for Secure, or when security not enabled */
102    static const uint8_t GIC_MIN_BPR = 2;
103    /* Minimum BPR for Nonsecure when security is enabled */
104    static const uint8_t GIC_MIN_BPR_NS = GIC_MIN_BPR + 1;
105
106    static const uint8_t VIRTUAL_PRIORITY_BITS = 5;
107    static const uint8_t VIRTUAL_PREEMPTION_BITS = 5;
108    static const uint8_t VIRTUAL_NUM_LIST_REGS = 16;
109
110    static const uint8_t GIC_MIN_VBPR = 7 - VIRTUAL_PREEMPTION_BITS;
111
112    typedef struct {
113        uint32_t intid;
114        uint8_t prio;
115        Gicv3::GroupId group;
116    } hppi_t;
117
118    hppi_t hppi;
119
120    // GIC CPU interface memory mapped control registers (legacy)
121    enum {
122        GICC_CTLR = 0x0000,
123        GICC_PMR = 0x0004,
124        GICC_BPR = 0x0008,
125        GICC_IAR = 0x000C,
126        GICC_EOIR = 0x0010,
127        GICC_RPR = 0x0014,
128        GICC_HPPI = 0x0018,
129        GICC_ABPR = 0x001C,
130        GICC_AIAR = 0x0020,
131        GICC_AEOIR = 0x0024,
132        GICC_AHPPIR = 0x0028,
133        GICC_STATUSR = 0x002C,
134        GICC_IIDR = 0x00FC,
135    };
136
137    static const AddrRange GICC_APR;
138    static const AddrRange GICC_NSAPR;
139
140    // GIC CPU virtual interface memory mapped control registers (legacy)
141    enum {
142        GICH_HCR = 0x0000,
143        GICH_VTR = 0x0004,
144        GICH_VMCR = 0x0008,
145        GICH_MISR = 0x0010,
146        GICH_EISR = 0x0020,
147        GICH_ELRSR = 0x0030,
148    };
149
150    static const AddrRange GICH_APR;
151    static const AddrRange GICH_LR;
152
153    static const uint32_t ICH_HCR_EL2_EN = 1 << 0;
154    static const uint32_t ICH_HCR_EL2_UIE = 1 << 1;
155    static const uint32_t ICH_HCR_EL2_LRENPIE = 1 << 2;
156    static const uint32_t ICH_HCR_EL2_NPIE = 1 << 3;
157    static const uint32_t ICH_HCR_EL2_VGRP0EIE = 1 << 4;
158    static const uint32_t ICH_HCR_EL2_VGRP0DIE = 1 << 5;
159    static const uint32_t ICH_HCR_EL2_VGRP1EIE = 1 << 6;
160    static const uint32_t ICH_HCR_EL2_VGRP1DIE = 1 << 7;
161    static const uint32_t ICH_HCR_EL2_TC = 1 << 10;
162    static const uint32_t ICH_HCR_EL2_TALL0 = 1 << 11;
163    static const uint32_t ICH_HCR_EL2_TALL1 = 1 << 12;
164    static const uint32_t ICH_HCR_EL2_TSEI = 1 << 13;
165    static const uint32_t ICH_HCR_EL2_TDIR = 1 << 14;
166    static const uint32_t ICH_HCR_EL2_EOICOUNT_MASK = 0x1fU << 27;
167
168    static const uint64_t ICH_LR_EL2_VINTID_SHIFT = 0;
169    static const uint64_t ICH_LR_EL2_VINTID_LENGTH = 32;
170    static const uint64_t ICH_LR_EL2_VINTID_MASK =
171        (0xffffffffULL << ICH_LR_EL2_VINTID_SHIFT);
172    static const uint64_t ICH_LR_EL2_PINTID_SHIFT = 32;
173    static const uint64_t ICH_LR_EL2_PINTID_LENGTH = 10;
174    static const uint64_t ICH_LR_EL2_PINTID_MASK =
175        (0x3ffULL << ICH_LR_EL2_PINTID_SHIFT);
176    /* Note that EOI shares with the top bit of the pINTID field */
177    static const uint64_t ICH_LR_EL2_EOI = (1ULL << 41);
178    static const uint64_t ICH_LR_EL2_PRIORITY_SHIFT = 48;
179    static const uint64_t ICH_LR_EL2_PRIORITY_LENGTH = 8;
180    static const uint64_t ICH_LR_EL2_PRIORITY_MASK =
181        (0xffULL << ICH_LR_EL2_PRIORITY_SHIFT);
182    static const uint64_t ICH_LR_EL2_GROUP = (1ULL << 60);
183    static const uint64_t ICH_LR_EL2_HW = (1ULL << 61);
184    static const uint64_t ICH_LR_EL2_STATE_SHIFT = 62;
185    static const uint64_t ICH_LR_EL2_STATE_LENGTH = 2;
186    static const uint64_t ICH_LR_EL2_STATE_MASK =
187        (3ULL << ICH_LR_EL2_STATE_SHIFT);
188    /* values for the state field: */
189    static const uint64_t ICH_LR_EL2_STATE_INVALID = 0;
190    static const uint64_t ICH_LR_EL2_STATE_PENDING = 1;
191    static const uint64_t ICH_LR_EL2_STATE_ACTIVE = 2;
192    static const uint64_t ICH_LR_EL2_STATE_ACTIVE_PENDING = 3;
193    static const uint64_t ICH_LR_EL2_STATE_PENDING_BIT =
194        (1ULL << ICH_LR_EL2_STATE_SHIFT);
195    static const uint64_t ICH_LR_EL2_STATE_ACTIVE_BIT =
196        (2ULL << ICH_LR_EL2_STATE_SHIFT);
197
198    static const uint64_t ICH_LRC_PRIORITY_SHIFT =
199        ICH_LR_EL2_PRIORITY_SHIFT - 32;
200    static const uint64_t ICH_LRC_PRIORITY_LENGTH =
201        ICH_LR_EL2_PRIORITY_LENGTH;
202
203    static const uint32_t ICH_MISR_EL2_EOI = (1 << 0);
204    static const uint32_t ICH_MISR_EL2_U = (1 << 1);
205    static const uint32_t ICH_MISR_EL2_LRENP = (1 << 2);
206    static const uint32_t ICH_MISR_EL2_NP = (1 << 3);
207    static const uint32_t ICH_MISR_EL2_VGRP0E = (1 << 4);
208    static const uint32_t ICH_MISR_EL2_VGRP0D = (1 << 5);
209    static const uint32_t ICH_MISR_EL2_VGRP1E = (1 << 6);
210    static const uint32_t ICH_MISR_EL2_VGRP1D = (1 << 7);
211
212    static const uint32_t ICH_VMCR_EL2_VENG0_SHIFT = 0;
213    static const uint32_t ICH_VMCR_EL2_VENG0 =
214        (1 << ICH_VMCR_EL2_VENG0_SHIFT);
215    static const uint32_t ICH_VMCR_EL2_VENG1_SHIFT = 1;
216    static const uint32_t ICH_VMCR_EL2_VENG1 =
217        (1 << ICH_VMCR_EL2_VENG1_SHIFT);
218    static const uint32_t ICH_VMCR_EL2_VACKCTL = (1 << 2);
219    static const uint32_t ICH_VMCR_EL2_VFIQEN = (1 << 3);
220    static const uint32_t ICH_VMCR_EL2_VCBPR_SHIFT = 4;
221    static const uint32_t ICH_VMCR_EL2_VCBPR =
222        (1 << ICH_VMCR_EL2_VCBPR_SHIFT);
223    static const uint32_t ICH_VMCR_EL2_VEOIM_SHIFT = 9;
224    static const uint32_t ICH_VMCR_EL2_VEOIM =
225        (1 << ICH_VMCR_EL2_VEOIM_SHIFT);
226    static const uint32_t ICH_VMCR_EL2_VBPR1_SHIFT = 18;
227    static const uint32_t ICH_VMCR_EL2_VBPR1_LENGTH = 3;
228    static const uint32_t ICH_VMCR_EL2_VBPR1_MASK =
229        (0x7U << ICH_VMCR_EL2_VBPR1_SHIFT);
230    static const uint32_t ICH_VMCR_EL2_VBPR0_SHIFT = 21;
231    static const uint32_t ICH_VMCR_EL2_VBPR0_LENGTH = 3;
232    static const uint32_t ICH_VMCR_EL2_VBPR0_MASK =
233        (0x7U << ICH_VMCR_EL2_VBPR0_SHIFT);
234    static const uint32_t ICH_VMCR_EL2_VPMR_SHIFT = 24;
235    static const uint32_t ICH_VMCR_EL2_VPMR_LENGTH = 8;
236    static const uint32_t ICH_VMCR_EL2_VPMR_MASK =
237        (0xffU << ICH_VMCR_EL2_VPMR_SHIFT);
238
239    static const uint32_t ICH_VTR_EL2_LISTREGS_SHIFT = 0;
240    static const uint32_t ICH_VTR_EL2_TDS = 1 << 19;
241    static const uint32_t ICH_VTR_EL2_NV4 = 1 << 20;
242    static const uint32_t ICH_VTR_EL2_A3V = 1 << 21;
243    static const uint32_t ICH_VTR_EL2_SEIS = 1 << 22;
244    static const uint32_t ICH_VTR_EL2_IDBITS_SHIFT = 23;
245    static const uint32_t ICH_VTR_EL2_PREBITS_SHIFT = 26;
246    static const uint32_t ICH_VTR_EL2_PRIBITS_SHIFT = 29;
247
248  public:
249
250    Gicv3CPUInterface(Gicv3 * gic, uint32_t cpu_id);
251    ~Gicv3CPUInterface();
252    void init();
253    void initState();
254
255    ArmISA::MiscReg readMiscReg(int misc_reg) override;
256    void setMiscReg(int misc_reg, ArmISA::MiscReg val) override;
257    void update();
258    void virtualUpdate();
259
260    void serialize(CheckpointOut & cp) const override;
261    void unserialize(CheckpointIn & cp) override;
262
263  protected:
264
265    void reset();
266    bool hppiCanPreempt();
267    bool hppviCanPreempt(int lrIdx);
268    bool groupEnabled(Gicv3::GroupId group);
269    uint8_t highestActivePriority();
270    uint8_t virtualHighestActivePriority();
271    bool inSecureState();
272    int currEL();
273    bool haveEL(ArmISA::ExceptionLevel el);
274    void activateIRQ(uint32_t intid, Gicv3::GroupId group);
275    void virtualActivateIRQ(uint32_t lrIdx);
276    void deactivateIRQ(uint32_t intid, Gicv3::GroupId group);
277    void virtualDeactivateIRQ(int lrIdx);
278    uint32_t groupPriorityMask(Gicv3::GroupId group);
279    uint32_t virtualGroupPriorityMask(Gicv3::GroupId group);
280    void dropPriority(Gicv3::GroupId group);
281    uint8_t virtualDropPriority();
282    ArmISA::InterruptTypes intSignalType(Gicv3::GroupId group);
283    bool isEOISplitMode();
284    bool virtualIsEOISplitMode();
285    bool isSecureBelowEL3();
286    bool inSecureState2();
287    uint32_t eoiMaintenanceInterruptStatus(uint32_t * misr);
288    uint32_t maintenanceInterruptStatus();
289    int highestActiveGroup();
290    bool getHCREL2FMO();
291    bool getHCREL2IMO();
292    uint32_t getHPPIR1();
293    uint32_t getHPPIR0();
294    int getHPPVILR();
295    int virtualFindActive(uint32_t intid);
296    void virtualIncrementEOICount();
297    bool isEL3OrMon();
298    bool isAA64();
299};
300
301#endif //__DEV_ARM_GICV3_CPU_INTERFACE_H__
302