68 lines
1.5 KiB
C
68 lines
1.5 KiB
C
#include <assert.h>
|
|
#include <coherent_page.h>
|
|
#include <log.h>
|
|
#include <mbox.h>
|
|
#include <mem.h>
|
|
#include <stdbool.h>
|
|
#include <string.h>
|
|
#include <tag.h>
|
|
|
|
struct __attribute__((packed)) property_buf {
|
|
uint32_t size;
|
|
uint32_t code;
|
|
uint8_t tags[0];
|
|
};
|
|
|
|
struct __attribute__((packed)) property_tag {
|
|
uint32_t id;
|
|
uint32_t value_len;
|
|
uint32_t param_len;
|
|
};
|
|
|
|
bool gilbraltar_get_tags(void *tags, size_t len) {
|
|
struct property_buf *buf =
|
|
(struct property_buf *)get_coherent_page(PROP_MAILBOX);
|
|
uintptr_t dma = (uintptr_t)buf;
|
|
uint32_t *top = (uint32_t *)(buf->tags + len);
|
|
|
|
assert((((uintptr_t)buf) & (16 - 1)) == 0);
|
|
assert(len >= sizeof(struct property_tag) + sizeof(uint32_t));
|
|
uint32_t size = sizeof(struct property_buf) + len + sizeof(uint32_t);
|
|
assert((size & 3) == 0);
|
|
|
|
buf->size = size;
|
|
buf->code = CODE_REQUEST;
|
|
memcpy(buf->tags, tags, len);
|
|
*top = PROPTAG_END;
|
|
data_sync_barrier();
|
|
|
|
if (gilbraltar_mbox_write_read(dma) != dma)
|
|
return false;
|
|
|
|
data_mem_barrier();
|
|
|
|
if (buf->code != CODE_RESPONSE_SUCCESS)
|
|
return false;
|
|
|
|
memcpy(tags, buf->tags, len);
|
|
return true;
|
|
}
|
|
|
|
#define VALUE_LENGTH_RESPONSE (1 << 31)
|
|
|
|
bool gilbraltar_get_tag(uint32_t tag, void *buf, size_t len, size_t param_len) {
|
|
struct property_tag *hdr = buf;
|
|
hdr->id = tag;
|
|
hdr->value_len = len - sizeof(struct property_tag);
|
|
hdr->param_len = param_len & ~VALUE_LENGTH_RESPONSE;
|
|
|
|
if (!gilbraltar_get_tags(buf, len))
|
|
return false;
|
|
|
|
hdr->param_len &= ~VALUE_LENGTH_RESPONSE;
|
|
|
|
if (hdr->param_len == 0)
|
|
return false;
|
|
|
|
return true;
|
|
}
|