forked from torvalds/linux
/
gunyah.h
186 lines (147 loc) · 4.47 KB
/
gunyah.h
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _GUNYAH_H
#define _GUNYAH_H
#include <linux/bitfield.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/mailbox_controller.h>
#include <linux/mailbox_client.h>
#include <linux/types.h>
/* Follows resource manager's resource types for VM_GET_HYP_RESOURCES */
enum gunyah_resource_type {
GUNYAH_RESOURCE_TYPE_BELL_TX = 0,
GUNYAH_RESOURCE_TYPE_BELL_RX = 1,
GUNYAH_RESOURCE_TYPE_MSGQ_TX = 2,
GUNYAH_RESOURCE_TYPE_MSGQ_RX = 3,
GUNYAH_RESOURCE_TYPE_VCPU = 4,
};
struct gunyah_resource {
enum gunyah_resource_type type;
u64 capid;
int irq;
/* To help allocator in resource manager */
struct list_head list;
u32 rm_label;
};
/**
* Gunyah Doorbells
*/
#define GH_DBL_NONBLOCK BIT(32)
/**
* Gunyah Message Queues
*/
#define GH_MSGQ_MAX_MSG_SIZE 240
struct gh_msgq_tx_data {
size_t length;
bool push;
char data[];
};
struct gh_msgq_rx_data {
size_t length;
char data[GH_MSGQ_MAX_MSG_SIZE];
};
struct gh_msgq {
struct gunyah_resource *tx_ghrsc;
struct gunyah_resource *rx_ghrsc;
/* msgq private */
int last_status;
struct mbox_controller mbox;
struct tasklet_struct txdone_tasklet;
};
int gh_msgq_init(struct device *parent, struct gh_msgq *msgq, struct mbox_client *cl,
struct gunyah_resource *tx_ghrsc, struct gunyah_resource *rx_ghrsc);
void gh_msgq_remove(struct gh_msgq *msgq);
static inline struct mbox_chan *gh_msgq_chan(struct gh_msgq *msgq)
{
return &msgq->mbox.chans[0];
}
/******************************************************************************/
/* Common arch-independent macros and definitions for Gunyah hypercalls */
#define GH_CAPID_INVAL U64_MAX
#define GH_VMID_ROOT_VM 0xff
#define GH_ERROR_OK 0
#define GH_ERROR_UNIMPLEMENTED -1
#define GH_ERROR_RETRY -2
#define GH_ERROR_ARG_INVAL 1
#define GH_ERROR_ARG_SIZE 2
#define GH_ERROR_ARG_ALIGN 3
#define GH_ERROR_NOMEM 10
#define GH_ERROR_ADDR_OVFL 20
#define GH_ERROR_ADDR_UNFL 21
#define GH_ERROR_ADDR_INVAL 22
#define GH_ERROR_DENIED 30
#define GH_ERROR_BUSY 31
#define GH_ERROR_IDLE 32
#define GH_ERROR_IRQ_BOUND 40
#define GH_ERROR_IRQ_UNBOUND 41
#define GH_ERROR_CSPACE_CAP_NULL 50
#define GH_ERROR_CSPACE_CAP_REVOKED 51
#define GH_ERROR_CSPACE_WRONG_OBJ_TYPE 52
#define GH_ERROR_CSPACE_INSUF_RIGHTS 53
#define GH_ERROR_CSPACE_FULL 54
#define GH_ERROR_MSGQUEUE_EMPTY 60
#define GH_ERROR_MSGQUEUE_FULL 61
static inline int gh_remap_error(int gh_error)
{
switch (gh_error) {
case GH_ERROR_OK:
return 0;
case GH_ERROR_NOMEM:
return -ENOMEM;
case GH_ERROR_DENIED:
case GH_ERROR_CSPACE_CAP_NULL:
case GH_ERROR_CSPACE_CAP_REVOKED:
case GH_ERROR_CSPACE_WRONG_OBJ_TYPE:
case GH_ERROR_CSPACE_INSUF_RIGHTS:
case GH_ERROR_CSPACE_FULL:
return -EACCES;
case GH_ERROR_BUSY:
case GH_ERROR_IDLE:
return -EBUSY;
case GH_ERROR_IRQ_BOUND:
case GH_ERROR_IRQ_UNBOUND:
case GH_ERROR_MSGQUEUE_FULL:
case GH_ERROR_MSGQUEUE_EMPTY:
return -EPERM;
default:
return -EINVAL;
}
}
#define GUNYAH_API_V1 1
#define GH_API_INFO_API_VERSION_MASK GENMASK_ULL(13, 0)
#define GH_API_INFO_BIG_ENDIAN BIT_ULL(14)
#define GH_API_INFO_IS_64BIT BIT_ULL(15)
#define GH_API_INFO_VARIANT_MASK GENMASK_ULL(63, 56)
#define GH_IDENTIFY_PARTITION_CSPACE BIT_ULL(0)
#define GH_IDENTIFY_DOORBELL BIT_ULL(1)
#define GH_IDENTIFY_MSGQUEUE BIT_ULL(2)
#define GH_IDENTIFY_VIC BIT_ULL(3)
#define GH_IDENTIFY_VPM BIT_ULL(4)
#define GH_IDENTIFY_VCPU BIT_ULL(5)
#define GH_IDENTIFY_MEMEXTENT BIT_ULL(6)
#define GH_IDENTIFY_TRACE_CTRL BIT_ULL(7)
struct gh_hypercall_hyp_identify_resp {
u64 api_info;
u64 flags[3];
};
extern struct gh_hypercall_hyp_identify_resp gunyah_api;
static inline u16 gh_api_version(void)
{
return FIELD_GET(GH_API_INFO_API_VERSION_MASK, gunyah_api.api_info);
}
void gh_hypercall_get_uid(u32 uid[4]);
void gh_hypercall_hyp_identify(struct gh_hypercall_hyp_identify_resp *hyp_identity);
int gh_hypercall_dbl_send(u64 capid, u64 new_flags, u64 *old_flags);
int gh_hypercall_dbl_set_mask(u64 capid, u64 enable_mask, u64 ack_mask);
#define GH_HYPERCALL_MSGQ_TX_FLAGS_PUSH BIT(0)
int gh_hypercall_msgq_send(u64 capid, size_t size, uintptr_t buff, int tx_flags, bool *ready);
int gh_hypercall_msgq_recv(u64 capid, uintptr_t buff, size_t size, size_t *recv_size, bool *ready);
struct gh_hypercall_vcpu_run_resp {
u64 state;
u64 state_data[3];
};
int gh_hypercall_vcpu_run(u64 capid, u64 *resume_data, struct gh_hypercall_vcpu_run_resp *resp);
#endif