38#include "debug/QemuFwCfg.hh"
39#include "debug/QemuFwCfgVerbose.hh"
54 const uint64_t total_length =
length();
56 if (
offset > total_length) {
58 std::memset(buf, 0, to_read);
62 if (
offset + to_read > total_length) {
66 uint64_t overflow =
offset + to_read - total_length;
72 std::memset((uint8_t *)buf + to_read, 0, overflow);
76 std::memcpy(buf, (uint8_t *)
data +
offset, to_read);
81 signature(
".[FW_CFG_SIGNATURE]", false,
"QEMU CFG", 0),
84 id(
".[FW_CFG_ID]", false,
"\x1", 1),
85 addrRanges(addr_ranges)
91 for (
auto factory:
p.items) {
93 auto &item = factory->item();
95 uint32_t &next_index =
97 const uint32_t &max_index =
102 item.index(next_index++);
105 "Firmware config device out of %s indexes.",
106 item.archSpecific() ?
"arch" :
"generic");
118 const auto [kit, ksuccess] =
121 panic_if(!ksuccess,
"Duplicate firmware config item key %#x, "
123 item->
index(), item->
path(), kit->second->path());
125 const std::string &
path = item->
path();
126 if (
path.empty() ||
path[0] !=
'.') {
130 panic_if(!res.second,
"Duplicate firmware config item path %s.",
138 DPRINTF(QemuFwCfg,
"Selecting item with key %#x.\n", key);
146 warn(
"Firmware config failed to select item with key %#x.", key);
150 auto item = iter->second;
154 DPRINTF(QemuFwCfg,
"Selected item with path %s.\n", item->path());
156 DPRINTF(QemuFwCfg,
"No item is currently selected.\n");
164 "Tried to read while nothing was selected.\n");
165 std::memset(buf, 0, length);
171 if (gem5::debug::QemuFwCfgVerbose) {
172 std::stringstream data_str;
173 for (
int idx = 0; idx < length; idx++)
174 ccprintf(data_str,
" %02x", ((uint8_t *)buf)[idx]);
176 DPRINTF(QemuFwCfgVerbose,
"Read [%#x-%#x) =>%s.\n",
189 const std::map<std::string, uint16_t> &
names,
190 const std::map<uint16_t, FwCfgItem *> &
numbers)
202 uint64_t bytes =
sizeof(
count) +
sizeof(File) *
count;
208 std::memcpy(ptr, &be_count,
sizeof(be_count));
209 ptr +=
sizeof(be_count);
214 std::memset(file.name, 0,
sizeof(file.name));
215 std::strncpy(file.name,
name.c_str(),
sizeof(file.name) - 1);
218 file.size =
htobe(file.size);
219 file.select =
htobe(file.select);
222 std::memcpy(ptr, &file,
sizeof(file));
230 {
p.selector_addr,
p.selector_addr + 2}}),
231 selectorAddr(
p.selector_addr), dataAddr(
p.selector_addr + 1)
238 const auto size = pkt->
getSize();
242 std::memset(pkt->
getPtr<uint8_t>(), 0, size);
245 warn(
"Read from firmware config selector register not supported.");
250 warn(
"Read from firmware config data register with width %d not "
254 panic(
"Unregognized firmware config read [%#x-%#x).",
265 const auto size = pkt->
getSize();
271 warn(
"Write to firmware config selector register with width %d "
272 "not supported.", size);
274 auto key = pkt->
getLE<uint16_t>();
280 warn(
"Write to firmware config data register not supported.");
282 panic(
"Unrecognized firmware config write [%#x-%#x).",
290 {
p.selector_addr,
p.selector_addr + 2},
291 {
p.data_addr_range}}),
292 selectorAddr(
p.selector_addr),
293 dataAddr(
p.data_addr_range.start()), dataSize(
p.data_addr_range.size())
300 const auto size = pkt->
getSize();
304 std::memset(pkt->
getPtr<uint8_t>(), 0, size);
307 warn(
"Read from firmware config selector register not supported.");
312 warn(
"Read from firmware config data register with width %d not "
316 panic(
"Unregognized firmware config read [%#x-%#x).",
327 const auto size = pkt->
getSize();
333 warn(
"Write to firmware config selector register with width %d "
334 "not supported.", size);
336 auto key = pkt->
getBE<uint16_t>();
342 warn(
"Write to firmware config data register not supported.");
344 panic(
"Unrecognized firmware config write [%#x-%#x).",
virtual std::string name() const
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
T getBE() const
Get the data in the packet byte swapped from big endian to host endian.
void makeResponse()
Take a request packet and modify it in place to be suitable for returning as a response to that reque...
T * getPtr()
get a pointer to the data ptr.
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
This device is the base class which all devices senstive to an address range inherit from.
static std::stack< std::string > path
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
virtual const void * bytes() const =0
void read(void *buf, uint64_t offset, uint32_t to_read) override
virtual void read(void *buf, uint64_t offset, uint32_t to_read)=0
virtual uint64_t length() const =0
const std::string & path() const
FwCfgMmio(const Params &p)
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
void update(const std::map< std::string, uint16_t > &names, const std::map< uint16_t, FwCfgItem * > &numbers)
FwCfg(const Params &p, const AddrRangeList &addr_ranges)
void readItem(void *buf, uint32_t length)
uint32_t nextGenericIndex
std::map< uint16_t, FwCfgItem * > numbers
static const uint32_t MaxGenericIndex
static const uint32_t MaxArchIndex
void select(uint16_t key)
FwCfgItemString signature
std::map< std::string, uint16_t > names
void addItem(FwCfgItem *item)
#define panic(...)
This implements a cprintf based panic() function.
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
uint64_t Tick
Tick count type.
void ccprintf(cp::Print &print)
const std::string & name()