As part of recent decisions regarding namespace naming conventions, all namespaces will be changed to snake case. ::SCMI became ::scmi. Change-Id: I68f729124079ecce02120577d2b89b25f10bde4a Signed-off-by: Daniel R. Carvalho <odanrc@yahoo.com.br> Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/45392 Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Bobby R. Bruce <bbruce@ucdavis.edu> Maintainer: Bobby R. Bruce <bbruce@ucdavis.edu>
333 lines
8.1 KiB
C++
333 lines
8.1 KiB
C++
/*
|
|
* Copyright (c) 2020 ARM Limited
|
|
* All rights reserved
|
|
*
|
|
* The license below extends only to copyright in the software and shall
|
|
* not be construed as granting a license to any other intellectual
|
|
* property including but not limited to intellectual property relating
|
|
* to a hardware implementation of the functionality of the software
|
|
* licensed hereunder. You may use the software subject to the license
|
|
* terms below provided that you ensure that this notice is replicated
|
|
* unmodified and in its entirety in all distributions of the software,
|
|
* modified or unmodified, in source code or in binary form.
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#ifndef __DEV_ARM_CSS_SCMI_PLATFORM_H__
|
|
#define __DEV_ARM_CSS_SCMI_PLATFORM_H__
|
|
|
|
#include "dev/arm/css/scmi_protocols.hh"
|
|
#include "dev/arm/css/scp.hh"
|
|
#include "dev/dma_device.hh"
|
|
#include "mem/mem_object.hh"
|
|
#include "params/ScmiPlatform.hh"
|
|
|
|
class Doorbell;
|
|
|
|
GEM5_DEPRECATED_NAMESPACE(SCMI, scmi);
|
|
namespace scmi
|
|
{
|
|
|
|
class Platform;
|
|
|
|
// Maximum number of protocols defined by the SCMI specification
|
|
static const uint8_t PROTOCOL_MAX = 6;
|
|
|
|
enum ProtocolID : uint8_t
|
|
{
|
|
BASE = 0x10,
|
|
START = 0x11,
|
|
POWER_DOMAIN = START,
|
|
SYSTEM_POWER = 0x12,
|
|
PERFORMANCE_DOMAIN = 0x13,
|
|
CLOCK = 0x14,
|
|
SENSOR = 0x15,
|
|
END = SENSOR
|
|
};
|
|
|
|
enum class MessageType
|
|
{
|
|
COMMANDS = 0,
|
|
DELAYED_RESPONSES = 2,
|
|
NOTIFICATIONS = 3
|
|
};
|
|
|
|
BitUnion32(MessageHeader)
|
|
Bitfield<27,18> token;
|
|
Bitfield<17,10> protocolId;
|
|
Bitfield<9,8> messageType;
|
|
Bitfield<7,0> messageId;
|
|
EndBitUnion(MessageHeader)
|
|
|
|
union Payload
|
|
{
|
|
struct
|
|
{
|
|
int32_t status;
|
|
} invalidCommand;
|
|
|
|
struct
|
|
{
|
|
int32_t status;
|
|
uint32_t version;
|
|
} baseProtocolVersion;
|
|
|
|
struct
|
|
{
|
|
int32_t status;
|
|
uint32_t attributes;
|
|
} baseProtocolAttributes;
|
|
|
|
struct
|
|
{
|
|
union
|
|
{
|
|
int32_t status;
|
|
uint32_t messageId;
|
|
};
|
|
uint32_t attributes;
|
|
} baseProtocolMessageAttributes;
|
|
|
|
struct
|
|
{
|
|
int32_t status;
|
|
uint8_t vendorIdentifier[Protocol::MAX_STRING_SIZE + 1];
|
|
} baseDiscoverVendor;
|
|
|
|
struct
|
|
{
|
|
int32_t status;
|
|
uint8_t vendorIdentifier[Protocol::MAX_STRING_SIZE + 1];
|
|
} baseDiscoverSubVendor;
|
|
|
|
struct
|
|
{
|
|
int32_t status;
|
|
uint32_t implementationVersion;
|
|
} baseDiscoverImplementationVersion;
|
|
|
|
struct
|
|
{
|
|
union
|
|
{
|
|
uint32_t skip;
|
|
int32_t status;
|
|
};
|
|
uint32_t numProtocols;
|
|
uint32_t protocols[(PROTOCOL_MAX - 1)/ 4];
|
|
} baseDiscoverListProtocols;
|
|
|
|
struct
|
|
{
|
|
union
|
|
{
|
|
uint32_t agentId;
|
|
int32_t status;
|
|
};
|
|
uint8_t name[Protocol::MAX_STRING_SIZE + 1];
|
|
} baseDiscoverAgent;
|
|
|
|
int32_t status;
|
|
};
|
|
|
|
struct Message
|
|
{
|
|
uint32_t reserved0;
|
|
uint32_t channelStatus;
|
|
uint64_t reserved1;
|
|
uint32_t mailboxFlags;
|
|
uint32_t length;
|
|
uint32_t header;
|
|
Payload payload;
|
|
};
|
|
|
|
/**
|
|
* Generic communication channel between the Agent and the Platform
|
|
*/
|
|
class VirtualChannel : public SimObject
|
|
{
|
|
public:
|
|
VirtualChannel(const ScmiChannelParams &p)
|
|
: SimObject(p),
|
|
msgBuffer(), pendingMessage(false), shmem(p.shmem_range),
|
|
physID(p.phys_id), virtID(p.virt_id),
|
|
doorbell(p.doorbell)
|
|
{}
|
|
|
|
/** Set a pointer to the SCMI platform */
|
|
void
|
|
setPlatform(Platform *_platform)
|
|
{
|
|
platform = _platform;
|
|
}
|
|
|
|
Message msgBuffer;
|
|
bool pendingMessage;
|
|
|
|
const AddrRange shmem;
|
|
|
|
const uint32_t physID;
|
|
const uint32_t virtID;
|
|
|
|
DmaPort *dmaPort;
|
|
Doorbell *doorbell;
|
|
Platform *platform;
|
|
|
|
private:
|
|
static const int dmaSize = 8; // 64 bits
|
|
};
|
|
|
|
/**
|
|
* This is a Agent to Platform channel (The agent is the initiator)
|
|
*/
|
|
class AgentChannel : public VirtualChannel
|
|
{
|
|
public:
|
|
AgentChannel(const ScmiChannelParams &p);
|
|
|
|
void initiateRead();
|
|
|
|
void readStatus();
|
|
void readLength();
|
|
void readMessage();
|
|
void handleMessage();
|
|
|
|
EventFunctionWrapper readLengthEvent;
|
|
EventFunctionWrapper readMessageEvent;
|
|
EventFunctionWrapper handleMessageEvent;
|
|
};
|
|
|
|
/**
|
|
* This is a Platform to Agent channel (The platform is the initiator)
|
|
*/
|
|
class PlatformChannel : public VirtualChannel
|
|
{
|
|
public:
|
|
PlatformChannel(const ScmiChannelParams &p);
|
|
|
|
void writeBackMessage(const Message &msg);
|
|
void notifyAgent();
|
|
void clearDoorbell();
|
|
void complete();
|
|
|
|
EventFunctionWrapper clearDoorbellEvent;
|
|
EventFunctionWrapper notifyAgentEvent;
|
|
EventFunctionWrapper completeEvent;
|
|
|
|
protected:
|
|
uint32_t agentDoorbellVal;
|
|
uint32_t platformDoorbellVal;
|
|
};
|
|
|
|
/**
|
|
* The SCMI Communication class models a bidirectional
|
|
* communication between the SCMI platform and the agent.
|
|
* As such it has a ScmiAgentChannel and a ScmiPlatformChannel
|
|
* object as members.
|
|
*/
|
|
class Communication : public SimObject
|
|
{
|
|
public:
|
|
Communication(const ScmiCommunicationParams &p)
|
|
: SimObject(p), platformChan(p.platform_channel),
|
|
agentChan(p.agent_channel)
|
|
{}
|
|
|
|
PlatformChannel *platformChan;
|
|
AgentChannel *agentChan;
|
|
};
|
|
|
|
class Platform : public Scp
|
|
{
|
|
public:
|
|
using ProtocolList = std::unordered_map<uint8_t, Protocol *>;
|
|
|
|
PARAMS(ScmiPlatform);
|
|
Platform(const Params &p);
|
|
~Platform();
|
|
|
|
void handleMessage(AgentChannel *ch, Message &msg);
|
|
|
|
/** Returns the number of agents in the system */
|
|
uint32_t numAgents() const { return agents.size(); }
|
|
|
|
/** Returns the name of an agent given an index */
|
|
const char*
|
|
getAgent(unsigned index) const
|
|
{
|
|
return agents[index].c_str();
|
|
}
|
|
|
|
/**
|
|
* Returns the number of protocols implemented, except for
|
|
* the base protocol
|
|
*/
|
|
uint32_t numProtocols() const { return protocols.size() - 1; }
|
|
|
|
Port& getPort(const std::string &if_name, PortID idx) override;
|
|
|
|
void raiseInterrupt(const Doorbell *doorbell) override;
|
|
void clearInterrupt(const Doorbell *doorbell) override;
|
|
|
|
static uint32_t
|
|
protocolID(const Message &msg)
|
|
{
|
|
return bits(msg.header, 17, 10);
|
|
}
|
|
|
|
static uint32_t
|
|
messageID(const Message &msg)
|
|
{
|
|
return bits(msg.header, 7, 0);
|
|
}
|
|
|
|
static uint32_t
|
|
messageType(const Message &msg)
|
|
{
|
|
return bits(msg.header, 9, 8);
|
|
}
|
|
|
|
const ProtocolList&
|
|
protocolList() const
|
|
{
|
|
return protocols;
|
|
}
|
|
|
|
AgentChannel* find(PlatformChannel* platform) const;
|
|
PlatformChannel* find(AgentChannel* agent) const;
|
|
|
|
private:
|
|
std::vector<Communication *> comms;
|
|
const std::vector<std::string> agents;
|
|
|
|
ProtocolList protocols;
|
|
|
|
DmaPort dmaPort;
|
|
};
|
|
|
|
} // namespace scmi
|
|
|
|
#endif // __DEV_ARM_CSS_SCMI_PLATFORM_H__
|