rvddt/src/devices.cc
2025-02-13 11:12:23 +00:00

168 lines
4.3 KiB
C++

//****************************************************************************
//
// RVDDT (RISC-V Dynamic Debugging Tool)
//
// Copyright (C) 2020 John Winans
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
// USA
//
//****************************************************************************
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include "devices.h"
#include "dev/device.h"
#include "main.h"
devices::devices()
{
setWarnings(1);
}
devices::~devices()
{
for (auto itr = devs.begin(); itr != devs.end(); ++itr)
delete *itr;
}
int8_t devices::get8(uint64_t addr)
{
for (auto itr = devs.begin(); itr != devs.end(); ++itr)
{
device *pdev = *itr;
if (pdev->getBaseAddress() <= addr && pdev->getLastAddress() >= addr)
return pdev->get8(addr);
}
errorGet("8", addr);
return -1; // invalid devices area, act like a hi-z TTL bus
}
int16_t devices::get16(uint64_t addr)
{
for (auto itr = devs.begin(); itr != devs.end(); ++itr)
{
device *pdev = *itr;
if (pdev->getBaseAddress() <= addr && pdev->getLastAddress() >= addr)
return pdev->get16(addr);
}
errorGet("16", addr);
return -1; // invalid devices area, act like a hi-z TTL bus
}
int32_t devices::get32(uint64_t addr)
{
for (auto itr = devs.begin(); itr != devs.end(); ++itr)
{
device *pdev = *itr;
if (pdev->getBaseAddress() <= addr && pdev->getLastAddress() >= addr)
return pdev->get32(addr);
}
errorGet("32", addr);
return -1; // invalid devices area, act like a hi-z TTL bus
}
int64_t devices::get64(uint64_t addr)
{
for (auto itr = devs.begin(); itr != devs.end(); ++itr)
{
device *pdev = *itr;
if (pdev->getBaseAddress() <= addr && pdev->getLastAddress() >= addr)
return pdev->get64(addr);
}
errorGet("64", addr);
return -1; // invalid devices area, act like a hi-z TTL bus
}
void devices::set8(uint64_t addr, uint8_t val)
{
for (auto itr = devs.begin(); itr != devs.end(); ++itr)
{
device *pdev = *itr;
if (pdev->getBaseAddress() <= addr && pdev->getLastAddress() >= addr)
{
pdev->set8(addr, val);
return;
}
}
errorSet("8", addr, val);
}
void devices::set16(uint64_t addr, uint16_t val)
{
for (auto itr = devs.begin(); itr != devs.end(); ++itr)
{
device *pdev = *itr;
if (pdev->getBaseAddress() <= addr && pdev->getLastAddress() >= addr)
{
pdev->set16(addr, val);
return;
}
}
errorSet("16", addr, val);
}
void devices::set32(uint64_t addr, uint32_t val)
{
for (auto itr = devs.begin(); itr != devs.end(); ++itr)
{
device *pdev = *itr;
if (pdev->getBaseAddress() <= addr && pdev->getLastAddress() >= addr)
{
pdev->set32(addr, val);
return;
}
}
errorSet("32", addr, val);
}
void devices::set64(uint64_t addr, uint64_t val)
{
for (auto itr = devs.begin(); itr != devs.end(); ++itr)
{
device *pdev = *itr;
if (pdev->getBaseAddress() <= addr && pdev->getLastAddress() >= addr)
{
pdev->set64(addr, val);
return;
}
}
errorSet("64", addr, val);
}
void devices::errorSet(const char *len, uint64_t addr, uint64_t val)
{
printf("WARNING: %s-bit write to non-existent device at address: 0x%8.8x = 0x%8.8x\n", len, (uint32_t)addr, (uint32_t)val);
}
void devices::errorGet(const char *len, uint64_t addr)
{
printf("WARNING: %s-bit read from non-existent device at address: 0x%8.8x\n", len, (uint32_t)addr);
}
void devices::errorInvalidWrite(const char *len, uint64_t addr, uint64_t val, const char *msg)
{
printf("WARNING: %s-bit write to address 0x%8.8x with illegal value 0x%8.8x\n", len, (uint32_t)addr, (uint32_t)val);
if (msg)
printf("%s\n", msg);
}