Signed-off-by: Sergey Kambalin <sergey.kamba...@auriga.com> --- tests/qtest/bcm2838-mailbox.c | 70 +++++++++++++++++++++++++++++++++++ tests/qtest/bcm2838-mailbox.h | 48 ++++++++++++++++++++++++ tests/qtest/meson.build | 1 + 3 files changed, 119 insertions(+) create mode 100644 tests/qtest/bcm2838-mailbox.c create mode 100644 tests/qtest/bcm2838-mailbox.h
diff --git a/tests/qtest/bcm2838-mailbox.c b/tests/qtest/bcm2838-mailbox.c new file mode 100644 index 0000000000..211d167ff8 --- /dev/null +++ b/tests/qtest/bcm2838-mailbox.c @@ -0,0 +1,70 @@ +/* + * Helper functions to work with BCM2838 mailbox via qtest interface. + * + * Copyright (c) 2023 Auriga LLC + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "libqtest-single.h" +#include "bcm2838-mailbox.h" + + +static uint32_t qtest_mbox0_read_reg32(QTestState *s, uint32_t offset) +{ + return qtest_readl(s, MBOX0_BASE + offset); +} + +static void qtest_mbox1_write_reg32(QTestState *s, uint32_t offset, uint32_t value) +{ + return qtest_writel(s, MBOX1_BASE + offset, value); +} + +static void qtest_mbox1_write(QTestState *s, uint8_t channel, uint32_t data) +{ + MboxRegWrite reg; + + reg.fields.channel = channel; + reg.fields.data = data; + qtest_mbox1_write_reg32(s, MBOX_REG_WRITE, reg.value); +} + +int qtest_mbox0_has_data(QTestState *s) { + return !(qtest_mbox0_read_reg32(s, MBOX_REG_STATUS) & MBOX_READ_EMPTY); +} + +int mbox0_has_data(void) { + return qtest_mbox0_has_data(global_qtest); +} + +void qtest_mbox0_read_message(QTestState *s, + uint8_t channel, + void *msgbuf, + size_t msgbuf_size) +{ + MboxRegRead reg; + uint32_t msgaddr; + + g_assert(qtest_mbox0_has_data(s)); + reg.value = qtest_mbox0_read_reg32(s, MBOX_REG_READ); + g_assert_cmphex(reg.fields.channel, ==, channel); + msgaddr = reg.fields.data << 4; + qtest_memread(s, msgaddr, msgbuf, msgbuf_size); +} + +void mbox0_read_message(uint8_t channel, void *msgbuf, size_t msgbuf_size) { + qtest_mbox0_read_message(global_qtest, channel, msgbuf, msgbuf_size); +} + +void qtest_mbox1_write_message(QTestState *s, uint8_t channel, uint32_t msg_addr) +{ + qtest_mbox1_write(s, channel, msg_addr >> 4); +} + + +void mbox1_write_message(uint8_t channel, uint32_t msg_addr) +{ + qtest_mbox1_write_message(global_qtest, channel, msg_addr); +} diff --git a/tests/qtest/bcm2838-mailbox.h b/tests/qtest/bcm2838-mailbox.h new file mode 100644 index 0000000000..a81b325af9 --- /dev/null +++ b/tests/qtest/bcm2838-mailbox.h @@ -0,0 +1,48 @@ +/* + * Declarations for BCM2838 mailbox test. + * + * Copyright (c) 2023 Auriga LLC + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +typedef union { + uint32_t value; + struct { + uint32_t channel: 4; + uint32_t data : 28; + } fields; +} MboxRegWrite; + +typedef MboxRegWrite MboxRegRead; + +typedef struct { + uint32_t size; + uint32_t req_resp_code; +} MboxBufHeader; + +#define DECLARE_TAG_TYPE(TypeName, RequestValueType, ResponseValueType) \ +typedef struct { \ + uint32_t id; \ + uint32_t value_buffer_size; \ + union { \ + struct { \ + uint32_t zero; \ + RequestValueType __attribute__((packed)) value; \ + } request; \ + struct { \ + uint32_t size : 31; \ + uint32_t success: 1; \ + ResponseValueType __attribute__((packed)) value; \ + } response; \ + }; \ +} TypeName + + +int mbox0_has_data(void); +void mbox0_read_message(uint8_t channel, void *msgbuf, size_t msgbuf_size); +void mbox1_write_message(uint8_t channel, uint32_t msg_addr); +int qtest_mbox0_has_data(QTestState *s); +void qtest_mbox0_read_message(QTestState *s, uint8_t channel, void *msgbuf, size_t msgbuf_size); +void qtest_mbox1_write_message(QTestState *s, uint8_t channel, uint32_t msg_addr); diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index b071d400b3..61e9aab835 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -318,6 +318,7 @@ qtests = { 'tpm-tis-device-test': [io, tpmemu_files, 'tpm-tis-util.c'], 'vmgenid-test': files('boot-sector.c', 'acpi-utils.c'), 'netdev-socket': files('netdev-socket.c', '../unit/socket-helpers.c'), + 'bcm2838-mbox-property-test' : files('bcm2838-mailbox.c'), } if vnc.found() -- 2.34.1