#include #include #include #include #include #include #include #include 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; }