You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
169 lines
7.3 KiB
169 lines
7.3 KiB
// Copyright 2020 The Android Open Source Project
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
#ifndef _HW_GOLDFISH_PIPE_H
|
|
#define _HW_GOLDFISH_PIPE_H
|
|
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
class QEMUFile;
|
|
|
|
/* The Android pipe virtual device expects an implementation of
|
|
* pipe services to be provided according to the following interface
|
|
*/
|
|
typedef struct GoldfishPipeBuffer {
|
|
void* data;
|
|
size_t size;
|
|
} GoldfishPipeBuffer;
|
|
|
|
/* List of bitflags returned by guest_poll() */
|
|
typedef enum {
|
|
GOLDFISH_PIPE_POLL_IN = (1 << 0), /* means guest can read */
|
|
GOLDFISH_PIPE_POLL_OUT = (1 << 1), /* means guest can write */
|
|
GOLDFISH_PIPE_POLL_HUP = (1 << 2), /* means closed by host */
|
|
} GoldfishPipePollFlags;
|
|
|
|
/* List of bitflags used to call goldfish_pipe_signal_wake() and
|
|
* guest_wake_on() */
|
|
typedef enum {
|
|
GOLDFISH_PIPE_WAKE_CLOSED = (1 << 0), /* emulator closed the pipe */
|
|
GOLDFISH_PIPE_WAKE_READ = (1 << 1), /* pipe can now be read from */
|
|
GOLDFISH_PIPE_WAKE_WRITE = (1 << 2), /* pipe can now be written to */
|
|
GOLDFISH_PIPE_WAKE_UNLOCK_DMA = (1 << 3),/* unlock this pipe's DMA buffer */
|
|
} GoldfishPipeWakeFlags;
|
|
|
|
/* List of error values possibly returned by guest_recv() and
|
|
* guest_send(). */
|
|
typedef enum {
|
|
GOLDFISH_PIPE_ERROR_INVAL = -1,
|
|
GOLDFISH_PIPE_ERROR_AGAIN = -2,
|
|
GOLDFISH_PIPE_ERROR_NOMEM = -3,
|
|
GOLDFISH_PIPE_ERROR_IO = -4,
|
|
} GoldfishPipeError;
|
|
|
|
/* List of reasons why pipe is closed. */
|
|
typedef enum {
|
|
GOLDFISH_PIPE_CLOSE_GRACEFUL = 0,
|
|
GOLDFISH_PIPE_CLOSE_REBOOT = 1,
|
|
GOLDFISH_PIPE_CLOSE_LOAD_SNAPSHOT = 2,
|
|
GOLDFISH_PIPE_CLOSE_ERROR = 3,
|
|
} GoldfishPipeCloseReason;
|
|
|
|
/* Opaque type of the hardware-side view of a pipe connection. This structure
|
|
* is implemented by the virtual device and is hidden from the host service
|
|
* implementation. */
|
|
typedef struct GoldfishHwPipe GoldfishHwPipe;
|
|
|
|
/* Opaque type of the host-side view of a pipe connection. This structure is
|
|
* implemented by the host pipe service implementation, and is hidden from
|
|
* the virtual device. */
|
|
typedef struct GoldfishHostPipe GoldfishHostPipe;
|
|
|
|
typedef struct {
|
|
// Open a new pipe. |hw_pipe| is a unique pointer value identifying the
|
|
// hardware-side view of the pipe, and will be passed to the
|
|
// goldfish_pipe_xxx() functions below. This returns a new host-specific
|
|
// pipe value that is only used by the virtual device to call other
|
|
// callbacks here. There is a one-to-one association between a |hw_pipe|
|
|
// and its |host_pipe| value, which can be reset by calling
|
|
// goldfish_pipe_reset().
|
|
GoldfishHostPipe* (*guest_open)(GoldfishHwPipe *hw_pipe);
|
|
GoldfishHostPipe* (*guest_open_with_flags)(GoldfishHwPipe *hw_pipe, uint32_t flags);
|
|
|
|
// Close and free a pipe. |host_pipe| must be the result of a previous
|
|
// guest_open() or guest_load() call, or the second parameter to
|
|
// goldfish_pipe_reset(). |reason| is why the pipe was closed.
|
|
void (*guest_close)(GoldfishHostPipe *host_pipe,
|
|
GoldfishPipeCloseReason reason);
|
|
|
|
// A set of hooks to prepare and cleanup save/load operations. These are
|
|
// called once per each snapshot operation, as opposed to the following
|
|
// guest_load()/guest_save().
|
|
void (*guest_pre_load)(QEMUFile *file);
|
|
void (*guest_post_load)(QEMUFile *file);
|
|
void (*guest_pre_save)(QEMUFile *file);
|
|
void (*guest_post_save)(QEMUFile *file);
|
|
|
|
// Load the state of a pipe from a stream. |file| is the input stream,
|
|
// |hw_pipe| is the hardware-side pipe descriptor. On success, return a new
|
|
// internal pipe instance (similar to one returned by guest_open()), and
|
|
// sets |*force_close| to 1 to indicate that the pipe must be force-closed
|
|
// just after its load/creation (only useful for certain services that can't
|
|
// preserve state into streams). Return NULL on faillure.
|
|
GoldfishHostPipe* (*guest_load)(QEMUFile *file, GoldfishHwPipe *hw_pipe,
|
|
char *force_close);
|
|
|
|
// Save the state of a pipe to a stream. |host_pipe| is the pipe
|
|
// instance from guest_open() or guest_load(). and |file| is the
|
|
// output stream.
|
|
void (*guest_save)(GoldfishHostPipe *host_pipe, QEMUFile *file);
|
|
|
|
// Poll the state of the pipe associated with |host_pipe|.
|
|
// This returns a combination of GoldfishPipePollFlags.
|
|
GoldfishPipePollFlags (*guest_poll)(GoldfishHostPipe *host_pipe);
|
|
|
|
// Called when the guest tries to receive data from the host through
|
|
// |host_pipe|. This will try to copy data to the memory ranges
|
|
// decribed by the array |buffers| or |num_buffers| items.
|
|
// Return number of bytes transferred, or a (negative) GoldfishPipeError
|
|
// value otherwise.
|
|
int (*guest_recv)(GoldfishHostPipe *host_pipe,
|
|
GoldfishPipeBuffer *buffers,
|
|
int num_buffers);
|
|
|
|
// Called when the guest tries to send data to the host through
|
|
// |host_pipe|. This will try to copy data from the memory ranges
|
|
// decribed by the array |buffers| or |num_buffers| items.
|
|
// Return number of bytes transferred, or a (negative) GoldfishPipeError
|
|
// value otherwise.
|
|
int (*guest_send)(GoldfishHostPipe **host_pipe,
|
|
const GoldfishPipeBuffer *buffers,
|
|
int num_buffers);
|
|
|
|
// Called when the guest wants to be waked on specific events.
|
|
// identified by the |wake_flags| bitmask. The host should call
|
|
// goldfish_pipe_signal_wake() with the appropriate bitmask when
|
|
// any of these events occur.
|
|
void (*guest_wake_on)(GoldfishHostPipe *host_pipe,
|
|
GoldfishPipeWakeFlags wake_flags);
|
|
|
|
// called to register a new DMA buffer that can be mapped in guest + host.
|
|
void (*dma_add_buffer)(void* pipe, uint64_t guest_paddr, uint64_t);
|
|
// called when the guest is done with a particular DMA buffer.
|
|
void (*dma_remove_buffer)(uint64_t guest_paddr);
|
|
// called when host mappings change, such
|
|
// as on pipe save/load during snapshots.
|
|
void (*dma_invalidate_host_mappings)(void);
|
|
// called when device reboots and we need to reset pipe state completely.
|
|
void (*dma_reset_host_mappings)(void);
|
|
// For snapshot save/load of DMA buffer state.
|
|
void (*dma_save_mappings)(QEMUFile* file);
|
|
void (*dma_load_mappings)(QEMUFile* file);
|
|
} GoldfishPipeServiceOps;
|
|
|
|
/* Called by the service implementation to register its callbacks.
|
|
* The default implementation doesn't do anything except returning
|
|
* an error when |guest_open| or |guest_load| are called. */
|
|
extern void goldfish_pipe_set_service_ops(
|
|
const GoldfishPipeServiceOps* ops);
|
|
|
|
/* Query the service ops struct from other places. For use with
|
|
* virtio. */
|
|
extern const GoldfishPipeServiceOps* goldfish_pipe_get_service_ops(void);
|
|
|
|
extern GoldfishHwPipe* goldfish_pipe_lookup_by_id(int id);
|
|
|
|
#endif /* _HW_GOLDFISH_PIPE_H */
|