xref: /aosp_15_r20/external/mesa3d/src/gfxstream/guest/GoldfishAddressSpace/GoldfishAddressSpaceStream.cpp (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright 2023 Google
3  * SPDX-License-Identifier: MIT
4  */
5 
6 #include "GoldfishAddressSpaceStream.h"
7 
8 #include "goldfish_address_space.h"
9 #include "util/log.h"
10 
createGoldfishAddressSpaceStream(size_t ignored_bufSize)11 AddressSpaceStream* createGoldfishAddressSpaceStream(size_t ignored_bufSize) {
12     // Ignore incoming ignored_bufSize
13     (void)ignored_bufSize;
14 
15     auto handle = goldfish_address_space_open();
16     address_space_handle_t child_device_handle;
17 
18     if (!goldfish_address_space_set_subdevice_type(handle, GoldfishAddressSpaceSubdeviceType::Graphics, &child_device_handle)) {
19         mesa_loge("AddressSpaceStream::create failed (initial device create)\n");
20         goldfish_address_space_close(handle);
21         return nullptr;
22     }
23 
24     struct address_space_ping request;
25     request.metadata = ASG_GET_RING;
26     if (!goldfish_address_space_ping(child_device_handle, &request)) {
27         mesa_loge("AddressSpaceStream::create failed (get ring)\n");
28         goldfish_address_space_close(child_device_handle);
29         return nullptr;
30     }
31 
32     uint64_t ringOffset = request.metadata;
33 
34     request.metadata = ASG_GET_BUFFER;
35     if (!goldfish_address_space_ping(child_device_handle, &request)) {
36         mesa_loge("AddressSpaceStream::create failed (get buffer)\n");
37         goldfish_address_space_close(child_device_handle);
38         return nullptr;
39     }
40 
41     uint64_t bufferOffset = request.metadata;
42     uint64_t bufferSize = request.size;
43 
44     if (!goldfish_address_space_claim_shared(
45         child_device_handle, ringOffset, sizeof(asg_ring_storage))) {
46         mesa_loge("AddressSpaceStream::create failed (claim ring storage)\n");
47         goldfish_address_space_close(child_device_handle);
48         return nullptr;
49     }
50 
51     if (!goldfish_address_space_claim_shared(
52         child_device_handle, bufferOffset, bufferSize)) {
53         mesa_loge("AddressSpaceStream::create failed (claim buffer storage)\n");
54         goldfish_address_space_unclaim_shared(child_device_handle, ringOffset);
55         goldfish_address_space_close(child_device_handle);
56         return nullptr;
57     }
58 
59     char* ringPtr = (char*)goldfish_address_space_map(
60         child_device_handle, ringOffset, sizeof(struct asg_ring_storage));
61 
62     if (!ringPtr) {
63         mesa_loge("AddressSpaceStream::create failed (map ring storage)\n");
64         goldfish_address_space_unclaim_shared(child_device_handle, bufferOffset);
65         goldfish_address_space_unclaim_shared(child_device_handle, ringOffset);
66         goldfish_address_space_close(child_device_handle);
67         return nullptr;
68     }
69 
70     char* bufferPtr = (char*)goldfish_address_space_map(
71         child_device_handle, bufferOffset, bufferSize);
72 
73     if (!bufferPtr) {
74         mesa_loge("AddressSpaceStream::create failed (map buffer storage)\n");
75         goldfish_address_space_unmap(ringPtr, sizeof(struct asg_ring_storage));
76         goldfish_address_space_unclaim_shared(child_device_handle, bufferOffset);
77         goldfish_address_space_unclaim_shared(child_device_handle, ringOffset);
78         goldfish_address_space_close(child_device_handle);
79         return nullptr;
80     }
81 
82     struct asg_context context =
83         asg_context_create(
84             ringPtr, bufferPtr, bufferSize);
85 
86     request.metadata = ASG_SET_VERSION;
87     request.size = 1; // version 1
88 
89     if (!goldfish_address_space_ping(child_device_handle, &request)) {
90         mesa_loge("AddressSpaceStream::create failed (get buffer)\n");
91         goldfish_address_space_unmap(bufferPtr, bufferSize);
92         goldfish_address_space_unmap(ringPtr, sizeof(struct asg_ring_storage));
93         goldfish_address_space_unclaim_shared(child_device_handle, bufferOffset);
94         goldfish_address_space_unclaim_shared(child_device_handle, ringOffset);
95         goldfish_address_space_close(child_device_handle);
96         return nullptr;
97     }
98 
99     uint32_t version = request.size;
100 
101     context.ring_config->transfer_mode = 1;
102     context.ring_config->host_consumed_pos = 0;
103     context.ring_config->guest_write_pos = 0;
104 
105     struct address_space_ops ops = {
106         .open = goldfish_address_space_open,
107         .close = goldfish_address_space_close,
108         .claim_shared = goldfish_address_space_claim_shared,
109         .unclaim_shared = goldfish_address_space_unclaim_shared,
110         .map = goldfish_address_space_map,
111         .unmap = goldfish_address_space_unmap,
112         .set_subdevice_type = goldfish_address_space_set_subdevice_type,
113         .ping = goldfish_address_space_ping,
114     };
115 
116     AddressSpaceStream* res = new AddressSpaceStream(child_device_handle, version, context,
117                                                      ringOffset, bufferOffset, ops);
118 
119     return res;
120 }
121