xref: /DragonOS/kernel/src/arch/x86_64/init/pvh/param.rs (revision 59a6bcf6aee15a11a16431bdf875905c5ecf9157)
1 /*
2  * Permission is hereby granted, free of charge, to any person obtaining a copy
3  * of this software and associated documentation files (the "Software"), to
4  * deal in the Software without restriction, including without limitation the
5  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
6  * sell copies of the Software, and to permit persons to whom the Software is
7  * furnished to do so, subject to the following conditions:
8  *
9  * The above copyright notice and this permission notice shall be included in
10  * all copies or substantial portions of the Software.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
17  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
18  * DEALINGS IN THE SOFTWARE.
19  *
20  * Copyright (c) 2016, Citrix Systems, Inc.
21  */
22 
23 /*
24  * automatically generated by rust-bindgen using:
25  *
26  * # bindgen start_info.h -- -include stdint.h > start_info.rs
27  *
28  * From the canonical version in upstream Xen repository
29  * xen/include/public/arch-x86/hvm/start_info.h
30  * at commit:
31  * b4642c32c4d079916d5607ddda0232aae5e1690e
32  *
33  * The generated file has been edited to eliminate unnecessary
34  * definitions, add comments, and relocate definitions and tests for clarity.
35  * Added Default to the list of traits that are automatically derived.
36  *
37  * The definitions in this file are intended to be exported and used by a particular
38  * VMM implementation in order to boot a Linux guest using the PVH entry point as
39  * specified in the x86/HVM direct boot ABI.
40  * These structures contain all the required information (cmdline address, ACPI RSDP,
41  * memory maps, etc) that must be written to guest memory before starting guest
42  * execution by jumping to the PVH entry point address.
43  * A comparable set of definitions to hvm_start_info and hvm_memmap_table_entry in this
44  * file would be the boot_params and boot_e820_entry definitions used by the Linux
45  * 64-bit boot protocol.
46  *
47  * Start of day structure passed to PVH guests and to HVM guests in %ebx.
48  *
49  * NOTE: nothing will be loaded at physical address 0, so a 0 value in any
50  * of the address fields should be treated as not present.
51  *
52  *  0 +----------------+
53  *    | magic          | Contains the magic value XEN_HVM_START_MAGIC_VALUE
54  *    |                | ("xEn3" with the 0x80 bit of the "E" set).
55  *  4 +----------------+
56  *    | version        | Version of this structure. Current version is 1. New
57  *    |                | versions are guaranteed to be backwards-compatible.
58  *  8 +----------------+
59  *    | flags          | SIF_xxx flags.
60  * 12 +----------------+
61  *    | nr_modules     | Number of modules passed to the kernel.
62  * 16 +----------------+
63  *    | modlist_paddr  | Physical address of an array of modules
64  *    |                | (layout of the structure below).
65  * 24 +----------------+
66  *    | cmdline_paddr  | Physical address of the command line,
67  *    |                | a zero-terminated ASCII string.
68  * 32 +----------------+
69  *    | rsdp_paddr     | Physical address of the RSDP ACPI data structure.
70  * 40 +----------------+
71  *    | memmap_paddr   | Physical address of the (optional) memory map. Only
72  *    |                | present in version 1 and newer of the structure.
73  * 48 +----------------+
74  *    | memmap_entries | Number of entries in the memory map table. Zero
75  *    |                | if there is no memory map being provided. Only
76  *    |                | present in version 1 and newer of the structure.
77  * 52 +----------------+
78  *    | reserved       | Version 1 and newer only.
79  * 56 +----------------+
80  *
81  * The layout of each entry in the module structure is the following:
82  *
83  *  0 +----------------+
84  *    | paddr          | Physical address of the module.
85  *  8 +----------------+
86  *    | size           | Size of the module in bytes.
87  * 16 +----------------+
88  *    | cmdline_paddr  | Physical address of the command line,
89  *    |                | a zero-terminated ASCII string.
90  * 24 +----------------+
91  *    | reserved       |
92  * 32 +----------------+
93  *
94  * The layout of each entry in the memory map table is as follows:
95  *
96  *  0 +----------------+
97  *    | addr           | Base address
98  *  8 +----------------+
99  *    | size           | Size of mapping in bytes
100  * 16 +----------------+
101  *    | type           | Type of mapping as defined between the hypervisor
102  *    |                | and guest. See XEN_HVM_MEMMAP_TYPE_* values below.
103  * 20 +----------------|
104  *    | reserved       |
105  * 24 +----------------+
106  *
107  * The address and sizes are always a 64bit little endian unsigned integer.
108  *
109  * NB: Xen on x86 will always try to place all the data below the 4GiB
110  * boundary.
111  *
112  * Version numbers of the hvm_start_info structure have evolved like this:
113  *
114  * Version 0:  Initial implementation.
115  *
116  * Version 1:  Added the memmap_paddr/memmap_entries fields (plus 4 bytes of
117  *             padding) to the end of the hvm_start_info struct. These new
118  *             fields can be used to pass a memory map to the guest. The
119  *             memory map is optional and so guests that understand version 1
120  *             of the structure must check that memmap_entries is non-zero
121  *             before trying to read the memory map.
122  */
123 
124 #[repr(C)]
125 #[derive(Debug, Copy, Clone, Default)]
126 pub struct HvmStartInfo {
127     pub magic: u32,
128     pub version: u32,
129     pub flags: u32,
130     pub nr_modules: u32,
131     pub modlist_paddr: u64,
132     pub cmdline_paddr: u64,
133     pub rsdp_paddr: u64,
134     pub memmap_paddr: u64,
135     pub memmap_entries: u32,
136     pub reserved: u32,
137 }
138 
139 impl HvmStartInfo {
140     pub const XEN_HVM_START_MAGIC_VALUE: u32 = 0x336ec578;
141 }
142 
143 #[repr(C)]
144 #[derive(Debug, Copy, Clone, Default)]
145 pub struct HvmModlistEntry {
146     pub paddr: u64,
147     pub size: u64,
148     pub cmdline_paddr: u64,
149     pub reserved: u64,
150 }
151 
152 #[repr(C)]
153 #[derive(Debug, Copy, Clone, Default)]
154 pub struct HvmMemmapTableEntry {
155     pub addr: u64,
156     pub size: u64,
157     pub type_: u32,
158     pub reserved: u32,
159 }
160 
161 /// The E820 types known to the kernel.
162 #[derive(Copy, Clone, Debug)]
163 #[repr(u32)]
164 pub enum E820Type {
165     Ram = 1,
166     Reserved = 2,
167     Acpi = 3,
168     Nvs = 4,
169     Unusable = 5,
170     Pmem = 7,
171     Pram = 12,
172     SoftReserved = 0xefffffff,
173     ReservedKern = 128,
174 }
175 
176 impl From<u32> for E820Type {
from(val: u32) -> Self177     fn from(val: u32) -> Self {
178         match val {
179             1 => E820Type::Ram,
180             2 => E820Type::Reserved,
181             3 => E820Type::Acpi,
182             4 => E820Type::Nvs,
183             5 => E820Type::Unusable,
184             7 => E820Type::Pmem,
185             12 => E820Type::Pram,
186             0xefffffff => E820Type::SoftReserved,
187             128 => E820Type::ReservedKern,
188             _ => E820Type::Reserved,
189         }
190     }
191 }
192 
193 #[cfg(test)]
194 mod tests {
195     use super::*;
196 
197     #[test]
bindgen_test_layout_hvm_start_info()198     fn bindgen_test_layout_hvm_start_info() {
199         const UNINIT: ::std::mem::MaybeUninit<HvmStartInfo> = ::std::mem::MaybeUninit::uninit();
200         let ptr = UNINIT.as_ptr();
201         assert_eq!(
202             ::std::mem::size_of::<HvmStartInfo>(),
203             56usize,
204             concat!("Size of: ", stringify!(hvm_start_info))
205         );
206         assert_eq!(
207             ::std::mem::align_of::<HvmStartInfo>(),
208             8usize,
209             concat!("Alignment of ", stringify!(hvm_start_info))
210         );
211         assert_eq!(
212             unsafe { ::std::ptr::addr_of!((*ptr).magic) as usize - ptr as usize },
213             0usize,
214             concat!(
215                 "Offset of field: ",
216                 stringify!(hvm_start_info),
217                 "::",
218                 stringify!(magic)
219             )
220         );
221         assert_eq!(
222             unsafe { ::std::ptr::addr_of!((*ptr).version) as usize - ptr as usize },
223             4usize,
224             concat!(
225                 "Offset of field: ",
226                 stringify!(hvm_start_info),
227                 "::",
228                 stringify!(version)
229             )
230         );
231         assert_eq!(
232             unsafe { ::std::ptr::addr_of!((*ptr).flags) as usize - ptr as usize },
233             8usize,
234             concat!(
235                 "Offset of field: ",
236                 stringify!(hvm_start_info),
237                 "::",
238                 stringify!(flags)
239             )
240         );
241         assert_eq!(
242             unsafe { ::std::ptr::addr_of!((*ptr).nr_modules) as usize - ptr as usize },
243             12usize,
244             concat!(
245                 "Offset of field: ",
246                 stringify!(hvm_start_info),
247                 "::",
248                 stringify!(nr_modules)
249             )
250         );
251         assert_eq!(
252             unsafe { ::std::ptr::addr_of!((*ptr).modlist_paddr) as usize - ptr as usize },
253             16usize,
254             concat!(
255                 "Offset of field: ",
256                 stringify!(hvm_start_info),
257                 "::",
258                 stringify!(modlist_paddr)
259             )
260         );
261         assert_eq!(
262             unsafe { ::std::ptr::addr_of!((*ptr).cmdline_paddr) as usize - ptr as usize },
263             24usize,
264             concat!(
265                 "Offset of field: ",
266                 stringify!(hvm_start_info),
267                 "::",
268                 stringify!(cmdline_paddr)
269             )
270         );
271         assert_eq!(
272             unsafe { ::std::ptr::addr_of!((*ptr).rsdp_paddr) as usize - ptr as usize },
273             32usize,
274             concat!(
275                 "Offset of field: ",
276                 stringify!(hvm_start_info),
277                 "::",
278                 stringify!(rsdp_paddr)
279             )
280         );
281         assert_eq!(
282             unsafe { ::std::ptr::addr_of!((*ptr).memmap_paddr) as usize - ptr as usize },
283             40usize,
284             concat!(
285                 "Offset of field: ",
286                 stringify!(hvm_start_info),
287                 "::",
288                 stringify!(memmap_paddr)
289             )
290         );
291         assert_eq!(
292             unsafe { ::std::ptr::addr_of!((*ptr).memmap_entries) as usize - ptr as usize },
293             48usize,
294             concat!(
295                 "Offset of field: ",
296                 stringify!(hvm_start_info),
297                 "::",
298                 stringify!(memmap_entries)
299             )
300         );
301         assert_eq!(
302             unsafe { ::std::ptr::addr_of!((*ptr).reserved) as usize - ptr as usize },
303             52usize,
304             concat!(
305                 "Offset of field: ",
306                 stringify!(hvm_start_info),
307                 "::",
308                 stringify!(reserved)
309             )
310         );
311     }
312 
313     #[test]
bindgen_test_layout_hvm_modlist_entry()314     fn bindgen_test_layout_hvm_modlist_entry() {
315         const UNINIT: ::std::mem::MaybeUninit<HvmModlistEntry> = ::std::mem::MaybeUninit::uninit();
316         let ptr = UNINIT.as_ptr();
317         assert_eq!(
318             ::std::mem::size_of::<HvmModlistEntry>(),
319             32usize,
320             concat!("Size of: ", stringify!(hvm_modlist_entry))
321         );
322         assert_eq!(
323             ::std::mem::align_of::<HvmModlistEntry>(),
324             8usize,
325             concat!("Alignment of ", stringify!(hvm_modlist_entry))
326         );
327         assert_eq!(
328             unsafe { ::std::ptr::addr_of!((*ptr).paddr) as usize - ptr as usize },
329             0usize,
330             concat!(
331                 "Offset of field: ",
332                 stringify!(hvm_modlist_entry),
333                 "::",
334                 stringify!(paddr)
335             )
336         );
337         assert_eq!(
338             unsafe { ::std::ptr::addr_of!((*ptr).size) as usize - ptr as usize },
339             8usize,
340             concat!(
341                 "Offset of field: ",
342                 stringify!(hvm_modlist_entry),
343                 "::",
344                 stringify!(size)
345             )
346         );
347         assert_eq!(
348             unsafe { ::std::ptr::addr_of!((*ptr).cmdline_paddr) as usize - ptr as usize },
349             16usize,
350             concat!(
351                 "Offset of field: ",
352                 stringify!(hvm_modlist_entry),
353                 "::",
354                 stringify!(cmdline_paddr)
355             )
356         );
357         assert_eq!(
358             unsafe { ::std::ptr::addr_of!((*ptr).reserved) as usize - ptr as usize },
359             24usize,
360             concat!(
361                 "Offset of field: ",
362                 stringify!(hvm_modlist_entry),
363                 "::",
364                 stringify!(reserved)
365             )
366         );
367     }
368 
369     #[test]
bindgen_test_layout_hvm_memmap_table_entry()370     fn bindgen_test_layout_hvm_memmap_table_entry() {
371         const UNINIT: ::std::mem::MaybeUninit<HvmMemmapTableEntry> =
372             ::std::mem::MaybeUninit::uninit();
373         let ptr = UNINIT.as_ptr();
374         assert_eq!(
375             ::std::mem::size_of::<HvmMemmapTableEntry>(),
376             24usize,
377             concat!("Size of: ", stringify!(hvm_memmap_table_entry))
378         );
379         assert_eq!(
380             ::std::mem::align_of::<HvmMemmapTableEntry>(),
381             8usize,
382             concat!("Alignment of ", stringify!(hvm_memmap_table_entry))
383         );
384         assert_eq!(
385             unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize },
386             0usize,
387             concat!(
388                 "Offset of field: ",
389                 stringify!(hvm_memmap_table_entry),
390                 "::",
391                 stringify!(addr)
392             )
393         );
394         assert_eq!(
395             unsafe { ::std::ptr::addr_of!((*ptr).size) as usize - ptr as usize },
396             8usize,
397             concat!(
398                 "Offset of field: ",
399                 stringify!(hvm_memmap_table_entry),
400                 "::",
401                 stringify!(size)
402             )
403         );
404         assert_eq!(
405             unsafe { ::std::ptr::addr_of!((*ptr).type_) as usize - ptr as usize },
406             16usize,
407             concat!(
408                 "Offset of field: ",
409                 stringify!(hvm_memmap_table_entry),
410                 "::",
411                 stringify!(type_)
412             )
413         );
414         assert_eq!(
415             unsafe { ::std::ptr::addr_of!((*ptr).reserved) as usize - ptr as usize },
416             20usize,
417             concat!(
418                 "Offset of field: ",
419                 stringify!(hvm_memmap_table_entry),
420                 "::",
421                 stringify!(reserved)
422             )
423         );
424     }
425 }
426