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
|
/*
* Copyright (c) 2019, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <fwk_errno.h>
#include <fwk_id.h>
#include <fwk_interrupt.h>
#include <fwk_mm.h>
#include <fwk_module.h>
#include <fwk_module_idx.h>
#include <openamp/rpmsg_internal.h>
#include <openamp/rpmsg_client.h>
#include <libmetal/mutex.h>
#include <mod_mhuv2.h>
#include <mod_log.h>
#include <mod_eventhandler.h>
struct rpmsg_ctx {
/* Log API pointer */
const struct mod_log_api *log_api;
const struct mod_mhu_driver_api *mhu2_api;
const struct mod_eventhandler_api *eventhandler_api;
};
static struct rpmsg_ctx rpmsg_ctx;
struct rpmsg_endpoint* get_endpoint(uint32_t address)
{
return rpmsg_get_endpoint(rpmesg_device,"arm-rpmsg", RPMSG_ADDR_ANY, address);
}
static int rpmsg_endpoint_cb(struct rpmsg_endpoint *ept, void *data, size_t len,
uint32_t src, void *priv)
{
int status = fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_EVENTHANDLER),
FWK_ID_API(FWK_MODULE_IDX_EVENTHANDLER, 0),&rpmsg_ctx.eventhandler_api);
if (status != FWK_SUCCESS)
return FWK_E_PANIC;
rpmsg_ctx.eventhandler_api->handleRpmsgEvent(ept, data, len);
return RPMSG_SUCCESS;
}
struct rpmsg_endpoint* endpoint_create(struct rpmsg_device *rdev, void *dest)
{
struct rpmsg_endpoint *lept;
uint32_t dest_addr = (uint32_t)dest;
int status;
lept = fwk_mm_calloc(1,sizeof(*lept));
status = rpmsg_create_ept(lept, rdev, "arm-rpmsg",RPMSG_ADDR_ANY,
dest_addr,rpmsg_endpoint_cb, NULL);
if (status == RPMSG_SUCCESS)
return lept;
else
return RPMSG_SUCCESS;
}
static int send_rpmsg(struct rpmsg_device *rdev,
uint32_t src, uint32_t dst,
const void *data, int size, int wait)
{
uint32_t message;
int status;
fwk_id_t fwk_dst;
status = fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_MHUV2),
FWK_ID_API(FWK_MODULE_IDX_MHUV2, 0),&rpmsg_ctx.mhu2_api);
if (status != FWK_SUCCESS)
return FWK_E_PANIC;
fwk_dst = rpmsg_ctx.mhu2_api->lookup_channel(dst);
message = *(uint32_t *)data;
status = rpmsg_ctx.mhu2_api->send_message(fwk_dst, message);
if(status == FWK_SUCCESS){
return RPMSG_SUCCESS;
} else {
return status;
}
}
struct rpmsg_device* init_rpmsg()
{
struct rpmsg_device *rdev;
rdev = fwk_mm_calloc(1,sizeof(*rdev));
metal_mutex_init(&rdev->lock);
metal_list_init(&rdev->endpoints);
rdev->ops.send_offchannel_raw = send_rpmsg;
rdev->ns_bind_cb = NULL;
rpmesg_device = rdev;
return rdev;
}
|