Commit 3446cf5f authored by Charlie Jacobsen's avatar Charlie Jacobsen
Browse files

lcd: Ported rpc tests from old2 code, no build attempt yet.

parent 96e5083a
......@@ -212,6 +212,7 @@ int fipc_recv_msg_if(struct fipc_ring_channel *chnl,
/* Caller wants the message */
*msg = m;
inc_rx_slot(chnl);
ret = 0;
} else {
ret = -ENOMSG;
}
......
......@@ -290,4 +290,43 @@ int fipc_recv_msg_if(struct fipc_ring_channel *chnl,
int fipc_recv_msg_end(struct fipc_ring_channel *chnl,
struct fipc_message *msg);
/* MESSAGE ACCESSORS ---------------------------------------- */
/* While use of these is not required, it makes your code independent
* of the layout of struct fipc_message, and does compile time bounds
* checking. */
#define FIPC_MK_REG_ACCESS(idx) \
static inline \
unsigned long fipc_get_reg##idx(struct fipc_message *msg) \
{ \
BUILD_BUG_ON(idx >= FIPC_NR_REGS); \
return msg->regs[idx]; \
} \
static inline \
void fipc_set_reg##idx(struct fipc_message *msg, unsigned long val) \
{ \
msg->regs[idx] = val; \
}
FIPC_MK_REG_ACCESS(0)
FIPC_MK_REG_ACCESS(1)
FIPC_MK_REG_ACCESS(2)
FIPC_MK_REG_ACCESS(3)
FIPC_MK_REG_ACCESS(4)
FIPC_MK_REG_ACCESS(5)
FIPC_MK_REG_ACCESS(6)
static inline
uint32_t fipc_get_flags(struct fipc_message *msg)
{
return msg->flags;
}
static inline
void fipc_set_flags(struct fipc_message *msg, uint32_t flags)
{
msg->flags = flags;
}
#endif /* LIBFIPC_H */
LIBFIPC=$(abs_top_buildir)/src/platform/kernel/libfipc.a
export LIBFIPC
# No op for now
# D=install dir
......
# @FIPC_AUTOCONF_NOTICE@
# Magic line so we can do out-of-source build
src = @abs_top_srcdir@/src/platform/kernel/tests/rpc
obj-m = libfipc_test_rpc.o
libfipc_test_rpc-objs = main.o callee.o caller.o
libfipc_test_rpc-objs = $(LIBFIPC)
# Add -DCHECK_MESSAGES to check that message values contain what is expected
ccflags-y += $(CFLAGS) $(AM_CPPFLAGS) -DCHECK_MESSAGES
/*
* callee.c
*
* Code for the "callee side" of the channel
*
* Copyright: University of Utah
*/
#include <linux/kernel.h>
#include <libfipc.h>
#include "rpc.h"
/*
* We use "noinline" because we want the function call to actually
* happen.
*/
static unsigned long noinline
null_invocation(void)
{
return 9;
}
static unsigned long noinline
add_constant(unsigned long trans)
{
return trans + 50;
}
static unsigned long noinline
add_nums(unsigned long trans, unsigned long res1)
{
return trans+res1;
}
static unsigned long noinline
add_3_nums(unsigned long trans, unsigned long res1, unsigned long res2)
{
return add_nums(trans, res1) + res2;
}
static unsigned long noinline
add_4_nums(unsigned long trans, unsigned long res1, unsigned long res2,
unsigned long res3)
{
return add_nums(trans, res1) + add_nums(res2, res3);
}
static unsigned long noinline
add_5_nums(unsigned long trans, unsigned long res1, unsigned long res2,
unsigned long res3, unsigned long res4)
{
return add_4_nums(trans,res1,res2,res3) + res4;
}
static unsigned long noinline
add_6_nums(unsigned long trans, unsigned long res1, unsigned long res2,
unsigned long res3, unsigned long res4, unsigned long res5)
{
return add_3_nums(trans,res1,res2) + add_3_nums(res3,res4,res5);
}
static inline int send_response(struct fipc_ring_channel *chnl,
struct fipc_message *recvd_msg,
unsigned long val, enum fn_type type)
{
int ret;
struct fipc_message *response;
/*
* Mark recvd msg slot as available
*/
ret = fipc_recv_msg_end(chnl, recvd_msg);
if (ret) {
pr_err("Error marking msg as recvd");
return ret;
}
/*
* Response
*/
ret = blocking_send_start(chnl, &response);
if (ret) {
pr_err("Error getting send slot");
return ret;
}
set_fn_type(response, type);
response->regs[0] = val;
ret = fipc_send_msg_end(chnl, response);
if (ret) {
pr_err("Error marking message as sent");
return ret;
}
return 0;
}
int callee(void *_callee_channel_header)
{
int ret = 0;
unsigned long temp_res;
struct fipc_ring_channel *chan = _callee_channel_header;
struct fipc_message *recvd_msg;
unsigned long transaction_id = 0;
enum fn_type type;
for (transaction_id = 0;
transaction_id < TRANSACTIONS;
transaction_id++) {
/*
* Try to receive a message
*/
ret = blocking_recv_start(chan, &recvd_msg);
if (ret) {
pr_err("Error receiving message, ret = %d", ret);
goto out;
}
/*
* Dispatch on message type
*/
type = get_fn_type(recvd_msg);
switch(type) {
case NULL_INVOCATION:
temp_res = null_invocation();
break;
case ADD_CONSTANT:
temp_res = add_constant(fipc_get_reg0(recvd_msg));
break;
case ADD_NUMS:
temp_res = add_nums(fipc_get_reg0(recvd_msg),
fipc_get_reg1(recvd_msg));
break;
case ADD_3_NUMS:
temp_res = add_3_nums(fipc_get_reg0(recvd_msg),
fipc_get_reg1(recvd_msg),
fipc_get_reg2(recvd_msg));
break;
case ADD_4_NUMS:
temp_res = add_4_nums(fipc_get_reg0(recvd_msg),
fipc_get_reg1(recvd_msg),
fipc_get_reg2(recvd_msg),
fipc_get_reg3(recvd_msg));
break;
case ADD_5_NUMS:
temp_res = add_5_nums(fipc_get_reg0(recvd_msg),
fipc_get_reg1(recvd_msg),
fipc_get_reg2(recvd_msg),
fipc_get_reg3(recvd_msg),
fipc_get_reg4(recvd_msg));
break;
case ADD_6_NUMS:
temp_res = add_6_nums(fipc_get_reg0(recvd_msg),
fipc_get_reg1(recvd_msg),
fipc_get_reg2(recvd_msg),
fipc_get_reg3(recvd_msg),
fipc_get_reg4(recvd_msg),
fipc_get_reg5(recvd_msg));
break;
}
/*
* Send response back
*/
ret = send_response(chan, recvd_msg, temp_res, type);
if (ret) {
pr_err("Error sending response back, ret = %d", ret);
goto out;
}
}
out:
return ret;
}
/*
* caller.c
*
* The "caller side" of the channel
*
* Copyright: University of Utah
*/
#include <linux/random.h>
#include "rpc.h"
static inline int send_and_get_response(
struct fipc_ring_channel *chan,
struct fipc_message *request,
struct fipc_message **response)
{
int ret;
struct fipc_message *resp;
/*
* Mark the request as sent
*/
ret = fipc_send_msg_end(chan, request);
if (ret) {
pr_err("failed to mark request as sent, ret = %d\n", ret);
goto fail1;
}
/*
* Try to get the response
*/
ret = blocking_recv_start(chan, &resp);
if (ret) {
pr_err("failed to get a response, ret = %d\n", ret);
goto fail2;
}
*response = resp;
return 0;
fail2:
fail1:
return ret;
}
#ifdef CHECK_MESSAGES
static inline int finish_response_check_fn_type(struct fipc_ring_channel *chnl,
struct fipc_message *response,
enum fn_type expected_type)
{
enum fn_type actual_type = get_fn_type(response);
ret = fipc_recv_msg_end(chnl, response);
if (ret) {
pr_err("Error finishing receipt of response, ret = %d\n", ret);
return ret;
} else if (actual_type != expected_type) {
pr_err("Unexpected fn type: actual = %d, expected = %d\n",
actual_type, expected_type);
return -EINVAL;
} else {
return 0;
}
}
static inline int finish_response_check_fn_type_and_reg0(
struct fipc_ring_channel *chnl,
struct fipc_message *response,
enum fn_type expected_type,
unsigned long expected_reg0)
{
enum fn_type actual_type = get_fn_type(response);
unsigned long actual_reg0 = fipc_get_reg0(response);
ret = fipc_recv_msg_end(chnl, response);
if (ret) {
pr_err("Error finishing receipt of response, ret = %d\n", ret);
return ret;
} else if (actual_type != expected_type) {
pr_err("Unexpected fn type: actual = %d, expected = %d\n",
actual_type, expected_type);
return -EINVAL;
} else if (actual_reg0 != expected_reg0) {
pr_err("Unexpected return value (reg0): actual = 0x%lx, expected = 0x%lx\n",
actual_reg0, expected_reg0);
return -EINVAL;
} else {
return 0;
}
}
#else /* !CHECK_MESSAGES */
static inline int finish_response_check_fn_type(struct fipc_ring_channel *chnl,
struct fipc_message *response,
enum fn_type expected_type)
{
return fipc_recv_msg_end(chnl, response);
}
static inline int finish_response_check_fn_type_and_reg0(
struct fipc_ring_channel *chnl,
struct fipc_message *response,
enum fn_type expected_type,
unsigned long expected_reg0)
{
return fipc_recv_msg_end(chnl, response);
}
#endif /* CHECK_MESSAGES */
static int noinline __used
null_invocation(struct fipc_ring_channel *chan)
{
struct fipc_message *request;
struct fipc_message *response;
int ret;
/*
* Set up request
*/
ret = blocking_send_start(chan, &request);
if (ret) {
pr_err("Error getting send message, ret = %d\n", ret);
goto fail;
}
set_fn_type(request, NULL_INVOCATION);
/*
* Send request, and get response
*/
ret = send_and_get_response(chan, request, &response);
if (ret) {
pr_err("Error getting response, ret = %d\n", ret);
goto fail;
}
/*
* Maybe check message
*/
return finish_response_check_fn_type(response, NULL_INVOCATION);
fail:
return ret;
}
static int noinline __used
add_constant(struct fipc_ring_channel *chan, unsigned long trans)
{
struct fipc_message *request;
struct fipc_message *response;
int ret;
/*
* Set up request
*/
ret = blocking_send_start(chan, &request);
if (ret) {
pr_err("Error getting send message, ret = %d\n", ret);
goto fail;
}
set_fn_type(request, ADD_CONSTANT);
fipc_set_reg0(request, trans);
/*
* Send request, and get response
*/
ret = send_and_get_response(chan, request, &response);
if (ret) {
pr_err("Error getting response, ret = %d\n", ret);
goto fail;
}
/*
* Maybe check message
*/
return finish_response_check_fn_type_and_reg0(
response,
ADD_CONSTANT,
trans + 50);
fail:
return ret;
}
static int noinline __used
add_nums(struct fipc_ring_channel *chan, unsigned long trans,
unsigned long res1)
{
struct fipc_message *request;
struct fipc_message *response;
int ret;
/*
* Set up request
*/
ret = blocking_send_start(chan, &request);
if (ret) {
pr_err("Error getting send message, ret = %d\n", ret);
goto fail;
}
set_fn_type(request, ADD_NUMS);
fipc_set_reg0(request, trans);
fipc_set_reg1(request, res1);
/*
* Send request, and get response
*/
ret = send_and_get_response(chan, request, &response);
if (ret) {
pr_err("Error getting response, ret = %d\n", ret);
goto fail;
}
/*
* Maybe check message
*/
return finish_response_check_fn_type_and_reg0(
response,
ADD_NUMS,
trans + res1);
fail:
return ret;
}
static int noinline __used
add_3_nums(struct fipc_ring_channel *chan, unsigned long trans,
unsigned long res1, unsigned long res2)
{
struct fipc_message *request;
struct fipc_message *response;
int ret;
/*
* Set up request
*/
ret = blocking_send_start(chan, &request);
if (ret) {
pr_err("Error getting send message, ret = %d\n", ret);
goto fail;
}
set_fn_type(request, ADD_3_NUMS);
fipc_set_reg0(request, trans);
fipc_set_reg1(request, res1);
fipc_set_reg2(request, res2);
/*
* Send request, and get response
*/
ret = send_and_get_response(chan, request, &response);
if (ret) {
pr_err("Error getting response, ret = %d\n", ret);
goto fail;
}
/*
* Maybe check message
*/
return finish_response_check_fn_type_and_reg0(
response,
ADD_3_NUMS,
trans + res1 + res2);
fail:
return ret;
}
static int noinline __used
add_4_nums(struct fipc_ring_channel *chan, unsigned long trans,
unsigned long res1, unsigned long res2, unsigned long res3)
{
struct fipc_message *request;
struct fipc_message *response;
int ret;
/*
* Set up request
*/
ret = blocking_send_start(chan, &request);
if (ret) {
pr_err("Error getting send message, ret = %d\n", ret);
goto fail;
}
set_fn_type(request, ADD_4_NUMS);
fipc_set_reg0(request, trans);
fipc_set_reg1(request, res1);
fipc_set_reg2(request, res2);
fipc_set_reg3(request, res3);
/*
* Send request, and get response
*/
ret = send_and_get_response(chan, request, &response);
if (ret) {
pr_err("Error getting response, ret = %d\n", ret);
goto fail;
}
/*
* Maybe check message
*/
return finish_response_check_fn_type_and_reg0(
response,
ADD_4_NUMS,
trans + res1 + res2 + res3);
fail:
return ret;
}
static int noinline __used
add_5_nums(struct fipc_ring_channel *chan, unsigned long trans,
unsigned long res1, unsigned long res2, unsigned long res3,
unsigned long res4)
{
struct fipc_message *request;
struct fipc_message *response;
int ret;
/*
* Set up request
*/
ret = blocking_send_start(chan, &request);
if (ret) {
pr_err("Error getting send message, ret = %d\n", ret);
goto fail;
}
set_fn_type(request, ADD_5_NUMS);
fipc_set_reg0(request, trans);
fipc_set_reg1(request, res1);
fipc_set_reg2(request, res2);
fipc_set_reg3(request, res3);
fipc_set_reg4(request, res4);
/*
* Send request, and get response
*/
ret = send_and_get_response(chan, request, &response);
if (ret) {
pr_err("Error getting response, ret = %d\n", ret);
goto fail;
}
/*
* Maybe check message
*/
return finish_response_check_fn_type_and_reg0(
response,
ADD_5_NUMS,
trans + res1 + res2 + res3 + res4);
fail:
return ret;
}
static int noinline __used
add_6_nums(struct fipc_ring_channel *chan, unsigned long trans,
unsigned long res1, unsigned long res2, unsigned long res3,
unsigned long res4, unsigned long res5)
{
struct fipc_message *request;
struct fipc_message *response;
int ret;
/*
* Set up request
*/
ret = blocking_send_start(chan, &request);
if (ret) {
pr_err("Error getting send message, ret = %d\n", ret);
goto fail;
}
set_fn_type(request, ADD_6_NUMS);
fipc_set_reg0(request, trans);
fipc_set_reg1(request, res1);
fipc_set_reg2(request, res2);
fipc_set_reg3(request, res3);
fipc_set_reg4(request, res4);
fipc_set_reg5(request, res5);
/*
* Send request, and get response
*/
ret = send_and_get_response(chan, request, &response);
if (ret) {
pr_err("Error getting response, ret = %d\n", ret);
goto fail;
}
/*