base_gic.hh (12974:b840a646cfbd) base_gic.hh (13531:e6f1bf55d038)
1/*
2 * Copyright (c) 2012-2013, 2017-2018 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Andreas Sandberg
38 */
39
40/** @file
41 * Base class for ARM GIC implementations
42 */
43
44#ifndef __DEV_ARM_BASE_GIC_H__
45#define __DEV_ARM_BASE_GIC_H__
46
47#include <unordered_map>
48
1/*
2 * Copyright (c) 2012-2013, 2017-2018 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Andreas Sandberg
38 */
39
40/** @file
41 * Base class for ARM GIC implementations
42 */
43
44#ifndef __DEV_ARM_BASE_GIC_H__
45#define __DEV_ARM_BASE_GIC_H__
46
47#include <unordered_map>
48
49#include "arch/arm/system.hh"
49#include "dev/io_device.hh"
50
51class Platform;
52class RealView;
53class ThreadContext;
54class ArmInterruptPin;
55class ArmSPI;
56class ArmPPI;
57
58struct ArmInterruptPinParams;
59struct ArmPPIParams;
60struct ArmSPIParams;
61struct BaseGicParams;
62
63class BaseGic : public PioDevice
64{
65 public:
66 typedef BaseGicParams Params;
67
68 BaseGic(const Params *p);
69 virtual ~BaseGic();
50#include "dev/io_device.hh"
51
52class Platform;
53class RealView;
54class ThreadContext;
55class ArmInterruptPin;
56class ArmSPI;
57class ArmPPI;
58
59struct ArmInterruptPinParams;
60struct ArmPPIParams;
61struct ArmSPIParams;
62struct BaseGicParams;
63
64class BaseGic : public PioDevice
65{
66 public:
67 typedef BaseGicParams Params;
68
69 BaseGic(const Params *p);
70 virtual ~BaseGic();
71 void init() override;
70
71 const Params * params() const;
72
73 /**
74 * Post an interrupt from a device that is connected to the GIC.
75 *
76 * Depending on the configuration, the GIC will pass this interrupt
77 * on through to a CPU.
78 *
79 * @param num number of interrupt to send
80 */
81 virtual void sendInt(uint32_t num) = 0;
82
83 /**
84 * Interface call for private peripheral interrupts.
85 *
86 * @param num number of interrupt to send
87 * @param cpu CPU to forward interrupt to
88 */
89 virtual void sendPPInt(uint32_t num, uint32_t cpu) = 0;
90 virtual void clearPPInt(uint32_t num, uint32_t cpu) = 0;
91
92 /**
93 * Clear an interrupt from a device that is connected to the GIC.
94 *
95 * Depending on the configuration, the GIC may de-assert it's CPU
96 * line.
97 *
98 * @param num number of interrupt to send
99 */
100 virtual void clearInt(uint32_t num) = 0;
101
72
73 const Params * params() const;
74
75 /**
76 * Post an interrupt from a device that is connected to the GIC.
77 *
78 * Depending on the configuration, the GIC will pass this interrupt
79 * on through to a CPU.
80 *
81 * @param num number of interrupt to send
82 */
83 virtual void sendInt(uint32_t num) = 0;
84
85 /**
86 * Interface call for private peripheral interrupts.
87 *
88 * @param num number of interrupt to send
89 * @param cpu CPU to forward interrupt to
90 */
91 virtual void sendPPInt(uint32_t num, uint32_t cpu) = 0;
92 virtual void clearPPInt(uint32_t num, uint32_t cpu) = 0;
93
94 /**
95 * Clear an interrupt from a device that is connected to the GIC.
96 *
97 * Depending on the configuration, the GIC may de-assert it's CPU
98 * line.
99 *
100 * @param num number of interrupt to send
101 */
102 virtual void clearInt(uint32_t num) = 0;
103
104 ArmSystem *
105 getSystem() const
106 {
107 return (ArmSystem *) sys;
108 }
109
102 protected:
103 /** Platform this GIC belongs to. */
104 Platform *platform;
105};
106
107class BaseGicRegisters
108{
109 public:
110 virtual uint32_t readDistributor(ContextID ctx, Addr daddr) = 0;
111 virtual uint32_t readCpu(ContextID ctx, Addr daddr) = 0;
112
113 virtual void writeDistributor(ContextID ctx, Addr daddr,
114 uint32_t data) = 0;
115 virtual void writeCpu(ContextID ctx, Addr daddr, uint32_t data) = 0;
116};
117
118/**
119 * This SimObject is instantiated in the python world and
120 * serves as an ArmInterruptPin generator. In this way it
121 * is possible to instantiate a single generator per component
122 * during configuration, and to dynamically spawn ArmInterruptPins.
123 * See ArmPPIGen for more info on how this is used.
124 */
125class ArmInterruptPinGen : public SimObject
126{
127 public:
128 ArmInterruptPinGen(const ArmInterruptPinParams *p);
129
130 virtual ArmInterruptPin* get(ThreadContext *tc = nullptr) = 0;
131};
132
133/**
134 * Shared Peripheral Interrupt Generator
135 * It is capable of generating one interrupt only: it maintains a pointer
136 * to it and returns it every time it is asked for it (via the get metod)
137 */
138class ArmSPIGen : public ArmInterruptPinGen
139{
140 public:
141 ArmSPIGen(const ArmSPIParams *p);
142
143 ArmInterruptPin* get(ThreadContext *tc = nullptr) override;
144 protected:
145 ArmSPI* pin;
146};
147
148/**
149 * Private Peripheral Interrupt Generator
150 * Since PPIs are banked in the GIC, this class is capable of generating
151 * more than one interrupt (one per ContextID).
152 */
153class ArmPPIGen : public ArmInterruptPinGen
154{
155 public:
156 ArmPPIGen(const ArmPPIParams *p);
157
158 ArmInterruptPin* get(ThreadContext* tc = nullptr) override;
159 protected:
160 std::unordered_map<ContextID, ArmPPI*> pins;
161};
162
163/**
164 * Generic representation of an Arm interrupt pin.
165 */
166class ArmInterruptPin
167{
168 friend class ArmInterruptPinGen;
169 protected:
170 ArmInterruptPin(Platform *platform, ThreadContext *tc,
171 uint32_t int_num);
172
173 public: /* Public interface */
174 /**
175 * Set the thread context owning this interrupt.
176 *
177 * This method is used to set the thread context for interrupts
178 * that are thread/CPU-specific. Only devices that are used in
179 * such a context are expected to call this method.
180 */
181 void setThreadContext(ThreadContext *tc);
182
183 /** Get interrupt number */
184 uint32_t num() const { return intNum; }
185
186 /** Signal an interrupt */
187 virtual void raise() = 0;
188 /** Clear a signalled interrupt */
189 virtual void clear() = 0;
190
191 protected:
192 /**
193 * Get the target context ID of this interrupt.
194 *
195 * @pre setThreadContext() must have been called prior to calling
196 * this method.
197 */
198 ContextID targetContext() const;
199
200 /**
201 * Pointer to the thread context that owns this interrupt in case
202 * it is a thread-/CPU-private interrupt
203 */
204 const ThreadContext *threadContext;
205
206 /** Arm platform to use for interrupt generation */
207 RealView *const platform;
208
209 /** Interrupt number to generate */
210 const uint32_t intNum;
211};
212
213class ArmSPI : public ArmInterruptPin
214{
215 friend class ArmSPIGen;
216 private:
217 ArmSPI(Platform *platform, uint32_t int_num);
218
219 public:
220 void raise() override;
221 void clear() override;
222};
223
224class ArmPPI : public ArmInterruptPin
225{
226 friend class ArmPPIGen;
227 private:
228 ArmPPI(Platform *platform, ThreadContext *tc, uint32_t int_num);
229
230 public:
231 void raise() override;
232 void clear() override;
233};
234
235#endif
110 protected:
111 /** Platform this GIC belongs to. */
112 Platform *platform;
113};
114
115class BaseGicRegisters
116{
117 public:
118 virtual uint32_t readDistributor(ContextID ctx, Addr daddr) = 0;
119 virtual uint32_t readCpu(ContextID ctx, Addr daddr) = 0;
120
121 virtual void writeDistributor(ContextID ctx, Addr daddr,
122 uint32_t data) = 0;
123 virtual void writeCpu(ContextID ctx, Addr daddr, uint32_t data) = 0;
124};
125
126/**
127 * This SimObject is instantiated in the python world and
128 * serves as an ArmInterruptPin generator. In this way it
129 * is possible to instantiate a single generator per component
130 * during configuration, and to dynamically spawn ArmInterruptPins.
131 * See ArmPPIGen for more info on how this is used.
132 */
133class ArmInterruptPinGen : public SimObject
134{
135 public:
136 ArmInterruptPinGen(const ArmInterruptPinParams *p);
137
138 virtual ArmInterruptPin* get(ThreadContext *tc = nullptr) = 0;
139};
140
141/**
142 * Shared Peripheral Interrupt Generator
143 * It is capable of generating one interrupt only: it maintains a pointer
144 * to it and returns it every time it is asked for it (via the get metod)
145 */
146class ArmSPIGen : public ArmInterruptPinGen
147{
148 public:
149 ArmSPIGen(const ArmSPIParams *p);
150
151 ArmInterruptPin* get(ThreadContext *tc = nullptr) override;
152 protected:
153 ArmSPI* pin;
154};
155
156/**
157 * Private Peripheral Interrupt Generator
158 * Since PPIs are banked in the GIC, this class is capable of generating
159 * more than one interrupt (one per ContextID).
160 */
161class ArmPPIGen : public ArmInterruptPinGen
162{
163 public:
164 ArmPPIGen(const ArmPPIParams *p);
165
166 ArmInterruptPin* get(ThreadContext* tc = nullptr) override;
167 protected:
168 std::unordered_map<ContextID, ArmPPI*> pins;
169};
170
171/**
172 * Generic representation of an Arm interrupt pin.
173 */
174class ArmInterruptPin
175{
176 friend class ArmInterruptPinGen;
177 protected:
178 ArmInterruptPin(Platform *platform, ThreadContext *tc,
179 uint32_t int_num);
180
181 public: /* Public interface */
182 /**
183 * Set the thread context owning this interrupt.
184 *
185 * This method is used to set the thread context for interrupts
186 * that are thread/CPU-specific. Only devices that are used in
187 * such a context are expected to call this method.
188 */
189 void setThreadContext(ThreadContext *tc);
190
191 /** Get interrupt number */
192 uint32_t num() const { return intNum; }
193
194 /** Signal an interrupt */
195 virtual void raise() = 0;
196 /** Clear a signalled interrupt */
197 virtual void clear() = 0;
198
199 protected:
200 /**
201 * Get the target context ID of this interrupt.
202 *
203 * @pre setThreadContext() must have been called prior to calling
204 * this method.
205 */
206 ContextID targetContext() const;
207
208 /**
209 * Pointer to the thread context that owns this interrupt in case
210 * it is a thread-/CPU-private interrupt
211 */
212 const ThreadContext *threadContext;
213
214 /** Arm platform to use for interrupt generation */
215 RealView *const platform;
216
217 /** Interrupt number to generate */
218 const uint32_t intNum;
219};
220
221class ArmSPI : public ArmInterruptPin
222{
223 friend class ArmSPIGen;
224 private:
225 ArmSPI(Platform *platform, uint32_t int_num);
226
227 public:
228 void raise() override;
229 void clear() override;
230};
231
232class ArmPPI : public ArmInterruptPin
233{
234 friend class ArmPPIGen;
235 private:
236 ArmPPI(Platform *platform, ThreadContext *tc, uint32_t int_num);
237
238 public:
239 void raise() override;
240 void clear() override;
241};
242
243#endif