• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 #ifndef _HW_GOLDFISH_PIPE_H
15 #define _HW_GOLDFISH_PIPE_H
16 
17 #include <stdbool.h>
18 #include <stddef.h>
19 #include <stdint.h>
20 
21 typedef struct QEMUFile QEMUFile;
22 
23 /* The Android pipe virtual device expects an implementation of
24  * pipe services to be provided according to the following interface
25  */
26 typedef struct GoldfishPipeBuffer {
27     void* data;
28     size_t size;
29 } GoldfishPipeBuffer;
30 
31 /* List of bitflags returned by guest_poll() */
32 typedef enum {
33     GOLDFISH_PIPE_POLL_IN = (1 << 0),   /* means guest can read */
34     GOLDFISH_PIPE_POLL_OUT = (1 << 1),  /* means guest can write */
35     GOLDFISH_PIPE_POLL_HUP = (1 << 2),  /* means closed by host */
36 } GoldfishPipePollFlags;
37 
38 /* List of bitflags used to call goldfish_pipe_signal_wake() and
39  * guest_wake_on() */
40 typedef enum {
41     GOLDFISH_PIPE_WAKE_CLOSED = (1 << 0),     /* emulator closed the pipe */
42     GOLDFISH_PIPE_WAKE_READ = (1 << 1),       /* pipe can now be read from */
43     GOLDFISH_PIPE_WAKE_WRITE = (1 << 2),      /* pipe can now be written to */
44     GOLDFISH_PIPE_WAKE_UNLOCK_DMA  = (1 << 3),/* unlock this pipe's DMA buffer */
45 } GoldfishPipeWakeFlags;
46 
47 /* List of error values possibly returned by guest_recv() and
48  * guest_send(). */
49 typedef enum {
50     GOLDFISH_PIPE_ERROR_INVAL = -1,
51     GOLDFISH_PIPE_ERROR_AGAIN = -2,
52     GOLDFISH_PIPE_ERROR_NOMEM = -3,
53     GOLDFISH_PIPE_ERROR_IO = -4,
54 } GoldfishPipeError;
55 
56 /* List of reasons why pipe is closed. */
57 typedef enum {
58     GOLDFISH_PIPE_CLOSE_GRACEFUL = 0,
59     GOLDFISH_PIPE_CLOSE_REBOOT = 1,
60     GOLDFISH_PIPE_CLOSE_LOAD_SNAPSHOT = 2,
61     GOLDFISH_PIPE_CLOSE_ERROR = 3,
62 } GoldfishPipeCloseReason;
63 
64 /* Opaque type of the hardware-side view of a pipe connection. This structure
65  * is implemented by the virtual device and is hidden from the host service
66  * implementation. */
67 typedef struct GoldfishHwPipe GoldfishHwPipe;
68 
69 /* Opaque type of the host-side view of a pipe connection. This structure is
70  * implemented by the host pipe service implementation, and is hidden from
71  * the virtual device. */
72 typedef struct GoldfishHostPipe GoldfishHostPipe;
73 
74 typedef struct GoldfishPipeServiceOps {
75     // Open a new pipe. |hw_pipe| is a unique pointer value identifying the
76     // hardware-side view of the pipe, and will be passed to the
77     // goldfish_pipe_xxx() functions below. This returns a new host-specific
78     // pipe value that is only used by the virtual device to call other
79     // callbacks here. There is a one-to-one association between a |hw_pipe|
80     // and its |host_pipe| value, which can be reset by calling
81     // goldfish_pipe_reset().
82     GoldfishHostPipe* (*guest_open)(GoldfishHwPipe *hw_pipe);
83     GoldfishHostPipe* (*guest_open_with_flags)(GoldfishHwPipe *hw_pipe, uint32_t flags);
84 
85     // Close and free a pipe. |host_pipe| must be the result of a previous
86     // guest_open() or guest_load() call, or the second parameter to
87     // goldfish_pipe_reset(). |reason| is why the pipe was closed.
88     void (*guest_close)(GoldfishHostPipe *host_pipe,
89                         GoldfishPipeCloseReason reason);
90 
91     // A set of hooks to prepare and cleanup save/load operations. These are
92     // called once per each snapshot operation, as opposed to the following
93     // guest_load()/guest_save().
94     void (*guest_pre_load)(QEMUFile *file);
95     void (*guest_post_load)(QEMUFile *file);
96     void (*guest_pre_save)(QEMUFile *file);
97     void (*guest_post_save)(QEMUFile *file);
98 
99     // Load the state of a  pipe from a stream. |file| is the input stream,
100     // |hw_pipe| is the hardware-side pipe descriptor. On success, return a new
101     // internal pipe instance (similar to one returned by guest_open()), and
102     // sets |*force_close| to 1 to indicate that the pipe must be force-closed
103     // just after its load/creation (only useful for certain services that can't
104     // preserve state into streams). Return NULL on faillure.
105     GoldfishHostPipe* (*guest_load)(QEMUFile *file, GoldfishHwPipe *hw_pipe,
106                                     char *force_close);
107 
108     // Save the state of a pipe to a stream. |host_pipe| is the pipe
109     // instance from guest_open() or guest_load(). and |file| is the
110     // output stream.
111     void (*guest_save)(GoldfishHostPipe *host_pipe, QEMUFile *file);
112 
113     // Poll the state of the pipe associated with |host_pipe|.
114     // This returns a combination of GoldfishPipePollFlags.
115     GoldfishPipePollFlags (*guest_poll)(GoldfishHostPipe *host_pipe);
116 
117     // Called when the guest tries to receive data from the host through
118     // |host_pipe|. This will try to copy data to the memory ranges
119     // decribed by the array |buffers| or |num_buffers| items.
120     // Return number of bytes transferred, or a (negative) GoldfishPipeError
121     // value otherwise.
122     int (*guest_recv)(GoldfishHostPipe *host_pipe,
123                       GoldfishPipeBuffer *buffers,
124                       int num_buffers);
125 
126     // Blocking call that waits until guest is able to receive data through |host_pipe|.
127     void (*wait_guest_recv)(GoldfishHostPipe* host_pipe);
128 
129     // Called when the guest tries to send data to the host through
130     // |host_pipe|. This will try to copy data from the memory ranges
131     // decribed by the array |buffers| or |num_buffers| items.
132     // Return number of bytes transferred, or a (negative) GoldfishPipeError
133     // value otherwise.
134     int (*guest_send)(GoldfishHostPipe **host_pipe,
135                       const GoldfishPipeBuffer *buffers,
136                       int num_buffers);
137 
138     // Blocking call that waits until guest is able to send data through |host_pipe|.
139     void (*wait_guest_send)(GoldfishHostPipe* host_pipe);
140 
141     // Called when the guest wants to be waked on specific events.
142     // identified by the |wake_flags| bitmask. The host should call
143     // goldfish_pipe_signal_wake() with the appropriate bitmask when
144     // any of these events occur.
145     void (*guest_wake_on)(GoldfishHostPipe *host_pipe,
146                           GoldfishPipeWakeFlags wake_flags);
147 
148     // called to register a new DMA buffer that can be mapped in guest + host.
149     void (*dma_add_buffer)(void* pipe, uint64_t guest_paddr, uint64_t);
150     // called when the guest is done with a particular DMA buffer.
151     void (*dma_remove_buffer)(uint64_t guest_paddr);
152     // called when host mappings change, such
153     // as on pipe save/load during snapshots.
154     void (*dma_invalidate_host_mappings)(void);
155     // called when device reboots and we need to reset pipe state completely.
156     void (*dma_reset_host_mappings)(void);
157     // For snapshot save/load of DMA buffer state.
158     void (*dma_save_mappings)(QEMUFile* file);
159     void (*dma_load_mappings)(QEMUFile* file);
160 } GoldfishPipeServiceOps;
161 
162 /* Called by the service implementation to register its callbacks.
163  * The default implementation doesn't do anything except returning
164  * an error when |guest_open| or |guest_load| are called. */
165 extern void goldfish_pipe_set_service_ops(
166         const GoldfishPipeServiceOps* ops);
167 
168 /* Query the service ops struct from other places. For use with
169  * virtio. */
170 extern const GoldfishPipeServiceOps* goldfish_pipe_get_service_ops(void);
171 
172 extern GoldfishHwPipe* goldfish_pipe_lookup_by_id(int id);
173 
174 #endif /* _HW_GOLDFISH_PIPE_H */
175