diff options
Diffstat (limited to 'roms/skiboot/core/test/run-msg.c')
-rw-r--r-- | roms/skiboot/core/test/run-msg.c | 281 |
1 files changed, 281 insertions, 0 deletions
diff --git a/roms/skiboot/core/test/run-msg.c b/roms/skiboot/core/test/run-msg.c new file mode 100644 index 000000000..3659a12d7 --- /dev/null +++ b/roms/skiboot/core/test/run-msg.c @@ -0,0 +1,281 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* + * Copyright 2013-2019 IBM Corp. + */ + +#include <inttypes.h> +#include <stdbool.h> +#include <stddef.h> +#include <assert.h> +#include <errno.h> +#include <stdlib.h> + +static bool zalloc_should_fail = false; +static int zalloc_should_fail_after = 0; + +/* Fake top_of_ram -- needed for API's */ +unsigned long top_of_ram = 0xffffffffffffffffULL; + +static void *zalloc(size_t size) +{ + if (zalloc_should_fail && zalloc_should_fail_after == 0) { + errno = ENOMEM; + return NULL; + } + if (zalloc_should_fail_after > 0) + zalloc_should_fail_after--; + + return calloc(size, 1); +} + +#include "../opal-msg.c" +#include <skiboot.h> + +void lock_caller(struct lock *l, const char *caller) +{ + (void)caller; + assert(!l->lock_val); + l->lock_val = 1; +} + +void unlock(struct lock *l) +{ + assert(l->lock_val); + l->lock_val = 0; +} + +void opal_update_pending_evt(uint64_t evt_mask, uint64_t evt_values) +{ + (void)evt_mask; + (void)evt_values; +} + +static long magic = 8097883813087437089UL; +static void callback(void *data, int status) +{ + assert((status == OPAL_SUCCESS || status == OPAL_PARTIAL)); + assert(*(uint64_t *)data == magic); +} + +static size_t list_count(struct list_head *list) +{ + size_t count = 0; + struct opal_msg_entry *dummy; + + list_for_each(list, dummy, link) + count++; + return count; +} + +int main(void) +{ + struct opal_msg_entry* entry; + int free_size = OPAL_MAX_MSGS; + int nfree = free_size; + int npending = 0; + int r; + static struct opal_msg m; + uint64_t *m_ptr = (uint64_t *)&m; + + zalloc_should_fail = true; + zalloc_should_fail_after = 3; + opal_init_msg(); + + zalloc_should_fail = false; + opal_init_msg(); + + assert(list_count(&msg_pending_list) == npending); + assert(list_count(&msg_free_list) == nfree); + + /* Callback. */ + r = opal_queue_msg(0, &magic, callback, (u64)0, (u64)1, (u64)2); + assert(r == 0); + + assert(list_count(&msg_pending_list) == ++npending); + assert(list_count(&msg_free_list) == --nfree); + + r = opal_get_msg(m_ptr, sizeof(m)); + assert(r == 0); + + assert(m.params[0] == 0); + assert(m.params[1] == 1); + assert(m.params[2] == 2); + + assert(list_count(&msg_pending_list) == --npending); + assert(list_count(&msg_free_list) == ++nfree); + + /* No params. */ + r = opal_queue_msg(0, NULL, NULL); + assert(r == 0); + + assert(list_count(&msg_pending_list) == ++npending); + assert(list_count(&msg_free_list) == --nfree); + + r = opal_get_msg(m_ptr, sizeof(m)); + assert(r == 0); + + assert(list_count(&msg_pending_list) == --npending); + assert(list_count(&msg_free_list) == ++nfree); + + /* > 8 params (ARRAY_SIZE(entry->msg.params) */ + r = opal_queue_msg(0, NULL, NULL, 0, 1, 2, 3, 4, 5, 6, 7, 0xBADDA7A); + assert(r == 0); + + assert(list_count(&msg_pending_list) == ++npending); + assert(list_count(&msg_free_list) == nfree); + + r = opal_get_msg(m_ptr, sizeof(m)); + assert(r == OPAL_PARTIAL); + + assert(list_count(&msg_pending_list) == --npending); + assert(list_count(&msg_free_list) == nfree); + + /* Return OPAL_PARTIAL to callback */ + r = opal_queue_msg(0, &magic, callback, 0, 1, 2, 3, 4, 5, 6, 7, 0xBADDA7A); + assert(r == 0); + + assert(list_count(&msg_pending_list) == ++npending); + assert(list_count(&msg_free_list) == nfree); + + r = opal_get_msg(m_ptr, sizeof(m)); + assert(r == OPAL_PARTIAL); + + assert(list_count(&msg_pending_list) == --npending); + assert(list_count(&msg_free_list) == nfree); + + /* return OPAL_PARAMETER */ + r = _opal_queue_msg(0, NULL, NULL, OPAL_MSG_SIZE, m_ptr); + assert(r == OPAL_PARAMETER); + + assert(m.params[0] == 0); + assert(m.params[1] == 1); + assert(m.params[2] == 2); + assert(m.params[3] == 3); + assert(m.params[4] == 4); + assert(m.params[5] == 5); + assert(m.params[6] == 6); + assert(m.params[7] == 7); + + /* 8 params (ARRAY_SIZE(entry->msg.params) */ + r = opal_queue_msg(0, NULL, NULL, 0, 10, 20, 30, 40, 50, 60, 70); + assert(r == 0); + + assert(list_count(&msg_pending_list) == ++npending); + assert(list_count(&msg_free_list) == --nfree); + + r = opal_get_msg(m_ptr, sizeof(m)); + assert(r == 0); + + assert(list_count(&msg_pending_list) == --npending); + assert(list_count(&msg_free_list) == ++nfree); + + assert(m.params[0] == 0); + assert(m.params[1] == 10); + assert(m.params[2] == 20); + assert(m.params[3] == 30); + assert(m.params[4] == 40); + assert(m.params[5] == 50); + assert(m.params[6] == 60); + assert(m.params[7] == 70); + + /* Full list (no free nodes in pending). */ + while (nfree > 0) { + r = opal_queue_msg(OPAL_MSG_ASYNC_COMP, NULL, NULL); + assert(r == 0); + assert(list_count(&msg_pending_list) == ++npending); + assert(list_count(&msg_free_list) == --nfree); + } + assert(list_count(&msg_free_list) == 0); + assert(nfree == 0); + assert(npending == OPAL_MAX_MSGS); + + r = opal_queue_msg(OPAL_MSG_ASYNC_COMP, NULL, NULL); + assert(r == 0); + + assert(list_count(&msg_pending_list) == OPAL_MAX_MSGS+1); + assert(list_count(&msg_pending_list) == ++npending); + assert(list_count(&msg_free_list) == nfree); + + /* Make zalloc fail to test error handling. */ + zalloc_should_fail = true; + r = opal_queue_msg(OPAL_MSG_ASYNC_COMP, NULL, NULL); + assert(r == OPAL_RESOURCE); + + assert(list_count(&msg_pending_list) == OPAL_MAX_MSGS+1); + assert(list_count(&msg_pending_list) == npending); + assert(list_count(&msg_free_list) == nfree); + + /* Empty list (no nodes). */ + while(!list_empty(&msg_pending_list)) { + r = opal_get_msg(m_ptr, sizeof(m)); + assert(r == 0); + npending--; + nfree++; + } + assert(list_count(&msg_pending_list) == npending); + assert(list_count(&msg_free_list) == nfree); + assert(npending == 0); + assert(nfree == OPAL_MAX_MSGS+1); + + r = opal_queue_msg(OPAL_MSG_ASYNC_COMP, NULL, NULL); + assert(r == 0); + + assert(list_count(&msg_pending_list) == ++npending); + assert(list_count(&msg_free_list) == --nfree); + + /* Request invalid size. */ + r = opal_get_msg(m_ptr, sizeof(m) - 1); + assert(r == OPAL_PARAMETER); + + /* Pass null buffer. */ + r = opal_get_msg(NULL, sizeof(m)); + assert(r == OPAL_PARAMETER); + + /* Get msg when none are pending. */ + r = opal_get_msg(m_ptr, sizeof(m)); + assert(r == 0); + + r = opal_get_msg(m_ptr, sizeof(m)); + assert(r == OPAL_RESOURCE); + +#define test_queue_num(type, val) \ + r = opal_queue_msg(0, NULL, NULL, \ + (type)val, (type)val, (type)val, (type)val, \ + (type)val, (type)val, (type)val, (type)val); \ + assert(r == 0); \ + opal_get_msg(m_ptr, sizeof(m)); \ + assert(r == OPAL_SUCCESS); \ + assert(m.params[0] == (type)val); \ + assert(m.params[1] == (type)val); \ + assert(m.params[2] == (type)val); \ + assert(m.params[3] == (type)val); \ + assert(m.params[4] == (type)val); \ + assert(m.params[5] == (type)val); \ + assert(m.params[6] == (type)val); \ + assert(m.params[7] == (type)val) + + /* Test types of various widths */ + test_queue_num(u64, -1); + test_queue_num(s64, -1); + test_queue_num(u32, -1); + test_queue_num(s32, -1); + test_queue_num(u16, -1); + test_queue_num(s16, -1); + test_queue_num(u8, -1); + test_queue_num(s8, -1); + + /* Clean up the list to keep valgrind happy. */ + while(!list_empty(&msg_free_list)) { + entry = list_pop(&msg_free_list, struct opal_msg_entry, link); + assert(entry); + free(entry); + } + + while(!list_empty(&msg_pending_list)) { + entry = list_pop(&msg_pending_list, struct opal_msg_entry, link); + assert(entry); + free(entry); + } + + return 0; +} |