36#ifndef _OPENLCB_VIRTUALMEMORYSPACE_HXX
37#define _OPENLCB_VIRTUALMEMORYSPACE_HXX
85 size_t write(address_t destination,
const uint8_t *data,
size_t len,
86 errorcode_t *error,
Notifiable *again)
override
90 *error = MemoryConfigDefs::ERROR_OUT_OF_BOUNDS;
113 address_t field_start = destination + skip;
133 std::min((
size_t)len, (
size_t)(element->
size_ + skip));
134 memcpy(&payload[-skip], (
const char *)data, written_len);
139 payload.assign((
const char *)data,
140 std::min((
size_t)len, (
size_t)element->
size_));
141 written_len = payload.size();
165 size_t read(address_t source, uint8_t *dst,
size_t len, errorcode_t *error,
170 *error = MemoryConfigDefs::ERROR_OUT_OF_BOUNDS;
183 memset(dst, 0, skip);
198 payload.resize(element->
size_);
199 size_t data_len = std::min(payload.size() + skip, len);
200 memcpy(dst, payload.data() - skip, data_len);
225 template <
typename T>
231 template <
typename T>
249 maxAddress_, (address_t)(group.offset() + group.size() - 1));
267 template <
unsigned SIZE>
280 template <
typename T>
285 auto trf = [read_f](
unsigned repeat,
string *contents,
287 T result = read_f(repeat, done);
289 contents->resize(
sizeof(T));
290 *((T *)&((*contents)[0])) =
293 auto twf = [write_f](
unsigned repeat,
string contents,
295 contents.resize(
sizeof(T));
297 *(
const T *)contents.data());
298 write_f(repeat, result, done);
301 entry.offset(), entry.
size(), std::move(trf), std::move(twf));
312 template <
class Group,
unsigned N>
316 re.
start_ = group.offset();
317 re.
end_ = group.end_offset();
422 bool in_repeat =
false;
423 address_t original_address = address;
427 auto rit =
repeats_.upper_bound(address);
435 if (rit->start_ <= address && address < rit->end_)
438 unsigned cnt = (address - rit->start_) / rit->repeatSize_;
440 if (address + rit->repeatSize_ < rit->end_)
446 address -= cnt * rit->repeatSize_;
453 "searching for element at address %u in_repeat=%d address=%u "
455 (
unsigned)original_address, in_repeat, (
unsigned)address,
458 for (
int is_repeat = 0; is_repeat <= max_repeat; ++is_repeat)
465 if (pit->address_ + pit->size_ > address)
475 if ((it !=
elements_.
end()) && (address + len > it->address_))
486 address -= rit->repeatSize_;
488 if (original_address + rit->repeatSize_ >= rit->end_)
504 LOG(
VERBOSE,
"element not found for address %u",
505 (
unsigned)original_address);
509 static constexpr unsigned NO_CACHE =
static_cast<address_t
>(-1);
A BarrierNotifiable allows to create a number of child Notifiable and wait for all of them to finish.
void notify() override
Implementation of the barrier semantics.
BarrierNotifiable * reset(Notifiable *done)
Resets the barrier. Returns &*this. Asserts that is_done().
BarrierNotifiable * new_child()
Call this for each child task.
bool abort_if_almost_done()
Checks if there is exactly one outstanding notification left in the barrier.
An object that can schedule itself on an executor to run.
An mostly std::set<> compatible class that stores the internal data in a sorted vector.
iterator lower_bound(key_type key)
void insert(data_type &&d)
Adds new entry to the vector.
container_type::iterator iterator
Iterator type.
Abstract base class for the address spaces exported via the Memory Config Protocol.
static const errorcode_t ERROR_AGAIN
This error code signals that the operation was only partially completed, the again notify was used an...
Implementation class for numeric configuration entries, templated by the integer type.
static uint8_t endian_convert(uint8_t d)
Performs endian conversion.
static constexpr unsigned size()
Storage bytes occupied by the instance in the config file.
Defines a repeated group of a given type and a given number of repeats.
Implementation class for string configuration entries.
Implementation of a memory space where the values are not stored in a contiguous storage area but are...
unsigned isReadOnly_
Whether the space should report as RO.
ssize_t find_data_element(address_t address, address_t len, const DataElement **ptr, unsigned *repeat)
Look up the first matching data element given an address in the virtual memory space.
BarrierNotifiable bn_
Helper object in the function calls.
void register_string(const StringConfigEntry< SIZE > &entry, ReadFunction read_f, WriteFunction write_f)
Registers a string typed element.
void expand_bounds_from_group(const G &group)
Expand the address bounds from a single CDI group declaration.
void register_numeric(const NumericConfigEntry< T > &entry, TypedReadFunction< T > read_f, TypedWriteFunction< T > write_f)
Registers a numeric typed element.
bool read_only() override
std::function< void(unsigned repeat, string contents, BarrierNotifiable *done)> WriteFunction
Function that will be called for writes.
void register_repeat(const RepeatedGroup< Group, N > &group)
Registers a repeated group.
void register_element(address_t address, address_t size, ReadFunction read_f, WriteFunction write_f)
Register an untyped element.
SortedListSet< DataElement, DataComparator > ElementsType
Container type for storing the data elements.
string cachedData_
Stored information for read-modify-write calls.
address_t maxAddress_
Bounds for valid addresses.
size_t write(address_t destination, const uint8_t *data, size_t len, errorcode_t *error, Notifiable *again) override
address_t minAddress_
Bounds for valid addresses.
std::function< void(unsigned repeat, string *contents, BarrierNotifiable *done)> ReadFunction
Function that will be called for reads.
size_t read(address_t source, uint8_t *dst, size_t len, errorcode_t *error, Notifiable *again) override
typename std::function< void(unsigned repeat, T contents, BarrierNotifiable *done)> TypedWriteFunction
Typed WriteFunction for primitive types.
ElementsType elements_
Stores all the registered variables.
address_t min_address() override
void set_bounds_from_group(const G &group)
Setup the address bounds from a single CDI group declaration.
SortedListSet< RepeatElement, RepeatComparator > repeats_
Stores all the registered variables.
typename std::function< T(unsigned repeat, BarrierNotifiable *done)> TypedReadFunction
Typed ReadFunction for primitive types.
address_t cacheOffset_
Offset in the memory space at which cachedData_ starts.
address_t max_address() override
#define LOG(level, message...)
Conditionally write a message to the logging output.
static const int VERBOSE
Loglevel that is usually not printed, reporting debugging information.
#define HASSERT(x)
Checks that the value of expression x is true, else terminates the current process.
STL-compatible comparator function for sorting DataElements.
bool operator()(const DataElement &a, const DataElement &b) const
Sorting operator by address.
bool operator()(const DataElement &a, unsigned b) const
Sorting operator by address.
bool operator()(unsigned a, const DataElement &b) const
Sorting operator by address.
We keep one of these for each variable that was declared.
address_t address_
Base offset of this variable (first repeat only).
address_t size_
Size of this variable.
ReadFunction readImpl_
Function that will be called for reads.
WriteFunction writeImpl_
Function that will be called for writes.
STL-compatible comparator function for sorting RepeatElements.
bool operator()(uint32_t a, const RepeatElement &b) const
Sorting operator by end address against a lookup key.
bool operator()(const RepeatElement &a, const RepeatElement &b) const
Sorting operator by end address.
Represents a repeated group.
uint32_t end_
Address byte after the last repeat.
uint32_t repeatSize_
Address bytes per repeat.
uint32_t start_
Offset of the repeated group (first repeat).