1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef BERBERIS_KERNEL_API_RISCV64_GUEST_TYPES_ARCH_H_
18 #define BERBERIS_KERNEL_API_RISCV64_GUEST_TYPES_ARCH_H_
19 
20 #include <dirent.h>
21 #include <sys/epoll.h>
22 #include <sys/file.h>
23 
24 #include "berberis/base/struct_check.h"
25 
26 namespace berberis {
27 
28 static_assert(EPOLL_CTL_ADD == 1);
29 static_assert(EPOLL_CTL_DEL == 2);
30 static_assert(EPOLL_CTL_MOD == 3);
31 static_assert(EPOLL_CLOEXEC == 02000000);
32 
33 struct Guest_epoll_event {
34   uint32_t events;
35   alignas(64 / CHAR_BIT) uint64_t data;
36 };
37 
38 // Verify precise layouts so ConvertHostEPollEventArrayToGuestInPlace is safe.
39 CHECK_STRUCT_LAYOUT(Guest_epoll_event, 128, 64);
40 CHECK_FIELD_LAYOUT(Guest_epoll_event, events, 0, 32);
41 CHECK_FIELD_LAYOUT(Guest_epoll_event, data, 64, 64);
42 static_assert(sizeof(epoll_event) <= sizeof(Guest_epoll_event));
43 static_assert(alignof(epoll_event) <= alignof(Guest_epoll_event));
44 
45 CHECK_STRUCT_LAYOUT(dirent64, 2240, 64);
46 CHECK_FIELD_LAYOUT(dirent64, d_ino, 0, 64);
47 CHECK_FIELD_LAYOUT(dirent64, d_off, 64, 64);
48 CHECK_FIELD_LAYOUT(dirent64, d_reclen, 128, 16);
49 CHECK_FIELD_LAYOUT(dirent64, d_type, 144, 8);
50 CHECK_FIELD_LAYOUT(dirent64, d_name, 152, 2048);
51 
52 using Guest_flock = struct flock;
53 using Guest_flock64 = struct flock64;
54 
55 CHECK_STRUCT_LAYOUT(Guest_flock, 256, 64);
56 CHECK_FIELD_LAYOUT(Guest_flock, l_type, 0, 16);
57 CHECK_FIELD_LAYOUT(Guest_flock, l_whence, 16, 16);
58 CHECK_FIELD_LAYOUT(Guest_flock, l_start, 64, 64);
59 CHECK_FIELD_LAYOUT(Guest_flock, l_len, 128, 64);
60 CHECK_FIELD_LAYOUT(Guest_flock, l_pid, 192, 32);
61 
62 CHECK_STRUCT_LAYOUT(Guest_flock64, 256, 64);
63 CHECK_FIELD_LAYOUT(Guest_flock64, l_type, 0, 16);
64 CHECK_FIELD_LAYOUT(Guest_flock64, l_whence, 16, 16);
65 CHECK_FIELD_LAYOUT(Guest_flock64, l_start, 64, 64);
66 CHECK_FIELD_LAYOUT(Guest_flock64, l_len, 128, 64);
67 CHECK_FIELD_LAYOUT(Guest_flock64, l_pid, 192, 32);
68 
69 static_assert(F_GETLK64 == 5);
70 static_assert(F_SETLK64 == 6);
71 static_assert(F_SETLKW64 == 7);
72 
73 CHECK_STRUCT_LAYOUT(timespec, 128, 64);
74 CHECK_FIELD_LAYOUT(timespec, tv_sec, 0, 64);
75 CHECK_FIELD_LAYOUT(timespec, tv_nsec, 64, 64);
76 
77 struct Guest_stat {
78   alignas(8) uint64_t st_dev;
79   alignas(8) uint64_t st_ino;
80   uint32_t st_mode;
81   uint32_t st_nlink;
82   uint32_t st_uid;
83   uint32_t st_gid;
84   alignas(8) uint64_t st_rdev;
85   alignas(8) int64_t padding;
86   alignas(8) int64_t st_size;
87   uint32_t st_blksize;
88   alignas(8) uint64_t st_blocks;
89   timespec st_atim;
90   timespec st_mtim;
91   timespec st_ctim;
92   uint64_t padding2;
93 };
94 
95 CHECK_STRUCT_LAYOUT(Guest_stat, 1024, 64);
96 CHECK_FIELD_LAYOUT(Guest_stat, st_dev, 0, 64);
97 CHECK_FIELD_LAYOUT(Guest_stat, st_ino, 64, 64);
98 CHECK_FIELD_LAYOUT(Guest_stat, st_mode, 128, 32);
99 CHECK_FIELD_LAYOUT(Guest_stat, st_nlink, 160, 32);
100 CHECK_FIELD_LAYOUT(Guest_stat, st_uid, 192, 32);
101 CHECK_FIELD_LAYOUT(Guest_stat, st_gid, 224, 32);
102 CHECK_FIELD_LAYOUT(Guest_stat, st_rdev, 256, 64);
103 CHECK_FIELD_LAYOUT(Guest_stat, st_size, 384, 64);
104 CHECK_FIELD_LAYOUT(Guest_stat, st_blksize, 448, 32);
105 CHECK_FIELD_LAYOUT(Guest_stat, st_blocks, 512, 64);
106 CHECK_FIELD_LAYOUT(Guest_stat, st_atim, 576, 128);
107 CHECK_FIELD_LAYOUT(Guest_stat, st_mtim, 704, 128);
108 CHECK_FIELD_LAYOUT(Guest_stat, st_ctim, 832, 128);
109 
110 struct Guest_riscv_hwprobe {
111   int64_t key;
112   uint64_t value;
113 };
114 
115 CHECK_STRUCT_LAYOUT(Guest_riscv_hwprobe, 128, 64);
116 CHECK_FIELD_LAYOUT(Guest_riscv_hwprobe, key, 0, 64);
117 CHECK_FIELD_LAYOUT(Guest_riscv_hwprobe, value, 64, 64);
118 
119 // Each RISCV_HWPROBE_KEY_* represents a capability key. These constants are sorted
120 // such that each capability key appears in numeric order, followed by the possible
121 // values for that key in numeric order.
122 // clang-format off
123 #define RISCV_HWPROBE_KEY_MVENDORID           0
124 #define RISCV_HWPROBE_KEY_MARCHID             1
125 #define RISCV_HWPROBE_KEY_MIMPID              2
126 #define RISCV_HWPROBE_KEY_BASE_BEHAVIOR       3
127 #define RISCV_HWPROBE_BASE_BEHAVIOR_IMA       (1 << 0)
128 #define RISCV_HWPROBE_KEY_IMA_EXT_0           4
129 #define RISCV_HWPROBE_IMA_FD                  (1 << 0)
130 #define RISCV_HWPROBE_IMA_C                   (1 << 1)
131 #define RISCV_HWPROBE_IMA_V                   (1 << 2)
132 #define RISCV_HWPROBE_EXT_ZBA                 (1 << 3)
133 #define RISCV_HWPROBE_EXT_ZBB                 (1 << 4)
134 #define RISCV_HWPROBE_EXT_ZBS                 (1 << 5)
135 #define RISCV_HWPROBE_KEY_CPUPERF_0           5
136 #define RISCV_HWPROBE_MISALIGNED_UNKNOWN      (0 << 0)
137 #define RISCV_HWPROBE_MISALIGNED_EMULATED     (1 << 0)
138 #define RISCV_HWPROBE_MISALIGNED_SLOW         (2 << 0)
139 #define RISCV_HWPROBE_MISALIGNED_FAST         (3 << 0)
140 #define RISCV_HWPROBE_MISALIGNED_UNSUPPORTED  (4 << 0)
141 #define RISCV_HWPROBE_MISALIGNED_MASK         (7 << 0)
142 // clang-format on
143 
144 }  // namespace berberis
145 
146 #endif  // BERBERIS_KERNEL_API_RISCV64_GUEST_TYPES_ARCH_H_
147