blob: 8e9bf20ed59389dd4b87ac23f8916376e3d1feee [file]
//
// Copyright (c) 2010-2024 Antmicro
//
// This file is licensed under the MIT License.
// Full license text is available in 'licenses/MIT.txt'.
//
#include "renode_cfu.h"
static RenodeAgent* renodeAgent;
#define IO_THREADS 1
//=================================================
// RenodeAgent
//=================================================
RenodeAgent::RenodeAgent(Cfu *_cfu) {
cfu = _cfu;
cfu->tickCounter = 0;
}
void RenodeAgent::tick(bool countEnable, uint64_t steps)
{
cfu->tick(countEnable, steps);
}
void RenodeAgent::reset()
{
cfu->reset();
}
uint64_t RenodeAgent::execute(uint32_t functionID, uint32_t data0, uint32_t data1, int* error)
{
uint64_t result = 0;
try {
result = cfu->execute(functionID, data0, data1, error);
*error = CFU_OK;
}
catch(const char* msg) {
if (msg == "Operation timeout") {
*error = CFU_TIMEOUT;
} else {
*error = CFU_FAIL;
}
}
return result;
}
void RenodeAgent::handleCustomRequestType(Protocol* message)
{
log(LOG_LEVEL_WARNING, "Unhandled request type: %d", message->actionId);
}
void RenodeAgent::log(int level, const char* fmt, ...)
{
char s[1024];
va_list ap;
va_start(ap, fmt);
vsnprintf(s, 1024, fmt, ap);
communicationChannel->log(level, s);
va_end(ap);
}
//=================================================
// NativeCommunicationChannel
//=================================================
extern void handleSenderMessage(void* ptr);
EXTERNAL_AS(action_intptr, HandleSenderMessage, handleSenderMessage);
void NativeCommunicationChannel::sendSender(const Protocol message)
{
handleSenderMessage(new Protocol(message));
}
void NativeCommunicationChannel::log(int logLevel, const char* data)
{
handleSenderMessage(new Protocol(logMessage, strlen(data) + 1, (uint64_t)data));
handleSenderMessage(new Protocol(logMessage, 0, logLevel));
}
//=================================================
// Functions exported to Renode
//=================================================
uint64_t execute(uint32_t functionID, uint32_t data0, uint32_t data1, int* error)
{
return renodeAgent->execute(functionID, data0, data1, error);
}
void initialize_native()
{
renodeAgent = Init();
renodeAgent->communicationChannel = new NativeCommunicationChannel();
}
void handle_request(Protocol* request)
{
long ticks;
switch(request->actionId) {
case invalidAction:
break;
case tickClock:
ticks = request->value - renodeAgent->cfu->tickCounter;
if(ticks > 0) {
renodeAgent->tick(false, ticks);
}
renodeAgent->cfu->tickCounter = 0;
renodeAgent->communicationChannel->sendSender(Protocol(tickClock, 0, 0));
break;
case resetPeripheral:
renodeAgent->reset();
break;
default:
renodeAgent->handleCustomRequestType(request);
break;
}
}
void reset_peripheral()
{
renodeAgent->reset();
}