FRAGS_INIT — frags_t initializer
#include <simics/device-api.h> // in C
// not available in DML
FRAGS_INIT;
An frags_t initializer that can be used in variable declarations.
frags_add — add data to a frags_t
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE void
frags_add(frags_t *buf, const void *data, size_t len);
Append the new data data of size len to buf. A frags_t can hold up to 8 data fragments.
None
Cell Context
uint8 new_data[2] = { 7, 8 };
frags_add(&foo, new_data, sizeof(new_data));
frags_init_add, frags_init_add_from_frags, frags_add_from_frags
frags_add_from_frags — append an existing frags_t to another
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE void
frags_add_from_frags(frags_t *dst, const frags_t *src,
size_t offset, size_t len);
Append len bytes of the data at offset offset in src to dst.
None
Cell Context
frags_add_from_frags(&foo, &bar, 4, frags_len(&bar) - 4);
frags_extract — extract the contents of a frags_t
#include <simics/device-api.h> // in C
// always available in DML
void frags_extract(const frags_t *buf, void *vdst);
Copy the whole contents of buf to vdst. The destination buffer vdst should be large enough to contain all data in buf.
This function is completely equivalent to frags_extract_slice() with an offset and a length covering the whole contents of the frags_t, and is provided for convenience.
None
Cell Context
uint8 all_data[frags_len(&foo)];
frags_extract(&foo, all_data);
frags_extract_8, frags_extract_slice, frags_extract_alloc, frags_extract_slice_alloc
frags_extract_8, frags_extract_be16, frags_extract_le16, frags_extract_be32, frags_extract_le32, frags_extract_be64, frags_extract_le64 — extract a value
#include <simics/device-api.h> // in C
// always available in DML
uint8 frags_extract_8(const frags_t *buf, size_t offset);
uint16 frags_extract_be16(const frags_t *buf, size_t offset);
uint16 frags_extract_le16(const frags_t *buf, size_t offset);
uint32 frags_extract_be32(const frags_t *buf, size_t offset);
uint32 frags_extract_le32(const frags_t *buf, size_t offset);
uint64 frags_extract_be64(const frags_t *buf, size_t offset);
uint64 frags_extract_le64(const frags_t *buf, size_t offset);
Extract a 8, 16, 32 or 64 bits value in either big-endian (_be) or little-endian (_le) format from the contents of the frags_t buf at offset offset.
Extracted value
Cell Context
uint8 val8 = frags_extract_8(&frame, 1);
uint16 val16 = frags_extract_be16(&frame, 2);
uint32 val32 = frags_extract_le32(&frame, 4);
uint32 val64 = frags_extract_be64(&frame, 8);
frags_extract_alloc — return a copy of the contents of a frags_t
#include <simics/device-api.h> // in C
// always available in DML
void *frags_extract_alloc(const frags_t *buf);
Return an allocated copy of the contents of buf. The buffer returned is allocated with MM_MALLOC(), and its ownership is passed to the caller, which should free it when appropriate.
This function is equivalent to allocating a buffer of the correct size with MM_MALLOC() followed by a call to frags_extract(), and is provided for convenience.
A newly allocated copy of the contents
Cell Context
uint8 *all = frags_extract_alloc(&foo);
/* ... */
MM_FREE(all);
frags_extract, frags_extract_slice, frags_extract_slice_alloc
frags_extract_slice — extract a slice of a frags_t
#include <simics/device-api.h> // in C
// always available in DML
void frags_extract_slice(const frags_t *buf, void *vdst, size_t offset,
size_t len);
Copy a slice of size len, starting at offset offset, of the contents of buf, to vdst. The destination buffer vdst should be able to contain at least len bytes.
None
Cell Context
uint8 some_data[16];
frags_extract_slice(&foo, some_data, 4, 16);
frags_extract_8, frags_extract, frags_extract_alloc, frags_extract_slice_alloc
frags_extract_slice_alloc — return a partial copy of the contents of a frags_t
#include <simics/device-api.h> // in C
// always available in DML
void *frags_extract_slice_alloc(const frags_t *buf, size_t offset, size_t len);
Return an allocated copy of a slice of size len, starting at offset offset, of the contents of buf. The return value is allocated with MM_MALLOC(), and its ownership is passed to the caller, which should free it when appropriate.
This function is equivalent to allocating a buffer of the correct size with MM_MALLOC() followed by a call to frags_extract_slice(), and is provided for convenience.
A newly allocated, partial copy of the data
Cell Context
uint8 *slice = frags_extract_slice_alloc(&foo, 4, 16);
/* ... */
MM_FREE(slice);
frags_init — initialize a frags_t
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE void frags_init(frags_t *buf);
Initialize the frags_t buf. An alternative is to use the FRAGS_INIT constant value.
None
Cell Context
/* Initialization with frags_init() */
frags_t bar;
frags_init(&bar);
/* Initialization with FRAGS_INIT */
frags_t foo = FRAGS_INIT;
frags_init_add — initialize a frags_t with an initial value
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE void
frags_init_add(frags_t *buf, const void *data, size_t len);
Initialize the frags_t buf and set it to represent the initial data data of size len.
This function is exactly equivalent to using frags_init(), followed by frags_add(), and is provided for convenience.
None
Cell Context
frags_t baz;
uint8 data[5] = { 0, 1, 2, 3, 4 };
frags_init_add(&baz, data, sizeof(data));
frags_init_add_from_frags — initialize a frags_t from another
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE void
frags_init_add_from_frags(frags_t *dst, const frags_t *src,
size_t offset, size_t len);
Initialize dst and set its initial value to the data of size len starting at offset offset in src.
This function is exactly equivalent to using frags_init(), followed by frags_add_from_frags(), and is provided for convenience.
None
Cell Context
frags_t bat;
ASSERT(frags_len(&foo) > 16);
frags_init_add_from_frags(&bat, &foo, 16, frags_len(&foo) - 16);
frags_it — return an iterator
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE frags_it_t
frags_it(const frags_t *buf, size_t offset, size_t len);
Return an iterator on the fragments that compose the data in buf, starting from offset offset and up to a length of len. To iterate on all the data in buf, offset should be set to 0 and len to the value returned by frags_len().
An iterator on the fragments covering the desired data range
Cell Context
unsigned sum = 0;
for (frags_it_t it = frags_it(&foo, 0, frags_len(&foo));
!frags_it_end(it);
it = frags_it_next(it)) {
unsigned f_len = frags_it_len(it);
const uint8 *f_data = frags_it_data(it);
for (int i=0; i<f_len; i++)
sum += f_data[i];
}
frags_it_data — return the data of the current fragment
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE const uint8 *
frags_it_data(frags_it_t it);
Return a pointer to the data of the current fragment pointed by the iterator it.
The data of the current fragment
Cell Context
unsigned sum = 0;
for (frags_it_t it = frags_it(&foo, 0, frags_len(&foo));
!frags_it_end(it);
it = frags_it_next(it)) {
unsigned f_len = frags_it_len(it);
const uint8 *f_data = frags_it_data(it);
for (int i=0; i<f_len; i++)
sum += f_data[i];
}
frags_it_end — return whether an iterator is finished
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE bool
frags_it_end(frags_it_t it);
Return true when the iterator it does not have any next fragment to return at the next call of frags_it_next(), and false otherwise.
true if the iterator is finished, false otherwise.
Cell Context
unsigned sum = 0;
for (frags_it_t it = frags_it(&foo, 0, frags_len(&foo));
!frags_it_end(it);
it = frags_it_next(it)) {
unsigned f_len = frags_it_len(it);
const uint8 *f_data = frags_it_data(it);
for (int i=0; i<f_len; i++)
sum += f_data[i];
}
frags_it_len — return the length of the current fragment
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE size_t
frags_it_len(frags_it_t it);
Return the length of the current fragment pointed by the iterator it.
The length of the current fragment
Cell Context
unsigned sum = 0;
for (frags_it_t it = frags_it(&foo, 0, frags_len(&foo));
!frags_it_end(it);
it = frags_it_next(it)) {
unsigned f_len = frags_it_len(it);
const uint8 *f_data = frags_it_data(it);
for (int i=0; i<f_len; i++)
sum += f_data[i];
}
frags_it_next — return the next fragment’s iterator
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE frags_it_t
frags_it_next(frags_it_t it);
Return an iterator pointing at the next data fragment. This function should only be called if frags_end(it) returns false.
An iterator on the next fragment
Cell Context
unsigned sum = 0;
for (frags_it_t it = frags_it(&foo, 0, frags_len(&foo));
!frags_it_end(it);
it = frags_it_next(it)) {
unsigned f_len = frags_it_len(it);
const uint8 *f_data = frags_it_data(it);
for (int i=0; i<f_len; i++)
sum += f_data[i];
}
frags_len — return the total data length
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE size_t frags_len(const frags_t *buf);
Return the total length of the data represented by buf.
The total data length
Cell Context
unsigned len = frags_len(&foo);
frags_prefix — prefix a frags_t with a header
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE frags_t
frags_prefix(const void *header, size_t header_len, const frags_t *body);
Create a frags_t composed of the header header of size header_len, followed by the contents of the frags_t body.
This function is equivalent to a sequence of frags_init(), frags_add(), frags_add_from_frags() to build a new fragment containing the prefix. It is provided for convenience.
A new frags_t including header and body
Cell Context
uint8 eth_header[14] = { 0 };
frags_t packet = frags_prefix(eth_header, sizeof(eth_header), &foo);
frags_suffix — append a suffix to a frags_t
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE frags_t
frags_suffix(const frags_t *body, void *header, size_t header_len);
Create a frags_t composed of the contents of the frags_t body, followed by the data header of size header_len.
This function is equivalent to a sequence of frags_init(), frags_add_from_frags(), frags_add() to build a new fragment containing the suffix. It is provided for convenience.
A new frags_t including body and header
Cell Context
uint8 eth_checksum[4] = { 0 };
frags_t frame = frags_suffix(&foo, eth_checksum, sizeof(eth_checksum));
frags_t, frags_it_t — encapsulate a data packet
#include <simics/device-api.h> // in C
// always available in DML
typedef struct frags frags_t;
typedef struct frags_it frags_it_t;
These types encapsulate a data packet, for use by models that send and receive data, such as network devices.
The structures should never be used directly. Only use the accessor functions.