blob: 776260380f430bebe64ab3f19fe3b904166590c6 [file] [log] [blame]
Cody Schuffelen134ff032019-11-22 00:25:32 -08001#pragma once
2
3/*
4 * Copyright (C) 2017 The Android Open Source Project
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19#include <sys/mman.h>
20#include <stdint.h>
21#include <memory>
22#include "uapi/vsoc_shm.h"
23
24namespace vsoc {
25
26/**
27 * Base class for side-specific utility functions that work on regions.
28 * The methods in this class do not assume that the region is mapped in memory.
29 * This makes is appropriate for ManagedRegions and certain low-level tests
30 * of VSoC shared memory. Most other users will want to use TypedRegions with
31 * a defined RegionLayout.
32 *
33 * This class is not directly instantiable because it must be specialized with
34 * additional fields for the host and guest.
35 */
36class RegionControl {
37 public:
38 virtual ~RegionControl() {
39 if (region_base_) {
40 munmap(region_base_, region_size());
41 }
42 region_base_ = nullptr;
43 }
44
45#if defined(CUTTLEFISH_HOST)
46 static std::shared_ptr<RegionControl> Open(const char* region_name,
47 const char* domain);
48#else
49 static std::shared_ptr<RegionControl> Open(const char* region_name);
50#endif
51
52 const vsoc_device_region& region_desc() const { return region_desc_; }
53
54 // Returns the size of the entire region, including the signal tables.
55 uint32_t region_size() const {
56 return region_desc_.region_end_offset - region_desc_.region_begin_offset;
57 }
58
59 // Returns the size of the region that is usable for region-specific data.
60 uint32_t region_data_size() const {
61 return region_size() - region_desc_.offset_of_region_data;
62 }
63
64 // Creates a FdScopedPermission. Returns the file descriptor or -1 on
65 // failure. FdScopedPermission is not supported on the host, so -1 is
66 // always returned there.
67 virtual int CreateFdScopedPermission(const char* managed_region_name,
68 uint32_t owner_offset,
69 uint32_t owned_value,
70 uint32_t begin_offset,
71 uint32_t end_offset) = 0;
72
73 // Interrupt our peer, causing it to scan the outgoing_signal_table
74 virtual bool InterruptPeer() = 0;
75
76 // Wake the local signal table scanner. Primarily used during shutdown
77 virtual void InterruptSelf() = 0;
78
79 // Maps the entire region at an address, returning a pointer to the mapping
80 virtual void* Map() = 0;
81
82 // Wait for an interrupt from our peer
83 virtual void WaitForInterrupt() = 0;
84
85 // Signals local waiters at the given region offset.
86 // Defined only on the guest.
87 // Return value is negative on error.
88 virtual int SignalSelf(uint32_t offset) = 0;
89
90 // Waits for a signal at the given region offset.
91 // Defined only on the guest.
92 // Return value is negative on error. The number of false wakes is returned
93 // on success.
94 virtual int WaitForSignal(uint32_t offset, uint32_t expected_value) = 0;
95
96 template <typename T>
97 T* region_offset_to_pointer(uint32_t offset) {
98 if (offset > region_size()) {
99 LOG(FATAL) << __FUNCTION__ << ": " << offset << " not in region @"
100 << region_base_;
101 }
102 return reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(region_base_) +
103 offset);
104 }
105
106 protected:
107 RegionControl() {}
108 void* region_base_{};
109 vsoc_device_region region_desc_{};
110};
111} // namespace vsoc