diff options
Diffstat (limited to 'src/dev/arm/gic_v3_redistributor.hh')
-rw-r--r-- | src/dev/arm/gic_v3_redistributor.hh | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/src/dev/arm/gic_v3_redistributor.hh b/src/dev/arm/gic_v3_redistributor.hh new file mode 100644 index 000000000..11553974a --- /dev/null +++ b/src/dev/arm/gic_v3_redistributor.hh @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2018 Metempsy Technology Consulting + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Jairo Balart + */ + +#ifndef __DEV_ARM_GICV3_REDISTRIBUTOR_H__ +#define __DEV_ARM_GICV3_REDISTRIBUTOR_H__ + +#include "base/addr_range.hh" +#include "dev/arm/gic_v3.hh" +#include "sim/serialize.hh" + +class Gicv3Distributor; +class Gicv3CPUInterface; + +class Gicv3Redistributor : public Serializable +{ + private: + + friend class Gicv3CPUInterface; + friend class Gicv3Distributor; + + protected: + + Gicv3 * gic; + Gicv3Distributor * distributor; + Gicv3CPUInterface * cpuInterface; + uint32_t cpuId; + + /* + * GICv3 defines 2 contiguous 64KB frames for each redistributor. + * Order of frames must be RD_base, SGI_base. + */ + static const uint32_t RD_base = 0x0; + static const uint32_t SGI_base = 0x10000; + + enum { + // Control Register + GICR_CTLR = RD_base + 0x0000, + // Implementer Identification Register + GICR_IIDR = RD_base + 0x0004, + // Type Register + GICR_TYPER = RD_base + 0x0008, + // Wake Register + GICR_WAKER = RD_base + 0x0014, + // Peripheral ID0 Register + GICR_PIDR0 = RD_base + 0xffe0, + // Peripheral ID1 Register + GICR_PIDR1 = RD_base + 0xffe4, + // Peripheral ID2 Register + GICR_PIDR2 = RD_base + 0xffe8, + // Peripheral ID3 Register + GICR_PIDR3 = RD_base + 0xffec, + // Peripheral ID4 Register + GICR_PIDR4 = RD_base + 0xffd0, + // Peripheral ID5 Register + GICR_PIDR5 = RD_base + 0xffd4, + // Peripheral ID6 Register + GICR_PIDR6 = RD_base + 0xffd8, + // Peripheral ID7 Register + GICR_PIDR7 = RD_base + 0xffdc, + }; + + static const uint32_t GICR_WAKER_ProcessorSleep = 1 << 1; + static const uint32_t GICR_WAKER_ChildrenAsleep = 1 << 2; + + bool peInLowPowerState; + + enum { + // Interrupt Group Register 0 + GICR_IGROUPR0 = SGI_base + 0x0080, + // Interrupt Set-Enable Register 0 + GICR_ISENABLER0 = SGI_base + 0x0100, + // Interrupt Clear-Enable Register 0 + GICR_ICENABLER0 = SGI_base + 0x0180, + // Interrupt Set-Pending Register 0 + GICR_ISPENDR0 = SGI_base + 0x0200, + // Interrupt Clear-Pending Register 0 + GICR_ICPENDR0 = SGI_base + 0x0280, + // Interrupt Set-Active Register 0 + GICR_ISACTIVER0 = SGI_base + 0x0300, + // Interrupt Clear-Active Register 0 + GICR_ICACTIVER0 = SGI_base + 0x0380, + // SGI Configuration Register + GICR_ICFGR0 = SGI_base + 0x0c00, + // PPI Configuration Register + GICR_ICFGR1 = SGI_base + 0x0c04, + // Interrupt Group Modifier Register 0 + GICR_IGRPMODR0 = SGI_base + 0x0d00, + // Non-secure Access Control Register + GICR_NSACR = SGI_base + 0x0e00, + }; + + // Interrupt Priority Registers + static const AddrRange GICR_IPRIORITYR; + + std::vector <uint8_t> irqGroup; + std::vector <bool> irqEnabled; + std::vector <bool> irqPending; + std::vector <bool> irqActive; + std::vector <uint8_t> irqPriority; + std::vector <Gicv3::IntTriggerType> irqConfig; + std::vector <uint8_t> irqGrpmod; + std::vector <uint8_t> irqNsacr; + + bool DPG1S; + bool DPG1NS; + bool DPG0; + + static const uint32_t GICR_CTLR_DPG0 = 1 << 24; + static const uint32_t GICR_CTLR_DPG1NS = 1 << 25; + static const uint32_t GICR_CTLR_DPG1S = 1 << 26; + + public: + + /* + * GICv3 defines only 2 64K consecutive frames for the redistributor + * (RD_base and SGI_base) but we are using 2 extra 64K stride frames + * to match GICv4 that defines 4 64K consecutive frames for them. + * Note this must match with DTB/DTS GIC node definition and boot + * loader code. + */ + static const uint32_t ADDR_RANGE_SIZE = 0x40000; + + Gicv3Redistributor(Gicv3 * gic, uint32_t cpu_id); + ~Gicv3Redistributor(); + void init(); + void initState(); + + uint64_t read(Addr addr, size_t size, bool is_secure_access); + void write(Addr addr, uint64_t data, size_t size, + bool is_secure_access); + void sendPPInt(uint32_t int_id); + void sendSGI(uint32_t int_id, Gicv3::GroupId group, bool ns); + void serialize(CheckpointOut & cp) const override; + void unserialize(CheckpointIn & cp) override; + uint32_t getAffinity(); + + Gicv3CPUInterface * + getCPUInterface() const + { + return cpuInterface; + } + + bool canBeSelectedFor1toNInterrupt(Gicv3::GroupId group); + + protected: + + void reset(); + void update(); + void updateAndInformCPUInterface(); + Gicv3::IntStatus intStatus(uint32_t int_id); + Gicv3::GroupId getIntGroup(int int_id); + void activateIRQ(uint32_t int_id); + void deactivateIRQ(uint32_t int_id); +}; + +#endif //__DEV_ARM_GICV3_REDISTRIBUTOR_H__ |