1/*
2 * Copyright (c) 2014-2015 ARM Limited
3 * All rights reserved
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 * Authors: Andreas Sandberg
18 */
19
20#ifndef _LIBNOMALIMODEL_GPUBLOCK_HH
21#define _LIBNOMALIMODEL_GPUBLOCK_HH
22
23#include "types.hh"
24
25namespace NoMali {
26
27class GPU;
28
29/**
30 * Base class for GPU function blocks providing common access
31 * functions.
32 */
33class GPUBlock
34{
35  public:
36    GPUBlock(GPU &_gpu);
37    GPUBlock(GPU &_gpu, RegVector::size_type no_regs);
38    GPUBlock(GPUBlock &&rhs);
39    virtual ~GPUBlock() = 0;
40
41    /**
42     * Reset the function block.
43     *
44     * This method is called to simulated a hard reset of the GPU. It
45     * resets all registers to their default state and resets any
46     * block-specific state. The default implementation resets all
47     * registers to 0.
48     */
49    virtual void reset();
50
51
52    /**
53     * @{
54     * @name Register Interface
55     */
56
57    /**
58     * Read a register within a function block.
59     *
60     * @param addr Function-block relative address.
61     * @return Register value (32-bits)
62     */
63    virtual uint32_t readReg(RegAddr addr);
64
65    /**
66     * Write to a register within a function block.
67     *
68     * @param addr Function-block relative address.
69     * @param value New value (32-bits)
70     */
71    virtual void writeReg(RegAddr addr, uint32_t value);
72
73
74    /**
75     * Read a register within a function block without side effects.
76     *
77     * Unlike a normal read (readReg()), this method does not include
78     * any side effects and reads straight from the register file. It
79     * is primarily intended for things checkpointing.
80     *
81     * @param addr Function-block relative address.
82     * @return Register value (32-bits)
83     */
84    virtual uint32_t readRegRaw(RegAddr addr);
85
86    /**
87     * Write to a register within a function block without side
88     * effects.
89     *
90     * Unlike a normal write (writeReg()), this method does not
91     * include any side effects and writes straight into the register
92     * file. It is primarily intended for things checkpointing.
93     *
94     * @param addr Function-block relative address.
95     * @param value New value (32-bits)
96     */
97    virtual void writeRegRaw(RegAddr addr, uint32_t value);
98
99    /** @} */
100
101  protected:
102    /** Reference to the top-level GPU component */
103    GPU &gpu;
104
105    /** GPU block register file */
106    RegVector regs;
107
108
109  private:
110    /** Disable the default constructor */
111    GPUBlock();
112
113    /** Disable the copy constructor */
114    GPUBlock(GPUBlock &_rhs);
115
116    /** Disable the assignment operator */
117    GPUBlock &operator=(GPUBlock &_rhs);
118};
119
120/**
121 * Base class for interrupt enabled GPU function blocks.
122 *
123 * Function blocks with interrupt functionality implement four
124 * different registers controlling interrupts:
125 * <ul>
126 *   <li>XX_IRQ_RAWSTAT -- Raw interrupt state bit mask. (RW)
127 *   <li>XX_IRQ_CLEAR -- Interrupt clear register. (WO)
128 *   <li>XX_IRQ_MASK -- Bitmaks of enabled interrupts. (RW)
129 *   <li>XX_IRQ_STATUS -- Currently pending unmasked interrupts. (RO)
130 * </ul>
131 *
132 * This class provides implements the handling of the registers above
133 * and utility functions to raise interrupts from the function block
134 * models.
135 */
136class GPUBlockInt
137    : public GPUBlock
138{
139  public:
140    GPUBlockInt(GPU &_gpu,
141                const RegAddr &irq_raw_stat,
142                const RegAddr &irq_clear,
143                const RegAddr &irq_mask,
144                const RegAddr &irq_stat);
145    virtual ~GPUBlockInt() = 0;
146
147    uint32_t readReg(RegAddr addr) override;
148    void writeReg(RegAddr addr, uint32_t value) override;
149
150    /**
151     * Raise an interrupt from this function block.
152     *
153     * Calling this method flags the interrupts in ints as pending in
154     * the raw interrupt status register. If this operation asserts a
155     * new unmasked interrupt (i.e., the state of the interrupt status
156     * register changes), the onInterrupt() callback is called to
157     * signal an interrupt state change.
158     *
159     * @param ints Bitfield representing interrupts to raise.
160     */
161    void raiseInterrupt(uint32_t ints);
162
163    /**
164     * Clear an interrupt from this function block.
165     *
166     * Calling this method clears the interrupts in ints in the raw
167     * interrupt status register. If this operation clears a an
168     * existing interrupt (i.e., the state of the interrupt status
169     * register changes), the onInterrupt() callback is called to
170     * signal an interrupt state change.
171     *
172     * @param ints Bitfield representing interrupts to raise.
173     */
174    void clearInterrupt(uint32_t ints);
175
176    /**
177     * Current interrupt status
178     *
179     * @return The value of the raw interrupt status register
180     * logically anded with the interrupt mask register.
181     */
182    uint32_t irqStatus() const;
183
184    /**
185     * Are there unmasked interrupts pending?
186     *
187     * @return true if the interrupt status register is non-zero,
188     * false otherwise.
189     */
190    bool intAsserted() const { return !!irqStatus(); }
191
192  protected:
193    /**
194     * Callback method for interrupt status change.
195     *
196     * This method is called whenever the interrupt signal going out
197     * of this GPU block changes. The new state of the signal can be
198     * determined from the 'set' parameter which is non-zero if the
199     * inerrupt is raised and zero if it is cleared. The state of the
200     * interrupt signal can also be queried using the irqStatus()
201     * method.
202     *
203     * @see raiseInterrupt()
204     * @see clearInterrupt()
205     * @see irqStatus()
206     *
207     * @param set Non-zero to raise interrupt, zero to clear
208     * interrupt.
209     */
210    virtual void onInterrupt(int set) = 0;
211
212  private:
213    const RegAddr addrIrqRawStat;
214    const RegAddr addrIrqClear;
215    const RegAddr addrIrqMask;
216    const RegAddr addrIrqStat;
217};
218
219}
220
221#endif // _LIBNOMALIMODEL_GPUBLOCK_HH
222