summaryrefslogtreecommitdiff
path: root/lib/utils/mailbox/rpmi_mailbox.c
blob: 371c719bea851c07712521d20be88d0ee170dd05 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/*
 * SPDX-License-Identifier: BSD-2-Clause
 *
 * Copyright (c) 2023 Ventana Micro Systems Inc.
 *
 * Authors:
 *   Anup Patel <[email protected]>
 */

#include <sbi/sbi_error.h>
#include <sbi_utils/mailbox/mailbox.h>
#include <sbi_utils/mailbox/rpmi_mailbox.h>

int rpmi_xlate_error(enum rpmi_error error)
{
	switch(error) {
	case RPMI_SUCCESS:
		return SBI_OK;
	case RPMI_ERR_FAILED:
		return SBI_EFAIL;
	case RPMI_ERR_NOTSUPP:
		return SBI_ENOTSUPP;
	case RPMI_ERR_INVALID_PARAM:
		return SBI_EINVAL;
	case RPMI_ERR_DENIED:
		return SBI_EDENIED;
	case RPMI_ERR_INVALID_ADDR:
		return SBI_EINVALID_ADDR;
	case RPMI_ERR_ALREADY:
		return SBI_EALREADY;
	case RPMI_ERR_EXTENSION:
		return SBI_EFAIL;
	case RPMI_ERR_HW_FAULT:
		return SBI_EIO;
	case RPMI_ERR_BUSY:
		return SBI_EFAIL;
	case RPMI_ERR_INVALID_STATE:
		return SBI_EINVALID_STATE;
	case RPMI_ERR_BAD_RANGE:
		return SBI_EBAD_RANGE;
	case RPMI_ERR_TIMEOUT:
		return SBI_ETIMEDOUT;
	case RPMI_ERR_IO:
		return SBI_EIO;
	case RPMI_ERR_NO_DATA:
		return SBI_EFAIL;
	default:
		return SBI_EUNKNOWN;
	}
}

int rpmi_normal_request_with_status(
			struct mbox_chan *chan, u32 service_id,
			void *req, u32 req_words, u32 req_endian_words,
			void *resp, u32 resp_words, u32 resp_endian_words)
{
	int ret;
	struct mbox_xfer xfer;
	struct rpmi_message_args args = { 0 };

	args.type = RPMI_MSG_NORMAL_REQUEST;
	args.service_id = service_id;
	args.tx_endian_words = req_endian_words;
	args.rx_endian_words = resp_endian_words;
	mbox_xfer_init_txrx(&xfer, &args,
			req, sizeof(u32) * req_words, RPMI_DEF_TX_TIMEOUT,
			resp, sizeof(u32) * resp_words, RPMI_DEF_RX_TIMEOUT);

	ret = mbox_chan_xfer(chan, &xfer);
	if (ret)
		return ret;

	return rpmi_xlate_error(((u32 *)resp)[0]);
}

int rpmi_posted_request(
		struct mbox_chan *chan, u32 service_id,
		void *req, u32 req_words, u32 req_endian_words)
{
	struct mbox_xfer xfer;
	struct rpmi_message_args args = { 0 };

	args.type = RPMI_MSG_POSTED_REQUEST;
	args.flags = RPMI_MSG_FLAGS_NO_RX;
	args.service_id = service_id;
	args.tx_endian_words = req_endian_words;
	mbox_xfer_init_tx(&xfer, &args,
			  req, sizeof(u32) * req_words, RPMI_DEF_TX_TIMEOUT);

	return mbox_chan_xfer(chan, &xfer);
}