281 lines
8.2 KiB
C
281 lines
8.2 KiB
C
// 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;
|
|
}
|