mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-11 23:43:15 +00:00
base-hw: fix data alignment error on RISC-V
Native UTCB data has to be at an machine word boundary. fixes #2027
This commit is contained in:
parent
22e908e801
commit
d1eee98012
@ -56,29 +56,29 @@ class Genode::Native_utcb
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note thats the member variables are sorted from the largest to the
|
* Note, the member variables are put into a header structure to ensure
|
||||||
* smallest size to avoid padding. Otherwise, the dimensioning of
|
* the header is padded by the compiler to the next machine-word
|
||||||
* '_data' would not yield a page-sized 'Native_utcb'.
|
* boundary and '_data' is aligned. This also makes the dimensioning of
|
||||||
|
* '_data' easy (page size - size of header).
|
||||||
*/
|
*/
|
||||||
|
struct {
|
||||||
size_t _cap_cnt; /* capability counter */
|
size_t cap_cnt; /* capability counter */
|
||||||
size_t _data_size; /* bytes to transfer */
|
size_t data_size; /* bytes to transfer */
|
||||||
long _exception_code; /* result code of RPC */
|
long exception_code; /* result code of RPC */
|
||||||
Kernel::capid_t _destination; /* invoked object */
|
Kernel::capid_t destination; /* invoked object */
|
||||||
Kernel::capid_t _caps[MAX_CAP_ARGS]; /* capability buffer */
|
Kernel::capid_t caps[MAX_CAP_ARGS]; /* capability buffer */
|
||||||
uint8_t _data[get_page_size() - sizeof(_caps) -
|
} _header; /* is padded to machine word boundary by the compiler */
|
||||||
sizeof(_cap_cnt) - sizeof(_data_size) -
|
uint8_t _data[get_page_size() - sizeof(_header)];
|
||||||
sizeof(_destination) - sizeof(_exception_code)];
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Native_utcb& operator= (const Native_utcb &other)
|
Native_utcb& operator= (const Native_utcb &other)
|
||||||
{
|
{
|
||||||
_cap_cnt = 0;
|
_header.cap_cnt = 0;
|
||||||
_data_size = min(sizeof(_data), other._data_size);
|
_header.data_size = min(sizeof(_data), other._header.data_size);
|
||||||
_exception_code = other._exception_code;
|
_header.exception_code = other._header.exception_code;
|
||||||
_destination = other._destination;
|
_header.destination = other._header.destination;
|
||||||
memcpy(_data, other._data, _data_size);
|
memcpy(_data, other._data, _header.data_size);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -86,26 +86,26 @@ class Genode::Native_utcb
|
|||||||
/**
|
/**
|
||||||
* Set the destination capability id (server object identity)
|
* Set the destination capability id (server object identity)
|
||||||
*/
|
*/
|
||||||
void destination(Kernel::capid_t id) { _destination = id; }
|
void destination(Kernel::capid_t id) { _header.destination = id; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return identity of invoked server object
|
* Return identity of invoked server object
|
||||||
*/
|
*/
|
||||||
Kernel::capid_t destination() const { return _destination; }
|
Kernel::capid_t destination() const { return _header.destination; }
|
||||||
|
|
||||||
void exception_code(long code) { _exception_code = code; }
|
void exception_code(long code) { _header.exception_code = code; }
|
||||||
|
|
||||||
long exception_code() const { return _exception_code; }
|
long exception_code() const { return _header.exception_code; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the count of capabilities in the UTCB
|
* Return the count of capabilities in the UTCB
|
||||||
*/
|
*/
|
||||||
size_t cap_cnt() const { return _cap_cnt; }
|
size_t cap_cnt() const { return _header.cap_cnt; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the count of capabilities in the UTCB
|
* Set the count of capabilities in the UTCB
|
||||||
*/
|
*/
|
||||||
void cap_cnt(size_t cnt) { _cap_cnt = cnt; }
|
void cap_cnt(size_t cnt) { _header.cap_cnt = cnt; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the start address of the payload data
|
* Return the start address of the payload data
|
||||||
@ -121,14 +121,14 @@ class Genode::Native_utcb
|
|||||||
/**
|
/**
|
||||||
* Return size of message data in bytes
|
* Return size of message data in bytes
|
||||||
*/
|
*/
|
||||||
size_t data_size() const { return _data_size; }
|
size_t data_size() const { return _header.data_size; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define size of message data to be transferred, in bytes
|
* Define size of message data to be transferred, in bytes
|
||||||
*/
|
*/
|
||||||
void data_size(size_t data_size)
|
void data_size(size_t data_size)
|
||||||
{
|
{
|
||||||
_data_size = min(data_size, sizeof(_data));
|
_header.data_size = min(data_size, sizeof(_data));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -136,7 +136,7 @@ class Genode::Native_utcb
|
|||||||
*/
|
*/
|
||||||
Kernel::capid_t cap_get(unsigned i) const
|
Kernel::capid_t cap_get(unsigned i) const
|
||||||
{
|
{
|
||||||
return (i < MAX_CAP_ARGS) ? _caps[i] : Kernel::cap_id_invalid();
|
return (i < MAX_CAP_ARGS) ? _header.caps[i] : Kernel::cap_id_invalid();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -145,14 +145,14 @@ class Genode::Native_utcb
|
|||||||
void cap_set(unsigned i, Kernel::capid_t cap)
|
void cap_set(unsigned i, Kernel::capid_t cap)
|
||||||
{
|
{
|
||||||
if (i < MAX_CAP_ARGS)
|
if (i < MAX_CAP_ARGS)
|
||||||
_caps[i] = cap;
|
_header.caps[i] = cap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the capability id 'cap_id' at the next index
|
* Set the capability id 'cap_id' at the next index
|
||||||
*/
|
*/
|
||||||
void cap_add(Kernel::capid_t cap_id) {
|
void cap_add(Kernel::capid_t cap_id) {
|
||||||
if (_cap_cnt < MAX_CAP_ARGS) _caps[_cap_cnt++] = cap_id; }
|
if (_header.cap_cnt < MAX_CAP_ARGS) _header.caps[_header.cap_cnt++] = cap_id; }
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(Genode::Native_utcb) == Genode::get_page_size(),
|
static_assert(sizeof(Genode::Native_utcb) == Genode::get_page_size(),
|
||||||
|
Loading…
Reference in New Issue
Block a user