gic_v3_distributor.hh revision 13927
113531Sjairo.balart@metempsy.com/*
213531Sjairo.balart@metempsy.com * Copyright (c) 2018 Metempsy Technology Consulting
313531Sjairo.balart@metempsy.com * All rights reserved.
413531Sjairo.balart@metempsy.com *
513531Sjairo.balart@metempsy.com * Redistribution and use in source and binary forms, with or without
613531Sjairo.balart@metempsy.com * modification, are permitted provided that the following conditions are
713531Sjairo.balart@metempsy.com * met: redistributions of source code must retain the above copyright
813531Sjairo.balart@metempsy.com * notice, this list of conditions and the following disclaimer;
913531Sjairo.balart@metempsy.com * redistributions in binary form must reproduce the above copyright
1013531Sjairo.balart@metempsy.com * notice, this list of conditions and the following disclaimer in the
1113531Sjairo.balart@metempsy.com * documentation and/or other materials provided with the distribution;
1213531Sjairo.balart@metempsy.com * neither the name of the copyright holders nor the names of its
1313531Sjairo.balart@metempsy.com * contributors may be used to endorse or promote products derived from
1413531Sjairo.balart@metempsy.com * this software without specific prior written permission.
1513531Sjairo.balart@metempsy.com *
1613531Sjairo.balart@metempsy.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1713531Sjairo.balart@metempsy.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1813531Sjairo.balart@metempsy.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1913531Sjairo.balart@metempsy.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2013531Sjairo.balart@metempsy.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2113531Sjairo.balart@metempsy.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2213531Sjairo.balart@metempsy.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2313531Sjairo.balart@metempsy.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2413531Sjairo.balart@metempsy.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2513531Sjairo.balart@metempsy.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2613531Sjairo.balart@metempsy.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2713531Sjairo.balart@metempsy.com *
2813531Sjairo.balart@metempsy.com * Authors: Jairo Balart
2913531Sjairo.balart@metempsy.com */
3013531Sjairo.balart@metempsy.com
3113531Sjairo.balart@metempsy.com#ifndef __DEV_ARM_GICV3_DISTRIBUTOR_H__
3213531Sjairo.balart@metempsy.com#define __DEV_ARM_GICV3_DISTRIBUTOR_H__
3313531Sjairo.balart@metempsy.com
3413531Sjairo.balart@metempsy.com#include "base/addr_range.hh"
3513531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3.hh"
3613531Sjairo.balart@metempsy.com#include "sim/serialize.hh"
3713531Sjairo.balart@metempsy.com
3813531Sjairo.balart@metempsy.comclass Gicv3Distributor : public Serializable
3913531Sjairo.balart@metempsy.com{
4013531Sjairo.balart@metempsy.com  private:
4113531Sjairo.balart@metempsy.com
4213531Sjairo.balart@metempsy.com    friend class Gicv3Redistributor;
4313531Sjairo.balart@metempsy.com    friend class Gicv3CPUInterface;
4413531Sjairo.balart@metempsy.com
4513531Sjairo.balart@metempsy.com  protected:
4613531Sjairo.balart@metempsy.com
4713531Sjairo.balart@metempsy.com    Gicv3 * gic;
4813531Sjairo.balart@metempsy.com    const uint32_t itLines;
4913531Sjairo.balart@metempsy.com
5013531Sjairo.balart@metempsy.com    enum {
5113531Sjairo.balart@metempsy.com        // Control Register
5213531Sjairo.balart@metempsy.com        GICD_CTLR  = 0x0000,
5313531Sjairo.balart@metempsy.com        // Interrupt Controller Type Register
5413531Sjairo.balart@metempsy.com        GICD_TYPER = 0x0004,
5513531Sjairo.balart@metempsy.com        // Implementer Identification Register
5613531Sjairo.balart@metempsy.com        GICD_IIDR = 0x0008,
5713531Sjairo.balart@metempsy.com        // Error Reporting Status Register
5813531Sjairo.balart@metempsy.com        GICD_STATUSR = 0x0010,
5913531Sjairo.balart@metempsy.com        // Peripheral ID0 Register
6013531Sjairo.balart@metempsy.com        GICD_PIDR0 = 0xffe0,
6113531Sjairo.balart@metempsy.com        // Peripheral ID1 Register
6213531Sjairo.balart@metempsy.com        GICD_PIDR1 = 0xffe4,
6313531Sjairo.balart@metempsy.com        // Peripheral ID2 Register
6413531Sjairo.balart@metempsy.com        GICD_PIDR2 = 0xffe8,
6513531Sjairo.balart@metempsy.com        // Peripheral ID3 Register
6613531Sjairo.balart@metempsy.com        GICD_PIDR3 = 0xffec,
6713531Sjairo.balart@metempsy.com        // Peripheral ID4 Register
6813531Sjairo.balart@metempsy.com        GICD_PIDR4 = 0xffd0,
6913531Sjairo.balart@metempsy.com        // Peripheral ID5 Register
7013531Sjairo.balart@metempsy.com        GICD_PIDR5 = 0xffd4,
7113531Sjairo.balart@metempsy.com        // Peripheral ID6 Register
7213531Sjairo.balart@metempsy.com        GICD_PIDR6 = 0xffd8,
7313531Sjairo.balart@metempsy.com        // Peripheral ID7 Register
7413531Sjairo.balart@metempsy.com        GICD_PIDR7 = 0xffdc,
7513531Sjairo.balart@metempsy.com    };
7613531Sjairo.balart@metempsy.com
7713531Sjairo.balart@metempsy.com    // Interrupt Group Registers
7813531Sjairo.balart@metempsy.com    static const AddrRange GICD_IGROUPR;
7913531Sjairo.balart@metempsy.com    // Interrupt Set-Enable Registers
8013531Sjairo.balart@metempsy.com    static const AddrRange GICD_ISENABLER;
8113531Sjairo.balart@metempsy.com    // Interrupt Clear-Enable Registers
8213531Sjairo.balart@metempsy.com    static const AddrRange GICD_ICENABLER;
8313531Sjairo.balart@metempsy.com    // Interrupt Set-Pending Registers
8413531Sjairo.balart@metempsy.com    static const AddrRange GICD_ISPENDR;
8513531Sjairo.balart@metempsy.com    // Interrupt Clear-Pending Registers
8613531Sjairo.balart@metempsy.com    static const AddrRange GICD_ICPENDR;
8713531Sjairo.balart@metempsy.com    // Interrupt Set-Active Registers
8813531Sjairo.balart@metempsy.com    static const AddrRange GICD_ISACTIVER;
8913531Sjairo.balart@metempsy.com    // Interrupt Clear-Active Registers
9013531Sjairo.balart@metempsy.com    static const AddrRange GICD_ICACTIVER;
9113531Sjairo.balart@metempsy.com    // Interrupt Priority Registers
9213531Sjairo.balart@metempsy.com    static const AddrRange GICD_IPRIORITYR;
9313531Sjairo.balart@metempsy.com    // Interrupt Processor Targets Registers
9413531Sjairo.balart@metempsy.com    static const AddrRange GICD_ITARGETSR; // GICv2 legacy
9513531Sjairo.balart@metempsy.com    // Interrupt Configuration Registers
9613531Sjairo.balart@metempsy.com    static const AddrRange GICD_ICFGR;
9713531Sjairo.balart@metempsy.com    // Interrupt Group Modifier Registers
9813531Sjairo.balart@metempsy.com    static const AddrRange GICD_IGRPMODR;
9913531Sjairo.balart@metempsy.com    // Non-secure Access Control Registers
10013531Sjairo.balart@metempsy.com    static const AddrRange GICD_NSACR;
10113531Sjairo.balart@metempsy.com    // SGI Clear-Pending Registers
10213531Sjairo.balart@metempsy.com    static const AddrRange GICD_CPENDSGIR; // GICv2 legacy
10313531Sjairo.balart@metempsy.com    // SGI Set-Pending Registers
10413531Sjairo.balart@metempsy.com    static const AddrRange GICD_SPENDSGIR; // GICv2 legacy
10513531Sjairo.balart@metempsy.com    // Interrupt Routing Registers
10613531Sjairo.balart@metempsy.com    static const AddrRange GICD_IROUTER;
10713531Sjairo.balart@metempsy.com
10813531Sjairo.balart@metempsy.com    BitUnion64(IROUTER)
10913756Sjairo.balart@metempsy.com        Bitfield<63, 40> res0_1;
11013756Sjairo.balart@metempsy.com        Bitfield<39, 32> Aff3;
11113756Sjairo.balart@metempsy.com        Bitfield<31>     IRM;
11213756Sjairo.balart@metempsy.com        Bitfield<30, 24> res0_2;
11313756Sjairo.balart@metempsy.com        Bitfield<23, 16> Aff2;
11413756Sjairo.balart@metempsy.com        Bitfield<15, 8>  Aff1;
11513756Sjairo.balart@metempsy.com        Bitfield<7, 0>   Aff0;
11613531Sjairo.balart@metempsy.com    EndBitUnion(IROUTER)
11713531Sjairo.balart@metempsy.com
11813756Sjairo.balart@metempsy.com    static const uint32_t GICD_CTLR_ENABLEGRP0   = 1 << 0;
11913756Sjairo.balart@metempsy.com    static const uint32_t GICD_CTLR_ENABLEGRP1   = 1 << 0;
12013531Sjairo.balart@metempsy.com    static const uint32_t GICD_CTLR_ENABLEGRP1NS = 1 << 1;
12113756Sjairo.balart@metempsy.com    static const uint32_t GICD_CTLR_ENABLEGRP1A  = 1 << 1;
12213756Sjairo.balart@metempsy.com    static const uint32_t GICD_CTLR_ENABLEGRP1S  = 1 << 2;
12313756Sjairo.balart@metempsy.com    static const uint32_t GICD_CTLR_DS           = 1 << 6;
12413531Sjairo.balart@metempsy.com
12513531Sjairo.balart@metempsy.com    bool ARE;
12613531Sjairo.balart@metempsy.com    bool DS;
12713531Sjairo.balart@metempsy.com    bool EnableGrp1S;
12813531Sjairo.balart@metempsy.com    bool EnableGrp1NS;
12913531Sjairo.balart@metempsy.com    bool EnableGrp0;
13013531Sjairo.balart@metempsy.com    std::vector <uint8_t> irqGroup;
13113531Sjairo.balart@metempsy.com    std::vector <bool> irqEnabled;
13213531Sjairo.balart@metempsy.com    std::vector <bool> irqPending;
13313531Sjairo.balart@metempsy.com    std::vector <bool> irqActive;
13413531Sjairo.balart@metempsy.com    std::vector <uint8_t> irqPriority;
13513531Sjairo.balart@metempsy.com    std::vector <Gicv3::IntTriggerType> irqConfig;
13613531Sjairo.balart@metempsy.com    std::vector <uint8_t> irqGrpmod;
13713531Sjairo.balart@metempsy.com    std::vector <uint8_t> irqNsacr;
13813531Sjairo.balart@metempsy.com    std::vector <IROUTER> irqAffinityRouting;
13913531Sjairo.balart@metempsy.com
14013531Sjairo.balart@metempsy.com  public:
14113531Sjairo.balart@metempsy.com
14213531Sjairo.balart@metempsy.com    static const uint32_t ADDR_RANGE_SIZE = 0x10000;
14313927Sgiacomo.travaglini@arm.com    static const uint32_t IDBITS = 0xf;
14413531Sjairo.balart@metempsy.com
14513756Sjairo.balart@metempsy.com  protected:
14613531Sjairo.balart@metempsy.com
14713756Sjairo.balart@metempsy.com    void activateIRQ(uint32_t int_id);
14813756Sjairo.balart@metempsy.com    void deactivateIRQ(uint32_t int_id);
14913756Sjairo.balart@metempsy.com    void fullUpdate();
15013756Sjairo.balart@metempsy.com    Gicv3::GroupId getIntGroup(int int_id) const;
15113531Sjairo.balart@metempsy.com
15213756Sjairo.balart@metempsy.com    inline bool
15313756Sjairo.balart@metempsy.com    groupEnabled(Gicv3::GroupId group) const
15413531Sjairo.balart@metempsy.com    {
15513531Sjairo.balart@metempsy.com        if (DS == 0) {
15613531Sjairo.balart@metempsy.com            switch (group) {
15713531Sjairo.balart@metempsy.com              case Gicv3::G0S:
15813531Sjairo.balart@metempsy.com                return EnableGrp0;
15913531Sjairo.balart@metempsy.com
16013531Sjairo.balart@metempsy.com              case Gicv3::G1S:
16113531Sjairo.balart@metempsy.com                return EnableGrp1S;
16213531Sjairo.balart@metempsy.com
16313531Sjairo.balart@metempsy.com              case Gicv3::G1NS:
16413531Sjairo.balart@metempsy.com                return EnableGrp1NS;
16513531Sjairo.balart@metempsy.com
16613531Sjairo.balart@metempsy.com              default:
16713531Sjairo.balart@metempsy.com                panic("Gicv3Distributor::groupEnabled(): "
16813531Sjairo.balart@metempsy.com                        "invalid group!\n");
16913531Sjairo.balart@metempsy.com            }
17013531Sjairo.balart@metempsy.com        } else {
17113531Sjairo.balart@metempsy.com            switch (group) {
17213531Sjairo.balart@metempsy.com              case Gicv3::G0S:
17313531Sjairo.balart@metempsy.com                return EnableGrp0;
17413531Sjairo.balart@metempsy.com
17513531Sjairo.balart@metempsy.com              case Gicv3::G1S:
17613531Sjairo.balart@metempsy.com              case Gicv3::G1NS:
17713531Sjairo.balart@metempsy.com                return EnableGrp1NS;
17813531Sjairo.balart@metempsy.com
17913531Sjairo.balart@metempsy.com              default:
18013531Sjairo.balart@metempsy.com                panic("Gicv3Distributor::groupEnabled(): "
18113531Sjairo.balart@metempsy.com                        "invalid group!\n");
18213531Sjairo.balart@metempsy.com            }
18313531Sjairo.balart@metempsy.com        }
18413531Sjairo.balart@metempsy.com    }
18513531Sjairo.balart@metempsy.com
18613756Sjairo.balart@metempsy.com    Gicv3::IntStatus intStatus(uint32_t int_id) const;
18713531Sjairo.balart@metempsy.com
18813813Sgiacomo.travaglini@arm.com    inline bool isNotSPI(uint32_t int_id) const
18913531Sjairo.balart@metempsy.com    {
19013531Sjairo.balart@metempsy.com        if (int_id < (Gicv3::SGI_MAX + Gicv3::PPI_MAX) || int_id >= itLines) {
19113531Sjairo.balart@metempsy.com            return true;
19213531Sjairo.balart@metempsy.com        } else {
19313531Sjairo.balart@metempsy.com            return false;
19413531Sjairo.balart@metempsy.com        }
19513531Sjairo.balart@metempsy.com    }
19613531Sjairo.balart@metempsy.com
19713813Sgiacomo.travaglini@arm.com    inline bool nsAccessToSecInt(uint32_t int_id, bool is_secure_access) const
19813531Sjairo.balart@metempsy.com    {
19913531Sjairo.balart@metempsy.com        return !DS && !is_secure_access && getIntGroup(int_id) != Gicv3::G1NS;
20013531Sjairo.balart@metempsy.com    }
20113531Sjairo.balart@metempsy.com
20213756Sjairo.balart@metempsy.com    void reset();
20313756Sjairo.balart@metempsy.com    void serialize(CheckpointOut & cp) const override;
20413756Sjairo.balart@metempsy.com    void unserialize(CheckpointIn & cp) override;
20513756Sjairo.balart@metempsy.com    void update();
20613756Sjairo.balart@metempsy.com    void updateAndInformCPUInterfaces();
20713531Sjairo.balart@metempsy.com
20813756Sjairo.balart@metempsy.com  public:
20913756Sjairo.balart@metempsy.com
21013756Sjairo.balart@metempsy.com    Gicv3Distributor(Gicv3 * gic, uint32_t it_lines);
21113756Sjairo.balart@metempsy.com
21213756Sjairo.balart@metempsy.com    void deassertSPI(uint32_t int_id);
21313756Sjairo.balart@metempsy.com    void init();
21413756Sjairo.balart@metempsy.com    void initState();
21513756Sjairo.balart@metempsy.com    uint64_t read(Addr addr, size_t size, bool is_secure_access);
21613756Sjairo.balart@metempsy.com    void sendInt(uint32_t int_id);
21713756Sjairo.balart@metempsy.com    void write(Addr addr, uint64_t data, size_t size,
21813756Sjairo.balart@metempsy.com               bool is_secure_access);
21913531Sjairo.balart@metempsy.com};
22013531Sjairo.balart@metempsy.com
22113531Sjairo.balart@metempsy.com#endif //__DEV_ARM_GICV3_DISTRIBUTOR_H__
222