110915Sandreas.sandberg@arm.com/*
210915Sandreas.sandberg@arm.com * Copyright (c) 2014-2015 ARM Limited
310915Sandreas.sandberg@arm.com * All rights reserved
410915Sandreas.sandberg@arm.com *
510915Sandreas.sandberg@arm.com * Licensed under the Apache License, Version 2.0 (the "License");
610915Sandreas.sandberg@arm.com * you may not use this file except in compliance with the License.
710915Sandreas.sandberg@arm.com * You may obtain a copy of the License at
810915Sandreas.sandberg@arm.com *
910915Sandreas.sandberg@arm.com *     http://www.apache.org/licenses/LICENSE-2.0
1010915Sandreas.sandberg@arm.com *
1110915Sandreas.sandberg@arm.com * Unless required by applicable law or agreed to in writing, software
1210915Sandreas.sandberg@arm.com * distributed under the License is distributed on an "AS IS" BASIS,
1310915Sandreas.sandberg@arm.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1410915Sandreas.sandberg@arm.com * See the License for the specific language governing permissions and
1510915Sandreas.sandberg@arm.com * limitations under the License.
1610915Sandreas.sandberg@arm.com *
1710915Sandreas.sandberg@arm.com * Authors: Andreas Sandberg
1810915Sandreas.sandberg@arm.com */
1910915Sandreas.sandberg@arm.com
2010915Sandreas.sandberg@arm.com#ifndef _LIBNOMALIMODEL_GPUBLOCK_HH
2110915Sandreas.sandberg@arm.com#define _LIBNOMALIMODEL_GPUBLOCK_HH
2210915Sandreas.sandberg@arm.com
2310915Sandreas.sandberg@arm.com#include "types.hh"
2410915Sandreas.sandberg@arm.com
2510915Sandreas.sandberg@arm.comnamespace NoMali {
2610915Sandreas.sandberg@arm.com
2710915Sandreas.sandberg@arm.comclass GPU;
2810915Sandreas.sandberg@arm.com
2910915Sandreas.sandberg@arm.com/**
3010915Sandreas.sandberg@arm.com * Base class for GPU function blocks providing common access
3110915Sandreas.sandberg@arm.com * functions.
3210915Sandreas.sandberg@arm.com */
3310915Sandreas.sandberg@arm.comclass GPUBlock
3410915Sandreas.sandberg@arm.com{
3510915Sandreas.sandberg@arm.com  public:
3610915Sandreas.sandberg@arm.com    GPUBlock(GPU &_gpu);
3710915Sandreas.sandberg@arm.com    GPUBlock(GPU &_gpu, RegVector::size_type no_regs);
3810915Sandreas.sandberg@arm.com    GPUBlock(GPUBlock &&rhs);
3910915Sandreas.sandberg@arm.com    virtual ~GPUBlock() = 0;
4010915Sandreas.sandberg@arm.com
4110915Sandreas.sandberg@arm.com    /**
4210915Sandreas.sandberg@arm.com     * Reset the function block.
4310915Sandreas.sandberg@arm.com     *
4410915Sandreas.sandberg@arm.com     * This method is called to simulated a hard reset of the GPU. It
4510915Sandreas.sandberg@arm.com     * resets all registers to their default state and resets any
4610915Sandreas.sandberg@arm.com     * block-specific state. The default implementation resets all
4710915Sandreas.sandberg@arm.com     * registers to 0.
4810915Sandreas.sandberg@arm.com     */
4910915Sandreas.sandberg@arm.com    virtual void reset();
5010915Sandreas.sandberg@arm.com
5110915Sandreas.sandberg@arm.com
5210915Sandreas.sandberg@arm.com    /**
5310915Sandreas.sandberg@arm.com     * @{
5410915Sandreas.sandberg@arm.com     * @name Register Interface
5510915Sandreas.sandberg@arm.com     */
5610915Sandreas.sandberg@arm.com
5710915Sandreas.sandberg@arm.com    /**
5810915Sandreas.sandberg@arm.com     * Read a register within a function block.
5910915Sandreas.sandberg@arm.com     *
6010915Sandreas.sandberg@arm.com     * @param addr Function-block relative address.
6110915Sandreas.sandberg@arm.com     * @return Register value (32-bits)
6210915Sandreas.sandberg@arm.com     */
6310915Sandreas.sandberg@arm.com    virtual uint32_t readReg(RegAddr addr);
6410915Sandreas.sandberg@arm.com
6510915Sandreas.sandberg@arm.com    /**
6610915Sandreas.sandberg@arm.com     * Write to a register within a function block.
6710915Sandreas.sandberg@arm.com     *
6810915Sandreas.sandberg@arm.com     * @param addr Function-block relative address.
6910915Sandreas.sandberg@arm.com     * @param value New value (32-bits)
7010915Sandreas.sandberg@arm.com     */
7110915Sandreas.sandberg@arm.com    virtual void writeReg(RegAddr addr, uint32_t value);
7210915Sandreas.sandberg@arm.com
7310915Sandreas.sandberg@arm.com
7410915Sandreas.sandberg@arm.com    /**
7510915Sandreas.sandberg@arm.com     * Read a register within a function block without side effects.
7610915Sandreas.sandberg@arm.com     *
7710915Sandreas.sandberg@arm.com     * Unlike a normal read (readReg()), this method does not include
7810915Sandreas.sandberg@arm.com     * any side effects and reads straight from the register file. It
7910915Sandreas.sandberg@arm.com     * is primarily intended for things checkpointing.
8010915Sandreas.sandberg@arm.com     *
8110915Sandreas.sandberg@arm.com     * @param addr Function-block relative address.
8210915Sandreas.sandberg@arm.com     * @return Register value (32-bits)
8310915Sandreas.sandberg@arm.com     */
8410915Sandreas.sandberg@arm.com    virtual uint32_t readRegRaw(RegAddr addr);
8510915Sandreas.sandberg@arm.com
8610915Sandreas.sandberg@arm.com    /**
8710915Sandreas.sandberg@arm.com     * Write to a register within a function block without side
8810915Sandreas.sandberg@arm.com     * effects.
8910915Sandreas.sandberg@arm.com     *
9010915Sandreas.sandberg@arm.com     * Unlike a normal write (writeReg()), this method does not
9110915Sandreas.sandberg@arm.com     * include any side effects and writes straight into the register
9210915Sandreas.sandberg@arm.com     * file. It is primarily intended for things checkpointing.
9310915Sandreas.sandberg@arm.com     *
9410915Sandreas.sandberg@arm.com     * @param addr Function-block relative address.
9510915Sandreas.sandberg@arm.com     * @param value New value (32-bits)
9610915Sandreas.sandberg@arm.com     */
9710915Sandreas.sandberg@arm.com    virtual void writeRegRaw(RegAddr addr, uint32_t value);
9810915Sandreas.sandberg@arm.com
9910915Sandreas.sandberg@arm.com    /** @} */
10010915Sandreas.sandberg@arm.com
10110915Sandreas.sandberg@arm.com  protected:
10210915Sandreas.sandberg@arm.com    /** Reference to the top-level GPU component */
10310915Sandreas.sandberg@arm.com    GPU &gpu;
10410915Sandreas.sandberg@arm.com
10510915Sandreas.sandberg@arm.com    /** GPU block register file */
10610915Sandreas.sandberg@arm.com    RegVector regs;
10710915Sandreas.sandberg@arm.com
10810915Sandreas.sandberg@arm.com
10910915Sandreas.sandberg@arm.com  private:
11010915Sandreas.sandberg@arm.com    /** Disable the default constructor */
11110915Sandreas.sandberg@arm.com    GPUBlock();
11210915Sandreas.sandberg@arm.com
11310915Sandreas.sandberg@arm.com    /** Disable the copy constructor */
11410915Sandreas.sandberg@arm.com    GPUBlock(GPUBlock &_rhs);
11510915Sandreas.sandberg@arm.com
11610915Sandreas.sandberg@arm.com    /** Disable the assignment operator */
11710915Sandreas.sandberg@arm.com    GPUBlock &operator=(GPUBlock &_rhs);
11810915Sandreas.sandberg@arm.com};
11910915Sandreas.sandberg@arm.com
12010915Sandreas.sandberg@arm.com/**
12110915Sandreas.sandberg@arm.com * Base class for interrupt enabled GPU function blocks.
12210915Sandreas.sandberg@arm.com *
12310915Sandreas.sandberg@arm.com * Function blocks with interrupt functionality implement four
12410915Sandreas.sandberg@arm.com * different registers controlling interrupts:
12510915Sandreas.sandberg@arm.com * <ul>
12610915Sandreas.sandberg@arm.com *   <li>XX_IRQ_RAWSTAT -- Raw interrupt state bit mask. (RW)
12710915Sandreas.sandberg@arm.com *   <li>XX_IRQ_CLEAR -- Interrupt clear register. (WO)
12810915Sandreas.sandberg@arm.com *   <li>XX_IRQ_MASK -- Bitmaks of enabled interrupts. (RW)
12910915Sandreas.sandberg@arm.com *   <li>XX_IRQ_STATUS -- Currently pending unmasked interrupts. (RO)
13010915Sandreas.sandberg@arm.com * </ul>
13110915Sandreas.sandberg@arm.com *
13210915Sandreas.sandberg@arm.com * This class provides implements the handling of the registers above
13310915Sandreas.sandberg@arm.com * and utility functions to raise interrupts from the function block
13410915Sandreas.sandberg@arm.com * models.
13510915Sandreas.sandberg@arm.com */
13610915Sandreas.sandberg@arm.comclass GPUBlockInt
13710915Sandreas.sandberg@arm.com    : public GPUBlock
13810915Sandreas.sandberg@arm.com{
13910915Sandreas.sandberg@arm.com  public:
14010915Sandreas.sandberg@arm.com    GPUBlockInt(GPU &_gpu,
14110915Sandreas.sandberg@arm.com                const RegAddr &irq_raw_stat,
14210915Sandreas.sandberg@arm.com                const RegAddr &irq_clear,
14310915Sandreas.sandberg@arm.com                const RegAddr &irq_mask,
14410915Sandreas.sandberg@arm.com                const RegAddr &irq_stat);
14510915Sandreas.sandberg@arm.com    virtual ~GPUBlockInt() = 0;
14610915Sandreas.sandberg@arm.com
14710915Sandreas.sandberg@arm.com    uint32_t readReg(RegAddr addr) override;
14810915Sandreas.sandberg@arm.com    void writeReg(RegAddr addr, uint32_t value) override;
14910915Sandreas.sandberg@arm.com
15010915Sandreas.sandberg@arm.com    /**
15110915Sandreas.sandberg@arm.com     * Raise an interrupt from this function block.
15210915Sandreas.sandberg@arm.com     *
15310915Sandreas.sandberg@arm.com     * Calling this method flags the interrupts in ints as pending in
15410915Sandreas.sandberg@arm.com     * the raw interrupt status register. If this operation asserts a
15510915Sandreas.sandberg@arm.com     * new unmasked interrupt (i.e., the state of the interrupt status
15610915Sandreas.sandberg@arm.com     * register changes), the onInterrupt() callback is called to
15710915Sandreas.sandberg@arm.com     * signal an interrupt state change.
15810915Sandreas.sandberg@arm.com     *
15910915Sandreas.sandberg@arm.com     * @param ints Bitfield representing interrupts to raise.
16010915Sandreas.sandberg@arm.com     */
16110915Sandreas.sandberg@arm.com    void raiseInterrupt(uint32_t ints);
16210915Sandreas.sandberg@arm.com
16310915Sandreas.sandberg@arm.com    /**
16410915Sandreas.sandberg@arm.com     * Clear an interrupt from this function block.
16510915Sandreas.sandberg@arm.com     *
16610915Sandreas.sandberg@arm.com     * Calling this method clears the interrupts in ints in the raw
16710915Sandreas.sandberg@arm.com     * interrupt status register. If this operation clears a an
16810915Sandreas.sandberg@arm.com     * existing interrupt (i.e., the state of the interrupt status
16910915Sandreas.sandberg@arm.com     * register changes), the onInterrupt() callback is called to
17010915Sandreas.sandberg@arm.com     * signal an interrupt state change.
17110915Sandreas.sandberg@arm.com     *
17210915Sandreas.sandberg@arm.com     * @param ints Bitfield representing interrupts to raise.
17310915Sandreas.sandberg@arm.com     */
17410915Sandreas.sandberg@arm.com    void clearInterrupt(uint32_t ints);
17510915Sandreas.sandberg@arm.com
17610915Sandreas.sandberg@arm.com    /**
17710915Sandreas.sandberg@arm.com     * Current interrupt status
17810915Sandreas.sandberg@arm.com     *
17910915Sandreas.sandberg@arm.com     * @return The value of the raw interrupt status register
18010915Sandreas.sandberg@arm.com     * logically anded with the interrupt mask register.
18110915Sandreas.sandberg@arm.com     */
18210915Sandreas.sandberg@arm.com    uint32_t irqStatus() const;
18310915Sandreas.sandberg@arm.com
18410915Sandreas.sandberg@arm.com    /**
18510915Sandreas.sandberg@arm.com     * Are there unmasked interrupts pending?
18610915Sandreas.sandberg@arm.com     *
18710915Sandreas.sandberg@arm.com     * @return true if the interrupt status register is non-zero,
18810915Sandreas.sandberg@arm.com     * false otherwise.
18910915Sandreas.sandberg@arm.com     */
19010915Sandreas.sandberg@arm.com    bool intAsserted() const { return !!irqStatus(); }
19110915Sandreas.sandberg@arm.com
19210915Sandreas.sandberg@arm.com  protected:
19310915Sandreas.sandberg@arm.com    /**
19410915Sandreas.sandberg@arm.com     * Callback method for interrupt status change.
19510915Sandreas.sandberg@arm.com     *
19610915Sandreas.sandberg@arm.com     * This method is called whenever the interrupt signal going out
19710915Sandreas.sandberg@arm.com     * of this GPU block changes. The new state of the signal can be
19810915Sandreas.sandberg@arm.com     * determined from the 'set' parameter which is non-zero if the
19910915Sandreas.sandberg@arm.com     * inerrupt is raised and zero if it is cleared. The state of the
20010915Sandreas.sandberg@arm.com     * interrupt signal can also be queried using the irqStatus()
20110915Sandreas.sandberg@arm.com     * method.
20210915Sandreas.sandberg@arm.com     *
20310915Sandreas.sandberg@arm.com     * @see raiseInterrupt()
20410915Sandreas.sandberg@arm.com     * @see clearInterrupt()
20510915Sandreas.sandberg@arm.com     * @see irqStatus()
20610915Sandreas.sandberg@arm.com     *
20710915Sandreas.sandberg@arm.com     * @param set Non-zero to raise interrupt, zero to clear
20810915Sandreas.sandberg@arm.com     * interrupt.
20910915Sandreas.sandberg@arm.com     */
21010915Sandreas.sandberg@arm.com    virtual void onInterrupt(int set) = 0;
21110915Sandreas.sandberg@arm.com
21210915Sandreas.sandberg@arm.com  private:
21310915Sandreas.sandberg@arm.com    const RegAddr addrIrqRawStat;
21410915Sandreas.sandberg@arm.com    const RegAddr addrIrqClear;
21510915Sandreas.sandberg@arm.com    const RegAddr addrIrqMask;
21610915Sandreas.sandberg@arm.com    const RegAddr addrIrqStat;
21710915Sandreas.sandberg@arm.com};
21810915Sandreas.sandberg@arm.com
21910915Sandreas.sandberg@arm.com}
22010915Sandreas.sandberg@arm.com
22110915Sandreas.sandberg@arm.com#endif // _LIBNOMALIMODEL_GPUBLOCK_HH
222