Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/firmware/arm_scmi/msg.c
26444 views
1
// SPDX-License-Identifier: GPL-2.0
2
/*
3
* For transports using message passing.
4
*
5
* Derived from shm.c.
6
*
7
* Copyright (C) 2019-2024 ARM Ltd.
8
* Copyright (C) 2020-2021 OpenSynergy GmbH
9
*/
10
11
#include <linux/types.h>
12
13
#include "common.h"
14
15
/*
16
* struct scmi_msg_payld - Transport SDU layout
17
*
18
* The SCMI specification requires all parameters, message headers, return
19
* arguments or any protocol data to be expressed in little endian format only.
20
*/
21
struct scmi_msg_payld {
22
__le32 msg_header;
23
__le32 msg_payload[];
24
};
25
26
/**
27
* msg_command_size() - Actual size of transport SDU for command.
28
*
29
* @xfer: message which core has prepared for sending
30
*
31
* Return: transport SDU size.
32
*/
33
static size_t msg_command_size(struct scmi_xfer *xfer)
34
{
35
return sizeof(struct scmi_msg_payld) + xfer->tx.len;
36
}
37
38
/**
39
* msg_response_size() - Maximum size of transport SDU for response.
40
*
41
* @xfer: message which core has prepared for sending
42
*
43
* Return: transport SDU size.
44
*/
45
static size_t msg_response_size(struct scmi_xfer *xfer)
46
{
47
return sizeof(struct scmi_msg_payld) + sizeof(__le32) + xfer->rx.len;
48
}
49
50
/**
51
* msg_tx_prepare() - Set up transport SDU for command.
52
*
53
* @msg: transport SDU for command
54
* @xfer: message which is being sent
55
*/
56
static void msg_tx_prepare(struct scmi_msg_payld *msg, struct scmi_xfer *xfer)
57
{
58
msg->msg_header = cpu_to_le32(pack_scmi_header(&xfer->hdr));
59
if (xfer->tx.buf)
60
memcpy(msg->msg_payload, xfer->tx.buf, xfer->tx.len);
61
}
62
63
/**
64
* msg_read_header() - Read SCMI header from transport SDU.
65
*
66
* @msg: transport SDU
67
*
68
* Return: SCMI header
69
*/
70
static u32 msg_read_header(struct scmi_msg_payld *msg)
71
{
72
return le32_to_cpu(msg->msg_header);
73
}
74
75
/**
76
* msg_fetch_response() - Fetch response SCMI payload from transport SDU.
77
*
78
* @msg: transport SDU with response
79
* @len: transport SDU size
80
* @xfer: message being responded to
81
*/
82
static void msg_fetch_response(struct scmi_msg_payld *msg,
83
size_t len, struct scmi_xfer *xfer)
84
{
85
size_t prefix_len = sizeof(*msg) + sizeof(msg->msg_payload[0]);
86
87
xfer->hdr.status = le32_to_cpu(msg->msg_payload[0]);
88
xfer->rx.len = min_t(size_t, xfer->rx.len,
89
len >= prefix_len ? len - prefix_len : 0);
90
91
/* Take a copy to the rx buffer.. */
92
memcpy(xfer->rx.buf, &msg->msg_payload[1], xfer->rx.len);
93
}
94
95
/**
96
* msg_fetch_notification() - Fetch notification payload from transport SDU.
97
*
98
* @msg: transport SDU with notification
99
* @len: transport SDU size
100
* @max_len: maximum SCMI payload size to fetch
101
* @xfer: notification message
102
*/
103
static void msg_fetch_notification(struct scmi_msg_payld *msg, size_t len,
104
size_t max_len, struct scmi_xfer *xfer)
105
{
106
xfer->rx.len = min_t(size_t, max_len,
107
len >= sizeof(*msg) ? len - sizeof(*msg) : 0);
108
109
/* Take a copy to the rx buffer.. */
110
memcpy(xfer->rx.buf, msg->msg_payload, xfer->rx.len);
111
}
112
113
static const struct scmi_message_operations scmi_msg_ops = {
114
.tx_prepare = msg_tx_prepare,
115
.command_size = msg_command_size,
116
.response_size = msg_response_size,
117
.read_header = msg_read_header,
118
.fetch_response = msg_fetch_response,
119
.fetch_notification = msg_fetch_notification,
120
};
121
122
const struct scmi_message_operations *scmi_message_operations_get(void)
123
{
124
return &scmi_msg_ops;
125
}
126
127